Switch to using bindless textures for the entire hwrenderer

This commit is contained in:
Magnus Norddahl 2024-02-10 01:36:27 +01:00
commit 4fbb58d836
9 changed files with 30 additions and 166 deletions

View file

@ -130,17 +130,6 @@ void VkDescriptorSetManager::ResetHWTextureSets()
for (auto mat : Materials)
mat->DeleteDescriptors();
auto deleteList = fb->GetCommands()->DrawDeleteList.get();
for (auto& desc : Texture.Pools)
{
deleteList->Add(std::move(desc));
}
deleteList->Add(std::move(Texture.NullSet));
Texture.Pools.clear();
Texture.SetsLeft = 0;
Texture.DescriptorsLeft = 0;
Bindless.Writer = WriteDescriptors();
Bindless.NextIndex = 0;
@ -148,61 +137,6 @@ void VkDescriptorSetManager::ResetHWTextureSets()
AddBindlessTextureIndex(fb->GetTextureManager()->GetNullTextureView(), fb->GetSamplerManager()->Get(CLAMP_XY_NOMIP));
}
VulkanDescriptorSet* VkDescriptorSetManager::GetNullTextureSet()
{
if (!Texture.NullSet)
{
Texture.NullSet = AllocateTextureSet(SHADER_MIN_REQUIRED_TEXTURE_LAYERS);
WriteDescriptors update;
for (int i = 0; i < SHADER_MIN_REQUIRED_TEXTURE_LAYERS; i++)
{
update.AddCombinedImageSampler(Texture.NullSet.get(), i, fb->GetTextureManager()->GetNullTextureView(), fb->GetSamplerManager()->Get(CLAMP_XY_NOMIP), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
}
update.Execute(fb->GetDevice());
}
return Texture.NullSet.get();
}
std::unique_ptr<VulkanDescriptorSet> VkDescriptorSetManager::AllocateTextureSet(int numLayers)
{
if (Texture.SetsLeft == 0 || Texture.DescriptorsLeft < numLayers)
{
Texture.SetsLeft = 1000;
Texture.DescriptorsLeft = 2000;
Texture.Pools.push_back(DescriptorPoolBuilder()
.AddPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, Texture.DescriptorsLeft)
.MaxSets(Texture.SetsLeft)
.DebugName("VkDescriptorSetManager.Texture.Pool")
.Create(fb->GetDevice()));
}
Texture.SetsLeft--;
Texture.DescriptorsLeft -= numLayers;
return Texture.Pools.back()->allocate(GetTextureLayout(numLayers));
}
VulkanDescriptorSetLayout* VkDescriptorSetManager::GetTextureLayout(int numLayers)
{
if (Texture.Layouts.size() < (size_t)numLayers)
Texture.Layouts.resize(numLayers);
auto& layout = Texture.Layouts[numLayers - 1];
if (layout)
return layout.get();
DescriptorSetLayoutBuilder builder;
for (int i = 0; i < numLayers; i++)
{
builder.AddBinding(i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
}
builder.DebugName("VkDescriptorSetManager.Texture.SetLayout");
layout = builder.Create(fb->GetDevice());
return layout.get();
}
void VkDescriptorSetManager::AddMaterial(VkMaterial* texture)
{
texture->it = Materials.insert(Materials.end(), texture);

View file

@ -26,17 +26,13 @@ public:
VulkanDescriptorSetLayout* GetLevelMeshLayout() { return LevelMesh.Layout.get(); }
VulkanDescriptorSetLayout* GetRSBufferLayout() { return RSBuffer.Layout.get(); }
VulkanDescriptorSetLayout* GetFixedLayout() { return Fixed.Layout.get(); }
VulkanDescriptorSetLayout* GetTextureLayout(int numLayers);
VulkanDescriptorSetLayout* GetBindlessLayout() { return Bindless.Layout.get(); }
VulkanDescriptorSet* GetLevelMeshSet() { return LevelMesh.Set.get(); }
VulkanDescriptorSet* GetRSBufferSet() { return RSBuffer.Set.get(); }
VulkanDescriptorSet* GetFixedSet() { return Fixed.Set.get(); }
VulkanDescriptorSet* GetNullTextureSet();
VulkanDescriptorSet* GetBindlessSet() { return Bindless.Set.get(); }
std::unique_ptr<VulkanDescriptorSet> AllocateTextureSet(int numLayers);
VulkanDescriptorSet* GetInput(VkPPRenderPassSetup* passSetup, const TArray<PPTextureInput>& textures, bool bindShadowMapBuffers);
void AddMaterial(VkMaterial* texture);
@ -89,15 +85,6 @@ private:
int NextIndex = 0;
} Bindless;
struct
{
std::vector<std::unique_ptr<VulkanDescriptorSetLayout>> Layouts;
int SetsLeft = 0;
int DescriptorsLeft = 0;
std::vector<std::unique_ptr<VulkanDescriptorPool>> Pools;
std::unique_ptr<VulkanDescriptorSet> NullSet;
} Texture;
struct
{
std::unique_ptr<VulkanDescriptorPool> Pool;

View file

@ -142,10 +142,7 @@ VulkanPipelineLayout* VkRenderPassManager::GetPipelineLayout(int numLayers, bool
PipelineLayoutBuilder builder;
builder.AddSetLayout(descriptors->GetFixedLayout());
builder.AddSetLayout(levelmesh ? descriptors->GetLevelMeshLayout() : descriptors->GetRSBufferLayout());
if (levelmesh)
builder.AddSetLayout(descriptors->GetBindlessLayout());
else if (numLayers != 0)
builder.AddSetLayout(descriptors->GetTextureLayout(numLayers));
builder.AddSetLayout(descriptors->GetBindlessLayout());
builder.AddPushConstantRange(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstants));
builder.DebugName("VkRenderPassManager.PipelineLayout");
layout = builder.Create(fb->GetDevice());

View file

@ -315,20 +315,7 @@ VkMaterial::~VkMaterial()
void VkMaterial::DeleteDescriptors()
{
if (fb)
{
auto deleteList = fb->GetCommands()->DrawDeleteList.get();
for (auto& it : mDescriptorSets)
{
deleteList->Add(std::move(it.descriptor));
}
mDescriptorSets.clear();
}
}
VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state)
{
return GetDescriptorEntry(state).descriptor.get();
mDescriptorSets.clear();
}
int VkMaterial::GetBindlessIndex(const FMaterialState& state)
@ -347,24 +334,16 @@ VkMaterial::DescriptorEntry& VkMaterial::GetDescriptorEntry(const FMaterialState
for (auto& set : mDescriptorSets)
{
if (set.descriptor && set.clampmode == clampmode && set.remap == translationp) return set;
if (set.clampmode == clampmode && set.remap == translationp) return set;
}
int numLayers = NumLayers();
auto descriptors = fb->GetDescriptorSetManager();
auto descriptor = descriptors->AllocateTextureSet(max(numLayers, SHADER_MIN_REQUIRED_TEXTURE_LAYERS));
descriptor->SetDebugName("VkHardwareTexture.mDescriptorSets");
auto* sampler = fb->GetSamplerManager()->Get(clampmode);
WriteDescriptors update;
MaterialLayerInfo *layer;
auto systex = static_cast<VkHardwareTexture*>(GetLayer(0, state.mTranslation, &layer));
auto systeximage = systex->GetImage(layer->layerTexture, state.mTranslation, layer->scaleFlags);
update.AddCombinedImageSampler(descriptor.get(), 0, systeximage->View.get(), fb->GetSamplerManager()->Get(GetLayerFilter(0), clampmode), systeximage->Layout);
int bindlessIndex = descriptors->AddBindlessTextureIndex(systeximage->View.get(), fb->GetSamplerManager()->Get(GetLayerFilter(0), clampmode));
if (!(layer->scaleFlags & CTF_Indexed))
@ -373,8 +352,6 @@ VkMaterial::DescriptorEntry& VkMaterial::GetDescriptorEntry(const FMaterialState
{
auto syslayer = static_cast<VkHardwareTexture*>(GetLayer(i, 0, &layer));
auto syslayerimage = syslayer->GetImage(layer->layerTexture, 0, layer->scaleFlags);
update.AddCombinedImageSampler(descriptor.get(), i, syslayerimage->View.get(), fb->GetSamplerManager()->Get(GetLayerFilter(i), clampmode), syslayerimage->Layout);
descriptors->AddBindlessTextureIndex(syslayerimage->View.get(), fb->GetSamplerManager()->Get(GetLayerFilter(i), clampmode));
}
}
@ -384,20 +361,11 @@ VkMaterial::DescriptorEntry& VkMaterial::GetDescriptorEntry(const FMaterialState
{
auto syslayer = static_cast<VkHardwareTexture*>(GetLayer(i, translation, &layer));
auto syslayerimage = syslayer->GetImage(layer->layerTexture, 0, layer->scaleFlags);
update.AddCombinedImageSampler(descriptor.get(), i, syslayerimage->View.get(), fb->GetSamplerManager()->Get(GetLayerFilter(i), clampmode), syslayerimage->Layout);
descriptors->AddBindlessTextureIndex(syslayerimage->View.get(), fb->GetSamplerManager()->Get(GetLayerFilter(i), clampmode));
}
numLayers = 3;
}
auto dummyImage = fb->GetTextureManager()->GetNullTextureView();
for (int i = numLayers; i < SHADER_MIN_REQUIRED_TEXTURE_LAYERS; i++)
{
update.AddCombinedImageSampler(descriptor.get(), i, dummyImage, sampler, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
}
update.Execute(fb->GetDevice());
mDescriptorSets.emplace_back(clampmode, translationp, std::move(descriptor), bindlessIndex);
mDescriptorSets.emplace_back(clampmode, translationp, bindlessIndex);
return mDescriptorSets.back();
}

View file

@ -70,7 +70,6 @@ public:
VulkanRenderDevice* fb = nullptr;
std::list<VkMaterial*>::iterator it;
VulkanDescriptorSet* GetDescriptorSet(const FMaterialState& state);
int GetBindlessIndex(const FMaterialState& state);
private:
@ -78,14 +77,12 @@ private:
{
int clampmode;
intptr_t remap;
std::unique_ptr<VulkanDescriptorSet> descriptor;
int bindlessIndex;
DescriptorEntry(int cm, intptr_t f, std::unique_ptr<VulkanDescriptorSet>&& d, int index)
DescriptorEntry(int cm, intptr_t f, int index)
{
clampmode = cm;
remap = f;
descriptor = std::move(d);
bindlessIndex = index;
}
};

View file

@ -205,7 +205,6 @@ void VkRenderState::Apply(int dt)
ApplyPushConstants();
ApplyVertexBuffers();
ApplyBufferSets();
ApplyMaterial();
mNeedApply = false;
drawcalls.Unclock();
@ -404,10 +403,22 @@ void VkRenderState::ApplySurfaceUniforms()
else
mSurfaceUniforms.timer = 0.0f;
if (mMaterial.mMaterial)
if (mMaterial.mChanged)
{
auto source = mMaterial.mMaterial->Source();
mSurfaceUniforms.uSpecularMaterial = { source->GetGlossiness(), source->GetSpecularLevel() };
if (mMaterial.mMaterial)
{
auto source = mMaterial.mMaterial->Source();
if (source->isHardwareCanvas())
static_cast<FCanvasTexture*>(source->GetTexture())->NeedUpdate();
mSurfaceUniforms.uTextureIndex = static_cast<VkMaterial*>(mMaterial.mMaterial)->GetBindlessIndex(mMaterial);
mSurfaceUniforms.uSpecularMaterial = { source->GetGlossiness(), source->GetSpecularLevel() };
}
else
{
mSurfaceUniforms.uTextureIndex = 0;
}
mMaterial.mChanged = false;
}
if (!mRSBuffers->SurfaceUniformsBuffer->Write(mSurfaceUniforms))
@ -481,24 +492,6 @@ void VkRenderState::ApplyVertexBuffers()
}
}
void VkRenderState::ApplyMaterial()
{
if (mMaterial.mChanged)
{
auto descriptors = fb->GetDescriptorSetManager();
VulkanPipelineLayout* layout = fb->GetRenderPassManager()->GetPipelineLayout(mPipelineKey.NumTextureLayers, mPipelineKey.ShaderKey.UseLevelMesh);
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->GetNullTextureSet();
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptors->GetFixedSet());
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 2, descriptorset);
mMaterial.mChanged = false;
}
}
void VkRenderState::ApplyBufferSets()
{
uint32_t matrixOffset = mRSBuffers->MatrixBuffer->Offset();
@ -513,6 +506,7 @@ void VkRenderState::ApplyBufferSets()
uint32_t offsets[5] = { mViewpointOffset, matrixOffset, surfaceUniformsOffset, lightsOffset, fogballsOffset };
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptors->GetFixedSet());
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 1, descriptors->GetRSBufferSet(), 5, offsets);
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 2, descriptors->GetBindlessSet());
mLastViewpointOffset = mViewpointOffset;
mLastMatricesOffset = matrixOffset;

View file

@ -84,7 +84,6 @@ protected:
void ApplyPushConstants();
void ApplyBufferSets();
void ApplyVertexBuffers();
void ApplyMaterial();
void BeginRenderPass(VulkanCommandBuffer *cmdbuffer);
void WaitForStreamBuffers();

View file

@ -1,6 +1,4 @@
#ifdef USE_LEVELMESH
layout(set = 2, binding = 0) uniform sampler2D textures[];
#define tex 0
@ -14,20 +12,12 @@ layout(set = 2, binding = 0) uniform sampler2D textures[];
#define texture9 8
#define texture10 9
#define texture11 10
#else
// textures
layout(set = 2, binding = 0) uniform sampler2D tex;
layout(set = 2, binding = 1) uniform sampler2D texture2;
layout(set = 2, binding = 2) uniform sampler2D texture3;
layout(set = 2, binding = 3) uniform sampler2D texture4;
layout(set = 2, binding = 4) uniform sampler2D texture5;
layout(set = 2, binding = 5) uniform sampler2D texture6;
layout(set = 2, binding = 6) uniform sampler2D texture7;
layout(set = 2, binding = 7) uniform sampler2D texture8;
layout(set = 2, binding = 8) uniform sampler2D texture9;
layout(set = 2, binding = 9) uniform sampler2D texture10;
layout(set = 2, binding = 10) uniform sampler2D texture11;
#endif
#define texture12 11
#define texture13 12
#define texture14 13
#define texture15 14
#define texture16 15
#define texture17 16
#define texture18 17
#define texture19 18
#define texture20 19

View file

@ -26,9 +26,7 @@ layout(location=1) out vec4 FragFog;
layout(location=2) out vec4 FragNormal;
#endif
#if defined(USE_LEVELMESH)
vec4 texture(int index, vec2 p)
{
return texture(textures[uTextureIndex + index], p);
}
#endif