git.s-ol.nu ~forks/DiligentCore / 5566a3f
More updates to ShaderResourceCacheD3D11 and resource binding in D3D11 assiduous 6 months ago
7 changed file(s) with 502 addition(s) and 505 deletion(s). Raw diff Collapse all Expand all
345345 /// An array of D3D11 constant buffers committed to D3D11 device context,
346346 /// for each shader type. The context addref's all bound resources, so we do
347347 /// not need to keep strong references.
348 ID3D11Buffer* D3D11CBs [NumShaderTypes][D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {};
348 ID3D11Buffer* d3d11CBs [NumShaderTypes][D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {};
349349
350350 /// An array of D3D11 shader resource views committed to D3D11 device context,
351351 /// for each shader type. The context addref's all bound resources, so we do
352352 /// not need to keep strong references.
353 ID3D11ShaderResourceView* D3D11SRVs [NumShaderTypes][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {};
353 ID3D11ShaderResourceView* d3d11SRVs [NumShaderTypes][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {};
354354
355355 /// An array of D3D11 samplers committed to D3D11 device context,
356356 /// for each shader type. The context addref's all bound resources, so we do
357357 /// not need to keep strong references.
358 ID3D11SamplerState* D3D11Samplers[NumShaderTypes][D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {};
358 ID3D11SamplerState* d3d11Samplers[NumShaderTypes][D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {};
359359
360360 /// An array of D3D11 UAVs committed to D3D11 device context,
361361 /// for each shader type. The context addref's all bound resources, so we do
362362 /// not need to keep strong references.
363 ID3D11UnorderedAccessView* D3D11UAVs [NumShaderTypes][D3D11_PS_CS_UAV_REGISTER_COUNT] = {};
363 ID3D11UnorderedAccessView* d3d11UAVs [NumShaderTypes][D3D11_PS_CS_UAV_REGISTER_COUNT] = {};
364364
365365 /// An array of D3D11 resources commited as SRV to D3D11 device context,
366366 /// for each shader type. The context addref's all bound resources, so we do
367367 /// not need to keep strong references.
368 ID3D11Resource* D3D11SRVResources [NumShaderTypes][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {};
368 ID3D11Resource* d3d11SRVResources [NumShaderTypes][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {};
369369
370370 /// An array of D3D11 resources commited as UAV to D3D11 device context,
371371 /// for each shader type. The context addref's all bound resources, so we do
372372 /// not need to keep strong references.
373 ID3D11Resource* D3D11UAVResources [NumShaderTypes][D3D11_PS_CS_UAV_REGISTER_COUNT] = {};
373 ID3D11Resource* d3d11UAVResources [NumShaderTypes][D3D11_PS_CS_UAV_REGISTER_COUNT] = {};
374374
375375 Uint8 NumCBs [NumShaderTypes] = {};
376376 Uint8 NumSRVs [NumShaderTypes] = {};
4646 namespace Diligent
4747 {
4848
49 /// The class implements a cache that holds resources bound to a specific shader stage
49 /// The class implements a cache that holds resources bound to all shader stages.
5050 // All resources are stored in the continuous memory using the following layout:
5151 //
5252 // | CachedCB | ID3D11Buffer* || CachedResource | ID3D11ShaderResourceView* || CachedSampler | ID3D11SamplerState* || CachedResource | ID3D11UnorderedAccessView*||
7272 ShaderResourceCacheD3D11& operator = (ShaderResourceCacheD3D11&&) = delete;
7373 // clang-format on
7474
75 /// Describes a resource associated with a cached constant buffer
76 struct CachedCB
77 {
78 /// Strong reference to the buffer
79 RefCntAutoPtr<BufferD3D11Impl> pBuff;
80
81 explicit operator bool() const
82 {
83 return pBuff;
84 }
85
86 __forceinline void Set(RefCntAutoPtr<BufferD3D11Impl> _pBuff)
87 {
88 pBuff = std::move(_pBuff);
89 }
90 };
91
92 /// Describes a resource associated with a cached sampler
93 struct CachedSampler
94 {
95 /// Strong reference to the sampler
96 RefCntAutoPtr<SamplerD3D11Impl> pSampler;
97
98 explicit operator bool() const
99 {
100 return pSampler;
101 }
102
103 __forceinline void Set(SamplerD3D11Impl* pSam)
104 {
105 pSampler = pSam;
106 }
107 };
108
109 /// Describes a resource associated with a cached SRV or a UAV
110 struct CachedResource
111 {
112 /// Wee keep strong reference to the view instead of the reference
113 /// to the texture or buffer because this is more efficient from
114 /// performance point of view: this avoids one pair of
115 /// AddStrongRef()/ReleaseStrongRef(). The view holds strong reference
116 /// to the texture or the buffer, so it makes no difference.
117 RefCntAutoPtr<IDeviceObject> pView;
118
119 TextureBaseD3D11* pTexture = nullptr;
120 BufferD3D11Impl* pBuffer = nullptr;
121
122 // There is no need to keep strong reference to D3D11 resource as
123 // it is already kept by either pTexture or pBuffer
124 ID3D11Resource* pd3d11Resource = nullptr;
125
126 CachedResource() noexcept {}
127
128 explicit operator bool() const
129 {
130 VERIFY_EXPR((pView && pd3d11Resource != nullptr) || (!pView && pd3d11Resource == nullptr));
131 VERIFY_EXPR(pTexture == nullptr || pBuffer == nullptr);
132 VERIFY_EXPR((pView && (pTexture != nullptr || pBuffer != nullptr)) || (!pView && (pTexture == nullptr && pBuffer == nullptr)));
133 return pView;
134 }
135
136 __forceinline void Set(RefCntAutoPtr<TextureViewD3D11Impl> pTexView)
137 {
138 pBuffer = nullptr;
139 // Avoid unnecessary virtual function calls
140 pTexture = pTexView ? pTexView->GetTexture<TextureBaseD3D11>() : nullptr;
141 pView = std::move(pTexView);
142 pd3d11Resource = pTexture ? pTexture->TextureBaseD3D11::GetD3D11Texture() : nullptr;
143 }
144
145 __forceinline void Set(RefCntAutoPtr<BufferViewD3D11Impl> pBufView)
146 {
147 pTexture = nullptr;
148 // Avoid unnecessary virtual function calls
149 pBuffer = pBufView ? pBufView->GetBuffer<BufferD3D11Impl>() : nullptr;
150 pView = std::move(pBufView);
151 pd3d11Resource = pBuffer ? pBuffer->BufferD3D11Impl::GetD3D11Buffer() : nullptr;
152 }
153 };
154
155 template <D3D11_RESOURCE_RANGE>
156 struct CachedResourceTraits;
157
158 static constexpr int NumShaderTypes = BindPointsD3D11::NumShaderTypes;
159 using TResourcesPerStage = std::array<std::array<Uint8, NumShaderTypes>, D3D11_RESOURCE_RANGE_COUNT>;
160
161 static size_t GetRequriedMemorySize(const TResourcesPerStage& ResCount);
162
163 void Initialize(const TResourcesPerStage& ResCount, IMemoryAllocator& MemAllocator);
164
165 __forceinline void SetCB(BindPointsD3D11 BindPoints, RefCntAutoPtr<BufferD3D11Impl> pBuffD3D11Impl)
166 {
167 auto* pd3d11Buff = pBuffD3D11Impl ? pBuffD3D11Impl->BufferD3D11Impl::GetD3D11Buffer() : nullptr;
168 SetD3D11ResourceInternal<D3D11_RESOURCE_RANGE_CBV>(BindPoints, std::move(pBuffD3D11Impl), pd3d11Buff);
169 }
170
171 __forceinline void SetTexSRV(BindPointsD3D11 BindPoints, RefCntAutoPtr<TextureViewD3D11Impl> pTexView)
172 {
173 auto* pd3d11SRV = pTexView ? static_cast<ID3D11ShaderResourceView*>(pTexView->TextureViewD3D11Impl::GetD3D11View()) : nullptr;
174 SetD3D11ResourceInternal<D3D11_RESOURCE_RANGE_SRV>(BindPoints, std::move(pTexView), pd3d11SRV);
175 }
176
177 __forceinline void SetBufSRV(BindPointsD3D11 BindPoints, RefCntAutoPtr<BufferViewD3D11Impl> pBuffView)
178 {
179 auto* pd3d11SRV = pBuffView ? static_cast<ID3D11ShaderResourceView*>(pBuffView->BufferViewD3D11Impl::GetD3D11View()) : nullptr;
180 SetD3D11ResourceInternal<D3D11_RESOURCE_RANGE_SRV>(BindPoints, std::move(pBuffView), pd3d11SRV);
181 }
182
183 __forceinline void SetTexUAV(BindPointsD3D11 BindPoints, RefCntAutoPtr<TextureViewD3D11Impl> pTexView)
184 {
185 auto* pd3d11UAV = pTexView ? static_cast<ID3D11UnorderedAccessView*>(pTexView->TextureViewD3D11Impl::GetD3D11View()) : nullptr;
186 SetD3D11ResourceInternal<D3D11_RESOURCE_RANGE_UAV>(BindPoints, std::move(pTexView), pd3d11UAV);
187 }
188
189 __forceinline void SetBufUAV(BindPointsD3D11 BindPoints, RefCntAutoPtr<BufferViewD3D11Impl> pBuffView)
190 {
191 auto* pd3d11UAV = pBuffView ? static_cast<ID3D11UnorderedAccessView*>(pBuffView->BufferViewD3D11Impl::GetD3D11View()) : nullptr;
192 SetD3D11ResourceInternal<D3D11_RESOURCE_RANGE_UAV>(BindPoints, std::move(pBuffView), pd3d11UAV);
193 }
194
195 __forceinline void SetSampler(BindPointsD3D11 BindPoints, SamplerD3D11Impl* pSampler)
196 {
197 auto* pd3d11Sampler = pSampler ? pSampler->SamplerD3D11Impl::GetD3D11SamplerState() : nullptr;
198 SetD3D11ResourceInternal<D3D11_RESOURCE_RANGE_SAMPLER>(BindPoints, pSampler, pd3d11Sampler);
199 }
200
201
202 template <D3D11_RESOURCE_RANGE ResRange>
203 __forceinline const typename CachedResourceTraits<ResRange>::CachedResourceType& GetResource(BindPointsD3D11 BindPoints) const
204 {
205 VERIFY(BindPoints.GetActiveBits() != 0, "No active shader stage");
206 const auto ShaderInd = PlatformMisc::GetLSB(BindPoints.GetActiveBits());
207 const auto Offset = BindPoints[ShaderInd];
208 VERIFY(Offset < GetResourceCount<ResRange>(ShaderInd), "Resource slot is out of range");
209 const auto ResArrays = GetConstResourceArrays<ResRange>(ShaderInd);
210 return ResArrays.first[BindPoints[ShaderInd]];
211 }
212
213 template <D3D11_RESOURCE_RANGE ResRange>
214 bool CopyResource(const ShaderResourceCacheD3D11& SrcCache, BindPointsD3D11 BindPoints)
215 {
216 bool IsBound = true;
217 for (Uint32 ActiveBits = BindPoints.GetActiveBits(); ActiveBits != 0;)
218 {
219 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
220 ActiveBits &= ~(1u << ShaderInd);
221
222 auto SrcResArrays = SrcCache.GetConstResourceArrays<ResRange>(ShaderInd);
223 auto DstResArrays = GetResourceArrays<ResRange>(ShaderInd);
224
225 const Uint32 CacheOffset = BindPoints[ShaderInd];
226 VERIFY(CacheOffset < GetResourceCount<ResRange>(ShaderInd), "Index is out of range");
227 if (!SrcResArrays.first[CacheOffset])
228 IsBound = false;
229
230 DstResArrays.first[CacheOffset] = SrcResArrays.first[CacheOffset];
231 DstResArrays.second[CacheOffset] = SrcResArrays.second[CacheOffset];
232 }
233 VERIFY_EXPR(IsBound == IsResourceBound<ResRange>(BindPoints));
234 return IsBound;
235 }
236
237 template <D3D11_RESOURCE_RANGE ResRange>
238 __forceinline bool IsResourceBound(BindPointsD3D11 BindPoints) const
239 {
240 Uint32 ActiveBits = BindPoints.GetActiveBits();
241 if (ActiveBits == 0)
242 return false;
243
244 const Uint32 FirstShaderInd = PlatformMisc::GetLSB(ActiveBits);
245 const bool IsBound = IsResourceBound<ResRange>(FirstShaderInd, BindPoints[FirstShaderInd]);
246
247 #ifdef DILIGENT_DEBUG
248 ActiveBits &= ~(1u << FirstShaderInd);
249 while (ActiveBits != 0)
250 {
251 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
252 ActiveBits &= ~(1u << ShaderInd);
253 VERIFY_EXPR(IsBound == IsResourceBound<ResRange>(ShaderInd, BindPoints[ShaderInd]));
254 }
255 #endif
256
257 return IsBound;
258 }
259
260 #ifdef DILIGENT_DEVELOPMENT
261 void DvpVerifyCacheConsistency();
262 #endif
263
264 // clang-format off
265 __forceinline Uint32 GetCBCount (Uint32 ShaderInd) const { return (m_Offsets[FirstCBOffsetIdx + ShaderInd + 1] - m_Offsets[FirstCBOffsetIdx + ShaderInd]) / (sizeof(CachedCB) + sizeof(ID3D11Buffer*)); }
266 __forceinline Uint32 GetSRVCount (Uint32 ShaderInd) const { return (m_Offsets[FirstSRVOffsetIdx + ShaderInd + 1] - m_Offsets[FirstSRVOffsetIdx + ShaderInd]) / (sizeof(CachedResource) + sizeof(ID3D11ShaderResourceView*)); }
267 __forceinline Uint32 GetSamplerCount(Uint32 ShaderInd) const { return (m_Offsets[FirstSamOffsetIdx + ShaderInd + 1] - m_Offsets[FirstSamOffsetIdx + ShaderInd]) / (sizeof(CachedSampler) + sizeof(ID3D11SamplerState*)); }
268 __forceinline Uint32 GetUAVCount (Uint32 ShaderInd) const { return (m_Offsets[FirstUAVOffsetIdx + ShaderInd + 1] - m_Offsets[FirstUAVOffsetIdx + ShaderInd]) / (sizeof(CachedResource) + sizeof(ID3D11UnorderedAccessView*));}
269 // clang-format on
270
271 template <D3D11_RESOURCE_RANGE>
272 __forceinline Uint32 GetResourceCount(Uint32 ShaderInd) const;
273
274 bool IsInitialized() const { return m_IsInitialized; }
275
276 ResourceCacheContentType GetContentType() const { return m_ContentType; }
277
278 struct MinMaxSlot
279 {
280 UINT MinSlot = UINT_MAX;
281 UINT MaxSlot = 0;
282
283 void Add(UINT Slot)
284 {
285 MinSlot = std::min(MinSlot, Slot);
286
287 VERIFY_EXPR(Slot >= MaxSlot);
288 MaxSlot = Slot;
289 }
290
291 explicit operator bool() const
292 {
293 return MinSlot <= MaxSlot;
294 }
295 };
296
297 template <D3D11_RESOURCE_RANGE Range>
298 MinMaxSlot BindResources(Uint32 ShaderInd,
299 typename CachedResourceTraits<Range>::D3D11ResourceType* CommittedD3D11Resources[],
300 Uint8& Binding) const;
301
302 template <D3D11_RESOURCE_RANGE Range>
303 MinMaxSlot BindResourceViews(Uint32 ShaderInd,
304 typename CachedResourceTraits<Range>::D3D11ResourceType* CommittedD3D11Views[],
305 ID3D11Resource* CommittedD3D11Resources[],
306 Uint8& Binding) const;
307
75308 enum class StateTransitionMode
76309 {
77310 Transition,
81314 template <StateTransitionMode Mode>
82315 void TransitionResourceStates(DeviceContextD3D11Impl& Ctx);
83316
84 /// Describes a resource associated with a cached constant buffer
85 struct CachedCB
86 {
87 /// Strong reference to the buffer
88 RefCntAutoPtr<BufferD3D11Impl> pBuff;
89
90 explicit operator bool() const
91 {
92 return pBuff;
93 }
94
95 private:
96 friend class ShaderResourceCacheD3D11;
97 __forceinline void Set(RefCntAutoPtr<BufferD3D11Impl> _pBuff)
98 {
99 pBuff = std::move(_pBuff);
100 }
101 };
102
103 /// Describes a resource associated with a cached sampler
104 struct CachedSampler
105 {
106 /// Strong reference to the sampler
107 RefCntAutoPtr<SamplerD3D11Impl> pSampler;
108
109 explicit operator bool() const
110 {
111 return pSampler;
112 }
113
114 private:
115 friend class ShaderResourceCacheD3D11;
116 __forceinline void Set(SamplerD3D11Impl* pSam)
117 {
118 pSampler = pSam;
119 }
120 };
121
122 /// Describes a resource associated with a cached SRV or a UAV
123 struct CachedResource
124 {
125 /// Wee keep strong reference to the view instead of the reference
126 /// to the texture or buffer because this is more efficient from
127 /// performance point of view: this avoids one pair of
128 /// AddStrongRef()/ReleaseStrongRef(). The view holds strong reference
129 /// to the texture or the buffer, so it makes no difference.
130 RefCntAutoPtr<IDeviceObject> pView;
131
132 TextureBaseD3D11* pTexture = nullptr;
133 BufferD3D11Impl* pBuffer = nullptr;
134
135 // There is no need to keep strong reference to D3D11 resource as
136 // it is already kept by either pTexture or pBuffer
137 ID3D11Resource* pd3d11Resource = nullptr;
138
139 CachedResource() noexcept {}
140
141 explicit operator bool() const
142 {
143 VERIFY_EXPR((pView && pd3d11Resource != nullptr) || (!pView && pd3d11Resource == nullptr));
144 VERIFY_EXPR(pTexture == nullptr || pBuffer == nullptr);
145 VERIFY_EXPR((pView && (pTexture != nullptr || pBuffer != nullptr)) || (!pView && (pTexture == nullptr && pBuffer == nullptr)));
146 return pView;
147 }
148
149 private:
150 friend class ShaderResourceCacheD3D11;
151 __forceinline void Set(RefCntAutoPtr<TextureViewD3D11Impl> pTexView)
152 {
153 pBuffer = nullptr;
154 // Avoid unnecessary virtual function calls
155 pTexture = pTexView ? pTexView->GetTexture<TextureBaseD3D11>() : nullptr;
156 pView = std::move(pTexView);
157 pd3d11Resource = pTexture ? pTexture->TextureBaseD3D11::GetD3D11Texture() : nullptr;
158 }
159
160 __forceinline void Set(RefCntAutoPtr<BufferViewD3D11Impl> pBufView)
161 {
162 pTexture = nullptr;
163 // Avoid unnecessary virtual function calls
164 pBuffer = pBufView ? pBufView->GetBuffer<BufferD3D11Impl>() : nullptr;
165 pView = std::move(pBufView);
166 pd3d11Resource = pBuffer ? pBuffer->BufferD3D11Impl::GetD3D11Buffer() : nullptr;
167 }
168 };
169
170 template <typename D3D11ResourceType>
171 struct CachedResourceTraits;
172
173 static constexpr int NumShaderTypes = BindPointsD3D11::NumShaderTypes;
174 using TBindingsPerStage = std::array<std::array<Uint8, NumShaderTypes>, D3D11_RESOURCE_RANGE_COUNT>;
175
176 static size_t GetRequriedMemorySize(const TBindingsPerStage& ResCount);
177
178 void Initialize(const TBindingsPerStage& ResCount, IMemoryAllocator& MemAllocator);
179
180 __forceinline void SetCB(BindPointsD3D11 BindPoints, RefCntAutoPtr<BufferD3D11Impl> pBuffD3D11Impl)
181 {
182 auto* pd3d11Buff = pBuffD3D11Impl ? pBuffD3D11Impl->BufferD3D11Impl::GetD3D11Buffer() : nullptr;
183 SetD3D11ResourceInternal(BindPoints, std::move(pBuffD3D11Impl), pd3d11Buff);
184 }
185
186 __forceinline void SetTexSRV(BindPointsD3D11 BindPoints, RefCntAutoPtr<TextureViewD3D11Impl> pTexView)
187 {
188 auto* pd3d11SRV = pTexView ? static_cast<ID3D11ShaderResourceView*>(pTexView->TextureViewD3D11Impl::GetD3D11View()) : nullptr;
189 SetD3D11ResourceInternal(BindPoints, std::move(pTexView), pd3d11SRV);
190 }
191
192 __forceinline void SetBufSRV(BindPointsD3D11 BindPoints, RefCntAutoPtr<BufferViewD3D11Impl> pBuffView)
193 {
194 auto* pd3d11SRV = pBuffView ? static_cast<ID3D11ShaderResourceView*>(pBuffView->BufferViewD3D11Impl::GetD3D11View()) : nullptr;
195 SetD3D11ResourceInternal(BindPoints, std::move(pBuffView), pd3d11SRV);
196 }
197
198 __forceinline void SetTexUAV(BindPointsD3D11 BindPoints, RefCntAutoPtr<TextureViewD3D11Impl> pTexView)
199 {
200 auto* pd3d11UAV = pTexView ? static_cast<ID3D11UnorderedAccessView*>(pTexView->TextureViewD3D11Impl::GetD3D11View()) : nullptr;
201 SetD3D11ResourceInternal(BindPoints, std::move(pTexView), pd3d11UAV);
202 }
203
204 __forceinline void SetBufUAV(BindPointsD3D11 BindPoints, RefCntAutoPtr<BufferViewD3D11Impl> pBuffView)
205 {
206 auto* pd3d11UAV = pBuffView ? static_cast<ID3D11UnorderedAccessView*>(pBuffView->BufferViewD3D11Impl::GetD3D11View()) : nullptr;
207 SetD3D11ResourceInternal(BindPoints, std::move(pBuffView), pd3d11UAV);
208 }
209
210 __forceinline void SetSampler(BindPointsD3D11 BindPoints, SamplerD3D11Impl* pSampler)
211 {
212 auto* pd3d11Sampler = pSampler ? pSampler->SamplerD3D11Impl::GetD3D11SamplerState() : nullptr;
213 SetD3D11ResourceInternal(BindPoints, pSampler, pd3d11Sampler);
214 }
215
216
217 template <typename D3D11ResourceType>
218 __forceinline const typename CachedResourceTraits<D3D11ResourceType>::CachedResourceType& GetResource(BindPointsD3D11 BindPoints) const
219 {
220 const Uint32 ShaderInd = PlatformMisc::GetLSB(BindPoints.GetActiveBits());
221 VERIFY(BindPoints[ShaderInd] < GetResourceCount<D3D11ResourceType>(ShaderInd), "Resource slot is out of range");
222 const auto ResArrays = GetConstResourceArrays<D3D11ResourceType>(ShaderInd);
223 return ResArrays.first[BindPoints[ShaderInd]];
224 }
225
226 template <typename D3D11ResourceType>
227 bool CopyResource(const ShaderResourceCacheD3D11& SrcCache, BindPointsD3D11 BindPoints)
228 {
229 bool IsBound = true;
230 for (Uint32 ActiveBits = BindPoints.GetActiveBits(); ActiveBits != 0;)
231 {
232 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
233 ActiveBits &= ~(1u << ShaderInd);
234
235 auto SrcResArrays = SrcCache.GetConstResourceArrays<D3D11ResourceType>(ShaderInd);
236 auto DstResArrays = GetResourceArrays<D3D11ResourceType>(ShaderInd);
237
238 const Uint32 CacheOffset = BindPoints[ShaderInd];
239 VERIFY(CacheOffset < GetResourceCount<D3D11ResourceType>(ShaderInd), "Index is out of range");
240 if (!SrcResArrays.first[CacheOffset])
241 IsBound = false;
242
243 DstResArrays.first[CacheOffset] = SrcResArrays.first[CacheOffset];
244 DstResArrays.second[CacheOffset] = SrcResArrays.second[CacheOffset];
245 }
246 return IsBound;
247 }
248
249 template <typename D3D11ResourceType>
250 __forceinline bool IsResourceBound(BindPointsD3D11 BindPoints) const
251 {
252 bool IsBound = true;
253 for (Uint32 ActiveBits = BindPoints.GetActiveBits(); ActiveBits != 0;)
254 {
255 const Uint32 ShaderInd = PlatformMisc::GetLSB(ActiveBits);
256 ActiveBits &= ~(1u << ShaderInd);
257 const Uint32 CacheOffset = BindPoints[ShaderInd];
258
259 const auto ResArrays = GetConstResourceArrays<D3D11ResourceType>(ShaderInd);
260 if (CacheOffset < GetResourceCount<D3D11ResourceType>(ShaderInd) && ResArrays.first[CacheOffset])
261 {
262 continue;
263 }
264 IsBound = false;
265 }
266 return IsBound;
267 }
268
269 #ifdef DILIGENT_DEVELOPMENT
270 void DvpVerifyCacheConsistency();
271 #endif
272
273 // clang-format off
274 __forceinline Uint32 GetCBCount (Uint32 ShaderInd) const { return (m_Offsets[CBOffset + ShaderInd + 1] - m_Offsets[CBOffset + ShaderInd]) / (sizeof(CachedCB) + sizeof(ID3D11Buffer*)); }
275 __forceinline Uint32 GetSRVCount (Uint32 ShaderInd) const { return (m_Offsets[SRVOffset + ShaderInd + 1] - m_Offsets[SRVOffset + ShaderInd]) / (sizeof(CachedResource) + sizeof(ID3D11ShaderResourceView*)); }
276 __forceinline Uint32 GetSamplerCount(Uint32 ShaderInd) const { return (m_Offsets[SampOffset + ShaderInd + 1] - m_Offsets[SampOffset + ShaderInd]) / (sizeof(CachedSampler) + sizeof(ID3D11SamplerState*)); }
277 __forceinline Uint32 GetUAVCount (Uint32 ShaderInd) const { return (m_Offsets[UAVOffset + ShaderInd + 1] - m_Offsets[UAVOffset + ShaderInd]) / (sizeof(CachedResource) + sizeof(ID3D11UnorderedAccessView*)); }
278 // clang-format on
279
280 template <typename D3D11ResourceType>
281 __forceinline Uint32 GetResourceCount(Uint32 ShaderInd) const;
282
283 bool IsInitialized() const { return m_IsInitialized; }
284
285 ResourceCacheContentType GetContentType() const { return m_ContentType; }
286
287 struct MinMaxSlot
288 {
289 UINT MinSlot = UINT_MAX;
290 UINT MaxSlot = 0;
291
292 void Add(UINT Slot)
293 {
294 MinSlot = std::min(MinSlot, Slot);
295
296 VERIFY_EXPR(Slot >= MaxSlot);
297 MaxSlot = Slot;
298 }
299
300 explicit operator bool() const
301 {
302 return MinSlot <= MaxSlot;
303 }
304 };
305
306 template <typename D3D11ResourceType>
307 MinMaxSlot BindResources(Uint32 ShaderInd,
308 D3D11ResourceType* CommittedD3D11Resources[],
309 Uint8& Binding) const;
310
311 template <typename D3D11ResourceViewType>
312 MinMaxSlot BindResourceViews(Uint32 ShaderInd,
313 D3D11ResourceViewType* CommittedD3D11Views[],
314 ID3D11Resource* CommittedD3D11Resources[],
315 Uint8& Binding) const;
316
317317 private:
318 template <typename D3D11ResourceTpye>
318 template <D3D11_RESOURCE_RANGE>
319319 __forceinline Uint32 GetResourceDataOffset(Uint32 ShaderInd) const;
320320
321 template <typename D3D11ResourceType>
322 __forceinline std::pair<typename CachedResourceTraits<D3D11ResourceType>::CachedResourceType*, D3D11ResourceType**>
321 template <D3D11_RESOURCE_RANGE ResRange>
322 __forceinline std::pair<typename CachedResourceTraits<ResRange>::CachedResourceType*,
323 typename CachedResourceTraits<ResRange>::D3D11ResourceType**>
323324 GetResourceArrays(Uint32 ShaderInd) const
324325 {
325 static_assert(alignof(CachedResourceTraits<D3D11ResourceType>::CachedResourceType) == alignof(D3D11ResourceType*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
326
327 using CachedResourceType = CachedResourceTraits<D3D11ResourceType>::CachedResourceType;
328 const auto DataOffset = GetResourceDataOffset<D3D11ResourceType>(ShaderInd);
329 const auto ResCount = GetResourceCount<D3D11ResourceType>(ShaderInd);
326 using CachedResourceType = CachedResourceTraits<ResRange>::CachedResourceType;
327 using D3D11ResourceType = CachedResourceTraits<ResRange>::D3D11ResourceType;
328 static_assert(alignof(CachedResourceType) == alignof(D3D11ResourceType*), "Alignment mismatch, pointer to D3D11 resource may not be properly aligned");
329
330 const auto DataOffset = GetResourceDataOffset<ResRange>(ShaderInd);
331 const auto ResCount = GetResourceCount<ResRange>(ShaderInd);
330332 auto* const pResources = reinterpret_cast<CachedResourceType*>(m_pResourceData.get() + DataOffset);
331333 auto* const pd3d11Resources = reinterpret_cast<D3D11ResourceType**>(pResources + ResCount);
332334 return std::make_pair(pResources, pd3d11Resources);
333335 }
334336
335 template <typename D3D11ResourceType>
336 __forceinline std::pair<const typename CachedResourceTraits<D3D11ResourceType>::CachedResourceType*, D3D11ResourceType* const*>
337 template <D3D11_RESOURCE_RANGE ResRange>
338 __forceinline std::pair<typename CachedResourceTraits<ResRange>::CachedResourceType const*,
339 typename CachedResourceTraits<ResRange>::D3D11ResourceType* const*>
337340 GetConstResourceArrays(Uint32 ShaderInd) const
338341 {
339 const auto ResArrays = GetResourceArrays<D3D11ResourceType>(ShaderInd);
342 const auto ResArrays = GetResourceArrays<ResRange>(ShaderInd);
340343 return std::make_pair(ResArrays.first, ResArrays.second);
341344 }
342345
343 template <typename TSrcResourceType, typename TD3D11ResourceType>
346 template <D3D11_RESOURCE_RANGE ResRange, typename TSrcResourceType, typename TD3D11ResourceType>
344347 __forceinline void SetD3D11ResourceInternal(BindPointsD3D11 BindPoints, TSrcResourceType pResource, TD3D11ResourceType* pd3d11Resource)
345348 {
346349 VERIFY(pResource != nullptr && pd3d11Resource != nullptr || pResource == nullptr && pd3d11Resource == nullptr,
351354 ActiveBits &= ~(1u << ShaderInd);
352355
353356 const Uint32 CacheOffset = BindPoints[ShaderInd];
354 const Uint32 ResCount = GetResourceCount<TD3D11ResourceType>(ShaderInd);
355 VERIFY(CacheOffset < ResCount, "Index is out of range");
356
357 auto ResArrays = GetResourceArrays<TD3D11ResourceType>(ShaderInd);
357 VERIFY(CacheOffset < GetResourceCount<ResRange>(ShaderInd), "Cache offset is out of range");
358
359 auto ResArrays = GetResourceArrays<ResRange>(ShaderInd);
358360 ResArrays.first[CacheOffset].Set(pResource);
359361 ResArrays.second[CacheOffset] = pd3d11Resource;
360362 }
363 }
364
365 template <D3D11_RESOURCE_RANGE ResRange>
366 __forceinline bool IsResourceBound(Uint32 ShaderInd, Uint32 Offset) const
367 {
368 const auto ResCount = GetResourceCount<ResRange>(ShaderInd);
369 VERIFY(Offset < ResCount, "Offset is out of range");
370 const auto ResArrays = GetConstResourceArrays<ResRange>(ShaderInd);
371 return Offset < ResCount && ResArrays.first[Offset];
361372 }
362373
363374 // Transitions or verifies the resource state.
376387 private:
377388 using OffsetType = Uint16;
378389
379 static constexpr size_t MaxAlignment = std::max(std::max(std::max(alignof(CachedCB), alignof(CachedResource)), alignof(CachedSampler)),
380 std::max(std::max(alignof(ID3D11Buffer*), alignof(ID3D11ShaderResourceView*)),
381 std::max(alignof(ID3D11SamplerState*), alignof(ID3D11UnorderedAccessView*))));
382
383 static constexpr Uint32 CBOffset = 0;
384 static constexpr Uint32 SRVOffset = CBOffset + NumShaderTypes;
385 static constexpr Uint32 SampOffset = SRVOffset + NumShaderTypes;
386 static constexpr Uint32 UAVOffset = SampOffset + NumShaderTypes;
387 static constexpr Uint32 MaxOffsets = UAVOffset + NumShaderTypes + 1;
390 static constexpr size_t MaxAlignment = std::max(std::max(std::max(alignof(CachedCB), alignof(CachedResource)), alignof(CachedSampler)), alignof(IUnknown*));
391
392 static constexpr Uint32 FirstCBOffsetIdx = 0;
393 static constexpr Uint32 FirstSRVOffsetIdx = FirstCBOffsetIdx + NumShaderTypes;
394 static constexpr Uint32 FirstSamOffsetIdx = FirstSRVOffsetIdx + NumShaderTypes;
395 static constexpr Uint32 FirstUAVOffsetIdx = FirstSamOffsetIdx + NumShaderTypes;
396 static constexpr Uint32 MaxOffsets = FirstUAVOffsetIdx + NumShaderTypes + 1;
388397
389398 std::array<OffsetType, MaxOffsets> m_Offsets = {};
390399
400409
401410
402411 template <>
403 struct ShaderResourceCacheD3D11::CachedResourceTraits<ID3D11Buffer>
412 struct ShaderResourceCacheD3D11::CachedResourceTraits<D3D11_RESOURCE_RANGE_CBV>
404413 {
405414 using CachedResourceType = CachedCB;
415 using D3D11ResourceType = ID3D11Buffer;
406416 };
407417
408418 template <>
409 struct ShaderResourceCacheD3D11::CachedResourceTraits<ID3D11SamplerState>
419 struct ShaderResourceCacheD3D11::CachedResourceTraits<D3D11_RESOURCE_RANGE_SAMPLER>
410420 {
411421 using CachedResourceType = CachedSampler;
422 using D3D11ResourceType = ID3D11SamplerState;
412423 };
413424
414425 template <>
415 struct ShaderResourceCacheD3D11::CachedResourceTraits<ID3D11ShaderResourceView>
426 struct ShaderResourceCacheD3D11::CachedResourceTraits<D3D11_RESOURCE_RANGE_SRV>
416427 {
417428 using CachedResourceType = CachedResource;
429 using D3D11ResourceType = ID3D11ShaderResourceView;
418430 };
419431
420432 template <>
421 struct ShaderResourceCacheD3D11::CachedResourceTraits<ID3D11UnorderedAccessView>
433 struct ShaderResourceCacheD3D11::CachedResourceTraits<D3D11_RESOURCE_RANGE_UAV>
422434 {
423435 using CachedResourceType = CachedResource;
436 using D3D11ResourceType = ID3D11UnorderedAccessView;
424437 };
425438
426439
427440 template <>
428 __forceinline Uint32 ShaderResourceCacheD3D11::GetResourceCount<ID3D11Buffer>(Uint32 ShaderInd) const
441 __forceinline Uint32 ShaderResourceCacheD3D11::GetResourceCount<D3D11_RESOURCE_RANGE_CBV>(Uint32 ShaderInd) const
429442 {
430443 return GetCBCount(ShaderInd);
431444 }
432445
433446 template <>
434 __forceinline Uint32 ShaderResourceCacheD3D11::GetResourceCount<ID3D11ShaderResourceView>(Uint32 ShaderInd) const
447 __forceinline Uint32 ShaderResourceCacheD3D11::GetResourceCount<D3D11_RESOURCE_RANGE_SRV>(Uint32 ShaderInd) const
435448 {
436449 return GetSRVCount(ShaderInd);
437450 }
438451
439452 template <>
440 __forceinline Uint32 ShaderResourceCacheD3D11::GetResourceCount<ID3D11UnorderedAccessView>(Uint32 ShaderInd) const
453 __forceinline Uint32 ShaderResourceCacheD3D11::GetResourceCount<D3D11_RESOURCE_RANGE_UAV>(Uint32 ShaderInd) const
441454 {
442455 return GetUAVCount(ShaderInd);
443456 }
444457
445458 template <>
446 __forceinline Uint32 ShaderResourceCacheD3D11::GetResourceCount<ID3D11SamplerState>(Uint32 ShaderInd) const
459 __forceinline Uint32 ShaderResourceCacheD3D11::GetResourceCount<D3D11_RESOURCE_RANGE_SAMPLER>(Uint32 ShaderInd) const
447460 {
448461 return GetSamplerCount(ShaderInd);
449462 }
450463
451464
452465 template <>
453 __forceinline Uint32 ShaderResourceCacheD3D11::GetResourceDataOffset<ID3D11Buffer>(Uint32 ShaderInd) const
454 {
455 return m_Offsets[CBOffset + ShaderInd];
456 }
457
458 template <>
459 __forceinline Uint32 ShaderResourceCacheD3D11::GetResourceDataOffset<ID3D11ShaderResourceView>(Uint32 ShaderInd) const
460 {
461 return m_Offsets[SRVOffset + ShaderInd];
462 }
463
464 template <>
465 __forceinline Uint32 ShaderResourceCacheD3D11::GetResourceDataOffset<ID3D11SamplerState>(Uint32 ShaderInd) const
466 {
467 return m_Offsets[SampOffset + ShaderInd];
468 }
469
470 template <>
471 __forceinline Uint32 ShaderResourceCacheD3D11::GetResourceDataOffset<ID3D11UnorderedAccessView>(Uint32 ShaderInd) const
472 {
473 return m_Offsets[UAVOffset + ShaderInd];
466 __forceinline Uint32 ShaderResourceCacheD3D11::GetResourceDataOffset<D3D11_RESOURCE_RANGE_CBV>(Uint32 ShaderInd) const
467 {
468 return m_Offsets[FirstCBOffsetIdx + ShaderInd];
469 }
470
471 template <>
472 __forceinline Uint32 ShaderResourceCacheD3D11::GetResourceDataOffset<D3D11_RESOURCE_RANGE_SRV>(Uint32 ShaderInd) const
473 {
474 return m_Offsets[FirstSRVOffsetIdx + ShaderInd];
475 }
476
477 template <>
478 __forceinline Uint32 ShaderResourceCacheD3D11::GetResourceDataOffset<D3D11_RESOURCE_RANGE_SAMPLER>(Uint32 ShaderInd) const
479 {
480 return m_Offsets[FirstSamOffsetIdx + ShaderInd];
481 }
482
483 template <>
484 __forceinline Uint32 ShaderResourceCacheD3D11::GetResourceDataOffset<D3D11_RESOURCE_RANGE_UAV>(Uint32 ShaderInd) const
485 {
486 return m_Offsets[FirstUAVOffsetIdx + ShaderInd];
474487 }
475488
476489 // Instantiate templates
477490 template void ShaderResourceCacheD3D11::TransitionResourceStates<ShaderResourceCacheD3D11::StateTransitionMode::Transition>(DeviceContextD3D11Impl& Ctx);
478491 template void ShaderResourceCacheD3D11::TransitionResourceStates<ShaderResourceCacheD3D11::StateTransitionMode::Verify>(DeviceContextD3D11Impl& Ctx);
479492
480
481 template <typename D3D11ResourceType>
493 template <D3D11_RESOURCE_RANGE Range>
482494 ShaderResourceCacheD3D11::MinMaxSlot ShaderResourceCacheD3D11::BindResources(
483 Uint32 ShaderInd,
484 D3D11ResourceType* CommittedD3D11Resources[],
485 Uint8& Binding) const
486 {
487 const auto ResCount = GetResourceCount<D3D11ResourceType>(ShaderInd);
488 const auto ResArrays = GetConstResourceArrays<D3D11ResourceType>(ShaderInd);
495 Uint32 ShaderInd,
496 typename CachedResourceTraits<Range>::D3D11ResourceType* CommittedD3D11Resources[],
497 Uint8& Binding) const
498 {
499 const auto ResCount = GetResourceCount<Range>(ShaderInd);
500 const auto ResArrays = GetConstResourceArrays<Range>(ShaderInd);
489501
490502 MinMaxSlot Slots;
491503 for (Uint32 res = 0; res < ResCount; ++res)
501513 return Slots;
502514 }
503515
504 template <typename D3D11ResourceViewType>
516
517 template <D3D11_RESOURCE_RANGE Range>
505518 ShaderResourceCacheD3D11::MinMaxSlot ShaderResourceCacheD3D11::BindResourceViews(
506 Uint32 ShaderInd,
507 D3D11ResourceViewType* CommittedD3D11Views[],
508 ID3D11Resource* CommittedD3D11Resources[],
509 Uint8& Binding) const
510 {
511 const auto ResCount = GetResourceCount<D3D11ResourceViewType>(ShaderInd);
512 const auto ResArrays = GetConstResourceArrays<D3D11ResourceViewType>(ShaderInd);
519 Uint32 ShaderInd,
520 typename CachedResourceTraits<Range>::D3D11ResourceType* CommittedD3D11Views[],
521 ID3D11Resource* CommittedD3D11Resources[],
522 Uint8& Binding) const
523 {
524 const auto ResCount = GetResourceCount<Range>(ShaderInd);
525 const auto ResArrays = GetConstResourceArrays<Range>(ShaderInd);
513526
514527 MinMaxSlot Slots;
515528 for (Uint32 res = 0; res < ResCount; ++res)
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.IsResourceBound<ID3D11Buffer>(GetAttribs().BindPoints + ArrayIndex);
135 return m_ParentManager.m_ResourceCache.IsResourceBound<D3D11_RESOURCE_RANGE_CBV>(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.IsResourceBound<ID3D11ShaderResourceView>(GetAttribs().BindPoints + ArrayIndex);
151 return m_ParentManager.m_ResourceCache.IsResourceBound<D3D11_RESOURCE_RANGE_SRV>(GetAttribs().BindPoints + ArrayIndex);
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.IsResourceBound<ID3D11UnorderedAccessView>(GetAttribs().BindPoints + ArrayIndex);
167 return m_ParentManager.m_ResourceCache.IsResourceBound<D3D11_RESOURCE_RANGE_UAV>(GetAttribs().BindPoints + ArrayIndex);
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.IsResourceBound<ID3D11UnorderedAccessView>(GetAttribs().BindPoints + ArrayIndex);
183 return m_ParentManager.m_ResourceCache.IsResourceBound<D3D11_RESOURCE_RANGE_UAV>(GetAttribs().BindPoints + ArrayIndex);
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.IsResourceBound<ID3D11ShaderResourceView>(GetAttribs().BindPoints + ArrayIndex);
199 return m_ParentManager.m_ResourceCache.IsResourceBound<D3D11_RESOURCE_RANGE_SRV>(GetAttribs().BindPoints + ArrayIndex);
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.IsResourceBound<ID3D11SamplerState>(GetAttribs().BindPoints + ArrayIndex);
215 return m_ParentManager.m_ResourceCache.IsResourceBound<D3D11_RESOURCE_RANGE_SAMPLER>(GetAttribs().BindPoints + ArrayIndex);
216216 }
217217 };
218218
267267 const TBindingsPerStage& BaseBindings,
268268 SHADER_TYPE ActiveStages)
269269 {
270 Uint8 ShaderIndices[NumShaderTypes] = {};
271 SHADER_TYPE ShaderTypes[NumShaderTypes] = {};
272 Uint32 ShaderCount = 0;
273
274 for (Uint32 Stages = ActiveStages; Stages != 0; ++ShaderCount)
275 {
276 const Uint32 ShaderInd = PlatformMisc::GetLSB(Stages);
277 Stages &= ~(1u << ShaderInd);
278 ShaderIndices[ShaderCount] = static_cast<Uint8>(ShaderInd);
279 ShaderTypes[ShaderCount] = static_cast<SHADER_TYPE>(1u << ShaderInd);
280 }
281
282 for (Uint32 i = 0; i < ShaderCount; ++i)
283 {
284 constexpr auto Range = D3D11_RESOURCE_RANGE_CBV;
285 const auto ShaderInd = ShaderIndices[i];
286 auto* CommittedD3D11CBs = m_CommittedRes.D3D11CBs[ShaderInd];
287 Uint8 Binding = BaseBindings[Range][ShaderInd];
288 auto Slots = ResourceCache.BindResources(ShaderInd, CommittedD3D11CBs, Binding);
289
290 if (Slots)
291 {
292 auto SetCBMethod = SetCBMethods[ShaderInd];
293 (m_pd3d11DeviceContext->*SetCBMethod)(Slots.MinSlot, Slots.MaxSlot - Slots.MinSlot + 1, CommittedD3D11CBs + Slots.MinSlot);
294 m_CommittedRes.NumCBs[ShaderInd] = std::max(m_CommittedRes.NumCBs[ShaderInd], Binding);
295 VERIFY_EXPR(Slots.MaxSlot < Binding);
296 }
270 bool ClearPixelShaderUAVs = m_CommittedRes.NumUAVs[PSInd] > 0;
271
272 while (ActiveStages != 0)
273 {
274 const auto ShaderInd = PlatformMisc::GetLSB(ActiveStages);
275 const auto ShaderType = static_cast<SHADER_TYPE>(1u << ShaderInd);
276 ActiveStages &= ~ShaderType;
277
278 {
279 auto* d3d11CBs = m_CommittedRes.d3d11CBs[ShaderInd];
280 Uint8 Binding = BaseBindings[D3D11_RESOURCE_RANGE_CBV][ShaderInd];
281 auto Slots = ResourceCache.BindResources<D3D11_RESOURCE_RANGE_CBV>(ShaderInd, d3d11CBs, Binding);
282
283 if (Slots)
284 {
285 auto SetCBMethod = SetCBMethods[ShaderInd];
286 (m_pd3d11DeviceContext->*SetCBMethod)(Slots.MinSlot, Slots.MaxSlot - Slots.MinSlot + 1, d3d11CBs + Slots.MinSlot);
287 m_CommittedRes.NumCBs[ShaderInd] = std::max(m_CommittedRes.NumCBs[ShaderInd], Binding);
288 VERIFY_EXPR(Slots.MaxSlot < Binding);
289 }
297290 #ifdef VERIFY_CONTEXT_BINDINGS
298 if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
299 {
300 DvpVerifyCommittedCBs(ShaderTypes[i]);
301 }
302 #endif
303 }
304
305 for (Uint32 i = 0; i < ShaderCount; ++i)
306 {
307 constexpr auto Range = D3D11_RESOURCE_RANGE_SRV;
308 const auto ShaderInd = ShaderIndices[i];
309 auto* CommittedD3D11SRVs = m_CommittedRes.D3D11SRVs[ShaderInd];
310 auto* CommittedD3D11SRVRes = m_CommittedRes.D3D11SRVResources[ShaderInd];
311 Uint8 Binding = BaseBindings[Range][ShaderInd];
312 auto Slots = ResourceCache.BindResourceViews(ShaderInd, CommittedD3D11SRVs, CommittedD3D11SRVRes, Binding);
313
314 if (Slots)
315 {
316 auto SetSRVMethod = SetSRVMethods[ShaderInd];
317 (m_pd3d11DeviceContext->*SetSRVMethod)(Slots.MinSlot, Slots.MaxSlot - Slots.MinSlot + 1, CommittedD3D11SRVs + Slots.MinSlot);
318 m_CommittedRes.NumSRVs[ShaderInd] = std::max(m_CommittedRes.NumSRVs[ShaderInd], Binding);
319 VERIFY_EXPR(Slots.MaxSlot <= Binding);
320 }
291 if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
292 {
293 DvpVerifyCommittedCBs(ShaderType);
294 }
295 #endif
296 }
297
298 {
299 auto* d3d11SRVs = m_CommittedRes.d3d11SRVs[ShaderInd];
300 auto* d3d11SRVRes = m_CommittedRes.d3d11SRVResources[ShaderInd];
301 Uint8 Binding = BaseBindings[D3D11_RESOURCE_RANGE_SRV][ShaderInd];
302 auto Slots = ResourceCache.BindResourceViews<D3D11_RESOURCE_RANGE_SRV>(ShaderInd, d3d11SRVs, d3d11SRVRes, Binding);
303
304 if (Slots)
305 {
306 auto SetSRVMethod = SetSRVMethods[ShaderInd];
307 (m_pd3d11DeviceContext->*SetSRVMethod)(Slots.MinSlot, Slots.MaxSlot - Slots.MinSlot + 1, d3d11SRVs + Slots.MinSlot);
308 m_CommittedRes.NumSRVs[ShaderInd] = std::max(m_CommittedRes.NumSRVs[ShaderInd], Binding);
309 VERIFY_EXPR(Slots.MaxSlot <= Binding);
310 }
321311 #ifdef VERIFY_CONTEXT_BINDINGS
322 if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
323 {
324 DvpVerifyCommittedSRVs(ShaderTypes[i]);
325 }
326 #endif
327 }
328
329 for (Uint32 i = 0; i < ShaderCount; ++i)
330 {
331 constexpr auto Range = D3D11_RESOURCE_RANGE_SAMPLER;
332 const auto ShaderInd = ShaderIndices[i];
333 auto* CommittedD3D11Samplers = m_CommittedRes.D3D11Samplers[ShaderInd];
334 Uint8 Binding = BaseBindings[Range][ShaderInd];
335 auto Slots = ResourceCache.BindResources(ShaderInd, CommittedD3D11Samplers, Binding);
336
337 if (Slots)
338 {
339 auto SetSamplerMethod = SetSamplerMethods[ShaderInd];
340 (m_pd3d11DeviceContext->*SetSamplerMethod)(Slots.MinSlot, Slots.MaxSlot - Slots.MinSlot + 1, CommittedD3D11Samplers + Slots.MinSlot);
341 m_CommittedRes.NumSamplers[ShaderInd] = std::max(m_CommittedRes.NumSamplers[ShaderInd], Binding);
342 VERIFY_EXPR(Slots.MaxSlot < Binding);
343 }
312 if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
313 {
314 DvpVerifyCommittedSRVs(ShaderType);
315 }
316 #endif
317 }
318
319 {
320 auto* d3d11Samplers = m_CommittedRes.d3d11Samplers[ShaderInd];
321 Uint8 Binding = BaseBindings[D3D11_RESOURCE_RANGE_SAMPLER][ShaderInd];
322 auto Slots = ResourceCache.BindResources<D3D11_RESOURCE_RANGE_SAMPLER>(ShaderInd, d3d11Samplers, Binding);
323
324 if (Slots)
325 {
326 auto SetSamplerMethod = SetSamplerMethods[ShaderInd];
327 (m_pd3d11DeviceContext->*SetSamplerMethod)(Slots.MinSlot, Slots.MaxSlot - Slots.MinSlot + 1, d3d11Samplers + Slots.MinSlot);
328 m_CommittedRes.NumSamplers[ShaderInd] = std::max(m_CommittedRes.NumSamplers[ShaderInd], Binding);
329 VERIFY_EXPR(Slots.MaxSlot < Binding);
330 }
344331 #ifdef VERIFY_CONTEXT_BINDINGS
345 if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
346 {
347 DvpVerifyCommittedSamplers(ShaderTypes[i]);
348 }
349 #endif
350 }
351
352 bool ClearPixelShaderUAVs = m_CommittedRes.NumUAVs[PSInd] > 0;
353 for (Uint32 i = 0; i < ShaderCount; ++i)
354 {
355 constexpr auto Range = D3D11_RESOURCE_RANGE_UAV;
356 const auto ShaderInd = ShaderIndices[i];
357 auto* CommittedD3D11UAVs = m_CommittedRes.D3D11UAVs[ShaderInd];
358 auto* CommittedD3D11UAVRes = m_CommittedRes.D3D11UAVResources[ShaderInd];
359 Uint8 Binding = BaseBindings[Range][ShaderInd];
360 auto Slots = ResourceCache.BindResourceViews(ShaderInd, CommittedD3D11UAVs, CommittedD3D11UAVRes, Binding);
361
362 if (Slots)
363 {
364 if (ShaderInd == PSInd)
365 ClearPixelShaderUAVs = false;
366
367 // Something has changed
368 if (ShaderInd == PSInd)
369 {
370 // Pixel shader UAVs cannot be set independently; they all need to be set at the same time.
371 // https://docs.microsoft.com/en-us/windows/desktop/api/d3d11/nf-d3d11-id3d11devicecontext-omsetrendertargetsandunorderedaccessviews#remarks
372 const auto StartUAVSlot = m_NumBoundRenderTargets;
373 const auto NumUAVSlot = Binding;
374 VERIFY(NumUAVSlot > StartUAVSlot, "Number of UAVs must be greater than the render target count");
375 m_pd3d11DeviceContext->OMSetRenderTargetsAndUnorderedAccessViews(
376 D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr,
377 StartUAVSlot, NumUAVSlot - StartUAVSlot, CommittedD3D11UAVs + StartUAVSlot, nullptr);
378 // Clear previously bound UAVs, but do not clear lower slots as if
379 // render target count reduces, we will bind these UAVs in CommitRenderTargets()
380 for (Uint32 uav = NumUAVSlot; uav < m_CommittedRes.NumUAVs[ShaderInd]; ++uav)
332 if (m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE)
333 {
334 DvpVerifyCommittedSamplers(ShaderType);
335 }
336 #endif
337 }
338
339 {
340 auto* d3d11UAVs = m_CommittedRes.d3d11UAVs[ShaderInd];
341 auto* d3d11UAVRes = m_CommittedRes.d3d11UAVResources[ShaderInd];
342 Uint8 Binding = BaseBindings[D3D11_RESOURCE_RANGE_UAV][ShaderInd];
343 auto Slots = ResourceCache.BindResourceViews<D3D11_RESOURCE_RANGE_UAV>(ShaderInd, d3d11UAVs, d3d11UAVRes, Binding);
344
345 if (Slots)
346 {
347 if (ShaderInd == PSInd)
348 ClearPixelShaderUAVs = false;
349
350 // Something has changed
351 if (ShaderInd == PSInd)
381352 {
382 CommittedD3D11UAVRes[uav] = nullptr;
383 CommittedD3D11UAVs[uav] = nullptr;
353 // Pixel shader UAVs cannot be set independently; they all need to be set at the same time.
354 // https://docs.microsoft.com/en-us/windows/desktop/api/d3d11/nf-d3d11-id3d11devicecontext-omsetrendertargetsandunorderedaccessviews#remarks
355 const auto StartUAVSlot = m_NumBoundRenderTargets;
356 const auto NumUAVSlot = Binding;
357 VERIFY(NumUAVSlot > StartUAVSlot, "Number of UAVs must be greater than the render target count");
358 m_pd3d11DeviceContext->OMSetRenderTargetsAndUnorderedAccessViews(
359 D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr,
360 StartUAVSlot, NumUAVSlot - StartUAVSlot, d3d11UAVs + StartUAVSlot, nullptr);
361 // Clear previously bound UAVs, but do not clear lower slots as if
362 // render target count reduces, we will bind these UAVs in CommitRenderTargets()
363 for (Uint32 uav = NumUAVSlot; uav < m_CommittedRes.NumUAVs[ShaderInd]; ++uav)
364 {
365 d3d11UAVRes[uav] = nullptr;
366 d3d11UAVs[uav] = nullptr;
367 }
368 m_CommittedRes.NumUAVs[ShaderInd] = NumUAVSlot;
384369 }
385 m_CommittedRes.NumUAVs[ShaderInd] = NumUAVSlot;
386 }
387 else if (ShaderInd == CSInd)
388 {
389 // This can only be CS
390 auto SetUAVMethod = SetUAVMethods[ShaderInd];
391 (m_pd3d11DeviceContext->*SetUAVMethod)(Slots.MinSlot, Slots.MaxSlot - Slots.MinSlot + 1, CommittedD3D11UAVs + Slots.MinSlot, nullptr);
392 m_CommittedRes.NumUAVs[ShaderInd] = std::max(m_CommittedRes.NumUAVs[ShaderInd], Binding);
393 VERIFY_EXPR(Slots.MaxSlot < Binding);
394 }
395 else
396 {
397 UNEXPECTED("UAV is not supported in shader that is not pixel or compute");
398 }
399 }
370 else if (ShaderInd == CSInd)
371 {
372 // This can only be CS
373 auto SetUAVMethod = SetUAVMethods[ShaderInd];
374 (m_pd3d11DeviceContext->*SetUAVMethod)(Slots.MinSlot, Slots.MaxSlot - Slots.MinSlot + 1, d3d11UAVs + Slots.MinSlot, nullptr);
375 m_CommittedRes.NumUAVs[ShaderInd] = std::max(m_CommittedRes.NumUAVs[ShaderInd], Binding);
376 VERIFY_EXPR(Slots.MaxSlot < Binding);
377 }
378 else
379 {
380 UNEXPECTED("UAV is not supported in shader that is not pixel or compute");
381 }
382 }
400383 #ifdef VERIFY_CONTEXT_BINDINGS
401 if ((m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE) != 0 && ShaderInd == CSInd)
402 {
403 DvpVerifyCommittedUAVs(ShaderTypes[i]);
404 }
405 #endif
384 if ((m_DebugFlags & D3D11_DEBUG_FLAG_VERIFY_COMMITTED_RESOURCE_RELEVANCE) != 0 && ShaderInd == CSInd)
385 {
386 DvpVerifyCommittedUAVs(ShaderType);
387 }
388 #endif
389 }
406390 }
407391
408392 if (ClearPixelShaderUAVs)
411395 // This is important as UnbindPixelShaderUAV<> function may need to rebind
412396 // existing UAVs and the UAVs pointed to by CommittedD3D11UAVRes must be alive
413397 // (we do not keep strong references to d3d11 UAVs)
414 auto* CommittedD3D11UAVs = m_CommittedRes.D3D11UAVs[PSInd];
415 auto* CommittedD3D11UAVRes = m_CommittedRes.D3D11UAVResources[PSInd];
398 auto* CommittedD3D11UAVs = m_CommittedRes.d3d11UAVs[PSInd];
399 auto* CommittedD3D11UAVRes = m_CommittedRes.d3d11UAVResources[PSInd];
416400 auto& NumCommittedPixelShaderUAVs = m_CommittedRes.NumUAVs[PSInd];
417401 for (Uint32 uav = 0; uav < NumCommittedPixelShaderUAVs; ++uav)
418402 {
11641148 m_pd3d11DeviceContext->OMSetRenderTargetsAndUnorderedAccessViews(NumRenderTargets, NumRenderTargets > 0 ? pd3d11RTs : nullptr, pd3d11DSV,
11651149 0, D3D11_KEEP_UNORDERED_ACCESS_VIEWS, nullptr, nullptr);
11661150
1167 auto CommittedD3D11UAVs = m_CommittedRes.D3D11UAVs[PSInd];
1168 auto CommittedD3D11UAVRes = m_CommittedRes.D3D11UAVResources[PSInd];
1151 auto CommittedD3D11UAVs = m_CommittedRes.d3d11UAVs[PSInd];
1152 auto CommittedD3D11UAVRes = m_CommittedRes.d3d11UAVResources[PSInd];
11691153 for (Uint32 slot = 0; slot < NumRenderTargets; ++slot)
11701154 {
11711155 CommittedD3D11UAVs[slot] = nullptr;
12881272 VERIFY(pTexture, "Null texture provided");
12891273 if (!pTexture) return;
12901274
1291 UnbindResourceView(m_CommittedRes.D3D11SRVs, m_CommittedRes.D3D11SRVResources, m_CommittedRes.NumSRVs, pd3d11Resource, SetSRVMethods);
1275 UnbindResourceView(m_CommittedRes.d3d11SRVs, m_CommittedRes.d3d11SRVResources, m_CommittedRes.NumSRVs, pd3d11Resource, SetSRVMethods);
12921276 pTexture->ClearState(RESOURCE_STATE_SHADER_RESOURCE | RESOURCE_STATE_INPUT_ATTACHMENT);
12931277 }
12941278
12991283
13001284 if (pBuffer->CheckState(RESOURCE_STATE_SHADER_RESOURCE))
13011285 {
1302 UnbindResourceView(m_CommittedRes.D3D11SRVs, m_CommittedRes.D3D11SRVResources, m_CommittedRes.NumSRVs, pd3d11Buffer, SetSRVMethods);
1286 UnbindResourceView(m_CommittedRes.d3d11SRVs, m_CommittedRes.d3d11SRVResources, m_CommittedRes.NumSRVs, pd3d11Buffer, SetSRVMethods);
13031287 pBuffer->ClearState(RESOURCE_STATE_SHADER_RESOURCE);
13041288 }
13051289
13451329 {
13461330 for (Int32 ShaderTypeInd = 0; ShaderTypeInd < NumShaderTypes; ++ShaderTypeInd)
13471331 {
1348 auto* CommittedD3D11CBs = m_CommittedRes.D3D11CBs[ShaderTypeInd];
1332 auto* CommittedD3D11CBs = m_CommittedRes.d3d11CBs[ShaderTypeInd];
13491333 auto NumSlots = m_CommittedRes.NumCBs[ShaderTypeInd];
13501334 for (Uint32 Slot = 0; Slot < NumSlots; ++Slot)
13511335 {
13671351 VERIFY(pResource, "Null resource provided");
13681352 if (!pResource) return;
13691353
1370 UnbindResourceView(m_CommittedRes.D3D11UAVs, m_CommittedRes.D3D11UAVResources, m_CommittedRes.NumUAVs, pd3d11Resource, SetUAVMethods);
1354 UnbindResourceView(m_CommittedRes.d3d11UAVs, m_CommittedRes.d3d11UAVResources, m_CommittedRes.NumUAVs, pd3d11Resource, SetUAVMethods);
13711355 }
13721356
13731357 void DeviceContextD3D11Impl::UnbindTextureFromRenderTarget(TextureBaseD3D11* pTexture)
14971481 if (auto* pTexView = FBDesc.ppAttachments[AttachmentRef.AttachmentIndex])
14981482 {
14991483 auto* pTexD3D11 = ValidatedCast<TextureBaseD3D11>(pTexView->GetTexture());
1500 UnbindResourceView(m_CommittedRes.D3D11SRVs, m_CommittedRes.D3D11SRVResources, m_CommittedRes.NumSRVs, pTexD3D11->GetD3D11Texture(), SetSRVMethods);
1484 UnbindResourceView(m_CommittedRes.d3d11SRVs, m_CommittedRes.d3d11SRVResources, m_CommittedRes.NumSRVs, pTexD3D11->GetD3D11Texture(), SetSRVMethods);
15011485 }
15021486 }
15031487 };
16791663 for (int ShaderType = 0; ShaderType < NumShaderTypes; ++ShaderType)
16801664 {
16811665 // clang-format off
1682 ReleaseCommittedShaderResourcesHelper(m_CommittedRes.D3D11CBs[ShaderType], m_CommittedRes.NumCBs[ShaderType], SetCBMethods[ShaderType], m_pd3d11DeviceContext);
1683 ReleaseCommittedShaderResourcesHelper(m_CommittedRes.D3D11SRVs[ShaderType], m_CommittedRes.NumSRVs[ShaderType], SetSRVMethods[ShaderType], m_pd3d11DeviceContext);
1684 ReleaseCommittedShaderResourcesHelper(m_CommittedRes.D3D11Samplers[ShaderType], m_CommittedRes.NumSamplers[ShaderType], SetSamplerMethods[ShaderType], m_pd3d11DeviceContext);
1666 ReleaseCommittedShaderResourcesHelper(m_CommittedRes.d3d11CBs[ShaderType], m_CommittedRes.NumCBs[ShaderType], SetCBMethods[ShaderType], m_pd3d11DeviceContext);
1667 ReleaseCommittedShaderResourcesHelper(m_CommittedRes.d3d11SRVs[ShaderType], m_CommittedRes.NumSRVs[ShaderType], SetSRVMethods[ShaderType], m_pd3d11DeviceContext);
1668 ReleaseCommittedShaderResourcesHelper(m_CommittedRes.d3d11Samplers[ShaderType], m_CommittedRes.NumSamplers[ShaderType], SetSamplerMethods[ShaderType], m_pd3d11DeviceContext);
16851669 // clang-format on
16861670
16871671 if (ShaderType == PSInd)
1688 ReleaseCommittedPSUAVs(m_CommittedRes.D3D11UAVs[ShaderType], m_CommittedRes.NumUAVs[ShaderType], m_pd3d11DeviceContext);
1672 ReleaseCommittedPSUAVs(m_CommittedRes.d3d11UAVs[ShaderType], m_CommittedRes.NumUAVs[ShaderType], m_pd3d11DeviceContext);
16891673 else
1690 ReleaseCommittedShaderResourcesHelper(m_CommittedRes.D3D11UAVs[ShaderType], m_CommittedRes.NumUAVs[ShaderType], SetUAVMethods[ShaderType], m_pd3d11DeviceContext);
1691
1692 memset(m_CommittedRes.D3D11SRVResources[ShaderType], 0, sizeof(m_CommittedRes.D3D11SRVResources[ShaderType][0]) * m_CommittedRes.NumSRVs[ShaderType]);
1693 memset(m_CommittedRes.D3D11UAVResources[ShaderType], 0, sizeof(m_CommittedRes.D3D11UAVResources[ShaderType][0]) * m_CommittedRes.NumUAVs[ShaderType]);
1674 ReleaseCommittedShaderResourcesHelper(m_CommittedRes.d3d11UAVs[ShaderType], m_CommittedRes.NumUAVs[ShaderType], SetUAVMethods[ShaderType], m_pd3d11DeviceContext);
1675
1676 memset(m_CommittedRes.d3d11SRVResources[ShaderType], 0, sizeof(m_CommittedRes.d3d11SRVResources[ShaderType][0]) * m_CommittedRes.NumSRVs[ShaderType]);
1677 memset(m_CommittedRes.d3d11UAVResources[ShaderType], 0, sizeof(m_CommittedRes.d3d11UAVResources[ShaderType][0]) * m_CommittedRes.NumUAVs[ShaderType]);
16941678 m_CommittedRes.NumCBs[ShaderType] = 0;
16951679 m_CommittedRes.NumSRVs[ShaderType] = 0;
16961680 m_CommittedRes.NumSamplers[ShaderType] = 0;
22692253
22702254 void DeviceContextD3D11Impl::DvpVerifyCommittedSRVs(SHADER_TYPE ShaderStages)
22712255 {
2272 DvpVerifyCommittedResources<D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT>(m_CommittedRes.D3D11SRVs, m_CommittedRes.NumSRVs, GetSRVMethods, "SRV", ShaderStages);
2273 DvpVerifyViewConsistency<D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT>(m_CommittedRes.D3D11SRVs, m_CommittedRes.D3D11SRVResources, m_CommittedRes.NumSRVs, "SRV", ShaderStages);
2256 DvpVerifyCommittedResources<D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT>(m_CommittedRes.d3d11SRVs, m_CommittedRes.NumSRVs, GetSRVMethods, "SRV", ShaderStages);
2257 DvpVerifyViewConsistency<D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT>(m_CommittedRes.d3d11SRVs, m_CommittedRes.d3d11SRVResources, m_CommittedRes.NumSRVs, "SRV", ShaderStages);
22742258 }
22752259
22762260 void DeviceContextD3D11Impl::DvpVerifyCommittedUAVs(SHADER_TYPE ShaderStages)
22772261 {
2278 DvpVerifyCommittedResources<D3D11_PS_CS_UAV_REGISTER_COUNT>(m_CommittedRes.D3D11UAVs, m_CommittedRes.NumUAVs, GetUAVMethods, "UAV", ShaderStages);
2279 DvpVerifyViewConsistency<D3D11_PS_CS_UAV_REGISTER_COUNT>(m_CommittedRes.D3D11UAVs, m_CommittedRes.D3D11UAVResources, m_CommittedRes.NumUAVs, "UAV", ShaderStages);
2262 DvpVerifyCommittedResources<D3D11_PS_CS_UAV_REGISTER_COUNT>(m_CommittedRes.d3d11UAVs, m_CommittedRes.NumUAVs, GetUAVMethods, "UAV", ShaderStages);
2263 DvpVerifyViewConsistency<D3D11_PS_CS_UAV_REGISTER_COUNT>(m_CommittedRes.d3d11UAVs, m_CommittedRes.d3d11UAVResources, m_CommittedRes.NumUAVs, "UAV", ShaderStages);
22802264 }
22812265
22822266 void DeviceContextD3D11Impl::DvpVerifyCommittedSamplers(SHADER_TYPE ShaderStages)
22832267 {
2284 DvpVerifyCommittedResources<D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT>(m_CommittedRes.D3D11Samplers, m_CommittedRes.NumSamplers, GetSamplerMethods, "Sampler", ShaderStages);
2268 DvpVerifyCommittedResources<D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT>(m_CommittedRes.d3d11Samplers, m_CommittedRes.NumSamplers, GetSamplerMethods, "Sampler", ShaderStages);
22852269 }
22862270
22872271 void DeviceContextD3D11Impl::DvpVerifyCommittedCBs(SHADER_TYPE ShaderStages)
22882272 {
2289 DvpVerifyCommittedResources<D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT>(m_CommittedRes.D3D11CBs, m_CommittedRes.NumCBs, GetCBMethods, "Constant buffer", ShaderStages);
2273 DvpVerifyCommittedResources<D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT>(m_CommittedRes.d3d11CBs, m_CommittedRes.NumCBs, GetCBMethods, "Constant buffer", ShaderStages);
22902274 }
22912275
22922276 void DeviceContextD3D11Impl::DvpVerifyCommittedIndexBuffer()
326326 case D3D11_RESOURCE_RANGE_CBV:
327327 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
328328 {
329 if (!DstResourceCache.CopyResource<ID3D11Buffer>(SrcResourceCache, ResAttr.BindPoints + ArrInd))
329 if (!DstResourceCache.CopyResource<D3D11_RESOURCE_RANGE_CBV>(SrcResourceCache, ResAttr.BindPoints + ArrInd))
330330 LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", GetShaderResourcePrintName(ResDesc, ArrInd), "' in pipeline resource signature '", m_Desc.Name, "'.");
331331 }
332332 break;
333333 case D3D11_RESOURCE_RANGE_SRV:
334334 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
335335 {
336 if (!DstResourceCache.CopyResource<ID3D11ShaderResourceView>(SrcResourceCache, ResAttr.BindPoints + ArrInd))
336 if (!DstResourceCache.CopyResource<D3D11_RESOURCE_RANGE_SRV>(SrcResourceCache, ResAttr.BindPoints + ArrInd))
337337 LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", GetShaderResourcePrintName(ResDesc, ArrInd), "' in pipeline resource signature '", m_Desc.Name, "'.");
338338 }
339339 break;
343343 {
344344 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
345345 {
346 if (!DstResourceCache.CopyResource<ID3D11SamplerState>(SrcResourceCache, ResAttr.BindPoints + ArrInd))
346 if (!DstResourceCache.CopyResource<D3D11_RESOURCE_RANGE_SAMPLER>(SrcResourceCache, ResAttr.BindPoints + ArrInd))
347347 LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", GetShaderResourcePrintName(ResDesc, ArrInd), "' in pipeline resource signature '", m_Desc.Name, "'.");
348348 }
349349 }
351351 case D3D11_RESOURCE_RANGE_UAV:
352352 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
353353 {
354 if (!DstResourceCache.CopyResource<ID3D11UnorderedAccessView>(SrcResourceCache, ResAttr.BindPoints + ArrInd))
354 if (!DstResourceCache.CopyResource<D3D11_RESOURCE_RANGE_UAV>(SrcResourceCache, ResAttr.BindPoints + ArrInd))
355355 LOG_ERROR_MESSAGE("No resource is assigned to static shader variable '", GetShaderResourcePrintName(ResDesc, ArrInd), "' in pipeline resource signature '", m_Desc.Name, "'.");
356356 }
357357 break;
466466 case D3D11_RESOURCE_RANGE_CBV:
467467 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
468468 {
469 if (!ResourceCache.IsResourceBound<ID3D11Buffer>(ResAttr.BindPoints + ArrInd))
469 if (!ResourceCache.IsResourceBound<D3D11_RESOURCE_RANGE_CBV>(ResAttr.BindPoints + ArrInd))
470470 {
471471 LOG_ERROR_MESSAGE("No resource is bound to variable '", GetShaderResourcePrintName(ResDesc, ArrInd),
472472 "' in shader '", ShaderName, "' of PSO '", PSOName, "'");
478478 case D3D11_RESOURCE_RANGE_SAMPLER:
479479 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
480480 {
481 if (!ResourceCache.IsResourceBound<ID3D11SamplerState>(ResAttr.BindPoints + ArrInd))
481 if (!ResourceCache.IsResourceBound<D3D11_RESOURCE_RANGE_SAMPLER>(ResAttr.BindPoints + ArrInd))
482482 {
483483 LOG_ERROR_MESSAGE("No resource is bound to variable '", GetShaderResourcePrintName(ResDesc, ArrInd),
484484 "' in shader '", ShaderName, "' of PSO '", PSOName, "'");
490490 case D3D11_RESOURCE_RANGE_SRV:
491491 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
492492 {
493 if (!ResourceCache.IsResourceBound<ID3D11ShaderResourceView>(ResAttr.BindPoints + ArrInd))
493 if (!ResourceCache.IsResourceBound<D3D11_RESOURCE_RANGE_SRV>(ResAttr.BindPoints + ArrInd))
494494 {
495495 LOG_ERROR_MESSAGE("No resource is bound to variable '", GetShaderResourcePrintName(ResDesc, ArrInd),
496496 "' in shader '", ShaderName, "' of PSO '", PSOName, "'");
510510 case D3D11_RESOURCE_RANGE_UAV:
511511 for (Uint32 ArrInd = 0; ArrInd < ResDesc.ArraySize; ++ArrInd)
512512 {
513 if (!ResourceCache.IsResourceBound<ID3D11UnorderedAccessView>(ResAttr.BindPoints + ArrInd))
513 if (!ResourceCache.IsResourceBound<D3D11_RESOURCE_RANGE_UAV>(ResAttr.BindPoints + ArrInd))
514514 {
515515 LOG_ERROR_MESSAGE("No resource is bound to variable '", GetShaderResourcePrintName(ResDesc, ArrInd),
516516 "' in shader '", ShaderName, "' of PSO '", PSOName, "'");
3838 namespace Diligent
3939 {
4040
41 size_t ShaderResourceCacheD3D11::GetRequriedMemorySize(const TBindingsPerStage& ResCount)
41 size_t ShaderResourceCacheD3D11::GetRequriedMemorySize(const TResourcesPerStage& ResCount)
4242 {
4343 size_t MemSize = 0;
4444 // clang-format off
5959 return MemSize;
6060 }
6161
62 void ShaderResourceCacheD3D11::Initialize(const TBindingsPerStage& ResCount, IMemoryAllocator& MemAllocator)
62 void ShaderResourceCacheD3D11::Initialize(const TResourcesPerStage& ResCount, IMemoryAllocator& MemAllocator)
6363 {
6464 // http://diligentgraphics.com/diligent-engine/architecture/d3d11/shader-resource-cache/
6565 VERIFY(!IsInitialized(), "Resource cache has already been intialized!");
6767 size_t MemOffset = 0;
6868 for (Uint32 ShaderInd = 0; ShaderInd < NumShaderTypes; ++ShaderInd)
6969 {
70 const Uint32 Idx = CBOffset + ShaderInd;
70 const Uint32 Idx = FirstCBOffsetIdx + ShaderInd;
7171 m_Offsets[Idx] = static_cast<OffsetType>(MemOffset);
7272 MemOffset = AlignUp(MemOffset + (sizeof(CachedCB) + sizeof(ID3D11Buffer*)) * ResCount[D3D11_RESOURCE_RANGE_CBV][ShaderInd], MaxAlignment);
7373 }
7474 for (Uint32 ShaderInd = 0; ShaderInd < NumShaderTypes; ++ShaderInd)
7575 {
76 const Uint32 Idx = SRVOffset + ShaderInd;
76 const Uint32 Idx = FirstSRVOffsetIdx + ShaderInd;
7777 m_Offsets[Idx] = static_cast<OffsetType>(MemOffset);
7878 MemOffset = AlignUp(MemOffset + (sizeof(CachedResource) + sizeof(ID3D11ShaderResourceView*)) * ResCount[D3D11_RESOURCE_RANGE_SRV][ShaderInd], MaxAlignment);
7979 }
8080 for (Uint32 ShaderInd = 0; ShaderInd < NumShaderTypes; ++ShaderInd)
8181 {
82 const Uint32 Idx = SampOffset + ShaderInd;
82 const Uint32 Idx = FirstSamOffsetIdx + ShaderInd;
8383 m_Offsets[Idx] = static_cast<OffsetType>(MemOffset);
8484 MemOffset = AlignUp(MemOffset + (sizeof(CachedSampler) + sizeof(ID3D11SamplerState*)) * ResCount[D3D11_RESOURCE_RANGE_SAMPLER][ShaderInd], MaxAlignment);
8585 }
8686 for (Uint32 ShaderInd = 0; ShaderInd < NumShaderTypes; ++ShaderInd)
8787 {
88 const Uint32 Idx = UAVOffset + ShaderInd;
88 const Uint32 Idx = FirstUAVOffsetIdx + ShaderInd;
8989 m_Offsets[Idx] = static_cast<OffsetType>(MemOffset);
9090 MemOffset = AlignUp(MemOffset + (sizeof(CachedResource) + sizeof(ID3D11UnorderedAccessView*)) * ResCount[D3D11_RESOURCE_RANGE_UAV][ShaderInd], MaxAlignment);
9191 }
111111 const auto CBCount = GetCBCount(ShaderInd);
112112 if (CBCount != 0)
113113 {
114 auto CBArrays = GetResourceArrays<ID3D11Buffer>(ShaderInd);
114 auto CBArrays = GetResourceArrays<D3D11_RESOURCE_RANGE_CBV>(ShaderInd);
115115 for (Uint32 cb = 0; cb < CBCount; ++cb)
116116 new (CBArrays.first + cb) CachedCB{};
117117 }
119119 const auto SRVCount = GetSRVCount(ShaderInd);
120120 if (SRVCount != 0)
121121 {
122 auto SRVArrays = GetResourceArrays<ID3D11ShaderResourceView>(ShaderInd);
122 auto SRVArrays = GetResourceArrays<D3D11_RESOURCE_RANGE_SRV>(ShaderInd);
123123 for (Uint32 srv = 0; srv < SRVCount; ++srv)
124124 new (SRVArrays.first + srv) CachedResource{};
125125 }
127127 const auto SamplerCount = GetSamplerCount(ShaderInd);
128128 if (SamplerCount != 0)
129129 {
130 auto SamArrays = GetResourceArrays<ID3D11SamplerState>(ShaderInd);
130 auto SamArrays = GetResourceArrays<D3D11_RESOURCE_RANGE_SAMPLER>(ShaderInd);
131131 for (Uint32 sam = 0; sam < SamplerCount; ++sam)
132132 new (SamArrays.first + sam) CachedSampler{};
133133 }
135135 const auto UAVCount = GetUAVCount(ShaderInd);
136136 if (UAVCount != 0)
137137 {
138 auto UAVArrays = GetResourceArrays<ID3D11UnorderedAccessView>(ShaderInd);
138 auto UAVArrays = GetResourceArrays<D3D11_RESOURCE_RANGE_UAV>(ShaderInd);
139139 for (Uint32 uav = 0; uav < UAVCount; ++uav)
140140 new (UAVArrays.first + uav) CachedResource{};
141141 }
154154 const auto CBCount = GetCBCount(ShaderInd);
155155 if (CBCount != 0)
156156 {
157 auto CBArrays = GetResourceArrays<ID3D11Buffer>(ShaderInd);
157 auto CBArrays = GetResourceArrays<D3D11_RESOURCE_RANGE_CBV>(ShaderInd);
158158 for (size_t cb = 0; cb < CBCount; ++cb)
159159 CBArrays.first[cb].~CachedCB();
160160 }
162162 const auto SRVCount = GetSRVCount(ShaderInd);
163163 if (SRVCount != 0)
164164 {
165 auto SRVArrays = GetResourceArrays<ID3D11ShaderResourceView>(ShaderInd);
165 auto SRVArrays = GetResourceArrays<D3D11_RESOURCE_RANGE_SRV>(ShaderInd);
166166 for (size_t srv = 0; srv < SRVCount; ++srv)
167167 SRVArrays.first[srv].~CachedResource();
168168 }
170170 const auto SamplerCount = GetSamplerCount(ShaderInd);
171171 if (SamplerCount != 0)
172172 {
173 auto SamArrays = GetResourceArrays<ID3D11SamplerState>(ShaderInd);
173 auto SamArrays = GetResourceArrays<D3D11_RESOURCE_RANGE_SAMPLER>(ShaderInd);
174174 for (size_t sam = 0; sam < SamplerCount; ++sam)
175175 SamArrays.first[sam].~CachedSampler();
176176 }
178178 const auto UAVCount = GetUAVCount(ShaderInd);
179179 if (UAVCount != 0)
180180 {
181 auto UAVArrays = GetResourceArrays<ID3D11UnorderedAccessView>(ShaderInd);
181 auto UAVArrays = GetResourceArrays<D3D11_RESOURCE_RANGE_UAV>(ShaderInd);
182182 for (size_t uav = 0; uav < UAVCount; ++uav)
183183 UAVArrays.first[uav].~CachedResource();
184184 }
245245
246246 for (Uint32 ShaderInd = 0; ShaderInd < NumShaderTypes; ++ShaderInd)
247247 {
248 const auto CBArrays = GetResourceArrays<ID3D11Buffer>(ShaderInd);
249 const auto SRVArrays = GetResourceArrays<ID3D11ShaderResourceView>(ShaderInd);
250 const auto SamArrays = GetResourceArrays<ID3D11SamplerState>(ShaderInd);
251 const auto UAVArrays = GetResourceArrays<ID3D11UnorderedAccessView>(ShaderInd);
248 const auto CBArrays = GetResourceArrays<D3D11_RESOURCE_RANGE_CBV>(ShaderInd);
249 const auto SRVArrays = GetResourceArrays<D3D11_RESOURCE_RANGE_SRV>(ShaderInd);
250 const auto SamArrays = GetResourceArrays<D3D11_RESOURCE_RANGE_SAMPLER>(ShaderInd);
251 const auto UAVArrays = GetResourceArrays<D3D11_RESOURCE_RANGE_UAV>(ShaderInd);
252252
253253 auto CBCount = GetCBCount(ShaderInd);
254254 for (size_t cb = 0; cb < CBCount; ++cb)
313313 if (CBCount == 0)
314314 continue;
315315
316 auto CBArrays = GetResourceArrays<ID3D11Buffer>(ShaderInd);
316 auto CBArrays = GetResourceArrays<D3D11_RESOURCE_RANGE_CBV>(ShaderInd);
317317 for (Uint32 i = 0; i < CBCount; ++i)
318318 {
319319 if (auto* pBuffer = CBArrays.first[i].pBuff.RawPtr<BufferD3D11Impl>())
345345 if (SRVCount == 0)
346346 continue;
347347
348 auto SRVArrays = GetResourceArrays<ID3D11ShaderResourceView>(ShaderInd);
348 auto SRVArrays = GetResourceArrays<D3D11_RESOURCE_RANGE_SRV>(ShaderInd);
349349 for (Uint32 i = 0; i < SRVCount; ++i)
350350 {
351351 auto& SRVRes = SRVArrays.first[i];
399399 if (UAVCount == 0)
400400 continue;
401401
402 auto UAVArrays = GetResourceArrays<ID3D11UnorderedAccessView>(ShaderInd);
402 auto UAVArrays = GetResourceArrays<D3D11_RESOURCE_RANGE_UAV>(ShaderInd);
403403 for (Uint32 i = 0; i < UAVCount; ++i)
404404 {
405405 auto& UAVRes = UAVArrays.first[i];
294294 RefCntAutoPtr<BufferD3D11Impl> pBuffD3D11Impl{pBuffer, IID_BufferD3D11};
295295 #ifdef DILIGENT_DEVELOPMENT
296296 {
297 const auto& CachedCB = ResourceCache.GetResource<ID3D11Buffer>(Attr.BindPoints + ArrayIndex);
297 const auto& CachedCB = ResourceCache.GetResource<D3D11_RESOURCE_RANGE_CBV>(Attr.BindPoints + ArrayIndex);
298298 VerifyConstantBufferBinding(Desc, ArrayIndex, pBuffer, pBuffD3D11Impl.RawPtr(), CachedCB.pBuff.RawPtr(),
299299 m_ParentManager.m_pSignature->GetDesc().Name);
300300 }
318318 RefCntAutoPtr<TextureViewD3D11Impl> pViewD3D11{pView, IID_TextureViewD3D11};
319319 #ifdef DILIGENT_DEVELOPMENT
320320 {
321 auto& CachedSRV = ResourceCache.GetResource<ID3D11ShaderResourceView>(Attr.BindPoints + ArrayIndex);
321 auto& CachedSRV = ResourceCache.GetResource<D3D11_RESOURCE_RANGE_SRV>(Attr.BindPoints + ArrayIndex);
322322 VerifyResourceViewBinding(Desc, ArrayIndex,
323323 pView, pViewD3D11.RawPtr(), {TEXTURE_VIEW_SHADER_RESOURCE},
324324 RESOURCE_DIM_UNDEFINED, false, CachedSRV.pView.RawPtr(),
352352 #ifdef DILIGENT_DEVELOPMENT
353353 if (SampDesc.VarType != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC)
354354 {
355 auto& CachedSampler = ResourceCache.GetResource<ID3D11SamplerState>(SampAttr.BindPoints + SampArrayIndex);
355 auto& CachedSampler = ResourceCache.GetResource<D3D11_RESOURCE_RANGE_SAMPLER>(SampAttr.BindPoints + SampArrayIndex);
356356 if (CachedSampler.pSampler != nullptr && CachedSampler.pSampler != pSamplerD3D11Impl)
357357 {
358358 auto VarTypeStr = GetShaderVariableTypeLiteralName(GetType());
396396
397397 if (GetType() != SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC)
398398 {
399 auto& CachedSampler = ResourceCache.GetResource<ID3D11SamplerState>(Attr.BindPoints + ArrayIndex);
399 auto& CachedSampler = ResourceCache.GetResource<D3D11_RESOURCE_RANGE_SAMPLER>(Attr.BindPoints + ArrayIndex);
400400 if (CachedSampler.pSampler != nullptr && CachedSampler.pSampler != pSamplerD3D11)
401401 {
402402 auto VarTypeStr = GetShaderVariableTypeLiteralName(GetType());
424424 RefCntAutoPtr<BufferViewD3D11Impl> pViewD3D11{pView, IID_BufferViewD3D11};
425425 #ifdef DILIGENT_DEVELOPMENT
426426 {
427 auto& CachedSRV = ResourceCache.GetResource<ID3D11ShaderResourceView>(Attr.BindPoints + ArrayIndex);
427 auto& CachedSRV = ResourceCache.GetResource<D3D11_RESOURCE_RANGE_SRV>(Attr.BindPoints + ArrayIndex);
428428 VerifyResourceViewBinding(Desc, ArrayIndex,
429429 pView, pViewD3D11.RawPtr(), {BUFFER_VIEW_SHADER_RESOURCE},
430430 RESOURCE_DIM_BUFFER, false, CachedSRV.pView.RawPtr(),
450450 RefCntAutoPtr<TextureViewD3D11Impl> pViewD3D11{pView, IID_TextureViewD3D11};
451451 #ifdef DILIGENT_DEVELOPMENT
452452 {
453 auto& CachedUAV = ResourceCache.GetResource<ID3D11UnorderedAccessView>(Attr.BindPoints + ArrayIndex);
453 auto& CachedUAV = ResourceCache.GetResource<D3D11_RESOURCE_RANGE_UAV>(Attr.BindPoints + ArrayIndex);
454454 VerifyResourceViewBinding(Desc, ArrayIndex,
455455 pView, pViewD3D11.RawPtr(), {TEXTURE_VIEW_UNORDERED_ACCESS},
456456 RESOURCE_DIM_UNDEFINED, false, CachedUAV.pView.RawPtr(),
475475 RefCntAutoPtr<BufferViewD3D11Impl> pViewD3D11{pView, IID_BufferViewD3D11};
476476 #ifdef DILIGENT_DEVELOPMENT
477477 {
478 auto& CachedUAV = ResourceCache.GetResource<ID3D11UnorderedAccessView>(Attr.BindPoints + ArrayIndex);
478 auto& CachedUAV = ResourceCache.GetResource<D3D11_RESOURCE_RANGE_UAV>(Attr.BindPoints + ArrayIndex);
479479 VerifyResourceViewBinding(Desc, ArrayIndex,
480480 pView, pViewD3D11.RawPtr(), {BUFFER_VIEW_UNORDERED_ACCESS},
481481 RESOURCE_DIM_BUFFER, false, CachedUAV.pView.RawPtr(),