From 4d768e5a491cbd638ed72318d5b82866d91f776e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 21 Mar 2019 23:41:24 +0100 Subject: [PATCH] - use a vector instead of a map to store a texture's descriptor sets. In this case a map is total overkill and its poor memory locality will always incur some performance hit. A vector here can only collect a very small amount of entries so the time to search is nearly irrelevant. --- .../vulkan/textures/vk_hwtexture.cpp | 58 ++++++++++--------- src/rendering/vulkan/textures/vk_hwtexture.h | 13 ++++- 2 files changed, 41 insertions(+), 30 deletions(-) diff --git a/src/rendering/vulkan/textures/vk_hwtexture.cpp b/src/rendering/vulkan/textures/vk_hwtexture.cpp index e7e2c58e6..45591e9c4 100644 --- a/src/rendering/vulkan/textures/vk_hwtexture.cpp +++ b/src/rendering/vulkan/textures/vk_hwtexture.cpp @@ -57,6 +57,12 @@ VkHardwareTexture::~VkHardwareTexture() if (fb) { auto &deleteList = fb->FrameDeleteList; + for (auto &it : mDescriptorSets) + { + deleteList.Descriptors.push_back(std::move(it.descriptor)); + it.descriptor = nullptr; + } + mDescriptorSets.clear(); if (mImage) deleteList.Images.push_back(std::move(mImage)); if (mImageView) deleteList.ImageViews.push_back(std::move(mImageView)); if (mStagingBuffer) deleteList.Buffers.push_back(std::move(mStagingBuffer)); @@ -104,36 +110,34 @@ VulkanDescriptorSet *VkHardwareTexture::GetDescriptorSet(const FMaterialState &s if (tex->isHardwareCanvas()) static_cast(tex)->NeedUpdate(); - DescriptorKey key; - key.clampmode = clampmode; - key.flags = flags; - auto &descriptorSet = mDescriptorSets[key]; - if (!descriptorSet) + for (auto &set : mDescriptorSets) { - auto fb = GetVulkanFrameBuffer(); - - descriptorSet = fb->GetRenderPassManager()->DescriptorPool->allocate(fb->GetRenderPassManager()->TextureSetLayout.get()); - descriptorSet->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(descriptorSet.get(), 0, baseView, sampler, mImageLayout); - for (int i = 1; i < numLayers; i++) - { - FTexture *layer; - auto systex = static_cast(mat->GetLayer(i, 0, &layer)); - update.addCombinedImageSampler(descriptorSet.get(), i, systex->GetImageView(layer, 0, mat->isExpanded() ? CTF_Expand : 0), sampler, systex->mImageLayout); - } - update.updateSets(fb->device); + if (set.descriptor && set.clampmode == clampmode && set.flags == flags) return set.descriptor.get(); } - return descriptorSet.get(); + auto fb = GetVulkanFrameBuffer(); + auto descriptor = fb->GetRenderPassManager()->DescriptorPool->allocate(fb->GetRenderPassManager()->TextureSetLayout.get()); + + 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); + for (int i = 1; i < numLayers; i++) + { + FTexture *layer; + auto systex = static_cast(mat->GetLayer(i, 0, &layer)); + update.addCombinedImageSampler(descriptor.get(), i, systex->GetImageView(layer, 0, mat->isExpanded() ? CTF_Expand : 0), sampler, systex->mImageLayout); + } + update.updateSets(fb->device); + mDescriptorSets.emplace_back(clampmode, flags, std::move(descriptor)); + return mDescriptorSets.back().descriptor.get(); } VulkanImage *VkHardwareTexture::GetImage(FTexture *tex, int translation, int flags) diff --git a/src/rendering/vulkan/textures/vk_hwtexture.h b/src/rendering/vulkan/textures/vk_hwtexture.h index d269b2a29..b2274f865 100644 --- a/src/rendering/vulkan/textures/vk_hwtexture.h +++ b/src/rendering/vulkan/textures/vk_hwtexture.h @@ -58,15 +58,22 @@ private: void GenerateMipmaps(VulkanImage *image, VulkanCommandBuffer *cmdbuffer); static int GetMipLevels(int w, int h); - struct DescriptorKey + struct DescriptorEntry { int clampmode; int flags; + std::unique_ptr descriptor; - bool operator<(const DescriptorKey &other) const { return memcmp(this, &other, sizeof(DescriptorKey)) < 0; } + DescriptorEntry(int cm, int f, std::unique_ptr &&d) + { + clampmode = cm; + flags = f; + descriptor = std::move(d); + } }; - std::map> mDescriptorSets; + + std::vector mDescriptorSets; std::unique_ptr mImage; std::unique_ptr mImageView; std::unique_ptr mStagingBuffer;