- 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.
This commit is contained in:
Christoph Oelckers 2019-03-21 23:41:24 +01:00
parent 3ad9783d8f
commit 4d768e5a49
2 changed files with 41 additions and 30 deletions

View file

@ -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,16 +110,15 @@ VulkanDescriptorSet *VkHardwareTexture::GetDescriptorSet(const FMaterialState &s
if (tex->isHardwareCanvas()) static_cast<FCanvasTexture*>(tex)->NeedUpdate();
DescriptorKey key;
key.clampmode = clampmode;
key.flags = flags;
auto &descriptorSet = mDescriptorSets[key];
if (!descriptorSet)
for (auto &set : mDescriptorSets)
{
auto fb = GetVulkanFrameBuffer();
if (set.descriptor && set.clampmode == clampmode && set.flags == flags) return set.descriptor.get();
}
descriptorSet = fb->GetRenderPassManager()->DescriptorPool->allocate(fb->GetRenderPassManager()->TextureSetLayout.get());
descriptorSet->SetDebugName("VkHardwareTexture.mDescriptorSets");
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();
@ -123,17 +128,16 @@ VulkanDescriptorSet *VkHardwareTexture::GetDescriptorSet(const FMaterialState &s
//numLayers = clamp(numLayers, 1, maxTextures);
WriteDescriptors update;
update.addCombinedImageSampler(descriptorSet.get(), 0, baseView, sampler, mImageLayout);
update.addCombinedImageSampler(descriptor.get(), 0, baseView, sampler, mImageLayout);
for (int i = 1; i < numLayers; i++)
{
FTexture *layer;
auto systex = static_cast<VkHardwareTexture*>(mat->GetLayer(i, 0, &layer));
update.addCombinedImageSampler(descriptorSet.get(), i, systex->GetImageView(layer, 0, mat->isExpanded() ? CTF_Expand : 0), sampler, systex->mImageLayout);
update.addCombinedImageSampler(descriptor.get(), i, systex->GetImageView(layer, 0, mat->isExpanded() ? CTF_Expand : 0), sampler, systex->mImageLayout);
}
update.updateSets(fb->device);
}
return descriptorSet.get();
mDescriptorSets.emplace_back(clampmode, flags, std::move(descriptor));
return mDescriptorSets.back().descriptor.get();
}
VulkanImage *VkHardwareTexture::GetImage(FTexture *tex, int translation, int flags)

View file

@ -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<VulkanDescriptorSet> descriptor;
bool operator<(const DescriptorKey &other) const { return memcmp(this, &other, sizeof(DescriptorKey)) < 0; }
DescriptorEntry(int cm, int f, std::unique_ptr<VulkanDescriptorSet> &&d)
{
clampmode = cm;
flags = f;
descriptor = std::move(d);
}
};
std::map<DescriptorKey, std::unique_ptr<VulkanDescriptorSet>> mDescriptorSets;
std::vector<DescriptorEntry> mDescriptorSets;
std::unique_ptr<VulkanImage> mImage;
std::unique_ptr<VulkanImageView> mImageView;
std::unique_ptr<VulkanBuffer> mStagingBuffer;