git.s-ol.nu ~forks/DiligentCore / 0420f68
Some more code improvemnts in D3D11 backend assiduous 6 months ago
11 changed file(s) with 268 addition(s) and 199 deletion(s). Raw diff Collapse all Expand all
436436 return PlatformMisc::GetLSB(Type);
437437 }
438438
439 inline Int32 GetFirstShaderStageIndex(SHADER_TYPE Stages)
440 {
441 if (Stages == SHADER_TYPE_UNKNOWN)
442 return -1;
443
444 VERIFY(Stages > SHADER_TYPE_UNKNOWN && Stages < SHADER_TYPE_LAST * 2, "Value ", Uint32{Stages}, " is not a valid SHADER_TYPE enum value");
445
446 return PlatformMisc::GetLSB(Stages);
447 }
448
449 inline Int32 ExtractFirstShaderStageIndex(SHADER_TYPE& Stages)
450 {
451 if (Stages == SHADER_TYPE_UNKNOWN)
452 return -1;
453
454 VERIFY(Stages > SHADER_TYPE_UNKNOWN && Stages < SHADER_TYPE_LAST * 2, "Value ", Uint32{Stages}, " is not a valid SHADER_TYPE enum value");
455
456 const auto StageIndex = PlatformMisc::GetLSB(Stages);
457 Stages &= ~static_cast<SHADER_TYPE>(1u << StageIndex);
458 return StageIndex;
459 }
460
461
439462 static_assert(SHADER_TYPE_LAST == 0x2000, "Please add the new shader type index below");
440463
441464 static constexpr Int32 VSInd = 0;
337337
338338 void BindShaderResources();
339339
340 static constexpr int NumShaderTypes = BindPointsD3D11::NumShaderTypes;
340 static constexpr int NumShaderTypes = D3D11ResourceBindPoints::NumShaderTypes;
341341 struct TCommittedResources
342342 {
343343 // clang-format off
392392 Bind
393393 };
394394
395 using TBindingsPerStage = PipelineResourceSignatureD3D11Impl::TBindingsPerStage;
396 void BindCacheResources(const ShaderResourceCacheD3D11& ResourceCache,
397 const TBindingsPerStage& BaseBindings,
398 SHADER_TYPE ActiveStages,
399 PixelShaderUAVBindMode& PsUavBindMode);
395 void BindCacheResources(const ShaderResourceCacheD3D11& ResourceCache,
396 const D3D11ShaderResourceCounters& BaseBindings,
397 SHADER_TYPE ActiveStages,
398 PixelShaderUAVBindMode& PsUavBindMode);
400399
401400 #ifdef DILIGENT_DEVELOPMENT
402401 void DvpValidateCommittedShaderResources();
423422 bool CommittedResourcesValidated = false;
424423
425424 // Binding offsets that was used at last BindProgramResources() call.
426 std::array<TBindingsPerStage, MAX_RESOURCE_SIGNATURES> BoundResOffsets = {};
425 std::array<D3D11ShaderResourceCounters, MAX_RESOURCE_SIGNATURES> BoundResOffsets = {};
427426 #endif
428427
429428 SRBState()
3333
3434 #include "BasicTypes.h"
3535 #include "DebugUtilities.hpp"
36 #include "HashUtils.hpp"
37 #include "GraphicsAccessories.hpp"
3638
3739 namespace Diligent
3840 {
4951 D3D11_RESOURCE_RANGE ShaderResourceToDescriptorRange(SHADER_RESOURCE_TYPE Type);
5052
5153
52 // sizeof(BindPointsD3D11) == 8, x64
53 struct BindPointsD3D11
54 /// Resource binding points in all shader stages.
55 // sizeof(D3D11ResourceBindPoints) == 8, x64
56 struct D3D11ResourceBindPoints
5457 {
5558 /// Number of different shader types (Vertex, Pixel, Geometry, Domain, Hull, Compute)
5659 static constexpr Uint32 NumShaderTypes = 6;
5760
61 D3D11ResourceBindPoints() noexcept
62 {
63 #ifdef DILIGENT_DEBUG
64 for (auto BindPoint : Bindings)
65 VERIFY_EXPR(BindPoint == InvalidBindPoint);
66 #endif
67 }
68
69 D3D11ResourceBindPoints(const D3D11ResourceBindPoints&) noexcept = default;
70
71 SHADER_TYPE GetActiveStages() const
72 {
73 return static_cast<SHADER_TYPE>(ActiveStages);
74 }
75
76 bool IsEmpty() const
77 {
78 return GetActiveStages() == SHADER_TYPE_UNKNOWN;
79 }
80
81 bool IsStageActive(Uint32 ShaderInd) const
82 {
83 bool IsActive = (GetActiveStages() & (1u << ShaderInd)) != 0;
84 VERIFY_EXPR((IsActive && Bindings[ShaderInd] != InvalidBindPoint ||
85 !IsActive && Bindings[ShaderInd] == InvalidBindPoint));
86 return IsActive;
87 }
88
89 Uint8 operator[](Uint32 ShaderInd) const
90 {
91 return Bindings[ShaderInd];
92 }
93
94 size_t GetHash() const
95 {
96 size_t Hash = 0;
97 for (auto Binding : Bindings)
98 HashCombine(Hash, Binding);
99 return Hash;
100 }
101
102 bool operator==(const D3D11ResourceBindPoints& rhs) const
103 {
104 return Bindings == rhs.Bindings;
105 }
106
107 D3D11ResourceBindPoints operator+(Uint32 value) const
108 {
109 D3D11ResourceBindPoints NewBindPoints{*this};
110 for (auto Stages = GetActiveStages(); Stages != 0;)
111 {
112 auto ShaderInd = ExtractFirstShaderStageIndex(Stages);
113 VERIFY_EXPR(Uint32{Bindings[ShaderInd]} + value < InvalidBindPoint);
114 NewBindPoints.Bindings[ShaderInd] = Bindings[ShaderInd] + static_cast<Uint8>(value);
115 }
116 return NewBindPoints;
117 }
118
119 private:
120 struct SetBindPointHelper
121 {
122 SetBindPointHelper(D3D11ResourceBindPoints& _BindPoints,
123 const Uint32 _ShaderInd) :
124 BindPoints{_BindPoints},
125 ShaderInd{_ShaderInd}
126 {}
127
128 Uint8 operator=(Uint32 BindPoint)
129 {
130 BindPoints.Set(ShaderInd, BindPoint);
131 return static_cast<Uint8>(BindPoint);
132 }
133
134 operator Uint8() const
135 {
136 return static_cast<const D3D11ResourceBindPoints&>(BindPoints)[ShaderInd];
137 }
138
139 private:
140 D3D11ResourceBindPoints& BindPoints;
141 const Uint32 ShaderInd;
142 };
143
144 public:
145 SetBindPointHelper operator[](Uint32 ShaderInd)
146 {
147 return SetBindPointHelper{*this, ShaderInd};
148 }
149
150 private:
151 void Set(Uint32 ShaderInd, Uint32 BindPoint)
152 {
153 VERIFY_EXPR(ShaderInd < NumShaderTypes);
154 VERIFY(BindPoint < InvalidBindPoint, "Bind point (", BindPoint, ") is out of range");
155
156 Bindings[ShaderInd] = static_cast<Uint8>(BindPoint);
157 ActiveStages |= Uint32{1} << ShaderInd;
158 }
159
58160 static constexpr Uint8 InvalidBindPoint = 0xFF;
59161
60 BindPointsD3D11() noexcept {}
61 BindPointsD3D11(const BindPointsD3D11&) noexcept = default;
62
63 // clang-format off
64 bool IsEmpty() const { return m_ActiveBits == 0; }
65 Uint32 GetActiveBits() const { return m_ActiveBits; }
66 bool IsValid(Uint32 index) const { return m_Bindings[index] != InvalidBindPoint; }
67 Uint8 operator[](Uint32 index) const { return m_Bindings[index]; }
68 // clang-format on
69
70 void Set(Uint32 Index, Uint32 BindPoint)
71 {
72 VERIFY_EXPR(Index < NumShaderTypes);
73 VERIFY_EXPR(BindPoint < InvalidBindPoint);
74 m_ActiveBits = static_cast<Uint8>(m_ActiveBits | (1u << Index));
75 m_Bindings[Index] = static_cast<Uint8>(BindPoint);
76 }
77
78 size_t GetHash() const
79 {
80 size_t Hash = 0;
81 for (Uint32 i = 0; i < NumShaderTypes; ++i)
82 HashCombine(Hash, m_Bindings[i]);
83 return Hash;
84 }
85
86 bool operator==(const BindPointsD3D11& rhs) const
87 {
88 return m_Bindings == rhs.m_Bindings;
89 }
90
91 BindPointsD3D11 operator+(Uint32 value) const
92 {
93 BindPointsD3D11 Result{*this};
94 for (Uint32 Bits = Result.m_ActiveBits; Bits != 0;)
95 {
96 auto Index = PlatformMisc::GetLSB(Bits);
97 Bits &= ~(1u << Index);
98
99 auto NewBindPoint = Result.m_Bindings[Index] + value;
100 VERIFY_EXPR(NewBindPoint < InvalidBindPoint);
101 Result.m_Bindings[Index] = static_cast<Uint8>(NewBindPoint);
102 }
103 return Result;
104 }
105
106 private:
107 Uint8 m_ActiveBits = 0;
108 std::array<Uint8, NumShaderTypes> m_Bindings = {InvalidBindPoint, InvalidBindPoint, InvalidBindPoint, InvalidBindPoint, InvalidBindPoint, InvalidBindPoint};
162 // 0 1 2 3 4 5
163 // | PS | VS | GS | HS | DS | CS |
164 std::array<Uint8, NumShaderTypes> Bindings{InvalidBindPoint, InvalidBindPoint, InvalidBindPoint, InvalidBindPoint, InvalidBindPoint, InvalidBindPoint};
165
166 Uint8 ActiveStages = 0;
109167 };
168
169
170 /// Resource counters for all shader stages and all resource types
171 using D3D11ShaderResourceCounters = std::array<std::array<Uint8, D3D11ResourceBindPoints::NumShaderTypes>, D3D11_RESOURCE_RANGE_COUNT>;
110172
111173
112174 // sizeof(PipelineResourceAttribsD3D11) == 12, x64
122184 // clang-format off
123185 const Uint32 SamplerInd : _SamplerIndBits; // Index of the assigned sampler in m_Desc.Resources.
124186 const Uint32 ImtblSamplerAssigned : _SamplerAssignedBits; // Immutable sampler flag.
125 BindPointsD3D11 BindPoints;
187 D3D11ResourceBindPoints BindPoints;
126188 // clang-format on
127189
128190 PipelineResourceAttribsD3D11(Uint32 _SamplerInd,
3131
3232 #include <array>
3333
34 #include "ResourceBindingMap.hpp"
35
3634 #include "EngineD3D11ImplTraits.hpp"
3735 #include "PipelineResourceSignatureBase.hpp"
3836 #include "PipelineResourceAttribsD3D11.hpp"
3937
4038 // ShaderVariableManagerD3D11, ShaderResourceCacheD3D11, and ShaderResourceBindingD3D11Impl
4139 // are required by PipelineResourceSignatureBase
40 #include "ShaderResourceCacheD3D11.hpp"
4241 #include "ShaderVariableManagerD3D11.hpp"
4342 #include "ShaderResourceBindingD3D11Impl.hpp"
44 #include "ShaderResourceCacheD3D11.hpp"
43 #include "SamplerD3D11Impl.hpp"
44
45 #include "ResourceBindingMap.hpp"
4546
4647 namespace Diligent
4748 {
5859 bool bIsDeviceInternal = false);
5960 ~PipelineResourceSignatureD3D11Impl();
6061
61 using ResourceAttribs = PipelineResourceAttribsD3D11;
62 static constexpr auto NumShaderTypes = BindPointsD3D11::NumShaderTypes;
62 using ResourceAttribs = PipelineResourceAttribsD3D11;
6363
6464 const ResourceAttribs& GetResourceAttribs(Uint32 ResIndex) const
6565 {
7171 struct ImmutableSamplerAttribs
7272 {
7373 public:
74 RefCntAutoPtr<ISampler> pSampler;
75 Uint32 ArraySize = 0;
76 BindPointsD3D11 BindPoints;
74 RefCntAutoPtr<SamplerD3D11Impl> pSampler;
75 Uint32 ArraySize = 0;
76 D3D11ResourceBindPoints BindPoints;
7777
7878 ImmutableSamplerAttribs() noexcept {}
7979
80 bool IsAllocated() const { return !BindPoints.IsEmpty(); }
81 SamplerD3D11Impl* GetSamplerD3D11() const { return ValidatedCast<SamplerD3D11Impl>(pSampler.RawPtr<ISampler>()); }
80 bool IsAllocated() const { return !BindPoints.IsEmpty(); }
8281 };
8382
8483 const ImmutableSamplerAttribs& GetImmutableSamplerAttribs(Uint32 SampIndex) const
8786 return m_ImmutableSamplers[SampIndex];
8887 }
8988
90 using TResourceCount = std::array<Uint8, D3D11_RESOURCE_RANGE_COUNT>;
91 using TBindingsPerStage = std::array<std::array<Uint8, NumShaderTypes>, D3D11_RESOURCE_RANGE_COUNT>;
92
93 __forceinline void ShiftBindings(TBindingsPerStage& Bindings) const
89 __forceinline void ShiftBindings(D3D11ShaderResourceCounters& Bindings) const
9490 {
9591 for (Uint32 r = 0; r < Bindings.size(); ++r)
9692 {
105101
106102 void InitSRBResourceCache(ShaderResourceCacheD3D11& ResourceCache);
107103
108 void UpdateShaderResourceBindingMap(ResourceBinding::TMap& ResourceMap, SHADER_TYPE ShaderStage, const TBindingsPerStage& BaseBindings) const;
104 void UpdateShaderResourceBindingMap(ResourceBinding::TMap& ResourceMap, SHADER_TYPE ShaderStage, const D3D11ShaderResourceCounters& BaseBindings) const;
109105
110106 // Copies static resources from the static resource cache to the destination cache
111107 void CopyStaticResources(ShaderResourceCacheD3D11& ResourceCache) const;
125121 void Destruct();
126122
127123 private:
128 TBindingsPerStage m_BindingCountPerStage = {};
129 ResourceAttribs* m_pResourceAttribs = nullptr; // [m_Desc.NumResources]
130 ImmutableSamplerAttribs* m_ImmutableSamplers = nullptr; // [m_Desc.NumImmutableSamplers]
124 D3D11ShaderResourceCounters m_BindingCountPerStage = {};
125 ResourceAttribs* m_pResourceAttribs = nullptr; // [m_Desc.NumResources]
126 ImmutableSamplerAttribs* m_ImmutableSamplers = nullptr; // [m_Desc.NumImmutableSamplers]
131127 };
132128
133129 } // namespace Diligent
9191 SHADER_TYPE GetShaderStageType(Uint32 Index) const;
9292
9393 #ifdef DILIGENT_DEVELOPMENT
94 using TBindingsPerStage = PipelineResourceSignatureD3D11Impl::TBindingsPerStage;
95 void DvpVerifySRBResources(class ShaderResourceBindingD3D11Impl* pSRBs[], const TBindingsPerStage BaseBindings[], Uint32 NumSRBs) const;
94 void DvpVerifySRBResources(class ShaderResourceBindingD3D11Impl* pSRBs[], const D3D11ShaderResourceCounters BaseBindings[], Uint32 NumSRBs) const;
9695 #endif
9796
9897 private:
155155 template <D3D11_RESOURCE_RANGE>
156156 struct CachedResourceTraits;
157157
158 static constexpr int NumShaderTypes = BindPointsD3D11::NumShaderTypes;
159 using TResourcesPerStage = std::array<std::array<Uint8, NumShaderTypes>, D3D11_RESOURCE_RANGE_COUNT>;
160
161 static size_t GetRequriedMemorySize(const TResourcesPerStage& ResCount);
162
163 void Initialize(const TResourcesPerStage& ResCount, IMemoryAllocator& MemAllocator);
164
165 __forceinline void SetCB(BindPointsD3D11 BindPoints, RefCntAutoPtr<BufferD3D11Impl> pBuffD3D11Impl)
158 static size_t GetRequriedMemorySize(const D3D11ShaderResourceCounters& ResCount);
159
160 void Initialize(const D3D11ShaderResourceCounters& ResCount, IMemoryAllocator& MemAllocator);
161
162 __forceinline void SetCB(const D3D11ResourceBindPoints& BindPoints, RefCntAutoPtr<BufferD3D11Impl> pBuffD3D11Impl)
166163 {
167164 auto* pd3d11Buff = pBuffD3D11Impl ? pBuffD3D11Impl->BufferD3D11Impl::GetD3D11Buffer() : nullptr;
168165 SetD3D11ResourceInternal<D3D11_RESOURCE_RANGE_CBV>(BindPoints, std::move(pBuffD3D11Impl), pd3d11Buff);
169166 }
170167
171 __forceinline void SetTexSRV(BindPointsD3D11 BindPoints, RefCntAutoPtr<TextureViewD3D11Impl> pTexView)
168 __forceinline void SetTexSRV(const D3D11ResourceBindPoints& BindPoints, RefCntAutoPtr<TextureViewD3D11Impl> pTexView)
172169 {
173170 auto* pd3d11SRV = pTexView ? static_cast<ID3D11ShaderResourceView*>(pTexView->TextureViewD3D11Impl::GetD3D11View()) : nullptr;
174171 SetD3D11ResourceInternal<D3D11_RESOURCE_RANGE_SRV>(BindPoints, std::move(pTexView), pd3d11SRV);
175172 }
176173
177 __forceinline void SetBufSRV(BindPointsD3D11 BindPoints, RefCntAutoPtr<BufferViewD3D11Impl> pBuffView)
174 __forceinline void SetBufSRV(const D3D11ResourceBindPoints& BindPoints, RefCntAutoPtr<BufferViewD3D11Impl> pBuffView)
178175 {
179176 auto* pd3d11SRV = pBuffView ? static_cast<ID3D11ShaderResourceView*>(pBuffView->BufferViewD3D11Impl::GetD3D11View()) : nullptr;
180177 SetD3D11ResourceInternal<D3D11_RESOURCE_RANGE_SRV>(BindPoints, std::move(pBuffView), pd3d11SRV);
181178 }
182179
183 __forceinline void SetTexUAV(BindPointsD3D11 BindPoints, RefCntAutoPtr<TextureViewD3D11Impl> pTexView)
180 __forceinline void SetTexUAV(const D3D11ResourceBindPoints& BindPoints, RefCntAutoPtr<TextureViewD3D11Impl> pTexView)
184181 {
185182 auto* pd3d11UAV = pTexView ? static_cast<ID3D11UnorderedAccessView*>(pTexView->TextureViewD3D11Impl::GetD3D11View()) : nullptr;
186183 SetD3D11ResourceInternal<D3D11_RESOURCE_RANGE_UAV>(BindPoints, std::move(pTexView), pd3d11UAV);
187184 }
188185
189 __forceinline void SetBufUAV(BindPointsD3D11 BindPoints, RefCntAutoPtr<BufferViewD3D11Impl> pBuffView)
186 __forceinline void SetBufUAV(const D3D11ResourceBindPoints& BindPoints, RefCntAutoPtr<BufferViewD3D11Impl> pBuffView)
190187 {
191188 auto* pd3d11UAV = pBuffView ? static_cast<ID3D11UnorderedAccessView*>(pBuffView->BufferViewD3D11Impl::GetD3D11View()) : nullptr;
192189 SetD3D11ResourceInternal<D3D11_RESOURCE_RANGE_UAV>(BindPoints, std::move(pBuffView), pd3d11UAV);
193190 }
194191
195 __forceinline void SetSampler(BindPointsD3D11 BindPoints, SamplerD3D11Impl* pSampler)
192 __forceinline void SetSampler(const D3D11ResourceBindPoints& BindPoints, SamplerD3D11Impl* pSampler)
196193 {
197194 auto* pd3d11Sampler = pSampler ? pSampler->SamplerD3D11Impl::GetD3D11SamplerState() : nullptr;
198195 SetD3D11ResourceInternal<D3D11_RESOURCE_RANGE_SAMPLER>(BindPoints, pSampler, pd3d11Sampler);
200197
201198
202199 template <D3D11_RESOURCE_RANGE ResRange>
203 __forceinline const typename CachedResourceTraits<ResRange>::CachedResourceType& GetResource(BindPointsD3D11 BindPoints) const
204 {
205 VERIFY(BindPoints.GetActiveBits() != 0, "No active shader stage");
206 const auto ShaderInd = PlatformMisc::GetLSB(BindPoints.GetActiveBits());
200 __forceinline const typename CachedResourceTraits<ResRange>::CachedResourceType& GetResource(const D3D11ResourceBindPoints& BindPoints) const
201 {
202 VERIFY(BindPoints.GetActiveStages() != SHADER_TYPE_UNKNOWN, "No active shader stage");
203 const auto ShaderInd = GetFirstShaderStageIndex(BindPoints.GetActiveStages());
207204 const auto Offset = BindPoints[ShaderInd];
208205 VERIFY(Offset < GetResourceCount<ResRange>(ShaderInd), "Resource slot is out of range");
209206 const auto ResArrays = GetConstResourceArrays<ResRange>(ShaderInd);
211208 }
212209
213210 template <D3D11_RESOURCE_RANGE ResRange>
214 bool CopyResource(const ShaderResourceCacheD3D11& SrcCache, BindPointsD3D11 BindPoints)
211 bool CopyResource(const ShaderResourceCacheD3D11& SrcCache, const D3D11ResourceBindPoints& BindPoints)
215212 {
216213 bool IsBound = true;
217 for (Uint32 ActiveBits = BindPoints.GetActiveBits(); ActiveBits != 0;)
218 {
219 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
220 ActiveBits &= ~(1u << ShaderInd);
214 for (auto ActiveStages = BindPoints.GetActiveStages(); ActiveStages != SHADER_TYPE_UNKNOWN;)
215 {
216 const auto ShaderInd = ExtractFirstShaderStageIndex(ActiveStages);
221217
222218 auto SrcResArrays = SrcCache.GetConstResourceArrays<ResRange>(ShaderInd);
223219 auto DstResArrays = GetResourceArrays<ResRange>(ShaderInd);
235231 }
236232
237233 template <D3D11_RESOURCE_RANGE ResRange>
238 __forceinline bool IsResourceBound(BindPointsD3D11 BindPoints) const
239 {
240 Uint32 ActiveBits = BindPoints.GetActiveBits();
241 if (ActiveBits == 0)
234 __forceinline bool IsResourceBound(const D3D11ResourceBindPoints& BindPoints) const
235 {
236 if (BindPoints.IsEmpty())
242237 return false;
243238
244 const Uint32 FirstShaderInd = PlatformMisc::GetLSB(ActiveBits);
245 const bool IsBound = IsResourceBound<ResRange>(FirstShaderInd, BindPoints[FirstShaderInd]);
239 auto ActiveStages = BindPoints.GetActiveStages();
240 const auto FirstShaderInd = ExtractFirstShaderStageIndex(ActiveStages);
241 const bool IsBound = IsResourceBound<ResRange>(FirstShaderInd, BindPoints[FirstShaderInd]);
246242
247243 #ifdef DILIGENT_DEBUG
248 ActiveBits &= ~(1u << FirstShaderInd);
249 while (ActiveBits != 0)
250 {
251 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
252 ActiveBits &= ~(1u << ShaderInd);
244 while (ActiveStages != SHADER_TYPE_UNKNOWN)
245 {
246 const Uint32 ShaderInd = ExtractFirstShaderStageIndex(ActiveStages);
253247 VERIFY_EXPR(IsBound == IsResourceBound<ResRange>(ShaderInd, BindPoints[ShaderInd]));
254248 }
255249 #endif
297291 template <D3D11_RESOURCE_RANGE Range>
298292 inline MinMaxSlot BindResources(Uint32 ShaderInd,
299293 typename CachedResourceTraits<Range>::D3D11ResourceType* CommittedD3D11Resources[],
300 const TResourcesPerStage& BaseBindings) const;
294 const D3D11ShaderResourceCounters& BaseBindings) const;
301295
302296 template <D3D11_RESOURCE_RANGE Range>
303297 inline MinMaxSlot BindResourceViews(Uint32 ShaderInd,
304298 typename CachedResourceTraits<Range>::D3D11ResourceType* CommittedD3D11Views[],
305299 ID3D11Resource* CommittedD3D11Resources[],
306 const TResourcesPerStage& BaseBindings) const;
300 const D3D11ShaderResourceCounters& BaseBindings) const;
307301
308302 enum class StateTransitionMode
309303 {
344338 }
345339
346340 template <D3D11_RESOURCE_RANGE ResRange, typename TSrcResourceType, typename TD3D11ResourceType>
347 __forceinline void SetD3D11ResourceInternal(BindPointsD3D11 BindPoints, TSrcResourceType pResource, TD3D11ResourceType* pd3d11Resource)
341 __forceinline void SetD3D11ResourceInternal(const D3D11ResourceBindPoints& BindPoints, TSrcResourceType pResource, TD3D11ResourceType* pd3d11Resource)
348342 {
349343 VERIFY(pResource != nullptr && pd3d11Resource != nullptr || pResource == nullptr && pd3d11Resource == nullptr,
350344 "Resource and D3D11 resource must be set/unset atomically");
351 for (Uint32 ActiveBits = BindPoints.GetActiveBits(); ActiveBits != 0;)
352 {
353 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
354 ActiveBits &= ~(1u << ShaderInd);
355
345 for (auto ActiveStages = BindPoints.GetActiveStages(); ActiveStages != SHADER_TYPE_UNKNOWN;)
346 {
347 const Uint32 ShaderInd = ExtractFirstShaderStageIndex(ActiveStages);
356348 const Uint32 CacheOffset = BindPoints[ShaderInd];
357349 VERIFY(CacheOffset < GetResourceCount<ResRange>(ShaderInd), "Cache offset is out of range");
358350
388380 using OffsetType = Uint16;
389381
390382 static constexpr size_t MaxAlignment = std::max(std::max(std::max(alignof(CachedCB), alignof(CachedResource)), alignof(CachedSampler)), alignof(IUnknown*));
383
384 static constexpr int NumShaderTypes = D3D11ResourceBindPoints::NumShaderTypes;
391385
392386 static constexpr Uint32 FirstCBOffsetIdx = 0;
393387 static constexpr Uint32 FirstSRVOffsetIdx = FirstCBOffsetIdx + NumShaderTypes;
494488 inline ShaderResourceCacheD3D11::MinMaxSlot ShaderResourceCacheD3D11::BindResources(
495489 Uint32 ShaderInd,
496490 typename CachedResourceTraits<Range>::D3D11ResourceType* CommittedD3D11Resources[],
497 const TResourcesPerStage& BaseBindings) const
491 const D3D11ShaderResourceCounters& BaseBindings) const
498492 {
499493 const auto ResCount = GetResourceCount<Range>(ShaderInd);
500494 const auto ResArrays = GetConstResourceArrays<Range>(ShaderInd);
520514 Uint32 ShaderInd,
521515 typename CachedResourceTraits<Range>::D3D11ResourceType* CommittedD3D11Views[],
522516 ID3D11Resource* CommittedD3D11Resources[],
523 const TResourcesPerStage& BaseBindings) const
517 const D3D11ShaderResourceCounters& BaseBindings) const
524518 {
525519 const auto ResCount = GetResourceCount<Range>(ShaderInd);
526520 const auto ResArrays = GetConstResourceArrays<Range>(ShaderInd);
263263 }
264264
265265
266 void DeviceContextD3D11Impl::BindCacheResources(const ShaderResourceCacheD3D11& ResourceCache,
267 const TBindingsPerStage& BaseBindings,
268 SHADER_TYPE ActiveStages,
269 PixelShaderUAVBindMode& PsUavBindMode)
266 void DeviceContextD3D11Impl::BindCacheResources(const ShaderResourceCacheD3D11& ResourceCache,
267 const D3D11ShaderResourceCounters& BaseBindings,
268 SHADER_TYPE ActiveStages,
269 PixelShaderUAVBindMode& PsUavBindMode)
270270 {
271271 while (ActiveStages != 0)
272272 {
366366 if ((m_BindInfo.StaleSRBMask & m_BindInfo.ActiveSRBMask) == 0)
367367 return;
368368
369 TBindingsPerStage Bindings = {};
370 const auto ActiveStages = m_BindInfo.ActiveStages;
369 D3D11ShaderResourceCounters Bindings = {};
370 const auto ActiveStages = m_BindInfo.ActiveStages;
371371
372372 if (m_pPipelineState->GetDesc().IsAnyGraphicsPipeline())
373 Bindings[D3D11_RESOURCE_RANGE_UAV][GetShaderTypeIndex(SHADER_TYPE_PIXEL)] = static_cast<Uint8>(m_pPipelineState->GetGraphicsPipelineDesc().NumRenderTargets);
373 Bindings[D3D11_RESOURCE_RANGE_UAV][PSInd] = static_cast<Uint8>(m_pPipelineState->GetGraphicsPipelineDesc().NumRenderTargets);
374374
375375 PixelShaderUAVBindMode PsUavBindMode = m_CommittedRes.NumUAVs[PSInd] > 0 ?
376376 PixelShaderUAVBindMode::Clear :
2525 */
2626
2727 #include "pch.h"
28
2829 #include "PipelineResourceSignatureD3D11Impl.hpp"
2930 #include "RenderDeviceD3D11Impl.hpp"
31 #include "ShaderVariableD3D.hpp"
3032
3133 namespace Diligent
3234 {
116118
117119 void PipelineResourceSignatureD3D11Impl::CreateLayout()
118120 {
119 using TBindings32 = std::array<Uint32, D3D11_RESOURCE_RANGE_COUNT>;
120 using TBindingsPerStage32 = std::array<std::array<Uint32, NumShaderTypes>, D3D11_RESOURCE_RANGE_COUNT>;
121
122 const auto AllocBindPoints = [](TBindingsPerStage32& BindingPerStage, BindPointsD3D11& BindPoints, SHADER_TYPE ShaderStages, Uint32 ArraySize, D3D11_RESOURCE_RANGE Range) //
121 const auto AllocBindPoints = [](D3D11ShaderResourceCounters& BindingPerStage, D3D11ResourceBindPoints& BindPoints, SHADER_TYPE ShaderStages, Uint32 ArraySize, D3D11_RESOURCE_RANGE Range) //
123122 {
124123 while (ShaderStages != 0)
125124 {
126 auto Stage = ExtractLSB(ShaderStages);
127 Uint32 ShaderInd = GetShaderTypeIndex(Stage);
128
129 BindPoints.Set(ShaderInd, BindingPerStage[Range][ShaderInd]);
130 BindingPerStage[Range][ShaderInd] += ArraySize;
125 auto Stage = ExtractLSB(ShaderStages);
126 auto ShaderInd = GetShaderTypeIndex(Stage);
127
128 BindPoints[ShaderInd] = BindingPerStage[Range][ShaderInd];
129
130 using T = std::remove_reference<decltype(BindingPerStage[Range][ShaderInd])>::type;
131 VERIFY(Uint32{BindingPerStage[Range][ShaderInd]} + ArraySize < std::numeric_limits<T>::max(), "Binding value exceeds representable range");
132 BindingPerStage[Range][ShaderInd] += static_cast<Uint8>(ArraySize);
131133 }
132134 };
133135
134136 if (m_pStaticResCache)
135137 {
136 TBindingsPerStage32 StaticBindingsPerStage32 = {};
137 const auto ResIdxRange = GetResourceIndexRange(SHADER_RESOURCE_VARIABLE_TYPE_STATIC);
138 for (Uint32 r = ResIdxRange.first; r < ResIdxRange.second; ++r)
139 {
140 const auto& ResDesc = m_Desc.Resources[r];
141 const auto Range = ShaderResourceToDescriptorRange(ResDesc.ResourceType);
142 BindPointsD3D11 BindPoints;
143 AllocBindPoints(StaticBindingsPerStage32, BindPoints, ResDesc.ShaderStages, ResDesc.ArraySize, Range);
144 }
145
146 TBindingsPerStage StaticBindingsPerStage8 = {};
147 for (Uint32 r = 0; r < StaticBindingsPerStage32.size(); ++r)
148 {
149 for (Uint32 s = 0; s < StaticBindingsPerStage32[r].size(); ++s)
150 {
151 using T = std::remove_reference<decltype(StaticBindingsPerStage8[r][s])>::type;
152 VERIFY_EXPR(StaticBindingsPerStage32[r][s] < std::numeric_limits<T>::max());
153 StaticBindingsPerStage8[r][s] = static_cast<T>(StaticBindingsPerStage32[r][s]);
154 }
155 }
156
157 m_pStaticResCache->Initialize(StaticBindingsPerStage8, GetRawAllocator());
138 D3D11ShaderResourceCounters StaticBindingsPerStage{};
139 const auto StaticResIdxRange = GetResourceIndexRange(SHADER_RESOURCE_VARIABLE_TYPE_STATIC);
140 for (Uint32 r = StaticResIdxRange.first; r < StaticResIdxRange.second; ++r)
141 {
142 const auto& ResDesc = m_Desc.Resources[r];
143 const auto Range = ShaderResourceToDescriptorRange(ResDesc.ResourceType);
144
145 D3D11ResourceBindPoints BindPoints;
146 AllocBindPoints(StaticBindingsPerStage, BindPoints, ResDesc.ShaderStages, ResDesc.ArraySize, Range);
147 }
148
149 m_pStaticResCache->Initialize(StaticBindingsPerStage, GetRawAllocator());
158150 VERIFY_EXPR(m_pStaticResCache->IsInitialized());
159151 }
160152
190182 }
191183 }
192184
193 TBindingsPerStage32 BindingPerStage = {};
194185 for (Uint32 i = 0; i < m_Desc.NumResources; ++i)
195186 {
196187 const auto& ResDesc = m_Desc.Resources[i];
222213
223214 if (!ImtblSampAttribs.IsAllocated())
224215 {
225 AllocBindPoints(BindingPerStage, ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, D3D11_RESOURCE_RANGE_SAMPLER);
216 AllocBindPoints(m_BindingCountPerStage, ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, D3D11_RESOURCE_RANGE_SAMPLER);
226217 }
227218 }
228219
233224 AssignedSamplerInd,
234225 SrcImmutableSamplerInd != InvalidImmutableSamplerIndex //
235226 };
236 AllocBindPoints(BindingPerStage, pAttrib->BindPoints, ResDesc.ShaderStages, ResDesc.ArraySize, Range);
227 AllocBindPoints(m_BindingCountPerStage, pAttrib->BindPoints, ResDesc.ShaderStages, ResDesc.ArraySize, Range);
237228 }
238229 else
239230 {
260251 if (IsUsingCombinedSamplers() && !ImtblSampAttribs.IsAllocated())
261252 continue;
262253
263 GetDevice()->CreateSampler(ImtblSamp.Desc, &ImtblSampAttribs.pSampler);
254 GetDevice()->CreateSampler(ImtblSamp.Desc, ImtblSampAttribs.pSampler.DblPtr<ISampler>());
264255
265256 // Add as separate sampler.
266257 if (!ImtblSampAttribs.IsAllocated())
267258 {
268259 ImtblSampAttribs.ArraySize = 1;
269 AllocBindPoints(BindingPerStage, ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, Range);
270 }
271 }
272
273 for (Uint32 r = 0; r < BindingPerStage.size(); ++r)
274 {
275 for (Uint32 s = 0; s < BindingPerStage[r].size(); ++s)
276 {
277 using T = std::remove_reference<decltype(m_BindingCountPerStage[r][s])>::type;
278 VERIFY_EXPR(BindingPerStage[r][s] < std::numeric_limits<T>::max());
279 m_BindingCountPerStage[r][s] = static_cast<T>(BindingPerStage[r][s]);
260 AllocBindPoints(m_BindingCountPerStage, ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, Range);
280261 }
281262 }
282263 }
373354
374355 if (ImtblSampAttr.IsAllocated())
375356 {
376 SamplerD3D11Impl* pSampler = ImtblSampAttr.GetSamplerD3D11();
377 VERIFY_EXPR(pSampler != nullptr);
357 SamplerD3D11Impl* pSampler = ImtblSampAttr.pSampler.RawPtr<SamplerD3D11Impl>();
358 VERIFY_EXPR(ImtblSampAttr.pSampler != nullptr);
378359 VERIFY_EXPR(ImtblSampAttr.ArraySize > 0);
379360
380361 for (Uint32 ArrInd = 0; ArrInd < ImtblSampAttr.ArraySize; ++ArrInd)
383364 }
384365 }
385366
386 void PipelineResourceSignatureD3D11Impl::UpdateShaderResourceBindingMap(ResourceBinding::TMap& ResourceMap, SHADER_TYPE ShaderStage, const TBindingsPerStage& BaseBindings) const
367 void PipelineResourceSignatureD3D11Impl::UpdateShaderResourceBindingMap(ResourceBinding::TMap& ResourceMap,
368 SHADER_TYPE ShaderStage,
369 const D3D11ShaderResourceCounters& BaseBindings) const
387370 {
388371 VERIFY(ShaderStage != SHADER_TYPE_UNKNOWN && IsPowerOfTwo(ShaderStage), "Only single shader stage must be provided.");
389372 const auto ShaderInd = GetShaderTypeIndex(ShaderStage);
396379
397380 if ((ResDesc.ShaderStages & ShaderStage) != 0)
398381 {
399 VERIFY_EXPR(ResAttr.BindPoints.IsValid(ShaderInd));
382 VERIFY_EXPR(ResAttr.BindPoints.IsStageActive(ShaderInd));
400383 ResourceBinding::BindInfo BindInfo //
401384 {
402385 Uint32{BaseBindings[Range][ShaderInd]} + ResAttr.BindPoints[ShaderInd],
419402
420403 if ((ImtblSam.ShaderStages & ShaderStage) != 0 && SampAttr.IsAllocated())
421404 {
422 VERIFY_EXPR(SampAttr.BindPoints.IsValid(ShaderInd));
405 VERIFY_EXPR(SampAttr.BindPoints.IsStageActive(ShaderInd));
423406
424407 String SampName{ImtblSam.SamplerOrTextureName};
425408 if (IsUsingCombinedSamplers())
497480 BindingsOK = false;
498481 continue;
499482 }
500 /*
501 const auto& SRV = ResourceCache.GetSRV(ResAttr.BindPoints + ArrInd);
483
484 const auto& SRV = ResourceCache.GetResource<D3D11_RESOURCE_RANGE_SRV>(ResAttr.BindPoints + ArrInd);
502485 if (SRV.pTexture)
503 ValidateResourceViewDimension(ResDesc.Name, ResDesc.ArraySize, ArrInd, SRV.pView.RawPtr<ITextureView>(), D3DAttribs.GetResourceDimension(), D3DAttribs.IsMultisample());
486 {
487 if (!ValidateResourceViewDimension(ResDesc.Name, ResDesc.ArraySize, ArrInd, SRV.pView.RawPtr<TextureViewD3D11Impl>(),
488 D3DAttribs.GetResourceDimension(), D3DAttribs.IsMultisample()))
489 BindingsOK = false;
490 }
504491 else
505 ValidateResourceViewDimension(ResDesc.Name, ResDesc.ArraySize, ArrInd, SRV.pView.RawPtr<IBufferView>(), D3DAttribs.GetResourceDimension(), D3DAttribs.IsMultisample());
506 */
492 {
493 if (!VerifyBufferViewModeD3D(SRV.pView.RawPtr<BufferViewD3D11Impl>(), D3DAttribs, ShaderName))
494 BindingsOK = false;
495 }
507496 }
508497 break;
509498
517506 BindingsOK = false;
518507 continue;
519508 }
520 /*
521 const auto& UAV = ResourceCache.GetUAV(ResAttr.BindPoints + ArrInd);
509 const auto& UAV = ResourceCache.GetResource<D3D11_RESOURCE_RANGE_UAV>(ResAttr.BindPoints + ArrInd);
522510 if (UAV.pTexture)
523 ValidateResourceViewDimension(ResDesc.Name, ResDesc.ArraySize, ArrInd, UAV.pView.RawPtr<ITextureView>(), D3DAttribs.GetResourceDimension(), D3DAttribs.IsMultisample());
511 {
512 if (!ValidateResourceViewDimension(ResDesc.Name, ResDesc.ArraySize, ArrInd, UAV.pView.RawPtr<TextureViewD3D11Impl>(),
513 D3DAttribs.GetResourceDimension(), D3DAttribs.IsMultisample()))
514 BindingsOK = false;
515 }
524516 else
525 ValidateResourceViewDimension(ResDesc.Name, ResDesc.ArraySize, ArrInd, UAV.pView.RawPtr<IBufferView>(), D3DAttribs.GetResourceDimension(), D3DAttribs.IsMultisample());
526 */
517 {
518 if (!VerifyBufferViewModeD3D(UAV.pView.RawPtr<BufferViewD3D11Impl>(), D3DAttribs, ShaderName))
519 BindingsOK = false;
520 }
527521 }
528522 break;
529523
199199 const auto ShaderType = pShader->GetDesc().ShaderType;
200200 auto* pBytecode = Shaders[s]->GetBytecode();
201201
202 PipelineResourceSignatureD3D11Impl::TBindingsPerStage BindingsPerStage = {};
202 D3D11ShaderResourceCounters BindingsPerStage = {};
203203 if (m_Desc.IsAnyGraphicsPipeline())
204204 BindingsPerStage[D3D11_RESOURCE_RANGE_UAV][PSInd] = GetGraphicsPipelineDesc().NumRenderTargets;
205205
228228 }
229229
230230 #ifdef DILIGENT_DEVELOPMENT
231 PipelineResourceSignatureD3D11Impl::TBindingsPerStage BindingsPerStage = {};
231 D3D11ShaderResourceCounters BindingsPerStage = {};
232232
233233 if (m_Desc.IsAnyGraphicsPipeline())
234234 BindingsPerStage[D3D11_RESOURCE_RANGE_UAV][PSInd] = GetGraphicsPipelineDesc().NumRenderTargets;
240240 pSignature->ShiftBindings(BindingsPerStage);
241241 }
242242
243 for (Uint32 s = 0; s < PipelineResourceSignatureD3D11Impl::NumShaderTypes; ++s)
243 for (Uint32 s = 0; s < D3D11ResourceBindPoints::NumShaderTypes; ++s)
244244 {
245245 DEV_CHECK_ERR(BindingsPerStage[D3D11_RESOURCE_RANGE_CBV][s] <= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT,
246246 "Constant buffer count ", Uint32{BindingsPerStage[D3D11_RESOURCE_RANGE_CBV][s]}, " exceeds D3D11 limit ", D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
515515 }
516516
517517 #ifdef DILIGENT_DEVELOPMENT
518 void PipelineStateD3D11Impl::DvpVerifySRBResources(class ShaderResourceBindingD3D11Impl* pSRBs[], const TBindingsPerStage BaseBindings[], Uint32 NumSRBs) const
518 void PipelineStateD3D11Impl::DvpVerifySRBResources(ShaderResourceBindingD3D11Impl* pSRBs[],
519 const D3D11ShaderResourceCounters BaseBindings[],
520 Uint32 NumSRBs) const
519521 {
520522 // Verify SRB compatibility with this pipeline
521 const auto SignCount = GetResourceSignatureCount();
522 TBindingsPerStage Bindings = {};
523 const auto SignCount = GetResourceSignatureCount();
524 D3D11ShaderResourceCounters Bindings = {};
523525
524526 if (m_Desc.IsAnyGraphicsPipeline())
525527 Bindings[D3D11_RESOURCE_RANGE_UAV][GetShaderTypeIndex(SHADER_TYPE_PIXEL)] = static_cast<Uint8>(GetGraphicsPipelineDesc().NumRenderTargets);
3838 namespace Diligent
3939 {
4040
41 size_t ShaderResourceCacheD3D11::GetRequriedMemorySize(const TResourcesPerStage& ResCount)
41 size_t ShaderResourceCacheD3D11::GetRequriedMemorySize(const D3D11ShaderResourceCounters& ResCount)
4242 {
4343 size_t MemSize = 0;
4444 // clang-format off
5959 return MemSize;
6060 }
6161
62 void ShaderResourceCacheD3D11::Initialize(const TResourcesPerStage& ResCount, IMemoryAllocator& MemAllocator)
62 void ShaderResourceCacheD3D11::Initialize(const D3D11ShaderResourceCounters& ResCount, IMemoryAllocator& MemAllocator)
6363 {
6464 // http://diligentgraphics.com/diligent-engine/architecture/d3d11/shader-resource-cache/
6565 VERIFY(!IsInitialized(), "Resource cache has already been intialized!");
383383 auto* pd3d12Resource = GetD3D12Resource();
384384 if (pd3d12Resource != nullptr)
385385 {
386 VERIFY(m_Desc.Usage != USAGE_DYNAMIC || (m_Desc.BindFlags | (BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS)) != 0, "Expected non-dynamic buffer or a buffer with SRV or UAV bind flags");
386 VERIFY(m_Desc.Usage != USAGE_DYNAMIC || (m_Desc.BindFlags & (BIND_SHADER_RESOURCE | BIND_UNORDERED_ACCESS)) != 0, "Expected non-dynamic buffer or a buffer with SRV or UAV bind flags");
387387 DataStartByteOffset = 0;
388388 return pd3d12Resource;
389389 }