Skip to content

Commit 43fecc0

Browse files
ShaderResourceCacheD3D11: enable inline constants (#672)
1 parent 73be86c commit 43fecc0

File tree

5 files changed

+253
-18
lines changed

5 files changed

+253
-18
lines changed

Graphics/GraphicsEngineD3D11/include/PipelineResourceSignatureD3D11Impl.hpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019-2024 Diligent Graphics LLC
2+
* Copyright 2019-2025 Diligent Graphics LLC
33
* Copyright 2015-2019 Egor Yusov
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -60,6 +60,13 @@ struct ImmutableSamplerAttribsD3D11
6060
};
6161
ASSERT_SIZEOF(ImmutableSamplerAttribsD3D11, 12, "The struct is used in serialization and must be tightly packed");
6262

63+
struct InlineConstantBufferAttribsD3D11
64+
{
65+
D3D11ResourceBindPoints BindPoints;
66+
Uint32 NumConstants = 0;
67+
RefCntAutoPtr<BufferD3D11Impl> pBuffer;
68+
};
69+
6370

6471
struct PipelineResourceSignatureInternalDataD3D11 : PipelineResourceSignatureInternalData<PipelineResourceAttribsD3D11, ImmutableSamplerAttribsD3D11>
6572
{
@@ -128,6 +135,9 @@ class PipelineResourceSignatureD3D11Impl final : public PipelineResourceSignatur
128135
// Indicates which constant buffer slots are allowed to contain buffers with dynamic offsets.
129136
std::array<Uint16, NumShaderTypes> m_DynamicCBSlotsMask{};
130137
static_assert(sizeof(m_DynamicCBSlotsMask[0]) * 8 >= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, "Not enough bits for all dynamic buffer slots");
138+
139+
Uint32 m_NumInlineConstantBuffers = 0;
140+
std::unique_ptr<InlineConstantBufferAttribsD3D11[]> m_InlineConstantBuffers;
131141
};
132142

133143
} // namespace Diligent

Graphics/GraphicsEngineD3D11/include/ShaderResourceCacheD3D11.hpp

Lines changed: 105 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,15 @@
4949
namespace Diligent
5050
{
5151

52+
struct InlineConstantBufferAttribsD3D11;
53+
5254
/// The class implements a cache that holds resources bound to all shader stages.
5355
// All resources are stored in the continuous memory using the following layout:
5456
//
55-
// | CachedCB | ID3D11Buffer* || CachedResource | ID3D11ShaderResourceView* || CachedSampler | ID3D11SamplerState* || CachedResource | ID3D11UnorderedAccessView*||
56-
// |--------------------------|------------------------||--------------------------|---------------------------||------------------------------|-----------------------------||-------------------------|---------------------------||
57-
// | 0 | 1 | ... | CBCount-1 | 0 | 1 | ...| CBCount-1 || 0 | 1 | ... | SRVCount-1 | 0 | 1 | ... | SRVCount-1 || 0 | 1 | ... | SamplerCount-1 | 0 | 1 | ...| SamplerCount-1 ||0 | 1 | ... | UAVCount-1 | 0 | 1 | ... | UAVCount-1 ||
58-
// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
57+
// | CachedCB | ID3D11Buffer* || CachedResource | ID3D11ShaderResourceView* || CachedSampler | ID3D11SamplerState* || CachedResource | ID3D11UnorderedAccessView*| Inline Constants |
58+
// |--------------------------|------------------------||--------------------------|---------------------------||------------------------------|-----------------------------||-------------------------|---------------------------|------------------|
59+
// | 0 | 1 | ... | CBCount-1 | 0 | 1 | ...| CBCount-1 || 0 | 1 | ... | SRVCount-1 | 0 | 1 | ... | SRVCount-1 || 0 | 1 | ... | SamplerCount-1 | 0 | 1 | ...| SamplerCount-1 ||0 | 1 | ... | UAVCount-1 | 0 | 1 | ... | UAVCount-1 | 0 | 1 | ... |
60+
// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
5961
//
6062
class ShaderResourceCacheD3D11 : public ShaderResourceCacheBase
6163
{
@@ -89,6 +91,9 @@ class ShaderResourceCacheD3D11 : public ShaderResourceCacheBase
8991
// Dynamic offset in bytes
9092
Uint32 DynamicOffset = 0;
9193

94+
// Pointer to inline constant data
95+
void* pInlineConstantData = nullptr;
96+
9297
explicit operator bool() const noexcept
9398
{
9499
return pBuff;
@@ -138,6 +143,17 @@ class ShaderResourceCacheD3D11 : public ShaderResourceCacheBase
138143
return pBuff && RangeSize != 0 && RangeSize < pBuff->GetDesc().Size;
139144
}
140145

146+
void SetInlineConstants(const void* pSrcConstants, Uint32 FirstConstant, Uint32 NumConstants)
147+
{
148+
VERIFY(pSrcConstants != nullptr, "Source constant data pointer is null");
149+
VERIFY(FirstConstant + NumConstants <= RangeSize / sizeof(Uint32),
150+
"Too many constants (", FirstConstant + NumConstants, ") for the allocated space (", RangeSize / sizeof(Uint32), ")");
151+
VERIFY(pInlineConstantData != nullptr, "Inline constant data pointer is null");
152+
memcpy(reinterpret_cast<Uint8*>(pInlineConstantData) + FirstConstant * sizeof(Uint32),
153+
pSrcConstants,
154+
NumConstants * sizeof(Uint32));
155+
}
156+
141157
// Returns ID3D11Buffer
142158
template <D3D11_RESOURCE_RANGE ResRange>
143159
typename CachedResourceTraits<ResRange>::D3D11ResourceType* GetD3D11Resource();
@@ -247,7 +263,9 @@ class ShaderResourceCacheD3D11 : public ShaderResourceCacheBase
247263
// Static resource cache does not allow dynamic buffers (pDynamicCBSlotsMask == null).
248264
void Initialize(const D3D11ShaderResourceCounters& ResCount,
249265
IMemoryAllocator& MemAllocator,
250-
const std::array<Uint16, NumShaderTypes>* pDynamicCBSlotsMask);
266+
const std::array<Uint16, NumShaderTypes>* pDynamicCBSlotsMask,
267+
const InlineConstantBufferAttribsD3D11* pInlineCBs,
268+
Uint32 NumInlineCBs);
251269

252270
template <D3D11_RESOURCE_RANGE ResRange, typename TSrcResourceType, typename... ExtraArgsType>
253271
inline void SetResource(const D3D11ResourceBindPoints& BindPoints,
@@ -256,6 +274,10 @@ class ShaderResourceCacheD3D11 : public ShaderResourceCacheBase
256274

257275
__forceinline void SetDynamicCBOffset(const D3D11ResourceBindPoints& BindPoints, Uint32 DynamicOffset);
258276

277+
__forceinline void SetInlineConstants(const D3D11ResourceBindPoints& BindPoints,
278+
const void* pConstants,
279+
Uint32 FirstConstant,
280+
Uint32 NumConstants);
259281

260282
template <D3D11_RESOURCE_RANGE ResRange>
261283
__forceinline const typename CachedResourceTraits<ResRange>::CachedResourceType& GetResource(const D3D11ResourceBindPoints& BindPoints) const
@@ -289,6 +311,8 @@ class ShaderResourceCacheD3D11 : public ShaderResourceCacheBase
289311
template <D3D11_RESOURCE_RANGE ResRange>
290312
bool CopyResource(const ShaderResourceCacheD3D11& SrcCache, const D3D11ResourceBindPoints& BindPoints);
291313

314+
inline void CopyInlineConstants(const ShaderResourceCacheD3D11& SrcCache, const D3D11ResourceBindPoints& BindPoints, Uint32 NumConstants);
315+
292316
template <D3D11_RESOURCE_RANGE ResRange>
293317
__forceinline bool IsResourceBound(const D3D11ResourceBindPoints& BindPoints) const
294318
{
@@ -402,6 +426,11 @@ class ShaderResourceCacheD3D11 : public ShaderResourceCacheBase
402426
#endif
403427

404428
private:
429+
void InitInlineConstantBuffer(const D3D11ResourceBindPoints& BindPoints,
430+
RefCntAutoPtr<BufferD3D11Impl> pBuffer,
431+
Uint32 NumConstants,
432+
void* pInlineConstantData);
433+
405434
template <D3D11_RESOURCE_RANGE>
406435
__forceinline Uint32 GetResourceDataOffset(Uint32 ShaderInd) const;
407436

@@ -730,6 +759,35 @@ __forceinline void ShaderResourceCacheD3D11::SetDynamicCBOffset(const D3D11Resou
730759
}
731760
}
732761

762+
__forceinline void ShaderResourceCacheD3D11::SetInlineConstants(const D3D11ResourceBindPoints& BindPoints,
763+
const void* pConstants,
764+
Uint32 FirstConstant,
765+
Uint32 NumConstants)
766+
{
767+
SHADER_TYPE ActiveStages = BindPoints.GetActiveStages();
768+
VERIFY_EXPR(ActiveStages != SHADER_TYPE_UNKNOWN);
769+
const Uint32 ShaderInd0 = ExtractFirstShaderStageIndex(ActiveStages);
770+
const Uint32 Binding0 = BindPoints[ShaderInd0];
771+
VERIFY(Binding0 < GetResourceCount<D3D11_RESOURCE_RANGE_CBV>(ShaderInd0), "Cache offset is out of range");
772+
const auto ResArrays0 = GetResourceArrays<D3D11_RESOURCE_RANGE_CBV>(ShaderInd0);
773+
ResArrays0.first[Binding0].SetInlineConstants(pConstants, FirstConstant, NumConstants);
774+
775+
#ifdef DILIGENT_DEBUG
776+
while (ActiveStages != SHADER_TYPE_UNKNOWN)
777+
{
778+
const Uint32 ShaderInd = ExtractFirstShaderStageIndex(ActiveStages);
779+
const Uint32 Binding = BindPoints[ShaderInd];
780+
VERIFY(Binding < GetResourceCount<D3D11_RESOURCE_RANGE_CBV>(ShaderInd), "Cache offset is out of range");
781+
782+
const auto ResArrays = GetResourceArrays<D3D11_RESOURCE_RANGE_CBV>(ShaderInd);
783+
VERIFY(ResArrays.first[Binding].pInlineConstantData == ResArrays0.first[Binding0].pInlineConstantData,
784+
"All active shader stages must share the same inline constant data");
785+
VERIFY(ResArrays.first[Binding] == ResArrays0.first[Binding0],
786+
"All active shader stages must share the same inline constant data attributes");
787+
}
788+
#endif
789+
}
790+
733791
template <>
734792
inline void ShaderResourceCacheD3D11::UpdateDynamicCBOffsetFlag<D3D11_RESOURCE_RANGE_CBV>(
735793
const ShaderResourceCacheD3D11::CachedCB& CB,
@@ -787,6 +845,48 @@ bool ShaderResourceCacheD3D11::CopyResource(const ShaderResourceCacheD3D11& SrcC
787845
return IsBound;
788846
}
789847

848+
inline void ShaderResourceCacheD3D11::CopyInlineConstants(const ShaderResourceCacheD3D11& SrcCache, const D3D11ResourceBindPoints& BindPoints, Uint32 NumConstants)
849+
{
850+
SHADER_TYPE ActiveStages = BindPoints.GetActiveStages();
851+
VERIFY_EXPR(ActiveStages != SHADER_TYPE_UNKNOWN);
852+
853+
const Int32 ShaderInd0 = ExtractFirstShaderStageIndex(ActiveStages);
854+
855+
const auto SrcResArrays0 = SrcCache.GetConstResourceArrays<D3D11_RESOURCE_RANGE_CBV>(ShaderInd0);
856+
const auto DstResArrays0 = GetResourceArrays<D3D11_RESOURCE_RANGE_CBV>(ShaderInd0);
857+
858+
const Uint32 Binding0 = BindPoints[ShaderInd0];
859+
VERIFY(Binding0 < GetResourceCount<D3D11_RESOURCE_RANGE_CBV>(ShaderInd0), "Destination index is out of range");
860+
VERIFY(Binding0 < SrcCache.GetResourceCount<D3D11_RESOURCE_RANGE_CBV>(ShaderInd0), "Source index is out of range");
861+
VERIFY(SrcResArrays0.first[Binding0].pInlineConstantData != nullptr, "Source inline constant data is null");
862+
VERIFY(DstResArrays0.first[Binding0].pInlineConstantData != nullptr, "Destination inline constant data is null");
863+
VERIFY(SrcResArrays0.first[Binding0].RangeSize == NumConstants * sizeof(Uint32), "Source inline constant buffer size mismatch");
864+
VERIFY(DstResArrays0.first[Binding0].RangeSize == NumConstants * sizeof(Uint32), "Destination inline constant buffer size mismatch");
865+
memcpy(DstResArrays0.first[Binding0].pInlineConstantData,
866+
SrcResArrays0.first[Binding0].pInlineConstantData,
867+
NumConstants * sizeof(Uint32));
868+
869+
#ifdef DILIGENT_DEBUG
870+
while (ActiveStages != SHADER_TYPE_UNKNOWN)
871+
{
872+
const Int32 ShaderInd = ExtractFirstShaderStageIndex(ActiveStages);
873+
874+
const auto SrcResArrays = SrcCache.GetConstResourceArrays<D3D11_RESOURCE_RANGE_CBV>(ShaderInd);
875+
const auto DstResArrays = GetResourceArrays<D3D11_RESOURCE_RANGE_CBV>(ShaderInd);
876+
877+
const Uint32 Binding = BindPoints[ShaderInd];
878+
VERIFY(Binding < GetResourceCount<D3D11_RESOURCE_RANGE_CBV>(ShaderInd), "Index is out of range");
879+
VERIFY(Binding < SrcCache.GetResourceCount<D3D11_RESOURCE_RANGE_CBV>(ShaderInd), "Index is out of range");
880+
VERIFY(SrcResArrays0.first[Binding0] == SrcResArrays.first[Binding], "All shader stages must share the same inline constant data attributes");
881+
VERIFY(DstResArrays0.first[Binding0] == DstResArrays.first[Binding], "All shader stages must share the same inline constant data attributes");
882+
VERIFY(SrcResArrays0.first[Binding0].pInlineConstantData == SrcResArrays.first[Binding].pInlineConstantData,
883+
"All active shader stages must share the same inline constant data");
884+
VERIFY(DstResArrays0.first[Binding0].pInlineConstantData == DstResArrays.first[Binding].pInlineConstantData,
885+
"All active shader stages must share the same inline constant data");
886+
}
887+
#endif
888+
}
889+
790890
template <>
791891
__forceinline ID3D11Buffer* ShaderResourceCacheD3D11::CachedCB::GetD3D11Resource<D3D11_RESOURCE_RANGE_CBV>()
792892
{

0 commit comments

Comments
 (0)