Skip to content

Commit 7cac8db

Browse files
PipelineResourceSignatureVkImpl: handle emulated buffers and push constants in CommitInlineConstants
1 parent 00d63c4 commit 7cac8db

4 files changed

Lines changed: 52 additions & 100 deletions

File tree

Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp

Lines changed: 2 additions & 5 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");
@@ -556,10 +556,7 @@ class DeviceContextVkImpl final : public DeviceContextNextGenBase<EngineVkImplTr
556556

557557
__forceinline void CommitDescriptorSets(ResourceBindInfo& BindInfo, Uint32 CommitSRBMask);
558558

559-
void UpdateInlineConstantBuffers(ResourceBindInfo& BindInfo);
560-
561-
// Commits push constants to the command buffer directly from SRB cache
562-
void CommitPushConstants(ResourceBindInfo& BindInfo);
559+
void CommitInlineConstants(ResourceBindInfo& BindInfo);
563560

564561
#ifdef DILIGENT_DEVELOPMENT
565562
void DvpValidateCommittedShaderResources(ResourceBindInfo& BindInfo);

Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -155,16 +155,17 @@ class PipelineResourceSignatureVkImpl final : public PipelineResourceSignatureBa
155155
void CommitDynamicResources(const ShaderResourceCacheVk& ResourceCache,
156156
VkDescriptorSet vkDynamicDescriptorSet) const;
157157

158-
// Updates inline constant buffers by mapping the internal buffers and copying data from the resource cache
159-
// ResourceCache must be valid - each SRB has its own copy of inline constant data stored in the cache
160-
// PushConstantResIndex: Resource index of the inline constant selected as push constant by PSO
161-
// Pass ~0u if no push constant is selected from this signature
162-
void UpdateInlineConstantBuffers(const ShaderResourceCacheVk& ResourceCache,
163-
DeviceContextVkImpl& Ctx,
164-
Uint32 PushConstantResIndex) const;
165-
166-
// Returns push constant data from the resource cache for the specified resource index
167-
const void* GetPushConstantData(const ShaderResourceCacheVk& ResourceCache, Uint32 ResIndex) const;
158+
struct CommitInlineConstantsAttribs
159+
{
160+
DeviceContextVkImpl& Ctx;
161+
VkPipelineLayout vkPipelineLayout = VK_NULL_HANDLE;
162+
VkPushConstantRange vkPushConstRange = {};
163+
const ShaderResourceCacheVk* pResourceCache = nullptr;
164+
Uint32 PushConstantResIndex = ~0u;
165+
};
166+
// Commits inline constants from the ResourceCache using push constants or
167+
// by mapping and updating the inline constant buffer.
168+
void CommitInlineConstants(const CommitInlineConstantsAttribs& Attribs) const;
168169

169170
#ifdef DILIGENT_DEVELOPMENT
170171
/// Verifies committed resource using the SPIRV resource attributes from the PSO.

Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp

Lines changed: 18 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -415,69 +415,43 @@ DeviceContextVkImpl::ResourceBindInfo& DeviceContextVkImpl::GetBindInfo(PIPELINE
415415
return m_BindInfo[Indices[Uint32{Type}]];
416416
}
417417

418-
void DeviceContextVkImpl::UpdateInlineConstantBuffers(ResourceBindInfo& BindInfo)
418+
void DeviceContextVkImpl::CommitInlineConstants(ResourceBindInfo& BindInfo)
419419
{
420-
const PipelineLayoutVk& Layout = m_pPipelineState->GetPipelineLayout();
421-
const auto& PushConstantInfo = Layout.GetPushConstantInfo();
422-
const Uint32 SignCount = m_pPipelineState->GetResourceSignatureCount();
423-
420+
const PipelineLayoutVk& Layout = m_pPipelineState->GetPipelineLayout();
421+
const PipelineLayoutVk::PushConstantInfo& PCInfo = Layout.GetPushConstantInfo();
422+
const Uint32 SignCount = m_pPipelineState->GetResourceSignatureCount();
423+
424+
PipelineResourceSignatureVkImpl::CommitInlineConstantsAttribs CommitAttribs{
425+
*this,
426+
Layout.GetVkPipelineLayout(),
427+
PCInfo.vkRange,
428+
};
424429
for (Uint32 i = 0; i < SignCount; ++i)
425430
{
426431
const PipelineResourceSignatureVkImpl* pSign = m_pPipelineState->GetResourceSignature(i);
427432
if (pSign == nullptr || !pSign->HasInlineConstants())
428433
continue;
429434

430-
const ShaderResourceCacheVk* pResourceCache = BindInfo.ResourceCaches[i];
431-
if (pResourceCache == nullptr)
435+
CommitAttribs.pResourceCache = BindInfo.ResourceCaches[i];
436+
if (CommitAttribs.pResourceCache == nullptr)
432437
{
433438
// Each signature with inline constants must have a bound SRB with a valid resource cache
434439
DEV_CHECK_ERR(false, "Signature '", pSign->GetDesc().Name, "' has inline constants but no SRB is bound. "
435440
"Did you call CommitShaderResources()?");
436441
continue;
437442
}
438443

439-
if (!pResourceCache->HasInlineConstants())
444+
if (!CommitAttribs.pResourceCache->HasInlineConstants())
440445
continue;
441446

442447
// Determine which resource (if any) in this signature should use push constant path
443448
// If this signature contains the selected push constant, pass its resource index
444449
// Otherwise pass ~0u to use emulated buffer path for all
445-
const Uint32 PushConstantResIndex = (i == PushConstantInfo.SignatureIndex) ? PushConstantInfo.ResourceIndex : ~0u;
450+
CommitAttribs.PushConstantResIndex = (i == PCInfo.SignatureIndex) ? PCInfo.ResourceIndex : ~0u;
446451

447452
// Update inline constant buffers
448-
pSign->UpdateInlineConstantBuffers(*pResourceCache, *this, PushConstantResIndex);
449-
}
450-
}
451-
452-
void DeviceContextVkImpl::CommitPushConstants(ResourceBindInfo& BindInfo)
453-
{
454-
VERIFY_EXPR(m_pPipelineState != nullptr);
455-
const PipelineLayoutVk& Layout = m_pPipelineState->GetPipelineLayout();
456-
const auto& PushConstantInfo = Layout.GetPushConstantInfo();
457-
458-
if (!PushConstantInfo)
459-
return;
460-
461-
const PipelineResourceSignatureVkImpl* pSign = m_pPipelineState->GetResourceSignature(PushConstantInfo.SignatureIndex);
462-
VERIFY_EXPR(pSign != nullptr);
463-
464-
const ShaderResourceCacheVk* pResourceCache = BindInfo.ResourceCaches[PushConstantInfo.SignatureIndex];
465-
if (pResourceCache == nullptr)
466-
{
467-
DEV_CHECK_ERR(false, "Signature '", pSign->GetDesc().Name, "' has push constants but no SRB is bound. "
468-
"Did you call CommitShaderResources()?");
469-
return;
470-
}
471-
472-
// Get inline constant data directly from the resource cache
473-
const void* pPushConstantData = pSign->GetPushConstantData(*pResourceCache, PushConstantInfo.ResourceIndex);
474-
if (pPushConstantData == nullptr)
475-
{
476-
DEV_CHECK_ERR(false, "Push constant data is null in signature '", pSign->GetDesc().Name, "'");
477-
return;
453+
pSign->CommitInlineConstants(CommitAttribs);
478454
}
479-
480-
m_CommandBuffer.PushConstants(Layout.GetVkPipelineLayout(), PushConstantInfo.vkRange, pPushConstantData);
481455
}
482456

483457
void DeviceContextVkImpl::CommitDescriptorSets(ResourceBindInfo& BindInfo, Uint32 CommitSRBMask)
@@ -829,7 +803,7 @@ void DeviceContextVkImpl::PrepareForDraw(DRAW_FLAGS Flags)
829803
const bool InlineConstantsIntact = (Flags & DRAW_FLAG_INLINE_CONSTANTS_INTACT) != 0;
830804
if (!InlineConstantsIntact)
831805
{
832-
UpdateInlineConstantBuffers(BindInfo);
806+
CommitInlineConstants(BindInfo);
833807
}
834808

835809
// First time we must always bind descriptor sets with dynamic offsets as SRBs are stale.
@@ -840,11 +814,6 @@ void DeviceContextVkImpl::PrepareForDraw(DRAW_FLAGS Flags)
840814
CommitDescriptorSets(BindInfo, CommitMask);
841815
}
842816

843-
// Commit push constants directly from SRB cache.
844-
// Push constants are always submitted before draw (similar to D3D11/D3D12) because
845-
// inline constants are designed to change every draw call.
846-
CommitPushConstants(BindInfo);
847-
848817
#ifdef DILIGENT_DEVELOPMENT
849818
// Must be called after CommitDescriptorSets as it needs SetInfo.BaseInd
850819
DvpValidateCommittedShaderResources(BindInfo);
@@ -1141,16 +1110,13 @@ void DeviceContextVkImpl::PrepareForDispatchCompute()
11411110
ResourceBindInfo& BindInfo = GetBindInfo(PIPELINE_TYPE_COMPUTE);
11421111

11431112
// Update inline constant buffers before binding descriptor sets
1144-
UpdateInlineConstantBuffers(BindInfo);
1113+
CommitInlineConstants(BindInfo);
11451114

11461115
if (Uint32 CommitMask = BindInfo.GetCommitMask())
11471116
{
11481117
CommitDescriptorSets(BindInfo, CommitMask);
11491118
}
11501119

1151-
// Commit push constants directly from SRB cache
1152-
CommitPushConstants(BindInfo);
1153-
11541120
#ifdef DILIGENT_DEVELOPMENT
11551121
// Must be called after CommitDescriptorSets as it needs SetInfo.BaseInd
11561122
DvpValidateCommittedShaderResources(BindInfo);
@@ -1164,16 +1130,13 @@ void DeviceContextVkImpl::PrepareForRayTracing()
11641130
ResourceBindInfo& BindInfo = GetBindInfo(PIPELINE_TYPE_RAY_TRACING);
11651131

11661132
// Update inline constant buffers before binding descriptor sets
1167-
UpdateInlineConstantBuffers(BindInfo);
1133+
CommitInlineConstants(BindInfo);
11681134

11691135
if (Uint32 CommitMask = BindInfo.GetCommitMask())
11701136
{
11711137
CommitDescriptorSets(BindInfo, CommitMask);
11721138
}
11731139

1174-
// Commit push constants directly from SRB cache
1175-
CommitPushConstants(BindInfo);
1176-
11771140
#ifdef DILIGENT_DEVELOPMENT
11781141
// Must be called after CommitDescriptorSets as it needs SetInfo.BaseInd
11791142
DvpValidateCommittedShaderResources(BindInfo);

Graphics/GraphicsEngineVulkan/src/PipelineResourceSignatureVkImpl.cpp

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,46 +1122,37 @@ PipelineResourceSignatureInternalDataVk PipelineResourceSignatureVkImpl::GetInte
11221122
return InternalData;
11231123
}
11241124

1125-
void PipelineResourceSignatureVkImpl::UpdateInlineConstantBuffers(const ShaderResourceCacheVk& ResourceCache,
1126-
DeviceContextVkImpl& Ctx,
1127-
Uint32 PushConstantResIndex) const
1125+
void PipelineResourceSignatureVkImpl::CommitInlineConstants(const CommitInlineConstantsAttribs& Attribs) const
11281126
{
1127+
const ShaderResourceCacheVk& ResourceCache = *Attribs.pResourceCache;
11291128
VERIFY(ResourceCache.GetContentType() == ResourceCacheContentType::SRB,
11301129
"Inline constant buffers can be updated only in SRB resource caches");
11311130
for (Uint32 i = 0; i < m_NumInlineConstantBuffers; ++i)
11321131
{
1133-
const InlineConstantBufferAttribsVk& InlineCBAttr = m_InlineConstantBuffers[i];
1134-
// Skip native push constants - they are handled directly by CommitPushConstants
1135-
if (InlineCBAttr.ResIndex == PushConstantResIndex)
1136-
continue;
1137-
1138-
const Uint32 DataSize = InlineCBAttr.NumConstants * sizeof(Uint32);
1139-
const void* pInlineConstantData = ResourceCache.GetInlineConstantData(InlineCBAttr.DescrSet, InlineCBAttr.SRBCacheOffset);
1132+
const InlineConstantBufferAttribsVk& InlineCBAttr = m_InlineConstantBuffers[i];
1133+
const Uint32 DataSize = InlineCBAttr.NumConstants * sizeof(Uint32);
1134+
const void* pInlineConstantData = ResourceCache.GetInlineConstantData(InlineCBAttr.DescrSet, InlineCBAttr.SRBCacheOffset);
11401135
VERIFY_EXPR(pInlineConstantData != nullptr);
1141-
VERIFY_EXPR(InlineCBAttr.pBuffer);
11421136

1143-
// Map the shared buffer and copy the data
1144-
void* pMappedData = nullptr;
1145-
Ctx.MapBuffer(InlineCBAttr.pBuffer, MAP_WRITE, MAP_FLAG_DISCARD, pMappedData);
1146-
memcpy(pMappedData, pInlineConstantData, DataSize);
1147-
Ctx.UnmapBuffer(InlineCBAttr.pBuffer, MAP_WRITE);
1148-
}
1149-
}
1150-
1151-
const void* PipelineResourceSignatureVkImpl::GetPushConstantData(const ShaderResourceCacheVk& ResourceCache, Uint32 ResIndex) const
1152-
{
1153-
VERIFY(ResourceCache.GetContentType() == ResourceCacheContentType::SRB,
1154-
"Push constant data can be retrieved only from SRB resource caches");
1155-
// Find the inline constant buffer with the specified resource index
1156-
for (Uint32 i = 0; i < m_NumInlineConstantBuffers; ++i)
1157-
{
1158-
const InlineConstantBufferAttribsVk& InlineCBAttr = m_InlineConstantBuffers[i];
1159-
if (InlineCBAttr.ResIndex == ResIndex)
1137+
if (InlineCBAttr.ResIndex == Attribs.PushConstantResIndex)
11601138
{
1161-
return ResourceCache.GetInlineConstantData(InlineCBAttr.DescrSet, InlineCBAttr.SRBCacheOffset);
1139+
VulkanUtilities::CommandBuffer& CmdBuffer = Attribs.Ctx.GetCommandBuffer();
1140+
VERIFY(Attribs.vkPushConstRange.size == DataSize,
1141+
"Push constant range size (", Attribs.vkPushConstRange.size,
1142+
") does not match the inline constant buffer data size (", DataSize, ")");
1143+
CmdBuffer.PushConstants(Attribs.vkPipelineLayout, Attribs.vkPushConstRange, pInlineConstantData);
1144+
}
1145+
else
1146+
{
1147+
VERIFY_EXPR(InlineCBAttr.pBuffer);
1148+
1149+
// Map the shared buffer and copy the data
1150+
void* pMappedData = nullptr;
1151+
Attribs.Ctx.MapBuffer(InlineCBAttr.pBuffer, MAP_WRITE, MAP_FLAG_DISCARD, pMappedData);
1152+
memcpy(pMappedData, pInlineConstantData, DataSize);
1153+
Attribs.Ctx.UnmapBuffer(InlineCBAttr.pBuffer, MAP_WRITE);
11621154
}
11631155
}
1164-
return nullptr;
11651156
}
11661157

11671158
} // namespace Diligent

0 commit comments

Comments
 (0)