Skip to content

Commit

Permalink
Merge branch 'main' into metal
Browse files Browse the repository at this point in the history
  • Loading branch information
SamoZ256 authored Jan 27, 2025
2 parents 58a8b70 + e834515 commit 2f9ef59
Show file tree
Hide file tree
Showing 18 changed files with 202 additions and 130 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/generate_pot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
-o cemu.pot
- name: Upload artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: POT file
path: ./cemu.pot
Expand Down
2 changes: 1 addition & 1 deletion src/Cafe/GameProfile/GameProfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ bool gameProfile_loadEnumOption(IniParser& iniParser, const char* optionName, T&
for(const T& v : T())
{
// test integer option
if (boost::iequals(fmt::format("{}", static_cast<typename std::underlying_type<T>::type>(v)), *option_value))
if (boost::iequals(fmt::format("{}", fmt::underlying(v)), *option_value))
{
option = v;
return true;
Expand Down
5 changes: 3 additions & 2 deletions src/Cafe/HW/Latte/Core/LatteShaderCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,9 @@ void LatteShaderCache_Load()
g_renderer->DeleteTexture(g_shaderCacheLoaderState.textureDRCId);

g_bootSndPlayer.FadeOutSound();

if(Latte_GetStopSignal())
LatteThread_Exit();
}

void LatteShaderCache_ShowProgress(const std::function <bool(void)>& loadUpdateFunc, bool isPipelines)
Expand Down Expand Up @@ -651,8 +654,6 @@ void LatteShaderCache_LoadPipelineCache(uint64 cacheTitleId)
else if (g_renderer->GetType() == RendererAPI::Metal)
MetalPipelineCache::GetInstance().EndLoading();
#endif
if(Latte_GetStopSignal())
LatteThread_Exit();
}

bool LatteShaderCache_updatePipelineLoadingProgress()
Expand Down
1 change: 1 addition & 0 deletions src/Cafe/HW/Latte/Core/LatteThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ void LatteThread_Exit()
LatteSHRC_UnloadAll();
// close disk cache
LatteShaderCache_Close();
RendererOutputShader::ShutdownStatic();
// destroy renderer but make sure that g_renderer remains valid until the destructor has finished
if (g_renderer)
{
Expand Down
20 changes: 16 additions & 4 deletions src/Cafe/HW/Latte/Renderer/RendererOuputShader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,8 @@ RendererOutputShader::RendererOutputShader(const std::string& vertex_source, con
else
finalFragmentSrc = PrependFragmentPreamble(fragment_source);

m_vertex_shader = g_renderer->shader_create(RendererShader::ShaderType::kVertex, 0, 0, vertex_source, false, false);
m_fragment_shader = g_renderer->shader_create(RendererShader::ShaderType::kFragment, 0, 0, finalFragmentSrc, false, false);
m_vertex_shader.reset(g_renderer->shader_create(RendererShader::ShaderType::kVertex, 0, 0, vertex_source, false, false));
m_fragment_shader.reset(g_renderer->shader_create(RendererShader::ShaderType::kFragment, 0, 0, finalFragmentSrc, false, false));

m_vertex_shader->PreponeCompilation(true);
m_fragment_shader->PreponeCompilation(true);
Expand Down Expand Up @@ -302,8 +302,8 @@ void RendererOutputShader::SetUniformParameters(const LatteTextureView& texture_
shader->SetUniform2fv(locations.m_loc_outputResolution, res, 1);
}
};
setUniforms(m_vertex_shader, m_uniformLocations[0]);
setUniforms(m_fragment_shader, m_uniformLocations[1]);
setUniforms(m_vertex_shader.get(), m_uniformLocations[0]);
setUniforms(m_fragment_shader.get(), m_uniformLocations[1]);
}

RendererOutputShader* RendererOutputShader::s_copy_shader;
Expand Down Expand Up @@ -513,3 +513,15 @@ void RendererOutputShader::InitializeStatic()
s_hermit_shader_ud = new RendererOutputShader(vertex_source_ud, s_hermite_shader_source);
}
}

void RendererOutputShader::ShutdownStatic()
{
delete s_copy_shader;
delete s_copy_shader_ud;

delete s_bicubic_shader;
delete s_bicubic_shader_ud;

delete s_hermit_shader;
delete s_hermit_shader_ud;
}
9 changes: 5 additions & 4 deletions src/Cafe/HW/Latte/Renderer/RendererOuputShader.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@ class RendererOutputShader

RendererShader* GetVertexShader() const
{
return m_vertex_shader;
return m_vertex_shader.get();
}

RendererShader* GetFragmentShader() const
{
return m_fragment_shader;
return m_fragment_shader.get();
}

static void InitializeStatic();
static void ShutdownStatic();

static RendererOutputShader* s_copy_shader;
static RendererOutputShader* s_copy_shader_ud;
Expand All @@ -47,8 +48,8 @@ class RendererOutputShader
static std::string PrependFragmentPreamble(const std::string& shaderSrc);

protected:
RendererShader* m_vertex_shader;
RendererShader* m_fragment_shader;
std::unique_ptr<RendererShader> m_vertex_shader;
std::unique_ptr<RendererShader> m_fragment_shader;

struct UniformLocations
{
Expand Down
3 changes: 3 additions & 0 deletions src/Cafe/HW/Latte/Renderer/Vulkan/RendererShaderVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ RendererShaderVk::~RendererShaderVk()
{
while (!list_pipelineInfo.empty())
delete list_pipelineInfo[0];

VkDevice vkDev = VulkanRenderer::GetInstance()->GetLogicalDevice();
vkDestroyShaderModule(vkDev, m_shader_module, nullptr);
}

void RendererShaderVk::Init()
Expand Down
2 changes: 1 addition & 1 deletion src/Cafe/HW/Latte/Renderer/Vulkan/SwapchainInfoVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ void SwapchainInfoVk::Create()
VkAttachmentDescription colorAttachment = {};
colorAttachment.format = m_surfaceFormat.format;
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
Expand Down
2 changes: 1 addition & 1 deletion src/Cafe/HW/Latte/Renderer/Vulkan/SwapchainInfoVk.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ struct SwapchainInfoVk
VkSurfaceFormatKHR m_surfaceFormat{};
VkSwapchainKHR m_swapchain{};
Vector2i m_desiredExtent{};
VkExtent2D m_actualExtent{};
uint32 swapchainImageIndex = (uint32)-1;
uint64 m_presentId = 1;
uint64 m_queueDepth = 0; // number of frames with pending presentation requests
Expand All @@ -92,5 +93,4 @@ struct SwapchainInfoVk
VkSemaphore m_currentSemaphore = VK_NULL_HANDLE;

std::array<uint32, 2> m_swapchainQueueFamilyIndices;
VkExtent2D m_actualExtent{};
};
79 changes: 29 additions & 50 deletions src/Cafe/HW/Latte/Renderer/Vulkan/VKRMemoryManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@

/* VKRSynchronizedMemoryBuffer */

VKRSynchronizedRingAllocator::~VKRSynchronizedRingAllocator()
{
for(auto& buf : m_buffers)
{
m_vkrMemMgr->DeleteBuffer(buf.vk_buffer, buf.vk_mem);
}
}

void VKRSynchronizedRingAllocator::addUploadBufferSyncPoint(AllocatorBuffer_t& buffer, uint32 offset)
{
auto cmdBufferId = m_vkr->GetCurrentCommandBufferId();
Expand Down Expand Up @@ -233,6 +241,15 @@ void VKRSynchronizedHeapAllocator::GetStats(uint32& numBuffers, size_t& totalBuf

/* VkTextureChunkedHeap */

VkTextureChunkedHeap::~VkTextureChunkedHeap()
{
VkDevice device = VulkanRenderer::GetInstance()->GetLogicalDevice();
for (auto& i : m_list_chunkInfo)
{
vkFreeMemory(device, i.mem, nullptr);
}
}

uint32 VkTextureChunkedHeap::allocateNewChunk(uint32 chunkIndex, uint32 minimumAllocationSize)
{
cemu_assert_debug(m_list_chunkInfo.size() == chunkIndex);
Expand Down Expand Up @@ -310,11 +327,11 @@ VKRBuffer* VKRBuffer::Create(VKR_BUFFER_TYPE bufferType, size_t bufferSize, VkMe
VkDeviceMemory bufferMemory;
bool allocSuccess;
if (bufferType == VKR_BUFFER_TYPE::STAGING)
allocSuccess = memMgr->CreateBuffer2(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, properties, buffer, bufferMemory);
allocSuccess = memMgr->CreateBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, properties, buffer, bufferMemory);
else if (bufferType == VKR_BUFFER_TYPE::INDEX)
allocSuccess = memMgr->CreateBuffer2(bufferSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, properties, buffer, bufferMemory);
allocSuccess = memMgr->CreateBuffer(bufferSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, properties, buffer, bufferMemory);
else if (bufferType == VKR_BUFFER_TYPE::STRIDE)
allocSuccess = memMgr->CreateBuffer2(bufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, properties, buffer, bufferMemory);
allocSuccess = memMgr->CreateBuffer(bufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, properties, buffer, bufferMemory);
else
cemu_assert_debug(false);
if (!allocSuccess)
Expand Down Expand Up @@ -363,28 +380,14 @@ uint32 VkBufferChunkedHeap::allocateNewChunk(uint32 chunkIndex, uint32 minimumAl
return allocationSize;
}

uint32_t VKRMemoryManager::FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) const
{
VkPhysicalDeviceMemoryProperties memProperties;
vkGetPhysicalDeviceMemoryProperties(m_vkr->GetPhysicalDevice(), &memProperties);

for (uint32 i = 0; i < memProperties.memoryTypeCount; i++)
{
if ((typeFilter & (1 << i)) != 0 && (memProperties.memoryTypes[i].propertyFlags & properties) == properties)
return i;
}
m_vkr->UnrecoverableError(fmt::format("failed to find suitable memory type ({0:#08x} {1:#08x})", typeFilter, properties).c_str());
return 0;
}

bool VKRMemoryManager::FindMemoryType2(uint32 typeFilter, VkMemoryPropertyFlags properties, uint32& memoryIndex) const
bool VKRMemoryManager::FindMemoryType(uint32 typeFilter, VkMemoryPropertyFlags properties, uint32& memoryIndex) const
{
VkPhysicalDeviceMemoryProperties memProperties;
vkGetPhysicalDeviceMemoryProperties(m_vkr->GetPhysicalDevice(), &memProperties);

for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++)
{
if (typeFilter & (1 << i) && memProperties.memoryTypes[i].propertyFlags == properties)
if (typeFilter & (1 << i) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties)
{
memoryIndex = i;
return true;
Expand Down Expand Up @@ -455,31 +458,7 @@ size_t VKRMemoryManager::GetTotalMemoryForBufferType(VkBufferUsageFlags usage, V
return total;
}

void VKRMemoryManager::CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory) const
{
VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.usage = usage;
bufferInfo.size = size;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
if (vkCreateBuffer(m_vkr->GetLogicalDevice(), &bufferInfo, nullptr, &buffer) != VK_SUCCESS)
m_vkr->UnrecoverableError("Failed to create buffer");

VkMemoryRequirements memRequirements;
vkGetBufferMemoryRequirements(m_vkr->GetLogicalDevice(), buffer, &memRequirements);

VkMemoryAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.allocationSize = memRequirements.size;
allocInfo.memoryTypeIndex = FindMemoryType(memRequirements.memoryTypeBits, properties);

if (vkAllocateMemory(m_vkr->GetLogicalDevice(), &allocInfo, nullptr, &bufferMemory) != VK_SUCCESS)
m_vkr->UnrecoverableError("Failed to allocate buffer memory");
if (vkBindBufferMemory(m_vkr->GetLogicalDevice(), buffer, bufferMemory, 0) != VK_SUCCESS)
m_vkr->UnrecoverableError("Failed to bind buffer memory");
}

bool VKRMemoryManager::CreateBuffer2(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory) const
bool VKRMemoryManager::CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory) const
{
VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
Expand All @@ -488,7 +467,7 @@ bool VKRMemoryManager::CreateBuffer2(VkDeviceSize size, VkBufferUsageFlags usage
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
if (vkCreateBuffer(m_vkr->GetLogicalDevice(), &bufferInfo, nullptr, &buffer) != VK_SUCCESS)
{
cemuLog_log(LogType::Force, "Failed to create buffer (CreateBuffer2)");
cemuLog_log(LogType::Force, "Failed to create buffer (CreateBuffer)");
return false;
}

Expand All @@ -498,7 +477,7 @@ bool VKRMemoryManager::CreateBuffer2(VkDeviceSize size, VkBufferUsageFlags usage
VkMemoryAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.allocationSize = memRequirements.size;
if (!FindMemoryType2(memRequirements.memoryTypeBits, properties, allocInfo.memoryTypeIndex))
if (!FindMemoryType(memRequirements.memoryTypeBits, properties, allocInfo.memoryTypeIndex))
{
vkDestroyBuffer(m_vkr->GetLogicalDevice(), buffer, nullptr);
return false;
Expand All @@ -511,7 +490,7 @@ bool VKRMemoryManager::CreateBuffer2(VkDeviceSize size, VkBufferUsageFlags usage
if (vkBindBufferMemory(m_vkr->GetLogicalDevice(), buffer, bufferMemory, 0) != VK_SUCCESS)
{
vkDestroyBuffer(m_vkr->GetLogicalDevice(), buffer, nullptr);
cemuLog_log(LogType::Force, "Failed to bind buffer (CreateBuffer2)");
cemuLog_log(LogType::Force, "Failed to bind buffer (CreateBuffer)");
return false;
}
return true;
Expand All @@ -533,7 +512,7 @@ bool VKRMemoryManager::CreateBufferFromHostMemory(void* hostPointer, VkDeviceSiz

if (vkCreateBuffer(m_vkr->GetLogicalDevice(), &bufferInfo, nullptr, &buffer) != VK_SUCCESS)
{
cemuLog_log(LogType::Force, "Failed to create buffer (CreateBuffer2)");
cemuLog_log(LogType::Force, "Failed to create buffer (CreateBuffer)");
return false;
}

Expand All @@ -554,7 +533,7 @@ bool VKRMemoryManager::CreateBufferFromHostMemory(void* hostPointer, VkDeviceSiz

allocInfo.pNext = &importHostMem;

if (!FindMemoryType2(memRequirements.memoryTypeBits, properties, allocInfo.memoryTypeIndex))
if (!FindMemoryType(memRequirements.memoryTypeBits, properties, allocInfo.memoryTypeIndex))
{
vkDestroyBuffer(m_vkr->GetLogicalDevice(), buffer, nullptr);
return false;
Expand Down Expand Up @@ -598,7 +577,7 @@ VkImageMemAllocation* VKRMemoryManager::imageMemoryAllocate(VkImage image)
map_textureHeap.emplace(typeFilter, texHeap);
}
else
texHeap = it->second;
texHeap = it->second.get();

// alloc mem from heap
uint32 allocationSize = (uint32)memRequirements.size;
Expand Down
11 changes: 5 additions & 6 deletions src/Cafe/HW/Latte/Renderer/Vulkan/VKRMemoryManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class VkTextureChunkedHeap : private ChunkedHeap<>
{
public:
VkTextureChunkedHeap(class VKRMemoryManager* memoryManager, uint32 typeFilter) : m_vkrMemoryManager(memoryManager), m_typeFilter(typeFilter) { };
~VkTextureChunkedHeap();

struct ChunkInfo
{
Expand Down Expand Up @@ -148,6 +149,7 @@ class VKRSynchronizedRingAllocator
public:
VKRSynchronizedRingAllocator(class VulkanRenderer* vkRenderer, class VKRMemoryManager* vkMemoryManager, VKR_BUFFER_TYPE bufferType, uint32 minimumBufferAllocSize) : m_vkr(vkRenderer), m_vkrMemMgr(vkMemoryManager), m_bufferType(bufferType), m_minimumBufferAllocSize(minimumBufferAllocSize) {};
VKRSynchronizedRingAllocator(const VKRSynchronizedRingAllocator&) = delete; // disallow copy
~VKRSynchronizedRingAllocator();

struct BufferSyncPoint_t
{
Expand Down Expand Up @@ -256,7 +258,7 @@ class VKRMemoryManager
}

// texture memory management
std::unordered_map<uint32, VkTextureChunkedHeap*> map_textureHeap; // one heap per memory type
std::unordered_map<uint32, std::unique_ptr<VkTextureChunkedHeap>> map_textureHeap; // one heap per memory type
std::vector<uint8> m_textureUploadBuffer;

// texture upload buffer
Expand Down Expand Up @@ -286,9 +288,7 @@ class VKRMemoryManager
m_vertexStrideMetalBuffer.CleanupBuffer(latestFinishedCommandBufferId);
}

// memory helpers
uint32_t FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) const;
bool FindMemoryType2(uint32 typeFilter, VkMemoryPropertyFlags properties, uint32& memoryIndex) const; // searches for exact properties. Can gracefully fail without throwing exception (returns false)
bool FindMemoryType(uint32 typeFilter, VkMemoryPropertyFlags properties, uint32& memoryIndex) const; // searches for exact properties. Can gracefully fail without throwing exception (returns false)
std::vector<uint32> FindMemoryTypes(uint32_t typeFilter, VkMemoryPropertyFlags properties) const;

// image memory allocation
Expand All @@ -298,8 +298,7 @@ class VKRMemoryManager
// buffer management
size_t GetTotalMemoryForBufferType(VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, size_t minimumBufferSize = 16 * 1024 * 1024);

void CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory) const;
bool CreateBuffer2(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory) const; // same as CreateBuffer but doesn't throw exception on failure
bool CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory) const; // same as CreateBuffer but doesn't throw exception on failure
bool CreateBufferFromHostMemory(void* hostPointer, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory) const;

void DeleteBuffer(VkBuffer& buffer, VkDeviceMemory& deviceMem) const;
Expand Down
3 changes: 3 additions & 0 deletions src/Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ VKFUNC_DEVICE(vkCmdDraw);
VKFUNC_DEVICE(vkCmdCopyBufferToImage);
VKFUNC_DEVICE(vkCmdCopyImageToBuffer);
VKFUNC_DEVICE(vkCmdClearColorImage);
VKFUNC_DEVICE(vkCmdClearAttachments);
VKFUNC_DEVICE(vkCmdBindIndexBuffer);
VKFUNC_DEVICE(vkCmdBindVertexBuffers);
VKFUNC_DEVICE(vkCmdDrawIndexed);
Expand Down Expand Up @@ -198,6 +199,7 @@ VKFUNC_DEVICE(vkCmdEndTransformFeedbackEXT);

// query
VKFUNC_DEVICE(vkCreateQueryPool);
VKFUNC_DEVICE(vkDestroyQueryPool);
VKFUNC_DEVICE(vkCmdResetQueryPool);
VKFUNC_DEVICE(vkCmdBeginQuery);
VKFUNC_DEVICE(vkCmdEndQuery);
Expand Down Expand Up @@ -236,6 +238,7 @@ VKFUNC_DEVICE(vkAllocateDescriptorSets);
VKFUNC_DEVICE(vkFreeDescriptorSets);
VKFUNC_DEVICE(vkUpdateDescriptorSets);
VKFUNC_DEVICE(vkCreateDescriptorPool);
VKFUNC_DEVICE(vkDestroyDescriptorPool);
VKFUNC_DEVICE(vkDestroyDescriptorSetLayout);

#undef VKFUNC_INIT
Expand Down
Loading

0 comments on commit 2f9ef59

Please sign in to comment.