Skip to content

Commit c189de6

Browse files
hzqstTheMostDiligent
authored andcommitted
Fix issue from DiligentGraphics#747
1 parent e9267d0 commit c189de6

File tree

11 files changed

+835
-71
lines changed

11 files changed

+835
-71
lines changed

Graphics/Archiver/src/Archiver_Vk.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,10 @@ void SerializedPipelineStateImpl::PatchShadersVk(const CreateInfoType& CreateInf
128128
{
129129
ShaderStageInfoVk& Src{ShaderStages[i]};
130130
PipelineStateVkImpl::ShaderStageInfo& Dst{ShaderStagesVk[i]};
131-
Dst.Type = Src.Type;
132-
Dst.Shaders = std::move(Src.Shaders);
133-
Dst.SPIRVs = std::move(Src.SPIRVs);
131+
Dst.Type = Src.Type;
132+
Dst.Shaders = std::move(Src.Shaders);
133+
Dst.SPIRVs = std::move(Src.SPIRVs);
134+
Dst.ShaderResources = std::move(Src.ShaderResources);
134135
}
135136

136137
IPipelineResourceSignature** ppSignatures = CreateInfo.ppResourceSignatures;

Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,12 @@ class DeviceContextVkImpl final : public DeviceContextNextGenBase<EngineVkImplTr
555555
__forceinline ResourceBindInfo& GetBindInfo(PIPELINE_TYPE Type);
556556

557557
__forceinline void CommitDescriptorSets(ResourceBindInfo& BindInfo, Uint32 CommitSRBMask);
558+
559+
void UpdateInlineConstantBuffers(ResourceBindInfo& BindInfo);
560+
561+
// Commits push constants to the command buffer directly from SRB cache
562+
void CommitPushConstants(ResourceBindInfo& BindInfo);
563+
558564
#ifdef DILIGENT_DEVELOPMENT
559565
void DvpValidateCommittedShaderResources(ResourceBindInfo& BindInfo);
560566
#endif

Graphics/GraphicsEngineVulkan/include/PipelineResourceSignatureVkImpl.hpp

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ namespace Diligent
5050

5151
struct SPIRVShaderResourceAttribs;
5252
class DeviceContextVkImpl;
53+
class BufferVkImpl;
5354

5455
struct ImmutableSamplerAttribsVk
5556
{
@@ -58,6 +59,27 @@ struct ImmutableSamplerAttribsVk
5859
};
5960
ASSERT_SIZEOF(ImmutableSamplerAttribsVk, 8, "The struct is used in serialization and must be tightly packed");
6061

62+
/// Inline constant buffer attributes for Vulkan backend.
63+
/// All inline constants are treated uniformly at PRS level - they all get:
64+
/// - DescriptorSet binding and cache allocation
65+
/// - Shared emulated buffer (created in the Signature, shared by all SRBs)
66+
///
67+
/// Push constant selection is deferred to PSO creation time. At PSO creation,
68+
/// one inline constant may be selected to use vkCmdPushConstants based on:
69+
/// 1. SPIR-V reflection (ResourceType::PushConstant in shader)
70+
/// 2. First inline constant as fallback (converted via PatchShader)
71+
struct InlineConstantBufferAttribsVk
72+
{
73+
Uint32 ResIndex = 0; // Resource index in the signature (used for matching)
74+
Uint32 DescrSet = 0; // Descriptor set index
75+
Uint32 BindingIndex = 0; // Binding index within the descriptor set
76+
Uint32 NumConstants = 0; // Number of 32-bit constants
77+
78+
// Shared buffer created in the Signature (similar to D3D11)
79+
// All SRBs reference this same buffer to reduce memory usage.
80+
RefCntAutoPtr<BufferVkImpl> pBuffer;
81+
};
82+
6183
struct PipelineResourceSignatureInternalDataVk : PipelineResourceSignatureInternalData<PipelineResourceAttribsVk, ImmutableSamplerAttribsVk>
6284
{
6385
Uint16 DynamicUniformBufferCount = 0;
@@ -134,6 +156,23 @@ class PipelineResourceSignatureVkImpl final : public PipelineResourceSignatureBa
134156
void CommitDynamicResources(const ShaderResourceCacheVk& ResourceCache,
135157
VkDescriptorSet vkDynamicDescriptorSet) const;
136158

159+
// Updates inline constant buffers by mapping the internal buffers and copying data from the resource cache
160+
// ResourceCache must be valid - each SRB has its own copy of inline constant data stored in the cache
161+
// PushConstantResIndex: Resource index of the inline constant selected as push constant by PSO
162+
// Pass ~0u if no push constant is selected from this signature
163+
void UpdateInlineConstantBuffers(const ShaderResourceCacheVk& ResourceCache,
164+
DeviceContextVkImpl& Ctx,
165+
Uint32 PushConstantResIndex) const;
166+
167+
// Returns the number of inline constant buffers
168+
Uint32 GetNumInlineConstantBufferAttribs() const { return m_NumInlineConstantBufferAttribs; }
169+
170+
// Returns the inline constant buffer attributes
171+
const InlineConstantBufferAttribsVk* GetInlineConstantBufferAttribs() const { return m_InlineConstantBufferAttribs.get(); }
172+
173+
// Returns push constant data from the resource cache for the specified resource index
174+
const void* GetPushConstantData(const ShaderResourceCacheVk& ResourceCache, Uint32 ResIndex) const;
175+
137176
#ifdef DILIGENT_DEVELOPMENT
138177
/// Verifies committed resource using the SPIRV resource attributes from the PSO.
139178
bool DvpValidateCommittedResource(const DeviceContextVkImpl* pDeviceCtx,
@@ -152,8 +191,7 @@ class PipelineResourceSignatureVkImpl final : public PipelineResourceSignatureBa
152191

153192
bool HasInlineConstants() const
154193
{
155-
// TODO
156-
return false;
194+
return m_NumInlineConstantBufferAttribs != 0;
157195
}
158196

159197
private:
@@ -199,6 +237,11 @@ class PipelineResourceSignatureVkImpl final : public PipelineResourceSignatureBa
199237
// The total number storage buffers with dynamic offsets in both descriptor sets,
200238
// accounting for array size.
201239
Uint16 m_DynamicStorageBufferCount = 0;
240+
241+
// Number of inline constant buffers
242+
Uint32 m_NumInlineConstantBufferAttribs = 0;
243+
// Inline constant buffer attributes
244+
std::unique_ptr<InlineConstantBufferAttribsVk[]> m_InlineConstantBufferAttribs;
202245
};
203246

204247
template <> Uint32 PipelineResourceSignatureVkImpl::GetDescriptorSetIndex<PipelineResourceSignatureVkImpl::DESCRIPTOR_SET_ID_STATIC_MUTABLE>() const;

Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,9 @@ class PipelineStateVkImpl final : public PipelineStateBase<EngineVkImplTraits>
8484
// Shader stage type. All shaders in the stage must have the same type.
8585
SHADER_TYPE Type = SHADER_TYPE_UNKNOWN;
8686

87-
std::vector<const ShaderVkImpl*> Shaders;
88-
std::vector<std::vector<uint32_t>> SPIRVs;
87+
std::vector<const ShaderVkImpl*> Shaders;
88+
std::vector<std::vector<uint32_t>> SPIRVs;
89+
std::vector<std::shared_ptr<const SPIRVShaderResources>> ShaderResources; //This can be also updated due to push constant
8990

9091
friend SHADER_TYPE GetShaderStageType(const ShaderStageInfo& Stage) { return Stage.Type; }
9192
};
@@ -133,6 +134,10 @@ class PipelineStateVkImpl final : public PipelineStateBase<EngineVkImplTraits>
133134
void InitializePipeline(const ComputePipelineStateCreateInfo& CreateInfo);
134135
void InitializePipeline(const RayTracingPipelineStateCreateInfo& CreateInfo);
135136

137+
void ValidateShaderPushConstants(const TShaderStages& ShaderStages) const noexcept(false);
138+
139+
void PatchShaderConvertUniformBufferToPushConstant(TShaderStages& ShaderStages) const noexcept(false);
140+
136141
// TPipelineStateBase::Construct needs access to InitializePipeline
137142
friend TPipelineStateBase;
138143

Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.hpp

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
// m_pMemory | | m_pResources, m_NumResources == m |
3838
// | m_DescriptorSetAllocation| | |
3939
// V | | V
40-
// | DescriptorSet[0] | .... | DescriptorSet[Ns-1] | Res[0] | ... | Res[n-1] | .... | Res[0] | ... | Res[m-1] |
40+
// | DescriptorSet[0] | .... | DescriptorSet[Ns-1] | Res[0] | ... | Res[n-1] | .... | Res[0] | ... | Res[m-1] | Inline constant values |
4141
// | | A \
4242
// | | | \
4343
// | |________________________________________________| \RefCntAutoPtr
@@ -74,7 +74,8 @@ class ShaderResourceCacheVk : public ShaderResourceCacheBase
7474
public:
7575
explicit ShaderResourceCacheVk(ResourceCacheContentType ContentType) noexcept :
7676
m_TotalResources{0},
77-
m_ContentType{static_cast<Uint32>(ContentType)}
77+
m_ContentType{static_cast<Uint32>(ContentType)},
78+
m_HasInlineConstants{0}
7879
{
7980
VERIFY_EXPR(GetContentType() == ContentType);
8081
}
@@ -88,12 +89,12 @@ class ShaderResourceCacheVk : public ShaderResourceCacheBase
8889

8990
~ShaderResourceCacheVk();
9091

91-
static size_t GetRequiredMemorySize(Uint32 NumSets, const Uint32* SetSizes);
92+
static size_t GetRequiredMemorySize(Uint32 NumSets, const Uint32* SetSizes, Uint32 TotalInlineConstantBytes = 0);
9293

93-
void InitializeSets(IMemoryAllocator& MemAllocator, Uint32 NumSets, const Uint32* SetSizes);
94+
void InitializeSets(IMemoryAllocator& MemAllocator, Uint32 NumSets, const Uint32* SetSizes, Uint32 TotalInlineConstantBytes = 0);
9495
void InitializeResources(Uint32 Set, Uint32 Offset, Uint32 ArraySize, DescriptorType Type, bool HasImmutableSampler);
9596

96-
// sizeof(Resource) == 32 (x64, msvc, Release)
97+
// sizeof(Resource) == 40 (x64, msvc, Release)
9798
struct Resource
9899
{
99100
explicit Resource(DescriptorType _Type, bool _HasImmutableSampler) noexcept :
@@ -120,6 +121,10 @@ class ShaderResourceCacheVk : public ShaderResourceCacheBase
120121
/*16 */ Uint64 BufferBaseOffset = 0;
121122
/*24 */ Uint64 BufferRangeSize = 0;
122123

124+
// For inline constants only - pointer to CPU-side staging buffer
125+
/*32 */ void* pInlineConstantData = nullptr;
126+
/*40 */ // End of structure
127+
123128
VkDescriptorBufferInfo GetUniformBufferDescriptorWriteInfo() const;
124129
VkDescriptorBufferInfo GetStorageBufferDescriptorWriteInfo() const;
125130
VkDescriptorImageInfo GetImageDescriptorWriteInfo () const;
@@ -245,13 +250,46 @@ class ShaderResourceCacheVk : public ShaderResourceCacheBase
245250
Uint32 CacheOffset,
246251
Uint32 DynamicBufferOffset);
247252

253+
// Sets inline constant data in the resource cache
254+
void SetInlineConstants(Uint32 DescrSetIndex,
255+
Uint32 CacheOffset,
256+
const void* pConstants,
257+
Uint32 FirstConstant,
258+
Uint32 NumConstants);
259+
260+
// Gets the inline constant data pointer from the resource cache
261+
const void* GetInlineConstantData(Uint32 DescrSetIndex, Uint32 CacheOffset) const;
262+
263+
// Initialize inline constant buffer in the resource cache
264+
void InitializeInlineConstantBuffer(Uint32 DescrSetIndex,
265+
Uint32 CacheOffset,
266+
Uint32 NumConstants,
267+
Uint32 InlineConstantOffset);
268+
269+
// Returns pointer to inline constant storage at the given byte offset
270+
void* GetInlineConstantStorage(Uint32 ByteOffset = 0)
271+
{
272+
return reinterpret_cast<Uint8*>(GetFirstResourcePtr() + m_TotalResources) + ByteOffset;
273+
}
274+
const void* GetInlineConstantStorage(Uint32 ByteOffset = 0) const
275+
{
276+
return reinterpret_cast<const Uint8*>(GetFirstResourcePtr() + m_TotalResources) + ByteOffset;
277+
}
278+
279+
// Explicitly marks that this cache contains inline constants.
280+
// This is useful when inline constant memory is initialized externally
281+
// (e.g., during SRB cache setup) before any data is written.
282+
void MarkHasInlineConstants()
283+
{
284+
m_HasInlineConstants = 1;
285+
}
248286

249287
Uint32 GetNumDescriptorSets() const { return m_NumSets; }
250288
bool HasDynamicResources() const { return m_NumDynamicBuffers > 0; }
251289

252290
bool HasInlineConstants() const
253291
{
254-
return false;
292+
return m_HasInlineConstants;
255293
}
256294

257295
ResourceCacheContentType GetContentType() const { return static_cast<ResourceCacheContentType>(m_ContentType); }
@@ -292,11 +330,14 @@ class ShaderResourceCacheVk : public ShaderResourceCacheBase
292330
// Total actual number of dynamic buffers (that were created with USAGE_DYNAMIC) bound in the resource cache
293331
// regardless of the variable type. Note this variable is not equal to dynamic offsets count, which is constant.
294332
Uint16 m_NumDynamicBuffers = 0;
295-
Uint32 m_TotalResources : 31;
333+
Uint32 m_TotalResources : 30;
296334

297335
// Indicates what types of resources are stored in the cache
298336
const Uint32 m_ContentType : 1;
299337

338+
// Indicates whether the cache contains inline constants
339+
Uint32 m_HasInlineConstants : 1;
340+
300341
#ifdef DILIGENT_DEBUG
301342
// Debug array that stores flags indicating if resources in the cache have been initialized
302343
std::vector<std::vector<bool>> m_DbgInitializedResources;

0 commit comments

Comments
 (0)