Make VkMaterial::GetDescriptorSet thread safe

This commit is contained in:
Magnus Norddahl 2023-05-17 19:08:57 +02:00 committed by Christoph Oelckers
parent 6ba64b8e2f
commit c06123e040
3 changed files with 35 additions and 3 deletions

View file

@ -304,6 +304,7 @@ void VkHardwareTexture::CreateWipeTexture(int w, int h, const char *name)
VkMaterial::VkMaterial(VulkanRenderDevice* fb, FGameTexture* tex, int scaleflags) : FMaterial(tex, scaleflags), fb(fb)
{
mThreadDescriptorSets.resize(fb->MaxThreads);
fb->GetDescriptorSetManager()->AddMaterial(this);
}
@ -323,6 +324,9 @@ void VkMaterial::DeleteDescriptors()
deleteList->Add(std::move(it.descriptor));
}
mDescriptorSets.clear();
for (auto& list : mThreadDescriptorSets)
list.clear();
}
}
@ -385,3 +389,19 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state)
return mDescriptorSets.back().descriptor.get();
}
VulkanDescriptorSet* VkMaterial::GetDescriptorSet(int threadIndex, const FMaterialState& state)
{
int clampmode = Source()->GetClampMode(state.mClampMode);
int translation = state.mTranslation;
auto translationp = IsLuminosityTranslation(translation) ? translation : intptr_t(GPalette.GetTranslation(GetTranslationType(translation), GetTranslationIndex(translation)));
for (auto& set : mThreadDescriptorSets[threadIndex])
{
if (set.descriptor && set.clampmode == clampmode && set.remap == translationp)
return set.descriptor;
}
std::unique_lock<std::mutex> lock(fb->ThreadMutex);
VulkanDescriptorSet* descriptorset = GetDescriptorSet(state);
mThreadDescriptorSets[threadIndex].push_back(ThreadDescriptorEntry(clampmode, translationp, descriptorset));
return descriptorset;
}

View file

@ -65,14 +65,16 @@ public:
VkMaterial(VulkanRenderDevice* fb, FGameTexture* tex, int scaleflags);
~VkMaterial();
VulkanDescriptorSet* GetDescriptorSet(const FMaterialState& state);
void DeleteDescriptors() override;
VulkanRenderDevice* fb = nullptr;
std::list<VkMaterial*>::iterator it;
VulkanDescriptorSet* GetDescriptorSet(int threadIndex, const FMaterialState& state);
private:
VulkanDescriptorSet* GetDescriptorSet(const FMaterialState& state);
struct DescriptorEntry
{
int clampmode;
@ -87,5 +89,15 @@ private:
}
};
struct ThreadDescriptorEntry
{
int clampmode;
intptr_t remap;
VulkanDescriptorSet* descriptor;
ThreadDescriptorEntry(int cm, intptr_t f, VulkanDescriptorSet* d) : clampmode(cm), remap(f), descriptor(d) { }
};
std::vector<DescriptorEntry> mDescriptorSets;
std::vector<std::vector<ThreadDescriptorEntry>> mThreadDescriptorSets;
};

View file

@ -486,7 +486,7 @@ void VkRenderState::ApplyMaterial()
if (mMaterial.mMaterial && mMaterial.mMaterial->Source()->isHardwareCanvas())
static_cast<FCanvasTexture*>(mMaterial.mMaterial->Source()->GetTexture())->NeedUpdate();
VulkanDescriptorSet* descriptorset = mMaterial.mMaterial ? static_cast<VkMaterial*>(mMaterial.mMaterial)->GetDescriptorSet(mMaterial) : descriptors->GetNullTextureDescriptorSet();
VulkanDescriptorSet* descriptorset = mMaterial.mMaterial ? static_cast<VkMaterial*>(mMaterial.mMaterial)->GetDescriptorSet(threadIndex, mMaterial) : descriptors->GetNullTextureDescriptorSet();
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptors->GetFixedDescriptorSet());
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 2, descriptorset);