git.s-ol.nu ~forks/DiligentCore / 250b656
Refactored D3D11 resource cache assiduous 6 months ago
11 changed file(s) with 473 addition(s) and 946 deletion(s). Raw diff Collapse all Expand all
332332
333333 void BindShaderResources();
334334
335 using TBindingsPerStage = PipelineResourceSignatureD3D11Impl::TBindingsPerStage;
336 using TCommittedResources = ShaderResourceCacheD3D11::TCommittedResources;
337 using TMinMaxSlotPerStage = ShaderResourceCacheD3D11::TMinMaxSlotPerStage;
338
339 static constexpr auto NumShaderTypes = PipelineResourceSignatureD3D11Impl::NumShaderTypes;
335 static constexpr int NumShaderTypes = BindPointsD3D11::NumShaderTypes;
336 struct TCommittedResources
337 {
338 // clang-format off
339
340 /// An array of D3D11 constant buffers committed to D3D11 device context,
341 /// for each shader type. The context addref's all bound resources, so we do
342 /// not need to keep strong references.
343 ID3D11Buffer* D3D11CBs [NumShaderTypes][D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {};
344
345 /// An array of D3D11 shader resource views committed to D3D11 device context,
346 /// for each shader type. The context addref's all bound resources, so we do
347 /// not need to keep strong references.
348 ID3D11ShaderResourceView* D3D11SRVs [NumShaderTypes][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {};
349
350 /// An array of D3D11 samplers committed to D3D11 device context,
351 /// for each shader type. The context addref's all bound resources, so we do
352 /// not need to keep strong references.
353 ID3D11SamplerState* D3D11Samplers[NumShaderTypes][D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {};
354
355 /// An array of D3D11 UAVs committed to D3D11 device context,
356 /// for each shader type. The context addref's all bound resources, so we do
357 /// not need to keep strong references.
358 ID3D11UnorderedAccessView* D3D11UAVs [NumShaderTypes][D3D11_PS_CS_UAV_REGISTER_COUNT] = {};
359
360 /// An array of D3D11 resources commited as SRV to D3D11 device context,
361 /// for each shader type. The context addref's all bound resources, so we do
362 /// not need to keep strong references.
363 ID3D11Resource* D3D11SRVResources [NumShaderTypes][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {};
364
365 /// An array of D3D11 resources commited as UAV to D3D11 device context,
366 /// for each shader type. The context addref's all bound resources, so we do
367 /// not need to keep strong references.
368 ID3D11Resource* D3D11UAVResources [NumShaderTypes][D3D11_PS_CS_UAV_REGISTER_COUNT] = {};
369
370 Uint8 NumCBs [NumShaderTypes] = {};
371 Uint8 NumSRVs [NumShaderTypes] = {};
372 Uint8 NumSamplers[NumShaderTypes] = {};
373 Uint8 NumUAVs [NumShaderTypes] = {};
374
375 // clang-format on
376
377 void Clear()
378 {
379 *this = {};
380 }
381 };
382
383 using TBindingsPerStage = PipelineResourceSignatureD3D11Impl::TBindingsPerStage;
384 struct MinMaxSlot
385 {
386 UINT MinSlot = UINT_MAX;
387 UINT MaxSlot = 0;
388 };
389 using TMinMaxSlotPerStage = std::array<std::array<MinMaxSlot, D3D11_RESOURCE_RANGE_COUNT>, NumShaderTypes>;
390
391
392 void BindCacheResources(const ShaderResourceCacheD3D11& ResourceCache,
393 const TBindingsPerStage& Bindings,
394 TMinMaxSlotPerStage& MinMaxSlot,
395 SHADER_TYPE ActiveStages);
340396
341397 #ifdef DILIGENT_DEVELOPMENT
342398 void DvpValidateCommittedShaderResources();
3737 namespace Diligent
3838 {
3939
40 enum DESCRIPTOR_RANGE : Uint32
40 enum D3D11_RESOURCE_RANGE : Uint32
4141 {
42 DESCRIPTOR_RANGE_CBV = 0,
43 DESCRIPTOR_RANGE_SRV,
44 DESCRIPTOR_RANGE_SAMPLER,
45 DESCRIPTOR_RANGE_UAV,
46 DESCRIPTOR_RANGE_COUNT,
47 DESCRIPTOR_RANGE_UNKNOWN = ~0u
42 D3D11_RESOURCE_RANGE_CBV = 0,
43 D3D11_RESOURCE_RANGE_SRV,
44 D3D11_RESOURCE_RANGE_SAMPLER,
45 D3D11_RESOURCE_RANGE_UAV,
46 D3D11_RESOURCE_RANGE_COUNT,
47 D3D11_RESOURCE_RANGE_UNKNOWN = ~0u
4848 };
49 DESCRIPTOR_RANGE ShaderResourceToDescriptorRange(SHADER_RESOURCE_TYPE Type);
49 D3D11_RESOURCE_RANGE ShaderResourceToDescriptorRange(SHADER_RESOURCE_TYPE Type);
5050
5151
5252 // sizeof(BindPointsD3D11) == 8, x64
121121 static constexpr Uint32 InvalidSamplerInd = (1u << _SamplerIndBits) - 1;
122122
123123 // clang-format off
124 const Uint32 CacheOffset : _CacheOffsetBits; // SRB and Signature has the same cache offsets for static resources.
124 const Uint32 CacheOffset : _CacheOffsetBits; // SRB and Signature have the same cache offsets for static resources
125 // (thanks to sorting variables by type, where all static vars go first).
125126 const Uint32 SamplerInd : _SamplerIndBits; // Index of the assigned sampler in m_Desc.Resources.
126127 const Uint32 ImtblSamplerAssigned : _SamplerAssignedBits; // Immutable sampler flag.
127128 BindPointsD3D11 BindPoints;
102102 }
103103
104104 using TBindings = ShaderResourceCacheD3D11::TResourceCount;
105 using TBindingsPerStage = ShaderResourceCacheD3D11::TBindingsPerStage;
105 using TResourceCount = std::array<Uint8, D3D11_RESOURCE_RANGE_COUNT>;
106 using TBindingsPerStage = std::array<TResourceCount, NumShaderTypes>;
107
106108
107109 __forceinline void ShiftBindings(TBindingsPerStage& Bindings) const
108110 {
2929 /// \file
3030 /// Declaration of Diligent::ShaderResourceCacheD3D11 class
3131
32 #include <array>
33 #include <memory>
34
3235 #include "MemoryAllocator.h"
3336 #include "ShaderResourceCacheCommon.hpp"
37 #include "PipelineResourceAttribsD3D11.hpp"
38
3439 #include "TextureBaseD3D11.hpp"
40 #include "TextureViewD3D11Impl.hpp"
3541 #include "BufferD3D11Impl.hpp"
3642 #include "BufferViewD3D11Impl.hpp"
3743 #include "SamplerD3D11Impl.hpp"
38 #include "PipelineResourceAttribsD3D11.hpp"
3944
4045 namespace Diligent
4146 {
7277 Verify
7378 };
7479 // Transitions all resources in the cache
75 void TransitionResourceStates(DeviceContextD3D11Impl& Ctx, StateTransitionMode Mode);
76
77
78 static constexpr int NumShaderTypes = BindPointsD3D11::NumShaderTypes;
79
80 struct TCommittedResources
81 {
82 // clang-format off
83
84 /// An array of D3D11 constant buffers committed to D3D11 device context,
85 /// for each shader type. The context addref's all bound resources, so we do
86 /// not need to keep strong references.
87 ID3D11Buffer* D3D11CBs [NumShaderTypes][D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {};
88
89 /// An array of D3D11 shader resource views committed to D3D11 device context,
90 /// for each shader type. The context addref's all bound resources, so we do
91 /// not need to keep strong references.
92 ID3D11ShaderResourceView* D3D11SRVs [NumShaderTypes][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {};
93
94 /// An array of D3D11 samplers committed to D3D11 device context,
95 /// for each shader type. The context addref's all bound resources, so we do
96 /// not need to keep strong references.
97 ID3D11SamplerState* D3D11Samplers[NumShaderTypes][D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {};
98
99 /// An array of D3D11 UAVs committed to D3D11 device context,
100 /// for each shader type. The context addref's all bound resources, so we do
101 /// not need to keep strong references.
102 ID3D11UnorderedAccessView* D3D11UAVs [NumShaderTypes][D3D11_PS_CS_UAV_REGISTER_COUNT] = {};
103
104 /// An array of D3D11 resources commited as SRV to D3D11 device context,
105 /// for each shader type. The context addref's all bound resources, so we do
106 /// not need to keep strong references.
107 ID3D11Resource* D3D11SRVResources [NumShaderTypes][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {};
108
109 /// An array of D3D11 resources commited as UAV to D3D11 device context,
110 /// for each shader type. The context addref's all bound resources, so we do
111 /// not need to keep strong references.
112 ID3D11Resource* D3D11UAVResources [NumShaderTypes][D3D11_PS_CS_UAV_REGISTER_COUNT] = {};
113
114 Uint8 NumCBs [NumShaderTypes] = {};
115 Uint8 NumSRVs [NumShaderTypes] = {};
116 Uint8 NumSamplers[NumShaderTypes] = {};
117 Uint8 NumUAVs [NumShaderTypes] = {};
118
119 // clang-format on
120
121 void Clear();
122 };
123
124 struct MinMaxSlot
125 {
126 UINT MinSlot = UINT_MAX;
127 UINT MaxSlot = 0;
128 };
129 using TMinMaxSlotPerStage = std::array<std::array<MinMaxSlot, DESCRIPTOR_RANGE_COUNT>, NumShaderTypes>;
130 using TResourceCount = std::array<Uint8, DESCRIPTOR_RANGE_COUNT>;
131 using TBindingsPerStage = std::array<TResourceCount, NumShaderTypes>;
132
133 void BindResources(DeviceContextD3D11Impl& Ctx, const TBindingsPerStage& BaseBindings, TMinMaxSlotPerStage& MinMaxSlot, TCommittedResources& CommittedRes, SHADER_TYPE ActiveStages) const;
134
80 template <StateTransitionMode Mode>
81 void TransitionResourceStates(DeviceContextD3D11Impl& Ctx);
13582
13683 /// Describes a resource associated with a cached constant buffer
13784 struct CachedCB
15198 struct CachedSampler
15299 {
153100 /// Strong reference to the sampler
154 RefCntAutoPtr<class SamplerD3D11Impl> pSampler;
101 RefCntAutoPtr<SamplerD3D11Impl> pSampler;
155102
156103 private:
157104 friend class ShaderResourceCacheD3D11;
186133 {
187134 pBuffer = nullptr;
188135 // Avoid unnecessary virtual function calls
189 pTexture = pTexView ? ValidatedCast<TextureBaseD3D11>(pTexView->TextureViewD3D11Impl::GetTexture()) : nullptr;
190 pView.Attach(pTexView.Detach());
136 pTexture = pTexView ? pTexView->GetTexture<TextureBaseD3D11>() : nullptr;
137 pView = std::move(pTexView);
191138 pd3d11Resource = pTexture ? pTexture->TextureBaseD3D11::GetD3D11Texture() : nullptr;
192139 }
193140
195142 {
196143 pTexture = nullptr;
197144 // Avoid unnecessary virtual function calls
198 pBuffer = pBufView ? ValidatedCast<BufferD3D11Impl>(pBufView->BufferViewD3D11Impl::GetBuffer()) : nullptr;
199 pView.Attach(pBufView.Detach());
145 pBuffer = pBufView ? pBufView->GetBuffer<BufferD3D11Impl>() : nullptr;
146 pView = std::move(pBufView);
200147 pd3d11Resource = pBuffer ? pBuffer->BufferD3D11Impl::GetD3D11Buffer() : nullptr;
201148 }
202149 };
203150
151 using TResourceCount = std::array<Uint8, D3D11_RESOURCE_RANGE_COUNT>;
204152 static size_t GetRequriedMemorySize(const TResourceCount& ResCount);
205153
206154 void Initialize(const TResourceCount& ResCount, IMemoryAllocator& MemAllocator);
248196 ShaderResourceCacheD3D11::CachedCB* CBs;
249197 ID3D11Buffer** pd3d11CBs;
250198 BindPointsD3D11* bindPoints;
251 const_cast<ShaderResourceCacheD3D11*>(this)->GetCBArrays(CBs, pd3d11CBs, bindPoints);
199 GetCBArrays(CBs, pd3d11CBs, bindPoints);
252200 return CBs[CacheOffset];
253201 }
254202
258206 ShaderResourceCacheD3D11::CachedResource* SRVResources;
259207 ID3D11ShaderResourceView** pd3d11SRVs;
260208 BindPointsD3D11* bindPoints;
261 const_cast<ShaderResourceCacheD3D11*>(this)->GetSRVArrays(SRVResources, pd3d11SRVs, bindPoints);
209 GetSRVArrays(SRVResources, pd3d11SRVs, bindPoints);
262210 return SRVResources[CacheOffset];
263211 }
264212
268216 ShaderResourceCacheD3D11::CachedResource* UAVResources;
269217 ID3D11UnorderedAccessView** pd3d11UAVs;
270218 BindPointsD3D11* bindPoints;
271 const_cast<ShaderResourceCacheD3D11*>(this)->GetUAVArrays(UAVResources, pd3d11UAVs, bindPoints);
219 GetUAVArrays(UAVResources, pd3d11UAVs, bindPoints);
272220 return UAVResources[CacheOffset];
273221 }
274222
278226 ShaderResourceCacheD3D11::CachedSampler* Samplers;
279227 ID3D11SamplerState** pd3d11Samplers;
280228 BindPointsD3D11* bindPoints;
281 const_cast<ShaderResourceCacheD3D11*>(this)->GetSamplerArrays(Samplers, pd3d11Samplers, bindPoints);
229 GetSamplerArrays(Samplers, pd3d11Samplers, bindPoints);
282230 return Samplers[CacheOffset];
283231 }
284232
352300 __forceinline Uint32 GetUAVCount() const { return m_UAVCount; }
353301 // clang-format on
354302
355 __forceinline void GetCBArrays(CachedCB*& CBs, ID3D11Buffer**& pd3d11CBs, BindPointsD3D11*& pBindPoints)
303 __forceinline void GetCBArrays(CachedCB*& CBs, ID3D11Buffer**& pd3d11CBs, BindPointsD3D11*& pBindPoints) const
356304 {
357305 VERIFY(alignof(CachedCB) == alignof(ID3D11Buffer*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
358 CBs = reinterpret_cast<CachedCB*>(m_pResourceData + m_CBOffset);
306 CBs = reinterpret_cast<CachedCB*>(m_pResourceData.get() + m_CBOffset);
359307 pd3d11CBs = reinterpret_cast<ID3D11Buffer**>(CBs + GetCBCount());
360308 pBindPoints = reinterpret_cast<BindPointsD3D11*>(pd3d11CBs + GetCBCount());
361309 }
362310
363 __forceinline void GetSRVArrays(CachedResource*& SRVResources, ID3D11ShaderResourceView**& d3d11SRVs, BindPointsD3D11*& pBindPoints)
311 __forceinline void GetSRVArrays(CachedResource*& SRVResources, ID3D11ShaderResourceView**& d3d11SRVs, BindPointsD3D11*& pBindPoints) const
364312 {
365313 VERIFY(alignof(CachedResource) == alignof(ID3D11ShaderResourceView*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
366 SRVResources = reinterpret_cast<CachedResource*>(m_pResourceData + m_SRVOffset);
314 SRVResources = reinterpret_cast<CachedResource*>(m_pResourceData.get() + m_SRVOffset);
367315 d3d11SRVs = reinterpret_cast<ID3D11ShaderResourceView**>(SRVResources + GetSRVCount());
368316 pBindPoints = reinterpret_cast<BindPointsD3D11*>(d3d11SRVs + GetSRVCount());
369317 }
370318
371 __forceinline void GetSamplerArrays(CachedSampler*& Samplers, ID3D11SamplerState**& pd3d11Samplers, BindPointsD3D11*& pBindPoints)
319 __forceinline void GetSamplerArrays(CachedSampler*& Samplers, ID3D11SamplerState**& pd3d11Samplers, BindPointsD3D11*& pBindPoints) const
372320 {
373321 VERIFY(alignof(CachedSampler) == alignof(ID3D11SamplerState*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
374 Samplers = reinterpret_cast<CachedSampler*>(m_pResourceData + m_SamplerOffset);
322 Samplers = reinterpret_cast<CachedSampler*>(m_pResourceData.get() + m_SamplerOffset);
375323 pd3d11Samplers = reinterpret_cast<ID3D11SamplerState**>(Samplers + GetSamplerCount());
376324 pBindPoints = reinterpret_cast<BindPointsD3D11*>(pd3d11Samplers + GetSamplerCount());
377325 }
378326
379 __forceinline void GetUAVArrays(CachedResource*& UAVResources, ID3D11UnorderedAccessView**& pd3d11UAVs, BindPointsD3D11*& pBindPoints)
327 __forceinline void GetUAVArrays(CachedResource*& UAVResources, ID3D11UnorderedAccessView**& pd3d11UAVs, BindPointsD3D11*& pBindPoints) const
380328 {
381329 VERIFY(alignof(CachedResource) == alignof(ID3D11UnorderedAccessView*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
382 UAVResources = reinterpret_cast<CachedResource*>(m_pResourceData + m_UAVOffset);
330 UAVResources = reinterpret_cast<CachedResource*>(m_pResourceData.get() + m_UAVOffset);
383331 pd3d11UAVs = reinterpret_cast<ID3D11UnorderedAccessView**>(UAVResources + GetUAVCount());
384332 pBindPoints = reinterpret_cast<BindPointsD3D11*>(pd3d11UAVs + GetUAVCount());
385333 }
387335 __forceinline void GetConstCBArrays(CachedCB const*& CBs, ID3D11Buffer* const*& pd3d11CBs, BindPointsD3D11 const*& pBindPoints) const
388336 {
389337 VERIFY(alignof(CachedCB) == alignof(ID3D11Buffer*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
390 CBs = reinterpret_cast<CachedCB const*>(m_pResourceData + m_CBOffset);
338 CBs = reinterpret_cast<CachedCB const*>(m_pResourceData.get() + m_CBOffset);
391339 pd3d11CBs = reinterpret_cast<ID3D11Buffer* const*>(CBs + GetCBCount());
392340 pBindPoints = reinterpret_cast<BindPointsD3D11 const*>(pd3d11CBs + GetCBCount());
393341 }
395343 __forceinline void GetConstSRVArrays(CachedResource const*& SRVResources, ID3D11ShaderResourceView* const*& d3d11SRVs, BindPointsD3D11 const*& pBindPoints) const
396344 {
397345 VERIFY(alignof(CachedResource) == alignof(ID3D11ShaderResourceView*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
398 SRVResources = reinterpret_cast<CachedResource const*>(m_pResourceData + m_SRVOffset);
346 SRVResources = reinterpret_cast<CachedResource const*>(m_pResourceData.get() + m_SRVOffset);
399347 d3d11SRVs = reinterpret_cast<ID3D11ShaderResourceView* const*>(SRVResources + GetSRVCount());
400348 pBindPoints = reinterpret_cast<BindPointsD3D11 const*>(d3d11SRVs + GetSRVCount());
401349 }
403351 __forceinline void GetConstSamplerArrays(CachedSampler const*& Samplers, ID3D11SamplerState* const*& pd3d11Samplers, BindPointsD3D11 const*& pBindPoints) const
404352 {
405353 VERIFY(alignof(CachedSampler) == alignof(ID3D11SamplerState*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
406 Samplers = reinterpret_cast<CachedSampler const*>(m_pResourceData + m_SamplerOffset);
354 Samplers = reinterpret_cast<CachedSampler const*>(m_pResourceData.get() + m_SamplerOffset);
407355 pd3d11Samplers = reinterpret_cast<ID3D11SamplerState* const*>(Samplers + GetSamplerCount());
408356 pBindPoints = reinterpret_cast<BindPointsD3D11 const*>(pd3d11Samplers + GetSamplerCount());
409357 }
411359 __forceinline void GetConstUAVArrays(CachedResource const*& UAVResources, ID3D11UnorderedAccessView* const*& pd3d11UAVs, BindPointsD3D11 const*& pBindPoints) const
412360 {
413361 VERIFY(alignof(CachedResource) == alignof(ID3D11UnorderedAccessView*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
414 UAVResources = reinterpret_cast<CachedResource const*>(m_pResourceData + m_UAVOffset);
362 UAVResources = reinterpret_cast<CachedResource const*>(m_pResourceData.get() + m_UAVOffset);
415363 pd3d11UAVs = reinterpret_cast<ID3D11UnorderedAccessView* const*>(UAVResources + GetUAVCount());
416364 pBindPoints = reinterpret_cast<BindPointsD3D11 const*>(pd3d11UAVs + GetUAVCount());
417365 }
439387 d3d11ResArr[CacheOffset] = pd3d11Resource;
440388 }
441389
442 template <typename THandleResource>
443 void ProcessResources(THandleResource HandleResource);
444
445 // Transitions resource to the shader resource state required by Type member.
446 __forceinline void TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedCB* CBs, ID3D11Buffer** pd3d11CBs);
447 __forceinline void TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedResource* SRVResources, ID3D11ShaderResourceView** d3d11SRVs);
448 __forceinline void TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedSampler* Samplers, ID3D11SamplerState** pd3d11Samplers);
449 __forceinline void TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedResource* UAVResources, ID3D11UnorderedAccessView** pd3d11UAVs);
450
451 #ifdef DILIGENT_DEVELOPMENT
452 // Verifies that resource is in correct shader resource state required by Type member.
453 void DvpVerifyResourceState(DeviceContextD3D11Impl& Ctx, Uint32 Count, const CachedCB* CBs, ID3D11Buffer**);
454 void DvpVerifyResourceState(DeviceContextD3D11Impl& Ctx, Uint32 Count, const CachedResource* SRVResources, ID3D11ShaderResourceView**);
455 void DvpVerifyResourceState(DeviceContextD3D11Impl& Ctx, Uint32 Count, const CachedSampler* Samplers, ID3D11SamplerState**);
456 void DvpVerifyResourceState(DeviceContextD3D11Impl& Ctx, Uint32 Count, const CachedResource* UAVResources, ID3D11UnorderedAccessView**);
457 #endif
390 // Transitions or verifies the resource state.
391 template <StateTransitionMode Mode>
392 void TransitionResources(DeviceContextD3D11Impl& Ctx, const ID3D11Buffer* /*Selector*/) const;
393
394 template <StateTransitionMode Mode>
395 void TransitionResources(DeviceContextD3D11Impl& Ctx, const ID3D11ShaderResourceView* /*Selector*/) const;
396
397 template <StateTransitionMode Mode>
398 void TransitionResources(DeviceContextD3D11Impl& Ctx, const ID3D11SamplerState* /*Selector*/) const;
399
400 template <StateTransitionMode Mode>
401 void TransitionResources(DeviceContextD3D11Impl& Ctx, const ID3D11UnorderedAccessView* /*Selector*/) const;
458402
459403 private:
460404 using OffsetType = Uint16;
472416 OffsetType m_UAVOffset = InvalidResourceOffset;
473417
474418 static constexpr Uint32 _CBCountBits = 7;
475 static constexpr Uint32 _SVCountBits = 10;
419 static constexpr Uint32 _SRVCountBits = 10;
476420 static constexpr Uint32 _SampCountBits = 7;
477421 static constexpr Uint32 _UAVCountBits = 4;
478422
423 static constexpr int NumShaderTypes = BindPointsD3D11::NumShaderTypes;
424
479425 // clang-format off
480 static_assert((1U << _CBCountBits) >= (D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT * NumShaderTypes), "Number of constant buffers is too small");
481 static_assert((1U << _SVCountBits) >= (D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT * NumShaderTypes), "Number of shader resources is too small");
482 static_assert((1U << _SampCountBits) >= (D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT * NumShaderTypes), "Number of samplers is too small");
483 static_assert((1U << _UAVCountBits) >= D3D11_PS_CS_UAV_REGISTER_COUNT, "Number of UAVs is too small");
426 static_assert((1U << _CBCountBits) >= (D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT * NumShaderTypes), "Not enough bits to represent CB count");
427 static_assert((1U << _SRVCountBits) >= (D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT * NumShaderTypes), "Not enough bits to represent SRV count");
428 static_assert((1U << _SampCountBits) >= (D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT * NumShaderTypes), "Not enough bits to represent Sampler count");
429 static_assert((1U << _UAVCountBits) >= D3D11_PS_CS_UAV_REGISTER_COUNT, "Not enough bits to represent UAV count");
484430
485431 Uint32 m_CBCount : _CBCountBits;
486 Uint32 m_SRVCount : _SVCountBits;
432 Uint32 m_SRVCount : _SRVCountBits;
487433 Uint32 m_SamplerCount : _SampCountBits;
488434 Uint32 m_UAVCount : _UAVCountBits;
489435 // clang-format on
491437 // Indicates what types of resources are stored in the cache
492438 const ResourceCacheContentType m_ContentType;
493439
494 Uint8* m_pResourceData = nullptr;
495 IMemoryAllocator* m_pAllocator = nullptr;
440 std::unique_ptr<Uint8, STDDeleter<Uint8, IMemoryAllocator>> m_pResourceData;
496441 };
497442
443 // Instantiate templates
444 template void ShaderResourceCacheD3D11::TransitionResourceStates<ShaderResourceCacheD3D11::StateTransitionMode::Transition>(DeviceContextD3D11Impl& Ctx);
445 template void ShaderResourceCacheD3D11::TransitionResourceStates<ShaderResourceCacheD3D11::StateTransitionMode::Verify>(DeviceContextD3D11Impl& Ctx);
446
498447 } // namespace Diligent
2929 /// \file
3030 /// Declaration of Diligent::ShaderResourcesD3D11 class
3131
32
33 // ShaderResourcesD3D11 are created by ShaderD3D11Impl instances. They are then referenced by ShaderResourceLayoutD3D11 objects, which are in turn
34 // created by instances of ShaderResourceBindingsD3D11Impl and PipelineStateD3D11Impl
35 //
36 // _________________
37 // | |
38 // | ShaderD3D11Impl |
39 // |_________________|
40 // |
41 // |shared_ptr
42 // ________V_____________ _____________________________________________________________________
43 // | | unique_ptr | | | | | | |
44 // | ShaderResourcesD3D11 |--------------->| CBs | TexSRVs | TexUAVs | BufSRVs | BufUAVs | Samplers |
45 // |______________________| |________|___________|___________|___________|___________|____________|
46 // A A A A A A A
47 // | \ \ \ \ \ \
48 // |shared_ptr Ref Ref Ref Ref Ref Ref
49 // ________|__________________ ____\_________\__________\__________\___________\_______ ___\______
50 // | | unique_ptr | | | | | | |
51 // | ShaderResourceLayoutD3D11 |--------------->| CBs | TexSRVs | TexUAVs | BufSRVs | BufUAVs | Samplers |
52 // |___________________________| |________|___________|___________|___________|___________|__________|
53 // | A
54 // |_________________SamplerIndex_________________|
55 //
56 //
57 // One ShaderResourcesD3D11 instance can be referenced by multiple objects
58 //
59 //
60 // ____<m_pResourceLayouts>___ ________________________________
61 // | | | |
62 // ----| ShaderResourceLayoutD3D11 |<-----| ShaderResourceBindingD3D11Impl |
63 // | |___________________________| |________________________________|
64 // |
65 // |
66 // _________________ ______________________ | ____<m_pResourceLayouts>___ ________________________________
67 // | | shared_ptr | | shared_ptr| | | | |
68 // | ShaderD3D11Impl |--------------->| ShaderResourcesD3D11 |<---------------| ShaderResourceLayoutD3D11 |<-----| ShaderResourceBindingD3D11Impl |
69 // |_________________| |______________________| | |___________________________| |________________________________|
70 // A |
71 // | |
72 // _____<StaticResLayout>_____ | | ____<m_pResourceLayouts>___ ________________________________
73 // | | shared_ptr | | | | | |
74 // | ShaderResourceLayoutD3D11 |------------------- ----| ShaderResourceLayoutD3D11 |<-----| ShaderResourceBindingD3D11Impl |
75 // |___________________________| |___________________________| |________________________________|
76 // A
77 // ___________|______________
78 // | |
79 // | PipelineStateD3D11Impl |
80 // |__________________________|
81 //
82
83 #include <vector>
84
8532 #include "ShaderResources.hpp"
8633
8734 namespace Diligent
11057 __forceinline Int32 GetMaxUAVBindPoint() const { return m_MaxUAVBindPoint; }
11158 // clang-format on
11259
113 #ifdef DILIGENT_DEVELOPMENT
114 void dvpVerifyCommittedResources(ID3D11Buffer* CommittedD3D11CBs[],
115 ID3D11ShaderResourceView* CommittedD3D11SRVs[],
116 ID3D11Resource* CommittedD3D11SRVResources[],
117 ID3D11SamplerState* CommittedD3D11Samplers[],
118 ID3D11UnorderedAccessView* CommittedD3D11UAVs[],
119 ID3D11Resource* CommittedD3D11UAVResources[],
120 class ShaderResourceCacheD3D11& ResourceCache) const;
121 #endif
122
123
12460 private:
12561 using MaxBindPointType = Int8;
12662
232232 auto* pShaderResBindingD3D11 = ValidatedCast<ShaderResourceBindingD3D11Impl>(pShaderResourceBinding);
233233 auto& ResourceCache = pShaderResBindingD3D11->GetResourceCache();
234234
235 ResourceCache.TransitionResourceStates(*this, ShaderResourceCacheD3D11::StateTransitionMode::Transition);
235 ResourceCache.TransitionResourceStates<ShaderResourceCacheD3D11::StateTransitionMode::Transition>(*this);
236236 }
237237
238238 void DeviceContextD3D11Impl::CommitShaderResources(IShaderResourceBinding* pShaderResourceBinding, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)
253253
254254 if (StateTransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION)
255255 {
256 ResourceCache.TransitionResourceStates(*this, ShaderResourceCacheD3D11::StateTransitionMode::Transition);
256 ResourceCache.TransitionResourceStates<ShaderResourceCacheD3D11::StateTransitionMode::Transition>(*this);
257257 }
258258 #ifdef DILIGENT_DEVELOPMENT
259259 else if (StateTransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY)
260260 {
261 ResourceCache.TransitionResourceStates(*this, ShaderResourceCacheD3D11::StateTransitionMode::Verify);
261 ResourceCache.TransitionResourceStates<ShaderResourceCacheD3D11::StateTransitionMode::Verify>(*this);
262262 }
263263 #endif
264 }
265
266
267 void DeviceContextD3D11Impl::BindCacheResources(const ShaderResourceCacheD3D11& ResourceCache,
268 const TBindingsPerStage& BaseBindings,
269 TMinMaxSlotPerStage& MinMaxSlot,
270 SHADER_TYPE ActiveStages)
271 {
272 const auto CBCount = ResourceCache.GetCBCount();
273 if (CBCount != 0)
274 {
275 constexpr auto Range = D3D11_RESOURCE_RANGE_CBV;
276 ShaderResourceCacheD3D11::CachedCB const* CBs;
277 ID3D11Buffer* const* d3d11CBs;
278 BindPointsD3D11 const* bindPoints;
279 ResourceCache.GetConstCBArrays(CBs, d3d11CBs, bindPoints);
280
281 for (Uint32 cb = 0; cb < CBCount; ++cb)
282 {
283 const auto& BindPoints = bindPoints[cb];
284 Uint32 ActiveBits = BindPoints.GetActiveBits() & ActiveStages;
285 VERIFY(ActiveBits != 0, "resource is not initialized");
286 while (ActiveBits != 0)
287 {
288 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
289 ActiveBits &= ~(1u << ShaderInd);
290 VERIFY_EXPR(BindPoints.IsValid(ShaderInd));
291
292 auto* CommittedD3D11CBs = m_CommittedRes.D3D11CBs[ShaderInd];
293 UINT& MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
294 UINT& MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
295 const UINT Slot = BaseBindings[ShaderInd][Range] + BindPoints[ShaderInd];
296 const bool IsNewCB = CommittedD3D11CBs[Slot] != d3d11CBs[cb];
297 MinSlot = IsNewCB ? std::min(MinSlot, Slot) : MinSlot;
298 MaxSlot = IsNewCB ? Slot : MaxSlot;
299
300 VERIFY_EXPR(!IsNewCB || (Slot >= MinSlot && Slot <= MaxSlot));
301 VERIFY_EXPR(d3d11CBs[cb] != nullptr);
302 CommittedD3D11CBs[Slot] = d3d11CBs[cb];
303 }
304 }
305 }
306
307 const auto SRVCount = ResourceCache.GetSRVCount();
308 if (SRVCount != 0)
309 {
310 constexpr auto Range = D3D11_RESOURCE_RANGE_SRV;
311 ShaderResourceCacheD3D11::CachedResource const* SRVResources;
312 ID3D11ShaderResourceView* const* d3d11SRVs;
313 BindPointsD3D11 const* bindPoints;
314 ResourceCache.GetConstSRVArrays(SRVResources, d3d11SRVs, bindPoints);
315
316 for (Uint32 srv = 0; srv < SRVCount; ++srv)
317 {
318 const auto& BindPoints = bindPoints[srv];
319 Uint32 ActiveBits = BindPoints.GetActiveBits() & ActiveStages;
320 VERIFY(ActiveBits != 0, "resource is not initialized");
321 while (ActiveBits != 0)
322 {
323 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
324 ActiveBits &= ~(1u << ShaderInd);
325 VERIFY_EXPR(BindPoints.IsValid(ShaderInd));
326
327 auto* CommittedD3D11SRVs = m_CommittedRes.D3D11SRVs[ShaderInd];
328 auto* CommittedD3D11SRVRes = m_CommittedRes.D3D11SRVResources[ShaderInd];
329 UINT& MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
330 UINT& MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
331 const UINT Slot = BaseBindings[ShaderInd][Range] + BindPoints[ShaderInd];
332 const bool IsNewSRV = CommittedD3D11SRVs[Slot] != d3d11SRVs[srv];
333 MinSlot = IsNewSRV ? std::min(MinSlot, Slot) : MinSlot;
334 MaxSlot = IsNewSRV ? Slot : MaxSlot;
335
336 VERIFY_EXPR(!IsNewSRV || (Slot >= MinSlot && Slot <= MaxSlot));
337 VERIFY_EXPR(d3d11SRVs[srv] != nullptr);
338 CommittedD3D11SRVRes[Slot] = SRVResources[srv].pd3d11Resource;
339 CommittedD3D11SRVs[Slot] = d3d11SRVs[srv];
340 }
341 }
342 }
343
344 const auto SamplerCount = ResourceCache.GetSamplerCount();
345 if (SamplerCount != 0)
346 {
347 constexpr auto Range = D3D11_RESOURCE_RANGE_SAMPLER;
348 ShaderResourceCacheD3D11::CachedSampler const* Samplers;
349 ID3D11SamplerState* const* d3d11Samplers;
350 BindPointsD3D11 const* bindPoints;
351 ResourceCache.GetConstSamplerArrays(Samplers, d3d11Samplers, bindPoints);
352
353 for (Uint32 sam = 0; sam < SamplerCount; ++sam)
354 {
355 const auto& BindPoints = bindPoints[sam];
356 Uint32 ActiveBits = BindPoints.GetActiveBits() & ActiveStages;
357 VERIFY(ActiveBits != 0, "resource is not initialized");
358 while (ActiveBits != 0)
359 {
360 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
361 ActiveBits &= ~(1u << ShaderInd);
362 VERIFY_EXPR(BindPoints.IsValid(ShaderInd));
363
364 auto* CommittedD3D11Samplers = m_CommittedRes.D3D11Samplers[ShaderInd];
365 UINT& MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
366 UINT& MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
367 const UINT Slot = BaseBindings[ShaderInd][Range] + BindPoints[ShaderInd];
368 const bool IsNewSam = CommittedD3D11Samplers[Slot] != d3d11Samplers[sam];
369 MinSlot = IsNewSam ? std::min(MinSlot, Slot) : MinSlot;
370 MaxSlot = IsNewSam ? Slot : MaxSlot;
371
372 VERIFY_EXPR(!IsNewSam || (Slot >= MinSlot && Slot <= MaxSlot));
373 VERIFY_EXPR(d3d11Samplers[sam] != nullptr);
374 CommittedD3D11Samplers[Slot] = d3d11Samplers[sam];
375 }
376 }
377 }
378
379 const auto UAVCount = ResourceCache.GetUAVCount();
380 if (UAVCount != 0)
381 {
382 constexpr auto Range = D3D11_RESOURCE_RANGE_UAV;
383 ShaderResourceCacheD3D11::CachedResource const* UAVResources;
384 ID3D11UnorderedAccessView* const* d3d11UAVs;
385 BindPointsD3D11 const* bindPoints;
386 ResourceCache.GetConstUAVArrays(UAVResources, d3d11UAVs, bindPoints);
387
388 for (Uint32 uav = 0; uav < UAVCount; ++uav)
389 {
390 const auto& BindPoints = bindPoints[uav];
391 Uint32 ActiveBits = BindPoints.GetActiveBits() & ActiveStages;
392 VERIFY(ActiveBits != 0, "resource is not initialized");
393 while (ActiveBits != 0)
394 {
395 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
396 ActiveBits &= ~(1u << ShaderInd);
397 VERIFY_EXPR(BindPoints.IsValid(ShaderInd));
398
399 auto* CommittedD3D11UAVs = m_CommittedRes.D3D11UAVs[ShaderInd];
400 auto* CommittedD3D11UAVRes = m_CommittedRes.D3D11UAVResources[ShaderInd];
401 UINT& MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
402 UINT& MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
403 const UINT Slot = BaseBindings[ShaderInd][Range] + BindPoints[ShaderInd];
404 const bool IsNewUAV = CommittedD3D11UAVs[Slot] != d3d11UAVs[uav];
405 MinSlot = IsNewUAV ? std::min(MinSlot, Slot) : MinSlot;
406 MaxSlot = IsNewUAV ? Slot : MaxSlot;
407
408 VERIFY_EXPR(!IsNewUAV || (Slot >= MinSlot && Slot <= MaxSlot));
409 VERIFY_EXPR(d3d11UAVs[uav] != nullptr);
410 CommittedD3D11UAVRes[Slot] = UAVResources[uav].pd3d11Resource;
411 CommittedD3D11UAVs[Slot] = d3d11UAVs[uav];
412 }
413 }
414 }
264415 }
265416
266417 void DeviceContextD3D11Impl::BindShaderResources()
267418 {
268419 if ((m_BindInfo.StaleSRBMask & m_BindInfo.ActiveSRBMask) == 0)
269420 return;
421
270422
271423 TBindingsPerStage Bindings = {};
272424 TMinMaxSlotPerStage MinMaxSlot = {};
273425 const auto ActiveStages = m_BindInfo.ActiveStages;
274426
275427 if (m_pPipelineState->GetDesc().IsAnyGraphicsPipeline())
276 Bindings[GetShaderTypeIndex(SHADER_TYPE_PIXEL)][DESCRIPTOR_RANGE_UAV] = static_cast<Uint8>(m_pPipelineState->GetGraphicsPipelineDesc().NumRenderTargets);
428 Bindings[GetShaderTypeIndex(SHADER_TYPE_PIXEL)][D3D11_RESOURCE_RANGE_UAV] = static_cast<Uint8>(m_pPipelineState->GetGraphicsPipelineDesc().NumRenderTargets);
277429
278430 auto ActiveSRBMask = Uint32{m_BindInfo.ActiveSRBMask};
279431 while (ActiveSRBMask != 0)
292444 #ifdef DILIGENT_DEVELOPMENT
293445 m_BindInfo.BoundResOffsets[sign] = Bindings;
294446 #endif
295 pSRB->GetResourceCache().BindResources(*this, Bindings, MinMaxSlot, m_CommittedRes, ActiveStages);
447 BindCacheResources(pSRB->GetResourceCache(), Bindings, MinMaxSlot, ActiveStages);
296448 }
297449 pSRB->GetSignature()->ShiftBindings(Bindings);
298450 }
307459
308460 // CBV
309461 {
310 const auto Range = DESCRIPTOR_RANGE_CBV;
462 const auto Range = D3D11_RESOURCE_RANGE_CBV;
311463 const UINT MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
312464 const UINT MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
313465 if (MinSlot != UINT_MAX)
327479
328480 // SRV
329481 {
330 const auto Range = DESCRIPTOR_RANGE_SRV;
482 const auto Range = D3D11_RESOURCE_RANGE_SRV;
331483 const UINT MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
332484 const UINT MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
333485 if (MinSlot != UINT_MAX)
347499
348500 // Sampler
349501 {
350 const auto Range = DESCRIPTOR_RANGE_SAMPLER;
502 const auto Range = D3D11_RESOURCE_RANGE_SAMPLER;
351503 const UINT MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
352504 const UINT MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
353505 if (MinSlot != UINT_MAX)
367519
368520 // UAV
369521 {
370 const auto Range = DESCRIPTOR_RANGE_UAV;
522 const auto Range = D3D11_RESOURCE_RANGE_UAV;
371523 const UINT MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
372524 const UINT MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
373525 if (MinSlot != UINT_MAX)
3131 namespace Diligent
3232 {
3333
34 DESCRIPTOR_RANGE ShaderResourceToDescriptorRange(SHADER_RESOURCE_TYPE Type)
34 D3D11_RESOURCE_RANGE ShaderResourceToDescriptorRange(SHADER_RESOURCE_TYPE Type)
3535 {
3636 static_assert(SHADER_RESOURCE_TYPE_LAST == 8, "Please update the switch below to handle the new shader resource type");
3737 switch (Type)
3838 {
3939 // clang-format off
40 case SHADER_RESOURCE_TYPE_CONSTANT_BUFFER: return DESCRIPTOR_RANGE_CBV;
41 case SHADER_RESOURCE_TYPE_TEXTURE_SRV: return DESCRIPTOR_RANGE_SRV;
42 case SHADER_RESOURCE_TYPE_BUFFER_SRV: return DESCRIPTOR_RANGE_SRV;
43 case SHADER_RESOURCE_TYPE_TEXTURE_UAV: return DESCRIPTOR_RANGE_UAV;
44 case SHADER_RESOURCE_TYPE_BUFFER_UAV: return DESCRIPTOR_RANGE_UAV;
45 case SHADER_RESOURCE_TYPE_SAMPLER: return DESCRIPTOR_RANGE_SAMPLER;
46 case SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT: return DESCRIPTOR_RANGE_SRV;
40 case SHADER_RESOURCE_TYPE_CONSTANT_BUFFER: return D3D11_RESOURCE_RANGE_CBV;
41 case SHADER_RESOURCE_TYPE_TEXTURE_SRV: return D3D11_RESOURCE_RANGE_SRV;
42 case SHADER_RESOURCE_TYPE_BUFFER_SRV: return D3D11_RESOURCE_RANGE_SRV;
43 case SHADER_RESOURCE_TYPE_TEXTURE_UAV: return D3D11_RESOURCE_RANGE_UAV;
44 case SHADER_RESOURCE_TYPE_BUFFER_UAV: return D3D11_RESOURCE_RANGE_UAV;
45 case SHADER_RESOURCE_TYPE_SAMPLER: return D3D11_RESOURCE_RANGE_SAMPLER;
46 case SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT: return D3D11_RESOURCE_RANGE_SRV;
4747 // clang-format on
4848 default:
4949 UNEXPECTED("Unsupported resource type");
50 return DESCRIPTOR_RANGE_UNKNOWN;
50 return D3D11_RESOURCE_RANGE_UNKNOWN;
5151 }
5252 }
5353
116116
117117 void PipelineResourceSignatureD3D11Impl::CreateLayout()
118118 {
119 using TBindings32 = std::array<Uint32, DESCRIPTOR_RANGE_COUNT>;
119 using TBindings32 = std::array<Uint32, D3D11_RESOURCE_RANGE_COUNT>;
120120 using TBindingsPerStage32 = std::array<TBindings32, NumShaderTypes>;
121121
122122 if (m_pStaticResCache)
174174
175175 TBindings32 ResourceCount = {};
176176 TBindingsPerStage32 BindingPerStage = {};
177 const auto AllocBindPoints = [&BindingPerStage](BindPointsD3D11& BindPoints, SHADER_TYPE ShaderStages, Uint32 ArraySize, DESCRIPTOR_RANGE Range) //
177 const auto AllocBindPoints = [&BindingPerStage](BindPointsD3D11& BindPoints, SHADER_TYPE ShaderStages, Uint32 ArraySize, D3D11_RESOURCE_RANGE Range) //
178178 {
179179 while (ShaderStages != 0)
180180 {
201201 }
202202
203203 constexpr SHADER_TYPE UAVStages = SHADER_TYPE_PIXEL | SHADER_TYPE_COMPUTE;
204 if (Range == DESCRIPTOR_RANGE_UAV && (ResDesc.ShaderStages & ~UAVStages) != 0)
204 if (Range == D3D11_RESOURCE_RANGE_UAV && (ResDesc.ShaderStages & ~UAVStages) != 0)
205205 {
206206 LOG_ERROR_AND_THROW("Description of a pipeline resource signature '", m_Desc.Name, "' is invalid: ",
207207 "Desc.Resources[", i, "].ResourceType (", GetShaderResourceTypeLiteralName(ResDesc.ResourceType),
217217
218218 if (!ImtblSampAttribs.IsAllocated())
219219 {
220 ImtblSampAttribs.CacheOffset = ResourceCount[DESCRIPTOR_RANGE_SAMPLER];
221 AllocBindPoints(ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, DESCRIPTOR_RANGE_SAMPLER);
222 ResourceCount[DESCRIPTOR_RANGE_SAMPLER] += ImtblSampAttribs.ArraySize;
220 ImtblSampAttribs.CacheOffset = ResourceCount[D3D11_RESOURCE_RANGE_SAMPLER];
221 AllocBindPoints(ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, D3D11_RESOURCE_RANGE_SAMPLER);
222 ResourceCount[D3D11_RESOURCE_RANGE_SAMPLER] += ImtblSampAttribs.ArraySize;
223223 }
224224 }
225225
252252 // Add bindings for immutable samplers that is not assigned to texture or separate sampler.
253253 for (Uint32 i = 0; i < m_Desc.NumImmutableSamplers; ++i)
254254 {
255 const auto Range = DESCRIPTOR_RANGE_SAMPLER;
255 const auto Range = D3D11_RESOURCE_RANGE_SAMPLER;
256256 const auto& ImtblSamp = GetImmutableSamplerDesc(i);
257257 auto& ImtblSampAttribs = m_ImmutableSamplers[i];
258258
328328 const auto& ResAttr = GetResourceAttribs(r);
329329 VERIFY_EXPR(ResDesc.VarType == SHADER_RESOURCE_VARIABLE_TYPE_STATIC);
330330
331 static_assert(DESCRIPTOR_RANGE_COUNT == 4, "Please update the switch below to handle the new descriptor range");
331 static_assert(D3D11_RESOURCE_RANGE_COUNT == 4, "Please update the switch below to handle the new descriptor range");
332332 switch (ShaderResourceToDescriptorRange(ResDesc.ResourceType))
333333 {
334 case DESCRIPTOR_RANGE_CBV:
334 case D3D11_RESOURCE_RANGE_CBV:
335335 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
336336 {
337337 const auto& SrcCachedRes = SrcResourceCache.GetCB(ResAttr.CacheOffset + ArrInd);
341341 DstResourceCache.SetCB(ResAttr.CacheOffset + ArrInd, ResAttr.BindPoints + ArrInd, RefCntAutoPtr<BufferD3D11Impl>{SrcCachedRes.pBuff});
342342 }
343343 break;
344 case DESCRIPTOR_RANGE_SRV:
344 case D3D11_RESOURCE_RANGE_SRV:
345345 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
346346 {
347347 const auto& SrcCachedRes = SrcResourceCache.GetSRV(ResAttr.CacheOffset + ArrInd);
354354 DstResourceCache.SetBufSRV(ResAttr.CacheOffset + ArrInd, ResAttr.BindPoints + ArrInd, RefCntAutoPtr<BufferViewD3D11Impl>{SrcCachedRes.pView.RawPtr<BufferViewD3D11Impl>()});
355355 }
356356 break;
357 case DESCRIPTOR_RANGE_SAMPLER:
357 case D3D11_RESOURCE_RANGE_SAMPLER:
358358 // Immutable samplers will be copied in InitSRBResourceCache().
359359 if (!ResAttr.IsImmutableSamplerAssigned())
360360 {
368368 }
369369 }
370370 break;
371 case DESCRIPTOR_RANGE_UAV:
371 case D3D11_RESOURCE_RANGE_UAV:
372372 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
373373 {
374374 const auto& SrcCachedRes = SrcResourceCache.GetUAV(ResAttr.CacheOffset + ArrInd);
440440 {
441441 const auto& ImtblSam = GetImmutableSamplerDesc(samp);
442442 const auto& SampAttr = GetImmutableSamplerAttribs(samp);
443 const auto Range = DESCRIPTOR_RANGE_SAMPLER;
443 const auto Range = D3D11_RESOURCE_RANGE_SAMPLER;
444444
445445 if ((ImtblSam.ShaderStages & ShaderStage) != 0 && SampAttr.IsAllocated())
446446 {
488488 bool BindingsOK = true;
489489 switch (ShaderResourceToDescriptorRange(ResDesc.ResourceType))
490490 {
491 case DESCRIPTOR_RANGE_CBV:
491 case D3D11_RESOURCE_RANGE_CBV:
492492 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
493493 {
494494 if (!ResourceCache.IsCBBound(ResAttr.CacheOffset + ArrInd))
500500 }
501501 break;
502502
503 case DESCRIPTOR_RANGE_SAMPLER:
503 case D3D11_RESOURCE_RANGE_SAMPLER:
504504 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
505505 {
506506 if (!ResourceCache.IsSamplerBound(ResAttr.CacheOffset + ArrInd))
512512 }
513513 break;
514514
515 case DESCRIPTOR_RANGE_SRV:
515 case D3D11_RESOURCE_RANGE_SRV:
516516 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
517517 {
518518 const bool IsTexView = (ResDesc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || ResDesc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT);
532532 }
533533 break;
534534
535 case DESCRIPTOR_RANGE_UAV:
535 case D3D11_RESOURCE_RANGE_UAV:
536536 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
537537 {
538538 const bool IsTexView = (ResDesc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || ResDesc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV);
201201
202202 PipelineResourceSignatureD3D11Impl::TBindingsPerStage BindingsPerStage = {};
203203 if (m_Desc.IsAnyGraphicsPipeline())
204 BindingsPerStage[PSInd][DESCRIPTOR_RANGE_UAV] = GetGraphicsPipelineDesc().NumRenderTargets;
204 BindingsPerStage[PSInd][D3D11_RESOURCE_RANGE_UAV] = GetGraphicsPipelineDesc().NumRenderTargets;
205205
206206 ResourceBinding::TMap ResourceMap;
207207 for (Uint32 sign = 0; sign < m_SignatureCount; ++sign)
231231 PipelineResourceSignatureD3D11Impl::TBindingsPerStage BindingsPerStage = {};
232232
233233 if (m_Desc.IsAnyGraphicsPipeline())
234 BindingsPerStage[PSInd][DESCRIPTOR_RANGE_UAV] = GetGraphicsPipelineDesc().NumRenderTargets;
234 BindingsPerStage[PSInd][D3D11_RESOURCE_RANGE_UAV] = GetGraphicsPipelineDesc().NumRenderTargets;
235235
236236 for (Uint32 sign = 0; sign < m_SignatureCount; ++sign)
237237 {
244244 {
245245 const auto& BindCount = BindingsPerStage[s];
246246
247 DEV_CHECK_ERR(BindCount[DESCRIPTOR_RANGE_CBV] <= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT,
248 "Constant buffer count ", Uint32{BindCount[DESCRIPTOR_RANGE_CBV]}, " exceeds D3D11 limit ", D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
249 DEV_CHECK_ERR(BindCount[DESCRIPTOR_RANGE_SRV] <= D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT,
250 "SRV count ", Uint32{BindCount[DESCRIPTOR_RANGE_SRV]}, " exceeds D3D11 limit ", D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT);
251 DEV_CHECK_ERR(BindCount[DESCRIPTOR_RANGE_SAMPLER] <= D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT,
252 "Sampler count ", Uint32{BindCount[DESCRIPTOR_RANGE_SAMPLER]}, " exceeds D3D11 limit ", D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT);
253 DEV_CHECK_ERR(BindCount[DESCRIPTOR_RANGE_UAV] <= D3D11_PS_CS_UAV_REGISTER_COUNT,
254 "UAV count ", Uint32{BindCount[DESCRIPTOR_RANGE_UAV]}, " exceeds D3D11 limit ", D3D11_PS_CS_UAV_REGISTER_COUNT);
247 DEV_CHECK_ERR(BindCount[D3D11_RESOURCE_RANGE_CBV] <= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT,
248 "Constant buffer count ", Uint32{BindCount[D3D11_RESOURCE_RANGE_CBV]}, " exceeds D3D11 limit ", D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
249 DEV_CHECK_ERR(BindCount[D3D11_RESOURCE_RANGE_SRV] <= D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT,
250 "SRV count ", Uint32{BindCount[D3D11_RESOURCE_RANGE_SRV]}, " exceeds D3D11 limit ", D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT);
251 DEV_CHECK_ERR(BindCount[D3D11_RESOURCE_RANGE_SAMPLER] <= D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT,
252 "Sampler count ", Uint32{BindCount[D3D11_RESOURCE_RANGE_SAMPLER]}, " exceeds D3D11 limit ", D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT);
253 DEV_CHECK_ERR(BindCount[D3D11_RESOURCE_RANGE_UAV] <= D3D11_PS_CS_UAV_REGISTER_COUNT,
254 "UAV count ", Uint32{BindCount[D3D11_RESOURCE_RANGE_UAV]}, " exceeds D3D11 limit ", D3D11_PS_CS_UAV_REGISTER_COUNT);
255255 }
256256 #endif
257257 }
524524 TBindingsPerStage Bindings = {};
525525
526526 if (m_Desc.IsAnyGraphicsPipeline())
527 Bindings[GetShaderTypeIndex(SHADER_TYPE_PIXEL)][DESCRIPTOR_RANGE_UAV] = static_cast<Uint8>(GetGraphicsPipelineDesc().NumRenderTargets);
527 Bindings[GetShaderTypeIndex(SHADER_TYPE_PIXEL)][D3D11_RESOURCE_RANGE_UAV] = static_cast<Uint8>(GetGraphicsPipelineDesc().NumRenderTargets);
528528
529529 for (Uint32 sign = 0; sign < SignCount; ++sign)
530530 {
3737
3838 namespace Diligent
3939 {
40
4041 size_t ShaderResourceCacheD3D11::GetRequriedMemorySize(const TResourceCount& ResCount)
4142 {
4243 // clang-format off
43 auto CBCount = ResCount[DESCRIPTOR_RANGE_CBV];
44 auto SRVCount = ResCount[DESCRIPTOR_RANGE_SRV];
45 auto SamplerCount = ResCount[DESCRIPTOR_RANGE_SAMPLER];
46 auto UAVCount = ResCount[DESCRIPTOR_RANGE_UAV];
44 auto CBCount = ResCount[D3D11_RESOURCE_RANGE_CBV];
45 auto SRVCount = ResCount[D3D11_RESOURCE_RANGE_SRV];
46 auto SamplerCount = ResCount[D3D11_RESOURCE_RANGE_SAMPLER];
47 auto UAVCount = ResCount[D3D11_RESOURCE_RANGE_UAV];
4748 size_t MemSize = 0;
4849 MemSize = AlignUp(MemSize + (sizeof(CachedCB) + sizeof(BindPointsD3D11) + sizeof(ID3D11Buffer*)) * CBCount, MaxAlignment);
4950 MemSize = AlignUp(MemSize + (sizeof(CachedResource) + sizeof(BindPointsD3D11) + sizeof(ID3D11ShaderResourceView*)) * SRVCount, MaxAlignment);
5758 void ShaderResourceCacheD3D11::Initialize(const TResourceCount& ResCount, IMemoryAllocator& MemAllocator)
5859 {
5960 // http://diligentgraphics.com/diligent-engine/architecture/d3d11/shader-resource-cache/
60 if (IsInitialized())
61 {
62 LOG_ERROR_MESSAGE("Resource cache is already intialized");
63 return;
64 }
65
66 const Uint32 CBCount = ResCount[DESCRIPTOR_RANGE_CBV];
67 const Uint32 SRVCount = ResCount[DESCRIPTOR_RANGE_SRV];
68 const Uint32 SamplerCount = ResCount[DESCRIPTOR_RANGE_SAMPLER];
69 const Uint32 UAVCount = ResCount[DESCRIPTOR_RANGE_UAV];
61 VERIFY(!IsInitialized(), "Resource cache has already been intialized!");
62
63 const Uint32 CBCount = ResCount[D3D11_RESOURCE_RANGE_CBV];
64 const Uint32 SRVCount = ResCount[D3D11_RESOURCE_RANGE_SRV];
65 const Uint32 SamplerCount = ResCount[D3D11_RESOURCE_RANGE_SAMPLER];
66 const Uint32 UAVCount = ResCount[D3D11_RESOURCE_RANGE_UAV];
7067
7168 // clang-format off
7269 m_CBCount = static_cast<decltype(m_CBCount )>(CBCount);
9188
9289 if (BufferSize > 0)
9390 {
94 m_pResourceData = ALLOCATE(MemAllocator, "Shader resource cache data buffer", Uint8, BufferSize);
95 memset(m_pResourceData, 0, BufferSize);
96 m_pAllocator = &MemAllocator;
91 m_pResourceData = decltype(m_pResourceData){
92 ALLOCATE(MemAllocator, "Shader resource cache data buffer", Uint8, BufferSize),
93 STDDeleter<Uint8, IMemoryAllocator>(MemAllocator) //
94 };
95 memset(m_pResourceData.get(), 0, BufferSize);
9796 }
9897
9998 // Explicitly construct all objects
207206 m_SamplerCount = 0;
208207 m_UAVCount = 0;
209208
210 if (m_pResourceData != nullptr)
211 m_pAllocator->Free(m_pResourceData);
212
213 m_pResourceData = nullptr;
214 m_pAllocator = nullptr;
209 m_pResourceData.reset();
215210 }
216211 }
217212
218213 #ifdef DILIGENT_DEVELOPMENT
219214 namespace
220215 {
216
221217 void DvpVerifyResource(ShaderResourceCacheD3D11::CachedResource& Res, ID3D11View* pd3d11View, const char* ViewType)
222218 {
223219 if (pd3d11View != nullptr)
235231 VERIFY(pd3d11ActualResource == Res.pBuffer->GetD3D11Buffer(), "Inconsistent buffer ", ViewType);
236232 if (Res.pView)
237233 {
238 RefCntAutoPtr<IBufferViewD3D11> pBufView(Res.pView, IID_BufferViewD3D11);
234 RefCntAutoPtr<IBufferViewD3D11> pBufView{Res.pView, IID_BufferViewD3D11};
239235 VERIFY(pBufView != nullptr, "Provided resource view is not D3D11 buffer view");
240236 if (pBufView)
241237 VERIFY(pBufView->GetBuffer() == Res.pBuffer, "Provided resource view is not a view of the buffer");
246242 VERIFY(pd3d11ActualResource == Res.pTexture->GetD3D11Texture(), "Inconsistent texture ", ViewType);
247243 if (Res.pView)
248244 {
249 RefCntAutoPtr<ITextureViewD3D11> pTexView(Res.pView, IID_TextureViewD3D11);
245 RefCntAutoPtr<ITextureViewD3D11> pTexView{Res.pView, IID_TextureViewD3D11};
250246 VERIFY(pTexView != nullptr, "Provided resource view is not D3D11 texture view");
251247 if (pTexView)
252248 VERIFY(pTexView->GetTexture() == Res.pTexture, "Provided resource view is not a view of the texture");
260256 VERIFY(Res.pd3d11Resource == nullptr, "Unexepected D3D11 resource");
261257 }
262258 }
259
263260 } // namespace
264261
265262 void ShaderResourceCacheD3D11::DvpVerifyCacheConsistency()
323320 }
324321 #endif
325322
326 template <typename THandleResource>
327 void ShaderResourceCacheD3D11::ProcessResources(THandleResource HandleResources)
328 {
329 {
330 ShaderResourceCacheD3D11::CachedCB* CachedCBs;
331 ID3D11Buffer** d3d11CBs;
332 BindPointsD3D11* bindPoints;
333 GetCBArrays(CachedCBs, d3d11CBs, bindPoints);
334 HandleResources(GetCBCount(), CachedCBs, d3d11CBs);
335 }
336 {
337 ShaderResourceCacheD3D11::CachedResource* CachedSRVResources;
338 ID3D11ShaderResourceView** d3d11SRVs;
339 BindPointsD3D11* bindPoints;
340 GetSRVArrays(CachedSRVResources, d3d11SRVs, bindPoints);
341 HandleResources(GetSRVCount(), CachedSRVResources, d3d11SRVs);
342 }
343 {
344 ShaderResourceCacheD3D11::CachedSampler* CachedSamplers;
345 ID3D11SamplerState** d3d11Samplers;
346 BindPointsD3D11* bindPoints;
347 GetSamplerArrays(CachedSamplers, d3d11Samplers, bindPoints);
348 HandleResources(GetSamplerCount(), CachedSamplers, d3d11Samplers);
349 }
350 {
351 ShaderResourceCacheD3D11::CachedResource* CachedUAVResources;
352 ID3D11UnorderedAccessView** d3d11UAVs;
353 BindPointsD3D11* bindPoints;
354 GetUAVArrays(CachedUAVResources, d3d11UAVs, bindPoints);
355 HandleResources(GetUAVCount(), CachedUAVResources, d3d11UAVs);
356 }
357 }
358
359 void ShaderResourceCacheD3D11::TransitionResourceStates(DeviceContextD3D11Impl& Ctx, StateTransitionMode Mode)
323 template <ShaderResourceCacheD3D11::StateTransitionMode Mode>
324 void ShaderResourceCacheD3D11::TransitionResourceStates(DeviceContextD3D11Impl& Ctx)
360325 {
361326 VERIFY_EXPR(IsInitialized());
362327
363 switch (Mode)
364 {
365 case StateTransitionMode::Transition:
366 {
367 ProcessResources([&](Uint32 Count, auto* Resources, auto* Views) { TransitionResource(Ctx, Count, Resources, Views); });
368 break;
369 }
370 case StateTransitionMode::Verify:
371 {
372 #ifdef DILIGENT_DEVELOPMENT
373 ProcessResources([&](Uint32 Count, auto* Resources, auto* Views) { DvpVerifyResourceState(Ctx, Count, Resources, Views); });
374 #endif
375 break;
376 }
377 default:
378 UNEXPECTED("Unexpected mode");
379 }
380 }
381
382 void ShaderResourceCacheD3D11::TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedCB* CBs, ID3D11Buffer** pd3d11CBs)
383 {
384 for (Uint32 i = 0; i < Count; ++i)
328 TransitionResources<Mode>(Ctx, static_cast<ID3D11Buffer*>(nullptr));
329 TransitionResources<Mode>(Ctx, static_cast<ID3D11ShaderResourceView*>(nullptr));
330 TransitionResources<Mode>(Ctx, static_cast<ID3D11SamplerState*>(nullptr));
331 TransitionResources<Mode>(Ctx, static_cast<ID3D11UnorderedAccessView*>(nullptr));
332 }
333
334 template <ShaderResourceCacheD3D11::StateTransitionMode Mode>
335 void ShaderResourceCacheD3D11::TransitionResources(DeviceContextD3D11Impl& Ctx, const ID3D11Buffer* /*Selector*/) const
336 {
337 const auto CBCount = GetCBCount();
338 if (CBCount == 0)
339 return;
340
341 CachedCB* CBs;
342 ID3D11Buffer** d3d11CBs;
343 BindPointsD3D11* bindPoints;
344 GetCBArrays(CBs, d3d11CBs, bindPoints);
345
346 for (Uint32 i = 0; i < CBCount; ++i)
385347 {
386348 if (auto* pBuffer = CBs[i].pBuff.RawPtr<BufferD3D11Impl>())
387349 {
388350 if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_CONSTANT_BUFFER))
389 { /*
390 if (pBuffer->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
391 {
392 // Even though we have unbound resources from UAV, we only checked shader
393 // stages active in current PSO, so we still may need to unbind the resource
394 // from UAV (for instance, unbind resource from CS UAV when running draw command).
395 Ctx.UnbindResourceFromUAV(pBuffer, pd3d11CBs[i]);
396 pBuffer->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
397 }
398 pBuffer->AddState(RESOURCE_STATE_CONSTANT_BUFFER);*/
399 Ctx.TransitionResource(pBuffer, RESOURCE_STATE_CONSTANT_BUFFER);
400 }
401 }
402 }
403 }
404
405 void ShaderResourceCacheD3D11::TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedResource* SRVResources, ID3D11ShaderResourceView** d3d11SRVs)
406 {
407 for (Uint32 i = 0; i < Count; ++i)
351 {
352 if (Mode == StateTransitionMode::Transition)
353 {
354 Ctx.TransitionResource(pBuffer, RESOURCE_STATE_CONSTANT_BUFFER);
355 }
356 else
357 {
358 LOG_ERROR_MESSAGE("Buffer '", pBuffer->GetDesc().Name,
359 "' has not been transitioned to Constant Buffer state. Call TransitionShaderResources(), use "
360 "RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the buffer to required state.");
361 }
362 }
363 }
364 }
365 }
366
367 template <ShaderResourceCacheD3D11::StateTransitionMode Mode>
368 void ShaderResourceCacheD3D11::TransitionResources(DeviceContextD3D11Impl& Ctx, const ID3D11ShaderResourceView* /*Selector*/) const
369 {
370 const auto SRVCount = GetSRVCount();
371 if (SRVCount == 0)
372 return;
373
374 CachedResource* SRVResources;
375 ID3D11ShaderResourceView** d3d11SRVs;
376 BindPointsD3D11* bindPoints;
377 GetSRVArrays(SRVResources, d3d11SRVs, bindPoints);
378
379 for (Uint32 i = 0; i < SRVCount; ++i)
408380 {
409381 auto& SRVRes = SRVResources[i];
410382 if (auto* pTexture = SRVRes.pTexture)
411383 {
412384 if (pTexture->IsInKnownState() && !pTexture->CheckAnyState(RESOURCE_STATE_SHADER_RESOURCE | RESOURCE_STATE_INPUT_ATTACHMENT))
413 { /*
414 if (pTexture->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
415 {
416 // Even though we have unbound resources from UAV, we only checked shader
417 // stages active in current PSO, so we still may need to unbind the resource
418 // from UAV (for instance, unbind resource from CS UAV when running draw command).
419 Ctx.UnbindResourceFromUAV(pTexture, SRVRes.pd3d11Resource);
420 pTexture->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
421 }
422
423 if (pTexture->CheckState(RESOURCE_STATE_RENDER_TARGET))
424 Ctx.UnbindTextureFromRenderTarget(pTexture);
425
426 if (pTexture->CheckState(RESOURCE_STATE_DEPTH_WRITE))
427 Ctx.UnbindTextureFromDepthStencil(pTexture);
428
429 pTexture->SetState(RESOURCE_STATE_SHADER_RESOURCE);*/
430 Ctx.TransitionResource(pTexture, RESOURCE_STATE_SHADER_RESOURCE);
385 {
386 if (Mode == StateTransitionMode::Transition)
387 {
388 Ctx.TransitionResource(pTexture, RESOURCE_STATE_SHADER_RESOURCE);
389 }
390 else
391 {
392 LOG_ERROR_MESSAGE("Texture '", pTexture->GetDesc().Name,
393 "' has not been transitioned to Shader Resource state. Call TransitionShaderResources(), use "
394 "RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the texture to required state.");
395 }
431396 }
432397 }
433398 else if (auto* pBuffer = SRVRes.pBuffer)
434399 {
435400 if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_SHADER_RESOURCE))
436 { /*
437 if (pBuffer->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
438 {
439 Ctx.UnbindResourceFromUAV(pBuffer, SRVRes.pd3d11Resource);
440 pBuffer->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
441 }
442 pBuffer->AddState(RESOURCE_STATE_SHADER_RESOURCE);*/
443 Ctx.TransitionResource(pBuffer, RESOURCE_STATE_SHADER_RESOURCE);
444 }
445 }
446 }
447 }
448
449 void ShaderResourceCacheD3D11::TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedSampler* Samplers, ID3D11SamplerState** pd3d11Samplers)
450 {
451 }
452
453 void ShaderResourceCacheD3D11::TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedResource* UAVResources, ID3D11UnorderedAccessView** pd3d11UAVs)
454 {
455 for (Uint32 i = 0; i < Count; ++i)
401 {
402 if (Mode == StateTransitionMode::Transition)
403 {
404 Ctx.TransitionResource(pBuffer, RESOURCE_STATE_SHADER_RESOURCE);
405 }
406 else
407 {
408 LOG_ERROR_MESSAGE("Buffer '", pBuffer->GetDesc().Name,
409 "' has not been transitioned to Shader Resource state. Call TransitionShaderResources(), use "
410 "RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the buffer to required state.");
411 }
412 }
413 }
414 }
415 }
416
417 template <ShaderResourceCacheD3D11::StateTransitionMode Mode>
418 void ShaderResourceCacheD3D11::TransitionResources(DeviceContextD3D11Impl& Ctx, const ID3D11SamplerState* /*Selector*/) const
419 {
420 }
421
422 template <ShaderResourceCacheD3D11::StateTransitionMode Mode>
423 void ShaderResourceCacheD3D11::TransitionResources(DeviceContextD3D11Impl& Ctx, const ID3D11UnorderedAccessView* /*Selector*/) const
424 {
425 const auto UAVCount = GetUAVCount();
426 if (UAVCount == 0)
427 return;
428
429 CachedResource* UAVResources;
430 ID3D11UnorderedAccessView** d3d11UAVs;
431 BindPointsD3D11* bindPoints;
432 GetUAVArrays(UAVResources, d3d11UAVs, bindPoints);
433
434 for (Uint32 i = 0; i < UAVCount; ++i)
456435 {
457436 auto& UAVRes = UAVResources[i];
458437 if (auto* pTexture = UAVRes.pTexture)
459438 {
460439 if (pTexture->IsInKnownState() && !pTexture->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
461 { /*
462 if (pTexture->CheckAnyState(RESOURCE_STATE_SHADER_RESOURCE | RESOURCE_STATE_INPUT_ATTACHMENT))
463 Ctx.UnbindTextureFromInput(pTexture, UAVRes.pd3d11Resource);
464 pTexture->SetState(RESOURCE_STATE_UNORDERED_ACCESS);*/
465 Ctx.TransitionResource(pTexture, RESOURCE_STATE_UNORDERED_ACCESS);
440 {
441 if (Mode == StateTransitionMode::Transition)
442 {
443 Ctx.TransitionResource(pTexture, RESOURCE_STATE_UNORDERED_ACCESS);
444 }
445 else
446 {
447 LOG_ERROR_MESSAGE("Texture '", pTexture->GetDesc().Name,
448 "' has not been transitioned to Unordered Access state. Call TransitionShaderResources(), use "
449 "RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the texture to required state.");
450 }
466451 }
467452 }
468453 else if (auto* pBuffer = UAVRes.pBuffer)
469454 {
470455 if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
471 { /*
472 if ((pBuffer->GetState() & RESOURCE_STATE_GENERIC_READ) != 0)
473 Ctx.UnbindBufferFromInput(pBuffer, UAVRes.pd3d11Resource);
474 pBuffer->SetState(RESOURCE_STATE_UNORDERED_ACCESS);*/
475 Ctx.TransitionResource(pBuffer, RESOURCE_STATE_UNORDERED_ACCESS);
476 }
477 }
478 }
479 }
480
481 #ifdef DILIGENT_DEVELOPMENT
482 void ShaderResourceCacheD3D11::DvpVerifyResourceState(DeviceContextD3D11Impl&, Uint32 Count, const CachedCB* CBs, ID3D11Buffer**)
483 {
484 for (Uint32 i = 0; i < Count; ++i)
485 {
486 if (const auto* pBuff = CBs[i].pBuff.RawPtr<BufferD3D11Impl>())
487 {
488 if (pBuff->IsInKnownState() && !pBuff->CheckState(RESOURCE_STATE_CONSTANT_BUFFER))
489 {
490 LOG_ERROR_MESSAGE("Buffer '", pBuff->GetDesc().Name, "' has not been transitioned to Constant Buffer state. Call TransitionShaderResources(), use RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the buffer to required state.");
491 }
492 }
493 }
494 }
495
496 void ShaderResourceCacheD3D11::DvpVerifyResourceState(DeviceContextD3D11Impl& Ctx, Uint32 Count, const CachedResource* SRVResources, ID3D11ShaderResourceView**)
497 {
498 for (Uint32 i = 0; i < Count; ++i)
499 {
500 auto& SRVRes = SRVResources[i];
501 if (const auto* pTexture = SRVRes.pTexture)
502 {
503 if (pTexture->IsInKnownState() &&
504 !(pTexture->CheckState(RESOURCE_STATE_SHADER_RESOURCE) || Ctx.HasActiveRenderPass() && pTexture->CheckState(RESOURCE_STATE_INPUT_ATTACHMENT)))
505 {
506 LOG_ERROR_MESSAGE("Texture '", pTexture->GetDesc().Name, "' has not been transitioned to Shader Resource state. Call TransitionShaderResources(), use RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the texture to required state.");
507 }
508 }
509 else if (const auto* pBuffer = SRVRes.pBuffer)
510 {
511 if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_SHADER_RESOURCE))
512 {
513 LOG_ERROR_MESSAGE("Buffer '", pBuffer->GetDesc().Name, "' has not been transitioned to Shader Resource state. Call TransitionShaderResources(), use RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the buffer to required state.");
514 }
515 }
516 }
517 }
518
519 void ShaderResourceCacheD3D11::DvpVerifyResourceState(DeviceContextD3D11Impl& Ctx, Uint32 Count, const CachedSampler* Samplers, ID3D11SamplerState**)
520 {
521 }
522
523 void ShaderResourceCacheD3D11::DvpVerifyResourceState(DeviceContextD3D11Impl&, Uint32 Count, const CachedResource* UAVResources, ID3D11UnorderedAccessView**)
524 {
525 for (Uint32 i = 0; i < Count; ++i)
526 {
527 auto& UAVRes = UAVResources[i];
528 if (const auto* pTexture = UAVRes.pTexture)
529 {
530 if (pTexture->IsInKnownState() && !pTexture->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
531 {
532 LOG_ERROR_MESSAGE("Texture '", pTexture->GetDesc().Name, "' has not been transitioned to Unordered Access state. Call TransitionShaderResources(), use RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the texture to required state.");
533 }
534 }
535 else if (const auto* pBuffer = UAVRes.pBuffer)
536 {
537 if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
538 {
539 LOG_ERROR_MESSAGE("Buffer '", pBuffer->GetDesc().Name, "' has not been transitioned to Unordered Access state. Call TransitionShaderResources(), use RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the buffer to required state.");
540 }
541 }
542 }
543 }
544 #endif // DILIGENT_DEVELOPMENT
545
546 void ShaderResourceCacheD3D11::BindResources(DeviceContextD3D11Impl& Ctx, const TBindingsPerStage& BaseBindings, TMinMaxSlotPerStage& MinMaxSlot, TCommittedResources& CommittedRes, SHADER_TYPE ActiveStages) const
547 {
548 const auto CBCount = GetCBCount();
549 if (CBCount != 0)
550 {
551 const auto Range = DESCRIPTOR_RANGE_CBV;
552 ShaderResourceCacheD3D11::CachedCB const* CBs;
553 ID3D11Buffer* const* d3d11CBs;
554 BindPointsD3D11 const* bindPoints;
555 GetConstCBArrays(CBs, d3d11CBs, bindPoints);
556
557 for (Uint32 cb = 0; cb < CBCount; ++cb)
558 {
559 const auto& BindPoints = bindPoints[cb];
560 Uint32 ActiveBits = BindPoints.GetActiveBits() & ActiveStages;
561 VERIFY(ActiveBits != 0, "resource is not initialized");
562 while (ActiveBits != 0)
563 {
564 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
565 ActiveBits &= ~(1u << ShaderInd);
566 VERIFY_EXPR(BindPoints.IsValid(ShaderInd));
567
568 auto* CommittedD3D11CBs = CommittedRes.D3D11CBs[ShaderInd];
569 UINT& MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
570 UINT& MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
571 const UINT Slot = BaseBindings[ShaderInd][Range] + BindPoints[ShaderInd];
572 const bool IsNewCB = CommittedD3D11CBs[Slot] != d3d11CBs[cb];
573 MinSlot = IsNewCB ? std::min(MinSlot, Slot) : MinSlot;
574 MaxSlot = IsNewCB ? Slot : MaxSlot;
575
576 VERIFY_EXPR(!IsNewCB || (Slot >= MinSlot && Slot <= MaxSlot));
577 VERIFY_EXPR(d3d11CBs[cb] != nullptr);
578 CommittedD3D11CBs[Slot] = d3d11CBs[cb];
579 }
580 }
581 }
582
583 const auto SRVCount = GetSRVCount();
584 if (SRVCount != 0)
585 {
586 const auto Range = DESCRIPTOR_RANGE_SRV;
587 ShaderResourceCacheD3D11::CachedResource const* SRVResources;
588 ID3D11ShaderResourceView* const* d3d11SRVs;
589 BindPointsD3D11 const* bindPoints;
590 GetConstSRVArrays(SRVResources, d3d11SRVs, bindPoints);
591
592 for (Uint32 srv = 0; srv < SRVCount; ++srv)
593 {
594 const auto& BindPoints = bindPoints[srv];
595 Uint32 ActiveBits = BindPoints.GetActiveBits() & ActiveStages;
596 VERIFY(ActiveBits != 0, "resource is not initialized");
597 while (ActiveBits != 0)
598 {
599 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
600 ActiveBits &= ~(1u << ShaderInd);
601 VERIFY_EXPR(BindPoints.IsValid(ShaderInd));
602
603 auto* CommittedD3D11SRVs = CommittedRes.D3D11SRVs[ShaderInd];
604 auto* CommittedD3D11SRVRes = CommittedRes.D3D11SRVResources[ShaderInd];
605 UINT& MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
606 UINT& MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
607 const UINT Slot = BaseBindings[ShaderInd][Range] + BindPoints[ShaderInd];
608 const bool IsNewSRV = CommittedD3D11SRVs[Slot] != d3d11SRVs[srv];
609 MinSlot = IsNewSRV ? std::min(MinSlot, Slot) : MinSlot;
610 MaxSlot = IsNewSRV ? Slot : MaxSlot;
611
612 VERIFY_EXPR(!IsNewSRV || (Slot >= MinSlot && Slot <= MaxSlot));
613 VERIFY_EXPR(d3d11SRVs[srv] != nullptr);
614 CommittedD3D11SRVRes[Slot] = SRVResources[srv].pd3d11Resource;
615 CommittedD3D11SRVs[Slot] = d3d11SRVs[srv];
616 }
617 }
618 }
619
620 const auto SamplerCount = GetSamplerCount();
621 if (SamplerCount != 0)
622 {
623 const auto Range = DESCRIPTOR_RANGE_SAMPLER;
624 ShaderResourceCacheD3D11::CachedSampler const* Samplers;
625 ID3D11SamplerState* const* d3d11Samplers;
626 BindPointsD3D11 const* bindPoints;
627 GetConstSamplerArrays(Samplers, d3d11Samplers, bindPoints);
628
629 for (Uint32 sam = 0; sam < SamplerCount; ++sam)
630 {
631 const auto& BindPoints = bindPoints[sam];
632 Uint32 ActiveBits = BindPoints.GetActiveBits() & ActiveStages;
633 VERIFY(ActiveBits != 0, "resource is not initialized");
634 while (ActiveBits != 0)
635 {
636 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
637 ActiveBits &= ~(1u << ShaderInd);
638 VERIFY_EXPR(BindPoints.IsValid(ShaderInd));
639
640 auto* CommittedD3D11Samplers = CommittedRes.D3D11Samplers[ShaderInd];
641 UINT& MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
642 UINT& MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
643 const UINT Slot = BaseBindings[ShaderInd][Range] + BindPoints[ShaderInd];
644 const bool IsNewSam = CommittedD3D11Samplers[Slot] != d3d11Samplers[sam];
645 MinSlot = IsNewSam ? std::min(MinSlot, Slot) : MinSlot;
646 MaxSlot = IsNewSam ? Slot : MaxSlot;
647
648 VERIFY_EXPR(!IsNewSam || (Slot >= MinSlot && Slot <= MaxSlot));
649 VERIFY_EXPR(d3d11Samplers[sam] != nullptr);
650 CommittedD3D11Samplers[Slot] = d3d11Samplers[sam];
651 }
652 }
653 }
654
655 const auto UAVCount = GetUAVCount();
656 if (UAVCount != 0)
657 {
658 const auto Range = DESCRIPTOR_RANGE_UAV;
659 ShaderResourceCacheD3D11::CachedResource const* UAVResources;
660 ID3D11UnorderedAccessView* const* d3d11UAVs;
661 BindPointsD3D11 const* bindPoints;
662 GetConstUAVArrays(UAVResources, d3d11UAVs, bindPoints);
663
664 for (Uint32 uav = 0; uav < UAVCount; ++uav)
665 {
666 const auto& BindPoints = bindPoints[uav];
667 Uint32 ActiveBits = BindPoints.GetActiveBits() & ActiveStages;
668 VERIFY(ActiveBits != 0, "resource is not initialized");
669 while (ActiveBits != 0)
670 {
671 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
672 ActiveBits &= ~(1u << ShaderInd);
673 VERIFY_EXPR(BindPoints.IsValid(ShaderInd));
674
675 auto* CommittedD3D11UAVs = CommittedRes.D3D11UAVs[ShaderInd];
676 auto* CommittedD3D11UAVRes = CommittedRes.D3D11UAVResources[ShaderInd];
677 UINT& MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
678 UINT& MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
679 const UINT Slot = BaseBindings[ShaderInd][Range] + BindPoints[ShaderInd];
680 const bool IsNewUAV = CommittedD3D11UAVs[Slot] != d3d11UAVs[uav];
681 MinSlot = IsNewUAV ? std::min(MinSlot, Slot) : MinSlot;
682 MaxSlot = IsNewUAV ? Slot : MaxSlot;
683
684 VERIFY_EXPR(!IsNewUAV || (Slot >= MinSlot && Slot <= MaxSlot));
685 VERIFY_EXPR(d3d11UAVs[uav] != nullptr);
686 CommittedD3D11UAVRes[Slot] = UAVResources[uav].pd3d11Resource;
687 CommittedD3D11UAVs[Slot] = d3d11UAVs[uav];
688 }
689 }
690 }
691 }
692
693 void ShaderResourceCacheD3D11::TCommittedResources::Clear()
694 {
695 for (int ShaderType = 0; ShaderType < NumShaderTypes; ++ShaderType)
696 {
697 // clang-format off
698 memset(D3D11CBs[ShaderType], 0, sizeof(D3D11CBs[ShaderType][0]) * NumCBs[ShaderType]);
699 memset(D3D11SRVs[ShaderType], 0, sizeof(D3D11SRVs[ShaderType][0]) * NumSRVs[ShaderType]);
700 memset(D3D11Samplers[ShaderType], 0, sizeof(D3D11Samplers[ShaderType][0]) * NumSamplers[ShaderType]);
701 memset(D3D11UAVs[ShaderType], 0, sizeof(D3D11UAVs[ShaderType][0]) * NumUAVs[ShaderType]);
702 memset(D3D11SRVResources[ShaderType], 0, sizeof(D3D11SRVResources[ShaderType][0]) * NumSRVs[ShaderType]);
703 memset(D3D11UAVResources[ShaderType], 0, sizeof(D3D11UAVResources[ShaderType][0]) * NumUAVs[ShaderType]);
704 // clang-format on
705
706 NumCBs[ShaderType] = 0;
707 NumSRVs[ShaderType] = 0;
708 NumSamplers[ShaderType] = 0;
709 NumUAVs[ShaderType] = 0;
456 {
457 if (Mode == StateTransitionMode::Transition)
458 {
459 Ctx.TransitionResource(pBuffer, RESOURCE_STATE_UNORDERED_ACCESS);
460 }
461 else
462 {
463 LOG_ERROR_MESSAGE("Buffer '", pBuffer->GetDesc().Name,
464 "' has not been transitioned to Unordered Access state. Call TransitionShaderResources(), use "
465 "RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the buffer to required state.");
466 }
467 }
468 }
710469 }
711470 }
712471
2626
2727 #include "pch.h"
2828
29 #include "ShaderResourcesD3D11.hpp"
30
2931 #include <d3dcompiler.h>
30 #include "ShaderResourcesD3D11.hpp"
31 #include "ShaderBase.hpp"
32 #include "ShaderResourceCacheD3D11.hpp"
32
3333 #include "RenderDeviceD3D11Impl.hpp"
3434
3535 namespace Diligent
3636 {
37
3837
3938 ShaderResourcesD3D11::ShaderResourcesD3D11(RenderDeviceD3D11Impl* pDeviceD3D11Impl,
4039 ID3DBlob* pShaderBytecode,
126125 {
127126 }
128127
129
130 #ifdef DILIGENT_DEVELOPMENT
131 static String DbgMakeResourceName(const D3DShaderResourceAttribs& Attr, Uint32 BindPoint)
132 {
133 VERIFY(BindPoint >= Uint32{Attr.BindPoint} && BindPoint < Uint32{Attr.BindPoint} + Attr.BindCount, "Bind point is out of allowed range");
134 if (Attr.BindCount == 1)
135 return Attr.Name;
136 else
137 return String(Attr.Name) + '[' + std::to_string(BindPoint - Attr.BindPoint) + ']';
138 }
139
140 void ShaderResourcesD3D11::dvpVerifyCommittedResources(ID3D11Buffer* CommittedD3D11CBs[],
141 ID3D11ShaderResourceView* CommittedD3D11SRVs[],
142 ID3D11Resource* CommittedD3D11SRVResources[],
143 ID3D11SamplerState* CommittedD3D11Samplers[],
144 ID3D11UnorderedAccessView* CommittedD3D11UAVs[],
145 ID3D11Resource* CommittedD3D11UAVResources[],
146 ShaderResourceCacheD3D11& ResourceCache) const
147 {
148 ShaderResourceCacheD3D11::CachedCB* CachedCBs = nullptr;
149 ID3D11Buffer** d3d11CBs = nullptr;
150 ShaderResourceCacheD3D11::CachedResource* CachedSRVResources = nullptr;
151 ID3D11ShaderResourceView** d3d11SRVs = nullptr;
152 ShaderResourceCacheD3D11::CachedSampler* CachedSamplers = nullptr;
153 ID3D11SamplerState** d3d11Samplers = nullptr;
154 ShaderResourceCacheD3D11::CachedResource* CachedUAVResources = nullptr;
155 ID3D11UnorderedAccessView** d3d11UAVs = nullptr;
156 BindPointsD3D11* BindPoints = nullptr;
157 // clang-format off
158 ResourceCache.GetCBArrays (CachedCBs, d3d11CBs, BindPoints);
159 ResourceCache.GetSRVArrays (CachedSRVResources, d3d11SRVs, BindPoints);
160 ResourceCache.GetSamplerArrays(CachedSamplers, d3d11Samplers, BindPoints);
161 ResourceCache.GetUAVArrays (CachedUAVResources, d3d11UAVs, BindPoints);
162 // clang-format on
163
164 ProcessResources(
165 [&](const D3DShaderResourceAttribs& cb, Uint32) //
166 {
167 for (auto BindPoint = cb.BindPoint; BindPoint < cb.BindPoint + cb.BindCount; ++BindPoint)
168 {
169 if (BindPoint >= ResourceCache.GetCBCount())
170 {
171 LOG_ERROR_MESSAGE("Unable to find constant buffer '", DbgMakeResourceName(cb, BindPoint), "' (slot ",
172 BindPoint, ") in the resource cache: the cache reserves ", ResourceCache.GetCBCount(),
173 " CB slots only. This should never happen and may be the result of using wrong resource cache.");
174 continue;
175 }
176 auto& CB = CachedCBs[BindPoint];
177 if (CB.pBuff == nullptr)
178 {
179 LOG_ERROR_MESSAGE("Constant buffer '", DbgMakeResourceName(cb, BindPoint), "' (slot ",
180 BindPoint, ") is not initialized in the resource cache.");
181 continue;
182 }
183
184 if (!(CB.pBuff->GetDesc().BindFlags & BIND_UNIFORM_BUFFER))
185 {
186 LOG_ERROR_MESSAGE("Buffer '", CB.pBuff->GetDesc().Name,
187 "' committed in the device context as constant buffer to variable '",
188 DbgMakeResourceName(cb, BindPoint), "' (slot ", BindPoint,
189 ") in shader '", GetShaderName(), "' was not created with BIND_UNIFORM_BUFFER flag");
190 continue;
191 }
192
193 VERIFY_EXPR(d3d11CBs[BindPoint] == CB.pBuff->GetD3D11Buffer());
194
195 if (CommittedD3D11CBs[BindPoint] == nullptr)
196 {
197 LOG_ERROR_MESSAGE("No D3D11 resource committed to constant buffer '", DbgMakeResourceName(cb, BindPoint),
198 "' (slot ", BindPoint, ") in shader '", GetShaderName(), "'");
199 continue;
200 }
201
202 if (CommittedD3D11CBs[BindPoint] != d3d11CBs[BindPoint])
203 {
204 LOG_ERROR_MESSAGE("D3D11 resource committed to constant buffer '", DbgMakeResourceName(cb, BindPoint),
205 "' (slot ", BindPoint, ") in shader '", GetShaderName(), "' does not match the resource in the resource cache");
206 continue;
207 }
208 }
209 },
210
211 [&](const D3DShaderResourceAttribs& sam, Uint32) //
212 {
213 for (auto BindPoint = sam.BindPoint; BindPoint < sam.BindPoint + sam.BindCount; ++BindPoint)
214 {
215 if (BindPoint >= ResourceCache.GetSamplerCount())
216 {
217 LOG_ERROR_MESSAGE("Unable to find sampler '", DbgMakeResourceName(sam, BindPoint), "' (slot ", BindPoint,
218 ") in the resource cache: the cache reserves ", ResourceCache.GetSamplerCount(),
219 " Sampler slots only. This should never happen and may be the result of using wrong resource cache.");
220 continue;
221 }
222 auto& Sam = CachedSamplers[BindPoint];
223 if (Sam.pSampler == nullptr)
224 {
225 LOG_ERROR_MESSAGE("Sampler '", DbgMakeResourceName(sam, BindPoint), "' (slot ", BindPoint,
226 ") is not initialized in the resource cache.");
227 continue;
228 }
229 VERIFY_EXPR(d3d11Samplers[BindPoint] == Sam.pSampler->GetD3D11SamplerState());
230
231 if (CommittedD3D11Samplers[BindPoint] == nullptr)
232 {
233 LOG_ERROR_MESSAGE("No D3D11 sampler committed to variable '", DbgMakeResourceName(sam, BindPoint),
234 "' (slot ", BindPoint, ") in shader '", GetShaderName(), "'");
235 continue;
236 }
237
238 if (CommittedD3D11Samplers[BindPoint] != d3d11Samplers[BindPoint])
239 {
240 LOG_ERROR_MESSAGE("D3D11 sampler committed to variable '", DbgMakeResourceName(sam, BindPoint),
241 "' (slot ", BindPoint, ") in shader '", GetShaderName(), "' does not match the resource in the resource cache");
242 continue;
243 }
244 }
245 },
246
247 [&](const D3DShaderResourceAttribs& tex, Uint32) //
248 {
249 for (auto BindPoint = tex.BindPoint; BindPoint < tex.BindPoint + tex.BindCount; ++BindPoint)
250 {
251 if (BindPoint >= ResourceCache.GetSRVCount())
252 {
253 LOG_ERROR_MESSAGE("Unable to find texture SRV '", DbgMakeResourceName(tex, BindPoint), "' (slot ",
254 BindPoint, ") in the resource cache: the cache reserves ", ResourceCache.GetSRVCount(),
255 " SRV slots only. This should never happen and may be the result of using wrong resource cache.");
256 continue;
257 }
258 auto& SRVRes = CachedSRVResources[BindPoint];
259 if (SRVRes.pBuffer != nullptr)
260 {
261 LOG_ERROR_MESSAGE("Unexpected buffer bound to variable '", DbgMakeResourceName(tex, BindPoint), "' (slot ",
262 BindPoint, "). Texture is expected.");
263 continue;
264 }
265 if (SRVRes.pTexture == nullptr)
266 {
267 LOG_ERROR_MESSAGE("Texture '", DbgMakeResourceName(tex, BindPoint), "' (slot ", BindPoint,
268 ") is not initialized in the resource cache.");
269 continue;
270 }
271
272 if (!(SRVRes.pTexture->GetDesc().BindFlags & BIND_SHADER_RESOURCE))
273 {
274 LOG_ERROR_MESSAGE("Texture '", SRVRes.pTexture->GetDesc().Name,
275 "' committed in the device context as SRV to variable '", DbgMakeResourceName(tex, BindPoint),
276 "' (slot ", BindPoint, ") in shader '", GetShaderName(), "' was not created with BIND_SHADER_RESOURCE flag");
277 }
278
279 if (CommittedD3D11SRVs[BindPoint] == nullptr)
280 {
281 LOG_ERROR_MESSAGE("No D3D11 resource committed to texture SRV '", DbgMakeResourceName(tex, BindPoint),
282 "' (slot ", BindPoint, ") in shader '", GetShaderName(), "'");
283 continue;
284 }
285
286 if (CommittedD3D11SRVs[BindPoint] != d3d11SRVs[BindPoint])
287 {
288 LOG_ERROR_MESSAGE("D3D11 resource committed to texture SRV '", DbgMakeResourceName(tex, BindPoint),
289 "' (slot ", BindPoint, ") in shader '", GetShaderName(),
290 "' does not match the resource in the resource cache");
291 continue;
292 }
293 }
294
295 if (tex.IsCombinedWithSampler())
296 {
297 const auto& SamAttribs = GetCombinedSampler(tex);
298 VERIFY_EXPR(SamAttribs.IsValidBindPoint());
299 VERIFY_EXPR(SamAttribs.BindCount == 1 || SamAttribs.BindCount == tex.BindCount);
300 }
301 },
302
303 [&](const D3DShaderResourceAttribs& uav, Uint32) //
304 {
305 for (auto BindPoint = uav.BindPoint; BindPoint < uav.BindPoint + uav.BindCount; ++BindPoint)
306 {
307 if (BindPoint >= ResourceCache.GetUAVCount())
308 {
309 LOG_ERROR_MESSAGE("Unable to find texture UAV '", DbgMakeResourceName(uav, BindPoint), "' (slot ",
310 BindPoint, ") in the resource cache: the cache reserves ", ResourceCache.GetUAVCount(),
311 " UAV slots only. This should never happen and may be the result of using wrong resource cache.");
312 continue;
313 }
314 auto& UAVRes = CachedUAVResources[BindPoint];
315 if (UAVRes.pBuffer != nullptr)
316 {
317 LOG_ERROR_MESSAGE("Unexpected buffer bound to variable '", DbgMakeResourceName(uav, BindPoint),
318 "' (slot ", BindPoint, "). Texture is expected.");
319 continue;
320 }
321 if (UAVRes.pTexture == nullptr)
322 {
323 LOG_ERROR_MESSAGE("Texture '", DbgMakeResourceName(uav, BindPoint), "' (slot ", BindPoint,
324 ") is not initialized in the resource cache.");
325 continue;
326 }
327
328 if (!(UAVRes.pTexture->GetDesc().BindFlags & BIND_UNORDERED_ACCESS))
329 {
330 LOG_ERROR_MESSAGE("Texture '", UAVRes.pTexture->GetDesc().Name,
331 "' committed in the device context as UAV to variable '", DbgMakeResourceName(uav, BindPoint), "' (slot ", BindPoint, ") in shader '", GetShaderName(), "' was not created with BIND_UNORDERED_ACCESS flag");
332 }
333
334 if (CommittedD3D11UAVs[BindPoint] == nullptr)
335 {
336 LOG_ERROR_MESSAGE("No D3D11 resource committed to texture UAV '", DbgMakeResourceName(uav, BindPoint),
337 "' (slot ", BindPoint, ") in shader '", GetShaderName(), "'");
338 continue;
339 }
340
341 if (CommittedD3D11UAVs[BindPoint] != d3d11UAVs[BindPoint])
342 {
343 LOG_ERROR_MESSAGE("D3D11 resource committed to texture UAV '", DbgMakeResourceName(uav, BindPoint),
344 "' (slot ", BindPoint, ") in shader '", GetShaderName(), "' does not match the resource in the resource cache");
345 continue;
346 }
347 }
348 },
349
350
351 [&](const D3DShaderResourceAttribs& buf, Uint32) //
352 {
353 for (auto BindPoint = buf.BindPoint; BindPoint < buf.BindPoint + buf.BindCount; ++BindPoint)
354 {
355 if (BindPoint >= ResourceCache.GetSRVCount())
356 {
357 LOG_ERROR_MESSAGE("Unable to find buffer SRV '", DbgMakeResourceName(buf, BindPoint), "' (slot ", BindPoint,
358 ") in the resource cache: the cache reserves ", ResourceCache.GetSRVCount(),
359 " SRV slots only. This should never happen and may be the result of using wrong resource cache.");
360 continue;
361 }
362 auto& SRVRes = CachedSRVResources[BindPoint];
363 if (SRVRes.pTexture != nullptr)
364 {
365 LOG_ERROR_MESSAGE("Unexpected texture bound to variable '", DbgMakeResourceName(buf, BindPoint),
366 "' (slot ", BindPoint, "). Buffer is expected.");
367 continue;
368 }
369 if (SRVRes.pBuffer == nullptr)
370 {
371 LOG_ERROR_MESSAGE("Buffer '", DbgMakeResourceName(buf, BindPoint), "' (slot ", BindPoint,
372 ") is not initialized in the resource cache.");
373 continue;
374 }
375
376 if (!(SRVRes.pBuffer->GetDesc().BindFlags & BIND_SHADER_RESOURCE))
377 {
378 LOG_ERROR_MESSAGE("Buffer '", SRVRes.pBuffer->GetDesc().Name,
379 "' committed in the device context as SRV to variable '", DbgMakeResourceName(buf, BindPoint),
380 "' (slot ", BindPoint, ") in shader '", GetShaderName(),
381 "' was not created with BIND_SHADER_RESOURCE flag");
382 }
383
384 if (CommittedD3D11SRVs[BindPoint] == nullptr)
385 {
386 LOG_ERROR_MESSAGE("No D3D11 resource committed to buffer SRV '", DbgMakeResourceName(buf, BindPoint),
387 "' (slot ", BindPoint, ") in shader '", GetShaderName(), "'");
388 continue;
389 }
390
391 if (CommittedD3D11SRVs[BindPoint] != d3d11SRVs[BindPoint])
392 {
393 LOG_ERROR_MESSAGE("D3D11 resource committed to buffer SRV '", DbgMakeResourceName(buf, BindPoint),
394 "' (slot ", BindPoint, ") in shader '", GetShaderName(),
395 "' does not match the resource in the resource cache");
396 continue;
397 }
398 }
399 },
400
401 [&](const D3DShaderResourceAttribs& uav, Uint32) //
402 {
403 for (auto BindPoint = uav.BindPoint; BindPoint < uav.BindPoint + uav.BindCount; ++BindPoint)
404 {
405 if (BindPoint >= ResourceCache.GetUAVCount())
406 {
407 LOG_ERROR_MESSAGE("Unable to find buffer UAV '", DbgMakeResourceName(uav, BindPoint), "' (slot ", BindPoint,
408 ") in the resource cache: the cache reserves ", ResourceCache.GetUAVCount(),
409 " UAV slots only. This should never happen and may be the result of using wrong resource cache.");
410 continue;
411 }
412 auto& UAVRes = CachedUAVResources[BindPoint];
413 if (UAVRes.pTexture != nullptr)
414 {
415 LOG_ERROR_MESSAGE("Unexpected texture bound to variable '", DbgMakeResourceName(uav, BindPoint),
416 "' (slot ", BindPoint, "). Buffer is expected.");
417 return;
418 }
419 if (UAVRes.pBuffer == nullptr)
420 {
421 LOG_ERROR_MESSAGE("Buffer UAV '", DbgMakeResourceName(uav, BindPoint), "' (slot ", BindPoint,
422 ") is not initialized in the resource cache.");
423 return;
424 }
425
426 if (!(UAVRes.pBuffer->GetDesc().BindFlags & BIND_UNORDERED_ACCESS))
427 {
428 LOG_ERROR_MESSAGE("Buffer '", UAVRes.pBuffer->GetDesc().Name,
429 "' committed in the device context as UAV to variable '", DbgMakeResourceName(uav, BindPoint), "' (slot ", BindPoint, ") in shader '", GetShaderName(), "' was not created with BIND_UNORDERED_ACCESS flag");
430 }
431
432 if (CommittedD3D11UAVs[BindPoint] == nullptr)
433 {
434 LOG_ERROR_MESSAGE("No D3D11 resource committed to buffer UAV '", DbgMakeResourceName(uav, BindPoint),
435 "' (slot ", BindPoint, ") in shader '", GetShaderName(), "'");
436 return;
437 }
438
439 if (CommittedD3D11UAVs[BindPoint] != d3d11UAVs[BindPoint])
440 {
441 LOG_ERROR_MESSAGE("D3D11 resource committed to buffer UAV '", DbgMakeResourceName(uav, BindPoint),
442 "' (slot ", BindPoint, ") in shader '", GetShaderName(),
443 "' does not match the resource in the resource cache");
444 return;
445 }
446 }
447 },
448
449 [&](const D3DShaderResourceAttribs&, Uint32) //
450 {
451 UNEXPECTED("Acceleration structure is not supported in DirectX 11");
452 } // clang-format off
453 ); // clang-format on
454 }
455 #endif
456
457128 } // namespace Diligent
4949
5050 // clang-format off
5151 const Uint32 CacheOffset; // SRB and Signature use the same cache offsets for static resources.
52 // Binding == BaseBinding[Range] + CacheOffset
52 // (thanks to sorting variables by type, where all static vars go first).
53 // Binding == BaseBinding[Range] + CacheOffset
5354 const Uint32 SamplerInd : _SamplerIndBits; // ImtblSamplerAssigned == true: index of the immutable sampler in m_ImmutableSamplers.
54 // ImtblSamplerAssigned == false: index of the assigned sampler in m_Desc.Resources.
55 // ImtblSamplerAssigned == false: index of the assigned sampler in m_Desc.Resources.
5556 const Uint32 ImtblSamplerAssigned : _SamplerAssignedBits; // Immutable sampler flag
5657 // clang-format on
5758