Add generalized shader code

This commit is contained in:
Magnus Norddahl 2025-04-03 01:23:06 +02:00
commit bb4d4f1bc0
6 changed files with 103 additions and 71 deletions

View file

@ -276,13 +276,20 @@ VulkanRenderPass *VkRenderPassSetup::GetRenderPass(int clearTargets)
VulkanPipeline *VkRenderPassSetup::GetPipeline(const VkPipelineKey &key, UniformStructHolder &Uniforms)
{
auto item = Pipelines.find(key);
if (item == Pipelines.end())
// To do:
// Build the generalized pipelines in the VkRenderPassSetup constructor
// Then build the specialized ones on a worker thread
#if 0 // generalized lookup
VkPipelineKey gkey = key;
gkey.ShaderKey.AsQWORD = 0;
auto item = GeneralizedPipelines.find(gkey);
if (item == GeneralizedPipelines.end())
{
Uniforms.Clear();
auto pipeline = CreatePipeline(key, Uniforms);
auto pipeline = CreatePipeline(gkey, true, Uniforms);
auto ptr = pipeline.get();
Pipelines.insert(std::pair<VkPipelineKey, PipelineData>{key, PipelineData{std::move(pipeline), Uniforms}});
GeneralizedPipelines.insert(std::pair<VkPipelineKey, PipelineData>{gkey, PipelineData{ std::move(pipeline), Uniforms }});
return ptr;
}
else
@ -290,16 +297,33 @@ VulkanPipeline *VkRenderPassSetup::GetPipeline(const VkPipelineKey &key, Uniform
Uniforms = item->second.Uniforms;
return item->second.pipeline.get();
}
#else // specialized lookup
auto item = SpecializedPipelines.find(key);
if (item == SpecializedPipelines.end())
{
auto pipeline = CreatePipeline(key, false, Uniforms);
auto ptr = pipeline.get();
SpecializedPipelines.insert(std::pair<VkPipelineKey, PipelineData>{key, PipelineData{std::move(pipeline), Uniforms}});
return ptr;
}
else
{
Uniforms = item->second.Uniforms;
return item->second.pipeline.get();
}
#endif
}
std::unique_ptr<VulkanPipeline> VkRenderPassSetup::CreatePipeline(const VkPipelineKey &key, UniformStructHolder &Uniforms)
std::unique_ptr<VulkanPipeline> VkRenderPassSetup::CreatePipeline(const VkPipelineKey &key, bool isUberShader, UniformStructHolder &Uniforms)
{
Uniforms.Clear();
GraphicsPipelineBuilder builder;
builder.Cache(fb->GetRenderPassManager()->GetCache());
builder.PolygonMode(key.DrawLine ? VK_POLYGON_MODE_LINE : VK_POLYGON_MODE_FILL);
VkShaderProgram *program = fb->GetShaderManager()->Get(key.ShaderKey);
VkShaderProgram *program = fb->GetShaderManager()->Get(key.ShaderKey, isUberShader);
builder.AddVertexShader(program->vert.get());
builder.AddConstant(0, (uint32_t)key.ShaderKey.AsQWORD);
builder.AddConstant(1, (uint32_t)(key.ShaderKey.AsQWORD >> 32));
@ -374,7 +398,7 @@ std::unique_ptr<VulkanPipeline> VkRenderPassSetup::CreatePipeline(const VkPipeli
builder.RasterizationSamples((VkSampleCountFlagBits)PassKey.Samples);
builder.Layout(fb->GetRenderPassManager()->GetPipelineLayout(key.ShaderKey.UseLevelMesh, program->Uniforms.sz));
builder.Layout(fb->GetRenderPassManager()->GetPipelineLayout(key.ShaderKey.Layout.UseLevelMesh, program->Uniforms.sz));
builder.RenderPass(GetRenderPass(0));
builder.DebugName("VkRenderPassSetup.Pipeline");

View file

@ -86,11 +86,12 @@ public:
VkRenderPassKey PassKey;
std::unique_ptr<VulkanRenderPass> RenderPasses[8];
std::map<VkPipelineKey, PipelineData> Pipelines;
std::map<VkPipelineKey, PipelineData> GeneralizedPipelines;
std::map<VkPipelineKey, PipelineData> SpecializedPipelines;
private:
std::unique_ptr<VulkanRenderPass> CreateRenderPass(int clearTargets);
std::unique_ptr<VulkanPipeline> CreatePipeline(const VkPipelineKey &key, UniformStructHolder &Uniforms);
std::unique_ptr<VulkanPipeline> CreatePipeline(const VkPipelineKey &key, bool isUberShader, UniformStructHolder &Uniforms);
VulkanRenderDevice* fb = nullptr;
};

View file

@ -91,9 +91,9 @@ void VkShaderManager::Deinit()
RemoveVkPPShader(PPShaders.back());
}
VkShaderProgram* VkShaderManager::Get(const VkShaderKey& key)
VkShaderProgram* VkShaderManager::Get(const VkShaderKey& key, bool isUberShader)
{
auto& program = programs[key];
VkShaderProgram& program = isUberShader ? specialized[key] : generic[key.Layout.AsDWORD];
if (program.frag)
return &program;
@ -124,12 +124,12 @@ VkShaderProgram* VkShaderManager::Get(const VkShaderKey& key)
};
VkShaderKey customKey = key;
customKey.AlphaTest = false;
customKey.Layout.AlphaTest = false;
const auto& desc = effectshaders[key.SpecialEffect];
program.vert = LoadVertShader(desc.ShaderName, mainvp, nullptr, desc.defines, key, nullptr);
program.vert = LoadVertShader(desc.ShaderName, mainvp, nullptr, desc.defines, key, nullptr, isUberShader);
if (!key.NoFragmentShader)
program.frag = LoadFragShader(desc.ShaderName, desc.fp1, desc.fp2, desc.fp3, desc.fp4, desc.fp5, desc.defines, key, nullptr);
program.frag = LoadFragShader(desc.ShaderName, desc.fp1, desc.fp2, desc.fp3, desc.fp4, desc.fp5, desc.defines, key, nullptr, isUberShader);
}
else
{
@ -167,9 +167,9 @@ VkShaderProgram* VkShaderManager::Get(const VkShaderKey& key)
if (key.EffectState < FIRST_USER_SHADER)
{
const auto& desc = defaultshaders[key.EffectState];
program.vert = LoadVertShader(desc.ShaderName, mainvp, nullptr, desc.Defines, key, nullptr);
program.vert = LoadVertShader(desc.ShaderName, mainvp, nullptr, desc.Defines, key, nullptr, isUberShader);
if (!key.NoFragmentShader)
program.frag = LoadFragShader(desc.ShaderName, mainfp, desc.material_lump, desc.mateffect_lump, desc.lightmodel_lump_shared, desc.lightmodel_lump, desc.Defines, key, nullptr);
program.frag = LoadFragShader(desc.ShaderName, mainfp, desc.material_lump, desc.mateffect_lump, desc.lightmodel_lump_shared, desc.lightmodel_lump, desc.Defines, key, nullptr, isUberShader);
}
else
{
@ -177,9 +177,9 @@ VkShaderProgram* VkShaderManager::Get(const VkShaderKey& key)
const FString& name = ExtractFileBase(desc.shader.GetChars());
FString defines = defaultshaders[desc.shaderType].Defines + desc.defines;
program.vert = LoadVertShader(name, mainvp, desc.vertshader.IsEmpty() ? nullptr : desc.vertshader.GetChars(), defines.GetChars(), key, &desc);
program.vert = LoadVertShader(name, mainvp, desc.vertshader.IsEmpty() ? nullptr : desc.vertshader.GetChars(), defines.GetChars(), key, &desc, isUberShader);
if (!key.NoFragmentShader)
program.frag = LoadFragShader(name, mainfp, desc.shader.GetChars(), defaultshaders[desc.shaderType].mateffect_lump, defaultshaders[desc.shaderType].lightmodel_lump_shared, defaultshaders[desc.shaderType].lightmodel_lump, defines.GetChars(), key, &desc);
program.frag = LoadFragShader(name, mainfp, desc.shader.GetChars(), defaultshaders[desc.shaderType].mateffect_lump, defaultshaders[desc.shaderType].lightmodel_lump_shared, defaultshaders[desc.shaderType].lightmodel_lump, defines.GetChars(), key, &desc, isUberShader);
desc.Uniforms.WriteUniforms(program.Uniforms);
}
@ -265,19 +265,19 @@ static void AddBuiltinFields(FString &layoutBlock, int &index, bool is_in, const
switch(field.cond)
{
case FieldCondition::NOTSIMPLE:
if(key.Simple) continue;
if(key.Layout.Simple) continue;
break;
case FieldCondition::HAS_CLIPDISTANCE:
if(!hasClipDistance) continue;
break;
case FieldCondition::GBUFFER_PASS:
if(!key.GBufferPass) continue;
if(!key.Layout.GBufferPass) continue;
break;
case FieldCondition::USELEVELMESH:
if(!key.UseLevelMesh) continue;
if(!key.Layout.UseLevelMesh) continue;
break;
case FieldCondition::SHADE_VERTEX:
if(!key.ShadeVertex) continue;
if(!key.Layout.ShadeVertex) continue;
break;
default:
break;
@ -295,7 +295,7 @@ void VkShaderManager::BuildLayoutBlock(FString &layoutBlock, bool isFrag, const
layoutBlock << "// This must match the PushConstants struct\n";
layoutBlock << "layout(push_constant) uniform PushConstants\n";
layoutBlock << "{\n";
if (key.UseLevelMesh)
if (key.Layout.UseLevelMesh)
{
layoutBlock << " int unused0;\n";
layoutBlock << " int unused1;\n";
@ -393,23 +393,15 @@ void VkShaderManager::BuildDefinesBlock(FString &definesBlock, const char *defin
// Controls layout and has to be defines:
if (key.AlphaTest) definesBlock << "#define DO_ALPHATEST\n";
if (key.Simple) definesBlock << "#define SIMPLE\n";
if (key.Simple3D) definesBlock << "#define SIMPLE3D\n";
if (key.GBufferPass) definesBlock << "#define GBUFFER_PASS\n";
if (key.UseLevelMesh) definesBlock << "#define USE_LEVELMESH\n";
if (key.ShadeVertex) definesBlock << "#define SHADE_VERTEX\n";
if (key.Layout.AlphaTest) definesBlock << "#define DO_ALPHATEST\n";
if (key.Layout.Simple) definesBlock << "#define SIMPLE\n";
if (key.Layout.Simple3D) definesBlock << "#define SIMPLE3D\n";
if (key.Layout.GBufferPass) definesBlock << "#define GBUFFER_PASS\n";
if (key.Layout.UseLevelMesh) definesBlock << "#define USE_LEVELMESH\n";
if (key.Layout.ShadeVertex) definesBlock << "#define SHADE_VERTEX\n";
// We could move this to shaders/shaderkey.glsl as its always the same:
// Should we define these anyway for completeness?
// definesBlock << "#define DO_ALPHATEST ((uShaderKey1 & SK1_ALPHATEST) != 0)\n";
// definesBlock << "#define SIMPLE ((uShaderKey1 & SK1_SIMPLE) != 0)\n";
// definesBlock << "#define SIMPLE3D ((uShaderKey1 & SK1_SIMPLE3D) != 0)\n";
// definesBlock << "#define GBUFFER_PASS ((uShaderKey1 & SK1_GBUFFER_PASS) != 0)\n";
// definesBlock << "#define USE_LEVELMESH (!!(uShaderKey1 & SK1_USE_LEVELMESH))\n";
// definesBlock << "#define SHADE_VERTEX ((uShaderKey2 & SK2_SHADE_VERTEX) != 0)\n";
definesBlock << "#define SIMPLE2D ((uShaderKey1 & SK1_SIMPLE2D) != 0)\n";
definesBlock << "#define TM_STENCIL (SK_GET_TEXTUREMODE() == SK1_TM_STENCIL)\n";
@ -476,13 +468,13 @@ void VkShaderManager::BuildDefinesBlock(FString &definesBlock, const char *defin
}
}
std::unique_ptr<VulkanShader> VkShaderManager::LoadVertShader(FString shadername, const char *vert_lump, const char *vert_lump_custom, const char *defines, const VkShaderKey& key, const UserShaderDesc *shader)
std::unique_ptr<VulkanShader> VkShaderManager::LoadVertShader(FString shadername, const char *vert_lump, const char *vert_lump_custom, const char *defines, const VkShaderKey& key, const UserShaderDesc *shader, bool isUberShader)
{
FString definesBlock;
BuildDefinesBlock(definesBlock, defines, false, key, shader);
FString layoutBlock;
BuildLayoutBlock(layoutBlock, false, key, shader);
BuildLayoutBlock(layoutBlock, false, key, shader, isUberShader);
FString codeBlock;
codeBlock << LoadPrivateShaderLump(vert_lump).GetChars() << "\n";
@ -509,13 +501,13 @@ std::unique_ptr<VulkanShader> VkShaderManager::LoadVertShader(FString shadername
.Create(shadername.GetChars(), fb->GetDevice());
}
std::unique_ptr<VulkanShader> VkShaderManager::LoadFragShader(FString shadername, const char *frag_lump, const char *material_lump, const char* mateffect_lump, const char *light_lump_shared, const char *light_lump, const char *defines, const VkShaderKey& key, const UserShaderDesc *shader)
std::unique_ptr<VulkanShader> VkShaderManager::LoadFragShader(FString shadername, const char *frag_lump, const char *material_lump, const char* mateffect_lump, const char *light_lump_shared, const char *light_lump, const char *defines, const VkShaderKey& key, const UserShaderDesc *shader, bool isUberShader)
{
FString definesBlock;
BuildDefinesBlock(definesBlock, defines, true, key, shader);
FString layoutBlock;
BuildLayoutBlock(layoutBlock, true, key, shader);
BuildLayoutBlock(layoutBlock, true, key, shader, isUberShader);
FString codeBlock;
codeBlock << LoadPrivateShaderLump(frag_lump).GetChars() << "\n";

View file

@ -81,16 +81,16 @@ public:
{
struct
{
uint64_t AlphaTest : 1; // !NO_ALPHATEST
uint64_t Simple : 1; // SIMPLE
uint64_t Unused0 : 1;
uint64_t Unused1 : 1;
uint64_t Simple2D : 1; // SIMPLE2D, uFogEnabled == -3
uint64_t Simple3D : 1; // SIMPLE3D
uint64_t Unused2 : 1;
uint64_t TextureMode : 3; // uTextureMode & 0xffff
uint64_t ClampY : 1; // uTextureMode & TEXF_ClampY
uint64_t Brightmap : 1; // uTextureMode & TEXF_Brightmap
uint64_t Detailmap : 1; // uTextureMode & TEXF_Detailmap
uint64_t Glowmap : 1; // uTextureMode & TEXF_Glowmap
uint64_t GBufferPass : 1; // GBUFFER_PASS
uint64_t Unused3 : 1;
uint64_t UseShadowmap : 1; // USE_SHADOWMAP
uint64_t UseRaytrace : 1; // USE_RAYTRACE
uint64_t UseRaytracePrecise : 1; // USE_RAYTRACE_PRECISE
@ -104,12 +104,12 @@ public:
uint64_t LightMode : 2; // LIGHTMODE_DEFAULT, LIGHTMODE_SOFTWARE, LIGHTMODE_VANILLA, LIGHTMODE_BUILD
uint64_t LightBlendMode : 2; // LIGHT_BLEND_CLAMPED , LIGHT_BLEND_COLORED_CLAMP , LIGHT_BLEND_UNCLAMPED
uint64_t LightAttenuationMode : 1; // LIGHT_ATTENUATION_LINEAR , LIGHT_ATTENUATION_INVERSE_SQUARE
uint64_t UseLevelMesh : 1; // USE_LEVELMESH
uint64_t Unused4: 1;
uint64_t FogBalls : 1; // FOGBALLS
uint64_t NoFragmentShader : 1;
uint64_t DepthFadeThreshold : 1;
uint64_t AlphaTestOnly : 1; // ALPHATEST_ONLY
uint64_t ShadeVertex : 1; // SHADE_VERTEX
uint64_t Unused5 : 1;
uint64_t LightNoNormals : 1; // LIGHT_NONORMALS
uint64_t UseSpriteCenter : 1; // USE_SPRITE_CENTER
uint64_t Unused : 26;
@ -120,7 +120,21 @@ public:
int SpecialEffect = 0;
int EffectState = 0;
int VertexFormat = 0;
int Padding = 0;
union
{
struct
{
uint32_t AlphaTest : 1; // !NO_ALPHATEST
uint32_t Simple : 1; // SIMPLE
uint32_t Simple3D : 1; // SIMPLE3D
uint32_t GBufferPass : 1; // GBUFFER_PASS
uint32_t UseLevelMesh : 1; // USE_LEVELMESH
uint32_t ShadeVertex : 1; // SHADE_VERTEX
uint32_t Unused : 26;
};
uint32_t AsDWORD = 0;
} Layout;
bool operator<(const VkShaderKey& other) const { return memcmp(this, &other, sizeof(VkShaderKey)) < 0; }
bool operator==(const VkShaderKey& other) const { return memcmp(this, &other, sizeof(VkShaderKey)) == 0; }
@ -146,7 +160,7 @@ public:
void Deinit();
VkShaderProgram* Get(const VkShaderKey& key);
VkShaderProgram* Get(const VkShaderKey& key, bool isUberShader);
bool CompileNextShader() { return true; }
@ -160,19 +174,20 @@ public:
VulkanShader* GetLightTilesShader() { return LightTiles.get(); }
private:
std::unique_ptr<VulkanShader> LoadVertShader(FString shadername, const char *vert_lump, const char *vert_lump_custom, const char *defines, const VkShaderKey& key, const UserShaderDesc *shader);
std::unique_ptr<VulkanShader> LoadFragShader(FString shadername, const char *frag_lump, const char *material_lump, const char* mateffect_lump, const char *light_lump_shared, const char *lightmodel_lump, const char *defines, const VkShaderKey& key, const UserShaderDesc *shader);
std::unique_ptr<VulkanShader> LoadVertShader(FString shadername, const char *vert_lump, const char *vert_lump_custom, const char *defines, const VkShaderKey& key, const UserShaderDesc *shader, bool isUberShader);
std::unique_ptr<VulkanShader> LoadFragShader(FString shadername, const char *frag_lump, const char *material_lump, const char* mateffect_lump, const char *light_lump_shared, const char *lightmodel_lump, const char *defines, const VkShaderKey& key, const UserShaderDesc *shader, bool isUberShader);
FString GetVersionBlock();
FString LoadPublicShaderLump(const char *lumpname);
FString LoadPrivateShaderLump(const char *lumpname);
void BuildLayoutBlock(FString &definesBlock, bool isFrag, const VkShaderKey& key, const UserShaderDesc *shader, bool isUberShader = false);
void BuildLayoutBlock(FString &definesBlock, bool isFrag, const VkShaderKey& key, const UserShaderDesc *shader, bool isUberShader);
void BuildDefinesBlock(FString &definesBlock, const char *defines, bool isFrag, const VkShaderKey& key, const UserShaderDesc *shader);
VulkanRenderDevice* fb = nullptr;
std::map<VkShaderKey, VkShaderProgram> programs;
std::map<uint32_t, VkShaderProgram> generic;
std::map<VkShaderKey, VkShaderProgram> specialized;
std::list<VkPPShader*> PPShaders;

View file

@ -718,7 +718,7 @@ int VulkanRenderDevice::GetLevelMeshPipelineID(const MeshApplyData& applyData, c
{
pipelineKey.ShaderKey.SpecialEffect = applyData.SpecialEffect;
pipelineKey.ShaderKey.EffectState = 0;
pipelineKey.ShaderKey.AlphaTest = false;
pipelineKey.ShaderKey.Layout.AlphaTest = false;
}
else
{
@ -727,7 +727,7 @@ int VulkanRenderDevice::GetLevelMeshPipelineID(const MeshApplyData& applyData, c
pipelineKey.ShaderKey.EffectState = applyData.TextureEnabled ? effectState : SHADER_NoTexture;
if (r_skipmats && pipelineKey.ShaderKey.EffectState >= 3 && pipelineKey.ShaderKey.EffectState <= 4)
pipelineKey.ShaderKey.EffectState = 0;
pipelineKey.ShaderKey.AlphaTest = surfaceUniforms.uAlphaThreshold >= 0.f;
pipelineKey.ShaderKey.Layout.AlphaTest = surfaceUniforms.uAlphaThreshold >= 0.f;
}
int tempTM = (material.mMaterial && material.mMaterial->Source()->isHardwareCanvas()) ? TM_OPAQUE : TM_NORMAL;
@ -781,7 +781,7 @@ int VulkanRenderDevice::GetLevelMeshPipelineID(const MeshApplyData& applyData, c
pipelineKey.ShaderKey.LightMode = 1; // Software
}
pipelineKey.ShaderKey.UseLevelMesh = true;
pipelineKey.ShaderKey.Layout.UseLevelMesh = true;
for (unsigned int i = 0, count = levelMeshPipelineKeys.Size(); i < count; i++)
{

View file

@ -264,8 +264,8 @@ void VkRenderState::ApplyRenderPass(int dt)
{
pipelineKey.ShaderKey.SpecialEffect = mSpecialEffect;
pipelineKey.ShaderKey.EffectState = 0;
pipelineKey.ShaderKey.Simple = (mSpecialEffect == EFF_BURN || mSpecialEffect == EFF_STENCIL || mSpecialEffect == EFF_PORTAL);
pipelineKey.ShaderKey.AlphaTest = false;
pipelineKey.ShaderKey.Layout.Simple = (mSpecialEffect == EFF_BURN || mSpecialEffect == EFF_STENCIL || mSpecialEffect == EFF_PORTAL);
pipelineKey.ShaderKey.Layout.AlphaTest = false;
}
else
{
@ -274,10 +274,10 @@ void VkRenderState::ApplyRenderPass(int dt)
pipelineKey.ShaderKey.EffectState = (mTextureEnabled && !mWireframe) ? effectState : SHADER_NoTexture;
if (r_skipmats && pipelineKey.ShaderKey.EffectState >= 3 && pipelineKey.ShaderKey.EffectState <= 4)
pipelineKey.ShaderKey.EffectState = 0;
pipelineKey.ShaderKey.AlphaTest = mSurfaceUniforms.uAlphaThreshold >= 0.f;
pipelineKey.ShaderKey.Layout.AlphaTest = mSurfaceUniforms.uAlphaThreshold >= 0.f;
pipelineKey.ShaderKey.Simple = mWireframe;
pipelineKey.ShaderKey.Simple3D = mWireframe; // simple notexture drawing for wireframe
pipelineKey.ShaderKey.Layout.Simple = mWireframe;
pipelineKey.ShaderKey.Layout.Simple3D = mWireframe; // simple notexture drawing for wireframe
}
int uTextureMode = GetTextureModeAndFlags((mMaterial.mMaterial && mMaterial.mMaterial->Source()->isHardwareCanvas()) ? TM_OPAQUE : TM_NORMAL);
@ -329,7 +329,7 @@ void VkRenderState::ApplyRenderPass(int dt)
pipelineKey.ShaderKey.LightMode = 1; // Software
}
pipelineKey.ShaderKey.ShadeVertex = mShadeVertex;
pipelineKey.ShaderKey.Layout.ShadeVertex = mShadeVertex;
pipelineKey.ShaderKey.LightNoNormals = mLightNoNormals;
pipelineKey.ShaderKey.UseSpriteCenter = mUseSpriteCenter;
@ -339,7 +339,7 @@ void VkRenderState::ApplyRenderPass(int dt)
pipelineKey.ShaderKey.PreciseMidtextureTrace = gl_precise_midtextures_trace;
pipelineKey.ShaderKey.ShadowmapFilter = std::clamp(int(gl_light_shadow_filter), 0, 15);
pipelineKey.ShaderKey.GBufferPass = mRenderTarget.DrawBuffers > 1;
pipelineKey.ShaderKey.Layout.GBufferPass = mRenderTarget.DrawBuffers > 1;
pipelineKey.ShaderKey.LightBlendMode = (level.info ? static_cast<int>(level.info->lightblendmode) : 0);
pipelineKey.ShaderKey.LightAttenuationMode = (level.info ? static_cast<int>(level.info->lightattenuationmode) : 0);
@ -492,11 +492,11 @@ void VkRenderState::ApplyPushConstants()
memcpy(buffer.Data(), &mPushConstants, sizeof(PushConstants));
memcpy(buffer.Data() + sizeof(PushConstants), mUniforms.addr, mUniforms.sz);
mCommandBuffer->pushConstants(fb->GetRenderPassManager()->GetPipelineLayout(mPipelineKey.ShaderKey.UseLevelMesh, mUniforms.sz), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sz, buffer.Data());
mCommandBuffer->pushConstants(fb->GetRenderPassManager()->GetPipelineLayout(mPipelineKey.ShaderKey.Layout.UseLevelMesh, mUniforms.sz), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sz, buffer.Data());
}
else
{
mCommandBuffer->pushConstants(fb->GetRenderPassManager()->GetPipelineLayout(mPipelineKey.ShaderKey.UseLevelMesh, mUniforms.sz), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &mPushConstants);
mCommandBuffer->pushConstants(fb->GetRenderPassManager()->GetPipelineLayout(mPipelineKey.ShaderKey.Layout.UseLevelMesh, mUniforms.sz), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &mPushConstants);
}
}
@ -563,7 +563,7 @@ void VkRenderState::ApplyBufferSets()
if (mViewpointOffset != mLastViewpointOffset || matrixOffset != mLastMatricesOffset || surfaceUniformsOffset != mLastSurfaceUniformsOffset || lightsOffset != mLastLightsOffset || fogballsOffset != mLastFogballsOffset)
{
auto descriptors = fb->GetDescriptorSetManager();
VulkanPipelineLayout* layout = fb->GetRenderPassManager()->GetPipelineLayout(mPipelineKey.ShaderKey.UseLevelMesh, mUniforms.sz);
VulkanPipelineLayout* layout = fb->GetRenderPassManager()->GetPipelineLayout(mPipelineKey.ShaderKey.Layout.UseLevelMesh, mUniforms.sz);
uint32_t offsets[5] = { mViewpointOffset, matrixOffset, surfaceUniformsOffset, lightsOffset, fogballsOffset };
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptors->GetFixedSet());
@ -1099,7 +1099,7 @@ void VkRenderState::ApplyLevelMeshPipeline(VulkanCommandBuffer* cmdbuffer, VkPip
pipelineKey.ShaderKey.AlphaTestOnly = true;
}
pipelineKey.ShaderKey.ShadeVertex = mShadeVertex;
pipelineKey.ShaderKey.Layout.ShadeVertex = mShadeVertex;
pipelineKey.ShaderKey.LightNoNormals = mLightNoNormals;
pipelineKey.ShaderKey.UseSpriteCenter = mUseSpriteCenter;
@ -1111,7 +1111,7 @@ void VkRenderState::ApplyLevelMeshPipeline(VulkanCommandBuffer* cmdbuffer, VkPip
pipelineKey.ShaderKey.PreciseMidtextureTrace = gl_precise_midtextures_trace;
pipelineKey.ShaderKey.ShadowmapFilter = std::clamp(int(gl_light_shadow_filter), 0, 15);
pipelineKey.ShaderKey.GBufferPass = mRenderTarget.DrawBuffers > 1;
pipelineKey.ShaderKey.Layout.GBufferPass = mRenderTarget.DrawBuffers > 1;
// State overridden by the renderstate drawing the mesh
pipelineKey.DrawLine = mDrawLine || mWireframe;
@ -1126,7 +1126,7 @@ void VkRenderState::ApplyLevelMeshPipeline(VulkanCommandBuffer* cmdbuffer, VkPip
if (!mTextureEnabled || mWireframe)
pipelineKey.ShaderKey.EffectState = SHADER_NoTexture;
pipelineKey.ShaderKey.Simple3D = mWireframe; // simple notexture drawing for wireframe
pipelineKey.ShaderKey.Layout.Simple3D = mWireframe; // simple notexture drawing for wireframe
mPipelineKey = pipelineKey;
@ -1134,7 +1134,7 @@ void VkRenderState::ApplyLevelMeshPipeline(VulkanCommandBuffer* cmdbuffer, VkPip
pushConstants.uBoneIndexBase = -1;
pushConstants.uFogballIndex = -1;
VulkanPipelineLayout* layout = fb->GetRenderPassManager()->GetPipelineLayout(pipelineKey.ShaderKey.UseLevelMesh, mUniforms.sz);
VulkanPipelineLayout* layout = fb->GetRenderPassManager()->GetPipelineLayout(pipelineKey.ShaderKey.Layout.UseLevelMesh, mUniforms.sz);
uint32_t viewpointOffset = mViewpointOffset;
uint32_t matrixOffset = mRSBuffers->MatrixBuffer->Offset();
uint32_t fogballsOffset = 0;