diff --git a/src/rendering/vulkan/renderer/vk_renderpass.cpp b/src/rendering/vulkan/renderer/vk_renderpass.cpp index 4e91efab1..414d22156 100644 --- a/src/rendering/vulkan/renderer/vk_renderpass.cpp +++ b/src/rendering/vulkan/renderer/vk_renderpass.cpp @@ -28,6 +28,13 @@ void VkRenderPassManager::RenderBuffersReset() RenderPassSetup.clear(); } +void VkRenderPassManager::TextureSetPoolReset() +{ + TextureDescriptorPools.clear(); + TextureDescriptorSetsLeft = 0; + TextureDescriptorsLeft = 0; +} + VkRenderPassSetup *VkRenderPassManager::GetRenderPass(const VkRenderPassKey &key) { auto &item = RenderPassSetup[key]; @@ -110,15 +117,17 @@ void VkRenderPassManager::CreateDescriptorPool() DescriptorPoolBuilder builder; builder.addPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 3); builder.addPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1); - builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 5000 * 6); - builder.setMaxSets(5000); - DescriptorPool = builder.create(GetVulkanFrameBuffer()->device); - DescriptorPool->SetDebugName("VkRenderPassManager.DescriptorPool"); + builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1); + builder.setMaxSets(1); + DynamicDescriptorPool = builder.create(GetVulkanFrameBuffer()->device); + DynamicDescriptorPool->SetDebugName("VkRenderPassManager.DynamicDescriptorPool"); } void VkRenderPassManager::CreateDynamicSet() { - DynamicSet = DescriptorPool->allocate(DynamicSetLayout.get()); + DynamicSet = DynamicDescriptorPool->allocate(DynamicSetLayout.get()); + if (!DynamicSet) + I_FatalError("CreateDynamicSet failed.\n"); } void VkRenderPassManager::UpdateDynamicSet() @@ -134,6 +143,27 @@ void VkRenderPassManager::UpdateDynamicSet() update.updateSets(fb->device); } +std::unique_ptr VkRenderPassManager::AllocateTextureDescriptorSet(int numLayers) +{ + numLayers = 6; // To do: remove this and create a TextureSetLayout for each amount to support custom materials + + if (TextureDescriptorSetsLeft == 0 || TextureDescriptorsLeft < numLayers) + { + TextureDescriptorSetsLeft = 1000; + TextureDescriptorsLeft = 2000; + + DescriptorPoolBuilder builder; + builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, TextureDescriptorsLeft); + builder.setMaxSets(TextureDescriptorSetsLeft); + TextureDescriptorPools.push_back(builder.create(GetVulkanFrameBuffer()->device)); + TextureDescriptorPools.back()->SetDebugName("VkRenderPassManager.TextureDescriptorPool"); + } + + TextureDescriptorSetsLeft--; + TextureDescriptorsLeft -= numLayers; + return TextureDescriptorPools.back()->allocate(TextureSetLayout.get()); +} + ///////////////////////////////////////////////////////////////////////////// VkRenderPassSetup::VkRenderPassSetup(const VkRenderPassKey &key) diff --git a/src/rendering/vulkan/renderer/vk_renderpass.h b/src/rendering/vulkan/renderer/vk_renderpass.h index b00220b08..0cd966428 100644 --- a/src/rendering/vulkan/renderer/vk_renderpass.h +++ b/src/rendering/vulkan/renderer/vk_renderpass.h @@ -70,14 +70,16 @@ public: void Init(); void RenderBuffersReset(); void UpdateDynamicSet(); + void TextureSetPoolReset(); VkRenderPassSetup *GetRenderPass(const VkRenderPassKey &key); int GetVertexFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs); + std::unique_ptr AllocateTextureDescriptorSet(int numLayers); + std::unique_ptr DynamicSetLayout; std::unique_ptr TextureSetLayout; std::unique_ptr PipelineLayout; - std::unique_ptr DescriptorPool; std::map> RenderPassSetup; std::unique_ptr DynamicSet; @@ -91,4 +93,8 @@ private: void CreateDescriptorPool(); void CreateDynamicSet(); + int TextureDescriptorSetsLeft = 0; + int TextureDescriptorsLeft = 0; + std::vector> TextureDescriptorPools; + std::unique_ptr DynamicDescriptorPool; }; diff --git a/src/rendering/vulkan/system/vk_framebuffer.cpp b/src/rendering/vulkan/system/vk_framebuffer.cpp index fbff8fa25..91878795c 100644 --- a/src/rendering/vulkan/system/vk_framebuffer.cpp +++ b/src/rendering/vulkan/system/vk_framebuffer.cpp @@ -620,8 +620,7 @@ void VulkanFrameBuffer::TextureFilterChanged() if (mSamplerManager) { // Destroy the texture descriptors as they used the old samplers - for (VkHardwareTexture *cur = VkHardwareTexture::First; cur; cur = cur->Next) - cur->ResetDescriptors(); + VkHardwareTexture::ResetAllDescriptors(); mSamplerManager->SetTextureFilterMode(); } @@ -630,8 +629,7 @@ void VulkanFrameBuffer::TextureFilterChanged() void VulkanFrameBuffer::StartPrecaching() { // Destroy the texture descriptors to avoid problems with potentially stale textures. - for (VkHardwareTexture *cur = VkHardwareTexture::First; cur; cur = cur->Next) - cur->ResetDescriptors(); + VkHardwareTexture::ResetAllDescriptors(); } void VulkanFrameBuffer::BlurScene(float amount) diff --git a/src/rendering/vulkan/textures/vk_hwtexture.cpp b/src/rendering/vulkan/textures/vk_hwtexture.cpp index 97a4198cc..13148eca1 100644 --- a/src/rendering/vulkan/textures/vk_hwtexture.cpp +++ b/src/rendering/vulkan/textures/vk_hwtexture.cpp @@ -82,6 +82,16 @@ void VkHardwareTexture::ResetDescriptors() mDescriptorSets.clear(); } +void VkHardwareTexture::ResetAllDescriptors() +{ + for (VkHardwareTexture *cur = First; cur; cur = cur->Next) + cur->ResetDescriptors(); + + auto fb = GetVulkanFrameBuffer(); + if (fb) + fb->GetRenderPassManager()->TextureSetPoolReset(); +} + void VkHardwareTexture::Precache(FMaterial *mat, int translation, int flags) { int numLayers = mat->GetLayers(); @@ -115,17 +125,16 @@ VulkanDescriptorSet *VkHardwareTexture::GetDescriptorSet(const FMaterialState &s if (set.descriptor && set.clampmode == clampmode && set.flags == flags) return set.descriptor.get(); } + int numLayers = mat->GetLayers(); + auto fb = GetVulkanFrameBuffer(); - auto descriptor = fb->GetRenderPassManager()->DescriptorPool->allocate(fb->GetRenderPassManager()->TextureSetLayout.get()); + auto descriptor = fb->GetRenderPassManager()->AllocateTextureDescriptorSet(numLayers); descriptor->SetDebugName("VkHardwareTexture.mDescriptorSets"); VulkanSampler *sampler = fb->GetSamplerManager()->Get(clampmode); - int numLayers = mat->GetLayers(); - //int maxTextures = 6; auto baseView = GetImageView(tex, translation, flags); - //numLayers = clamp(numLayers, 1, maxTextures); WriteDescriptors update; update.addCombinedImageSampler(descriptor.get(), 0, baseView, sampler, mImageLayout); diff --git a/src/rendering/vulkan/textures/vk_hwtexture.h b/src/rendering/vulkan/textures/vk_hwtexture.h index b2274f865..0334bbbda 100644 --- a/src/rendering/vulkan/textures/vk_hwtexture.h +++ b/src/rendering/vulkan/textures/vk_hwtexture.h @@ -24,7 +24,6 @@ public: ~VkHardwareTexture(); void Reset(); - void ResetDescriptors(); void Precache(FMaterial *mat, int translation, int flags); @@ -45,11 +44,7 @@ public: VulkanImage *GetImage(FTexture *tex, int translation, int flags); VulkanImageView *GetImageView(FTexture *tex, int translation, int flags); - static void ResetAllDescriptors() - { - for (VkHardwareTexture *cur = First; cur; cur = cur->Next) - cur->ResetDescriptors(); - } + static void ResetAllDescriptors(); private: void CreateImage(FTexture *tex, int translation, int flags); @@ -58,6 +53,8 @@ private: void GenerateMipmaps(VulkanImage *image, VulkanCommandBuffer *cmdbuffer); static int GetMipLevels(int w, int h); + void ResetDescriptors(); + struct DescriptorEntry { int clampmode; @@ -72,7 +69,6 @@ private: } }; - std::vector mDescriptorSets; std::unique_ptr mImage; std::unique_ptr mImageView;