git.s-ol.nu ~forks/DiligentCore / efc9d06
Direct3D11: resource cache refactoring azhirnov authored 6 months ago assiduous committed 6 months ago
11 changed file(s) with 1061 addition(s) and 995 deletion(s). Raw diff Collapse all Expand all
386386 };
387387
388388 using TBindingsPerStage = PipelineResourceSignatureD3D11Impl::TBindingsPerStage;
389 struct MinMaxSlot
390 {
391 UINT MinSlot = UINT_MAX;
392 UINT MaxSlot = 0;
393 };
394 using TMinMaxSlotPerStage = std::array<std::array<MinMaxSlot, D3D11_RESOURCE_RANGE_COUNT>, NumShaderTypes>;
395
396
397389 void BindCacheResources(const ShaderResourceCacheD3D11& ResourceCache,
398 const TBindingsPerStage& Bindings,
399 TMinMaxSlotPerStage& MinMaxSlot,
390 const TBindingsPerStage& BaseBindings,
400391 SHADER_TYPE ActiveStages);
401392
402393 #ifdef DILIGENT_DEVELOPMENT
6161 BindPointsD3D11(const BindPointsD3D11&) noexcept = default;
6262
6363 // clang-format off
64 bool IsEmpty() const { return m_ActiveBits == 0; }
6465 Uint32 GetActiveBits() const { return m_ActiveBits; }
6566 bool IsValid(Uint32 index) const { return m_Bindings[index] != InvalidBindPoint; }
6667 Uint8 operator[](Uint32 index) const { return m_Bindings[index]; }
112113 struct PipelineResourceAttribsD3D11
113114 {
114115 private:
115 static constexpr Uint32 _CacheOffsetBits = 10;
116116 static constexpr Uint32 _SamplerIndBits = 10;
117117 static constexpr Uint32 _SamplerAssignedBits = 1;
118118
119119 public:
120 static constexpr Uint32 InvalidCacheOffset = (1u << _CacheOffsetBits) - 1;
121 static constexpr Uint32 InvalidSamplerInd = (1u << _SamplerIndBits) - 1;
120 static constexpr Uint32 InvalidSamplerInd = (1u << _SamplerIndBits) - 1;
122121
123122 // clang-format off
124 const Uint32 CacheOffset : _CacheOffsetBits; // SRB and Signature have the same cache offsets for static resources
125 // (thanks to sorting variables by type, where all static vars go first).
126123 const Uint32 SamplerInd : _SamplerIndBits; // Index of the assigned sampler in m_Desc.Resources.
127124 const Uint32 ImtblSamplerAssigned : _SamplerAssignedBits; // Immutable sampler flag.
128125 BindPointsD3D11 BindPoints;
129126 // clang-format on
130127
131 PipelineResourceAttribsD3D11(Uint32 _CacheOffset,
132 Uint32 _SamplerInd,
128 PipelineResourceAttribsD3D11(Uint32 _SamplerInd,
133129 bool _ImtblSamplerAssigned) noexcept :
134130 // clang-format off
135 CacheOffset {_CacheOffset },
136131 SamplerInd {_SamplerInd },
137132 ImtblSamplerAssigned{_ImtblSamplerAssigned ? 1u : 0u}
138133 // clang-format on
139134 {
140 VERIFY(CacheOffset == _CacheOffset, "Cache offset (", _CacheOffset, ") exceeds maximum representable value");
141135 VERIFY(SamplerInd == _SamplerInd, "Sampler index (", _SamplerInd, ") exceeds maximum representable value");
142136 }
143137
7070 // sizeof(ImmutableSamplerAttribs) == 24, x64
7171 struct ImmutableSamplerAttribs
7272 {
73 private:
74 static constexpr Uint32 _CacheOffsetBits = 10;
75 static constexpr Uint32 _ArraySizeBits = 22;
73 public:
74 RefCntAutoPtr<ISampler> pSampler;
75 Uint32 ArraySize = 0;
76 BindPointsD3D11 BindPoints;
7677
77 public:
78 static constexpr Uint32 InvalidCacheOffset = (1u << _CacheOffsetBits) - 1;
79 static_assert(InvalidCacheOffset == ResourceAttribs::InvalidCacheOffset,
80 "InvalidCacheOffset value mismatch between ResourceAttribs and ImmutableSamplerAttribs");
78 ImmutableSamplerAttribs() noexcept {}
8179
82 // clang-format off
83 RefCntAutoPtr<ISampler> pSampler;
84 Uint32 CacheOffset : _CacheOffsetBits;
85 Uint32 ArraySize : _ArraySizeBits;
86 BindPointsD3D11 BindPoints;
87 // clang-format on
88
89 ImmutableSamplerAttribs() :
90 CacheOffset{InvalidCacheOffset},
91 ArraySize{0}
92 {}
93
94 bool IsAllocated() const { return CacheOffset != InvalidCacheOffset; }
80 bool IsAllocated() const { return !BindPoints.IsEmpty(); }
9581 SamplerD3D11Impl* GetSamplerD3D11() const { return ValidatedCast<SamplerD3D11Impl>(pSampler.RawPtr<ISampler>()); }
9682 };
9783
10187 return m_ImmutableSamplers[SampIndex];
10288 }
10389
104 using TBindings = ShaderResourceCacheD3D11::TResourceCount;
10590 using TResourceCount = std::array<Uint8, D3D11_RESOURCE_RANGE_COUNT>;
106 using TBindingsPerStage = std::array<TResourceCount, NumShaderTypes>;
107
91 using TBindingsPerStage = std::array<std::array<Uint8, NumShaderTypes>, D3D11_RESOURCE_RANGE_COUNT>;
10892
10993 __forceinline void ShiftBindings(TBindingsPerStage& Bindings) const
11094 {
111 for (Uint32 s = 0; s < Bindings.size(); ++s)
95 for (Uint32 r = 0; r < Bindings.size(); ++r)
11296 {
113 for (Uint32 i = 0; i < Bindings[s].size(); ++i)
97 for (Uint32 s = 0; s < Bindings[r].size(); ++s)
11498 {
115 Uint32 Count = Bindings[s][i] + m_BindingCountPerStage[s][i];
99 Uint32 Count = Bindings[r][s] + m_BindingCountPerStage[r][s];
116100 VERIFY_EXPR(Count < std::numeric_limits<Uint8>::max());
117 Bindings[s][i] = static_cast<Uint8>(Count);
101 Bindings[r][s] = static_cast<Uint8>(Count);
118102 }
119103 }
120104 }
141125 void Destruct();
142126
143127 private:
144 TBindings m_ResourceCount = {};
145 TBindingsPerStage m_BindingCountPerStage = {};
146
147 ResourceAttribs* m_pResourceAttribs = nullptr; // [m_Desc.NumResources]
148 ImmutableSamplerAttribs* m_ImmutableSamplers = nullptr; // [m_Desc.NumImmutableSamplers]
128 TBindingsPerStage m_BindingCountPerStage = {};
129 ResourceAttribs* m_pResourceAttribs = nullptr; // [m_Desc.NumResources]
130 ImmutableSamplerAttribs* m_ImmutableSamplers = nullptr; // [m_Desc.NumImmutableSamplers]
149131 };
150132
151133 } // namespace Diligent
113113 void ValidateShaderResources(const ShaderD3D11Impl* pShader);
114114
115115 private:
116 using SignaturePtr = RefCntAutoPtr<PipelineResourceSignatureD3D11Impl>;
117
118116 std::array<Uint8, 5> m_ShaderTypes = {};
119117 Uint8 m_NumShaders = 0;
120118
8888
8989 private:
9090 friend class ShaderResourceCacheD3D11;
91 __forceinline void Set(RefCntAutoPtr<BufferD3D11Impl>&& _pBuff)
91 __forceinline void Set(RefCntAutoPtr<BufferD3D11Impl> _pBuff)
9292 {
9393 pBuff = std::move(_pBuff);
9494 }
129129
130130 private:
131131 friend class ShaderResourceCacheD3D11;
132 __forceinline void Set(RefCntAutoPtr<TextureViewD3D11Impl>&& pTexView)
132 __forceinline void Set(RefCntAutoPtr<TextureViewD3D11Impl> pTexView)
133133 {
134134 pBuffer = nullptr;
135135 // Avoid unnecessary virtual function calls
138138 pd3d11Resource = pTexture ? pTexture->TextureBaseD3D11::GetD3D11Texture() : nullptr;
139139 }
140140
141 __forceinline void Set(RefCntAutoPtr<BufferViewD3D11Impl>&& pBufView)
141 __forceinline void Set(RefCntAutoPtr<BufferViewD3D11Impl> pBufView)
142142 {
143143 pTexture = nullptr;
144144 // Avoid unnecessary virtual function calls
148148 }
149149 };
150150
151 using TResourceCount = std::array<Uint8, D3D11_RESOURCE_RANGE_COUNT>;
152 static size_t GetRequriedMemorySize(const TResourceCount& ResCount);
153
154 void Initialize(const TResourceCount& ResCount, IMemoryAllocator& MemAllocator);
155
156 __forceinline void SetCB(Uint32 CacheOffset, BindPointsD3D11 BindPoints, RefCntAutoPtr<BufferD3D11Impl>&& pBuffD3D11Impl)
151 static constexpr int NumShaderTypes = BindPointsD3D11::NumShaderTypes;
152 using TBindingsPerStage = std::array<std::array<Uint8, NumShaderTypes>, D3D11_RESOURCE_RANGE_COUNT>;
153
154 static size_t GetRequriedMemorySize(const TBindingsPerStage& ResCount);
155
156 void Initialize(const TBindingsPerStage& ResCount, IMemoryAllocator& MemAllocator);
157
158 __forceinline void SetCB(BindPointsD3D11 BindPoints, RefCntAutoPtr<BufferD3D11Impl> pBuffD3D11Impl)
157159 {
158160 auto* pd3d11Buff = pBuffD3D11Impl ? pBuffD3D11Impl->BufferD3D11Impl::GetD3D11Buffer() : nullptr;
159 SetD3D11ResourceInternal<CachedCB>(CacheOffset, GetCBCount(), BindPoints, &ShaderResourceCacheD3D11::GetCBArrays, std::move(pBuffD3D11Impl), pd3d11Buff);
160 }
161
162 __forceinline void SetTexSRV(Uint32 CacheOffset, BindPointsD3D11 BindPoints, RefCntAutoPtr<TextureViewD3D11Impl>&& pTexView)
161 SetD3D11ResourceInternal<CachedCB>(BindPoints, &ShaderResourceCacheD3D11::GetCBCount, &ShaderResourceCacheD3D11::GetCBArrays, std::move(pBuffD3D11Impl), pd3d11Buff);
162 }
163
164 __forceinline void SetTexSRV(BindPointsD3D11 BindPoints, RefCntAutoPtr<TextureViewD3D11Impl> pTexView)
163165 {
164166 auto* pd3d11SRV = pTexView ? static_cast<ID3D11ShaderResourceView*>(pTexView->TextureViewD3D11Impl::GetD3D11View()) : nullptr;
165 SetD3D11ResourceInternal<CachedResource>(CacheOffset, GetSRVCount(), BindPoints, &ShaderResourceCacheD3D11::GetSRVArrays, std::move(pTexView), pd3d11SRV);
166 }
167
168 __forceinline void SetBufSRV(Uint32 CacheOffset, BindPointsD3D11 BindPoints, RefCntAutoPtr<BufferViewD3D11Impl>&& pBuffView)
167 SetD3D11ResourceInternal<CachedResource>(BindPoints, &ShaderResourceCacheD3D11::GetSRVCount, &ShaderResourceCacheD3D11::GetSRVArrays, std::move(pTexView), pd3d11SRV);
168 }
169
170 __forceinline void SetBufSRV(BindPointsD3D11 BindPoints, RefCntAutoPtr<BufferViewD3D11Impl> pBuffView)
169171 {
170172 auto* pd3d11SRV = pBuffView ? static_cast<ID3D11ShaderResourceView*>(pBuffView->BufferViewD3D11Impl::GetD3D11View()) : nullptr;
171 SetD3D11ResourceInternal<CachedResource>(CacheOffset, GetSRVCount(), BindPoints, &ShaderResourceCacheD3D11::GetSRVArrays, std::move(pBuffView), pd3d11SRV);
172 }
173
174 __forceinline void SetTexUAV(Uint32 CacheOffset, BindPointsD3D11 BindPoints, RefCntAutoPtr<TextureViewD3D11Impl>&& pTexView)
173 SetD3D11ResourceInternal<CachedResource>(BindPoints, &ShaderResourceCacheD3D11::GetSRVCount, &ShaderResourceCacheD3D11::GetSRVArrays, std::move(pBuffView), pd3d11SRV);
174 }
175
176 __forceinline void SetTexUAV(BindPointsD3D11 BindPoints, RefCntAutoPtr<TextureViewD3D11Impl> pTexView)
175177 {
176178 auto* pd3d11UAV = pTexView ? static_cast<ID3D11UnorderedAccessView*>(pTexView->TextureViewD3D11Impl::GetD3D11View()) : nullptr;
177 SetD3D11ResourceInternal<CachedResource>(CacheOffset, GetUAVCount(), BindPoints, &ShaderResourceCacheD3D11::GetUAVArrays, std::move(pTexView), pd3d11UAV);
178 }
179
180 __forceinline void SetBufUAV(Uint32 CacheOffset, BindPointsD3D11 BindPoints, RefCntAutoPtr<BufferViewD3D11Impl>&& pBuffView)
179 SetD3D11ResourceInternal<CachedResource>(BindPoints, &ShaderResourceCacheD3D11::GetUAVCount, &ShaderResourceCacheD3D11::GetUAVArrays, std::move(pTexView), pd3d11UAV);
180 }
181
182 __forceinline void SetBufUAV(BindPointsD3D11 BindPoints, RefCntAutoPtr<BufferViewD3D11Impl> pBuffView)
181183 {
182184 auto* pd3d11UAV = pBuffView ? static_cast<ID3D11UnorderedAccessView*>(pBuffView->BufferViewD3D11Impl::GetD3D11View()) : nullptr;
183 SetD3D11ResourceInternal<CachedResource>(CacheOffset, GetUAVCount(), BindPoints, &ShaderResourceCacheD3D11::GetUAVArrays, std::move(pBuffView), pd3d11UAV);
184 }
185
186 __forceinline void SetSampler(Uint32 CacheOffset, BindPointsD3D11 BindPoints, SamplerD3D11Impl* pSampler)
185 SetD3D11ResourceInternal<CachedResource>(BindPoints, &ShaderResourceCacheD3D11::GetUAVCount, &ShaderResourceCacheD3D11::GetUAVArrays, std::move(pBuffView), pd3d11UAV);
186 }
187
188 __forceinline void SetSampler(BindPointsD3D11 BindPoints, SamplerD3D11Impl* pSampler)
187189 {
188190 auto* pd3d11Sampler = pSampler ? pSampler->SamplerD3D11Impl::GetD3D11SamplerState() : nullptr;
189 SetD3D11ResourceInternal<CachedSampler>(CacheOffset, GetSamplerCount(), BindPoints, &ShaderResourceCacheD3D11::GetSamplerArrays, pSampler, pd3d11Sampler);
190 }
191
192
193 __forceinline CachedCB const& GetCB(Uint32 CacheOffset) const
194 {
195 VERIFY(CacheOffset < GetCBCount(), "CB slot is out of range");
196 ShaderResourceCacheD3D11::CachedCB* CBs;
197 ID3D11Buffer** pd3d11CBs;
198 BindPointsD3D11* bindPoints;
199 GetCBArrays(CBs, pd3d11CBs, bindPoints);
200 return CBs[CacheOffset];
201 }
202
203 __forceinline CachedResource const& GetSRV(Uint32 CacheOffset) const
204 {
205 VERIFY(CacheOffset < GetSRVCount(), "SRV slot is out of range");
206 ShaderResourceCacheD3D11::CachedResource* SRVResources;
207 ID3D11ShaderResourceView** pd3d11SRVs;
208 BindPointsD3D11* bindPoints;
209 GetSRVArrays(SRVResources, pd3d11SRVs, bindPoints);
210 return SRVResources[CacheOffset];
211 }
212
213 __forceinline CachedResource const& GetUAV(Uint32 CacheOffset) const
214 {
215 VERIFY(CacheOffset < GetUAVCount(), "UAV slot is out of range");
216 ShaderResourceCacheD3D11::CachedResource* UAVResources;
217 ID3D11UnorderedAccessView** pd3d11UAVs;
218 BindPointsD3D11* bindPoints;
219 GetUAVArrays(UAVResources, pd3d11UAVs, bindPoints);
220 return UAVResources[CacheOffset];
221 }
222
223 __forceinline CachedSampler const& GetSampler(Uint32 CacheOffset) const
224 {
225 VERIFY(CacheOffset < GetSamplerCount(), "Sampler slot is out of range");
226 ShaderResourceCacheD3D11::CachedSampler* Samplers;
227 ID3D11SamplerState** pd3d11Samplers;
228 BindPointsD3D11* bindPoints;
229 GetSamplerArrays(Samplers, pd3d11Samplers, bindPoints);
230 return Samplers[CacheOffset];
231 }
232
233
234 __forceinline bool IsCBBound(Uint32 CacheOffset) const
235 {
236 CachedCB const* CBs;
237 ID3D11Buffer* const* d3d11CBs;
238 BindPointsD3D11 const* bindPoints;
239 GetConstCBArrays(CBs, d3d11CBs, bindPoints);
240 if (CacheOffset < GetCBCount() && d3d11CBs[CacheOffset] != nullptr)
241 {
242 VERIFY(CBs[CacheOffset].pBuff != nullptr, "No relevant buffer resource");
243 return true;
244 }
245 return false;
246 }
247
248 __forceinline bool IsSRVBound(Uint32 CacheOffset, bool dbgIsTextureView) const
249 {
250 CachedResource const* SRVResources;
251 ID3D11ShaderResourceView* const* d3d11SRVs;
252 BindPointsD3D11 const* bindPoints;
253 GetConstSRVArrays(SRVResources, d3d11SRVs, bindPoints);
254 if (CacheOffset < GetSRVCount() && d3d11SRVs[CacheOffset] != nullptr)
255 {
256 VERIFY((dbgIsTextureView && SRVResources[CacheOffset].pTexture != nullptr) || (!dbgIsTextureView && SRVResources[CacheOffset].pBuffer != nullptr),
257 "No relevant resource");
258 return true;
259 }
260 return false;
261 }
262
263 __forceinline bool IsUAVBound(Uint32 CacheOffset, bool dbgIsTextureView) const
264 {
265 CachedResource const* UAVResources;
266 ID3D11UnorderedAccessView* const* d3d11UAVs;
267 BindPointsD3D11 const* bindPoints;
268 GetConstUAVArrays(UAVResources, d3d11UAVs, bindPoints);
269 if (CacheOffset < GetUAVCount() && d3d11UAVs[CacheOffset] != nullptr)
270 {
271 VERIFY((dbgIsTextureView && UAVResources[CacheOffset].pTexture != nullptr) || (!dbgIsTextureView && UAVResources[CacheOffset].pBuffer != nullptr),
272 "No relevant resource");
273 return true;
274 }
275 return false;
276 }
277
278 __forceinline bool IsSamplerBound(Uint32 CacheOffset) const
279 {
280 CachedSampler const* Samplers;
281 ID3D11SamplerState* const* d3d11Samplers;
282 BindPointsD3D11 const* bindPoints;
283 GetConstSamplerArrays(Samplers, d3d11Samplers, bindPoints);
284 if (CacheOffset < GetSamplerCount() && d3d11Samplers[CacheOffset] != nullptr)
285 {
286 VERIFY(Samplers[CacheOffset].pSampler != nullptr, "No relevant sampler");
287 return true;
288 }
289 return false;
191 SetD3D11ResourceInternal<CachedSampler>(BindPoints, &ShaderResourceCacheD3D11::GetSamplerCount, &ShaderResourceCacheD3D11::GetSamplerArrays, pSampler, pd3d11Sampler);
192 }
193
194
195 __forceinline CachedCB const& GetCB(BindPointsD3D11 BindPoints) const
196 {
197 const Uint32 ShaderInd = PlatformMisc::GetLSB(BindPoints.GetActiveBits());
198 VERIFY(BindPoints[ShaderInd] < GetCBCount(ShaderInd), "CB slot is out of range");
199 ShaderResourceCacheD3D11::CachedCB const* CBs;
200 ID3D11Buffer* const* pd3d11CBs;
201 GetConstCBArrays(ShaderInd, CBs, pd3d11CBs);
202 return CBs[BindPoints[ShaderInd]];
203 }
204
205 __forceinline CachedResource const& GetSRV(BindPointsD3D11 BindPoints) const
206 {
207 const Uint32 ShaderInd = PlatformMisc::GetLSB(BindPoints.GetActiveBits());
208 VERIFY(BindPoints[ShaderInd] < GetSRVCount(ShaderInd), "SRV slot is out of range");
209 ShaderResourceCacheD3D11::CachedResource const* SRVResources;
210 ID3D11ShaderResourceView* const* pd3d11SRVs;
211 GetConstSRVArrays(ShaderInd, SRVResources, pd3d11SRVs);
212 return SRVResources[BindPoints[ShaderInd]];
213 }
214
215 __forceinline CachedResource const& GetUAV(BindPointsD3D11 BindPoints) const
216 {
217 const Uint32 ShaderInd = PlatformMisc::GetLSB(BindPoints.GetActiveBits());
218 VERIFY(BindPoints[ShaderInd] < GetUAVCount(ShaderInd), "UAV slot is out of range");
219 ShaderResourceCacheD3D11::CachedResource const* UAVResources;
220 ID3D11UnorderedAccessView* const* pd3d11UAVs;
221 GetConstUAVArrays(ShaderInd, UAVResources, pd3d11UAVs);
222 return UAVResources[BindPoints[ShaderInd]];
223 }
224
225 __forceinline CachedSampler const& GetSampler(BindPointsD3D11 BindPoints) const
226 {
227 const Uint32 ShaderInd = PlatformMisc::GetLSB(BindPoints.GetActiveBits());
228 VERIFY(BindPoints[ShaderInd] < GetSamplerCount(ShaderInd), "Sampler slot is out of range");
229 ShaderResourceCacheD3D11::CachedSampler const* Samplers;
230 ID3D11SamplerState* const* pd3d11Samplers;
231 GetConstSamplerArrays(ShaderInd, Samplers, pd3d11Samplers);
232 return Samplers[BindPoints[ShaderInd]];
233 }
234
235
236 __forceinline bool CopyCB(const ShaderResourceCacheD3D11& SrcCache, BindPointsD3D11 BindPoints)
237 {
238 bool IsBound = true;
239 for (Uint32 ActiveBits = BindPoints.GetActiveBits(); ActiveBits != 0;)
240 {
241 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
242 ActiveBits &= ~(1u << ShaderInd);
243
244 CachedCB const* pSrcCBs;
245 ID3D11Buffer* const* pSrcd3d11CBs;
246 SrcCache.GetConstCBArrays(ShaderInd, pSrcCBs, pSrcd3d11CBs);
247
248 CachedCB* pCBs;
249 ID3D11Buffer** pd3d11CBs;
250 GetCBArrays(ShaderInd, pCBs, pd3d11CBs);
251
252 const Uint32 CacheOffset = BindPoints[ShaderInd];
253 VERIFY(CacheOffset < GetCBCount(ShaderInd), "Index is out of range");
254 if (pSrcCBs[CacheOffset].pBuff == nullptr)
255 IsBound = false;
256
257 pCBs[CacheOffset] = pSrcCBs[CacheOffset];
258 pd3d11CBs[CacheOffset] = pSrcd3d11CBs[CacheOffset];
259 }
260 return IsBound;
261 }
262
263 __forceinline bool CopySRV(const ShaderResourceCacheD3D11& SrcCache, BindPointsD3D11 BindPoints)
264 {
265 bool IsBound = true;
266 for (Uint32 ActiveBits = BindPoints.GetActiveBits(); ActiveBits != 0;)
267 {
268 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
269 ActiveBits &= ~(1u << ShaderInd);
270
271 CachedResource const* pSrcSRVResources;
272 ID3D11ShaderResourceView* const* pSrcd3d11SRVs;
273 SrcCache.GetConstSRVArrays(ShaderInd, pSrcSRVResources, pSrcd3d11SRVs);
274
275 CachedResource* pSRVResources;
276 ID3D11ShaderResourceView** pd3d11SRVs;
277 GetSRVArrays(ShaderInd, pSRVResources, pd3d11SRVs);
278
279 const Uint32 CacheOffset = BindPoints[ShaderInd];
280 VERIFY(CacheOffset < GetSRVCount(ShaderInd), "Index is out of range");
281 if (pSrcSRVResources[CacheOffset].pBuffer == nullptr && pSrcSRVResources[CacheOffset].pTexture == nullptr)
282 IsBound = false;
283
284 pSRVResources[CacheOffset] = pSrcSRVResources[CacheOffset];
285 pd3d11SRVs[CacheOffset] = pSrcd3d11SRVs[CacheOffset];
286 }
287 return IsBound;
288 }
289
290 __forceinline bool CopyUAV(const ShaderResourceCacheD3D11& SrcCache, BindPointsD3D11 BindPoints)
291 {
292 bool IsBound = true;
293 for (Uint32 ActiveBits = BindPoints.GetActiveBits(); ActiveBits != 0;)
294 {
295 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
296 ActiveBits &= ~(1u << ShaderInd);
297
298 CachedResource const* pSrcUAVResources;
299 ID3D11UnorderedAccessView* const* pSrcd3d11UAVs;
300 SrcCache.GetConstUAVArrays(ShaderInd, pSrcUAVResources, pSrcd3d11UAVs);
301
302 CachedResource* pUAVResources;
303 ID3D11UnorderedAccessView** pd3d11UAVs;
304 GetUAVArrays(ShaderInd, pUAVResources, pd3d11UAVs);
305
306 const Uint32 CacheOffset = BindPoints[ShaderInd];
307 VERIFY(CacheOffset < GetUAVCount(ShaderInd), "Index is out of range");
308 if (pSrcUAVResources[CacheOffset].pBuffer == nullptr && pSrcUAVResources[CacheOffset].pTexture == nullptr)
309 IsBound = false;
310
311 pUAVResources[CacheOffset] = pSrcUAVResources[CacheOffset];
312 pd3d11UAVs[CacheOffset] = pSrcd3d11UAVs[CacheOffset];
313 }
314 return IsBound;
315 }
316
317 __forceinline bool CopySampler(const ShaderResourceCacheD3D11& SrcCache, BindPointsD3D11 BindPoints)
318 {
319 bool IsBound = true;
320 for (Uint32 ActiveBits = BindPoints.GetActiveBits(); ActiveBits != 0;)
321 {
322 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
323 ActiveBits &= ~(1u << ShaderInd);
324
325 CachedSampler const* pSrcSamplers;
326 ID3D11SamplerState* const* pSrcd3d11Samplers;
327 SrcCache.GetConstSamplerArrays(ShaderInd, pSrcSamplers, pSrcd3d11Samplers);
328
329 CachedSampler* pSamplers;
330 ID3D11SamplerState** pd3d11Samplers;
331 GetSamplerArrays(ShaderInd, pSamplers, pd3d11Samplers);
332
333 const Uint32 CacheOffset = BindPoints[ShaderInd];
334 VERIFY(CacheOffset < GetSamplerCount(ShaderInd), "Index is out of range");
335 if (pSrcSamplers[CacheOffset].pSampler == nullptr)
336 IsBound = false;
337
338 pSamplers[CacheOffset] = pSrcSamplers[CacheOffset];
339 pd3d11Samplers[CacheOffset] = pSrcd3d11Samplers[CacheOffset];
340 }
341 return IsBound;
342 }
343
344
345 __forceinline bool IsCBBound(BindPointsD3D11 BindPoints) const
346 {
347 bool IsBound = true;
348 for (Uint32 ActiveBits = BindPoints.GetActiveBits(); ActiveBits != 0;)
349 {
350 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
351 ActiveBits &= ~(1u << ShaderInd);
352 const Uint32 CacheOffset = BindPoints[ShaderInd];
353
354 CachedCB const* CBs;
355 ID3D11Buffer* const* d3d11CBs;
356 GetConstCBArrays(ShaderInd, CBs, d3d11CBs);
357 if (CacheOffset < GetCBCount(ShaderInd) && d3d11CBs[CacheOffset] != nullptr)
358 {
359 VERIFY(CBs[CacheOffset].pBuff != nullptr, "No relevant buffer resource");
360 continue;
361 }
362 IsBound = false;
363 }
364 return IsBound;
365 }
366
367 __forceinline bool IsSRVBound(BindPointsD3D11 BindPoints, bool dbgIsTextureView) const
368 {
369 bool IsBound = true;
370 for (Uint32 ActiveBits = BindPoints.GetActiveBits(); ActiveBits != 0;)
371 {
372 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
373 ActiveBits &= ~(1u << ShaderInd);
374 const Uint32 CacheOffset = BindPoints[ShaderInd];
375
376 CachedResource const* SRVResources;
377 ID3D11ShaderResourceView* const* d3d11SRVs;
378 GetConstSRVArrays(ShaderInd, SRVResources, d3d11SRVs);
379 if (CacheOffset < GetSRVCount(ShaderInd) && d3d11SRVs[CacheOffset] != nullptr)
380 {
381 VERIFY((dbgIsTextureView && SRVResources[CacheOffset].pTexture != nullptr) || (!dbgIsTextureView && SRVResources[CacheOffset].pBuffer != nullptr),
382 "No relevant resource");
383 continue;
384 }
385 IsBound = false;
386 }
387 return IsBound;
388 }
389
390 __forceinline bool IsUAVBound(BindPointsD3D11 BindPoints, bool dbgIsTextureView) const
391 {
392 bool IsBound = true;
393 for (Uint32 ActiveBits = BindPoints.GetActiveBits(); ActiveBits != 0;)
394 {
395 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
396 ActiveBits &= ~(1u << ShaderInd);
397 const Uint32 CacheOffset = BindPoints[ShaderInd];
398
399 CachedResource const* UAVResources;
400 ID3D11UnorderedAccessView* const* d3d11UAVs;
401 GetConstUAVArrays(ShaderInd, UAVResources, d3d11UAVs);
402 if (CacheOffset < GetUAVCount(ShaderInd) && d3d11UAVs[CacheOffset] != nullptr)
403 {
404 VERIFY((dbgIsTextureView && UAVResources[CacheOffset].pTexture != nullptr) || (!dbgIsTextureView && UAVResources[CacheOffset].pBuffer != nullptr),
405 "No relevant resource");
406 continue;
407 }
408 IsBound = false;
409 }
410 return IsBound;
411 }
412
413 __forceinline bool IsSamplerBound(BindPointsD3D11 BindPoints) const
414 {
415 bool IsBound = true;
416 for (Uint32 ActiveBits = BindPoints.GetActiveBits(); ActiveBits != 0;)
417 {
418 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
419 ActiveBits &= ~(1u << ShaderInd);
420 const Uint32 CacheOffset = BindPoints[ShaderInd];
421
422 CachedSampler const* Samplers;
423 ID3D11SamplerState* const* d3d11Samplers;
424 GetConstSamplerArrays(ShaderInd, Samplers, d3d11Samplers);
425 if (CacheOffset < GetSamplerCount(ShaderInd) && d3d11Samplers[CacheOffset] != nullptr)
426 {
427 VERIFY(Samplers[CacheOffset].pSampler != nullptr, "No relevant sampler");
428 continue;
429 }
430 IsBound = false;
431 }
432 return IsBound;
290433 }
291434
292435 #ifdef DILIGENT_DEVELOPMENT
294437 #endif
295438
296439 // clang-format off
297 __forceinline Uint32 GetCBCount() const { return m_CBCount; }
298 __forceinline Uint32 GetSRVCount() const { return m_SRVCount; }
299 __forceinline Uint32 GetSamplerCount() const { return m_SamplerCount; }
300 __forceinline Uint32 GetUAVCount() const { return m_UAVCount; }
440 __forceinline Uint32 GetCBCount (Uint32 ShaderInd) const { return (m_Offsets[CBOffset + ShaderInd + 1] - m_Offsets[CBOffset + ShaderInd]) / (sizeof(CachedCB) + sizeof(ID3D11Buffer*)); }
441 __forceinline Uint32 GetSRVCount (Uint32 ShaderInd) const { return (m_Offsets[SRVOffset + ShaderInd + 1] - m_Offsets[SRVOffset + ShaderInd]) / (sizeof(CachedResource) + sizeof(ID3D11ShaderResourceView*)); }
442 __forceinline Uint32 GetSamplerCount(Uint32 ShaderInd) const { return (m_Offsets[SampOffset + ShaderInd + 1] - m_Offsets[SampOffset + ShaderInd]) / (sizeof(CachedSampler) + sizeof(ID3D11SamplerState*)); }
443 __forceinline Uint32 GetUAVCount (Uint32 ShaderInd) const { return (m_Offsets[UAVOffset + ShaderInd + 1] - m_Offsets[UAVOffset + ShaderInd]) / (sizeof(CachedResource) + sizeof(ID3D11UnorderedAccessView*)); }
301444 // clang-format on
302445
303 __forceinline void GetCBArrays(CachedCB*& CBs, ID3D11Buffer**& pd3d11CBs, BindPointsD3D11*& pBindPoints) const
446 __forceinline void GetCBArrays(Uint32 ShaderInd, CachedCB*& CBs, ID3D11Buffer**& pd3d11CBs) const
304447 {
305448 VERIFY(alignof(CachedCB) == alignof(ID3D11Buffer*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
306 CBs = reinterpret_cast<CachedCB*>(m_pResourceData.get() + m_CBOffset);
307 pd3d11CBs = reinterpret_cast<ID3D11Buffer**>(CBs + GetCBCount());
308 pBindPoints = reinterpret_cast<BindPointsD3D11*>(pd3d11CBs + GetCBCount());
309 }
310
311 __forceinline void GetSRVArrays(CachedResource*& SRVResources, ID3D11ShaderResourceView**& d3d11SRVs, BindPointsD3D11*& pBindPoints) const
449 CBs = reinterpret_cast<CachedCB*>(m_pResourceData.get() + m_Offsets[CBOffset + ShaderInd]);
450 pd3d11CBs = reinterpret_cast<ID3D11Buffer**>(CBs + GetCBCount(ShaderInd));
451 }
452
453 __forceinline void GetSRVArrays(Uint32 ShaderInd, CachedResource*& SRVResources, ID3D11ShaderResourceView**& d3d11SRVs) const
312454 {
313455 VERIFY(alignof(CachedResource) == alignof(ID3D11ShaderResourceView*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
314 SRVResources = reinterpret_cast<CachedResource*>(m_pResourceData.get() + m_SRVOffset);
315 d3d11SRVs = reinterpret_cast<ID3D11ShaderResourceView**>(SRVResources + GetSRVCount());
316 pBindPoints = reinterpret_cast<BindPointsD3D11*>(d3d11SRVs + GetSRVCount());
317 }
318
319 __forceinline void GetSamplerArrays(CachedSampler*& Samplers, ID3D11SamplerState**& pd3d11Samplers, BindPointsD3D11*& pBindPoints) const
456 SRVResources = reinterpret_cast<CachedResource*>(m_pResourceData.get() + m_Offsets[SRVOffset + ShaderInd]);
457 d3d11SRVs = reinterpret_cast<ID3D11ShaderResourceView**>(SRVResources + GetSRVCount(ShaderInd));
458 }
459
460 __forceinline void GetSamplerArrays(Uint32 ShaderInd, CachedSampler*& Samplers, ID3D11SamplerState**& pd3d11Samplers) const
320461 {
321462 VERIFY(alignof(CachedSampler) == alignof(ID3D11SamplerState*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
322 Samplers = reinterpret_cast<CachedSampler*>(m_pResourceData.get() + m_SamplerOffset);
323 pd3d11Samplers = reinterpret_cast<ID3D11SamplerState**>(Samplers + GetSamplerCount());
324 pBindPoints = reinterpret_cast<BindPointsD3D11*>(pd3d11Samplers + GetSamplerCount());
325 }
326
327 __forceinline void GetUAVArrays(CachedResource*& UAVResources, ID3D11UnorderedAccessView**& pd3d11UAVs, BindPointsD3D11*& pBindPoints) const
463 Samplers = reinterpret_cast<CachedSampler*>(m_pResourceData.get() + m_Offsets[SampOffset + ShaderInd]);
464 pd3d11Samplers = reinterpret_cast<ID3D11SamplerState**>(Samplers + GetSamplerCount(ShaderInd));
465 }
466
467 __forceinline void GetUAVArrays(Uint32 ShaderInd, CachedResource*& UAVResources, ID3D11UnorderedAccessView**& pd3d11UAVs) const
328468 {
329469 VERIFY(alignof(CachedResource) == alignof(ID3D11UnorderedAccessView*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
330 UAVResources = reinterpret_cast<CachedResource*>(m_pResourceData.get() + m_UAVOffset);
331 pd3d11UAVs = reinterpret_cast<ID3D11UnorderedAccessView**>(UAVResources + GetUAVCount());
332 pBindPoints = reinterpret_cast<BindPointsD3D11*>(pd3d11UAVs + GetUAVCount());
333 }
334
335 __forceinline void GetConstCBArrays(CachedCB const*& CBs, ID3D11Buffer* const*& pd3d11CBs, BindPointsD3D11 const*& pBindPoints) const
470 UAVResources = reinterpret_cast<CachedResource*>(m_pResourceData.get() + m_Offsets[UAVOffset + ShaderInd]);
471 pd3d11UAVs = reinterpret_cast<ID3D11UnorderedAccessView**>(UAVResources + GetUAVCount(ShaderInd));
472 }
473
474 __forceinline void GetConstCBArrays(Uint32 ShaderInd, CachedCB const*& CBs, ID3D11Buffer* const*& pd3d11CBs) const
336475 {
337476 VERIFY(alignof(CachedCB) == alignof(ID3D11Buffer*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
338 CBs = reinterpret_cast<CachedCB const*>(m_pResourceData.get() + m_CBOffset);
339 pd3d11CBs = reinterpret_cast<ID3D11Buffer* const*>(CBs + GetCBCount());
340 pBindPoints = reinterpret_cast<BindPointsD3D11 const*>(pd3d11CBs + GetCBCount());
341 }
342
343 __forceinline void GetConstSRVArrays(CachedResource const*& SRVResources, ID3D11ShaderResourceView* const*& d3d11SRVs, BindPointsD3D11 const*& pBindPoints) const
477 CBs = reinterpret_cast<CachedCB const*>(m_pResourceData.get() + m_Offsets[CBOffset + ShaderInd]);
478 pd3d11CBs = reinterpret_cast<ID3D11Buffer* const*>(CBs + GetCBCount(ShaderInd));
479 }
480
481 __forceinline void GetConstSRVArrays(Uint32 ShaderInd, CachedResource const*& SRVResources, ID3D11ShaderResourceView* const*& d3d11SRVs) const
344482 {
345483 VERIFY(alignof(CachedResource) == alignof(ID3D11ShaderResourceView*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
346 SRVResources = reinterpret_cast<CachedResource const*>(m_pResourceData.get() + m_SRVOffset);
347 d3d11SRVs = reinterpret_cast<ID3D11ShaderResourceView* const*>(SRVResources + GetSRVCount());
348 pBindPoints = reinterpret_cast<BindPointsD3D11 const*>(d3d11SRVs + GetSRVCount());
349 }
350
351 __forceinline void GetConstSamplerArrays(CachedSampler const*& Samplers, ID3D11SamplerState* const*& pd3d11Samplers, BindPointsD3D11 const*& pBindPoints) const
484 SRVResources = reinterpret_cast<CachedResource const*>(m_pResourceData.get() + m_Offsets[SRVOffset + ShaderInd]);
485 d3d11SRVs = reinterpret_cast<ID3D11ShaderResourceView* const*>(SRVResources + GetSRVCount(ShaderInd));
486 }
487
488 __forceinline void GetConstSamplerArrays(Uint32 ShaderInd, CachedSampler const*& Samplers, ID3D11SamplerState* const*& pd3d11Samplers) const
352489 {
353490 VERIFY(alignof(CachedSampler) == alignof(ID3D11SamplerState*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
354 Samplers = reinterpret_cast<CachedSampler const*>(m_pResourceData.get() + m_SamplerOffset);
355 pd3d11Samplers = reinterpret_cast<ID3D11SamplerState* const*>(Samplers + GetSamplerCount());
356 pBindPoints = reinterpret_cast<BindPointsD3D11 const*>(pd3d11Samplers + GetSamplerCount());
357 }
358
359 __forceinline void GetConstUAVArrays(CachedResource const*& UAVResources, ID3D11UnorderedAccessView* const*& pd3d11UAVs, BindPointsD3D11 const*& pBindPoints) const
491 Samplers = reinterpret_cast<CachedSampler const*>(m_pResourceData.get() + m_Offsets[SampOffset + ShaderInd]);
492 pd3d11Samplers = reinterpret_cast<ID3D11SamplerState* const*>(Samplers + GetSamplerCount(ShaderInd));
493 }
494
495 __forceinline void GetConstUAVArrays(Uint32 ShaderInd, CachedResource const*& UAVResources, ID3D11UnorderedAccessView* const*& pd3d11UAVs) const
360496 {
361497 VERIFY(alignof(CachedResource) == alignof(ID3D11UnorderedAccessView*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
362 UAVResources = reinterpret_cast<CachedResource const*>(m_pResourceData.get() + m_UAVOffset);
363 pd3d11UAVs = reinterpret_cast<ID3D11UnorderedAccessView* const*>(UAVResources + GetUAVCount());
364 pBindPoints = reinterpret_cast<BindPointsD3D11 const*>(pd3d11UAVs + GetUAVCount());
365 }
366
367 __forceinline bool IsInitialized() const
368 {
369 return m_UAVOffset != InvalidResourceOffset;
370 }
498 UAVResources = reinterpret_cast<CachedResource const*>(m_pResourceData.get() + m_Offsets[UAVOffset + ShaderInd]);
499 pd3d11UAVs = reinterpret_cast<ID3D11UnorderedAccessView* const*>(UAVResources + GetUAVCount(ShaderInd));
500 }
501
502 bool IsInitialized() const { return m_IsInitialized; }
371503
372504 ResourceCacheContentType GetContentType() const { return m_ContentType; }
373505
506 void BindCBs(Uint32 ShaderInd,
507 ID3D11Buffer* CommittedD3D11CBs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT],
508 Uint8& Binding,
509 Uint32& MinSlot,
510 Uint32& MaxSlot) const;
511 void BindSRVs(Uint32 ShaderInd,
512 ID3D11ShaderResourceView* CommittedD3D11SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT],
513 ID3D11Resource* CommittedD3D11SRVResources[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT],
514 Uint8& Binding,
515 Uint32& MinSlot,
516 Uint32& MaxSlot) const;
517 void BindSamplers(Uint32 ShaderInd,
518 ID3D11SamplerState* CommittedD3D11Samplers[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT],
519 Uint8& Binding,
520 Uint32& MinSlot,
521 Uint32& MaxSlot) const;
522 void BindUAVs(Uint32 ShaderInd,
523 ID3D11UnorderedAccessView* CommittedD3D11UAVs[D3D11_PS_CS_UAV_REGISTER_COUNT],
524 ID3D11Resource* CommittedD3D11UAVResources[D3D11_PS_CS_UAV_REGISTER_COUNT],
525 Uint8& Binding,
526 Uint32& MinSlot,
527 Uint32& MaxSlot) const;
528
374529 private:
375 template <typename TCachedResourceType, typename TGetResourceArraysFunc, typename TSrcResourceType, typename TD3D11ResourceType>
376 __forceinline void SetD3D11ResourceInternal(Uint32 CacheOffset, Uint32 Size, BindPointsD3D11 BindPoints, TGetResourceArraysFunc GetArrays, TSrcResourceType&& pResource, TD3D11ResourceType* pd3d11Resource)
377 {
378 VERIFY(CacheOffset < Size, "Resource cache is not big enough");
530 template <typename TCachedResourceType, typename TGetResourceCount, typename TGetResourceArraysFunc, typename TSrcResourceType, typename TD3D11ResourceType>
531 __forceinline void SetD3D11ResourceInternal(BindPointsD3D11 BindPoints, TGetResourceCount GetCount, TGetResourceArraysFunc GetArrays, TSrcResourceType pResource, TD3D11ResourceType* pd3d11Resource)
532 {
379533 VERIFY(pResource != nullptr && pd3d11Resource != nullptr || pResource == nullptr && pd3d11Resource == nullptr,
380534 "Resource and D3D11 resource must be set/unset atomically");
381 TCachedResourceType* Resources;
382 TD3D11ResourceType** d3d11ResArr;
383 BindPointsD3D11* bindPoints;
384 (this->*GetArrays)(Resources, d3d11ResArr, bindPoints);
385 Resources[CacheOffset].Set(std::forward<TSrcResourceType>(pResource));
386 bindPoints[CacheOffset] = BindPoints;
387 d3d11ResArr[CacheOffset] = pd3d11Resource;
535 for (Uint32 ActiveBits = BindPoints.GetActiveBits(); ActiveBits != 0;)
536 {
537 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
538 ActiveBits &= ~(1u << ShaderInd);
539
540 const Uint32 CacheOffset = BindPoints[ShaderInd];
541 const Uint32 ResCount = (this->*GetCount)(ShaderInd);
542 VERIFY(CacheOffset < ResCount, "Index is out of range");
543
544 TCachedResourceType* Resources;
545 TD3D11ResourceType** d3d11ResArr;
546 (this->*GetArrays)(ShaderInd, Resources, d3d11ResArr);
547 Resources[CacheOffset].Set(pResource);
548 d3d11ResArr[CacheOffset] = pd3d11Resource;
549 }
388550 }
389551
390552 // Transitions or verifies the resource state.
403565 private:
404566 using OffsetType = Uint16;
405567
406 static constexpr size_t MaxAlignment = std::max(std::max(std::max(alignof(CachedCB), alignof(CachedResource)),
407 std::max(alignof(CachedSampler), alignof(BindPointsD3D11))),
568 static constexpr size_t MaxAlignment = std::max(std::max(std::max(alignof(CachedCB), alignof(CachedResource)), alignof(CachedSampler)),
408569 std::max(std::max(alignof(ID3D11Buffer*), alignof(ID3D11ShaderResourceView*)),
409570 std::max(alignof(ID3D11SamplerState*), alignof(ID3D11UnorderedAccessView*))));
410571
411 static constexpr OffsetType InvalidResourceOffset = std::numeric_limits<OffsetType>::max();
412
413 static constexpr OffsetType m_CBOffset = 0;
414 OffsetType m_SRVOffset = InvalidResourceOffset;
415 OffsetType m_SamplerOffset = InvalidResourceOffset;
416 OffsetType m_UAVOffset = InvalidResourceOffset;
417
418 static constexpr Uint32 _CBCountBits = 7;
419 static constexpr Uint32 _SRVCountBits = 10;
420 static constexpr Uint32 _SampCountBits = 7;
421 static constexpr Uint32 _UAVCountBits = 4;
422
423 static constexpr int NumShaderTypes = BindPointsD3D11::NumShaderTypes;
424
425 // clang-format off
426 static_assert((1U << _CBCountBits) >= (D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT * NumShaderTypes), "Not enough bits to represent CB count");
427 static_assert((1U << _SRVCountBits) >= (D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT * NumShaderTypes), "Not enough bits to represent SRV count");
428 static_assert((1U << _SampCountBits) >= (D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT * NumShaderTypes), "Not enough bits to represent Sampler count");
429 static_assert((1U << _UAVCountBits) >= D3D11_PS_CS_UAV_REGISTER_COUNT, "Not enough bits to represent UAV count");
430
431 Uint32 m_CBCount : _CBCountBits;
432 Uint32 m_SRVCount : _SRVCountBits;
433 Uint32 m_SamplerCount : _SampCountBits;
434 Uint32 m_UAVCount : _UAVCountBits;
435 // clang-format on
572 static constexpr Uint32 CBOffset = 0;
573 static constexpr Uint32 SRVOffset = CBOffset + NumShaderTypes;
574 static constexpr Uint32 SampOffset = SRVOffset + NumShaderTypes;
575 static constexpr Uint32 UAVOffset = SampOffset + NumShaderTypes;
576 static constexpr Uint32 MaxOffsets = UAVOffset + NumShaderTypes + 1;
577
578 std::array<OffsetType, MaxOffsets> m_Offsets = {};
579
580 bool m_IsInitialized = false;
436581
437582 // Indicates what types of resources are stored in the cache
438583 const ResourceCacheContentType m_ContentType;
439584
440585 std::unique_ptr<Uint8, STDDeleter<Uint8, IMemoryAllocator>> m_pResourceData;
441586 };
587
588 static constexpr size_t ResCacheSize = sizeof(ShaderResourceCacheD3D11);
442589
443590 // Instantiate templates
444591 template void ShaderResourceCacheD3D11::TransitionResourceStates<ShaderResourceCacheD3D11::StateTransitionMode::Transition>(DeviceContextD3D11Impl& Ctx);
132132 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
133133 {
134134 VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
135 return m_ParentManager.m_ResourceCache.IsCBBound(GetAttribs().CacheOffset + ArrayIndex);
135 return m_ParentManager.m_ResourceCache.IsCBBound(GetAttribs().BindPoints + ArrayIndex);
136136 }
137137 };
138138
148148 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
149149 {
150150 VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
151 return m_ParentManager.m_ResourceCache.IsSRVBound(GetAttribs().CacheOffset + ArrayIndex, true);
151 return m_ParentManager.m_ResourceCache.IsSRVBound(GetAttribs().BindPoints + ArrayIndex, true);
152152 }
153153 };
154154
164164 __forceinline virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
165165 {
166166 VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
167 return m_ParentManager.m_ResourceCache.IsUAVBound(GetAttribs().CacheOffset + ArrayIndex, true);
167 return m_ParentManager.m_ResourceCache.IsUAVBound(GetAttribs().BindPoints + ArrayIndex, true);
168168 }
169169 };
170170
180180 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
181181 {
182182 VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
183 return m_ParentManager.m_ResourceCache.IsUAVBound(GetAttribs().CacheOffset + ArrayIndex, false);
183 return m_ParentManager.m_ResourceCache.IsUAVBound(GetAttribs().BindPoints + ArrayIndex, false);
184184 }
185185 };
186186
196196 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
197197 {
198198 VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
199 return m_ParentManager.m_ResourceCache.IsSRVBound(GetAttribs().CacheOffset + ArrayIndex, false);
199 return m_ParentManager.m_ResourceCache.IsSRVBound(GetAttribs().BindPoints + ArrayIndex, false);
200200 }
201201 };
202202
212212 virtual bool DILIGENT_CALL_TYPE IsBound(Uint32 ArrayIndex) const override final
213213 {
214214 VERIFY_EXPR(ArrayIndex < GetDesc().ArraySize);
215 return m_ParentManager.m_ResourceCache.IsSamplerBound(GetAttribs().CacheOffset + ArrayIndex);
215 return m_ParentManager.m_ResourceCache.IsSamplerBound(GetAttribs().BindPoints + ArrayIndex);
216216 }
217217 };
218218
265265
266266 void DeviceContextD3D11Impl::BindCacheResources(const ShaderResourceCacheD3D11& ResourceCache,
267267 const TBindingsPerStage& BaseBindings,
268 TMinMaxSlotPerStage& MinMaxSlot,
269268 SHADER_TYPE ActiveStages)
270269 {
271 const auto CBCount = ResourceCache.GetCBCount();
272 if (CBCount != 0)
273 {
274 constexpr auto Range = D3D11_RESOURCE_RANGE_CBV;
275 ShaderResourceCacheD3D11::CachedCB const* CBs;
276 ID3D11Buffer* const* d3d11CBs;
277 BindPointsD3D11 const* bindPoints;
278 ResourceCache.GetConstCBArrays(CBs, d3d11CBs, bindPoints);
279
280 for (Uint32 cb = 0; cb < CBCount; ++cb)
281 {
282 const auto& BindPoints = bindPoints[cb];
283 Uint32 ActiveBits = BindPoints.GetActiveBits() & ActiveStages;
284 VERIFY(ActiveBits != 0, "resource is not initialized");
285 while (ActiveBits != 0)
270 struct MinMaxSlot
271 {
272 UINT MinSlot = UINT_MAX;
273 UINT MaxSlot = 0;
274 };
275 using TMinMaxSlotPerStage = std::array<MinMaxSlot, NumShaderTypes>;
276 using TBindings = TBindingsPerStage::value_type;
277
278 Uint8 ShaderIndices[NumShaderTypes] = {};
279 SHADER_TYPE ShaderTypes[NumShaderTypes] = {};
280 Uint32 ShaderCount = 0;
281
282 for (Uint32 Stages = ActiveStages; Stages != 0; ++ShaderCount)
283 {
284 const Uint32 ShaderInd = PlatformMisc::GetLSB(Stages);
285 Stages &= ~(1u << ShaderInd);
286 ShaderIndices[ShaderCount] = static_cast<Uint8>(ShaderInd);
287 ShaderTypes[ShaderCount] = static_cast<SHADER_TYPE>(1u << ShaderInd);
288 }
289
290 for (Uint32 i = 0; i < ShaderCount; ++i)
291 {
292 constexpr auto Range = D3D11_RESOURCE_RANGE_CBV;
293 const auto ShaderInd = ShaderIndices[i];
294 auto* CommittedD3D11CBs = m_CommittedRes.D3D11CBs[ShaderInd];
295 Uint8 Binding = BaseBindings[Range][ShaderInd];
296 Uint32 MinSlot = UINT_MAX;
297 Uint32 MaxSlot = 0;
298 ResourceCache.BindCBs(ShaderInd, CommittedD3D11CBs, Binding, MinSlot, MaxSlot);
299
300 if (MinSlot != UINT_MAX)
301 {
302 auto SetCBMethod = SetCBMethods[ShaderInd];
303 (m_pd3d11DeviceContext->*SetCBMethod)(MinSlot, MaxSlot - MinSlot + 1, CommittedD3D11CBs + MinSlot);
304 m_CommittedRes.NumCBs[ShaderInd] = std::max(m_CommittedRes.NumCBs[ShaderInd], Binding);
305 VERIFY_EXPR(MaxSlot < Binding);
306 }
307 #ifdef VERIFY_CONTEXT_BINDINGS
308 if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
309 {
310 DvpVerifyCommittedCBs(ShaderTypes[i]);
311 }
312 #endif
313 }
314
315 for (Uint32 i = 0; i < ShaderCount; ++i)
316 {
317 constexpr auto Range = D3D11_RESOURCE_RANGE_SRV;
318 const auto ShaderInd = ShaderIndices[i];
319 auto* CommittedD3D11SRVs = m_CommittedRes.D3D11SRVs[ShaderInd];
320 auto* CommittedD3D11SRVRes = m_CommittedRes.D3D11SRVResources[ShaderInd];
321 Uint8 Binding = BaseBindings[Range][ShaderInd];
322 Uint32 MinSlot = UINT_MAX;
323 Uint32 MaxSlot = 0;
324 ResourceCache.BindSRVs(ShaderInd, CommittedD3D11SRVs, CommittedD3D11SRVRes, Binding, MinSlot, MaxSlot);
325
326 if (MinSlot != UINT_MAX)
327 {
328 auto SetSRVMethod = SetSRVMethods[ShaderInd];
329 (m_pd3d11DeviceContext->*SetSRVMethod)(MinSlot, MaxSlot - MinSlot + 1, CommittedD3D11SRVs + MinSlot);
330 m_CommittedRes.NumSRVs[ShaderInd] = std::max(m_CommittedRes.NumSRVs[ShaderInd], Binding);
331 VERIFY_EXPR(MaxSlot <= Binding);
332 }
333 #ifdef VERIFY_CONTEXT_BINDINGS
334 if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
335 {
336 DvpVerifyCommittedSRVs(ShaderTypes[i]);
337 }
338 #endif
339 }
340
341 for (Uint32 i = 0; i < ShaderCount; ++i)
342 {
343 constexpr auto Range = D3D11_RESOURCE_RANGE_SAMPLER;
344 const auto ShaderInd = ShaderIndices[i];
345 auto* CommittedD3D11Samplers = m_CommittedRes.D3D11Samplers[ShaderInd];
346 Uint8 Binding = BaseBindings[Range][ShaderInd];
347 Uint32 MinSlot = UINT_MAX;
348 Uint32 MaxSlot = 0;
349 ResourceCache.BindSamplers(ShaderInd, CommittedD3D11Samplers, Binding, MinSlot, MaxSlot);
350
351 if (MinSlot != UINT_MAX)
352 {
353 auto SetSamplerMethod = SetSamplerMethods[ShaderInd];
354 (m_pd3d11DeviceContext->*SetSamplerMethod)(MinSlot, MaxSlot - MinSlot + 1, CommittedD3D11Samplers + MinSlot);
355 m_CommittedRes.NumSamplers[ShaderInd] = std::max(m_CommittedRes.NumSamplers[ShaderInd], Binding);
356 VERIFY_EXPR(MaxSlot < Binding);
357 }
358 #ifdef VERIFY_CONTEXT_BINDINGS
359 if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
360 {
361 DvpVerifyCommittedSamplers(ShaderTypes[i]);
362 }
363 #endif
364 }
365
366 bool ClearPixelShaderUAVs = m_CommittedRes.NumUAVs[PSInd] > 0;
367 for (Uint32 i = 0; i < ShaderCount; ++i)
368 {
369 constexpr auto Range = D3D11_RESOURCE_RANGE_UAV;
370 const auto ShaderInd = ShaderIndices[i];
371 auto* CommittedD3D11UAVs = m_CommittedRes.D3D11UAVs[ShaderInd];
372 auto* CommittedD3D11UAVRes = m_CommittedRes.D3D11UAVResources[ShaderInd];
373 Uint8 Binding = BaseBindings[Range][ShaderInd];
374 Uint32 MinSlot = UINT_MAX;
375 Uint32 MaxSlot = 0;
376 ResourceCache.BindUAVs(ShaderInd, CommittedD3D11UAVs, CommittedD3D11UAVRes, Binding, MinSlot, MaxSlot);
377
378 if (MinSlot != UINT_MAX)
379 {
380 if (ShaderInd == PSInd)
381 ClearPixelShaderUAVs = false;
382
383 // Something has changed
384 if (ShaderInd == PSInd)
286385 {
287 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
288 ActiveBits &= ~(1u << ShaderInd);
289 VERIFY_EXPR(BindPoints.IsValid(ShaderInd));
290
291 auto* CommittedD3D11CBs = m_CommittedRes.D3D11CBs[ShaderInd];
292 UINT& MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
293 UINT& MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
294 const UINT Slot = BaseBindings[ShaderInd][Range] + BindPoints[ShaderInd];
295 const bool IsNewCB = CommittedD3D11CBs[Slot] != d3d11CBs[cb];
296 MinSlot = IsNewCB ? std::min(MinSlot, Slot) : MinSlot;
297 MaxSlot = IsNewCB ? Slot : MaxSlot;
298
299 VERIFY_EXPR(!IsNewCB || (Slot >= MinSlot && Slot <= MaxSlot));
300 VERIFY_EXPR(d3d11CBs[cb] != nullptr);
301 CommittedD3D11CBs[Slot] = d3d11CBs[cb];
386 // Pixel shader UAVs cannot be set independently; they all need to be set at the same time.
387 // https://docs.microsoft.com/en-us/windows/desktop/api/d3d11/nf-d3d11-id3d11devicecontext-omsetrendertargetsandunorderedaccessviews#remarks
388 const auto StartUAVSlot = m_NumBoundRenderTargets;
389 const auto NumUAVSlot = Binding;
390 VERIFY(NumUAVSlot > StartUAVSlot, "Number of UAVs must be greater than the render target count");
391 m_pd3d11DeviceContext->OMSetRenderTargetsAndUnorderedAccessViews(
392 D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr,
393 StartUAVSlot, NumUAVSlot - StartUAVSlot, CommittedD3D11UAVs + StartUAVSlot, nullptr);
394 // Clear previously bound UAVs, but do not clear lower slots as if
395 // render target count reduces, we will bind these UAVs in CommitRenderTargets()
396 for (Uint32 uav = NumUAVSlot; uav < m_CommittedRes.NumUAVs[ShaderInd]; ++uav)
397 {
398 CommittedD3D11UAVRes[uav] = nullptr;
399 CommittedD3D11UAVs[uav] = nullptr;
400 }
401 m_CommittedRes.NumUAVs[ShaderInd] = NumUAVSlot;
302402 }
303 }
304 }
305
306 const auto SRVCount = ResourceCache.GetSRVCount();
307 if (SRVCount != 0)
308 {
309 constexpr auto Range = D3D11_RESOURCE_RANGE_SRV;
310 ShaderResourceCacheD3D11::CachedResource const* SRVResources;
311 ID3D11ShaderResourceView* const* d3d11SRVs;
312 BindPointsD3D11 const* bindPoints;
313 ResourceCache.GetConstSRVArrays(SRVResources, d3d11SRVs, bindPoints);
314
315 for (Uint32 srv = 0; srv < SRVCount; ++srv)
316 {
317 const auto& BindPoints = bindPoints[srv];
318 Uint32 ActiveBits = BindPoints.GetActiveBits() & ActiveStages;
319 VERIFY(ActiveBits != 0, "resource is not initialized");
320 while (ActiveBits != 0)
403 else if (ShaderInd == CSInd)
321404 {
322 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
323 ActiveBits &= ~(1u << ShaderInd);
324 VERIFY_EXPR(BindPoints.IsValid(ShaderInd));
325
326 auto* CommittedD3D11SRVs = m_CommittedRes.D3D11SRVs[ShaderInd];
327 auto* CommittedD3D11SRVRes = m_CommittedRes.D3D11SRVResources[ShaderInd];
328 UINT& MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
329 UINT& MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
330 const UINT Slot = BaseBindings[ShaderInd][Range] + BindPoints[ShaderInd];
331 const bool IsNewSRV = CommittedD3D11SRVs[Slot] != d3d11SRVs[srv];
332 MinSlot = IsNewSRV ? std::min(MinSlot, Slot) : MinSlot;
333 MaxSlot = IsNewSRV ? Slot : MaxSlot;
334
335 VERIFY_EXPR(!IsNewSRV || (Slot >= MinSlot && Slot <= MaxSlot));
336 VERIFY_EXPR(d3d11SRVs[srv] != nullptr);
337 CommittedD3D11SRVRes[Slot] = SRVResources[srv].pd3d11Resource;
338 CommittedD3D11SRVs[Slot] = d3d11SRVs[srv];
405 // This can only be CS
406 auto SetUAVMethod = SetUAVMethods[ShaderInd];
407 (m_pd3d11DeviceContext->*SetUAVMethod)(MinSlot, MaxSlot - MinSlot + 1, CommittedD3D11UAVs + MinSlot, nullptr);
408 m_CommittedRes.NumUAVs[ShaderInd] = std::max(m_CommittedRes.NumUAVs[ShaderInd], Binding);
409 VERIFY_EXPR(MaxSlot < Binding);
339410 }
340 }
341 }
342
343 const auto SamplerCount = ResourceCache.GetSamplerCount();
344 if (SamplerCount != 0)
345 {
346 constexpr auto Range = D3D11_RESOURCE_RANGE_SAMPLER;
347 ShaderResourceCacheD3D11::CachedSampler const* Samplers;
348 ID3D11SamplerState* const* d3d11Samplers;
349 BindPointsD3D11 const* bindPoints;
350 ResourceCache.GetConstSamplerArrays(Samplers, d3d11Samplers, bindPoints);
351
352 for (Uint32 sam = 0; sam < SamplerCount; ++sam)
353 {
354 const auto& BindPoints = bindPoints[sam];
355 Uint32 ActiveBits = BindPoints.GetActiveBits() & ActiveStages;
356 VERIFY(ActiveBits != 0, "resource is not initialized");
357 while (ActiveBits != 0)
411 else
358412 {
359 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
360 ActiveBits &= ~(1u << ShaderInd);
361 VERIFY_EXPR(BindPoints.IsValid(ShaderInd));
362
363 auto* CommittedD3D11Samplers = m_CommittedRes.D3D11Samplers[ShaderInd];
364 UINT& MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
365 UINT& MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
366 const UINT Slot = BaseBindings[ShaderInd][Range] + BindPoints[ShaderInd];
367 const bool IsNewSam = CommittedD3D11Samplers[Slot] != d3d11Samplers[sam];
368 MinSlot = IsNewSam ? std::min(MinSlot, Slot) : MinSlot;
369 MaxSlot = IsNewSam ? Slot : MaxSlot;
370
371 VERIFY_EXPR(!IsNewSam || (Slot >= MinSlot && Slot <= MaxSlot));
372 VERIFY_EXPR(d3d11Samplers[sam] != nullptr);
373 CommittedD3D11Samplers[Slot] = d3d11Samplers[sam];
413 UNEXPECTED("UAV is not supported in shader that is not pixel or compute");
374414 }
375415 }
376 }
377
378 const auto UAVCount = ResourceCache.GetUAVCount();
379 if (UAVCount != 0)
380 {
381 constexpr auto Range = D3D11_RESOURCE_RANGE_UAV;
382 ShaderResourceCacheD3D11::CachedResource const* UAVResources;
383 ID3D11UnorderedAccessView* const* d3d11UAVs;
384 BindPointsD3D11 const* bindPoints;
385 ResourceCache.GetConstUAVArrays(UAVResources, d3d11UAVs, bindPoints);
386
387 for (Uint32 uav = 0; uav < UAVCount; ++uav)
388 {
389 const auto& BindPoints = bindPoints[uav];
390 Uint32 ActiveBits = BindPoints.GetActiveBits() & ActiveStages;
391 VERIFY(ActiveBits != 0, "resource is not initialized");
392 while (ActiveBits != 0)
393 {
394 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
395 ActiveBits &= ~(1u << ShaderInd);
396 VERIFY_EXPR(BindPoints.IsValid(ShaderInd));
397
398 auto* CommittedD3D11UAVs = m_CommittedRes.D3D11UAVs[ShaderInd];
399 auto* CommittedD3D11UAVRes = m_CommittedRes.D3D11UAVResources[ShaderInd];
400 UINT& MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
401 UINT& MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
402 const UINT Slot = BaseBindings[ShaderInd][Range] + BindPoints[ShaderInd];
403 const bool IsNewUAV = CommittedD3D11UAVs[Slot] != d3d11UAVs[uav];
404 MinSlot = IsNewUAV ? std::min(MinSlot, Slot) : MinSlot;
405 MaxSlot = IsNewUAV ? Slot : MaxSlot;
406
407 VERIFY_EXPR(!IsNewUAV || (Slot >= MinSlot && Slot <= MaxSlot));
408 VERIFY_EXPR(d3d11UAVs[uav] != nullptr);
409 CommittedD3D11UAVRes[Slot] = UAVResources[uav].pd3d11Resource;
410 CommittedD3D11UAVs[Slot] = d3d11UAVs[uav];
411 }
412 }
413 }
414 }
415
416 void DeviceContextD3D11Impl::BindShaderResources()
417 {
418 if ((m_BindInfo.StaleSRBMask & m_BindInfo.ActiveSRBMask) == 0)
419 return;
420
421
422 TBindingsPerStage Bindings = {};
423 TMinMaxSlotPerStage MinMaxSlot = {};
424 const auto ActiveStages = m_BindInfo.ActiveStages;
425
426 if (m_pPipelineState->GetDesc().IsAnyGraphicsPipeline())
427 Bindings[GetShaderTypeIndex(SHADER_TYPE_PIXEL)][D3D11_RESOURCE_RANGE_UAV] = static_cast<Uint8>(m_pPipelineState->GetGraphicsPipelineDesc().NumRenderTargets);
428
429 auto ActiveSRBMask = Uint32{m_BindInfo.ActiveSRBMask};
430 while (ActiveSRBMask != 0)
431 {
432 Uint32 sign = PlatformMisc::GetLSB(ActiveSRBMask);
433 Uint32 SigBit = (1u << sign);
434 VERIFY_EXPR(sign < m_pPipelineState->GetResourceSignatureCount());
435
436 ActiveSRBMask &= ~SigBit;
437
438 auto* pSRB = m_BindInfo.SRBs[sign];
439 VERIFY_EXPR(pSRB);
440
441 if (m_BindInfo.StaleSRBMask & SigBit)
442 {
443 #ifdef DILIGENT_DEVELOPMENT
444 m_BindInfo.BoundResOffsets[sign] = Bindings;
445 #endif
446 BindCacheResources(pSRB->GetResourceCache(), Bindings, MinMaxSlot, ActiveStages);
447 }
448 pSRB->GetSignature()->ShiftBindings(Bindings);
449 }
450
451 m_BindInfo.StaleSRBMask &= ~m_BindInfo.ActiveSRBMask;
452 bool ClearPixelShaderUAVs = m_CommittedRes.NumUAVs[PSInd] > 0;
453
454 for (Uint32 s = 0, ShaderCount = m_pPipelineState->GetNumShaders(); s < ShaderCount; ++s)
455 {
456 const auto ShaderType = m_pPipelineState->GetShaderStageType(s);
457 const Uint32 ShaderInd = GetShaderTypeIndex(ShaderType);
458
459 // CBV
460 {
461 const auto Range = D3D11_RESOURCE_RANGE_CBV;
462 const UINT MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
463 const UINT MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
464 if (MinSlot != UINT_MAX)
465 {
466 auto SetCBMethod = SetCBMethods[ShaderInd];
467 (m_pd3d11DeviceContext->*SetCBMethod)(MinSlot, MaxSlot - MinSlot + 1, m_CommittedRes.D3D11CBs[ShaderInd] + MinSlot);
468 m_CommittedRes.NumCBs[ShaderInd] = std::max(m_CommittedRes.NumCBs[ShaderInd], Bindings[ShaderInd][Range]);
469 VERIFY_EXPR(MaxSlot < Bindings[ShaderInd][Range]);
470 }
471416 #ifdef VERIFY_CONTEXT_BINDINGS
472 if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
473 {
474 DvpVerifyCommittedCBs(ShaderType);
475 }
476 #endif
477 }
478
479 // SRV
480 {
481 const auto Range = D3D11_RESOURCE_RANGE_SRV;
482 const UINT MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
483 const UINT MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
484 if (MinSlot != UINT_MAX)
485 {
486 auto SetSRVMethod = SetSRVMethods[ShaderInd];
487 (m_pd3d11DeviceContext->*SetSRVMethod)(MinSlot, MaxSlot - MinSlot + 1, m_CommittedRes.D3D11SRVs[ShaderInd] + MinSlot);
488 m_CommittedRes.NumSRVs[ShaderInd] = std::max(m_CommittedRes.NumSRVs[ShaderInd], Bindings[ShaderInd][Range]);
489 VERIFY_EXPR(MaxSlot <= Bindings[ShaderInd][Range]);
490 }
491 #ifdef VERIFY_CONTEXT_BINDINGS
492 if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
493 {
494 DvpVerifyCommittedSRVs(ShaderType);
495 }
496 #endif
497 }
498
499 // Sampler
500 {
501 const auto Range = D3D11_RESOURCE_RANGE_SAMPLER;
502 const UINT MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
503 const UINT MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
504 if (MinSlot != UINT_MAX)
505 {
506 auto SetSamplerMethod = SetSamplerMethods[ShaderInd];
507 (m_pd3d11DeviceContext->*SetSamplerMethod)(MinSlot, MaxSlot - MinSlot + 1, m_CommittedRes.D3D11Samplers[ShaderInd] + MinSlot);
508 m_CommittedRes.NumSamplers[ShaderInd] = std::max(m_CommittedRes.NumSamplers[ShaderInd], Bindings[ShaderInd][Range]);
509 VERIFY_EXPR(MaxSlot < Bindings[ShaderInd][Range]);
510 }
511 #ifdef VERIFY_CONTEXT_BINDINGS
512 if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
513 {
514 DvpVerifyCommittedSamplers(ShaderType);
515 }
516 #endif
517 }
518
519 // UAV
520 {
521 const auto Range = D3D11_RESOURCE_RANGE_UAV;
522 const UINT MinSlot = MinMaxSlot[ShaderInd][Range].MinSlot;
523 const UINT MaxSlot = MinMaxSlot[ShaderInd][Range].MaxSlot;
524 if (MinSlot != UINT_MAX)
525 {
526 auto* CommittedD3D11UAVs = m_CommittedRes.D3D11UAVs[ShaderInd];
527 auto* CommittedD3D11UAVRes = m_CommittedRes.D3D11UAVResources[ShaderInd];
528
529 if (ShaderInd == PSInd)
530 ClearPixelShaderUAVs = false;
531
532 // Something has changed
533 if (ShaderInd == PSInd)
534 {
535 // Pixel shader UAVs cannot be set independently; they all need to be set at the same time.
536 // https://docs.microsoft.com/en-us/windows/desktop/api/d3d11/nf-d3d11-id3d11devicecontext-omsetrendertargetsandunorderedaccessviews#remarks
537 const auto StartUAVSlot = m_NumBoundRenderTargets;
538 const auto NumUAVSlot = Bindings[ShaderInd][Range];
539 VERIFY(NumUAVSlot > StartUAVSlot, "Number of UAVs must be greater than the render target count");
540 m_pd3d11DeviceContext->OMSetRenderTargetsAndUnorderedAccessViews(
541 D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr,
542 StartUAVSlot, NumUAVSlot - StartUAVSlot, CommittedD3D11UAVs + StartUAVSlot, nullptr);
543 // Clear previously bound UAVs, but do not clear lower slots as if
544 // render target count reduces, we will bind these UAVs in CommitRenderTargets()
545 for (Uint32 uav = NumUAVSlot; uav < m_CommittedRes.NumUAVs[ShaderInd]; ++uav)
546 {
547 CommittedD3D11UAVRes[uav] = nullptr;
548 CommittedD3D11UAVs[uav] = nullptr;
549 }
550 m_CommittedRes.NumUAVs[ShaderInd] = NumUAVSlot;
551 }
552 else if (ShaderInd == CSInd)
553 {
554 // This can only be CS
555 auto SetUAVMethod = SetUAVMethods[ShaderInd];
556 (m_pd3d11DeviceContext->*SetUAVMethod)(MinSlot, MaxSlot - MinSlot + 1, CommittedD3D11UAVs + MinSlot, nullptr);
557 m_CommittedRes.NumUAVs[ShaderInd] = std::max(m_CommittedRes.NumUAVs[ShaderInd], Bindings[ShaderInd][Range]);
558 VERIFY_EXPR(MaxSlot < Bindings[ShaderInd][Range]);
559 }
560 else
561 {
562 UNEXPECTED("UAV is not supported in shader that is not pixel or compute");
563 }
564 }
565 #ifdef VERIFY_CONTEXT_BINDINGS
566 if ((m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE) != 0 && ShaderInd == CSInd)
567 {
568 DvpVerifyCommittedUAVs(ShaderType);
569 }
570 #endif
571 }
417 if ((m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE) != 0 && ShaderInd == CSInd)
418 {
419 DvpVerifyCommittedUAVs(ShaderTypes[i]);
420 }
421 #endif
572422 }
573423
574424 if (ClearPixelShaderUAVs)
590440 0, 0, nullptr, nullptr);
591441 NumCommittedPixelShaderUAVs = 0;
592442 }
443 }
444
445 void DeviceContextD3D11Impl::BindShaderResources()
446 {
447 if ((m_BindInfo.StaleSRBMask & m_BindInfo.ActiveSRBMask) == 0)
448 return;
449
450 TBindingsPerStage Bindings = {};
451 const auto ActiveStages = m_BindInfo.ActiveStages;
452
453 if (m_pPipelineState->GetDesc().IsAnyGraphicsPipeline())
454 Bindings[D3D11_RESOURCE_RANGE_UAV][GetShaderTypeIndex(SHADER_TYPE_PIXEL)] = static_cast<Uint8>(m_pPipelineState->GetGraphicsPipelineDesc().NumRenderTargets);
455
456 auto ActiveSRBMask = Uint32{m_BindInfo.ActiveSRBMask};
457 while (ActiveSRBMask != 0)
458 {
459 Uint32 sign = PlatformMisc::GetLSB(ActiveSRBMask);
460 Uint32 SigBit = (1u << sign);
461 VERIFY_EXPR(sign < m_pPipelineState->GetResourceSignatureCount());
462
463 ActiveSRBMask &= ~SigBit;
464
465 auto* pSRB = m_BindInfo.SRBs[sign];
466 VERIFY_EXPR(pSRB);
467
468 if (m_BindInfo.StaleSRBMask & SigBit)
469 {
470 #ifdef DILIGENT_DEVELOPMENT
471 m_BindInfo.BoundResOffsets[sign] = Bindings;
472 #endif
473 BindCacheResources(pSRB->GetResourceCache(), Bindings, ActiveStages);
474 }
475 pSRB->GetSignature()->ShiftBindings(Bindings);
476 }
477
478 m_BindInfo.StaleSRBMask &= ~m_BindInfo.ActiveSRBMask;
593479 }
594480
595481 #ifdef DILIGENT_DEVELOPMENT
101101 ShaderVariableDataSizes[s] = ShaderVariableManagerD3D11::GetRequiredMemorySize(*this, AllowedVarTypes, _countof(AllowedVarTypes), GetActiveShaderStageType(s));
102102 }
103103
104 const size_t CacheMemorySize = ShaderResourceCacheD3D11::GetRequriedMemorySize(m_ResourceCount);
104 const size_t CacheMemorySize = ShaderResourceCacheD3D11::GetRequriedMemorySize(m_BindingCountPerStage);
105105 m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumActiveShaderStages(), ShaderVariableDataSizes.data(), 1, &CacheMemorySize);
106106 }
107107
117117 void PipelineResourceSignatureD3D11Impl::CreateLayout()
118118 {
119119 using TBindings32 = std::array<Uint32, D3D11_RESOURCE_RANGE_COUNT>;
120 using TBindingsPerStage32 = std::array<TBindings32, NumShaderTypes>;
120 using TBindingsPerStage32 = std::array<std::array<Uint32, NumShaderTypes>, D3D11_RESOURCE_RANGE_COUNT>;
121
122 const auto AllocBindPoints = [](TBindingsPerStage32& BindingPerStage, BindPointsD3D11& BindPoints, SHADER_TYPE ShaderStages, Uint32 ArraySize, D3D11_RESOURCE_RANGE Range) //
123 {
124 while (ShaderStages != 0)
125 {
126 auto Stage = ExtractLSB(ShaderStages);
127 Uint32 ShaderInd = GetShaderTypeIndex(Stage);
128
129 BindPoints.Set(ShaderInd, BindingPerStage[Range][ShaderInd]);
130 BindingPerStage[Range][ShaderInd] += ArraySize;
131 }
132 };
121133
122134 if (m_pStaticResCache)
123135 {
124 TBindings32 StaticCounter32 = {};
125 const auto ResIdxRange = GetResourceIndexRange(SHADER_RESOURCE_VARIABLE_TYPE_STATIC);
136 TBindingsPerStage32 StaticBindingsPerStage32 = {};
137 const auto ResIdxRange = GetResourceIndexRange(SHADER_RESOURCE_VARIABLE_TYPE_STATIC);
126138 for (Uint32 r = ResIdxRange.first; r < ResIdxRange.second; ++r)
127139 {
128 const auto& ResDesc = m_Desc.Resources[r];
129 const auto Range = ShaderResourceToDescriptorRange(ResDesc.ResourceType);
130 StaticCounter32[Range] += ResDesc.ArraySize;
131 }
132
133 TBindings StaticCounter8 = {};
134 for (Uint32 i = 0; i < StaticCounter8.size(); ++i)
135 {
136 VERIFY_EXPR(StaticCounter8[i] < std::numeric_limits<Uint8>::max());
137 StaticCounter8[i] = static_cast<Uint8>(StaticCounter32[i]);
138 }
139
140 m_pStaticResCache->Initialize(StaticCounter8, GetRawAllocator());
140 const auto& ResDesc = m_Desc.Resources[r];
141 const auto Range = ShaderResourceToDescriptorRange(ResDesc.ResourceType);
142 BindPointsD3D11 BindPoints;
143 AllocBindPoints(StaticBindingsPerStage32, BindPoints, ResDesc.ShaderStages, ResDesc.ArraySize, Range);
144 }
145
146 TBindingsPerStage StaticBindingsPerStage8 = {};
147 for (Uint32 r = 0; r < StaticBindingsPerStage32.size(); ++r)
148 {
149 for (Uint32 s = 0; s < StaticBindingsPerStage32[r].size(); ++s)
150 {
151 using T = std::remove_reference<decltype(StaticBindingsPerStage8[r][s])>::type;
152 VERIFY_EXPR(StaticBindingsPerStage32[r][s] < std::numeric_limits<T>::max());
153 StaticBindingsPerStage8[r][s] = static_cast<T>(StaticBindingsPerStage32[r][s]);
154 }
155 }
156
157 m_pStaticResCache->Initialize(StaticBindingsPerStage8, GetRawAllocator());
158 VERIFY_EXPR(m_pStaticResCache->IsInitialized());
141159 }
142160
143161 // Index of the assigned sampler, for every texture SRV in m_Desc.Resources, or InvalidSamplerInd.
172190 }
173191 }
174192
175 TBindings32 ResourceCount = {};
176193 TBindingsPerStage32 BindingPerStage = {};
177 const auto AllocBindPoints = [&BindingPerStage](BindPointsD3D11& BindPoints, SHADER_TYPE ShaderStages, Uint32 ArraySize, D3D11_RESOURCE_RANGE Range) //
178 {
179 while (ShaderStages != 0)
180 {
181 auto Stage = ExtractLSB(ShaderStages);
182 Uint32 ShaderInd = GetShaderTypeIndex(Stage);
183
184 BindPoints.Set(ShaderInd, BindingPerStage[ShaderInd][Range]);
185 BindingPerStage[ShaderInd][Range] += ArraySize;
186 }
187 };
188
189194 for (Uint32 i = 0; i < m_Desc.NumResources; ++i)
190195 {
191196 const auto& ResDesc = m_Desc.Resources[i];
217222
218223 if (!ImtblSampAttribs.IsAllocated())
219224 {
220 ImtblSampAttribs.CacheOffset = ResourceCount[D3D11_RESOURCE_RANGE_SAMPLER];
221 AllocBindPoints(ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, D3D11_RESOURCE_RANGE_SAMPLER);
222 ResourceCount[D3D11_RESOURCE_RANGE_SAMPLER] += ImtblSampAttribs.ArraySize;
225 AllocBindPoints(BindingPerStage, ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, D3D11_RESOURCE_RANGE_SAMPLER);
223226 }
224227 }
225228
227230 {
228231 auto* pAttrib = new (m_pResourceAttribs + i) ResourceAttribs //
229232 {
230 ResourceCount[Range],
231233 AssignedSamplerInd,
232234 SrcImmutableSamplerInd != InvalidImmutableSamplerIndex //
233235 };
234 AllocBindPoints(pAttrib->BindPoints, ResDesc.ShaderStages, ResDesc.ArraySize, Range);
235 ResourceCount[Range] += ResDesc.ArraySize;
236 AllocBindPoints(BindingPerStage, pAttrib->BindPoints, ResDesc.ShaderStages, ResDesc.ArraySize, Range);
236237 }
237238 else
238239 {
241242 auto& ImtblSampAttribs = m_ImmutableSamplers[SrcImmutableSamplerInd];
242243 auto* pAttrib = new (m_pResourceAttribs + i) ResourceAttribs //
243244 {
244 ImtblSampAttribs.CacheOffset,
245245 ResourceAttribs::InvalidSamplerInd,
246246 SrcImmutableSamplerInd != InvalidImmutableSamplerIndex //
247247 };
248248 pAttrib->BindPoints = ImtblSampAttribs.BindPoints;
249 VERIFY_EXPR(!pAttrib->BindPoints.IsEmpty());
249250 }
250251 }
251252
264265 // Add as separate sampler.
265266 if (!ImtblSampAttribs.IsAllocated())
266267 {
267 ImtblSampAttribs.ArraySize = 1;
268 ImtblSampAttribs.CacheOffset = ResourceCount[Range];
269 ResourceCount[Range] += ImtblSampAttribs.ArraySize;
270 AllocBindPoints(ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, Range);
271 }
272 }
273
274 for (Uint32 i = 0; i < ResourceCount.size(); ++i)
275 {
276 using T = std::remove_reference<decltype(m_ResourceCount[i])>::type;
277 VERIFY_EXPR(ResourceCount[i] < std::numeric_limits<T>::max());
278 m_ResourceCount[i] = static_cast<T>(ResourceCount[i]);
279 }
280
281 for (Uint32 s = 0; s < BindingPerStage.size(); ++s)
282 {
283 for (Uint32 i = 0; i < BindingPerStage[s].size(); ++i)
284 {
285 using T = std::remove_reference<decltype(m_BindingCountPerStage[s][i])>::type;
286 VERIFY_EXPR(BindingPerStage[s][i] < std::numeric_limits<T>::max());
287 m_BindingCountPerStage[s][i] = static_cast<T>(BindingPerStage[s][i]);
268 ImtblSampAttribs.ArraySize = 1;
269 AllocBindPoints(BindingPerStage, ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, Range);
270 }
271 }
272
273 for (Uint32 r = 0; r < BindingPerStage.size(); ++r)
274 {
275 for (Uint32 s = 0; s < BindingPerStage[r].size(); ++s)
276 {
277 using T = std::remove_reference<decltype(m_BindingCountPerStage[r][s])>::type;
278 VERIFY_EXPR(BindingPerStage[r][s] < std::numeric_limits<T>::max());
279 m_BindingCountPerStage[r][s] = static_cast<T>(BindingPerStage[r][s]);
288280 }
289281 }
290282 }
334326 case D3D11_RESOURCE_RANGE_CBV:
335327 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
336328 {
337 const auto& SrcCachedRes = SrcResourceCache.GetCB(ResAttr.CacheOffset + ArrInd);
338 if (!SrcCachedRes.pBuff)
329 if (!DstResourceCache.CopyCB(SrcResourceCache, ResAttr.BindPoints + ArrInd))
339330 LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", GetShaderResourcePrintName(ResDesc, ArrInd), "' in pipeline resource signature '", m_Desc.Name, "'.");
340
341 DstResourceCache.SetCB(ResAttr.CacheOffset + ArrInd, ResAttr.BindPoints + ArrInd, RefCntAutoPtr<BufferD3D11Impl>{SrcCachedRes.pBuff});
342331 }
343332 break;
344333 case D3D11_RESOURCE_RANGE_SRV:
345334 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
346335 {
347 const auto& SrcCachedRes = SrcResourceCache.GetSRV(ResAttr.CacheOffset + ArrInd);
348 if (!SrcCachedRes.pBuffer && !SrcCachedRes.pTexture)
336 if (!DstResourceCache.CopySRV(SrcResourceCache, ResAttr.BindPoints + ArrInd))
349337 LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", GetShaderResourcePrintName(ResDesc, ArrInd), "' in pipeline resource signature '", m_Desc.Name, "'.");
350
351 if (SrcCachedRes.pTexture)
352 DstResourceCache.SetTexSRV(ResAttr.CacheOffset + ArrInd, ResAttr.BindPoints + ArrInd, RefCntAutoPtr<TextureViewD3D11Impl>{SrcCachedRes.pView.RawPtr<TextureViewD3D11Impl>()});
353 else
354 DstResourceCache.SetBufSRV(ResAttr.CacheOffset + ArrInd, ResAttr.BindPoints + ArrInd, RefCntAutoPtr<BufferViewD3D11Impl>{SrcCachedRes.pView.RawPtr<BufferViewD3D11Impl>()});
355338 }
356339 break;
357340 case D3D11_RESOURCE_RANGE_SAMPLER:
360343 {
361344 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
362345 {
363 const auto& SrcCachedRes = SrcResourceCache.GetSampler(ResAttr.CacheOffset + ArrInd);
364 if (!SrcCachedRes.pSampler)
346 if (!DstResourceCache.CopySampler(SrcResourceCache, ResAttr.BindPoints + ArrInd))
365347 LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", GetShaderResourcePrintName(ResDesc, ArrInd), "' in pipeline resource signature '", m_Desc.Name, "'.");
366
367 DstResourceCache.SetSampler(ResAttr.CacheOffset + ArrInd, ResAttr.BindPoints + ArrInd, RefCntAutoPtr<SamplerD3D11Impl>{SrcCachedRes.pSampler});
368348 }
369349 }
370350 break;
371351 case D3D11_RESOURCE_RANGE_UAV:
372352 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
373353 {
374 const auto& SrcCachedRes = SrcResourceCache.GetUAV(ResAttr.CacheOffset + ArrInd);
375 if (!SrcCachedRes.pBuffer && !SrcCachedRes.pTexture)
354 if (!DstResourceCache.CopyUAV(SrcResourceCache, ResAttr.BindPoints + ArrInd))
376355 LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", GetShaderResourcePrintName(ResDesc, ArrInd), "' in pipeline resource signature '", m_Desc.Name, "'.");
377
378 if (SrcCachedRes.pTexture)
379 DstResourceCache.SetTexUAV(ResAttr.CacheOffset + ArrInd, ResAttr.BindPoints + ArrInd, RefCntAutoPtr<TextureViewD3D11Impl>{SrcCachedRes.pView.RawPtr<TextureViewD3D11Impl>()});
380 else
381 DstResourceCache.SetBufUAV(ResAttr.CacheOffset + ArrInd, ResAttr.BindPoints + ArrInd, RefCntAutoPtr<BufferViewD3D11Impl>{SrcCachedRes.pView.RawPtr<BufferViewD3D11Impl>()});
382356 }
383357 break;
384358 default:
389363
390364 void PipelineResourceSignatureD3D11Impl::InitSRBResourceCache(ShaderResourceCacheD3D11& ResourceCache)
391365 {
392 ResourceCache.Initialize(m_ResourceCount, m_SRBMemAllocator.GetResourceCacheDataAllocator(0));
366 ResourceCache.Initialize(m_BindingCountPerStage, m_SRBMemAllocator.GetResourceCacheDataAllocator(0));
367 VERIFY_EXPR(ResourceCache.IsInitialized());
393368
394369 // Copy immutable samplers.
395370 for (Uint32 i = 0; i < m_Desc.NumImmutableSamplers; ++i)
403378 VERIFY_EXPR(ImtblSampAttr.ArraySize > 0);
404379
405380 for (Uint32 ArrInd = 0; ArrInd < ImtblSampAttr.ArraySize; ++ArrInd)
406 ResourceCache.SetSampler(ImtblSampAttr.CacheOffset + ArrInd, ImtblSampAttr.BindPoints + ArrInd, pSampler);
381 ResourceCache.SetSampler(ImtblSampAttr.BindPoints + ArrInd, pSampler);
407382 }
408383 }
409384 }
424399 VERIFY_EXPR(ResAttr.BindPoints.IsValid(ShaderInd));
425400 ResourceBinding::BindInfo BindInfo //
426401 {
427 Uint32{BaseBindings[ShaderInd][Range]} + ResAttr.BindPoints[ShaderInd],
402 Uint32{BaseBindings[Range][ShaderInd]} + ResAttr.BindPoints[ShaderInd],
428403 0u, // register space is not supported
429404 ResDesc.ArraySize,
430405 ResDesc.ResourceType //
452427
453428 ResourceBinding::BindInfo BindInfo //
454429 {
455 Uint32{BaseBindings[ShaderInd][Range]} + SampAttr.BindPoints[ShaderInd],
430 Uint32{BaseBindings[Range][ShaderInd]} + SampAttr.BindPoints[ShaderInd],
456431 0u, // register space is not supported
457432 SampAttr.ArraySize,
458433 SHADER_RESOURCE_TYPE_SAMPLER //
491466 case D3D11_RESOURCE_RANGE_CBV:
492467 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
493468 {
494 if (!ResourceCache.IsCBBound(ResAttr.CacheOffset + ArrInd))
469 if (!ResourceCache.IsCBBound(ResAttr.BindPoints + ArrInd))
495470 {
496471 LOG_ERROR_MESSAGE("No resource is bound to variable '", GetShaderResourcePrintName(ResDesc, ArrInd),
497472 "' in shader '", ShaderName, "' of PSO '", PSOName, "'");
503478 case D3D11_RESOURCE_RANGE_SAMPLER:
504479 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
505480 {
506 if (!ResourceCache.IsSamplerBound(ResAttr.CacheOffset + ArrInd))
481 if (!ResourceCache.IsSamplerBound(ResAttr.BindPoints + ArrInd))
507482 {
508483 LOG_ERROR_MESSAGE("No resource is bound to variable '", GetShaderResourcePrintName(ResDesc, ArrInd),
509484 "' in shader '", ShaderName, "' of PSO '", PSOName, "'");
516491 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
517492 {
518493 const bool IsTexView = (ResDesc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || ResDesc.ResourceType == SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT);
519 if (!ResourceCache.IsSRVBound(ResAttr.CacheOffset + ArrInd, IsTexView))
494 if (!ResourceCache.IsSRVBound(ResAttr.BindPoints + ArrInd, IsTexView))
520495 {
521496 LOG_ERROR_MESSAGE("No resource is bound to variable '", GetShaderResourcePrintName(ResDesc, ArrInd),
522497 "' in shader '", ShaderName, "' of PSO '", PSOName, "'");
523498 BindingsOK = false;
524499 continue;
525500 }
526
527 const auto& SRV = ResourceCache.GetSRV(ResAttr.CacheOffset + ArrInd);
501 /*
502 const auto& SRV = ResourceCache.GetSRV(ResAttr.BindPoints + ArrInd);
528503 if (SRV.pTexture)
529504 ValidateResourceViewDimension(ResDesc.Name, ResDesc.ArraySize, ArrInd, SRV.pView.RawPtr<ITextureView>(), D3DAttribs.GetResourceDimension(), D3DAttribs.IsMultisample());
530505 else
531506 ValidateResourceViewDimension(ResDesc.Name, ResDesc.ArraySize, ArrInd, SRV.pView.RawPtr<IBufferView>(), D3DAttribs.GetResourceDimension(), D3DAttribs.IsMultisample());
507 */
532508 }
533509 break;
534510
536512 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
537513 {
538514 const bool IsTexView = (ResDesc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_SRV || ResDesc.ResourceType == SHADER_RESOURCE_TYPE_TEXTURE_UAV);
539 if (!ResourceCache.IsUAVBound(ResAttr.CacheOffset + ArrInd, IsTexView))
515 if (!ResourceCache.IsUAVBound(ResAttr.BindPoints + ArrInd, IsTexView))
540516 {
541517 LOG_ERROR_MESSAGE("No resource is bound to variable '", GetShaderResourcePrintName(ResDesc, ArrInd),
542518 "' in shader '", ShaderName, "' of PSO '", PSOName, "'");
543519 BindingsOK = false;
544520 continue;
545521 }
546
547 const auto& UAV = ResourceCache.GetUAV(ResAttr.CacheOffset + ArrInd);
522 /*
523 const auto& UAV = ResourceCache.GetUAV(ResAttr.BindPoints + ArrInd);
548524 if (UAV.pTexture)
549525 ValidateResourceViewDimension(ResDesc.Name, ResDesc.ArraySize, ArrInd, UAV.pView.RawPtr<ITextureView>(), D3DAttribs.GetResourceDimension(), D3DAttribs.IsMultisample());
550526 else
551527 ValidateResourceViewDimension(ResDesc.Name, ResDesc.ArraySize, ArrInd, UAV.pView.RawPtr<IBufferView>(), D3DAttribs.GetResourceDimension(), D3DAttribs.IsMultisample());
528 */
552529 }
553530 break;
554531
201201
202202 PipelineResourceSignatureD3D11Impl::TBindingsPerStage BindingsPerStage = {};
203203 if (m_Desc.IsAnyGraphicsPipeline())
204 BindingsPerStage[PSInd][D3D11_RESOURCE_RANGE_UAV] = GetGraphicsPipelineDesc().NumRenderTargets;
204 BindingsPerStage[D3D11_RESOURCE_RANGE_UAV][PSInd] = GetGraphicsPipelineDesc().NumRenderTargets;
205205
206206 ResourceBinding::TMap ResourceMap;
207207 for (Uint32 sign = 0; sign < m_SignatureCount; ++sign)
231231 PipelineResourceSignatureD3D11Impl::TBindingsPerStage BindingsPerStage = {};
232232
233233 if (m_Desc.IsAnyGraphicsPipeline())
234 BindingsPerStage[PSInd][D3D11_RESOURCE_RANGE_UAV] = GetGraphicsPipelineDesc().NumRenderTargets;
234 BindingsPerStage[D3D11_RESOURCE_RANGE_UAV][PSInd] = GetGraphicsPipelineDesc().NumRenderTargets;
235235
236236 for (Uint32 sign = 0; sign < m_SignatureCount; ++sign)
237237 {
240240 pSignature->ShiftBindings(BindingsPerStage);
241241 }
242242
243 for (Uint32 s = 0; s < BindingsPerStage.size(); ++s)
244 {
245 const auto& BindCount = BindingsPerStage[s];
246
247 DEV_CHECK_ERR(BindCount[D3D11_RESOURCE_RANGE_CBV] <= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT,
248 "Constant buffer count ", Uint32{BindCount[D3D11_RESOURCE_RANGE_CBV]}, " exceeds D3D11 limit ", D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
249 DEV_CHECK_ERR(BindCount[D3D11_RESOURCE_RANGE_SRV] <= D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT,
250 "SRV count ", Uint32{BindCount[D3D11_RESOURCE_RANGE_SRV]}, " exceeds D3D11 limit ", D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT);
251 DEV_CHECK_ERR(BindCount[D3D11_RESOURCE_RANGE_SAMPLER] <= D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT,
252 "Sampler count ", Uint32{BindCount[D3D11_RESOURCE_RANGE_SAMPLER]}, " exceeds D3D11 limit ", D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT);
253 DEV_CHECK_ERR(BindCount[D3D11_RESOURCE_RANGE_UAV] <= D3D11_PS_CS_UAV_REGISTER_COUNT,
254 "UAV count ", Uint32{BindCount[D3D11_RESOURCE_RANGE_UAV]}, " exceeds D3D11 limit ", D3D11_PS_CS_UAV_REGISTER_COUNT);
243 for (Uint32 s = 0; s < PipelineResourceSignatureD3D11Impl::NumShaderTypes; ++s)
244 {
245 DEV_CHECK_ERR(BindingsPerStage[D3D11_RESOURCE_RANGE_CBV][s] <= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT,
246 "Constant buffer count ", Uint32{BindingsPerStage[D3D11_RESOURCE_RANGE_CBV][s]}, " exceeds D3D11 limit ", D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
247 DEV_CHECK_ERR(BindingsPerStage[D3D11_RESOURCE_RANGE_SRV][s] <= D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT,
248 "SRV count ", Uint32{BindingsPerStage[D3D11_RESOURCE_RANGE_SRV][s]}, " exceeds D3D11 limit ", D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT);
249 DEV_CHECK_ERR(BindingsPerStage[D3D11_RESOURCE_RANGE_SAMPLER][s] <= D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT,
250 "Sampler count ", Uint32{BindingsPerStage[D3D11_RESOURCE_RANGE_SAMPLER][s]}, " exceeds D3D11 limit ", D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT);
251 DEV_CHECK_ERR(BindingsPerStage[D3D11_RESOURCE_RANGE_UAV][s] <= D3D11_PS_CS_UAV_REGISTER_COUNT,
252 "UAV count ", Uint32{BindingsPerStage[D3D11_RESOURCE_RANGE_UAV][s]}, " exceeds D3D11 limit ", D3D11_PS_CS_UAV_REGISTER_COUNT);
255253 }
256254 #endif
257255 }
524522 TBindingsPerStage Bindings = {};
525523
526524 if (m_Desc.IsAnyGraphicsPipeline())
527 Bindings[GetShaderTypeIndex(SHADER_TYPE_PIXEL)][D3D11_RESOURCE_RANGE_UAV] = static_cast<Uint8>(GetGraphicsPipelineDesc().NumRenderTargets);
525 Bindings[D3D11_RESOURCE_RANGE_UAV][GetShaderTypeIndex(SHADER_TYPE_PIXEL)] = static_cast<Uint8>(GetGraphicsPipelineDesc().NumRenderTargets);
528526
529527 for (Uint32 sign = 0; sign < SignCount; ++sign)
530528 {
3838 namespace Diligent
3939 {
4040
41 size_t ShaderResourceCacheD3D11::GetRequriedMemorySize(const TResourceCount& ResCount)
42 {
41 size_t ShaderResourceCacheD3D11::GetRequriedMemorySize(const TBindingsPerStage& ResCount)
42 {
43 size_t MemSize = 0;
4344 // clang-format off
44 auto CBCount = ResCount[D3D11_RESOURCE_RANGE_CBV];
45 auto SRVCount = ResCount[D3D11_RESOURCE_RANGE_SRV];
46 auto SamplerCount = ResCount[D3D11_RESOURCE_RANGE_SAMPLER];
47 auto UAVCount = ResCount[D3D11_RESOURCE_RANGE_UAV];
48 size_t MemSize = 0;
49 MemSize = AlignUp(MemSize + (sizeof(CachedCB) + sizeof(BindPointsD3D11) + sizeof(ID3D11Buffer*)) * CBCount, MaxAlignment);
50 MemSize = AlignUp(MemSize + (sizeof(CachedResource) + sizeof(BindPointsD3D11) + sizeof(ID3D11ShaderResourceView*)) * SRVCount, MaxAlignment);
51 MemSize = AlignUp(MemSize + (sizeof(CachedSampler) + sizeof(BindPointsD3D11) + sizeof(ID3D11SamplerState*)) * SamplerCount, MaxAlignment);
52 MemSize = AlignUp(MemSize + (sizeof(CachedResource) + sizeof(BindPointsD3D11) + sizeof(ID3D11UnorderedAccessView*)) * UAVCount, MaxAlignment);
45 for (Uint32 ShaderInd = 0; ShaderInd < NumShaderTypes; ++ShaderInd)
46 MemSize = AlignUp(MemSize + (sizeof(CachedCB) + sizeof(ID3D11Buffer*)) * ResCount[D3D11_RESOURCE_RANGE_CBV][ShaderInd], MaxAlignment);
47
48 for (Uint32 ShaderInd = 0; ShaderInd < NumShaderTypes; ++ShaderInd)
49 MemSize = AlignUp(MemSize + (sizeof(CachedResource) + sizeof(ID3D11ShaderResourceView*)) * ResCount[D3D11_RESOURCE_RANGE_SRV][ShaderInd], MaxAlignment);
50
51 for (Uint32 ShaderInd = 0; ShaderInd < NumShaderTypes; ++ShaderInd)
52 MemSize = AlignUp(MemSize + (sizeof(CachedSampler) + sizeof(ID3D11SamplerState*)) * ResCount[D3D11_RESOURCE_RANGE_SAMPLER][ShaderInd], MaxAlignment);
53
54 for (Uint32 ShaderInd = 0; ShaderInd < NumShaderTypes; ++ShaderInd)
55 MemSize = AlignUp(MemSize + (sizeof(CachedResource) + sizeof(ID3D11UnorderedAccessView*)) * ResCount[D3D11_RESOURCE_RANGE_UAV][ShaderInd], MaxAlignment);
5356 // clang-format on
54 VERIFY(MemSize < InvalidResourceOffset, "Memory size exeed the maximum allowed size.");
57
58 VERIFY(MemSize < std::numeric_limits<OffsetType>::max(), "Memory size exeed the maximum allowed size.");
5559 return MemSize;
5660 }
5761
58 void ShaderResourceCacheD3D11::Initialize(const TResourceCount& ResCount, IMemoryAllocator& MemAllocator)
62 void ShaderResourceCacheD3D11::Initialize(const TBindingsPerStage& ResCount, IMemoryAllocator& MemAllocator)
5963 {
6064 // http://diligentgraphics.com/diligent-engine/architecture/d3d11/shader-resource-cache/
6165 VERIFY(!IsInitialized(), "Resource cache has already been intialized!");
6266
63 const Uint32 CBCount = ResCount[D3D11_RESOURCE_RANGE_CBV];
64 const Uint32 SRVCount = ResCount[D3D11_RESOURCE_RANGE_SRV];
65 const Uint32 SamplerCount = ResCount[D3D11_RESOURCE_RANGE_SAMPLER];
66 const Uint32 UAVCount = ResCount[D3D11_RESOURCE_RANGE_UAV];
67
68 // clang-format off
69 m_CBCount = static_cast<decltype(m_CBCount )>(CBCount);
70 m_SRVCount = static_cast<decltype(m_SRVCount )>(SRVCount);
71 m_SamplerCount = static_cast<decltype(m_SamplerCount)>(SamplerCount);
72 m_UAVCount = static_cast<decltype(m_UAVCount )>(UAVCount);
73
74 VERIFY(CBCount == m_CBCount, "Constant buffer count (", CBCount, ") exceeds maximum representable value");
75 VERIFY(SRVCount == m_SRVCount, "Shader resources count (", SRVCount, ") exceeds maximum representable value");
76 VERIFY(SamplerCount == m_SamplerCount, "Sampler count (", SamplerCount, ") exceeds maximum representable value");
77 VERIFY(UAVCount == m_UAVCount, "UAVs count (", UAVCount, ") exceeds maximum representable value");
78
79 // m_CBOffset = 0
80 m_SRVOffset = static_cast<OffsetType>(AlignUp(m_CBOffset + (sizeof(CachedCB) + sizeof(BindPointsD3D11) + sizeof(ID3D11Buffer*)) * CBCount, MaxAlignment));
81 m_SamplerOffset = static_cast<OffsetType>(AlignUp(m_SRVOffset + (sizeof(CachedResource) + sizeof(BindPointsD3D11) + sizeof(ID3D11ShaderResourceView*)) * SRVCount, MaxAlignment));
82 m_UAVOffset = static_cast<OffsetType>(AlignUp(m_SamplerOffset + (sizeof(CachedSampler) + sizeof(BindPointsD3D11) + sizeof(ID3D11SamplerState*)) * SamplerCount, MaxAlignment));
83 size_t BufferSize = static_cast<OffsetType>(AlignUp(m_UAVOffset + (sizeof(CachedResource) + sizeof(BindPointsD3D11) + sizeof(ID3D11UnorderedAccessView*)) * UAVCount, MaxAlignment));
84 // clang-format on
67 size_t MemOffset = 0;
68 for (Uint32 ShaderInd = 0; ShaderInd < NumShaderTypes; ++ShaderInd)
69 {
70 const Uint32 Idx = CBOffset + ShaderInd;
71 m_Offsets[Idx] = static_cast<OffsetType>(MemOffset);
72 MemOffset = AlignUp(MemOffset + (sizeof(CachedCB) + sizeof(ID3D11Buffer*)) * ResCount[D3D11_RESOURCE_RANGE_CBV][ShaderInd], MaxAlignment);
73 }
74 for (Uint32 ShaderInd = 0; ShaderInd < NumShaderTypes; ++ShaderInd)
75 {
76 const Uint32 Idx = SRVOffset + ShaderInd;
77 m_Offsets[Idx] = static_cast<OffsetType>(MemOffset);
78 MemOffset = AlignUp(MemOffset + (sizeof(CachedResource) + sizeof(ID3D11ShaderResourceView*)) * ResCount[D3D11_RESOURCE_RANGE_SRV][ShaderInd], MaxAlignment);
79 }
80 for (Uint32 ShaderInd = 0; ShaderInd < NumShaderTypes; ++ShaderInd)
81 {
82 const Uint32 Idx = SampOffset + ShaderInd;
83 m_Offsets[Idx] = static_cast<OffsetType>(MemOffset);
84 MemOffset = AlignUp(MemOffset + (sizeof(CachedSampler) + sizeof(ID3D11SamplerState*)) * ResCount[D3D11_RESOURCE_RANGE_SAMPLER][ShaderInd], MaxAlignment);
85 }
86 for (Uint32 ShaderInd = 0; ShaderInd < NumShaderTypes; ++ShaderInd)
87 {
88 const Uint32 Idx = UAVOffset + ShaderInd;
89 m_Offsets[Idx] = static_cast<OffsetType>(MemOffset);
90 MemOffset = AlignUp(MemOffset + (sizeof(CachedResource) + sizeof(ID3D11UnorderedAccessView*)) * ResCount[D3D11_RESOURCE_RANGE_UAV][ShaderInd], MaxAlignment);
91 }
92 m_Offsets[MaxOffsets - 1] = static_cast<OffsetType>(MemOffset);
93
94 const size_t BufferSize = MemOffset;
8595
8696 VERIFY_EXPR(m_pResourceData == nullptr);
8797 VERIFY_EXPR(BufferSize == GetRequriedMemorySize(ResCount));
96106 }
97107
98108 // Explicitly construct all objects
99 if (CBCount != 0)
100 {
101 CachedCB* CBs = nullptr;
102 ID3D11Buffer** d3d11CBs = nullptr;
103 BindPointsD3D11* bindPoints = nullptr;
104 GetCBArrays(CBs, d3d11CBs, bindPoints);
105 for (Uint32 cb = 0; cb < CBCount; ++cb)
106 {
107 new (CBs + cb) CachedCB{};
108 new (bindPoints + cb) BindPointsD3D11{};
109 }
110 }
111
112 if (SRVCount != 0)
113 {
114 CachedResource* SRVResources = nullptr;
115 ID3D11ShaderResourceView** d3d11SRVs = nullptr;
116 BindPointsD3D11* bindPoints = nullptr;
117 GetSRVArrays(SRVResources, d3d11SRVs, bindPoints);
118 for (Uint32 srv = 0; srv < SRVCount; ++srv)
119 {
120 new (SRVResources + srv) CachedResource{};
121 new (bindPoints + srv) BindPointsD3D11{};
122 }
123 }
124
125 if (SamplerCount != 0)
126 {
127 CachedSampler* Samplers = nullptr;
128 ID3D11SamplerState** d3d11Samplers = nullptr;
129 BindPointsD3D11* bindPoints = nullptr;
130 GetSamplerArrays(Samplers, d3d11Samplers, bindPoints);
131 for (Uint32 sam = 0; sam < SamplerCount; ++sam)
132 {
133 new (Samplers + sam) CachedSampler{};
134 new (bindPoints + sam) BindPointsD3D11{};
135 }
136 }
137
138 if (UAVCount != 0)
139 {
140 CachedResource* UAVResources = nullptr;
141 ID3D11UnorderedAccessView** d3d11UAVs = nullptr;
142 BindPointsD3D11* bindPoints = nullptr;
143 GetUAVArrays(UAVResources, d3d11UAVs, bindPoints);
144 for (Uint32 uav = 0; uav < UAVCount; ++uav)
145 {
146 new (UAVResources + uav) CachedResource{};
147 new (bindPoints + uav) BindPointsD3D11{};
148 }
149 }
150 }
151
152 ShaderResourceCacheD3D11::~ShaderResourceCacheD3D11()
153 {
154 if (IsInitialized())
155 {
156 // Explicitly destory all objects
157 auto CBCount = GetCBCount();
109 for (Uint32 ShaderInd = 0; ShaderInd < NumShaderTypes; ++ShaderInd)
110 {
111 const auto CBCount = GetCBCount(ShaderInd);
158112 if (CBCount != 0)
159113 {
160 CachedCB* CBs = nullptr;
161 ID3D11Buffer** d3d11CBs = nullptr;
162 BindPointsD3D11* bindPoints = nullptr;
163 GetCBArrays(CBs, d3d11CBs, bindPoints);
164 for (size_t cb = 0; cb < CBCount; ++cb)
165 CBs[cb].~CachedCB();
166 }
167
168 auto SRVCount = GetSRVCount();
114 CachedCB* CBs = nullptr;
115 ID3D11Buffer** d3d11CBs = nullptr;
116 GetCBArrays(ShaderInd, CBs, d3d11CBs);
117 for (Uint32 cb = 0; cb < CBCount; ++cb)
118 new (CBs + cb) CachedCB{};
119 }
120
121 const auto SRVCount = GetSRVCount(ShaderInd);
169122 if (SRVCount != 0)
170123 {
171124 CachedResource* SRVResources = nullptr;
172125 ID3D11ShaderResourceView** d3d11SRVs = nullptr;
173 BindPointsD3D11* bindPoints = nullptr;
174 GetSRVArrays(SRVResources, d3d11SRVs, bindPoints);
175 for (size_t srv = 0; srv < SRVCount; ++srv)
176 SRVResources[srv].~CachedResource();
177 }
178
179 auto SamplerCount = GetSamplerCount();
126 GetSRVArrays(ShaderInd, SRVResources, d3d11SRVs);
127 for (Uint32 srv = 0; srv < SRVCount; ++srv)
128 new (SRVResources + srv) CachedResource{};
129 }
130
131 const auto SamplerCount = GetSamplerCount(ShaderInd);
180132 if (SamplerCount != 0)
181133 {
182134 CachedSampler* Samplers = nullptr;
183135 ID3D11SamplerState** d3d11Samplers = nullptr;
184 BindPointsD3D11* bindPoints = nullptr;
185 GetSamplerArrays(Samplers, d3d11Samplers, bindPoints);
186 for (size_t sam = 0; sam < SamplerCount; ++sam)
187 Samplers[sam].~CachedSampler();
188 }
189
190 auto UAVCount = GetUAVCount();
136 GetSamplerArrays(ShaderInd, Samplers, d3d11Samplers);
137 for (Uint32 sam = 0; sam < SamplerCount; ++sam)
138 new (Samplers + sam) CachedSampler{};
139 }
140
141 const auto UAVCount = GetUAVCount(ShaderInd);
191142 if (UAVCount != 0)
192143 {
193144 CachedResource* UAVResources = nullptr;
194145 ID3D11UnorderedAccessView** d3d11UAVs = nullptr;
195 BindPointsD3D11* bindPoints = nullptr;
196 GetUAVArrays(UAVResources, d3d11UAVs, bindPoints);
197 for (size_t uav = 0; uav < UAVCount; ++uav)
198 UAVResources[uav].~CachedResource();
199 }
200
201 m_SRVOffset = InvalidResourceOffset;
202 m_SamplerOffset = InvalidResourceOffset;
203 m_UAVOffset = InvalidResourceOffset;
204 m_CBCount = 0;
205 m_SRVCount = 0;
206 m_SamplerCount = 0;
207 m_UAVCount = 0;
146 GetUAVArrays(ShaderInd, UAVResources, d3d11UAVs);
147 for (Uint32 uav = 0; uav < UAVCount; ++uav)
148 new (UAVResources + uav) CachedResource{};
149 }
150 }
151
152 m_IsInitialized = true;
153 }
154
155 ShaderResourceCacheD3D11::~ShaderResourceCacheD3D11()
156 {
157 if (IsInitialized())
158 {
159 // Explicitly destory all objects
160 for (Uint32 ShaderInd = 0; ShaderInd < NumShaderTypes; ++ShaderInd)
161 {
162 const auto CBCount = GetCBCount(ShaderInd);
163 if (CBCount != 0)
164 {
165 CachedCB* CBs = nullptr;
166 ID3D11Buffer** d3d11CBs = nullptr;
167 GetCBArrays(ShaderInd, CBs, d3d11CBs);
168 for (size_t cb = 0; cb < CBCount; ++cb)
169 CBs[cb].~CachedCB();
170 }
171
172 const auto SRVCount = GetSRVCount(ShaderInd);
173 if (SRVCount != 0)
174 {
175 CachedResource* SRVResources = nullptr;
176 ID3D11ShaderResourceView** d3d11SRVs = nullptr;
177 GetSRVArrays(ShaderInd, SRVResources, d3d11SRVs);
178 for (size_t srv = 0; srv < SRVCount; ++srv)
179 SRVResources[srv].~CachedResource();
180 }
181
182 const auto SamplerCount = GetSamplerCount(ShaderInd);
183 if (SamplerCount != 0)
184 {
185 CachedSampler* Samplers = nullptr;
186 ID3D11SamplerState** d3d11Samplers = nullptr;
187 GetSamplerArrays(ShaderInd, Samplers, d3d11Samplers);
188 for (size_t sam = 0; sam < SamplerCount; ++sam)
189 Samplers[sam].~CachedSampler();
190 }
191
192 const auto UAVCount = GetUAVCount(ShaderInd);
193 if (UAVCount != 0)
194 {
195 CachedResource* UAVResources = nullptr;
196 ID3D11UnorderedAccessView** d3d11UAVs = nullptr;
197 GetUAVArrays(ShaderInd, UAVResources, d3d11UAVs);
198 for (size_t uav = 0; uav < UAVCount; ++uav)
199 UAVResources[uav].~CachedResource();
200 }
201 }
202 m_Offsets = {};
203 m_IsInitialized = false;
208204
209205 m_pResourceData.reset();
210206 }
263259 {
264260 VERIFY(IsInitialized(), "Cache is not initialized");
265261
266 CachedCB* CBs = nullptr;
267 ID3D11Buffer** d3d11CBs = nullptr;
268 CachedResource* SRVResources = nullptr;
269 ID3D11ShaderResourceView** d3d11SRVs = nullptr;
270 CachedSampler* Samplers = nullptr;
271 ID3D11SamplerState** d3d11Samplers = nullptr;
272 CachedResource* UAVResources = nullptr;
273 ID3D11UnorderedAccessView** d3d11UAVs = nullptr;
274 BindPointsD3D11* bindPoints = nullptr;
275
276 GetCBArrays(CBs, d3d11CBs, bindPoints);
277 GetSRVArrays(SRVResources, d3d11SRVs, bindPoints);
278 GetSamplerArrays(Samplers, d3d11Samplers, bindPoints);
279 GetUAVArrays(UAVResources, d3d11UAVs, bindPoints);
280
281 auto CBCount = GetCBCount();
282 for (size_t cb = 0; cb < CBCount; ++cb)
283 {
284 auto& pBuff = CBs[cb].pBuff;
285 auto* pd3d11Buff = d3d11CBs[cb];
286 VERIFY(pBuff == nullptr && pd3d11Buff == nullptr || pBuff != nullptr && pd3d11Buff != nullptr, "CB resource and d3d11 buffer must be set/unset atomically");
287 if (pBuff != nullptr && pd3d11Buff != nullptr)
288 {
289 VERIFY(pd3d11Buff == pBuff->GetD3D11Buffer(), "Inconsistent D3D11 buffer");
290 }
291 }
292
293 auto SRVCount = GetSRVCount();
294 for (size_t srv = 0; srv < SRVCount; ++srv)
295 {
296 auto& Res = SRVResources[srv];
297 auto* pd3d11SRV = d3d11SRVs[srv];
298 DvpVerifyResource(Res, pd3d11SRV, "SRV");
299 }
300
301 auto UAVCount = GetUAVCount();
302 for (size_t uav = 0; uav < UAVCount; ++uav)
303 {
304 auto& Res = UAVResources[uav];
305 auto* pd3d11UAV = d3d11UAVs[uav];
306 DvpVerifyResource(Res, pd3d11UAV, "UAV");
307 }
308
309 auto SamplerCount = GetSamplerCount();
310 for (size_t sam = 0; sam < SamplerCount; ++sam)
311 {
312 auto& pSampler = Samplers[sam].pSampler;
313 auto* pd3d11Sampler = d3d11Samplers[sam];
314 VERIFY(pSampler == nullptr && pd3d11Sampler == nullptr || pSampler != nullptr && pd3d11Sampler != nullptr, "CB resource and d3d11 buffer must be set/unset atomically");
315 if (pSampler != nullptr && pd3d11Sampler != nullptr)
316 {
317 VERIFY(pd3d11Sampler == pSampler->GetD3D11SamplerState(), "Inconsistent D3D11 sampler");
318 }
319 }
320 }
321 #endif
262 for (Uint32 ShaderInd = 0; ShaderInd < NumShaderTypes; ++ShaderInd)
263 {
264 CachedCB* CBs = nullptr;
265 ID3D11Buffer** d3d11CBs = nullptr;
266 CachedResource* SRVResources = nullptr;
267 ID3D11ShaderResourceView** d3d11SRVs = nullptr;
268 CachedSampler* Samplers = nullptr;
269 ID3D11SamplerState** d3d11Samplers = nullptr;
270 CachedResource* UAVResources = nullptr;
271 ID3D11UnorderedAccessView** d3d11UAVs = nullptr;
272
273 GetCBArrays(ShaderInd, CBs, d3d11CBs);
274 GetSRVArrays(ShaderInd, SRVResources, d3d11SRVs);
275 GetSamplerArrays(ShaderInd, Samplers, d3d11Samplers);
276 GetUAVArrays(ShaderInd, UAVResources, d3d11UAVs);
277
278 auto CBCount = GetCBCount(ShaderInd);
279 for (size_t cb = 0; cb < CBCount; ++cb)
280 {
281 auto& pBuff = CBs[cb].pBuff;
282 auto* pd3d11Buff = d3d11CBs[cb];
283 VERIFY(pBuff == nullptr && pd3d11Buff == nullptr || pBuff != nullptr && pd3d11Buff != nullptr, "CB resource and d3d11 buffer must be set/unset atomically");
284 if (pBuff != nullptr && pd3d11Buff != nullptr)
285 {
286 VERIFY(pd3d11Buff == pBuff->GetD3D11Buffer(), "Inconsistent D3D11 buffer");
287 }
288 }
289
290 auto SRVCount = GetSRVCount(ShaderInd);
291 for (size_t srv = 0; srv < SRVCount; ++srv)
292 {
293 auto& Res = SRVResources[srv];
294 auto* pd3d11SRV = d3d11SRVs[srv];
295 DvpVerifyResource(Res, pd3d11SRV, "SRV");
296 }
297
298 auto UAVCount = GetUAVCount(ShaderInd);
299 for (size_t uav = 0; uav < UAVCount; ++uav)
300 {
301 auto& Res = UAVResources[uav];
302 auto* pd3d11UAV = d3d11UAVs[uav];
303 DvpVerifyResource(Res, pd3d11UAV, "UAV");
304 }
305
306 auto SamplerCount = GetSamplerCount(ShaderInd);
307 for (size_t sam = 0; sam < SamplerCount; ++sam)
308 {
309 auto& pSampler = Samplers[sam].pSampler;
310 auto* pd3d11Sampler = d3d11Samplers[sam];
311 VERIFY(pSampler == nullptr && pd3d11Sampler == nullptr || pSampler != nullptr && pd3d11Sampler != nullptr, "CB resource and d3d11 buffer must be set/unset atomically");
312 if (pSampler != nullptr && pd3d11Sampler != nullptr)
313 {
314 VERIFY(pd3d11Sampler == pSampler->GetD3D11SamplerState(), "Inconsistent D3D11 sampler");
315 }
316 }
317 }
318 }
319 #endif // DILIGENT_DEVELOPMENT
322320
323321 template <ShaderResourceCacheD3D11::StateTransitionMode Mode>
324322 void ShaderResourceCacheD3D11::TransitionResourceStates(DeviceContextD3D11Impl& Ctx)
334332 template <ShaderResourceCacheD3D11::StateTransitionMode Mode>
335333 void ShaderResourceCacheD3D11::TransitionResources(DeviceContextD3D11Impl& Ctx, const ID3D11Buffer* /*Selector*/) const
336334 {
337 const auto CBCount = GetCBCount();
338 if (CBCount == 0)
339 return;
340
341 CachedCB* CBs;
342 ID3D11Buffer** d3d11CBs;
343 BindPointsD3D11* bindPoints;
344 GetCBArrays(CBs, d3d11CBs, bindPoints);
345
346 for (Uint32 i = 0; i < CBCount; ++i)
347 {
348 if (auto* pBuffer = CBs[i].pBuff.RawPtr<BufferD3D11Impl>())
349 {
350 if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_CONSTANT_BUFFER))
351 {
352 if (Mode == StateTransitionMode::Transition)
335 for (Uint32 ShaderInd = 0; ShaderInd < NumShaderTypes; ++ShaderInd)
336 {
337 const auto CBCount = GetCBCount(ShaderInd);
338 if (CBCount == 0)
339 continue;
340
341 CachedCB* CBs;
342 ID3D11Buffer** d3d11CBs;
343 GetCBArrays(ShaderInd, CBs, d3d11CBs);
344
345 for (Uint32 i = 0; i < CBCount; ++i)
346 {
347 if (auto* pBuffer = CBs[i].pBuff.RawPtr<BufferD3D11Impl>())
348 {
349 if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_CONSTANT_BUFFER))
353350 {
354 Ctx.TransitionResource(pBuffer, RESOURCE_STATE_CONSTANT_BUFFER);
355 }
356 else
357 {
358 LOG_ERROR_MESSAGE("Buffer '", pBuffer->GetDesc().Name,
359 "' has not been transitioned to Constant Buffer state. Call TransitionShaderResources(), use "
360 "RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the buffer to required state.");
351 if (Mode == StateTransitionMode::Transition)
352 {
353 Ctx.TransitionResource(pBuffer, RESOURCE_STATE_CONSTANT_BUFFER);
354 }
355 else
356 {
357 LOG_ERROR_MESSAGE("Buffer '", pBuffer->GetDesc().Name,
358 "' has not been transitioned to Constant Buffer state. Call TransitionShaderResources(), use "
359 "RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the buffer to required state.");
360 }
361361 }
362362 }
363363 }
367367 template <ShaderResourceCacheD3D11::StateTransitionMode Mode>
368368 void ShaderResourceCacheD3D11::TransitionResources(DeviceContextD3D11Impl& Ctx, const ID3D11ShaderResourceView* /*Selector*/) const
369369 {
370 const auto SRVCount = GetSRVCount();
371 if (SRVCount == 0)
372 return;
373
374 CachedResource* SRVResources;
375 ID3D11ShaderResourceView** d3d11SRVs;
376 BindPointsD3D11* bindPoints;
377 GetSRVArrays(SRVResources, d3d11SRVs, bindPoints);
378
379 for (Uint32 i = 0; i < SRVCount; ++i)
380 {
381 auto& SRVRes = SRVResources[i];
382 if (auto* pTexture = SRVRes.pTexture)
383 {
384 if (pTexture->IsInKnownState() && !pTexture->CheckAnyState(RESOURCE_STATE_SHADER_RESOURCE | RESOURCE_STATE_INPUT_ATTACHMENT))
385 {
386 if (Mode == StateTransitionMode::Transition)
370 for (Uint32 ShaderInd = 0; ShaderInd < NumShaderTypes; ++ShaderInd)
371 {
372 const auto SRVCount = GetSRVCount(ShaderInd);
373 if (SRVCount == 0)
374 continue;
375
376 CachedResource* SRVResources;
377 ID3D11ShaderResourceView** d3d11SRVs;
378 GetSRVArrays(ShaderInd, SRVResources, d3d11SRVs);
379
380 for (Uint32 i = 0; i < SRVCount; ++i)
381 {
382 auto& SRVRes = SRVResources[i];
383 if (auto* pTexture = SRVRes.pTexture)
384 {
385 if (pTexture->IsInKnownState() && !pTexture->CheckAnyState(RESOURCE_STATE_SHADER_RESOURCE | RESOURCE_STATE_INPUT_ATTACHMENT))
387386 {
388 Ctx.TransitionResource(pTexture, RESOURCE_STATE_SHADER_RESOURCE);
387 if (Mode == StateTransitionMode::Transition)
388 {
389 Ctx.TransitionResource(pTexture, RESOURCE_STATE_SHADER_RESOURCE);
390 }
391 else
392 {
393 LOG_ERROR_MESSAGE("Texture '", pTexture->GetDesc().Name,
394 "' has not been transitioned to Shader Resource state. Call TransitionShaderResources(), use "
395 "RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the texture to required state.");
396 }
389397 }
390 else
398 }
399 else if (auto* pBuffer = SRVRes.pBuffer)
400 {
401 if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_SHADER_RESOURCE))
391402 {
392 LOG_ERROR_MESSAGE("Texture '", pTexture->GetDesc().Name,
393 "' has not been transitioned to Shader Resource state. Call TransitionShaderResources(), use "
394 "RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the texture to required state.");
395 }
396 }
397 }
398 else if (auto* pBuffer = SRVRes.pBuffer)
399 {
400 if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_SHADER_RESOURCE))
401 {
402 if (Mode == StateTransitionMode::Transition)
403 {
404 Ctx.TransitionResource(pBuffer, RESOURCE_STATE_SHADER_RESOURCE);
405 }
406 else
407 {
408 LOG_ERROR_MESSAGE("Buffer '", pBuffer->GetDesc().Name,
409 "' has not been transitioned to Shader Resource state. Call TransitionShaderResources(), use "
410 "RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the buffer to required state.");
403 if (Mode == StateTransitionMode::Transition)
404 {
405 Ctx.TransitionResource(pBuffer, RESOURCE_STATE_SHADER_RESOURCE);
406 }
407 else
408 {
409 LOG_ERROR_MESSAGE("Buffer '", pBuffer->GetDesc().Name,
410 "' has not been transitioned to Shader Resource state. Call TransitionShaderResources(), use "
411 "RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the buffer to required state.");
412 }
411413 }
412414 }
413415 }
422424 template <ShaderResourceCacheD3D11::StateTransitionMode Mode>
423425 void ShaderResourceCacheD3D11::TransitionResources(DeviceContextD3D11Impl& Ctx, const ID3D11UnorderedAccessView* /*Selector*/) const
424426 {
425 const auto UAVCount = GetUAVCount();
426 if (UAVCount == 0)
427 return;
428
429 CachedResource* UAVResources;
430 ID3D11UnorderedAccessView** d3d11UAVs;
431 BindPointsD3D11* bindPoints;
432 GetUAVArrays(UAVResources, d3d11UAVs, bindPoints);
433
434 for (Uint32 i = 0; i < UAVCount; ++i)
435 {
436 auto& UAVRes = UAVResources[i];
437 if (auto* pTexture = UAVRes.pTexture)
438 {
439 if (pTexture->IsInKnownState() && !pTexture->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
440 {
441 if (Mode == StateTransitionMode::Transition)
427 for (Uint32 ShaderInd = 0; ShaderInd < NumShaderTypes; ++ShaderInd)
428 {
429 const auto UAVCount = GetUAVCount(ShaderInd);
430 if (UAVCount == 0)
431 continue;
432
433 CachedResource* UAVResources;
434 ID3D11UnorderedAccessView** d3d11UAVs;
435 GetUAVArrays(ShaderInd, UAVResources, d3d11UAVs);
436
437 for (Uint32 i = 0; i < UAVCount; ++i)
438 {
439 auto& UAVRes = UAVResources[i];
440 if (auto* pTexture = UAVRes.pTexture)
441 {
442 if (pTexture->IsInKnownState() && !pTexture->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
442443 {
443 Ctx.TransitionResource(pTexture, RESOURCE_STATE_UNORDERED_ACCESS);
444 if (Mode == StateTransitionMode::Transition)
445 {
446 Ctx.TransitionResource(pTexture, RESOURCE_STATE_UNORDERED_ACCESS);
447 }
448 else
449 {
450 LOG_ERROR_MESSAGE("Texture '", pTexture->GetDesc().Name,
451 "' has not been transitioned to Unordered Access state. Call TransitionShaderResources(), use "
452 "RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the texture to required state.");
453 }
444454 }
445 else
455 }
456 else if (auto* pBuffer = UAVRes.pBuffer)
457 {
458 if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
446459 {
447 LOG_ERROR_MESSAGE("Texture '", pTexture->GetDesc().Name,
448 "' has not been transitioned to Unordered Access state. Call TransitionShaderResources(), use "
449 "RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the texture to required state.");
460 if (Mode == StateTransitionMode::Transition)
461 {
462 Ctx.TransitionResource(pBuffer, RESOURCE_STATE_UNORDERED_ACCESS);
463 }
464 else
465 {
466 LOG_ERROR_MESSAGE("Buffer '", pBuffer->GetDesc().Name,
467 "' has not been transitioned to Unordered Access state. Call TransitionShaderResources(), use "
468 "RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the buffer to required state.");
469 }
450470 }
451471 }
452472 }
453 else if (auto* pBuffer = UAVRes.pBuffer)
454 {
455 if (pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
456 {
457 if (Mode == StateTransitionMode::Transition)
458 {
459 Ctx.TransitionResource(pBuffer, RESOURCE_STATE_UNORDERED_ACCESS);
460 }
461 else
462 {
463 LOG_ERROR_MESSAGE("Buffer '", pBuffer->GetDesc().Name,
464 "' has not been transitioned to Unordered Access state. Call TransitionShaderResources(), use "
465 "RESOURCE_STATE_TRANSITION_MODE_TRANSITION mode or explicitly transition the buffer to required state.");
466 }
467 }
468 }
473 }
474 }
475
476 void ShaderResourceCacheD3D11::BindCBs(Uint32 ShaderInd,
477 ID3D11Buffer* CommittedD3D11CBs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT],
478 Uint8& Binding,
479 Uint32& MinSlot,
480 Uint32& MaxSlot) const
481 {
482 CachedCB const* CBs;
483 ID3D11Buffer* const* d3d11CBs;
484 GetConstCBArrays(ShaderInd, CBs, d3d11CBs);
485
486 const auto CBCount = GetCBCount(ShaderInd);
487 for (Uint32 cb = 0; cb < CBCount; ++cb)
488 {
489 const Uint32 Slot = Binding++;
490 const bool IsNewCB = CommittedD3D11CBs[Slot] != d3d11CBs[cb];
491 MinSlot = IsNewCB ? std::min(MinSlot, Slot) : MinSlot;
492 MaxSlot = IsNewCB ? Slot : MaxSlot;
493
494 VERIFY_EXPR(!IsNewCB || (Slot >= MinSlot && Slot <= MaxSlot));
495 VERIFY_EXPR(d3d11CBs[cb] != nullptr);
496 CommittedD3D11CBs[Slot] = d3d11CBs[cb];
497 }
498 }
499
500 void ShaderResourceCacheD3D11::BindSRVs(Uint32 ShaderInd,
501 ID3D11ShaderResourceView* CommittedD3D11SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT],
502 ID3D11Resource* CommittedD3D11SRVResources[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT],
503 Uint8& Binding,
504 Uint32& MinSlot,
505 Uint32& MaxSlot) const
506 {
507 CachedResource const* SRVResources;
508 ID3D11ShaderResourceView* const* d3d11SRVs;
509 GetConstSRVArrays(ShaderInd, SRVResources, d3d11SRVs);
510
511 const auto SRVCount = GetSRVCount(ShaderInd);
512 for (Uint32 srv = 0; srv < SRVCount; ++srv)
513 {
514 const Uint32 Slot = Binding++;
515 const bool IsNewSRV = CommittedD3D11SRVs[Slot] != d3d11SRVs[srv];
516 MinSlot = IsNewSRV ? std::min(MinSlot, Slot) : MinSlot;
517 MaxSlot = IsNewSRV ? Slot : MaxSlot;
518
519 VERIFY_EXPR(!IsNewSRV || (Slot >= MinSlot && Slot <= MaxSlot));
520 VERIFY_EXPR(d3d11SRVs[srv] != nullptr);
521 CommittedD3D11SRVResources[Slot] = SRVResources[srv].pd3d11Resource;
522 CommittedD3D11SRVs[Slot] = d3d11SRVs[srv];
523 }
524 }
525
526 void ShaderResourceCacheD3D11::BindSamplers(Uint32 ShaderInd,
527 ID3D11SamplerState* CommittedD3D11Samplers[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT],
528 Uint8& Binding,
529 Uint32& MinSlot,
530 Uint32& MaxSlot) const
531 {
532 CachedSampler const* Samplers;
533 ID3D11SamplerState* const* d3d11Samplers;
534 GetConstSamplerArrays(ShaderInd, Samplers, d3d11Samplers);
535
536 const auto SamplerCount = GetSamplerCount(ShaderInd);
537 for (Uint32 sam = 0; sam < SamplerCount; ++sam)
538 {
539 const Uint32 Slot = Binding++;
540 const bool IsNewSam = CommittedD3D11Samplers[Slot] != d3d11Samplers[sam];
541 MinSlot = IsNewSam ? std::min(MinSlot, Slot) : MinSlot;
542 MaxSlot = IsNewSam ? Slot : MaxSlot;
543
544 VERIFY_EXPR(!IsNewSam || (Slot >= MinSlot && Slot <= MaxSlot));
545 VERIFY_EXPR(d3d11Samplers[sam] != nullptr);
546 CommittedD3D11Samplers[Slot] = d3d11Samplers[sam];
547 }
548 }
549
550 void ShaderResourceCacheD3D11::BindUAVs(Uint32 ShaderInd,
551 ID3D11UnorderedAccessView* CommittedD3D11UAVs[D3D11_PS_CS_UAV_REGISTER_COUNT],
552 ID3D11Resource* CommittedD3D11UAVResources[D3D11_PS_CS_UAV_REGISTER_COUNT],
553 Uint8& Binding,
554 Uint32& MinSlot,
555 Uint32& MaxSlot) const
556 {
557 CachedResource const* UAVResources;
558 ID3D11UnorderedAccessView* const* d3d11UAVs;
559 GetConstUAVArrays(ShaderInd, UAVResources, d3d11UAVs);
560
561 const auto UAVCount = GetUAVCount(ShaderInd);
562 for (Uint32 uav = 0; uav < UAVCount; ++uav)
563 {
564 const Uint32 Slot = Binding++;
565 const bool IsNewUAV = CommittedD3D11UAVs[Slot] != d3d11UAVs[uav];
566 MinSlot = IsNewUAV ? std::min(MinSlot, Slot) : MinSlot;
567 MaxSlot = IsNewUAV ? Slot : MaxSlot;
568
569 VERIFY_EXPR(!IsNewUAV || (Slot >= MinSlot && Slot <= MaxSlot));
570 VERIFY_EXPR(d3d11UAVs[uav] != nullptr);
571 CommittedD3D11UAVResources[Slot] = UAVResources[uav].pd3d11Resource;
572 CommittedD3D11UAVs[Slot] = d3d11UAVs[uav];
469573 }
470574 }
471575
226226 Uint32 bufUav = 0;
227227 Uint32 sam = 0;
228228
229 Uint32 NumCBSlots = 0;
230 Uint32 NumSRVSlots = 0;
231 Uint32 NumSamplerSlots = 0;
232 Uint32 NumUAVSlots = 0;
233229 ProcessSignatureResources(
234230 Signature, AllowedVarTypes, NumAllowedTypes, ShaderType,
235231 [&](Uint32 Index) //
236232 {
237233 const auto& ResDesc = Signature.GetResourceDesc(Index);
238 const auto& ResAttr = Signature.GetResourceAttribs(Index);
239234 static_assert(SHADER_RESOURCE_TYPE_LAST == 8, "Please update the switch below to handle the new shader resource range");
240235 switch (ResDesc.ResourceType)
241236 {
242237 case SHADER_RESOURCE_TYPE_CONSTANT_BUFFER:
243238 // Initialize current CB in place, increment CB counter
244239 new (&GetResource<ConstBuffBindInfo>(cb++)) ConstBuffBindInfo(*this, Index);
245 NumCBSlots = std::max(NumCBSlots, ResAttr.CacheOffset + ResDesc.ArraySize);
246240 break;
247241
248242 case SHADER_RESOURCE_TYPE_TEXTURE_SRV:
249243 case SHADER_RESOURCE_TYPE_INPUT_ATTACHMENT:
250244 // Initialize tex SRV in place, increment counter of tex SRVs
251245 new (&GetResource<TexSRVBindInfo>(texSrv++)) TexSRVBindInfo{*this, Index};
252 NumSRVSlots = std::max(NumSRVSlots, ResAttr.CacheOffset + ResDesc.ArraySize);
253246 break;
254247
255248 case SHADER_RESOURCE_TYPE_BUFFER_SRV:
256249 // Initialize buff SRV in place, increment counter of buff SRVs
257250 new (&GetResource<BuffSRVBindInfo>(bufSrv++)) BuffSRVBindInfo(*this, Index);
258 NumSRVSlots = std::max(NumSRVSlots, ResAttr.CacheOffset + ResDesc.ArraySize);
259251 break;
260252
261253 case SHADER_RESOURCE_TYPE_TEXTURE_UAV:
262254 // Initialize tex UAV in place, increment counter of tex UAVs
263255 new (&GetResource<TexUAVBindInfo>(texUav++)) TexUAVBindInfo(*this, Index);
264 NumUAVSlots = std::max(NumUAVSlots, ResAttr.CacheOffset + ResDesc.ArraySize);
265256 break;
266257
267258 case SHADER_RESOURCE_TYPE_BUFFER_UAV:
268259 // Initialize buff UAV in place, increment counter of buff UAVs
269260 new (&GetResource<BuffUAVBindInfo>(bufUav++)) BuffUAVBindInfo(*this, Index);
270 NumUAVSlots = std::max(NumUAVSlots, ResAttr.CacheOffset + ResDesc.ArraySize);
271261 break;
272262
273263 case SHADER_RESOURCE_TYPE_SAMPLER:
274264 // Initialize current sampler in place, increment sampler counter
275265 new (&GetResource<SamplerBindInfo>(sam++)) SamplerBindInfo(*this, Index);
276 NumSamplerSlots = std::max(NumSamplerSlots, ResAttr.CacheOffset + ResDesc.ArraySize);
277266 break;
278267
279268 default:
305294 RefCntAutoPtr<BufferD3D11Impl> pBuffD3D11Impl{pBuffer, IID_BufferD3D11};
306295 #ifdef DILIGENT_DEVELOPMENT
307296 {
308 const auto& CachedCB = ResourceCache.GetCB(Attr.CacheOffset + ArrayIndex);
297 const auto& CachedCB = ResourceCache.GetCB(Attr.BindPoints + ArrayIndex);
309298 VerifyConstantBufferBinding(Desc, ArrayIndex, pBuffer, pBuffD3D11Impl.RawPtr(), CachedCB.pBuff.RawPtr(),
310299 m_ParentManager.m_pSignature->GetDesc().Name);
311300 }
312301 #endif
313 ResourceCache.SetCB(Attr.CacheOffset + ArrayIndex, Attr.BindPoints + ArrayIndex, std::move(pBuffD3D11Impl));
302 ResourceCache.SetCB(Attr.BindPoints + ArrayIndex, std::move(pBuffD3D11Impl));
314303 }
315304
316305
329318 RefCntAutoPtr<TextureViewD3D11Impl> pViewD3D11{pView, IID_TextureViewD3D11};
330319 #ifdef DILIGENT_DEVELOPMENT
331320 {
332 auto& CachedSRV = ResourceCache.GetSRV(Attr.CacheOffset + ArrayIndex);
321 auto& CachedSRV = ResourceCache.GetSRV(Attr.BindPoints + ArrayIndex);
333322 VerifyResourceViewBinding(Desc, ArrayIndex,
334323 pView, pViewD3D11.RawPtr(), {TEXTURE_VIEW_SHADER_RESOURCE},
335324 RESOURCE_DIM_UNDEFINED, false, CachedSRV.pView.RawPtr(),
363352 #ifdef DILIGENT_DEVELOPMENT
364353 if (SampDesc.VarType != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC)
365354 {
366 auto& CachedSampler = ResourceCache.GetSampler(SampAttr.CacheOffset + SampArrayIndex);
355 auto& CachedSampler = ResourceCache.GetSampler(SampAttr.BindPoints + SampArrayIndex);
367356 if (CachedSampler.pSampler != nullptr && CachedSampler.pSampler != pSamplerD3D11Impl)
368357 {
369358 auto VarTypeStr = GetShaderVariableTypeLiteralName(GetType());
372361 }
373362 }
374363 #endif
375 ResourceCache.SetSampler(SampAttr.CacheOffset + SampArrayIndex, SampAttr.BindPoints + SampArrayIndex, pSamplerD3D11Impl);
376 }
377 ResourceCache.SetTexSRV(Attr.CacheOffset + ArrayIndex, Attr.BindPoints + ArrayIndex, std::move(pViewD3D11));
364 ResourceCache.SetSampler(SampAttr.BindPoints + SampArrayIndex, pSamplerD3D11Impl);
365 }
366 ResourceCache.SetTexSRV(Attr.BindPoints + ArrayIndex, std::move(pViewD3D11));
378367 }
379368
380369 void ShaderVariableManagerD3D11::SamplerBindInfo::BindResource(IDeviceObject* pSampler, Uint32 ArrayIndex)
407396
408397 if (GetType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC)
409398 {
410 auto& CachedSampler = ResourceCache.GetSampler(Attr.CacheOffset + ArrayIndex);
399 auto& CachedSampler = ResourceCache.GetSampler(Attr.BindPoints + ArrayIndex);
411400 if (CachedSampler.pSampler != nullptr && CachedSampler.pSampler != pSamplerD3D11)
412401 {
413402 auto VarTypeStr = GetShaderVariableTypeLiteralName(GetType());
418407 }
419408 #endif
420409
421 ResourceCache.SetSampler(Attr.CacheOffset + ArrayIndex, Attr.BindPoints + ArrayIndex, std::move(pSamplerD3D11));
410 ResourceCache.SetSampler(Attr.BindPoints + ArrayIndex, std::move(pSamplerD3D11));
422411 }
423412
424413 void ShaderVariableManagerD3D11::BuffSRVBindInfo::BindResource(IDeviceObject* pView, Uint32 ArrayIndex)
435424 RefCntAutoPtr<BufferViewD3D11Impl> pViewD3D11{pView, IID_BufferViewD3D11};
436425 #ifdef DILIGENT_DEVELOPMENT
437426 {
438 auto& CachedSRV = ResourceCache.GetSRV(Attr.CacheOffset + ArrayIndex);
427 auto& CachedSRV = ResourceCache.GetSRV(Attr.BindPoints + ArrayIndex);
439428 VerifyResourceViewBinding(Desc, ArrayIndex,
440429 pView, pViewD3D11.RawPtr(), {BUFFER_VIEW_SHADER_RESOURCE},
441430 RESOURCE_DIM_BUFFER, false, CachedSRV.pView.RawPtr(),
443432 ValidateBufferMode(Desc, ArrayIndex, pViewD3D11.RawPtr());
444433 }
445434 #endif
446 ResourceCache.SetBufSRV(Attr.CacheOffset + ArrayIndex, Attr.BindPoints + ArrayIndex, std::move(pViewD3D11));
435 ResourceCache.SetBufSRV(Attr.BindPoints + ArrayIndex, std::move(pViewD3D11));
447436 }
448437
449438
461450 RefCntAutoPtr<TextureViewD3D11Impl> pViewD3D11{pView, IID_TextureViewD3D11};
462451 #ifdef DILIGENT_DEVELOPMENT
463452 {
464 auto& CachedUAV = ResourceCache.GetUAV(Attr.CacheOffset + ArrayIndex);
453 auto& CachedUAV = ResourceCache.GetUAV(Attr.BindPoints + ArrayIndex);
465454 VerifyResourceViewBinding(Desc, ArrayIndex,
466455 pView, pViewD3D11.RawPtr(), {TEXTURE_VIEW_UNORDERED_ACCESS},
467456 RESOURCE_DIM_UNDEFINED, false, CachedUAV.pView.RawPtr(),
468457 m_ParentManager.m_pSignature->GetDesc().Name);
469458 }
470459 #endif
471 ResourceCache.SetTexUAV(Attr.CacheOffset + ArrayIndex, Attr.BindPoints + ArrayIndex, std::move(pViewD3D11));
460 ResourceCache.SetTexUAV(Attr.BindPoints + ArrayIndex, std::move(pViewD3D11));
472461 }
473462
474463
486475 RefCntAutoPtr<BufferViewD3D11Impl> pViewD3D11{pView, IID_BufferViewD3D11};
487476 #ifdef DILIGENT_DEVELOPMENT
488477 {
489 auto& CachedUAV = ResourceCache.GetUAV(Attr.CacheOffset + ArrayIndex);
478 auto& CachedUAV = ResourceCache.GetUAV(Attr.BindPoints + ArrayIndex);
490479 VerifyResourceViewBinding(Desc, ArrayIndex,
491480 pView, pViewD3D11.RawPtr(), {BUFFER_VIEW_UNORDERED_ACCESS},
492481 RESOURCE_DIM_BUFFER, false, CachedUAV.pView.RawPtr(),
494483 ValidateBufferMode(Desc, ArrayIndex, pViewD3D11.RawPtr());
495484 }
496485 #endif
497 ResourceCache.SetBufUAV(Attr.CacheOffset + ArrayIndex, Attr.BindPoints + ArrayIndex, std::move(pViewD3D11));
486 ResourceCache.SetBufUAV(Attr.BindPoints + ArrayIndex, std::move(pViewD3D11));
498487 }
499488
500489 void ShaderVariableManagerD3D11::BindResources(IResourceMapping* pResourceMapping, Uint32 Flags)