mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-06 06:51:18 +12:00
Vulkan: Improve post-shutdown cleanup and minor improvements (#1401)
This commit is contained in:
parent
4f9eea07e0
commit
e834515f43
15 changed files with 190 additions and 118 deletions
|
@ -439,7 +439,7 @@ VulkanRenderer::VulkanRenderer()
|
|||
GetDeviceFeatures();
|
||||
|
||||
// init memory manager
|
||||
memoryManager = new VKRMemoryManager(this);
|
||||
memoryManager.reset(new VKRMemoryManager(this));
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -577,15 +577,15 @@ VulkanRenderer::VulkanRenderer()
|
|||
void* bufferPtr;
|
||||
// init ringbuffer for uniform vars
|
||||
m_uniformVarBufferMemoryIsCoherent = false;
|
||||
if (memoryManager->CreateBuffer2(UNIFORMVAR_RINGBUFFER_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT, m_uniformVarBuffer, m_uniformVarBufferMemory))
|
||||
if (memoryManager->CreateBuffer(UNIFORMVAR_RINGBUFFER_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT, m_uniformVarBuffer, m_uniformVarBufferMemory))
|
||||
m_uniformVarBufferMemoryIsCoherent = true;
|
||||
else if (memoryManager->CreateBuffer2(UNIFORMVAR_RINGBUFFER_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_uniformVarBuffer, m_uniformVarBufferMemory))
|
||||
else if (memoryManager->CreateBuffer(UNIFORMVAR_RINGBUFFER_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, m_uniformVarBuffer, m_uniformVarBufferMemory))
|
||||
m_uniformVarBufferMemoryIsCoherent = true; // unified memory
|
||||
else if (memoryManager->CreateBuffer2(UNIFORMVAR_RINGBUFFER_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, m_uniformVarBuffer, m_uniformVarBufferMemory))
|
||||
else if (memoryManager->CreateBuffer(UNIFORMVAR_RINGBUFFER_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, m_uniformVarBuffer, m_uniformVarBufferMemory))
|
||||
m_uniformVarBufferMemoryIsCoherent = true;
|
||||
else
|
||||
{
|
||||
memoryManager->CreateBuffer2(UNIFORMVAR_RINGBUFFER_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, m_uniformVarBuffer, m_uniformVarBufferMemory);
|
||||
memoryManager->CreateBuffer(UNIFORMVAR_RINGBUFFER_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, m_uniformVarBuffer, m_uniformVarBufferMemory);
|
||||
}
|
||||
|
||||
if (!m_uniformVarBufferMemoryIsCoherent)
|
||||
|
@ -628,6 +628,31 @@ VulkanRenderer::~VulkanRenderer()
|
|||
m_pipeline_cache_semaphore.notify();
|
||||
m_pipeline_cache_save_thread.join();
|
||||
|
||||
vkDestroyPipelineCache(m_logicalDevice, m_pipeline_cache, nullptr);
|
||||
|
||||
if(!m_backbufferBlitDescriptorSetCache.empty())
|
||||
{
|
||||
std::vector<VkDescriptorSet> freeVector;
|
||||
freeVector.reserve(m_backbufferBlitDescriptorSetCache.size());
|
||||
std::transform(m_backbufferBlitDescriptorSetCache.begin(), m_backbufferBlitDescriptorSetCache.end(), std::back_inserter(freeVector), [](auto& i) {
|
||||
return i.second;
|
||||
});
|
||||
vkFreeDescriptorSets(m_logicalDevice, m_descriptorPool, freeVector.size(), freeVector.data());
|
||||
}
|
||||
|
||||
vkDestroyDescriptorPool(m_logicalDevice, m_descriptorPool, nullptr);
|
||||
|
||||
for(auto& i : m_backbufferBlitPipelineCache)
|
||||
{
|
||||
vkDestroyPipeline(m_logicalDevice, i.second, nullptr);
|
||||
}
|
||||
m_backbufferBlitPipelineCache = {};
|
||||
|
||||
if(m_occlusionQueries.queryPool != VK_NULL_HANDLE)
|
||||
vkDestroyQueryPool(m_logicalDevice, m_occlusionQueries.queryPool, nullptr);
|
||||
|
||||
vkDestroyDescriptorSetLayout(m_logicalDevice, m_swapchainDescriptorSetLayout, nullptr);
|
||||
|
||||
// shut down imgui
|
||||
ImGui_ImplVulkan_Shutdown();
|
||||
|
||||
|
@ -640,10 +665,6 @@ VulkanRenderer::~VulkanRenderer()
|
|||
memoryManager->DeleteBuffer(m_xfbRingBuffer, m_xfbRingBufferMemory);
|
||||
memoryManager->DeleteBuffer(m_occlusionQueries.bufferQueryResults, m_occlusionQueries.memoryQueryResults);
|
||||
memoryManager->DeleteBuffer(m_bufferCache, m_bufferCacheMemory);
|
||||
// texture memory
|
||||
// todo
|
||||
// upload buffers
|
||||
// todo
|
||||
|
||||
m_padSwapchainInfo = nullptr;
|
||||
m_mainSwapchainInfo = nullptr;
|
||||
|
@ -666,6 +687,12 @@ VulkanRenderer::~VulkanRenderer()
|
|||
it = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
for(auto& sem : m_commandBufferSemaphores)
|
||||
{
|
||||
vkDestroySemaphore(m_logicalDevice, sem, nullptr);
|
||||
sem = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (m_pipelineLayout != VK_NULL_HANDLE)
|
||||
vkDestroyPipelineLayout(m_logicalDevice, m_pipelineLayout, nullptr);
|
||||
|
||||
|
@ -681,8 +708,11 @@ VulkanRenderer::~VulkanRenderer()
|
|||
vkDestroyDebugUtilsMessengerEXT(m_instance, m_debugCallback, nullptr);
|
||||
}
|
||||
|
||||
while(!m_destructionQueue.empty())
|
||||
ProcessDestructionQueue();
|
||||
|
||||
// destroy memory manager
|
||||
delete memoryManager;
|
||||
memoryManager.reset();
|
||||
|
||||
// destroy instance, devices
|
||||
if (m_instance != VK_NULL_HANDLE)
|
||||
|
@ -825,7 +855,14 @@ void VulkanRenderer::HandleScreenshotRequest(LatteTextureView* texView, bool pad
|
|||
VkMemoryAllocateInfo allocInfo{};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
allocInfo.allocationSize = memRequirements.size;
|
||||
allocInfo.memoryTypeIndex = memoryManager->FindMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
uint32 memIndex;
|
||||
bool foundMemory = memoryManager->FindMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, memIndex);
|
||||
if(!foundMemory)
|
||||
{
|
||||
cemuLog_log(LogType::Force, "Screenshot request failed due to incompatible vulkan memory types.");
|
||||
return;
|
||||
}
|
||||
allocInfo.memoryTypeIndex = memIndex;
|
||||
|
||||
if (vkAllocateMemory(m_logicalDevice, &allocInfo, nullptr, &imageMemory) != VK_SUCCESS)
|
||||
{
|
||||
|
@ -1608,6 +1645,7 @@ void VulkanRenderer::Initialize()
|
|||
|
||||
void VulkanRenderer::Shutdown()
|
||||
{
|
||||
DeleteFontTextures();
|
||||
Renderer::Shutdown();
|
||||
SubmitCommandBuffer();
|
||||
WaitDeviceIdle();
|
||||
|
@ -1808,7 +1846,6 @@ void VulkanRenderer::ImguiEnd()
|
|||
vkCmdEndRenderPass(m_state.currentCommandBuffer);
|
||||
}
|
||||
|
||||
std::vector<LatteTextureVk*> g_imgui_textures; // TODO manage better
|
||||
ImTextureID VulkanRenderer::GenerateTexture(const std::vector<uint8>& data, const Vector2i& size)
|
||||
{
|
||||
try
|
||||
|
@ -1838,6 +1875,7 @@ void VulkanRenderer::DeleteTexture(ImTextureID id)
|
|||
|
||||
void VulkanRenderer::DeleteFontTextures()
|
||||
{
|
||||
WaitDeviceIdle();
|
||||
ImGui_ImplVulkan_DestroyFontsTexture();
|
||||
}
|
||||
|
||||
|
@ -1876,7 +1914,7 @@ void VulkanRenderer::InitFirstCommandBuffer()
|
|||
vkResetFences(m_logicalDevice, 1, &m_cmd_buffer_fences[m_commandBufferIndex]);
|
||||
VkCommandBufferBeginInfo beginInfo{};
|
||||
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
|
||||
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
vkBeginCommandBuffer(m_state.currentCommandBuffer, &beginInfo);
|
||||
|
||||
vkCmdSetViewport(m_state.currentCommandBuffer, 0, 1, &m_state.currentViewport);
|
||||
|
@ -1998,7 +2036,7 @@ void VulkanRenderer::SubmitCommandBuffer(VkSemaphore signalSemaphore, VkSemaphor
|
|||
|
||||
VkCommandBufferBeginInfo beginInfo{};
|
||||
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
|
||||
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
vkBeginCommandBuffer(m_state.currentCommandBuffer, &beginInfo);
|
||||
|
||||
// make sure some states are set for this command buffer
|
||||
|
@ -2519,9 +2557,8 @@ VkPipeline VulkanRenderer::backbufferBlit_createGraphicsPipeline(VkDescriptorSet
|
|||
hash += (uint64)(chainInfo.m_usesSRGB);
|
||||
hash += ((uint64)padView) << 1;
|
||||
|
||||
static std::unordered_map<uint64, VkPipeline> s_pipeline_cache;
|
||||
const auto it = s_pipeline_cache.find(hash);
|
||||
if (it != s_pipeline_cache.cend())
|
||||
const auto it = m_backbufferBlitPipelineCache.find(hash);
|
||||
if (it != m_backbufferBlitPipelineCache.cend())
|
||||
return it->second;
|
||||
|
||||
std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
|
||||
|
@ -2625,7 +2662,7 @@ VkPipeline VulkanRenderer::backbufferBlit_createGraphicsPipeline(VkDescriptorSet
|
|||
throw std::runtime_error(fmt::format("Failed to create graphics pipeline: {}", result));
|
||||
}
|
||||
|
||||
s_pipeline_cache[hash] = pipeline;
|
||||
m_backbufferBlitPipelineCache[hash] = pipeline;
|
||||
m_pipeline_cache_semaphore.notify();
|
||||
|
||||
return pipeline;
|
||||
|
@ -2922,9 +2959,6 @@ void VulkanRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutpu
|
|||
LatteTextureViewVk* texViewVk = (LatteTextureViewVk*)texView;
|
||||
draw_endRenderPass();
|
||||
|
||||
if (clearBackground)
|
||||
ClearColorbuffer(padView);
|
||||
|
||||
// barrier for input texture
|
||||
VkMemoryBarrier memoryBarrier{};
|
||||
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
|
||||
|
@ -2961,6 +2995,16 @@ void VulkanRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutpu
|
|||
|
||||
vkCmdBeginRenderPass(m_state.currentCommandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
if (clearBackground)
|
||||
{
|
||||
VkClearAttachment clearAttachment{};
|
||||
clearAttachment.clearValue = {0,0,0,0};
|
||||
clearAttachment.colorAttachment = 0;
|
||||
clearAttachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
VkClearRect clearExtent = {{{0,0},chainInfo.m_actualExtent}, 0, 1};
|
||||
vkCmdClearAttachments(m_state.currentCommandBuffer, 1, &clearAttachment, 1, &clearExtent);
|
||||
}
|
||||
|
||||
vkCmdBindPipeline(m_state.currentCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
m_state.currentPipeline = pipeline;
|
||||
|
||||
|
@ -3025,9 +3069,8 @@ VkDescriptorSet VulkanRenderer::backbufferBlit_createDescriptorSet(VkDescriptorS
|
|||
hash += (uint64)texViewVk->GetViewRGBA();
|
||||
hash += (uint64)texViewVk->GetDefaultTextureSampler(useLinearTexFilter);
|
||||
|
||||
static std::unordered_map<uint64, VkDescriptorSet> s_set_cache;
|
||||
const auto it = s_set_cache.find(hash);
|
||||
if (it != s_set_cache.cend())
|
||||
const auto it = m_backbufferBlitDescriptorSetCache.find(hash);
|
||||
if (it != m_backbufferBlitDescriptorSetCache.cend())
|
||||
return it->second;
|
||||
|
||||
VkDescriptorSetAllocateInfo allocInfo = {};
|
||||
|
@ -3058,7 +3101,7 @@ VkDescriptorSet VulkanRenderer::backbufferBlit_createDescriptorSet(VkDescriptorS
|
|||
vkUpdateDescriptorSets(m_logicalDevice, 1, &descriptorWrites, 0, nullptr);
|
||||
performanceMonitor.vk.numDescriptorSamplerTextures.increment();
|
||||
|
||||
s_set_cache[hash] = result;
|
||||
m_backbufferBlitDescriptorSetCache[hash] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -3191,7 +3234,8 @@ VkDescriptorSetInfo::~VkDescriptorSetInfo()
|
|||
performanceMonitor.vk.numDescriptorDynUniformBuffers.decrement(statsNumDynUniformBuffers);
|
||||
performanceMonitor.vk.numDescriptorStorageBuffers.decrement(statsNumStorageBuffers);
|
||||
|
||||
VulkanRenderer::GetInstance()->ReleaseDestructibleObject(m_vkObjDescriptorSet);
|
||||
auto renderer = VulkanRenderer::GetInstance();
|
||||
renderer->ReleaseDestructibleObject(m_vkObjDescriptorSet);
|
||||
m_vkObjDescriptorSet = nullptr;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue