Skip to content

Commit eb11532

Browse files
committed
Step: 1.5) Fix ArraySize in GetDefaultSignatureDesc for inline constants
1 parent 0e7e10c commit eb11532

3 files changed

Lines changed: 63 additions & 9 deletions

File tree

Graphics/GraphicsEngineOpenGL/include/ShaderResourcesGL.hpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2025 Diligent Graphics LLC
2+
* Copyright 2019-2026 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -147,19 +147,31 @@ class ShaderResourcesGL
147147
SHADER_TYPE _ShaderStages,
148148
SHADER_RESOURCE_TYPE _ResourceType,
149149
Uint32 _ArraySize,
150-
GLuint _UBIndex)noexcept :
150+
GLuint _UBIndex,
151+
Uint32 _BufferSize = 0)noexcept :
151152
GLResourceAttribs{_Name, _ShaderStages, _ResourceType, PIPELINE_RESOURCE_FLAG_NONE, _ArraySize},
152-
UBIndex {_UBIndex}
153+
UBIndex {_UBIndex},
154+
BufferSize {_BufferSize}
153155
{}
154156

155157
UniformBufferInfo(const UniformBufferInfo& UB,
156158
StringPool& NamesPool)noexcept :
157159
GLResourceAttribs{UB, NamesPool},
158-
UBIndex {UB.UBIndex }
160+
UBIndex {UB.UBIndex },
161+
BufferSize {UB.BufferSize }
159162
{}
160163
// clang-format on
161164

162165
const GLuint UBIndex;
166+
const Uint32 BufferSize; // Buffer size in bytes
167+
168+
/// Returns the number of 32-bit constants in the buffer.
169+
/// This is used for inline constants where ArraySize represents
170+
/// the number of constants, not the UBO array size.
171+
Uint32 GetInlineConstantCount() const
172+
{
173+
return BufferSize / sizeof(Uint32);
174+
}
163175
};
164176
static_assert((sizeof(UniformBufferInfo) % sizeof(void*)) == 0, "sizeof(UniformBufferInfo) must be multiple of sizeof(void*)");
165177

Graphics/GraphicsEngineOpenGL/src/PipelineStateGLImpl.cpp

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2025 Diligent Graphics LLC
2+
* Copyright 2019-2026 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -130,12 +130,48 @@ PipelineResourceSignatureDescWrapper PipelineStateGLImpl::GetDefaultSignatureDes
130130
}
131131
};
132132

133+
// Specialized handler for uniform buffers to handle inline constants correctly
134+
const auto HandleUniformBuffer = [&](const ShaderResourcesGL::UniformBufferInfo& UB) //
135+
{
136+
const ShaderResourceVariableDesc VarDesc = FindPipelineResourceLayoutVariable(ResourceLayout, UB.Name, UB.ShaderStages, nullptr);
137+
const auto it_assigned = UniqueResources.emplace(ShaderResourceHashKey{VarDesc.ShaderStages, UB.Name}, UB);
138+
if (it_assigned.second)
139+
{
140+
const PIPELINE_RESOURCE_FLAGS Flags = UB.ResourceFlags | ShaderVariableFlagsToPipelineResourceFlags(VarDesc.Flags);
141+
142+
// For inline constants, use the constant count instead of the UBO array size
143+
Uint32 ArraySize = UB.ArraySize;
144+
if (Flags & PIPELINE_RESOURCE_FLAG_INLINE_CONSTANTS)
145+
{
146+
VERIFY(Flags == PIPELINE_RESOURCE_FLAG_INLINE_CONSTANTS, "INLINE_CONSTANTS flag cannot be combined with other flags.");
147+
ArraySize = UB.GetInlineConstantCount();
148+
if (ArraySize == 0)
149+
{
150+
LOG_ERROR_AND_THROW("Inline constants resource '", UB.Name, "' has zero buffer size. "
151+
"Make sure the shader was compiled with constant buffer reflection enabled.");
152+
}
153+
if (ArraySize > MAX_INLINE_CONSTANTS)
154+
{
155+
LOG_ERROR_AND_THROW("Inline constants resource '", UB.Name, "' has ",
156+
ArraySize, " constants. The maximum supported number of inline constants is ",
157+
MAX_INLINE_CONSTANTS, '.');
158+
}
159+
}
160+
161+
SignDesc.AddResource(VarDesc.ShaderStages, UB.Name, ArraySize, UB.ResourceType, VarDesc.Type, Flags);
162+
}
163+
else
164+
{
165+
VerifyResourceMerge(m_Desc, it_assigned.first->second, UB);
166+
}
167+
};
168+
133169
if (m_IsProgramPipelineSupported)
134170
{
135171
for (size_t i = 0; i < ShaderStages.size(); ++i)
136172
{
137173
ShaderGLImpl* pShaderGL = ShaderStages[i];
138-
pShaderGL->GetShaderResources()->ProcessConstResources(HandleResource, HandleResource, HandleResource, HandleResource);
174+
pShaderGL->GetShaderResources()->ProcessConstResources(HandleUniformBuffer, HandleResource, HandleResource, HandleResource);
139175
}
140176
}
141177
else
@@ -153,7 +189,7 @@ PipelineResourceSignatureDescWrapper PipelineStateGLImpl::GetDefaultSignatureDes
153189
SamplerResFlag,
154190
pImmediateCtx->GetContextState());
155191
}
156-
m_GLPrograms[0]->GetResources()->ProcessConstResources(HandleResource, HandleResource, HandleResource, HandleResource);
192+
m_GLPrograms[0]->GetResources()->ProcessConstResources(HandleUniformBuffer, HandleResource, HandleResource, HandleResource);
157193

158194
if (ResourceLayout.NumImmutableSamplers > 0)
159195
{

Graphics/GraphicsEngineOpenGL/src/ShaderResourcesGL.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2025 Diligent Graphics LLC
2+
* Copyright 2019-2026 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -754,12 +754,18 @@ void ShaderResourcesGL::LoadUniforms(const LoadUniformsAttribs& Attribs)
754754

755755
if (IsNewBlock)
756756
{
757+
// Get the buffer size for this uniform block
758+
GLint BufferSize = 0;
759+
glGetActiveUniformBlockiv(GLProgram, UniformBlockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &BufferSize);
760+
DEV_CHECK_GL_ERROR("Failed to get the value of the GL_UNIFORM_BLOCK_DATA_SIZE parameter");
761+
757762
UniformBlocks.emplace_back(
758763
NamesPool.emplace(Name.data()).first->c_str(),
759764
Attribs.ShaderStages,
760765
SHADER_RESOURCE_TYPE_CONSTANT_BUFFER,
761766
static_cast<Uint32>(ArraySize),
762-
UniformBlockIndex //
767+
UniformBlockIndex,
768+
static_cast<Uint32>(BufferSize) //
763769
);
764770
}
765771
}

0 commit comments

Comments
 (0)