Skip to content

Commit b44e771

Browse files
PipelineLayoutVk: add static version of GetPushConstantInfo
1 parent f15f478 commit b44e771

File tree

2 files changed

+68
-51
lines changed

2 files changed

+68
-51
lines changed

Graphics/GraphicsEngineVulkan/include/PipelineLayoutVk.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ class PipelineLayoutVk
4747
PipelineLayoutVk();
4848
~PipelineLayoutVk();
4949

50-
void Create(RenderDeviceVkImpl* pDeviceVk,
51-
RefCntAutoPtr<PipelineResourceSignatureVkImpl> ppSignatures[],
52-
Uint32 SignatureCount) noexcept(false);
50+
void Create(RenderDeviceVkImpl* pDeviceVk,
51+
RefCntAutoPtr<PipelineResourceSignatureVkImpl>* ppSignatures,
52+
Uint32 SignatureCount) noexcept(false);
5353
void Release(RenderDeviceVkImpl* pDeviceVkImpl, Uint64 CommandQueueMask);
5454

5555
VkPipelineLayout GetVkPipelineLayout() const { return m_VkPipelineLayout; }
@@ -70,6 +70,9 @@ class PipelineLayoutVk
7070

7171
constexpr explicit operator bool() const { return Size != 0; }
7272
};
73+
static PushConstantInfo GetPushConstantInfo(const RefCntAutoPtr<PipelineResourceSignatureVkImpl>* ppSignatures,
74+
Uint32 SignatureCount);
75+
7376
const PushConstantInfo& GetPushConstantInfo() const { return m_PushConstantInfo; }
7477

7578
private:

Graphics/GraphicsEngineVulkan/src/PipelineLayoutVk.cpp

Lines changed: 62 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,49 @@ void PipelineLayoutVk::Release(RenderDeviceVkImpl* pDeviceVk, Uint64 CommandQueu
5959
}
6060
}
6161

62-
void PipelineLayoutVk::Create(RenderDeviceVkImpl* pDeviceVk,
63-
RefCntAutoPtr<PipelineResourceSignatureVkImpl> ppSignatures[],
64-
Uint32 SignatureCount) noexcept(false)
62+
PipelineLayoutVk::PushConstantInfo PipelineLayoutVk::GetPushConstantInfo(
63+
const RefCntAutoPtr<PipelineResourceSignatureVkImpl>* ppSignatures,
64+
Uint32 SignatureCount)
65+
{
66+
PushConstantInfo PCInfo;
67+
for (Uint32 BindInd = 0; BindInd < SignatureCount; ++BindInd)
68+
{
69+
// Signatures are arranged by binding index by PipelineStateBase::CopyResourceSignatures
70+
const RefCntAutoPtr<PipelineResourceSignatureVkImpl>& pSignature = ppSignatures[BindInd];
71+
if (pSignature == nullptr)
72+
continue;
73+
74+
// Vulkan allows only one push constant range per pipeline layout.
75+
// Diligent API allows multiple inline constant resources, so we promote only the first inline constant
76+
// from resource signatures to push constants. Other inline constants remain uniform buffers.
77+
if (pSignature->HasInlineConstants())
78+
{
79+
for (Uint32 r = 0; r < pSignature->GetTotalResourceCount(); ++r)
80+
{
81+
const PipelineResourceDesc& ResDesc = pSignature->GetResourceDesc(r);
82+
if (ResDesc.Flags & PIPELINE_RESOURCE_FLAG_INLINE_CONSTANTS)
83+
{
84+
VERIFY_EXPR(ResDesc.ArraySize > 0);
85+
// For inline constants, ArraySize contains the number of 32-bit constants.
86+
PCInfo.Size = ResDesc.ArraySize * sizeof(Uint32);
87+
PCInfo.StageFlags = ShaderTypesToVkShaderStageFlags(ResDesc.ShaderStages);
88+
PCInfo.SignatureIndex = BindInd;
89+
PCInfo.ResourceIndex = r;
90+
break;
91+
}
92+
}
93+
94+
VERIFY(PCInfo, "pSignature->HasInlineConstants() returned true, but no inline constant resource was found. This is a bug.");
95+
break;
96+
}
97+
}
98+
99+
return PCInfo;
100+
}
101+
102+
void PipelineLayoutVk::Create(RenderDeviceVkImpl* pDeviceVk,
103+
RefCntAutoPtr<PipelineResourceSignatureVkImpl>* ppSignatures,
104+
Uint32 SignatureCount) noexcept(false)
65105
{
66106
VERIFY(m_DescrSetCount == 0 && !m_VkPipelineLayout, "This pipeline layout is already initialized");
67107

@@ -94,27 +134,6 @@ void PipelineLayoutVk::Create(RenderDeviceVkImpl* pDe
94134
#ifdef DILIGENT_DEBUG
95135
m_DbgMaxBindIndex = std::max(m_DbgMaxBindIndex, Uint32{pSignature->GetDesc().BindingIndex});
96136
#endif
97-
98-
// Vulkan allows only one push constant range per pipeline layout.
99-
// Diligent API allows multiple inline constant resources, so we promote only the first inline constant
100-
// from resource signatures to push constants. Other inline constants remain uniform buffers.
101-
if (!m_PushConstantInfo && pSignature->HasInlineConstants())
102-
{
103-
for (Uint32 r = 0; r < pSignature->GetTotalResourceCount(); ++r)
104-
{
105-
const PipelineResourceDesc& ResDesc = pSignature->GetResourceDesc(r);
106-
if (ResDesc.Flags & PIPELINE_RESOURCE_FLAG_INLINE_CONSTANTS)
107-
{
108-
VERIFY_EXPR(ResDesc.ArraySize > 0);
109-
// For inline constants, ArraySize contains the number of 32-bit constants.
110-
m_PushConstantInfo.Size = ResDesc.ArraySize * sizeof(Uint32);
111-
m_PushConstantInfo.StageFlags = ShaderTypesToVkShaderStageFlags(ResDesc.ShaderStages);
112-
m_PushConstantInfo.SignatureIndex = BindInd;
113-
m_PushConstantInfo.ResourceIndex = r;
114-
break;
115-
}
116-
}
117-
}
118137
}
119138
VERIFY_EXPR(DescSetLayoutCount <= MAX_RESOURCE_SIGNATURES * 2);
120139

@@ -137,42 +156,37 @@ void PipelineLayoutVk::Create(RenderDeviceVkImpl* pDe
137156
") used by the pipeline layout exceeds device limit (", Limits.maxDescriptorSetStorageBuffersDynamic, ")");
138157
}
139158

140-
// Validate push constant size against device limits
141-
if (m_PushConstantInfo.Size > Limits.maxPushConstantsSize)
142-
{
143-
LOG_ERROR_AND_THROW("Push constant size (", m_PushConstantInfo.Size,
144-
" bytes) exceeds device limit (", Limits.maxPushConstantsSize, " bytes)");
145-
}
146-
147-
VERIFY(m_DescrSetCount <= std::numeric_limits<decltype(m_DescrSetCount)>::max(),
148-
"Descriptor set count (", DescSetLayoutCount, ") exceeds the maximum representable value");
149-
150-
VkPipelineLayoutCreateInfo PipelineLayoutCI{};
151-
PipelineLayoutCI.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
152-
PipelineLayoutCI.pNext = nullptr;
153-
PipelineLayoutCI.flags = 0; // reserved for future use
154-
PipelineLayoutCI.setLayoutCount = DescSetLayoutCount;
155-
PipelineLayoutCI.pSetLayouts = DescSetLayoutCount ? DescSetLayouts.data() : nullptr;
159+
m_PushConstantInfo = GetPushConstantInfo(ppSignatures, SignatureCount);
156160

157161
// Set up push constant range if present
158162
VkPushConstantRange PushConstantRange{};
159163
if (m_PushConstantInfo)
160164
{
165+
// Validate push constant size against device limits
166+
if (m_PushConstantInfo.Size > Limits.maxPushConstantsSize)
167+
{
168+
LOG_ERROR_AND_THROW("Push constant size (", m_PushConstantInfo.Size,
169+
" bytes) exceeds device limit (", Limits.maxPushConstantsSize, " bytes)");
170+
}
171+
161172
PushConstantRange.stageFlags = m_PushConstantInfo.StageFlags;
162173
PushConstantRange.offset = 0;
163174
PushConstantRange.size = m_PushConstantInfo.Size;
164-
165-
PipelineLayoutCI.pushConstantRangeCount = 1;
166-
PipelineLayoutCI.pPushConstantRanges = &PushConstantRange;
167-
}
168-
else
169-
{
170-
PipelineLayoutCI.pushConstantRangeCount = 0;
171-
PipelineLayoutCI.pPushConstantRanges = nullptr;
172175
}
173176

177+
VkPipelineLayoutCreateInfo PipelineLayoutCI{};
178+
PipelineLayoutCI.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
179+
PipelineLayoutCI.pNext = nullptr;
180+
PipelineLayoutCI.flags = 0; // reserved for future use
181+
PipelineLayoutCI.setLayoutCount = DescSetLayoutCount;
182+
PipelineLayoutCI.pSetLayouts = DescSetLayoutCount ? DescSetLayouts.data() : nullptr;
183+
PipelineLayoutCI.pushConstantRangeCount = m_PushConstantInfo ? 1 : 0;
184+
PipelineLayoutCI.pPushConstantRanges = m_PushConstantInfo ? &PushConstantRange : nullptr;
185+
174186
m_VkPipelineLayout = pDeviceVk->GetLogicalDevice().CreatePipelineLayout(PipelineLayoutCI);
175187

188+
VERIFY(DescSetLayoutCount <= std::numeric_limits<decltype(m_DescrSetCount)>::max(),
189+
"Descriptor set count (", DescSetLayoutCount, ") exceeds the maximum representable value");
176190
m_DescrSetCount = static_cast<Uint8>(DescSetLayoutCount);
177191
}
178192

0 commit comments

Comments
 (0)