Skip to content

Commit 82cd67d

Browse files
Vulkan: fix handling of push constant blocks of different sizes across shader stages
1 parent 179f633 commit 82cd67d

2 files changed

Lines changed: 12 additions & 23 deletions

File tree

Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -566,23 +566,10 @@ MergedPushConstantMapType MergePushConstants(const PipelineStateVkImpl::TShaderS
566566
const SPIRVShaderResourceAttribs& PCAttribs = ShaderResources.GetPushConstant(i);
567567
MergedPushConstantInfo& MergedPC = MergedPushConstants[PCAttribs.Name];
568568
const Uint32 BufferSize = PCAttribs.GetConstantBufferSize();
569-
if (MergedPC.Stages == SHADER_TYPE_UNKNOWN)
570-
{
571-
MergedPC.Stages = Stage.Type;
572-
MergedPC.Size = BufferSize;
573-
}
574-
else if (MergedPC.Size == BufferSize)
575-
{
576-
MergedPC.Stages |= Stage.Type;
577-
}
578-
else
579-
{
580-
LOG_ERROR_AND_THROW("Push constant '", PCAttribs.Name,
581-
"' is shared between multiple shaders in pipeline '", (PSOName ? PSOName : ""),
582-
"', but its size varies (",
583-
MergedPC.Size, " vs ", BufferSize,
584-
"). A push constant shared between multiple shaders must have the same size in all shaders.");
585-
}
569+
570+
// Combine push constants from all stages
571+
MergedPC.Stages |= Stage.Type;
572+
MergedPC.Size = std::max(MergedPC.Size, BufferSize);
586573
}
587574
}
588575
}
@@ -682,7 +669,7 @@ PipelineResourceSignatureDescWrapper PipelineStateVkImpl::GetDefaultResourceSign
682669
auto it = MergedPushConstants.find(VarDesc.Name);
683670
if (it != MergedPushConstants.end())
684671
{
685-
VERIFY_EXPR(Attribs.GetConstantBufferSize() == it->second.Size);
672+
VERIFY_EXPR(Attribs.GetConstantBufferSize() <= it->second.Size);
686673
VarDesc.ShaderStages = it->second.Stages;
687674
}
688675
else

Tests/DiligentCoreAPITest/src/InlineConstantsTest.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ const std::string VulkanPushConstants_VS{
108108
struct PushConstants_t
109109
{
110110
float4 g_Positions[6];
111-
float4 g_Colors[3];
111+
// Make VS push constant size smaller than PS
112112
};
113113
114114
[[vk::push_constant]] ConstantBuffer<PushConstants_t> PushConstants;
@@ -121,8 +121,12 @@ struct PSInput
121121
122122
void main(uint VertexId : SV_VertexId, out PSInput PSIn)
123123
{
124+
float4 Colors[3];
125+
Colors[0] = float4(1.0, 0.0, 0.0, 1.0);
126+
Colors[1] = float4(0.0, 1.0, 0.0, 1.0);
127+
Colors[2] = float4(0.0, 0.0, 1.0, 1.0);
124128
PSIn.Pos = PushConstants.g_Positions[VertexId];
125-
PSIn.Color = PushConstants.g_Colors[VertexId % 3];
129+
PSIn.Color = Colors[VertexId % 3];
126130
}
127131
)"};
128132

@@ -131,7 +135,7 @@ const std::string VulkanPushConstants_PS{
131135
struct PushConstants_t
132136
{
133137
float4 g_Positions[6];
134-
float4 g_Colors[3];
138+
float4 g_Colors[3]; // Make PS push constant size larger than VS
135139
};
136140
137141
[[vk::push_constant]] ConstantBuffer<PushConstants_t> PushConstants;
@@ -144,8 +148,6 @@ struct PSInput
144148
145149
float4 main(in PSInput PSIn) : SV_Target
146150
{
147-
// Use push constants from PS to apply color modulation
148-
// This ensures both VS and PS access the same PushConstants
149151
return float4(
150152
PSIn.Color.r * PushConstants.g_Colors[0].r,
151153
PSIn.Color.g * PushConstants.g_Colors[1].g,

0 commit comments

Comments
 (0)