From 7c3e99a6f1956c5643c29fa7ae4908cb247b9807 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 10 May 2019 02:16:26 +0200 Subject: [PATCH] - Intel on Linux used the footnote in the standard saying a descriptor pool can become fragmented (thanks guys!) --- .../vulkan/renderer/vk_postprocess.cpp | 26 ++++++++++++------- .../vulkan/renderer/vk_postprocess.h | 2 +- .../vulkan/system/vk_framebuffer.cpp | 13 +++++----- src/rendering/vulkan/system/vk_objects.h | 19 +++++++++++++- 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/rendering/vulkan/renderer/vk_postprocess.cpp b/src/rendering/vulkan/renderer/vk_postprocess.cpp index 660afe96c4..2aa739bc35 100644 --- a/src/rendering/vulkan/renderer/vk_postprocess.cpp +++ b/src/rendering/vulkan/renderer/vk_postprocess.cpp @@ -271,17 +271,25 @@ void VkPostprocess::UpdateShadowMap() } } -void VkPostprocess::BeginFrame() +std::unique_ptr VkPostprocess::AllocateDescriptorSet(VulkanDescriptorSetLayout *layout) { - if (!mDescriptorPool) + if (mDescriptorPool) { - DescriptorPoolBuilder builder; - builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 200); - builder.addPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 4); - builder.setMaxSets(100); - mDescriptorPool = builder.create(GetVulkanFrameBuffer()->device); - mDescriptorPool->SetDebugName("VkPostprocess.mDescriptorPool"); + auto descriptors = mDescriptorPool->tryAllocate(layout); + if (descriptors) + return descriptors; + + GetVulkanFrameBuffer()->FrameDeleteList.DescriptorPools.push_back(std::move(mDescriptorPool)); } + + DescriptorPoolBuilder builder; + builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 200); + builder.addPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 4); + builder.setMaxSets(100); + mDescriptorPool = builder.create(GetVulkanFrameBuffer()->device); + mDescriptorPool->SetDebugName("VkPostprocess.mDescriptorPool"); + + return mDescriptorPool->allocate(layout); } void VkPostprocess::RenderBuffersReset() @@ -522,7 +530,7 @@ VulkanDescriptorSet *VkPPRenderState::GetInput(VkPPRenderPassSetup *passSetup, c { auto fb = GetVulkanFrameBuffer(); auto pp = fb->GetPostprocess(); - auto descriptors = pp->mDescriptorPool->allocate(passSetup->DescriptorLayout.get()); + auto descriptors = pp->AllocateDescriptorSet(passSetup->DescriptorLayout.get()); descriptors->SetDebugName("VkPostprocess.descriptors"); WriteDescriptors write; diff --git a/src/rendering/vulkan/renderer/vk_postprocess.h b/src/rendering/vulkan/renderer/vk_postprocess.h index 8a4489ddeb..9ae39a6f85 100644 --- a/src/rendering/vulkan/renderer/vk_postprocess.h +++ b/src/rendering/vulkan/renderer/vk_postprocess.h @@ -52,7 +52,6 @@ public: VkPostprocess(); ~VkPostprocess(); - void BeginFrame(); void RenderBuffersReset(); void SetActiveRenderTarget(); @@ -73,6 +72,7 @@ public: private: void NextEye(int eyeCount); + std::unique_ptr AllocateDescriptorSet(VulkanDescriptorSetLayout *layout); VulkanSampler *GetSampler(PPFilterMode filter, PPWrapMode wrap); std::array, 4> mSamplers; diff --git a/src/rendering/vulkan/system/vk_framebuffer.cpp b/src/rendering/vulkan/system/vk_framebuffer.cpp index 253eacf94a..6387d754cd 100644 --- a/src/rendering/vulkan/system/vk_framebuffer.cpp +++ b/src/rendering/vulkan/system/vk_framebuffer.cpp @@ -796,18 +796,17 @@ TArray VulkanFrameBuffer::GetScreenshotBuffer(int &pitch, ESSType &colo void VulkanFrameBuffer::BeginFrame() { + SetViewportRects(nullptr); + mScreenBuffers->BeginFrame(screen->mScreenViewport.width, screen->mScreenViewport.height, screen->mSceneViewport.width, screen->mSceneViewport.height); + mSaveBuffers->BeginFrame(SAVEPICWIDTH, SAVEPICHEIGHT, SAVEPICWIDTH, SAVEPICHEIGHT); + mRenderState->BeginFrame(); + mRenderPassManager->UpdateDynamicSet(); + if (mNextTimestampQuery > 0) { GetDrawCommands()->resetQueryPool(mTimestampQueryPool.get(), 0, mNextTimestampQuery); mNextTimestampQuery = 0; } - - SetViewportRects(nullptr); - mScreenBuffers->BeginFrame(screen->mScreenViewport.width, screen->mScreenViewport.height, screen->mSceneViewport.width, screen->mSceneViewport.height); - mSaveBuffers->BeginFrame(SAVEPICWIDTH, SAVEPICHEIGHT, SAVEPICWIDTH, SAVEPICHEIGHT); - mPostprocess->BeginFrame(); - mRenderState->BeginFrame(); - mRenderPassManager->UpdateDynamicSet(); } void VulkanFrameBuffer::PushGroup(const FString &name) diff --git a/src/rendering/vulkan/system/vk_objects.h b/src/rendering/vulkan/system/vk_objects.h index 799f645608..ac7bd89f28 100644 --- a/src/rendering/vulkan/system/vk_objects.h +++ b/src/rendering/vulkan/system/vk_objects.h @@ -192,6 +192,7 @@ public: void SetDebugName(const char *name) { device->SetDebugObjectName(name, (uint64_t)pool, VK_OBJECT_TYPE_DESCRIPTOR_POOL); } + std::unique_ptr tryAllocate(VulkanDescriptorSetLayout *layout); std::unique_ptr allocate(VulkanDescriptorSetLayout *layout); VulkanDevice *device; @@ -932,6 +933,22 @@ inline VulkanDescriptorPool::~VulkanDescriptorPool() vkDestroyDescriptorPool(device->device, pool, nullptr); } +inline std::unique_ptr VulkanDescriptorPool::tryAllocate(VulkanDescriptorSetLayout *layout) +{ + VkDescriptorSetAllocateInfo allocInfo = {}; + allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + allocInfo.descriptorPool = pool; + allocInfo.descriptorSetCount = 1; + allocInfo.pSetLayouts = &layout->layout; + + VkDescriptorSet descriptorSet; + VkResult result = vkAllocateDescriptorSets(device->device, &allocInfo, &descriptorSet); + if (result != VK_SUCCESS) + return nullptr; + + return std::make_unique(device, this, descriptorSet); +} + inline std::unique_ptr VulkanDescriptorPool::allocate(VulkanDescriptorSetLayout *layout) { VkDescriptorSetAllocateInfo allocInfo = {}; @@ -943,7 +960,7 @@ inline std::unique_ptr VulkanDescriptorPool::allocate(Vulka VkDescriptorSet descriptorSet; VkResult result = vkAllocateDescriptorSets(device->device, &allocInfo, &descriptorSet); if (result != VK_SUCCESS) - I_Error("Could not allocate descriptor sets"); + I_FatalError("Could not allocate descriptor sets"); return std::make_unique(device, this, descriptorSet); }