git.s-ol.nu ~forks/DiligentCore / 9411711
Direct3D11: added resource signature azhirnov authored 6 months ago assiduous committed 6 months ago
38 changed file(s) with 4277 addition(s) and 3409 deletion(s). Raw diff Collapse all Expand all
245245 /// resets render targets if it is.
246246 bool UnbindTextureFromFramebuffer(TextureImplType* pTexture, bool bShowMessage);
247247
248 bool HasActiveRenderPass() const { return m_pActiveRenderPass != nullptr; }
249
248250 protected:
249251 /// Caches the render target and depth stencil views. Returns true if any view is different
250252 /// from the cached value and false otherwise.
460460 return true;
461461 }
462462
463 SHADER_TYPE GetActiveShaderStages() const
464 {
465 return m_ActiveShaderStages;
466 }
467
463468 protected:
464469 using TNameToGroupIndexMap = std::unordered_map<HashMapStringKey, Uint32, HashMapStringKey::Hasher>;
465470
1515 include/FenceD3D11Impl.hpp
1616 include/FramebufferD3D11Impl.hpp
1717 include/PipelineStateD3D11Impl.hpp
18 include/PipelineResourceAttribsD3D11.hpp
19 include/PipelineResourceSignatureD3D11Impl.hpp
1820 include/QueryD3D11Impl.hpp
1921 include/RenderDeviceD3D11Impl.hpp
2022 include/RenderPassD3D11Impl.hpp
2224 include/ShaderD3D11Impl.hpp
2325 include/ShaderResourceBindingD3D11Impl.hpp
2426 include/ShaderResourceCacheD3D11.hpp
25 include/ShaderResourceLayoutD3D11.hpp
27 include/ShaderVariableManagerD3D11.hpp
2628 include/ShaderResourcesD3D11.hpp
2729 include/SwapChainD3D11Impl.hpp
2830 include/targetver.h
6264 src/FramebufferD3D11Impl.cpp
6365 src/GUIDDef.cpp
6466 src/PipelineStateD3D11Impl.cpp
67 src/PipelineResourceSignatureD3D11Impl.cpp
6568 src/QueryD3D11Impl.cpp
6669 src/RenderDeviceD3D11Impl.cpp
6770 src/RenderPassD3D11Impl.cpp
6972 src/ShaderD3D11Impl.cpp
7073 src/ShaderResourceBindingD3D11Impl.cpp
7174 src/ShaderResourceCacheD3D11.cpp
72 src/ShaderResourceLayoutD3D11.cpp
75 src/ShaderVariableManagerD3D11.cpp
7376 src/ShaderResourcesD3D11.cpp
7477 src/SwapChainD3D11Impl.cpp
7578 src/Texture1D_D3D11.cpp
3838 namespace Diligent
3939 {
4040
41 class FixedBlockMemoryAllocator;
42
4341 /// Buffer object implementation in Direct3D11 backend.
44 class BufferD3D11Impl final : public BufferBase<IBufferD3D11, RenderDeviceD3D11Impl, BufferViewD3D11Impl, FixedBlockMemoryAllocator>
42 class BufferD3D11Impl final : public BufferBase<EngineD3D11ImplTraits>
4543 {
4644 public:
47 using TBufferBase = BufferBase<IBufferD3D11, RenderDeviceD3D11Impl, BufferViewD3D11Impl, FixedBlockMemoryAllocator>;
45 using TBufferBase = BufferBase<EngineD3D11ImplTraits>;
4846
4947 BufferD3D11Impl(IReferenceCounters* pRefCounters,
5048 FixedBlockMemoryAllocator& BuffViewObjMemAllocator,
4040 class FixedBlockMemoryAllocator;
4141
4242 /// Buffer view implementation in Direct3D11 backend.
43 class BufferViewD3D11Impl final : public BufferViewBase<IBufferViewD3D11, RenderDeviceD3D11Impl>
43 class BufferViewD3D11Impl final : public BufferViewBase<EngineD3D11ImplTraits>
4444 {
4545 public:
46 using TBufferViewBase = BufferViewBase<IBufferViewD3D11, RenderDeviceD3D11Impl>;
46 using TBufferViewBase = BufferViewBase<EngineD3D11ImplTraits>;
4747
4848 BufferViewD3D11Impl(IReferenceCounters* pRefCounters,
4949 RenderDeviceD3D11Impl* pDevice,
5050 const BufferViewDesc& ViewDesc,
51 IBuffer* pBuffer,
51 BufferD3D11Impl* pBuffer,
5252 ID3D11View* pD3D11View,
5353 bool bIsDefaultView);
5454
4242 #include "DisjointQueryPool.hpp"
4343 #include "BottomLevelASBase.hpp"
4444 #include "TopLevelASBase.hpp"
45
46 #ifdef DILIGENT_DEBUG
45 #include "ShaderResourceBindingD3D11Impl.hpp"
46
47 #ifdef DILIGENT_DEVELOPMENT
4748 # define VERIFY_CONTEXT_BINDINGS
4849 #endif
4950
5051 namespace Diligent
5152 {
5253
53 struct DeviceContextD3D11ImplTraits
54 {
55 using BufferType = BufferD3D11Impl;
56 using TextureType = TextureBaseD3D11;
57 using PipelineStateType = PipelineStateD3D11Impl;
58 using DeviceType = RenderDeviceD3D11Impl;
59 using QueryType = QueryD3D11Impl;
60 using FramebufferType = FramebufferD3D11Impl;
61 using RenderPassType = RenderPassD3D11Impl;
62 using BottomLevelASType = BottomLevelASBase<IBottomLevelAS, RenderDeviceD3D11Impl>;
63 using TopLevelASType = TopLevelASBase<ITopLevelAS, BottomLevelASType, RenderDeviceD3D11Impl>;
64 };
65
6654 /// Device context implementation in Direct3D11 backend.
67 class DeviceContextD3D11Impl final : public DeviceContextBase<IDeviceContextD3D11, DeviceContextD3D11ImplTraits>
55 class DeviceContextD3D11Impl final : public DeviceContextBase<EngineD3D11ImplTraits>
6856 {
6957 public:
70 using TDeviceContextBase = DeviceContextBase<IDeviceContextD3D11, DeviceContextD3D11ImplTraits>;
58 using TDeviceContextBase = DeviceContextBase<EngineD3D11ImplTraits>;
7159
7260 DeviceContextD3D11Impl(IReferenceCounters* pRefCounters,
7361 IMemoryAllocator& Allocator,
287275 /// Unbinds all render targets. Used when resizing the swap chain.
288276 virtual void ResetRenderTargets() override final;
289277
290 /// Number of different shader types (Vertex, Pixel, Geometry, Domain, Hull, Compute)
291 static constexpr int NumShaderTypes = 6;
278 void TransitionResource(TextureBaseD3D11* pTexture, RESOURCE_STATE NewState, RESOURCE_STATE OldState = RESOURCE_STATE_UNKNOWN, bool UpdateResourceState = true);
279 void TransitionResource(BufferD3D11Impl* pBuffer, RESOURCE_STATE NewState, RESOURCE_STATE OldState = RESOURCE_STATE_UNKNOWN, bool UpdateResourceState = true);
292280
293281 private:
294282 /// Commits d3d11 index buffer to d3d11 device context.
340328 /// Ends current subpass
341329 void EndSubpass();
342330
343 template <bool TransitionResources,
344 bool CommitResources>
345 void TransitionAndCommitShaderResources(IPipelineState* pPSO, IShaderResourceBinding* pShaderResourceBinding, bool VerifyStates);
346
347331 void ClearStateCache();
348332
333 void BindShaderResources();
334
335 using TBindingsPerStage = PipelineResourceSignatureD3D11Impl::TBindingsPerStage;
336 using TCommittedResources = ShaderResourceCacheD3D11::TCommittedResources;
337 using TMinMaxSlotPerStage = ShaderResourceCacheD3D11::TMinMaxSlotPerStage;
338
339 static constexpr auto NumShaderTypes = PipelineResourceSignatureD3D11Impl::NumShaderTypes;
340
341 #ifdef DILIGENT_DEVELOPMENT
342 void DvpValidateCommittedShaderResources();
343 #endif
344
349345 std::shared_ptr<DisjointQueryPool::DisjointQueryWrapper> BeginDisjointQuery();
350346
351347 CComPtr<ID3D11DeviceContext> m_pd3d11DeviceContext; ///< D3D11 device context
352348
353 // clang-format off
354
355 /// An array of D3D11 constant buffers 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 ID3D11Buffer* m_CommittedD3D11CBs [NumShaderTypes][D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {};
359
360 /// An array of D3D11 shader resource views committed 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 ID3D11ShaderResourceView* m_CommittedD3D11SRVs [NumShaderTypes][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {};
364
365 /// An array of D3D11 samplers committed 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 ID3D11SamplerState* m_CommittedD3D11Samplers[NumShaderTypes][D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {};
369
370 /// An array of D3D11 UAVs committed to D3D11 device context,
371 /// for each shader type. The context addref's all bound resources, so we do
372 /// not need to keep strong references.
373 ID3D11UnorderedAccessView* m_CommittedD3D11UAVs [NumShaderTypes][D3D11_PS_CS_UAV_REGISTER_COUNT] = {};
374
375 /// An array of D3D11 resources commited as SRV to D3D11 device context,
376 /// for each shader type. The context addref's all bound resources, so we do
377 /// not need to keep strong references.
378 ID3D11Resource* m_CommittedD3D11SRVResources [NumShaderTypes][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {};
379
380 /// An array of D3D11 resources commited as UAV to D3D11 device context,
381 /// for each shader type. The context addref's all bound resources, so we do
382 /// not need to keep strong references.
383 ID3D11Resource* m_CommittedD3D11UAVResources [NumShaderTypes][D3D11_PS_CS_UAV_REGISTER_COUNT] = {};
384
385 Uint8 m_NumCommittedCBs [NumShaderTypes] = {};
386 Uint8 m_NumCommittedSRVs [NumShaderTypes] = {};
387 Uint8 m_NumCommittedSamplers[NumShaderTypes] = {};
388 Uint8 m_NumCommittedUAVs [NumShaderTypes] = {};
389
390 // clang-format on
349 struct SRBState
350 {
351 // Do not use strong references!
352 std::array<ShaderResourceBindingD3D11Impl*, MAX_RESOURCE_SIGNATURES> SRBs = {};
353
354 using Bitfield = Uint8;
355 static_assert(sizeof(Bitfield) * 8 >= MAX_RESOURCE_SIGNATURES, "not enought space to store MAX_RESOURCE_SIGNATURES bits");
356
357 Bitfield ActiveSRBMask = 0; // Indicates which SRBs are active in current PSO
358 Bitfield StaleSRBMask = 0; // Indicates stale SRBs that have descriptor sets that need to be bound
359
360 SHADER_TYPE ActiveStages = SHADER_TYPE_UNKNOWN;
361
362 #ifdef DILIGENT_DEVELOPMENT
363 bool CommittedResourcesValidated = false;
364
365 // Binding offsets that was used at last BindProgramResources() call.
366 std::array<TBindingsPerStage, MAX_RESOURCE_SIGNATURES> BoundResOffsets = {};
367 #endif
368
369 SRBState()
370 {}
371
372 void SetStaleSRBBit(Uint32 Index) { StaleSRBMask |= static_cast<Bitfield>(1u << Index); }
373 void ClearStaleSRBBit(Uint32 Index) { StaleSRBMask &= static_cast<Bitfield>(~(1u << Index)); }
374
375 } m_BindInfo;
376
377 TCommittedResources m_CommittedRes;
391378
392379 /// An array of D3D11 vertex buffers committed to D3D device context.
393380 /// There is no need to keep strong references because D3D11 device context
437424
438425 /// Helper template function used to facilitate context verification
439426 template <UINT MaxResources, typename TD3D11ResourceType, typename TGetD3D11ResourcesType>
440 void dbgVerifyCommittedResources(TD3D11ResourceType CommittedD3D11ResourcesArr[][MaxResources],
427 void DvpVerifyCommittedResources(TD3D11ResourceType CommittedD3D11ResourcesArr[][MaxResources],
441428 Uint8 NumCommittedResourcesArr[],
442429 TGetD3D11ResourcesType GetD3D11ResMethods[],
443430 const Char* ResourceName,
444 SHADER_TYPE ShaderType);
431 SHADER_TYPE ShaderStages);
445432
446433 /// Helper template function used to facilitate validation of SRV and UAV consistency with D3D11 resources
447434 template <UINT MaxResources, typename TD3D11ViewType>
448 void dbgVerifyViewConsistency(TD3D11ViewType CommittedD3D11ViewArr[][MaxResources],
435 void DvpVerifyViewConsistency(TD3D11ViewType CommittedD3D11ViewArr[][MaxResources],
449436 ID3D11Resource* CommittedD3D11ResourcesArr[][MaxResources],
450437 Uint8 NumCommittedResourcesArr[],
451438 const Char* ResourceName,
452 SHADER_TYPE ShaderType);
439 SHADER_TYPE ShaderStages);
453440
454441 /// Debug function that verifies that SRVs cached in m_CommittedD3D11SRVs
455442 /// array comply with resources actually committed to D3D11 device context
456 void dbgVerifyCommittedSRVs(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN);
443 void DvpVerifyCommittedSRVs(SHADER_TYPE ShaderStages);
457444
458445 /// Debug function that verifies that UAVs cached in m_CommittedD3D11UAVs
459446 /// array comply with resources actually committed to D3D11 device context
460 void dbgVerifyCommittedUAVs(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN);
447 void DvpVerifyCommittedUAVs(SHADER_TYPE ShaderStages);
461448
462449 /// Debug function that verifies that samplers cached in m_CommittedD3D11Samplers
463450 /// array comply with resources actually committed to D3D11 device context
464 void dbgVerifyCommittedSamplers(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN);
451 void DvpVerifyCommittedSamplers(SHADER_TYPE ShaderStages);
465452
466453 /// Debug function that verifies that constant buffers cached in m_CommittedD3D11CBs
467454 /// array comply with buffers actually committed to D3D11 device context
468 void dbgVerifyCommittedCBs(SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN);
455 void DvpVerifyCommittedCBs(SHADER_TYPE ShaderStages);
469456
470457 /// Debug function that verifies that index buffer cached in
471458 /// m_CommittedD3D11IndexBuffer is the buffer actually committed to D3D11
472459 /// device context
473 void dbgVerifyCommittedIndexBuffer();
460 void DvpVerifyCommittedIndexBuffer();
474461
475462 /// Debug function that verifies that vertex buffers cached in
476463 /// m_CommittedD3D11VertexBuffers are the buffers actually committed to D3D11
477464 /// device context
478 void dbgVerifyCommittedVertexBuffers();
465 void DvpVerifyCommittedVertexBuffers();
479466
480467 /// Debug function that verifies that shaders cached in
481468 /// m_CommittedD3DShaders are the shaders actually committed to D3D11
482469 /// device context
483 void dbgVerifyCommittedShaders();
484
485 #else
486 # define dbgVerifyRenderTargetFormats(...)
487 # define dbgVerifyCommittedSRVs(...)
488 # define dbgVerifyCommittedUAVs(...)
489 # define dbgVerifyCommittedSamplers(...)
490 # define dbgVerifyCommittedCBs(...)
491 # define dbgVerifyCommittedIndexBuffer(...)
492 # define dbgVerifyCommittedVertexBuffers(...)
493 # define dbgVerifyCommittedShaders(...)
470 void DvpVerifyCommittedShaders();
471
494472 #endif // VERIFY_CONTEXT_BINDINGS
495473 };
496474
0 /*
1 * Copyright 2019-2021 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #pragma once
28
29 /// \file
30 /// Declaration of Diligent::EngineD3D11ImplTraits struct
31
32 #include "RenderDeviceD3D11.h"
33 #include "PipelineStateD3D11.h"
34 #include "ShaderResourceBindingD3D11.h"
35 #include "BufferD3D11.h"
36 #include "BufferViewD3D11.h"
37 #include "TextureD3D11.h"
38 #include "TextureViewD3D11.h"
39 #include "ShaderD3D11.h"
40 #include "SamplerD3D11.h"
41 #include "FenceD3D11.h"
42 #include "QueryD3D11.h"
43 #include "RenderPass.h"
44 #include "Framebuffer.h"
45 #include "PipelineResourceSignature.h"
46 #include "DeviceContextD3D11.h"
47
48 namespace Diligent
49 {
50
51 class RenderDeviceD3D11Impl;
52 class DeviceContextD3D11Impl;
53 class PipelineStateD3D11Impl;
54 class ShaderResourceBindingD3D11Impl;
55 class BufferD3D11Impl;
56 class BufferViewD3D11Impl;
57 class TextureBaseD3D11;
58 class TextureViewD3D11Impl;
59 class ShaderD3D11Impl;
60 class SamplerD3D11Impl;
61 class FenceD3D11Impl;
62 class QueryD3D11Impl;
63 class RenderPassD3D11Impl;
64 class FramebufferD3D11Impl;
65 class BottomLevelASD3D11Impl;
66 class TopLevelASD3D11Impl;
67 class ShaderBindingTableD3D11Impl;
68 class PipelineResourceSignatureD3D11Impl;
69
70 class FixedBlockMemoryAllocator;
71
72 class ShaderResourceCacheD3D11;
73 class ShaderVariableManagerD3D11;
74
75 struct EngineD3D11ImplTraits
76 {
77 using RenderDeviceInterface = IRenderDeviceD3D11;
78 using DeviceContextInterface = IDeviceContextD3D11;
79 using PipelineStateInterface = IPipelineStateD3D11;
80 using ShaderResourceBindingInterface = IShaderResourceBindingD3D11;
81 using BufferInterface = IBufferD3D11;
82 using BufferViewInterface = IBufferViewD3D11;
83 using TextureInterface = ITextureD3D11;
84 using TextureViewInterface = ITextureViewD3D11;
85 using ShaderInterface = IShaderD3D11;
86 using SamplerInterface = ISamplerD3D11;
87 using FenceInterface = IFenceD3D11;
88 using QueryInterface = IQueryD3D11;
89 using RenderPassInterface = IRenderPass;
90 using FramebufferInterface = IFramebuffer;
91 using PipelineResourceSignatureInterface = IPipelineResourceSignature;
92
93 using RenderDeviceImplType = RenderDeviceD3D11Impl;
94 using DeviceContextImplType = DeviceContextD3D11Impl;
95 using PipelineStateImplType = PipelineStateD3D11Impl;
96 using ShaderResourceBindingImplType = ShaderResourceBindingD3D11Impl;
97 using BufferImplType = BufferD3D11Impl;
98 using BufferViewImplType = BufferViewD3D11Impl;
99 using TextureImplType = TextureBaseD3D11;
100 using TextureViewImplType = TextureViewD3D11Impl;
101 using ShaderImplType = ShaderD3D11Impl;
102 using SamplerImplType = SamplerD3D11Impl;
103 using FenceImplType = FenceD3D11Impl;
104 using QueryImplType = QueryD3D11Impl;
105 using RenderPassImplType = RenderPassD3D11Impl;
106 using FramebufferImplType = FramebufferD3D11Impl;
107 using BottomLevelASImplType = BottomLevelASD3D11Impl;
108 using TopLevelASImplType = TopLevelASD3D11Impl;
109 using ShaderBindingTableImplType = ShaderBindingTableD3D11Impl;
110 using PipelineResourceSignatureImplType = PipelineResourceSignatureD3D11Impl;
111
112 using BuffViewObjAllocatorType = FixedBlockMemoryAllocator;
113 using TexViewObjAllocatorType = FixedBlockMemoryAllocator;
114
115 using ShaderResourceCacheImplType = ShaderResourceCacheD3D11;
116 using ShaderVariableManagerImplType = ShaderVariableManagerD3D11;
117 };
118
119 } // namespace Diligent
3838 namespace Diligent
3939 {
4040
41 class FixedBlockMemoryAllocator;
42
4341 /// Fence implementation in Direct3D11 backend.
44 class FenceD3D11Impl final : public FenceBase<IFenceD3D11, RenderDeviceD3D11Impl>
42 class FenceD3D11Impl final : public FenceBase<EngineD3D11ImplTraits>
4543 {
4644 public:
47 using TFenceBase = FenceBase<IFenceD3D11, RenderDeviceD3D11Impl>;
45 using TFenceBase = FenceBase<EngineD3D11ImplTraits>;
4846
4947 FenceD3D11Impl(IReferenceCounters* pRefCounters,
5048 RenderDeviceD3D11Impl* pDevice,
3939 class FixedBlockMemoryAllocator;
4040
4141 /// Render pass implementation in Direct3D11 backend.
42 class FramebufferD3D11Impl final : public FramebufferBase<IFramebuffer, RenderDeviceD3D11Impl>
42 class FramebufferD3D11Impl final : public FramebufferBase<EngineD3D11ImplTraits>
4343 {
4444 public:
45 using TFramebufferBase = FramebufferBase<IFramebuffer, RenderDeviceD3D11Impl>;
45 using TFramebufferBase = FramebufferBase<EngineD3D11ImplTraits>;
4646
4747 FramebufferD3D11Impl(IReferenceCounters* pRefCounters,
4848 RenderDeviceD3D11Impl* pDevice,
0 /*
1 * Copyright 2019-2021 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #pragma once
28
29 /// \file
30 /// Declaration of Diligent::PipelineResourceAttribsD3D11 struct
31
32 #include <array>
33
34 #include "BasicTypes.h"
35 #include "DebugUtilities.hpp"
36
37 namespace Diligent
38 {
39
40 enum DESCRIPTOR_RANGE : Uint32
41 {
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
48 };
49 DESCRIPTOR_RANGE ShaderResourceToDescriptorRange(SHADER_RESOURCE_TYPE Type);
50
51 // sizeof(PipelineResourceAttribsD3D11) == 4, x64
52 struct PipelineResourceAttribsD3D11
53 {
54 private:
55 static constexpr Uint32 _CacheOffsetBits = 10;
56 static constexpr Uint32 _SamplerIndBits = 10;
57 static constexpr Uint32 _SamplerAssignedBits = 1;
58
59 public:
60 static constexpr Uint32 InvalidCacheOffset = (1u << _CacheOffsetBits) - 1;
61 static constexpr Uint32 InvalidSamplerInd = (1u << _SamplerIndBits) - 1;
62
63 /// Number of different shader types (Vertex, Pixel, Geometry, Domain, Hull, Compute)
64 static constexpr Uint32 NumShaderTypes = 6;
65
66 using TBindPoints = std::array<Uint8, NumShaderTypes>;
67 static constexpr Uint8 InvalidBindPoint = 0xFF;
68 static constexpr TBindPoints InvalidBindPoints = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
69
70 // clang-format off
71 const Uint32 CacheOffset : _CacheOffsetBits; // SRB and Signature has the same cache offsets for static resources.
72 const Uint32 SamplerInd : _SamplerIndBits; // Index of the assigned sampler in m_Desc.Resources.
73 const Uint32 ImtblSamplerAssigned : _SamplerAssignedBits; // Immutable sampler flag.
74 TBindPoints BindPoints = InvalidBindPoints;
75 // clang-format on
76
77 PipelineResourceAttribsD3D11(Uint32 _CacheOffset,
78 Uint32 _SamplerInd,
79 bool _ImtblSamplerAssigned) noexcept :
80 // clang-format off
81 CacheOffset {_CacheOffset },
82 SamplerInd {_SamplerInd },
83 ImtblSamplerAssigned{_ImtblSamplerAssigned ? 1u : 0u}
84 // clang-format on
85 {
86 VERIFY(CacheOffset == _CacheOffset, "Cache offset (", _CacheOffset, ") exceeds maximum representable value");
87 VERIFY(SamplerInd == _SamplerInd, "Sampler index (", _SamplerInd, ") exceeds maximum representable value");
88 }
89
90 bool IsSamplerAssigned() const { return SamplerInd != InvalidSamplerInd; }
91 bool IsImmutableSamplerAssigned() const { return ImtblSamplerAssigned != 0; }
92
93 bool IsCompatibleWith(const PipelineResourceAttribsD3D11& rhs) const
94 {
95 // Ignore sampler index.
96 // clang-format off
97 return CacheOffset == rhs.CacheOffset &&
98 IsImmutableSamplerAssigned() == rhs.IsImmutableSamplerAssigned() &&
99 BindPoints == rhs.BindPoints;
100 // clang-format on
101 }
102
103 size_t GetHash() const
104 {
105 Uint64 h = 0;
106 for (Uint32 i = 0; i < NumShaderTypes; ++i)
107 {
108 h |= (BindPoints[i] << (i * 8));
109 }
110 return ComputeHash(h);
111 }
112 };
113
114 } // namespace Diligent
0 /*
1 * Copyright 2019-2021 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #pragma once
28
29 /// \file
30 /// Declaration of Diligent::PipelineResourceSignatureD3D11Impl class
31
32 #include <array>
33
34 #include "ResourceBindingMap.hpp"
35
36 #include "EngineD3D11ImplTraits.hpp"
37 #include "PipelineResourceSignatureBase.hpp"
38 #include "PipelineResourceAttribsD3D11.hpp"
39
40 // ShaderVariableManagerD3D11, ShaderResourceCacheD3D11, and ShaderResourceBindingD3D11Impl
41 // are required by PipelineResourceSignatureBase
42 #include "ShaderVariableManagerD3D11.hpp"
43 #include "ShaderResourceBindingD3D11Impl.hpp"
44 #include "ShaderResourceCacheD3D11.hpp"
45
46 namespace Diligent
47 {
48
49 /// Implementation of the Diligent::PipelineResourceSignatureD3D11Impl class
50 class PipelineResourceSignatureD3D11Impl final : public PipelineResourceSignatureBase<EngineD3D11ImplTraits>
51 {
52 public:
53 using TPipelineResourceSignatureBase = PipelineResourceSignatureBase<EngineD3D11ImplTraits>;
54
55 PipelineResourceSignatureD3D11Impl(IReferenceCounters* pRefCounters,
56 RenderDeviceD3D11Impl* pDevice,
57 const PipelineResourceSignatureDesc& Desc,
58 bool bIsDeviceInternal = false);
59 ~PipelineResourceSignatureD3D11Impl();
60
61 using ResourceAttribs = PipelineResourceAttribsD3D11;
62 using TBindPoints = PipelineResourceAttribsD3D11::TBindPoints;
63
64 static constexpr auto NumShaderTypes = ResourceAttribs::NumShaderTypes;
65 static constexpr auto InvalidBindPoint = ResourceAttribs::InvalidBindPoint;
66 static constexpr auto InvalidBindPoints = ResourceAttribs::InvalidBindPoints;
67
68 const ResourceAttribs& GetResourceAttribs(Uint32 ResIndex) const
69 {
70 VERIFY_EXPR(ResIndex < m_Desc.NumResources);
71 return m_pResourceAttribs[ResIndex];
72 }
73
74 // sizeof(ImmutableSamplerAttribs) == 16, x64
75 struct ImmutableSamplerAttribs
76 {
77 private:
78 static constexpr Uint32 _CacheOffsetBits = 10;
79 static constexpr Uint32 _ArraySizeBits = 22;
80
81 public:
82 static constexpr Uint32 InvalidCacheOffset = (1u << _CacheOffsetBits) - 1;
83 static_assert(InvalidCacheOffset == ResourceAttribs::InvalidCacheOffset,
84 "InvalidCacheOffset value mismatch between ResourceAttribs and ImmutableSamplerAttribs");
85
86 // clang-format off
87 RefCntAutoPtr<ISampler> pSampler;
88 TBindPoints BindPoints = InvalidBindPoints;
89 TBindPoints LastBindPoints = InvalidBindPoints; // array size for each stage may be different
90 Uint32 CacheOffset : _CacheOffsetBits;
91 Uint32 ArraySize : _ArraySizeBits;
92 // clang-format on
93
94 ImmutableSamplerAttribs() :
95 CacheOffset{InvalidCacheOffset},
96 ArraySize{0}
97 {}
98
99 bool IsAllocated() const { return CacheOffset != InvalidCacheOffset; }
100 SamplerD3D11Impl* GetSamplerD3D11() const { return ValidatedCast<SamplerD3D11Impl>(pSampler.RawPtr<ISampler>()); }
101 };
102
103 const ImmutableSamplerAttribs& GetImmutableSamplerAttribs(Uint32 SampIndex) const
104 {
105 VERIFY_EXPR(SampIndex < m_Desc.NumImmutableSamplers);
106 return m_ImmutableSamplers[SampIndex];
107 }
108
109 using TBindings = ShaderResourceCacheD3D11::TResourceCount;
110 using TBindingsPerStage = ShaderResourceCacheD3D11::TBindingsPerStage;
111
112 void AddBindings(TBindingsPerStage& Bindings) const;
113
114 void InitSRBResourceCache(ShaderResourceCacheD3D11& ResourceCache);
115
116 void UpdateShaderResourceBindingMap(ResourceBinding::TMap& ResourceMap, SHADER_TYPE ShaderStage, const TBindingsPerStage& BaseBindings) const;
117
118 // Copies static resources from the static resource cache to the destination cache
119 void CopyStaticResources(ShaderResourceCacheD3D11& ResourceCache) const;
120
121 #ifdef DILIGENT_DEVELOPMENT
122 /// Verifies committed resource attribs using the SPIRV resource attributes from the PSO.
123 bool DvpValidateCommittedResource(const D3DShaderResourceAttribs& D3DAttribs,
124 RESOURCE_DIMENSION ResourceDim,
125 bool IsMultisample,
126 Uint32 ResIndex,
127 const ShaderResourceCacheD3D11& ResourceCache,
128 const char* ShaderName,
129 const char* PSOName) const;
130 #endif
131
132 private:
133 void CreateLayout();
134
135 void Destruct();
136
137 private:
138 TBindings m_ResourceCount = {};
139 TBindingsPerStage m_BindingCountPerStage = {};
140
141 ResourceAttribs* m_pResourceAttribs = nullptr; // [m_Desc.NumResources]
142 ImmutableSamplerAttribs* m_ImmutableSamplers = nullptr; // [m_Desc.NumImmutableSamplers]
143 };
144
145
146 __forceinline void PipelineResourceSignatureD3D11Impl::AddBindings(TBindingsPerStage& Bindings) const
147 {
148 for (Uint32 s = 0; s < Bindings.size(); ++s)
149 {
150 for (Uint32 i = 0; i < Bindings[s].size(); ++i)
151 {
152 Uint32 Count = Bindings[s][i] + m_BindingCountPerStage[s][i];
153 VERIFY_EXPR(Count < std::numeric_limits<Uint8>::max());
154 Bindings[s][i] = static_cast<Uint8>(Count);
155 }
156 }
157 }
158
159 } // namespace Diligent
3232 #include "PipelineStateD3D11.h"
3333 #include "RenderDeviceD3D11.h"
3434 #include "PipelineStateBase.hpp"
35 #include "ShaderResourceLayoutD3D11.hpp"
36 #include "SRBMemoryAllocator.hpp"
37 #include "RenderDeviceD3D11Impl.hpp"
35
36 #include "PipelineResourceSignatureD3D11Impl.hpp" // Required by PipelineStateBase
3837 #include "ShaderD3D11Impl.hpp"
3938
4039 namespace Diligent
4140 {
4241
43 class FixedBlockMemoryAllocator;
44
4542 /// Pipeline state object implementation in Direct3D11 backend.
46 class PipelineStateD3D11Impl final : public PipelineStateBase<IPipelineStateD3D11, RenderDeviceD3D11Impl>
43 class PipelineStateD3D11Impl final : public PipelineStateBase<EngineD3D11ImplTraits>
4744 {
4845 public:
49 using TPipelineStateBase = PipelineStateBase<IPipelineStateD3D11, RenderDeviceD3D11Impl>;
46 using TPipelineStateBase = PipelineStateBase<EngineD3D11ImplTraits>;
5047
5148 PipelineStateD3D11Impl(IReferenceCounters* pRefCounters,
5249 class RenderDeviceD3D11Impl* pDeviceD3D11,
5855
5956 virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final;
6057
61 /// Implementation of IPipelineState::BindStaticResources() in Direct3D11 backend.
62 virtual void DILIGENT_CALL_TYPE BindStaticResources(Uint32 ShaderFlags,
63 IResourceMapping* pResourceMapping,
64 Uint32 Flags) override final;
65
66 /// Implementation of IPipelineState::GetStaticVariableCount() in Direct3D11 backend.
67 virtual Uint32 DILIGENT_CALL_TYPE GetStaticVariableCount(SHADER_TYPE ShaderType) const override final;
68
69 /// Implementation of IPipelineState::GetStaticVariableByName() in Direct3D11 backend.
70 virtual IShaderResourceVariable* DILIGENT_CALL_TYPE GetStaticVariableByName(SHADER_TYPE ShaderType,
71 const Char* Name) override final;
72
73 /// Implementation of IPipelineState::GetStaticVariableByIndex() in Direct3D11 backend.
74 virtual IShaderResourceVariable* DILIGENT_CALL_TYPE GetStaticVariableByIndex(SHADER_TYPE ShaderType,
75 Uint32 Index) override final;
76
77 /// Implementation of IPipelineState::CreateShaderResourceBinding() in Direct3D11 backend.
78 virtual void DILIGENT_CALL_TYPE CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding,
79 bool InitStaticResources) override final;
80
8158 /// Implementation of IPipelineState::IsCompatibleWith() in Direct3D11 backend.
8259 virtual bool DILIGENT_CALL_TYPE IsCompatibleWith(const IPipelineState* pPSO) const override final;
8360
84
8561 /// Implementation of IPipelineStateD3D11::GetD3D11BlendState() method.
86 virtual ID3D11BlendState* DILIGENT_CALL_TYPE GetD3D11BlendState() override final;
62 virtual ID3D11BlendState* DILIGENT_CALL_TYPE GetD3D11BlendState() override final { return m_pd3d11BlendState; }
8763
8864 /// Implementation of IPipelineStateD3D11::GetD3D11RasterizerState() method.
89 virtual ID3D11RasterizerState* DILIGENT_CALL_TYPE GetD3D11RasterizerState() override final;
65 virtual ID3D11RasterizerState* DILIGENT_CALL_TYPE GetD3D11RasterizerState() override final { return m_pd3d11RasterizerState; }
9066
9167 /// Implementation of IPipelineStateD3D11::GetD3D11DepthStencilState() method.
92 virtual ID3D11DepthStencilState* DILIGENT_CALL_TYPE GetD3D11DepthStencilState() override final;
68 virtual ID3D11DepthStencilState* DILIGENT_CALL_TYPE GetD3D11DepthStencilState() override final { return m_pd3d11DepthStencilState; }
9369
9470 /// Implementation of IPipelineStateD3D11::GetD3D11InputLayout() method.
95 virtual ID3D11InputLayout* DILIGENT_CALL_TYPE GetD3D11InputLayout() override final;
71 virtual ID3D11InputLayout* DILIGENT_CALL_TYPE GetD3D11InputLayout() override final { return m_pd3d11InputLayout; }
9672
9773 /// Implementation of IPipelineStateD3D11::GetD3D11VertexShader() method.
98 virtual ID3D11VertexShader* DILIGENT_CALL_TYPE GetD3D11VertexShader() override final;
74 virtual ID3D11VertexShader* DILIGENT_CALL_TYPE GetD3D11VertexShader() override final { return m_pVS; }
9975
10076 /// Implementation of IPipelineStateD3D11::GetD3D11PixelShader() method.
101 virtual ID3D11PixelShader* DILIGENT_CALL_TYPE GetD3D11PixelShader() override final;
77 virtual ID3D11PixelShader* DILIGENT_CALL_TYPE GetD3D11PixelShader() override final { return m_pPS; }
10278
10379 /// Implementation of IPipelineStateD3D11::GetD3D11GeometryShader() method.
104 virtual ID3D11GeometryShader* DILIGENT_CALL_TYPE GetD3D11GeometryShader() override final;
80 virtual ID3D11GeometryShader* DILIGENT_CALL_TYPE GetD3D11GeometryShader() override final { return m_pGS; }
10581
10682 /// Implementation of IPipelineStateD3D11::GetD3D11DomainShader() method.
107 virtual ID3D11DomainShader* DILIGENT_CALL_TYPE GetD3D11DomainShader() override final;
83 virtual ID3D11DomainShader* DILIGENT_CALL_TYPE GetD3D11DomainShader() override final { return m_pDS; }
10884
10985 /// Implementation of IPipelineStateD3D11::GetD3D11HullShader() method.
110 virtual ID3D11HullShader* DILIGENT_CALL_TYPE GetD3D11HullShader() override final;
86 virtual ID3D11HullShader* DILIGENT_CALL_TYPE GetD3D11HullShader() override final { return m_pHS; }
11187
11288 /// Implementation of IPipelineStateD3D11::GetD3D11ComputeShader() method.
113 virtual ID3D11ComputeShader* DILIGENT_CALL_TYPE GetD3D11ComputeShader() override final;
89 virtual ID3D11ComputeShader* DILIGENT_CALL_TYPE GetD3D11ComputeShader() override final { return m_pCS; }
11490
115
116 SRBMemoryAllocator& GetSRBMemoryAllocator()
117 {
118 return m_SRBMemAllocator;
119 }
120
121 const ShaderResourceLayoutD3D11& GetStaticResourceLayout(Uint32 s) const
122 {
123 VERIFY_EXPR(s < GetNumShaderStages());
124 return m_pStaticResourceLayouts[s];
125 }
126
127 ShaderResourceCacheD3D11& GetStaticResourceCache(Uint32 s)
128 {
129 VERIFY_EXPR(s < GetNumShaderStages());
130 return m_pStaticResourceCaches[s];
131 }
132
133 const ShaderD3D11Impl* GetShaderByType(SHADER_TYPE ShaderType) const;
134 const ShaderD3D11Impl* GetShader(Uint32 Index) const;
135
136 void SetImmutableSamplers(ShaderResourceCacheD3D11& ResourceCache, Uint32 ShaderInd) const;
91 Uint32 GetNumShaders() const { return m_NumShaders; }
92 SHADER_TYPE GetShaderStageType(Uint32 Index) const;
13793
13894 private:
13995 template <typename PSOCreateInfoType>
140 void InitInternalObjects(const PSOCreateInfoType& CreateInfo);
96 void InitInternalObjects(const PSOCreateInfoType& CreateInfo,
97 std::vector<CComPtr<ID3DBlob>>& ByteCodes);
14198
14299 void InitResourceLayouts(const PipelineStateCreateInfo& CreateInfo,
143 const std::vector<ShaderD3D11Impl*>& Shaders);
100 const std::vector<ShaderD3D11Impl*>& Shaders,
101 std::vector<CComPtr<ID3DBlob>>& ByteCodes);
102
103 RefCntAutoPtr<PipelineResourceSignatureD3D11Impl> CreateDefaultResourceSignature(
104 const PipelineStateCreateInfo& CreateInfo,
105 const std::vector<ShaderD3D11Impl*>& Shaders);
144106
145107 void Destruct();
108
109 void ValidateShaderResources(const ShaderD3D11Impl* pShader);
110
111 private:
112 using SignaturePtr = RefCntAutoPtr<PipelineResourceSignatureD3D11Impl>;
113
114 std::array<Uint8, 5> m_ShaderTypes = {};
115 Uint8 m_NumShaders = 0;
146116
147117 CComPtr<ID3D11BlendState> m_pd3d11BlendState;
148118 CComPtr<ID3D11RasterizerState> m_pd3d11RasterizerState;
149119 CComPtr<ID3D11DepthStencilState> m_pd3d11DepthStencilState;
150120 CComPtr<ID3D11InputLayout> m_pd3d11InputLayout;
121 CComPtr<ID3D11VertexShader> m_pVS;
122 CComPtr<ID3D11PixelShader> m_pPS;
123 CComPtr<ID3D11GeometryShader> m_pGS;
124 CComPtr<ID3D11DomainShader> m_pDS;
125 CComPtr<ID3D11HullShader> m_pHS;
126 CComPtr<ID3D11ComputeShader> m_pCS;
151127
152 RefCntAutoPtr<ShaderD3D11Impl> m_pVS;
153 RefCntAutoPtr<ShaderD3D11Impl> m_pPS;
154 RefCntAutoPtr<ShaderD3D11Impl> m_pGS;
155 RefCntAutoPtr<ShaderD3D11Impl> m_pDS;
156 RefCntAutoPtr<ShaderD3D11Impl> m_pHS;
157 RefCntAutoPtr<ShaderD3D11Impl> m_pCS;
128 #ifdef DILIGENT_DEVELOPMENT
129 // Shader resources for all shaders in all shader stages in the pipeline.
130 std::vector<std::shared_ptr<const ShaderResourcesD3D11>> m_ShaderResources;
158131
159 // The caches are indexed by the shader order in the PSO, not shader index
160 ShaderResourceCacheD3D11* m_pStaticResourceCaches = nullptr; // [m_NumShaderStages]
161 ShaderResourceLayoutD3D11* m_pStaticResourceLayouts = nullptr; // [m_NumShaderStages]
162
163 // SRB memory allocator must be defined before the default shader res binding
164 SRBMemoryAllocator m_SRBMemAllocator;
165
166 // Resource layout index in m_pStaticResourceLayouts array for every shader stage,
167 // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex)
168 std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1, -1};
169 static_assert(MAX_SHADERS_IN_PIPELINE == 6, "Please update the initializer list above");
170
171 std::array<Uint16, MAX_SHADERS_IN_PIPELINE + 1> m_ImmutableSamplerOffsets = {};
172 struct ImmutableSamplerInfo
173 {
174 const D3DShaderResourceAttribs& Attribs;
175 RefCntAutoPtr<ISampler> pSampler;
176 ImmutableSamplerInfo(const D3DShaderResourceAttribs& _Attribs,
177 RefCntAutoPtr<ISampler> _pSampler) :
178 // clang-format off
179 Attribs {_Attribs},
180 pSampler {std::move(_pSampler)}
181 // clang-format on
182 {}
183 };
184 std::vector<ImmutableSamplerInfo, STDAllocatorRawMem<ImmutableSamplerInfo>> m_ImmutableSamplers;
132 // Shader resource attributions for every resource in m_ShaderResources, in the same order.
133 std::vector<ResourceAttribution> m_ResourceAttibutions;
134 #endif
185135 };
186136
137 __forceinline SHADER_TYPE GetShaderStageType(const ShaderD3D11Impl* pShader)
138 {
139 return pShader->GetDesc().ShaderType;
140 }
141
187142 } // namespace Diligent
4242 class FixedBlockMemoryAllocator;
4343
4444 /// Query implementation in Direct3D11 backend.
45 class QueryD3D11Impl final : public QueryBase<IQueryD3D11, RenderDeviceD3D11Impl>
45 class QueryD3D11Impl final : public QueryBase<EngineD3D11ImplTraits>
4646 {
4747 public:
48 using TQueryBase = QueryBase<IQueryD3D11, RenderDeviceD3D11Impl>;
48 using TQueryBase = QueryBase<EngineD3D11ImplTraits>;
4949
5050 QueryD3D11Impl(IReferenceCounters* pRefCounters,
5151 RenderDeviceD3D11Impl* pDevice,
2929 /// \file
3030 /// Declaration of Diligent::RenderDeviceD3D11Impl class
3131
32 #include "RenderDeviceD3D11.h"
32 #include "EngineD3D11ImplTraits.hpp"
3333 #include "RenderDeviceD3DBase.hpp"
3434 #include "DeviceContextD3D11.h"
3535
3737 {
3838
3939 /// Render device implementation in Direct3D11 backend.
40 class RenderDeviceD3D11Impl final : public RenderDeviceD3DBase<IRenderDeviceD3D11>
40 class RenderDeviceD3D11Impl final : public RenderDeviceD3DBase<EngineD3D11ImplTraits>
4141 {
4242 public:
43 using TRenderDeviceBase = RenderDeviceD3DBase<IRenderDeviceD3D11>;
43 using TRenderDeviceBase = RenderDeviceD3DBase<EngineD3D11ImplTraits>;
4444
4545 RenderDeviceD3D11Impl(IReferenceCounters* pRefCounters,
4646 IMemoryAllocator& RawMemAllocator,
108108 virtual void DILIGENT_CALL_TYPE CreateSBT(const ShaderBindingTableDesc& Desc,
109109 IShaderBindingTable** ppSBT) override final;
110110
111 /// Implementation of IRenderDevice::CreatePipelineResourceSignature() in Direct3D11 backend.
112 virtual void DILIGENT_CALL_TYPE CreatePipelineResourceSignature(const PipelineResourceSignatureDesc& Desc,
113 IPipelineResourceSignature** ppSignature) override final;
114
115 void CreatePipelineResourceSignature(const PipelineResourceSignatureDesc& Desc,
116 IPipelineResourceSignature** ppSignature,
117 bool IsDeviceInternal);
118
111119 /// Implementation of IRenderDeviceD3D11::GetD3D11Device() in Direct3D11 backend.
112120 ID3D11Device* DILIGENT_CALL_TYPE GetD3D11Device() override final { return m_pd3d11Device; }
113121
3939 class FixedBlockMemoryAllocator;
4040
4141 /// Render pass implementation in Direct3D11 backend.
42 class RenderPassD3D11Impl final : public RenderPassBase<IRenderPass, RenderDeviceD3D11Impl>
42 class RenderPassD3D11Impl final : public RenderPassBase<EngineD3D11ImplTraits>
4343 {
4444 public:
45 using TRenderPassBase = RenderPassBase<IRenderPass, RenderDeviceD3D11Impl>;
45 using TRenderPassBase = RenderPassBase<EngineD3D11ImplTraits>;
4646
4747 RenderPassD3D11Impl(IReferenceCounters* pRefCounters,
4848 RenderDeviceD3D11Impl* pDevice,
4040 class FixedBlockMemoryAllocator;
4141
4242 /// Sampler implementation in Direct3D11 backend.
43 class SamplerD3D11Impl final : public SamplerBase<ISamplerD3D11, RenderDeviceD3D11Impl>
43 class SamplerD3D11Impl final : public SamplerBase<EngineD3D11ImplTraits>
4444 {
4545 public:
46 using TSamplerBase = SamplerBase<ISamplerD3D11, RenderDeviceD3D11Impl>;
46 using TSamplerBase = SamplerBase<EngineD3D11ImplTraits>;
4747
4848 SamplerD3D11Impl(IReferenceCounters* pRefCounters,
4949 class RenderDeviceD3D11Impl* pRenderDeviceD3D11,
3333 #include "RenderDeviceD3D11.h"
3434 #include "ShaderBase.hpp"
3535 #include "ShaderD3DBase.hpp"
36 #include "ShaderResourceLayoutD3D11.hpp"
3736 #include "ShaderResourceCacheD3D11.hpp"
3837 #include "EngineD3D11Defines.h"
3938 #include "ShaderResourcesD3D11.hpp"
4645 class ResourceMapping;
4746
4847 /// Shader implementation in Direct3D11 backend.
49 class ShaderD3D11Impl final : public ShaderBase<IShaderD3D11, RenderDeviceD3D11Impl>, public ShaderD3DBase
48 class ShaderD3D11Impl final : public ShaderBase<EngineD3D11ImplTraits>, public ShaderD3DBase
5049 {
5150 public:
52 using TShaderBase = ShaderBase<IShaderD3D11, RenderDeviceD3D11Impl>;
51 using TShaderBase = ShaderBase<EngineD3D11ImplTraits>;
5352
5453 ShaderD3D11Impl(IReferenceCounters* pRefCounters,
5554 class RenderDeviceD3D11Impl* pRenderDeviceD3D11,
8483
8584 ID3DBlob* GetBytecode() { return m_pShaderByteCode; }
8685
87 const std::shared_ptr<const ShaderResourcesD3D11>& GetD3D11Resources() const { return m_pShaderResources; }
86 const std::shared_ptr<const ShaderResourcesD3D11>& GetShaderResources() const { return m_pShaderResources; }
8887
8988 private:
9089 /// D3D11 shader
3434 #include "ShaderResourceBindingD3D11.h"
3535 #include "RenderDeviceD3D11.h"
3636 #include "ShaderResourceBindingBase.hpp"
37
38 // ShaderResourceCacheD3D11 and ShaderVariableManagerD3D11 are required by ShaderResourceBindingBase
3739 #include "ShaderResourceCacheD3D11.hpp"
38 #include "ShaderResourceLayoutD3D11.hpp"
39 #include "STDAllocator.hpp"
40 #include "ShaderVariableManagerD3D11.hpp"
4041
4142 namespace Diligent
4243 {
4344
44 class PipelineStateD3D11Impl;
45
4645 /// Implementation of shader resource binding object in Direct3D11 backend.
47 class ShaderResourceBindingD3D11Impl final : public ShaderResourceBindingBase<IShaderResourceBindingD3D11, PipelineStateD3D11Impl>
46 class ShaderResourceBindingD3D11Impl final : public ShaderResourceBindingBase<EngineD3D11ImplTraits>
4847 {
4948 public:
50 using TBase = ShaderResourceBindingBase<IShaderResourceBindingD3D11, PipelineStateD3D11Impl>;
49 using TBase = ShaderResourceBindingBase<EngineD3D11ImplTraits>;
5150
52 ShaderResourceBindingD3D11Impl(IReferenceCounters* pRefCounters,
53 PipelineStateD3D11Impl* pPSO,
54 bool IsInternal);
51 ShaderResourceBindingD3D11Impl(IReferenceCounters* pRefCounters,
52 PipelineResourceSignatureD3D11Impl* pPRS);
5553 ~ShaderResourceBindingD3D11Impl();
5654
5755 virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final;
58
59 /// Implementation of IShaderResourceBinding::BindResources() in Direct3D11 backend.
60 virtual void DILIGENT_CALL_TYPE BindResources(Uint32 ShaderFlags,
61 IResourceMapping* pResMapping,
62 Uint32 Flags) override final;
63
64 /// Implementation of IShaderResourceBinding::GetVariableByName() in Direct3D11 backend.
65 virtual IShaderResourceVariable* DILIGENT_CALL_TYPE GetVariableByName(SHADER_TYPE ShaderType, const char* Name) override final;
66
67 /// Implementation of IShaderResourceBinding::GetVariableCount() in Direct3D11 backend.
68 virtual Uint32 DILIGENT_CALL_TYPE GetVariableCount(SHADER_TYPE ShaderType) const override final;
69
70 /// Implementation of IShaderResourceBinding::GetVariableByIndex() in Direct3D11 backend.
71 virtual IShaderResourceVariable* DILIGENT_CALL_TYPE GetVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index) override final;
72
73 /// Implementation of IShaderResourceBinding::InitializeStaticResources() in Direct3D11 backend.
74 virtual void DILIGENT_CALL_TYPE InitializeStaticResources(const IPipelineState* pPipelineState) override final;
75
76 ShaderResourceCacheD3D11& GetResourceCache(Uint32 Ind)
77 {
78 VERIFY_EXPR(Ind < m_NumActiveShaders);
79 return m_pBoundResourceCaches[Ind];
80 }
81
82 ShaderResourceLayoutD3D11& GetResourceLayout(Uint32 Ind)
83 {
84 VERIFY_EXPR(Ind < m_NumActiveShaders);
85 return m_pResourceLayouts[Ind];
86 }
87
88 inline bool IsStaticResourcesBound() const { return m_bIsStaticResourcesBound; }
89
90 Uint32 GetNumActiveShaders() const
91 {
92 return Uint32{m_NumActiveShaders};
93 }
94
95 SHADER_TYPE GetActiveShaderType(Uint32 s) const
96 {
97 VERIFY_EXPR(s < m_NumActiveShaders);
98 return m_ShaderTypes[s];
99 }
100
101 private:
102 void Destruct();
103
104 // The caches are indexed by the shader order in the PSO, not shader index
105 ShaderResourceCacheD3D11* m_pBoundResourceCaches = nullptr;
106 ShaderResourceLayoutD3D11* m_pResourceLayouts = nullptr;
107
108 std::array<SHADER_TYPE, MAX_SHADERS_IN_PIPELINE> m_ShaderTypes = {};
109
110 // Resource layout index in m_pResourceLayouts array for every shader stage,
111 // indexed by the shader type pipeline index (returned by GetShaderTypePipelineIndex)
112 std::array<Int8, MAX_SHADERS_IN_PIPELINE> m_ResourceLayoutIndex = {-1, -1, -1, -1, -1, -1};
113 static_assert(MAX_SHADERS_IN_PIPELINE == 6, "Please update the initializer list above");
114
115 Uint8 m_NumActiveShaders = 0;
116
117 bool m_bIsStaticResourcesBound = false;
11856 };
11957
12058 } // namespace Diligent
3030 /// Declaration of Diligent::ShaderResourceCacheD3D11 class
3131
3232 #include "MemoryAllocator.h"
33 #include "ShaderResourceCacheCommon.hpp"
3334 #include "TextureBaseD3D11.hpp"
3435 #include "BufferD3D11Impl.hpp"
3536 #include "SamplerD3D11Impl.hpp"
37 #include "PipelineResourceAttribsD3D11.hpp"
3638
3739 namespace Diligent
3840 {
5052 class ShaderResourceCacheD3D11
5153 {
5254 public:
53 ShaderResourceCacheD3D11() noexcept
55 explicit ShaderResourceCacheD3D11(ResourceCacheContentType ContentType) noexcept :
56 m_ContentType{ContentType}
5457 {}
5558
5659 ~ShaderResourceCacheD3D11();
6265 ShaderResourceCacheD3D11& operator = (ShaderResourceCacheD3D11&&) = delete;
6366 // clang-format on
6467
68 enum class StateTransitionMode
69 {
70 Transition,
71 Verify
72 };
73 // Transitions all resources in the cache
74 void TransitionResourceStates(DeviceContextD3D11Impl& Ctx, StateTransitionMode Mode);
75
76
77 static constexpr int NumShaderTypes = PipelineResourceAttribsD3D11::NumShaderTypes;
78
79 struct TCommittedResources
80 {
81 // clang-format off
82
83 /// An array of D3D11 constant buffers committed to D3D11 device context,
84 /// for each shader type. The context addref's all bound resources, so we do
85 /// not need to keep strong references.
86 ID3D11Buffer* D3D11CBs [NumShaderTypes][D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {};
87
88 /// An array of D3D11 shader resource views committed to D3D11 device context,
89 /// for each shader type. The context addref's all bound resources, so we do
90 /// not need to keep strong references.
91 ID3D11ShaderResourceView* D3D11SRVs [NumShaderTypes][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {};
92
93 /// An array of D3D11 samplers committed to D3D11 device context,
94 /// for each shader type. The context addref's all bound resources, so we do
95 /// not need to keep strong references.
96 ID3D11SamplerState* D3D11Samplers[NumShaderTypes][D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {};
97
98 /// An array of D3D11 UAVs committed to D3D11 device context,
99 /// for each shader type. The context addref's all bound resources, so we do
100 /// not need to keep strong references.
101 ID3D11UnorderedAccessView* D3D11UAVs [NumShaderTypes][D3D11_PS_CS_UAV_REGISTER_COUNT] = {};
102
103 /// An array of D3D11 resources commited as SRV to D3D11 device context,
104 /// for each shader type. The context addref's all bound resources, so we do
105 /// not need to keep strong references.
106 ID3D11Resource* D3D11SRVResources [NumShaderTypes][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {};
107
108 /// An array of D3D11 resources commited as UAV to D3D11 device context,
109 /// for each shader type. The context addref's all bound resources, so we do
110 /// not need to keep strong references.
111 ID3D11Resource* D3D11UAVResources [NumShaderTypes][D3D11_PS_CS_UAV_REGISTER_COUNT] = {};
112
113 Uint8 NumCBs [NumShaderTypes] = {};
114 Uint8 NumSRVs [NumShaderTypes] = {};
115 Uint8 NumSamplers[NumShaderTypes] = {};
116 Uint8 NumUAVs [NumShaderTypes] = {};
117
118 // clang-format on
119
120 void Clear();
121 };
122
123 struct MinMaxSlot
124 {
125 UINT MinSlot = UINT_MAX;
126 UINT MaxSlot = 0;
127 };
128 using TMinMaxSlotPerStage = std::array<std::array<MinMaxSlot, DESCRIPTOR_RANGE_COUNT>, NumShaderTypes>;
129 using TResourceCount = std::array<Uint8, DESCRIPTOR_RANGE_COUNT>;
130 using TBindingsPerStage = std::array<TResourceCount, NumShaderTypes>;
131
132 void BindResources(DeviceContextD3D11Impl& Ctx, const TBindingsPerStage& BaseBindings, TMinMaxSlotPerStage& MinMaxSlot, TCommittedResources& CommittedRes, SHADER_TYPE ActiveStages) const;
133
134
65135 /// Describes a resource associated with a cached constant buffer
66136 struct CachedCB
67137 {
68138 /// Strong reference to the buffer
69139 RefCntAutoPtr<BufferD3D11Impl> pBuff;
70140
141 private:
142 friend class ShaderResourceCacheD3D11;
71143 __forceinline void Set(RefCntAutoPtr<BufferD3D11Impl>&& _pBuff)
72144 {
73145 pBuff = std::move(_pBuff);
80152 /// Strong reference to the sampler
81153 RefCntAutoPtr<class SamplerD3D11Impl> pSampler;
82154
155 private:
156 friend class ShaderResourceCacheD3D11;
83157 __forceinline void Set(SamplerD3D11Impl* pSam)
84158 {
85159 pSampler = pSam;
105179
106180 CachedResource() noexcept {}
107181
182 private:
183 friend class ShaderResourceCacheD3D11;
108184 __forceinline void Set(RefCntAutoPtr<TextureViewD3D11Impl>&& pTexView)
109185 {
110186 pBuffer = nullptr;
124200 }
125201 };
126202
127 static size_t GetRequriedMemorySize(const class ShaderResourcesD3D11& Resources);
128
129 void Initialize(const class ShaderResourcesD3D11& Resources, IMemoryAllocator& MemAllocator);
130 void Initialize(Uint32 CBCount, Uint32 SRVCount, Uint32 SamplerCount, Uint32 UAVCount, IMemoryAllocator& MemAllocator);
131 void Destroy(IMemoryAllocator& MemAllocator);
132
133
134 __forceinline void SetCB(Uint32 Slot, RefCntAutoPtr<BufferD3D11Impl>&& pBuffD3D11Impl)
203 static size_t GetRequriedMemorySize(const TResourceCount& ResCount);
204
205 void Initialize(const TResourceCount& ResCount, IMemoryAllocator& MemAllocator);
206
207
208 using TBindPoints = PipelineResourceAttribsD3D11::TBindPoints;
209 using TBindPointsAndActiveBits = std::array<Uint8, NumShaderTypes + 1>; // ActiveBits [0], TBindPoints [1..6]
210 static constexpr auto InvalidBindPoint = PipelineResourceAttribsD3D11::InvalidBindPoint;
211
212 __forceinline void SetCB(Uint32 CacheOffset, Uint32 ArrayIndex, TBindPoints BindPoints, RefCntAutoPtr<BufferD3D11Impl>&& pBuffD3D11Impl)
135213 {
136214 auto* pd3d11Buff = pBuffD3D11Impl ? pBuffD3D11Impl->BufferD3D11Impl::GetD3D11Buffer() : nullptr;
137 SetD3D11ResourceInternal<CachedCB>(Slot, GetCBCount(), &ShaderResourceCacheD3D11::GetCBArrays, std::move(pBuffD3D11Impl), pd3d11Buff);
138 }
139
140 __forceinline void SetTexSRV(Uint32 Slot, RefCntAutoPtr<TextureViewD3D11Impl>&& pTexView)
215 SetD3D11ResourceInternal<CachedCB>(CacheOffset, ArrayIndex, GetCBCount(), BindPoints, &ShaderResourceCacheD3D11::GetCBArrays, std::move(pBuffD3D11Impl), pd3d11Buff);
216 }
217
218 __forceinline void SetTexSRV(Uint32 CacheOffset, Uint32 ArrayIndex, TBindPoints BindPoints, RefCntAutoPtr<TextureViewD3D11Impl>&& pTexView)
141219 {
142220 auto* pd3d11SRV = pTexView ? static_cast<ID3D11ShaderResourceView*>(pTexView->TextureViewD3D11Impl::GetD3D11View()) : nullptr;
143 SetD3D11ResourceInternal<CachedResource>(Slot, GetSRVCount(), &ShaderResourceCacheD3D11::GetSRVArrays, std::move(pTexView), pd3d11SRV);
144 }
145
146 __forceinline void SetBufSRV(Uint32 Slot, RefCntAutoPtr<BufferViewD3D11Impl>&& pBuffView)
221 SetD3D11ResourceInternal<CachedResource>(CacheOffset, ArrayIndex, GetSRVCount(), BindPoints, &ShaderResourceCacheD3D11::GetSRVArrays, std::move(pTexView), pd3d11SRV);
222 }
223
224 __forceinline void SetBufSRV(Uint32 CacheOffset, Uint32 ArrayIndex, TBindPoints BindPoints, RefCntAutoPtr<BufferViewD3D11Impl>&& pBuffView)
147225 {
148226 auto* pd3d11SRV = pBuffView ? static_cast<ID3D11ShaderResourceView*>(pBuffView->BufferViewD3D11Impl::GetD3D11View()) : nullptr;
149 SetD3D11ResourceInternal<CachedResource>(Slot, GetSRVCount(), &ShaderResourceCacheD3D11::GetSRVArrays, std::move(pBuffView), pd3d11SRV);
150 }
151
152 __forceinline void SetTexUAV(Uint32 Slot, RefCntAutoPtr<TextureViewD3D11Impl>&& pTexView)
227 SetD3D11ResourceInternal<CachedResource>(CacheOffset, ArrayIndex, GetSRVCount(), BindPoints, &ShaderResourceCacheD3D11::GetSRVArrays, std::move(pBuffView), pd3d11SRV);
228 }
229
230 __forceinline void SetTexUAV(Uint32 CacheOffset, Uint32 ArrayIndex, TBindPoints BindPoints, RefCntAutoPtr<TextureViewD3D11Impl>&& pTexView)
153231 {
154232 auto* pd3d11UAV = pTexView ? static_cast<ID3D11UnorderedAccessView*>(pTexView->TextureViewD3D11Impl::GetD3D11View()) : nullptr;
155 SetD3D11ResourceInternal<CachedResource>(Slot, GetUAVCount(), &ShaderResourceCacheD3D11::GetUAVArrays, std::move(pTexView), pd3d11UAV);
156 }
157
158 __forceinline void SetBufUAV(Uint32 Slot, RefCntAutoPtr<BufferViewD3D11Impl>&& pBuffView)
233 SetD3D11ResourceInternal<CachedResource>(CacheOffset, ArrayIndex, GetUAVCount(), BindPoints, &ShaderResourceCacheD3D11::GetUAVArrays, std::move(pTexView), pd3d11UAV);
234 }
235
236 __forceinline void SetBufUAV(Uint32 CacheOffset, Uint32 ArrayIndex, TBindPoints BindPoints, RefCntAutoPtr<BufferViewD3D11Impl>&& pBuffView)
159237 {
160238 auto* pd3d11UAV = pBuffView ? static_cast<ID3D11UnorderedAccessView*>(pBuffView->BufferViewD3D11Impl::GetD3D11View()) : nullptr;
161 SetD3D11ResourceInternal<CachedResource>(Slot, GetUAVCount(), &ShaderResourceCacheD3D11::GetUAVArrays, std::move(pBuffView), pd3d11UAV);
162 }
163
164 __forceinline void SetSampler(Uint32 Slot, SamplerD3D11Impl* pSampler)
239 SetD3D11ResourceInternal<CachedResource>(CacheOffset, ArrayIndex, GetUAVCount(), BindPoints, &ShaderResourceCacheD3D11::GetUAVArrays, std::move(pBuffView), pd3d11UAV);
240 }
241
242 __forceinline void SetSampler(Uint32 CacheOffset, Uint32 ArrayIndex, TBindPoints BindPoints, SamplerD3D11Impl* pSampler)
165243 {
166244 auto* pd3d11Sampler = pSampler ? pSampler->SamplerD3D11Impl::GetD3D11SamplerState() : nullptr;
167 SetD3D11ResourceInternal<CachedSampler>(Slot, GetSamplerCount(), &ShaderResourceCacheD3D11::GetSamplerArrays, pSampler, pd3d11Sampler);
168 }
169
170
171
172 __forceinline CachedCB& GetCB(Uint32 Slot)
173 {
174 VERIFY(Slot < GetCBCount(), "CB slot is out of range");
245 SetD3D11ResourceInternal<CachedSampler>(CacheOffset, ArrayIndex, GetSamplerCount(), BindPoints, &ShaderResourceCacheD3D11::GetSamplerArrays, pSampler, pd3d11Sampler);
246 }
247
248
249 __forceinline CachedCB const& GetCB(Uint32 CacheOffset) const
250 {
251 VERIFY(CacheOffset < GetCBCount(), "CB slot is out of range");
175252 ShaderResourceCacheD3D11::CachedCB* CBs;
176253 ID3D11Buffer** pd3d11CBs;
177 GetCBArrays(CBs, pd3d11CBs);
178 return CBs[Slot];
179 }
180
181 __forceinline CachedResource& GetSRV(Uint32 Slot)
182 {
183 VERIFY(Slot < GetSRVCount(), "SRV slot is out of range");
254 TBindPointsAndActiveBits* bindPoints;
255 const_cast<ShaderResourceCacheD3D11*>(this)->GetCBArrays(CBs, pd3d11CBs, bindPoints);
256 return CBs[CacheOffset];
257 }
258
259 __forceinline CachedResource const& GetSRV(Uint32 CacheOffset) const
260 {
261 VERIFY(CacheOffset < GetSRVCount(), "SRV slot is out of range");
184262 ShaderResourceCacheD3D11::CachedResource* SRVResources;
185263 ID3D11ShaderResourceView** pd3d11SRVs;
186 GetSRVArrays(SRVResources, pd3d11SRVs);
187 return SRVResources[Slot];
188 }
189
190 __forceinline CachedResource& GetUAV(Uint32 Slot)
191 {
192 VERIFY(Slot < GetUAVCount(), "UAV slot is out of range");
264 TBindPointsAndActiveBits* bindPoints;
265 const_cast<ShaderResourceCacheD3D11*>(this)->GetSRVArrays(SRVResources, pd3d11SRVs, bindPoints);
266 return SRVResources[CacheOffset];
267 }
268
269 __forceinline CachedResource const& GetUAV(Uint32 CacheOffset) const
270 {
271 VERIFY(CacheOffset < GetUAVCount(), "UAV slot is out of range");
193272 ShaderResourceCacheD3D11::CachedResource* UAVResources;
194273 ID3D11UnorderedAccessView** pd3d11UAVs;
195 GetUAVArrays(UAVResources, pd3d11UAVs);
196 return UAVResources[Slot];
197 }
198
199 __forceinline CachedSampler& GetSampler(Uint32 Slot)
200 {
201 VERIFY(Slot < GetSamplerCount(), "Sampler slot is out of range");
274 TBindPointsAndActiveBits* bindPoints;
275 const_cast<ShaderResourceCacheD3D11*>(this)->GetUAVArrays(UAVResources, pd3d11UAVs, bindPoints);
276 return UAVResources[CacheOffset];
277 }
278
279 __forceinline CachedSampler const& GetSampler(Uint32 CacheOffset) const
280 {
281 VERIFY(CacheOffset < GetSamplerCount(), "Sampler slot is out of range");
202282 ShaderResourceCacheD3D11::CachedSampler* Samplers;
203283 ID3D11SamplerState** pd3d11Samplers;
204 GetSamplerArrays(Samplers, pd3d11Samplers);
205 return Samplers[Slot];
206 }
207
208
209 __forceinline bool IsCBBound(Uint32 Slot) const
210 {
211 CachedCB* CBs = nullptr;
212 ID3D11Buffer** d3d11CBs = nullptr;
213 const_cast<ShaderResourceCacheD3D11*>(this)->GetCBArrays(CBs, d3d11CBs);
214 if (Slot < GetCBCount() && d3d11CBs[Slot] != nullptr)
215 {
216 VERIFY(CBs[Slot].pBuff != nullptr, "No relevant buffer resource");
284 TBindPointsAndActiveBits* bindPoints;
285 const_cast<ShaderResourceCacheD3D11*>(this)->GetSamplerArrays(Samplers, pd3d11Samplers, bindPoints);
286 return Samplers[CacheOffset];
287 }
288
289
290 __forceinline bool IsCBBound(Uint32 CacheOffset) const
291 {
292 CachedCB const* CBs;
293 ID3D11Buffer* const* d3d11CBs;
294 TBindPointsAndActiveBits const* bindPoints;
295 GetConstCBArrays(CBs, d3d11CBs, bindPoints);
296 if (CacheOffset < GetCBCount() && d3d11CBs[CacheOffset] != nullptr)
297 {
298 VERIFY(CBs[CacheOffset].pBuff != nullptr, "No relevant buffer resource");
217299 return true;
218300 }
219301 return false;
220302 }
221303
222 __forceinline bool IsSRVBound(Uint32 Slot, bool dbgIsTextureView) const
223 {
224 CachedResource* SRVResources = nullptr;
225 ID3D11ShaderResourceView** d3d11SRVs = nullptr;
226 const_cast<ShaderResourceCacheD3D11*>(this)->GetSRVArrays(SRVResources, d3d11SRVs);
227 if (Slot < GetSRVCount() && d3d11SRVs[Slot] != nullptr)
228 {
229 VERIFY((dbgIsTextureView && SRVResources[Slot].pTexture != nullptr) || (!dbgIsTextureView && SRVResources[Slot].pBuffer != nullptr),
304 __forceinline bool IsSRVBound(Uint32 CacheOffset, bool dbgIsTextureView) const
305 {
306 CachedResource const* SRVResources;
307 ID3D11ShaderResourceView* const* d3d11SRVs;
308 TBindPointsAndActiveBits const* bindPoints;
309 GetConstSRVArrays(SRVResources, d3d11SRVs, bindPoints);
310 if (CacheOffset < GetSRVCount() && d3d11SRVs[CacheOffset] != nullptr)
311 {
312 VERIFY((dbgIsTextureView && SRVResources[CacheOffset].pTexture != nullptr) || (!dbgIsTextureView && SRVResources[CacheOffset].pBuffer != nullptr),
230313 "No relevant resource");
231314 return true;
232315 }
233316 return false;
234317 }
235318
236 __forceinline bool IsUAVBound(Uint32 Slot, bool dbgIsTextureView) const
237 {
238 CachedResource* UAVResources = nullptr;
239 ID3D11UnorderedAccessView** d3d11UAVs = nullptr;
240 const_cast<ShaderResourceCacheD3D11*>(this)->GetUAVArrays(UAVResources, d3d11UAVs);
241 if (Slot < GetUAVCount() && d3d11UAVs[Slot] != nullptr)
242 {
243 VERIFY((dbgIsTextureView && UAVResources[Slot].pTexture != nullptr) || (!dbgIsTextureView && UAVResources[Slot].pBuffer != nullptr),
319 __forceinline bool IsUAVBound(Uint32 CacheOffset, bool dbgIsTextureView) const
320 {
321 CachedResource const* UAVResources;
322 ID3D11UnorderedAccessView* const* d3d11UAVs;
323 TBindPointsAndActiveBits const* bindPoints;
324 GetConstUAVArrays(UAVResources, d3d11UAVs, bindPoints);
325 if (CacheOffset < GetUAVCount() && d3d11UAVs[CacheOffset] != nullptr)
326 {
327 VERIFY((dbgIsTextureView && UAVResources[CacheOffset].pTexture != nullptr) || (!dbgIsTextureView && UAVResources[CacheOffset].pBuffer != nullptr),
244328 "No relevant resource");
245329 return true;
246330 }
247331 return false;
248332 }
249333
250 __forceinline bool IsSamplerBound(Uint32 Slot) const
251 {
252 CachedSampler* Samplers = nullptr;
253 ID3D11SamplerState** d3d11Samplers = nullptr;
254 const_cast<ShaderResourceCacheD3D11*>(this)->GetSamplerArrays(Samplers, d3d11Samplers);
255 if (Slot < GetSamplerCount() && d3d11Samplers[Slot] != nullptr)
256 {
257 VERIFY(Samplers[Slot].pSampler != nullptr, "No relevant sampler");
334 __forceinline bool IsSamplerBound(Uint32 CacheOffset) const
335 {
336 CachedSampler const* Samplers;
337 ID3D11SamplerState* const* d3d11Samplers;
338 TBindPointsAndActiveBits const* bindPoints;
339 GetConstSamplerArrays(Samplers, d3d11Samplers, bindPoints);
340 if (CacheOffset < GetSamplerCount() && d3d11Samplers[CacheOffset] != nullptr)
341 {
342 VERIFY(Samplers[CacheOffset].pSampler != nullptr, "No relevant sampler");
258343 return true;
259344 }
260345 return false;
261346 }
262347
263 void dbgVerifyCacheConsistency();
348 #ifdef DILIGENT_DEVELOPMENT
349 void DvpVerifyCacheConsistency();
350 #endif
264351
265352 // clang-format off
266 __forceinline Uint32 GetCBCount() const { return (m_SRVOffset - m_CBOffset) / (sizeof(CachedCB) + sizeof(ID3D11Buffer*)); }
267 __forceinline Uint32 GetSRVCount() const { return (m_SamplerOffset - m_SRVOffset) / (sizeof(CachedResource) + sizeof(ID3D11ShaderResourceView*)); }
268 __forceinline Uint32 GetSamplerCount() const { return (m_UAVOffset - m_SamplerOffset) / (sizeof(CachedSampler) + sizeof(ID3D11SamplerState*)); }
269 __forceinline Uint32 GetUAVCount() const { return (m_MemoryEndOffset - m_UAVOffset) / (sizeof(CachedResource) + sizeof(ID3D11UnorderedAccessView*)); }
353 __forceinline Uint32 GetCBCount() const { return m_CBCount; }
354 __forceinline Uint32 GetSRVCount() const { return m_SRVCount; }
355 __forceinline Uint32 GetSamplerCount() const { return m_SamplerCount; }
356 __forceinline Uint32 GetUAVCount() const { return m_UAVCount; }
270357 // clang-format on
271358
272 __forceinline void GetCBArrays(CachedCB*& CBs, ID3D11Buffer**& pd3d11CBs)
273 {
274 CBs = reinterpret_cast<CachedCB*>(m_pResourceData + m_CBOffset);
275 pd3d11CBs = reinterpret_cast<ID3D11Buffer**>(CBs + GetCBCount());
276 }
277
278 __forceinline void GetSRVArrays(CachedResource*& SRVResources, ID3D11ShaderResourceView**& d3d11SRVs)
279 {
359 __forceinline void GetCBArrays(CachedCB*& CBs, ID3D11Buffer**& pd3d11CBs, TBindPointsAndActiveBits*& pBindPoints)
360 {
361 VERIFY(alignof(CachedCB) == alignof(ID3D11Buffer*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
362 CBs = reinterpret_cast<CachedCB*>(m_pResourceData + m_CBOffset);
363 pd3d11CBs = reinterpret_cast<ID3D11Buffer**>(CBs + GetCBCount());
364 pBindPoints = reinterpret_cast<TBindPointsAndActiveBits*>(pd3d11CBs + GetCBCount());
365 }
366
367 __forceinline void GetSRVArrays(CachedResource*& SRVResources, ID3D11ShaderResourceView**& d3d11SRVs, TBindPointsAndActiveBits*& pBindPoints)
368 {
369 VERIFY(alignof(CachedResource) == alignof(ID3D11ShaderResourceView*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
280370 SRVResources = reinterpret_cast<CachedResource*>(m_pResourceData + m_SRVOffset);
281371 d3d11SRVs = reinterpret_cast<ID3D11ShaderResourceView**>(SRVResources + GetSRVCount());
282 }
283
284 __forceinline void GetSamplerArrays(CachedSampler*& Samplers, ID3D11SamplerState**& pd3d11Samplers)
285 {
372 pBindPoints = reinterpret_cast<TBindPointsAndActiveBits*>(d3d11SRVs + GetSRVCount());
373 }
374
375 __forceinline void GetSamplerArrays(CachedSampler*& Samplers, ID3D11SamplerState**& pd3d11Samplers, TBindPointsAndActiveBits*& pBindPoints)
376 {
377 VERIFY(alignof(CachedSampler) == alignof(ID3D11SamplerState*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
286378 Samplers = reinterpret_cast<CachedSampler*>(m_pResourceData + m_SamplerOffset);
287379 pd3d11Samplers = reinterpret_cast<ID3D11SamplerState**>(Samplers + GetSamplerCount());
288 }
289
290 __forceinline void GetUAVArrays(CachedResource*& UAVResources, ID3D11UnorderedAccessView**& pd3d11UAVs)
291 {
380 pBindPoints = reinterpret_cast<TBindPointsAndActiveBits*>(pd3d11Samplers + GetSamplerCount());
381 }
382
383 __forceinline void GetUAVArrays(CachedResource*& UAVResources, ID3D11UnorderedAccessView**& pd3d11UAVs, TBindPointsAndActiveBits*& pBindPoints)
384 {
385 VERIFY(alignof(CachedResource) == alignof(ID3D11UnorderedAccessView*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
292386 UAVResources = reinterpret_cast<CachedResource*>(m_pResourceData + m_UAVOffset);
293387 pd3d11UAVs = reinterpret_cast<ID3D11UnorderedAccessView**>(UAVResources + GetUAVCount());
388 pBindPoints = reinterpret_cast<TBindPointsAndActiveBits*>(pd3d11UAVs + GetUAVCount());
389 }
390
391 __forceinline void GetConstCBArrays(CachedCB const*& CBs, ID3D11Buffer* const*& pd3d11CBs, TBindPointsAndActiveBits const*& pBindPoints) const
392 {
393 VERIFY(alignof(CachedCB) == alignof(ID3D11Buffer*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
394 CBs = reinterpret_cast<CachedCB const*>(m_pResourceData + m_CBOffset);
395 pd3d11CBs = reinterpret_cast<ID3D11Buffer* const*>(CBs + GetCBCount());
396 pBindPoints = reinterpret_cast<TBindPointsAndActiveBits const*>(pd3d11CBs + GetCBCount());
397 }
398
399 __forceinline void GetConstSRVArrays(CachedResource const*& SRVResources, ID3D11ShaderResourceView* const*& d3d11SRVs, TBindPointsAndActiveBits const*& pBindPoints) const
400 {
401 VERIFY(alignof(CachedResource) == alignof(ID3D11ShaderResourceView*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
402 SRVResources = reinterpret_cast<CachedResource const*>(m_pResourceData + m_SRVOffset);
403 d3d11SRVs = reinterpret_cast<ID3D11ShaderResourceView* const*>(SRVResources + GetSRVCount());
404 pBindPoints = reinterpret_cast<TBindPointsAndActiveBits const*>(d3d11SRVs + GetSRVCount());
405 }
406
407 __forceinline void GetConstSamplerArrays(CachedSampler const*& Samplers, ID3D11SamplerState* const*& pd3d11Samplers, TBindPointsAndActiveBits const*& pBindPoints) const
408 {
409 VERIFY(alignof(CachedSampler) == alignof(ID3D11SamplerState*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
410 Samplers = reinterpret_cast<CachedSampler const*>(m_pResourceData + m_SamplerOffset);
411 pd3d11Samplers = reinterpret_cast<ID3D11SamplerState* const*>(Samplers + GetSamplerCount());
412 pBindPoints = reinterpret_cast<TBindPointsAndActiveBits const*>(pd3d11Samplers + GetSamplerCount());
413 }
414
415 __forceinline void GetConstUAVArrays(CachedResource const*& UAVResources, ID3D11UnorderedAccessView* const*& pd3d11UAVs, TBindPointsAndActiveBits const*& pBindPoints) const
416 {
417 VERIFY(alignof(CachedResource) == alignof(ID3D11UnorderedAccessView*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
418 UAVResources = reinterpret_cast<CachedResource const*>(m_pResourceData + m_UAVOffset);
419 pd3d11UAVs = reinterpret_cast<ID3D11UnorderedAccessView* const*>(UAVResources + GetUAVCount());
420 pBindPoints = reinterpret_cast<TBindPointsAndActiveBits const*>(pd3d11UAVs + GetUAVCount());
294421 }
295422
296423 __forceinline bool IsInitialized() const
297424 {
298 return m_MemoryEndOffset != InvalidResourceOffset;
299 }
425 return m_UAVOffset != InvalidResourceOffset;
426 }
427
428 ResourceCacheContentType GetContentType() const { return m_ContentType; }
300429
301430 private:
302431 template <typename TCachedResourceType, typename TGetResourceArraysFunc, typename TSrcResourceType, typename TD3D11ResourceType>
303 __forceinline void SetD3D11ResourceInternal(Uint32 Slot, Uint32 Size, TGetResourceArraysFunc GetArrays, TSrcResourceType&& pResource, TD3D11ResourceType* pd3d11Resource)
304 {
305 VERIFY(Slot < Size, "Resource cache is not big enough");
432 __forceinline void SetD3D11ResourceInternal(Uint32 CacheOffset, Uint32 ArrayIndex, Uint32 Size, TBindPoints SrcBindPoints, TGetResourceArraysFunc GetArrays, TSrcResourceType&& pResource, TD3D11ResourceType* pd3d11Resource)
433 {
434 CacheOffset += ArrayIndex;
435
436 TBindPointsAndActiveBits BindPointsAndActiveBits;
437 auto& ActiveBits = BindPointsAndActiveBits[0];
438 auto* BindPoints = &BindPointsAndActiveBits[1];
439
440 ActiveBits = 0;
441 for (Uint32 i = 0; i < SrcBindPoints.size(); ++i)
442 {
443 if (SrcBindPoints[i] != InvalidBindPoint)
444 {
445 auto BindPoint = SrcBindPoints[i] + ArrayIndex;
446 VERIFY_EXPR(BindPoint < InvalidBindPoint);
447 BindPoints[i] = static_cast<Uint8>(BindPoint);
448 ActiveBits |= static_cast<Uint8>(1u << i);
449 }
450 else
451 {
452 BindPoints[i] = InvalidBindPoint;
453 }
454 }
455
456 VERIFY(CacheOffset < Size, "Resource cache is not big enough");
306457 VERIFY(pResource != nullptr && pd3d11Resource != nullptr || pResource == nullptr && pd3d11Resource == nullptr,
307458 "Resource and D3D11 resource must be set/unset atomically");
308 TCachedResourceType* Resources;
309 TD3D11ResourceType** d3d11ResArr;
310 (this->*GetArrays)(Resources, d3d11ResArr);
311 Resources[Slot].Set(std::forward<TSrcResourceType>(pResource));
312 d3d11ResArr[Slot] = pd3d11Resource;
313 }
314
315 static constexpr const Uint16 InvalidResourceOffset = 0xFFFF;
316 // Resource limits in D3D11:
317 // Max CB count: 14
318 // Max SRV count: 128
319 // Max Sampler count: 16
320 // Max UAV count: 8
321 static constexpr const Uint16 m_CBOffset = 0;
322 Uint16 m_SRVOffset = InvalidResourceOffset;
323 Uint16 m_SamplerOffset = InvalidResourceOffset;
324 Uint16 m_UAVOffset = InvalidResourceOffset;
325 Uint16 m_MemoryEndOffset = InvalidResourceOffset;
326
327 Uint8* m_pResourceData = nullptr;
328
329 #ifdef DILIGENT_DEBUG
330 IMemoryAllocator* m_pdbgMemoryAllocator = nullptr;
459 TCachedResourceType* Resources;
460 TD3D11ResourceType** d3d11ResArr;
461 TBindPointsAndActiveBits* bindPoints;
462 (this->*GetArrays)(Resources, d3d11ResArr, bindPoints);
463 Resources[CacheOffset].Set(std::forward<TSrcResourceType>(pResource));
464 bindPoints[CacheOffset] = BindPointsAndActiveBits;
465 d3d11ResArr[CacheOffset] = pd3d11Resource;
466 }
467
468 template <typename THandleResource>
469 void ProcessResources(THandleResource HandleResource);
470
471 // Transitions resource to the shader resource state required by Type member.
472 __forceinline void TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedCB* CBs, ID3D11Buffer** pd3d11CBs);
473 __forceinline void TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedResource* SRVResources, ID3D11ShaderResourceView** d3d11SRVs);
474 __forceinline void TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedSampler* Samplers, ID3D11SamplerState** pd3d11Samplers);
475 __forceinline void TransitionResource(DeviceContextD3D11Impl& Ctx, Uint32 Count, CachedResource* UAVResources, ID3D11UnorderedAccessView** pd3d11UAVs);
476
477 #ifdef DILIGENT_DEVELOPMENT
478 // Verifies that resource is in correct shader resource state required by Type member.
479 void DvpVerifyResourceState(DeviceContextD3D11Impl& Ctx, Uint32 Count, const CachedCB* CBs, ID3D11Buffer**);
480 void DvpVerifyResourceState(DeviceContextD3D11Impl& Ctx, Uint32 Count, const CachedResource* SRVResources, ID3D11ShaderResourceView**);
481 void DvpVerifyResourceState(DeviceContextD3D11Impl& Ctx, Uint32 Count, const CachedSampler* Samplers, ID3D11SamplerState**);
482 void DvpVerifyResourceState(DeviceContextD3D11Impl& Ctx, Uint32 Count, const CachedResource* UAVResources, ID3D11UnorderedAccessView**);
331483 #endif
484
485 private:
486 using OffsetType = Uint16;
487
488 static constexpr size_t MaxAlignment = std::max(std::max(std::max(alignof(CachedCB), alignof(CachedResource)),
489 std::max(alignof(CachedSampler), alignof(TBindPoints))),
490 std::max(std::max(alignof(ID3D11Buffer*), alignof(ID3D11ShaderResourceView*)),
491 std::max(alignof(ID3D11SamplerState*), alignof(ID3D11UnorderedAccessView*))));
492
493 static constexpr OffsetType InvalidResourceOffset = std::numeric_limits<OffsetType>::max();
494
495 static constexpr OffsetType m_CBOffset = 0;
496 OffsetType m_SRVOffset = InvalidResourceOffset;
497 OffsetType m_SamplerOffset = InvalidResourceOffset;
498 OffsetType m_UAVOffset = InvalidResourceOffset;
499
500 static constexpr Uint32 _CBCountBits = 7;
501 static constexpr Uint32 _SVCountBits = 10;
502 static constexpr Uint32 _SampCountBits = 7;
503 static constexpr Uint32 _UAVCountBits = 4;
504
505 // clang-format off
506 static_assert((1U << _CBCountBits) >= (D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT * NumShaderTypes), "Number of constant buffers is too small");
507 static_assert((1U << _SVCountBits) >= (D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT * NumShaderTypes), "Number of shader resources is too small");
508 static_assert((1U << _SampCountBits) >= (D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT * NumShaderTypes), "Number of samplers is too small");
509 static_assert((1U << _UAVCountBits) >= D3D11_PS_CS_UAV_REGISTER_COUNT, "Number of UAVs is too small");
510
511 Uint32 m_CBCount : _CBCountBits;
512 Uint32 m_SRVCount : _SVCountBits;
513 Uint32 m_SamplerCount : _SampCountBits;
514 Uint32 m_UAVCount : _UAVCountBits;
515 // clang-format on
516
517 // Indicates what types of resources are stored in the cache
518 const ResourceCacheContentType m_ContentType;
519
520 Uint8* m_pResourceData = nullptr;
521 IMemoryAllocator* m_pAllocator = nullptr;
332522 };
333523
334524 } // namespace Diligent
+0
-430
Graphics/GraphicsEngineD3D11/include/ShaderResourceLayoutD3D11.hpp less more
0 /*
1 * Copyright 2019-2021 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #pragma once
28
29 /// \file
30 /// Declaration of Diligent::ShaderResourceLayoutD3D11 class
31
32 #include "ShaderResources.hpp"
33 #include "ShaderBase.hpp"
34 #include "ShaderResourceCacheD3D11.hpp"
35 #include "EngineD3D11Defines.h"
36 #include "STDAllocator.hpp"
37 #include "ShaderVariableD3DBase.hpp"
38 #include "ShaderResourcesD3D11.hpp"
39
40 namespace Diligent
41 {
42
43 /// Diligent::ShaderResourceLayoutD3D11 class
44 /// http://diligentgraphics.com/diligent-engine/architecture/d3d11/shader-resource-layout/
45 // sizeof(ShaderResourceLayoutD3D11) == 64 (x64)
46 class ShaderResourceLayoutD3D11
47 {
48 public:
49 ShaderResourceLayoutD3D11(IObject& Owner,
50 ShaderResourceCacheD3D11& ResourceCache) noexcept :
51 m_Owner{Owner},
52 m_ResourceCache{ResourceCache}
53 {
54 }
55
56 void Initialize(std::shared_ptr<const ShaderResourcesD3D11> pSrcResources,
57 const PipelineResourceLayoutDesc& ResourceLayout,
58 const SHADER_RESOURCE_VARIABLE_TYPE* VarTypes,
59 Uint32 NumVarTypes,
60 IMemoryAllocator& ResCacheDataAllocator,
61 IMemoryAllocator& ResLayoutDataAllocator);
62 ~ShaderResourceLayoutD3D11();
63
64 // clang-format off
65 // No copies, only moves are allowed
66 ShaderResourceLayoutD3D11 (const ShaderResourceLayoutD3D11&) = delete;
67 ShaderResourceLayoutD3D11& operator = (const ShaderResourceLayoutD3D11&) = delete;
68 ShaderResourceLayoutD3D11 ( ShaderResourceLayoutD3D11&&) = default;
69 ShaderResourceLayoutD3D11& operator = ( ShaderResourceLayoutD3D11&&) = delete;
70 // clang-format on
71
72 static size_t GetRequiredMemorySize(const ShaderResourcesD3D11& SrcResources,
73 const PipelineResourceLayoutDesc& ResourceLayout,
74 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
75 Uint32 NumAllowedTypes) noexcept;
76
77 void CopyResources(ShaderResourceCacheD3D11& DstCache) const;
78
79 using ShaderVariableD3D11Base = ShaderVariableD3DBase<ShaderResourceLayoutD3D11>;
80
81 struct ConstBuffBindInfo final : ShaderVariableD3D11Base
82 {
83 ConstBuffBindInfo(const D3DShaderResourceAttribs& ResourceAttribs,
84 ShaderResourceLayoutD3D11& ParentResLayout,
85 SHADER_RESOURCE_VARIABLE_TYPE VariableType) :
86 ShaderVariableD3D11Base{ParentResLayout, ResourceAttribs, VariableType}
87 {}
88 // Non-virtual function
89 __forceinline void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
90
91 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final { BindResource(pObject, 0); }
92
93 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
94 Uint32 FirstElement,
95 Uint32 NumElements) override final
96 {
97 VerifyAndCorrectSetArrayArguments(m_Attribs.Name, m_Attribs.BindCount, FirstElement, NumElements);
98 for (Uint32 elem = 0; elem < NumElements; ++elem)
99 BindResource(ppObjects[elem], FirstElement + elem);
100 }
101
102 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
103 {
104 VERIFY_EXPR(ArrayIndex < m_Attribs.BindCount);
105 return m_ParentResLayout.m_ResourceCache.IsCBBound(m_Attribs.BindPoint + ArrayIndex);
106 }
107 };
108
109 struct TexSRVBindInfo final : ShaderVariableD3D11Base
110 {
111 TexSRVBindInfo(const D3DShaderResourceAttribs& _TextureAttribs,
112 Uint32 _SamplerIndex,
113 ShaderResourceLayoutD3D11& ParentResLayout,
114 SHADER_RESOURCE_VARIABLE_TYPE VariableType) :
115 ShaderVariableD3D11Base{ParentResLayout, _TextureAttribs, VariableType},
116 SamplerIndex{_SamplerIndex}
117 {}
118
119 // Non-virtual function
120 __forceinline void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
121
122 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final { BindResource(pObject, 0); }
123
124 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
125 Uint32 FirstElement,
126 Uint32 NumElements) override final
127 {
128 VerifyAndCorrectSetArrayArguments(m_Attribs.Name, m_Attribs.BindCount, FirstElement, NumElements);
129 for (Uint32 elem = 0; elem < NumElements; ++elem)
130 BindResource(ppObjects[elem], FirstElement + elem);
131 }
132
133 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
134 {
135 VERIFY_EXPR(ArrayIndex < m_Attribs.BindCount);
136 return m_ParentResLayout.m_ResourceCache.IsSRVBound(m_Attribs.BindPoint + ArrayIndex, true);
137 }
138
139
140 bool ValidSamplerAssigned() const { return SamplerIndex != InvalidSamplerIndex; }
141
142 static constexpr Uint32 InvalidSamplerIndex = static_cast<Uint32>(-1);
143 const Uint32 SamplerIndex;
144 };
145
146 struct TexUAVBindInfo final : ShaderVariableD3D11Base
147 {
148 TexUAVBindInfo(const D3DShaderResourceAttribs& ResourceAttribs,
149 ShaderResourceLayoutD3D11& ParentResLayout,
150 SHADER_RESOURCE_VARIABLE_TYPE VariableType) :
151 ShaderVariableD3D11Base(ParentResLayout, ResourceAttribs, VariableType)
152 {}
153
154 // Provide non-virtual function
155 __forceinline void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
156
157 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final { BindResource(pObject, 0); }
158
159 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
160 Uint32 FirstElement,
161 Uint32 NumElements) override final
162 {
163 VerifyAndCorrectSetArrayArguments(m_Attribs.Name, m_Attribs.BindCount, FirstElement, NumElements);
164 for (Uint32 elem = 0; elem < NumElements; ++elem)
165 BindResource(ppObjects[elem], FirstElement + elem);
166 }
167
168 __forceinline virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
169 {
170 VERIFY_EXPR(ArrayIndex < m_Attribs.BindCount);
171 return m_ParentResLayout.m_ResourceCache.IsUAVBound(m_Attribs.BindPoint + ArrayIndex, true);
172 }
173 };
174
175 struct BuffUAVBindInfo final : ShaderVariableD3D11Base
176 {
177 BuffUAVBindInfo(const D3DShaderResourceAttribs& ResourceAttribs,
178 ShaderResourceLayoutD3D11& ParentResLayout,
179 SHADER_RESOURCE_VARIABLE_TYPE VariableType) :
180 ShaderVariableD3D11Base{ParentResLayout, ResourceAttribs, VariableType}
181 {}
182
183 // Non-virtual function
184 __forceinline void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
185
186 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final { BindResource(pObject, 0); }
187
188 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
189 Uint32 FirstElement,
190 Uint32 NumElements) override final
191 {
192 VerifyAndCorrectSetArrayArguments(m_Attribs.Name, m_Attribs.BindCount, FirstElement, NumElements);
193 for (Uint32 elem = 0; elem < NumElements; ++elem)
194 BindResource(ppObjects[elem], FirstElement + elem);
195 }
196
197 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
198 {
199 VERIFY_EXPR(ArrayIndex < m_Attribs.BindCount);
200 return m_ParentResLayout.m_ResourceCache.IsUAVBound(m_Attribs.BindPoint + ArrayIndex, false);
201 }
202 };
203
204 struct BuffSRVBindInfo final : ShaderVariableD3D11Base
205 {
206 BuffSRVBindInfo(const D3DShaderResourceAttribs& ResourceAttribs,
207 ShaderResourceLayoutD3D11& ParentResLayout,
208 SHADER_RESOURCE_VARIABLE_TYPE VariableType) :
209 ShaderVariableD3D11Base{ParentResLayout, ResourceAttribs, VariableType}
210 {}
211
212 // Non-virtual function
213 __forceinline void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
214
215 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final { BindResource(pObject, 0); }
216
217 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
218 Uint32 FirstElement,
219 Uint32 NumElements) override final
220 {
221 VerifyAndCorrectSetArrayArguments(m_Attribs.Name, m_Attribs.BindCount, FirstElement, NumElements);
222 for (Uint32 elem = 0; elem < NumElements; ++elem)
223 BindResource(ppObjects[elem], FirstElement + elem);
224 }
225
226 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
227 {
228 VERIFY_EXPR(ArrayIndex < m_Attribs.BindCount);
229 return m_ParentResLayout.m_ResourceCache.IsSRVBound(m_Attribs.BindPoint + ArrayIndex, false);
230 }
231 };
232
233 struct SamplerBindInfo final : ShaderVariableD3D11Base
234 {
235 SamplerBindInfo(const D3DShaderResourceAttribs& ResourceAttribs,
236 ShaderResourceLayoutD3D11& ParentResLayout,
237 SHADER_RESOURCE_VARIABLE_TYPE VariableType) :
238 ShaderVariableD3D11Base{ParentResLayout, ResourceAttribs, VariableType}
239 {}
240
241 // Non-virtual function
242 __forceinline void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
243
244 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final { BindResource(pObject, 0); }
245
246 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
247 Uint32 FirstElement,
248 Uint32 NumElements) override final
249 {
250 VerifyAndCorrectSetArrayArguments(m_Attribs.Name, m_Attribs.BindCount, FirstElement, NumElements);
251 for (Uint32 elem = 0; elem < NumElements; ++elem)
252 BindResource(ppObjects[elem], FirstElement + elem);
253 }
254
255 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
256 {
257 VERIFY_EXPR(ArrayIndex < m_Attribs.BindCount);
258 return m_ParentResLayout.m_ResourceCache.IsSamplerBound(m_Attribs.BindPoint + ArrayIndex);
259 }
260 };
261
262 // dbgResourceCache is only used for sanity check and as a remainder that the resource cache must be alive
263 // while Layout is alive
264 void BindResources(IResourceMapping* pResourceMapping, Uint32 Flags, const ShaderResourceCacheD3D11& dbgResourceCache);
265
266 #ifdef DILIGENT_DEVELOPMENT
267 bool dvpVerifyBindings() const;
268 #endif
269
270 IShaderResourceVariable* GetShaderVariable(const Char* Name);
271 IShaderResourceVariable* GetShaderVariable(Uint32 Index);
272 __forceinline SHADER_TYPE GetShaderType() const { return m_pResources->GetShaderType(); }
273
274 IObject& GetOwner() { return m_Owner; }
275
276 Uint32 GetVariableIndex(const ShaderVariableD3D11Base& Variable) const;
277 Uint32 GetTotalResourceCount() const
278 {
279 auto ResourceCount = GetNumCBs() + GetNumTexSRVs() + GetNumTexUAVs() + GetNumBufUAVs() + GetNumBufSRVs();
280 // Do not expose sampler variables when using combined texture samplers
281 if (!m_pResources->IsUsingCombinedTextureSamplers())
282 ResourceCount += GetNumSamplers();
283 return ResourceCount;
284 }
285
286 // clang-format off
287 Uint32 GetNumCBs() const { return (m_TexSRVsOffset - 0 ) / sizeof(ConstBuffBindInfo);}
288 Uint32 GetNumTexSRVs() const { return (m_TexUAVsOffset - m_TexSRVsOffset ) / sizeof(TexSRVBindInfo); }
289 Uint32 GetNumTexUAVs() const { return (m_BuffSRVsOffset - m_TexUAVsOffset ) / sizeof(TexUAVBindInfo) ; }
290 Uint32 GetNumBufSRVs() const { return (m_BuffUAVsOffset - m_BuffSRVsOffset) / sizeof(BuffSRVBindInfo); }
291 Uint32 GetNumBufUAVs() const { return (m_SamplerOffset - m_BuffUAVsOffset) / sizeof(BuffUAVBindInfo); }
292 Uint32 GetNumSamplers() const { return (m_MemorySize - m_SamplerOffset ) / sizeof(SamplerBindInfo); }
293
294 template<typename ResourceType> Uint32 GetNumResources()const;
295 template<> Uint32 GetNumResources<ConstBuffBindInfo>() const { return GetNumCBs(); }
296 template<> Uint32 GetNumResources<TexSRVBindInfo> () const { return GetNumTexSRVs(); }
297 template<> Uint32 GetNumResources<TexUAVBindInfo> () const { return GetNumTexUAVs(); }
298 template<> Uint32 GetNumResources<BuffSRVBindInfo> () const { return GetNumBufSRVs(); }
299 template<> Uint32 GetNumResources<BuffUAVBindInfo> () const { return GetNumBufUAVs(); }
300 template<> Uint32 GetNumResources<SamplerBindInfo> () const { return GetNumSamplers(); }
301 // clang-format on
302
303 const Char* GetShaderName() const
304 {
305 return m_pResources->GetShaderName();
306 }
307
308 private:
309 // clang-format off
310
311 /* 0 */ IObject& m_Owner;
312 /* 8 */ std::shared_ptr<const ShaderResourcesD3D11> m_pResources;
313
314 // No need to use shared pointer, as the resource cache is either part of the same
315 // ShaderD3D11Impl object, or ShaderResourceBindingD3D11Impl object
316 /*24*/ ShaderResourceCacheD3D11& m_ResourceCache;
317
318 /*32*/ std::unique_ptr<void, STDDeleterRawMem<void> > m_ResourceBuffer;
319
320 // Offsets in bytes
321 using OffsetType = Uint16;
322 /*48*/ OffsetType m_TexSRVsOffset = 0;
323 /*50*/ OffsetType m_TexUAVsOffset = 0;
324 /*52*/ OffsetType m_BuffSRVsOffset = 0;
325 /*54*/ OffsetType m_BuffUAVsOffset = 0;
326 /*56*/ OffsetType m_SamplerOffset = 0;
327 /*58*/ OffsetType m_MemorySize = 0;
328 /*60 - 64*/
329 /*64*/ // End of data
330
331
332 template<typename ResourceType> OffsetType GetResourceOffset()const;
333 template<> OffsetType GetResourceOffset<ConstBuffBindInfo>() const { return 0; }
334 template<> OffsetType GetResourceOffset<TexSRVBindInfo> () const { return m_TexSRVsOffset; }
335 template<> OffsetType GetResourceOffset<TexUAVBindInfo> () const { return m_TexUAVsOffset; }
336 template<> OffsetType GetResourceOffset<BuffSRVBindInfo> () const { return m_BuffSRVsOffset; }
337 template<> OffsetType GetResourceOffset<BuffUAVBindInfo> () const { return m_BuffUAVsOffset; }
338 template<> OffsetType GetResourceOffset<SamplerBindInfo> () const { return m_SamplerOffset; }
339
340 // clang-format on
341
342 template <typename ResourceType>
343 ResourceType& GetResource(Uint32 ResIndex)
344 {
345 VERIFY(ResIndex < GetNumResources<ResourceType>(), "Resource index (", ResIndex, ") exceeds max allowed value (", GetNumResources<ResourceType>() - 1, ")");
346 auto Offset = GetResourceOffset<ResourceType>();
347 return reinterpret_cast<ResourceType*>(reinterpret_cast<Uint8*>(m_ResourceBuffer.get()) + Offset)[ResIndex];
348 }
349
350 template <typename ResourceType>
351 const ResourceType& GetConstResource(Uint32 ResIndex) const
352 {
353 VERIFY(ResIndex < GetNumResources<ResourceType>(), "Resource index (", ResIndex, ") exceeds max allowed value (", GetNumResources<ResourceType>() - 1, ")");
354 auto Offset = GetResourceOffset<ResourceType>();
355 return reinterpret_cast<const ResourceType*>(reinterpret_cast<const Uint8*>(m_ResourceBuffer.get()) + Offset)[ResIndex];
356 }
357
358 template <typename ResourceType>
359 IShaderResourceVariable* GetResourceByName(const Char* Name);
360
361 template <typename THandleCB,
362 typename THandleTexSRV,
363 typename THandleTexUAV,
364 typename THandleBufSRV,
365 typename THandleBufUAV,
366 typename THandleSampler>
367 void HandleResources(THandleCB HandleCB,
368 THandleTexSRV HandleTexSRV,
369 THandleTexUAV HandleTexUAV,
370 THandleBufSRV HandleBufSRV,
371 THandleBufUAV HandleBufUAV,
372 THandleSampler HandleSampler)
373 {
374 for (Uint32 cb = 0; cb < GetNumResources<ConstBuffBindInfo>(); ++cb)
375 HandleCB(GetResource<ConstBuffBindInfo>(cb));
376
377 for (Uint32 t = 0; t < GetNumResources<TexSRVBindInfo>(); ++t)
378 HandleTexSRV(GetResource<TexSRVBindInfo>(t));
379
380 for (Uint32 u = 0; u < GetNumResources<TexUAVBindInfo>(); ++u)
381 HandleTexUAV(GetResource<TexUAVBindInfo>(u));
382
383 for (Uint32 s = 0; s < GetNumResources<BuffSRVBindInfo>(); ++s)
384 HandleBufSRV(GetResource<BuffSRVBindInfo>(s));
385
386 for (Uint32 u = 0; u < GetNumResources<BuffUAVBindInfo>(); ++u)
387 HandleBufUAV(GetResource<BuffUAVBindInfo>(u));
388
389 for (Uint32 s = 0; s < GetNumResources<SamplerBindInfo>(); ++s)
390 HandleSampler(GetResource<SamplerBindInfo>(s));
391 }
392
393 template <typename THandleCB,
394 typename THandleTexSRV,
395 typename THandleTexUAV,
396 typename THandleBufSRV,
397 typename THandleBufUAV,
398 typename THandleSampler>
399 void HandleConstResources(THandleCB HandleCB,
400 THandleTexSRV HandleTexSRV,
401 THandleTexUAV HandleTexUAV,
402 THandleBufSRV HandleBufSRV,
403 THandleBufUAV HandleBufUAV,
404 THandleSampler HandleSampler) const
405 {
406 for (Uint32 cb = 0; cb < GetNumResources<ConstBuffBindInfo>(); ++cb)
407 HandleCB(GetConstResource<ConstBuffBindInfo>(cb));
408
409 for (Uint32 t = 0; t < GetNumResources<TexSRVBindInfo>(); ++t)
410 HandleTexSRV(GetConstResource<TexSRVBindInfo>(t));
411
412 for (Uint32 u = 0; u < GetNumResources<TexUAVBindInfo>(); ++u)
413 HandleTexUAV(GetConstResource<TexUAVBindInfo>(u));
414
415 for (Uint32 s = 0; s < GetNumResources<BuffSRVBindInfo>(); ++s)
416 HandleBufSRV(GetConstResource<BuffSRVBindInfo>(s));
417
418 for (Uint32 u = 0; u < GetNumResources<BuffUAVBindInfo>(); ++u)
419 HandleBufUAV(GetConstResource<BuffUAVBindInfo>(u));
420
421 for (Uint32 s = 0; s < GetNumResources<SamplerBindInfo>(); ++s)
422 HandleSampler(GetConstResource<SamplerBindInfo>(s));
423 }
424
425 friend class ShaderVariableIndexLocator;
426 friend class ShaderVariableLocator;
427 };
428
429 } // namespace Diligent
0 /*
1 * Copyright 2019-2021 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #pragma once
28
29 /// \file
30 /// Declaration of Diligent::ShaderVariableManagerD3D11 class
31
32 #include "ShaderResources.hpp"
33 #include "ShaderBase.hpp"
34 #include "ShaderResourceVariableBase.hpp"
35 #include "ShaderVariableD3D.hpp"
36 #include "ShaderResourcesD3D11.hpp"
37 #include "ShaderResourceVariableD3D.h"
38 #include "PipelineResourceAttribsD3D11.hpp"
39 #include "ShaderResourceCacheD3D11.hpp"
40
41 namespace Diligent
42 {
43
44 /// Diligent::ShaderVariableManagerD3D11 class
45 // sizeof(ShaderVariableManagerD3D11) == AZ TODO (Release, x64)
46 class ShaderVariableManagerD3D11
47 {
48 public:
49 ShaderVariableManagerD3D11(IObject& Owner,
50 ShaderResourceCacheD3D11& ResourceCache) noexcept :
51 m_Owner{Owner},
52 m_ResourceCache{ResourceCache}
53 {
54 }
55
56 ~ShaderVariableManagerD3D11();
57
58 void Destroy(IMemoryAllocator& Allocator);
59
60 // clang-format off
61 // No copies, only moves are allowed
62 ShaderVariableManagerD3D11 (const ShaderVariableManagerD3D11&) = delete;
63 ShaderVariableManagerD3D11& operator = (const ShaderVariableManagerD3D11&) = delete;
64 ShaderVariableManagerD3D11 ( ShaderVariableManagerD3D11&&) = default;
65 ShaderVariableManagerD3D11& operator = ( ShaderVariableManagerD3D11&&) = delete;
66 // clang-format on
67
68 void Initialize(const PipelineResourceSignatureD3D11Impl& Signature,
69 IMemoryAllocator& Allocator,
70 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
71 Uint32 NumAllowedTypes,
72 SHADER_TYPE ShaderType);
73
74 static size_t GetRequiredMemorySize(const PipelineResourceSignatureD3D11Impl& Signature,
75 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
76 Uint32 NumAllowedTypes,
77 SHADER_TYPE ShaderType);
78
79 using ResourceAttribs = PipelineResourceAttribsD3D11;
80
81 const PipelineResourceDesc& GetResourceDesc(Uint32 Index) const;
82 const ResourceAttribs& GetAttribs(Uint32 Index) const;
83
84
85 struct ShaderVariableD3D11Base : ShaderVariableBase<ShaderVariableManagerD3D11, IShaderResourceVariableD3D>
86 {
87 public:
88 ShaderVariableD3D11Base(ShaderVariableManagerD3D11& ParentLayout, Uint32 ResIndex) :
89 ShaderVariableBase<ShaderVariableManagerD3D11, IShaderResourceVariableD3D>{ParentLayout},
90 m_ResIndex{ResIndex}
91 {}
92
93 // clang-format off
94 ShaderVariableD3D11Base (const ShaderVariableD3D11Base&) = delete;
95 ShaderVariableD3D11Base ( ShaderVariableD3D11Base&&) = delete;
96 ShaderVariableD3D11Base& operator= (const ShaderVariableD3D11Base&) = delete;
97 ShaderVariableD3D11Base& operator= ( ShaderVariableD3D11Base&&) = delete;
98 // clang-format on
99
100 const PipelineResourceDesc& GetDesc() const { return m_ParentManager.GetResourceDesc(m_ResIndex); }
101 const ResourceAttribs& GetAttribs() const { return m_ParentManager.GetAttribs(m_ResIndex); }
102
103 virtual void DILIGENT_CALL_TYPE QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final
104 {
105 if (ppInterface == nullptr)
106 return;
107
108 *ppInterface = nullptr;
109 if (IID == IID_ShaderResourceVariableD3D || IID == IID_ShaderResourceVariable || IID == IID_Unknown)
110 {
111 *ppInterface = this;
112 (*ppInterface)->AddRef();
113 }
114 }
115
116 virtual SHADER_RESOURCE_VARIABLE_TYPE DILIGENT_CALL_TYPE GetType() const override final
117 {
118 return GetDesc().VarType;
119 }
120
121 virtual void DILIGENT_CALL_TYPE GetResourceDesc(ShaderResourceDesc& ResourceDesc) const override final
122 {
123 const auto& Desc = GetDesc();
124 ResourceDesc.Name = Desc.Name;
125 ResourceDesc.Type = Desc.ResourceType;
126 ResourceDesc.ArraySize = Desc.ArraySize;
127 }
128
129 virtual Uint32 DILIGENT_CALL_TYPE GetIndex() const override final
130 {
131 return m_ParentManager.GetVariableIndex(*this);
132 }
133
134 virtual void DILIGENT_CALL_TYPE GetHLSLResourceDesc(HLSLShaderResourceDesc& HLSLResDesc) const override final
135 {
136 // AZ TODO
137 }
138
139 private:
140 const Uint32 m_ResIndex;
141 };
142
143 struct ConstBuffBindInfo final : ShaderVariableD3D11Base
144 {
145 ConstBuffBindInfo(ShaderVariableManagerD3D11& ParentLayout, Uint32 ResIndex) :
146 ShaderVariableD3D11Base{ParentLayout, ResIndex}
147 {}
148
149 // Non-virtual function
150 __forceinline void BindResource(IDeviceObject* pObj, Uint32 ArrayIndex);
151
152 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
153 {
154 BindResource(pObject, 0);
155 }
156
157 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
158 Uint32 FirstElement,
159 Uint32 NumElements) override final
160 {
161 const auto& Desc = GetDesc();
162 VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
163 for (Uint32 elem = 0; elem < NumElements; ++elem)
164 BindResource(ppObjects[elem], FirstElement + elem);
165 }
166
167 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
168 {
169 VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
170 return m_ParentManager.m_ResourceCache.IsCBBound(GetAttribs().CacheOffset + ArrayIndex);
171 }
172 };
173
174 struct TexSRVBindInfo final : ShaderVariableD3D11Base
175 {
176 TexSRVBindInfo(ShaderVariableManagerD3D11& ParentLayout, Uint32 ResIndex) :
177 ShaderVariableD3D11Base{ParentLayout, ResIndex}
178 {}
179
180 // Non-virtual function
181 __forceinline void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
182
183 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
184 {
185 BindResource(pObject, 0);
186 }
187
188 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
189 Uint32 FirstElement,
190 Uint32 NumElements) override final
191 {
192 const auto& Desc = GetDesc();
193 VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
194 for (Uint32 elem = 0; elem < NumElements; ++elem)
195 BindResource(ppObjects[elem], FirstElement + elem);
196 }
197
198 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
199 {
200 VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
201 return m_ParentManager.m_ResourceCache.IsSRVBound(GetAttribs().CacheOffset + ArrayIndex, true);
202 }
203 };
204
205 struct TexUAVBindInfo final : ShaderVariableD3D11Base
206 {
207 TexUAVBindInfo(ShaderVariableManagerD3D11& ParentLayout, Uint32 ResIndex) :
208 ShaderVariableD3D11Base{ParentLayout, ResIndex}
209 {}
210
211 // Provide non-virtual function
212 __forceinline void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
213
214 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
215 {
216 BindResource(pObject, 0);
217 }
218
219 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
220 Uint32 FirstElement,
221 Uint32 NumElements) override final
222 {
223 const auto& Desc = GetDesc();
224 VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
225 for (Uint32 elem = 0; elem < NumElements; ++elem)
226 BindResource(ppObjects[elem], FirstElement + elem);
227 }
228
229 __forceinline virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
230 {
231 VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
232 return m_ParentManager.m_ResourceCache.IsUAVBound(GetAttribs().CacheOffset + ArrayIndex, true);
233 }
234 };
235
236 struct BuffUAVBindInfo final : ShaderVariableD3D11Base
237 {
238 BuffUAVBindInfo(ShaderVariableManagerD3D11& ParentLayout, Uint32 ResIndex) :
239 ShaderVariableD3D11Base{ParentLayout, ResIndex}
240 {}
241
242 // Non-virtual function
243 __forceinline void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
244
245 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
246 {
247 BindResource(pObject, 0);
248 }
249
250 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
251 Uint32 FirstElement,
252 Uint32 NumElements) override final
253 {
254 const auto& Desc = GetDesc();
255 VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
256 for (Uint32 elem = 0; elem < NumElements; ++elem)
257 BindResource(ppObjects[elem], FirstElement + elem);
258 }
259
260 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
261 {
262 VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
263 return m_ParentManager.m_ResourceCache.IsUAVBound(GetAttribs().CacheOffset + ArrayIndex, false);
264 }
265 };
266
267 struct BuffSRVBindInfo final : ShaderVariableD3D11Base
268 {
269 BuffSRVBindInfo(ShaderVariableManagerD3D11& ParentLayout, Uint32 ResIndex) :
270 ShaderVariableD3D11Base{ParentLayout, ResIndex}
271 {}
272
273 // Non-virtual function
274 __forceinline void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
275
276 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
277 {
278 BindResource(pObject, 0);
279 }
280
281 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
282 Uint32 FirstElement,
283 Uint32 NumElements) override final
284 {
285 const auto& Desc = GetDesc();
286 VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
287 for (Uint32 elem = 0; elem < NumElements; ++elem)
288 BindResource(ppObjects[elem], FirstElement + elem);
289 }
290
291 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
292 {
293 VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
294 return m_ParentManager.m_ResourceCache.IsSRVBound(GetAttribs().CacheOffset + ArrayIndex, false);
295 }
296 };
297
298 struct SamplerBindInfo final : ShaderVariableD3D11Base
299 {
300 SamplerBindInfo(ShaderVariableManagerD3D11& ParentLayout, Uint32 ResIndex) :
301 ShaderVariableD3D11Base{ParentLayout, ResIndex}
302 {}
303
304 // Non-virtual function
305 __forceinline void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex);
306
307 virtual void DILIGENT_CALL_TYPE Set(IDeviceObject* pObject) override final
308 {
309 BindResource(pObject, 0);
310 }
311
312 virtual void DILIGENT_CALL_TYPE SetArray(IDeviceObject* const* ppObjects,
313 Uint32 FirstElement,
314 Uint32 NumElements) override final
315 {
316 const auto& Desc = GetDesc();
317 VerifyAndCorrectSetArrayArguments(Desc.Name, Desc.ArraySize, FirstElement, NumElements);
318 for (Uint32 elem = 0; elem < NumElements; ++elem)
319 BindResource(ppObjects[elem], FirstElement + elem);
320 }
321
322 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
323 {
324 VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
325 return m_ParentManager.m_ResourceCache.IsSamplerBound(GetAttribs().CacheOffset + ArrayIndex);
326 }
327 };
328
329 void BindResources(IResourceMapping* pResourceMapping, Uint32 Flags);
330
331 #ifdef DILIGENT_DEVELOPMENT
332 bool dvpVerifyBindings() const;
333 #endif
334
335 IShaderResourceVariable* GetVariable(const Char* Name) const;
336 IShaderResourceVariable* GetVariable(Uint32 Index) const;
337
338 IObject& GetOwner() { return m_Owner; }
339
340 Uint32 GetVariableCount() const;
341
342 Uint32 GetVariableIndex(const ShaderVariableD3D11Base& Variable) const;
343
344 // clang-format off
345 Uint32 GetNumCBs() const { return (m_TexSRVsOffset - 0 ) / sizeof(ConstBuffBindInfo);}
346 Uint32 GetNumTexSRVs() const { return (m_TexUAVsOffset - m_TexSRVsOffset ) / sizeof(TexSRVBindInfo); }
347 Uint32 GetNumTexUAVs() const { return (m_BuffSRVsOffset - m_TexUAVsOffset ) / sizeof(TexUAVBindInfo) ; }
348 Uint32 GetNumBufSRVs() const { return (m_BuffUAVsOffset - m_BuffSRVsOffset) / sizeof(BuffSRVBindInfo); }
349 Uint32 GetNumBufUAVs() const { return (m_SamplerOffset - m_BuffUAVsOffset) / sizeof(BuffUAVBindInfo); }
350 Uint32 GetNumSamplers() const { return (m_MemorySize - m_SamplerOffset ) / sizeof(SamplerBindInfo); }
351
352 template<typename ResourceType> Uint32 GetNumResources()const;
353 template<> Uint32 GetNumResources<ConstBuffBindInfo>() const { return GetNumCBs(); }
354 template<> Uint32 GetNumResources<TexSRVBindInfo> () const { return GetNumTexSRVs(); }
355 template<> Uint32 GetNumResources<TexUAVBindInfo> () const { return GetNumTexUAVs(); }
356 template<> Uint32 GetNumResources<BuffSRVBindInfo> () const { return GetNumBufSRVs(); }
357 template<> Uint32 GetNumResources<BuffUAVBindInfo> () const { return GetNumBufUAVs(); }
358 template<> Uint32 GetNumResources<SamplerBindInfo> () const { return GetNumSamplers(); }
359 // clang-format on
360
361 private:
362 static void CountResources(const PipelineResourceSignatureD3D11Impl& Signature,
363 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
364 Uint32 NumAllowedTypes,
365 SHADER_TYPE ShaderType,
366 D3DShaderResourceCounters& Counters);
367
368 template <typename HandlerType>
369 static void ProcessSignatureResources(const PipelineResourceSignatureD3D11Impl& Signature,
370 const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes,
371 Uint32 NumAllowedTypes,
372 SHADER_TYPE ShaderType,
373 HandlerType Handler);
374
375 // clang-format off
376 using OffsetType = Uint16;
377 template<typename ResourceType> OffsetType GetResourceOffset()const;
378 template<> OffsetType GetResourceOffset<ConstBuffBindInfo>() const { return 0; }
379 template<> OffsetType GetResourceOffset<TexSRVBindInfo> () const { return m_TexSRVsOffset; }
380 template<> OffsetType GetResourceOffset<TexUAVBindInfo> () const { return m_TexUAVsOffset; }
381 template<> OffsetType GetResourceOffset<BuffSRVBindInfo> () const { return m_BuffSRVsOffset; }
382 template<> OffsetType GetResourceOffset<BuffUAVBindInfo> () const { return m_BuffUAVsOffset; }
383 template<> OffsetType GetResourceOffset<SamplerBindInfo> () const { return m_SamplerOffset; }
384 // clang-format on
385
386 template <typename ResourceType>
387 ResourceType& GetResource(Uint32 ResIndex) const
388 {
389 VERIFY(ResIndex < GetNumResources<ResourceType>(), "Resource index (", ResIndex, ") must be less than (", GetNumResources<ResourceType>(), ")");
390 auto Offset = GetResourceOffset<ResourceType>();
391 return reinterpret_cast<ResourceType*>(reinterpret_cast<Uint8*>(m_ResourceBuffer) + Offset)[ResIndex];
392 }
393
394 template <typename ResourceType>
395 const ResourceType& GetConstResource(Uint32 ResIndex) const
396 {
397 VERIFY(ResIndex < GetNumResources<ResourceType>(), "Resource index (", ResIndex, ") must be less than (", GetNumResources<ResourceType>(), ")");
398 auto Offset = GetResourceOffset<ResourceType>();
399 return reinterpret_cast<const ResourceType*>(reinterpret_cast<const Uint8*>(m_ResourceBuffer) + Offset)[ResIndex];
400 }
401
402 template <typename ResourceType>
403 IShaderResourceVariable* GetResourceByName(const Char* Name) const;
404
405 template <typename THandleCB,
406 typename THandleTexSRV,
407 typename THandleTexUAV,
408 typename THandleBufSRV,
409 typename THandleBufUAV,
410 typename THandleSampler>
411 void HandleResources(THandleCB HandleCB,
412 THandleTexSRV HandleTexSRV,
413 THandleTexUAV HandleTexUAV,
414 THandleBufSRV HandleBufSRV,
415 THandleBufUAV HandleBufUAV,
416 THandleSampler HandleSampler)
417 {
418 for (Uint32 cb = 0; cb < GetNumResources<ConstBuffBindInfo>(); ++cb)
419 HandleCB(GetResource<ConstBuffBindInfo>(cb));
420
421 for (Uint32 t = 0; t < GetNumResources<TexSRVBindInfo>(); ++t)
422 HandleTexSRV(GetResource<TexSRVBindInfo>(t));
423
424 for (Uint32 u = 0; u < GetNumResources<TexUAVBindInfo>(); ++u)
425 HandleTexUAV(GetResource<TexUAVBindInfo>(u));
426
427 for (Uint32 s = 0; s < GetNumResources<BuffSRVBindInfo>(); ++s)
428 HandleBufSRV(GetResource<BuffSRVBindInfo>(s));
429
430 for (Uint32 u = 0; u < GetNumResources<BuffUAVBindInfo>(); ++u)
431 HandleBufUAV(GetResource<BuffUAVBindInfo>(u));
432
433 for (Uint32 s = 0; s < GetNumResources<SamplerBindInfo>(); ++s)
434 HandleSampler(GetResource<SamplerBindInfo>(s));
435 }
436
437 template <typename THandleCB,
438 typename THandleTexSRV,
439 typename THandleTexUAV,
440 typename THandleBufSRV,
441 typename THandleBufUAV,
442 typename THandleSampler>
443 void HandleConstResources(THandleCB HandleCB,
444 THandleTexSRV HandleTexSRV,
445 THandleTexUAV HandleTexUAV,
446 THandleBufSRV HandleBufSRV,
447 THandleBufUAV HandleBufUAV,
448 THandleSampler HandleSampler) const
449 {
450 for (Uint32 cb = 0; cb < GetNumResources<ConstBuffBindInfo>(); ++cb)
451 HandleCB(GetConstResource<ConstBuffBindInfo>(cb));
452
453 for (Uint32 t = 0; t < GetNumResources<TexSRVBindInfo>(); ++t)
454 HandleTexSRV(GetConstResource<TexSRVBindInfo>(t));
455
456 for (Uint32 u = 0; u < GetNumResources<TexUAVBindInfo>(); ++u)
457 HandleTexUAV(GetConstResource<TexUAVBindInfo>(u));
458
459 for (Uint32 s = 0; s < GetNumResources<BuffSRVBindInfo>(); ++s)
460 HandleBufSRV(GetConstResource<BuffSRVBindInfo>(s));
461
462 for (Uint32 u = 0; u < GetNumResources<BuffUAVBindInfo>(); ++u)
463 HandleBufUAV(GetConstResource<BuffUAVBindInfo>(u));
464
465 for (Uint32 s = 0; s < GetNumResources<SamplerBindInfo>(); ++s)
466 HandleSampler(GetConstResource<SamplerBindInfo>(s));
467 }
468
469 friend class ShaderVariableIndexLocator;
470 friend class ShaderVariableLocator;
471
472 private:
473 PipelineResourceSignatureD3D11Impl const* m_pSignature = nullptr;
474
475 IObject& m_Owner;
476
477 // No need to use shared pointer, as the resource cache is either part of the same
478 // ShaderD3D11Impl object, or ShaderResourceBindingD3D11Impl object
479 ShaderResourceCacheD3D11& m_ResourceCache;
480 void* m_ResourceBuffer = nullptr;
481
482 // Offsets in bytes
483 OffsetType m_TexSRVsOffset = 0;
484 OffsetType m_TexUAVsOffset = 0;
485 OffsetType m_BuffSRVsOffset = 0;
486 OffsetType m_BuffUAVsOffset = 0;
487 OffsetType m_SamplerOffset = 0;
488 OffsetType m_MemorySize = 0;
489
490 #ifdef DILIGENT_DEBUG
491 IMemoryAllocator* m_pDbgAllocator = nullptr;
492 #endif
493 };
494
495 } // namespace Diligent
4141 class FixedBlockMemoryAllocator;
4242
4343 /// Base implementation of a texture object in Direct3D11 backend.
44 class TextureBaseD3D11 : public TextureBase<ITextureD3D11, RenderDeviceD3D11Impl, TextureViewD3D11Impl, FixedBlockMemoryAllocator>
44 class TextureBaseD3D11 : public TextureBase<EngineD3D11ImplTraits>
4545 {
4646 public:
47 using TTextureBase = TextureBase<ITextureD3D11, RenderDeviceD3D11Impl, TextureViewD3D11Impl, FixedBlockMemoryAllocator>;
47 using TTextureBase = TextureBase<EngineD3D11ImplTraits>;
4848 using ViewImplType = TextureViewD3D11Impl;
4949
5050 TextureBaseD3D11(IReferenceCounters* pRefCounters,
4040 class FixedBlockMemoryAllocator;
4141
4242 /// Texture view implementation in Direct3D11 backend.
43 class TextureViewD3D11Impl final : public TextureViewBase<ITextureViewD3D11, RenderDeviceD3D11Impl>
43 class TextureViewD3D11Impl final : public TextureViewBase<EngineD3D11ImplTraits>
4444 {
4545 public:
46 using TTextureViewBase = TextureViewBase<ITextureViewD3D11, RenderDeviceD3D11Impl>;
46 using TTextureViewBase = TextureViewBase<EngineD3D11ImplTraits>;
4747
4848 TextureViewD3D11Impl(IReferenceCounters* pRefCounters,
4949 RenderDeviceD3D11Impl* pDevice,
2626
2727 #include "pch.h"
2828 #include "BufferViewD3D11Impl.hpp"
29 #include "BufferD3D11Impl.hpp"
2930
3031 namespace Diligent
3132 {
3334 BufferViewD3D11Impl::BufferViewD3D11Impl(IReferenceCounters* pRefCounters,
3435 RenderDeviceD3D11Impl* pDevice,
3536 const BufferViewDesc& ViewDesc,
36 IBuffer* pBuffer,
37 BufferD3D11Impl* pBuffer,
3738 ID3D11View* pD3D11View,
3839 bool bIsDefaultView) :
3940 // clang-format off
132132 {
133133 UNEXPECTED(GetPipelineTypeString(Desc.PipelineType), " pipelines '", Desc.Name, "' are not supported in OpenGL");
134134 }
135
136 const auto SignCount = m_pPipelineState->GetResourceSignatureCount();
137 const auto ActiveStages = m_pPipelineState->GetActiveShaderStages();
138
139 m_BindInfo.ActiveSRBMask = 0;
140 for (Uint32 s = 0; s < SignCount; ++s)
141 {
142 const auto* pLayoutSign = m_pPipelineState->GetResourceSignature(s);
143 if (pLayoutSign == nullptr || pLayoutSign->GetTotalResourceCount() == 0)
144 continue;
145
146 m_BindInfo.ActiveSRBMask |= (1u << s);
147 }
148
149 // Reset states if new pipeline have new shader stages.
150 if ((m_BindInfo.ActiveStages & ActiveStages) != ActiveStages)
151 {
152 m_BindInfo.ActiveStages = ActiveStages;
153 m_BindInfo.StaleSRBMask = 0xFF;
154 }
155
156 #ifdef DILIGENT_DEVELOPMENT
157 // Find the first incompatible shader resource bindings
158 Uint32 sign = 0;
159 for (; sign < SignCount; ++sign)
160 {
161 const auto* pLayoutSign = m_pPipelineState->GetResourceSignature(sign);
162 const auto* pSRBSign = m_BindInfo.SRBs[sign] != nullptr ? m_BindInfo.SRBs[sign]->GetSignature() : nullptr;
163
164 if ((pLayoutSign == nullptr || pLayoutSign->GetTotalResourceCount() == 0) != (pSRBSign == nullptr || pSRBSign->GetTotalResourceCount() == 0))
165 {
166 // One signature is null or empty while the other is not - SRB is not compatible with the layout.
167 break;
168 }
169
170 if (pLayoutSign != nullptr && pSRBSign != nullptr && pLayoutSign->IsIncompatibleWith(*pSRBSign))
171 {
172 // Signatures are incompatible
173 break;
174 }
175 }
176
177 // Unbind incompatible SRB and SRB with a higher binding index.
178 // This is the same behavior that used in Vulkan backend.
179 for (; sign < SignCount; ++sign)
180 {
181 m_BindInfo.SRBs[sign] = nullptr;
182 m_BindInfo.ClearStaleSRBBit(sign);
183 }
184
185 m_BindInfo.CommittedResourcesValidated = false;
186 #endif
135187 }
136188
137189 // clang-format off
167219
168220 // clang-format on
169221
170 // http://diligentgraphics.com/diligent-engine/architecture/d3d11/committing-shader-resources-to-the-gpu-pipeline/
171 template <bool TransitionResources, bool CommitResources>
172 void DeviceContextD3D11Impl::TransitionAndCommitShaderResources(IPipelineState* pPSO, IShaderResourceBinding* pShaderResourceBinding, bool VerifyStates)
173 {
174 VERIFY_EXPR(pPSO != nullptr);
175 static_assert(TransitionResources || CommitResources, "At least one of TransitionResources or CommitResources flags is expected to be true");
176
177 auto* pPipelineStateD3D11 = ValidatedCast<PipelineStateD3D11Impl>(pPSO);
178
179 if (pShaderResourceBinding == nullptr)
180 {
222 void DeviceContextD3D11Impl::TransitionShaderResources(IPipelineState* pPipelineState, IShaderResourceBinding* pShaderResourceBinding)
223 {
224 DEV_CHECK_ERR(pPipelineState != nullptr, "Pipeline state must not be null");
225 DEV_CHECK_ERR(pShaderResourceBinding != nullptr, "Shader resource binding must not be null");
226 if (m_pActiveRenderPass)
227 {
228 LOG_ERROR_MESSAGE("State transitions are not allowed inside a render pass.");
229 return;
230 }
231
232 auto* pShaderResBindingD3D11 = ValidatedCast<ShaderResourceBindingD3D11Impl>(pShaderResourceBinding);
233 auto& ResourceCache = pShaderResBindingD3D11->GetResourceCache();
234
235 ResourceCache.TransitionResourceStates(*this, ShaderResourceCacheD3D11::StateTransitionMode::Transition);
236 }
237
238 void DeviceContextD3D11Impl::CommitShaderResources(IShaderResourceBinding* pShaderResourceBinding, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)
239 {
240 if (!DeviceContextBase::CommitShaderResources(pShaderResourceBinding, StateTransitionMode, 0 /*Dummy*/))
241 return;
242
243 auto* pShaderResBindingD3D11 = ValidatedCast<ShaderResourceBindingD3D11Impl>(pShaderResourceBinding);
244 const auto SRBIndex = pShaderResBindingD3D11->GetBindingIndex();
245 auto& ResourceCache = pShaderResBindingD3D11->GetResourceCache();
246
247 m_BindInfo.SRBs[SRBIndex] = pShaderResBindingD3D11;
248 m_BindInfo.SetStaleSRBBit(SRBIndex);
249
181250 #ifdef DILIGENT_DEVELOPMENT
182 bool ResourcesPresent = false;
183 for (Uint32 s = 0; s < pPipelineStateD3D11->GetNumShaderStages(); ++s)
184 {
185 auto* pShaderD3D11 = pPipelineStateD3D11->GetShader(s);
186 if (pShaderD3D11->GetD3D11Resources()->GetTotalResources() > 0)
187 ResourcesPresent = true;
188 }
189
190 if (ResourcesPresent)
191 {
192 LOG_ERROR_MESSAGE("Pipeline state '", pPSO->GetDesc().Name, "' requires shader resource binding object to ",
193 (CommitResources ? "commit" : "transition"), " resources, but none is provided.");
194 }
251 m_BindInfo.CommittedResourcesValidated = false;
195252 #endif
253
254 if (StateTransitionMode == RESOURCE_STATE_TRANSITION_MODE_TRANSITION)
255 {
256 ResourceCache.TransitionResourceStates(*this, ShaderResourceCacheD3D11::StateTransitionMode::Transition);
257 }
258 #ifdef DILIGENT_DEVELOPMENT
259 else if (StateTransitionMode == RESOURCE_STATE_TRANSITION_MODE_VERIFY)
260 {
261 ResourceCache.TransitionResourceStates(*this, ShaderResourceCacheD3D11::StateTransitionMode::Verify);
262 }
263 #endif
264 }
265
266 void DeviceContextD3D11Impl::BindShaderResources()
267 {
268 if ((m_BindInfo.StaleSRBMask & m_BindInfo.ActiveSRBMask) == 0)
196269 return;
197 }
198
199
200 auto pShaderResBindingD3D11 = ValidatedCast<ShaderResourceBindingD3D11Impl>(pShaderResourceBinding);
270
271 TBindingsPerStage Bindings = {};
272 TMinMaxSlotPerStage MinMaxSlot = {};
273 const auto ActiveStages = m_BindInfo.ActiveStages;
274
275 if (m_pPipelineState->GetDesc().IsAnyGraphicsPipeline())
276 Bindings[GetShaderTypeIndex(SHADER_TYPE_PIXEL)][DESCRIPTOR_RANGE_UAV] = static_cast<Uint8>(m_pPipelineState->GetGraphicsPipelineDesc().NumRenderTargets);
277
278 auto ActiveSRBMask = Uint32{m_BindInfo.ActiveSRBMask};
279 while (ActiveSRBMask != 0)
280 {
281 Uint32 sign = PlatformMisc::GetLSB(ActiveSRBMask);
282 Uint32 SigBit = (1u << sign);
283 VERIFY_EXPR(sign < m_pPipelineState->GetResourceSignatureCount());
284
285 ActiveSRBMask &= ~SigBit;
286
287 auto* pSRB = m_BindInfo.SRBs[sign];
288 VERIFY_EXPR(pSRB);
289
290 if (m_BindInfo.StaleSRBMask & SigBit)
291 {
201292 #ifdef DILIGENT_DEVELOPMENT
202 if (pPipelineStateD3D11->IsIncompatibleWith(pShaderResourceBinding->GetPipelineState()))
203 {
204 LOG_ERROR_MESSAGE("Shader resource binding does not match Pipeline State");
205 return;
206 }
293 m_BindInfo.BoundResOffsets[sign] = Bindings;
207294 #endif
208
209 auto NumShaders = pShaderResBindingD3D11->GetNumActiveShaders();
210 VERIFY(NumShaders == pPipelineStateD3D11->GetNumShaderStages(), "Number of active shaders in shader resource binding is not consistent with the number of shaders in the pipeline state");
211
212 #ifdef DILIGENT_DEVELOPMENT
213 {
214 bool StaticResourcesPresent = false;
215 for (Uint32 s = 0; s < NumShaders; ++s)
216 {
217 const auto& StaticResLayout = pPipelineStateD3D11->GetStaticResourceLayout(s);
218 if (StaticResLayout.GetTotalResourceCount() > 0)
219 StaticResourcesPresent = true;
220 }
221 // Static resource bindings are verified in BindStaticShaderResources()
222 if (StaticResourcesPresent && !pShaderResBindingD3D11->IsStaticResourcesBound())
223 {
224 LOG_ERROR_MESSAGE("Static resources have not been initialized in the shader resource binding object being committed for PSO '", pPSO->GetDesc().Name, "'. Please call IShaderResourceBinding::InitializeStaticResources().");
225 }
226 }
295 pSRB->GetResourceCache().BindResources(*this, Bindings, MinMaxSlot, m_CommittedRes, ActiveStages);
296 }
297 pSRB->GetSignature()->AddBindings(Bindings);
298 }
299
300 m_BindInfo.StaleSRBMask &= ~m_BindInfo.ActiveSRBMask;
301 bool ClearPixelShaderUAVs = m_CommittedRes.NumUAVs[PSInd] > 0;
302
303 for (Uint32 s = 0, ShaderCount = m_pPipelineState->GetNumShaders(); s < ShaderCount; ++s)
304 {
305 const auto ShaderType = m_pPipelineState->GetShaderStageType(s);
306 const Uint32 ShaderInd = GetShaderTypeIndex(ShaderType);
307
308 // CBV
309 {
310 const auto Range = DESCRIPTOR_RANGE_CBV;
311 const UINT MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
312 const UINT MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
313 if (MinSlot != UINT_MAX)
314 {
315 auto SetCBMethod = SetCBMethods[ShaderInd];
316 (m_pd3d11DeviceContext->*SetCBMethod)(MinSlot, MaxSlot - MinSlot + 1, m_CommittedRes.D3D11CBs[ShaderInd] + MinSlot);
317 m_CommittedRes.NumCBs[ShaderInd] = std::max(m_CommittedRes.NumCBs[ShaderInd], Bindings[ShaderInd][Range]);
318 VERIFY_EXPR(MaxSlot < Bindings[ShaderInd][Range]);
319 }
320 #ifdef VERIFY_CONTEXT_BINDINGS
321 if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
322 {
323 DvpVerifyCommittedCBs(ShaderType);
324 }
227325 #endif
228
229 bool ClearPixelShaderUAVs = m_NumCommittedUAVs[PSInd] > 0;
230 // First, commit all UAVs for all shader stages. This will unbind them from input
231 for (Uint32 s = 0; s < NumShaders; ++s)
232 {
233 const auto ShaderType = pShaderResBindingD3D11->GetActiveShaderType(s);
234 const auto ShaderTypeInd = GetShaderTypeIndex(ShaderType);
235
236 #ifdef DILIGENT_DEVELOPMENT
237 auto* pShaderD3D11 = pPipelineStateD3D11->GetShader(s);
238 VERIFY_EXPR(ShaderType == pShaderD3D11->GetDesc().ShaderType);
326 }
327
328 // SRV
329 {
330 const auto Range = DESCRIPTOR_RANGE_SRV;
331 const UINT MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
332 const UINT MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
333 if (MinSlot != UINT_MAX)
334 {
335 auto SetSRVMethod = SetSRVMethods[ShaderInd];
336 (m_pd3d11DeviceContext->*SetSRVMethod)(MinSlot, MaxSlot - MinSlot + 1, m_CommittedRes.D3D11SRVs[ShaderInd] + MinSlot);
337 m_CommittedRes.NumSRVs[ShaderInd] = std::max(m_CommittedRes.NumSRVs[ShaderInd], Bindings[ShaderInd][Range]);
338 VERIFY_EXPR(MaxSlot <= Bindings[ShaderInd][Range]);
339 }
340 #ifdef VERIFY_CONTEXT_BINDINGS
341 if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
342 {
343 DvpVerifyCommittedSRVs(ShaderType);
344 }
239345 #endif
240
241 auto& Cache = pShaderResBindingD3D11->GetResourceCache(s);
242 auto NumUAVs = Cache.GetUAVCount();
243 if (NumUAVs)
244 {
245 ShaderResourceCacheD3D11::CachedResource* CachedUAVResources;
246 ID3D11UnorderedAccessView** d3d11UAVs;
247 Cache.GetUAVArrays(CachedUAVResources, d3d11UAVs);
248
249 auto* CommittedD3D11UAVs = m_CommittedD3D11UAVs[ShaderTypeInd];
250 auto* CommittedD3D11UAVRes = m_CommittedD3D11UAVResources[ShaderTypeInd];
251
252 if (ShaderTypeInd == PSInd)
253 ClearPixelShaderUAVs = false;
254
255 UINT MinSlot = UINT_MAX;
256 UINT MaxSlot = 0;
257
258 for (Uint32 uav = 0; uav < NumUAVs; ++uav)
259 {
260 VERIFY_EXPR(uav < Cache.GetUAVCount());
261 auto& UAVRes = CachedUAVResources[uav];
262 // WARNING! This code is not thread-safe. It is up to the application to make
263 // sure that multiple threads do not modify the texture state simultaneously.
264 if (TransitionResources)
346 }
347
348 // Sampler
349 {
350 const auto Range = DESCRIPTOR_RANGE_SAMPLER;
351 const UINT MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
352 const UINT MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
353 if (MinSlot != UINT_MAX)
354 {
355 auto SetSamplerMethod = SetSamplerMethods[ShaderInd];
356 (m_pd3d11DeviceContext->*SetSamplerMethod)(MinSlot, MaxSlot - MinSlot + 1, m_CommittedRes.D3D11Samplers[ShaderInd] + MinSlot);
357 m_CommittedRes.NumSamplers[ShaderInd] = std::max(m_CommittedRes.NumSamplers[ShaderInd], Bindings[ShaderInd][Range]);
358 VERIFY_EXPR(MaxSlot < Bindings[ShaderInd][Range]);
359 }
360 #ifdef VERIFY_CONTEXT_BINDINGS
361 if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
362 {
363 DvpVerifyCommittedSamplers(ShaderType);
364 }
365 #endif
366 }
367
368 // UAV
369 {
370 const auto Range = DESCRIPTOR_RANGE_UAV;
371 const UINT MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
372 const UINT MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
373 if (MinSlot != UINT_MAX)
374 {
375 auto* CommittedD3D11UAVs = m_CommittedRes.D3D11UAVs[ShaderInd];
376 auto* CommittedD3D11UAVRes = m_CommittedRes.D3D11UAVResources[ShaderInd];
377
378 if (ShaderInd == PSInd)
379 ClearPixelShaderUAVs = false;
380
381 // Something has changed
382 if (ShaderInd == PSInd)
265383 {
266 if (auto* pTexture = ValidatedCast<TextureBaseD3D11>(UAVRes.pTexture))
384 // Pixel shader UAVs cannot be set independently; they all need to be set at the same time.
385 // https://docs.microsoft.com/en-us/windows/desktop/api/d3d11/nf-d3d11-id3d11devicecontext-omsetrendertargetsandunorderedaccessviews#remarks
386 const auto StartUAVSlot = m_NumBoundRenderTargets;
387 const auto NumUAVSlot = Bindings[ShaderInd][Range];
388 VERIFY(NumUAVSlot > StartUAVSlot, "Number of UAVs must be greater than the render target count");
389 m_pd3d11DeviceContext->OMSetRenderTargetsAndUnorderedAccessViews(
390 D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr,
391 StartUAVSlot, NumUAVSlot - StartUAVSlot, CommittedD3D11UAVs + StartUAVSlot, nullptr);
392 // Clear previously bound UAVs, but do not clear lower slots as if
393 // render target count reduces, we will bind these UAVs in CommitRenderTargets()
394 for (Uint32 uav = NumUAVSlot; uav < m_CommittedRes.NumUAVs[ShaderInd]; ++uav)
267395 {
268 if (pTexture->IsInKnownState() && !pTexture->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
269 {
270 if (pTexture->CheckAnyState(RESOURCE_STATE_SHADER_RESOURCE | RESOURCE_STATE_INPUT_ATTACHMENT))
271 UnbindTextureFromInput(pTexture, UAVRes.pd3d11Resource);
272 pTexture->SetState(RESOURCE_STATE_UNORDERED_ACCESS);
273 }
396 CommittedD3D11UAVRes[uav] = nullptr;
397 CommittedD3D11UAVs[uav] = nullptr;
274398 }
275 else if (auto* pBuffer = ValidatedCast<BufferD3D11Impl>(UAVRes.pBuffer))
276 {
277 if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
278 {
279 if ((pBuffer->GetState() & RESOURCE_STATE_GENERIC_READ) != 0)
280 UnbindBufferFromInput(pBuffer, UAVRes.pd3d11Resource);
281 pBuffer->SetState(RESOURCE_STATE_UNORDERED_ACCESS);
282 }
283 }
399 m_CommittedRes.NumUAVs[ShaderInd] = NumUAVSlot;
284400 }
285 #ifdef DILIGENT_DEVELOPMENT
286 else if (VerifyStates)
401 else if (ShaderInd == CSInd)
287402 {
288 if (const auto* pTexture = ValidatedCast<TextureBaseD3D11>(UAVRes.pTexture))
289 {
290 if (pTexture->IsInKnownState() && !pTexture->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
291 {
292 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.");
293 }
294 }
295 else if (const auto* pBuffer = ValidatedCast<BufferD3D11Impl>(UAVRes.pBuffer))
296 {
297 if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
298 {
299 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.");
300 }
301 }
403 // This can only be CS
404 auto SetUAVMethod = SetUAVMethods[ShaderInd];
405 (m_pd3d11DeviceContext->*SetUAVMethod)(MinSlot, MaxSlot - MinSlot + 1, CommittedD3D11UAVs + MinSlot, nullptr);
406 m_CommittedRes.NumUAVs[ShaderInd] = std::max(m_CommittedRes.NumUAVs[ShaderInd], Bindings[ShaderInd][Range]);
407 VERIFY_EXPR(MaxSlot < Bindings[ShaderInd][Range]);
302408 }
409 else
410 {
411 UNEXPECTED("UAV is not supported in shader that is not pixel or compute");
412 }
413 }
414 #ifdef VERIFY_CONTEXT_BINDINGS
415 if ((m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE) != 0 && ShaderInd == CSInd)
416 {
417 DvpVerifyCommittedUAVs(ShaderType);
418 }
303419 #endif
304 if (CommitResources)
305 {
306 bool IsNewUAV = CommittedD3D11UAVs[uav] != d3d11UAVs[uav];
307 MinSlot = IsNewUAV ? std::min(MinSlot, uav) : MinSlot;
308 MaxSlot = IsNewUAV ? uav : MaxSlot;
309
310 CommittedD3D11UAVRes[uav] = UAVRes.pd3d11Resource;
311 CommittedD3D11UAVs[uav] = d3d11UAVs[uav];
312 }
313 }
314
315 if (CommitResources)
316 {
317 if (MinSlot != UINT_MAX || ShaderTypeInd == PSInd && m_NumCommittedUAVs[PSInd] != NumUAVs)
318 {
319 // Something has changed
320 if (ShaderTypeInd == PSInd)
321 {
322 // Pixel shader UAVs cannot be set independently; they all need to be set at the same time.
323 // https://docs.microsoft.com/en-us/windows/desktop/api/d3d11/nf-d3d11-id3d11devicecontext-omsetrendertargetsandunorderedaccessviews#remarks
324 auto StartUAVSlot = m_NumBoundRenderTargets;
325 VERIFY(NumUAVs > StartUAVSlot, "Number of UAVs must be greater than the render target count");
326 m_pd3d11DeviceContext->OMSetRenderTargetsAndUnorderedAccessViews(
327 D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr,
328 StartUAVSlot, NumUAVs - StartUAVSlot, CommittedD3D11UAVs + StartUAVSlot, nullptr);
329 // Clear previously bound UAVs, but do not clear lower slots as if
330 // render target count reduces, we will bind these UAVs in CommitRenderTargets()
331 for (Uint32 uav = NumUAVs; uav < m_NumCommittedUAVs[ShaderTypeInd]; ++uav)
332 {
333 CommittedD3D11UAVRes[uav] = nullptr;
334 CommittedD3D11UAVs[uav] = nullptr;
335 }
336 m_NumCommittedUAVs[ShaderTypeInd] = static_cast<Uint8>(NumUAVs);
337 }
338 else
339 {
340 // This can only be CS
341 auto SetUAVMethod = SetUAVMethods[ShaderTypeInd];
342 (m_pd3d11DeviceContext->*SetUAVMethod)(MinSlot, MaxSlot - MinSlot + 1, CommittedD3D11UAVs + MinSlot, nullptr);
343 m_NumCommittedUAVs[ShaderTypeInd] = std::max(m_NumCommittedUAVs[ShaderTypeInd], static_cast<Uint8>(NumUAVs));
344 }
345 }
346
347 #ifdef DILIGENT_DEVELOPMENT
348 if ((m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE) != 0 && ShaderTypeInd == CSInd)
349 {
350 dbgVerifyCommittedUAVs(pShaderD3D11->GetDesc().ShaderType);
351 }
352 #endif
353 }
354420 }
355421 }
356422
360426 // This is important as UnbindPixelShaderUAV<> function may need to rebind
361427 // existing UAVs and the UAVs pointed to by CommittedD3D11UAVRes must be alive
362428 // (we do not keep strong references to d3d11 UAVs)
363 auto* CommittedD3D11UAVs = m_CommittedD3D11UAVs[PSInd];
364 auto* CommittedD3D11UAVRes = m_CommittedD3D11UAVResources[PSInd];
365 auto& NumCommittedPixelShaderUAVs = m_NumCommittedUAVs[PSInd];
429 auto* CommittedD3D11UAVs = m_CommittedRes.D3D11UAVs[PSInd];
430 auto* CommittedD3D11UAVRes = m_CommittedRes.D3D11UAVResources[PSInd];
431 auto& NumCommittedPixelShaderUAVs = m_CommittedRes.NumUAVs[PSInd];
366432 for (Uint32 uav = 0; uav < NumCommittedPixelShaderUAVs; ++uav)
367433 {
368434 CommittedD3D11UAVRes[uav] = nullptr;
373439 0, 0, nullptr, nullptr);
374440 NumCommittedPixelShaderUAVs = 0;
375441 }
376
377 // Commit input resources (CBs, SRVs and Samplers)
378 for (Uint32 s = 0; s < NumShaders; ++s)
379 {
380 const auto ShaderType = pShaderResBindingD3D11->GetActiveShaderType(s);
381 const auto ShaderTypeInd = GetShaderTypeIndex(ShaderType);
442 }
382443