git.s-ol.nu ~forks/DiligentCore / a2012c6
D3D11 backend: optimized resource counters assiduous 6 months ago
3 changed file(s) with 125 addition(s) and 37 deletion(s). Raw diff Collapse all Expand all
117117 }
118118
119119 private:
120 struct SetBindPointHelper
121 {
122 SetBindPointHelper(D3D11ResourceBindPoints& _BindPoints,
123 const Uint32 _ShaderInd) :
120 struct StageAccessor
121 {
122 StageAccessor(D3D11ResourceBindPoints& _BindPoints,
123 const Uint32 _ShaderInd) :
124124 BindPoints{_BindPoints},
125125 ShaderInd{_ShaderInd}
126126 {}
127127
128 // clang-format off
129 StageAccessor (const StageAccessor&) = delete;
130 StageAccessor ( StageAccessor&&) = default;
131 StageAccessor& operator=(const StageAccessor&) = delete;
132 StageAccessor& operator=( StageAccessor&&) = delete;
133 // clang-format on
134
128135 Uint8 operator=(Uint32 BindPoint)
129136 {
130 BindPoints.Set(ShaderInd, BindPoint);
131 return static_cast<Uint8>(BindPoint);
137 return BindPoints.Set(ShaderInd, BindPoint);
132138 }
133139
134140 operator Uint8() const
142148 };
143149
144150 public:
145 SetBindPointHelper operator[](Uint32 ShaderInd)
146 {
147 return SetBindPointHelper{*this, ShaderInd};
148 }
149
150 private:
151 void Set(Uint32 ShaderInd, Uint32 BindPoint)
151 StageAccessor operator[](Uint32 ShaderInd)
152 {
153 return StageAccessor{*this, ShaderInd};
154 }
155
156 private:
157 Uint8 Set(Uint32 ShaderInd, Uint32 BindPoint)
152158 {
153159 VERIFY_EXPR(ShaderInd < NumShaderTypes);
154160 VERIFY(BindPoint < InvalidBindPoint, "Bind point (", BindPoint, ") is out of range");
155161
156162 Bindings[ShaderInd] = static_cast<Uint8>(BindPoint);
157163 ActiveStages |= Uint32{1} << ShaderInd;
164 return static_cast<Uint8>(BindPoint);
158165 }
159166
160167 static constexpr Uint8 InvalidBindPoint = 0xFF;
167174 };
168175
169176
177 /// Shader resource counters for one specific resource range
178 struct D3D11ResourceRangeCounters
179 {
180 Uint8 operator[](Uint32 Stage) const
181 {
182 VERIFY_EXPR(Stage < D3D11ResourceBindPoints::NumShaderTypes);
183 return (PackedCounters >> (NumBitsPerStage * Stage)) & StageMask;
184 }
185
186 D3D11ResourceRangeCounters& operator+=(const D3D11ResourceRangeCounters& rhs)
187 {
188 #ifdef DILIGENT_DEBUG
189 for (Uint32 s = 0; s < D3D11ResourceBindPoints::NumShaderTypes; ++s)
190 {
191 const Uint32 val0 = (*static_cast<const D3D11ResourceRangeCounters*>(this))[s];
192 const Uint32 val1 = rhs[s];
193 VERIFY(val0 + val1 <= MaxCounter, "The resulting value is out of range");
194 }
195 #endif
196 PackedCounters += rhs.PackedCounters;
197 return *this;
198 }
199
200 bool operator==(const D3D11ResourceRangeCounters& rhs) const
201 {
202 return PackedCounters == rhs.PackedCounters;
203 }
204
205 private:
206 struct StageAccessor
207 {
208 StageAccessor(D3D11ResourceRangeCounters& _Counters,
209 const Uint32 _ShaderInd) :
210 Counters{_Counters},
211 ShaderInd{_ShaderInd}
212 {}
213
214 // clang-format off
215 StageAccessor (const StageAccessor&) = delete;
216 StageAccessor ( StageAccessor&&) = default;
217 StageAccessor& operator=(const StageAccessor&) = delete;
218 StageAccessor& operator=( StageAccessor&&) = delete;
219 // clang-format on
220
221 Uint8 operator=(Uint32 Counter)
222 {
223 return Counters.Set(ShaderInd, Counter);
224 }
225
226 Uint8 operator+=(Uint32 Val)
227 {
228 Uint32 CurrValue = static_cast<const D3D11ResourceRangeCounters&>(Counters)[ShaderInd];
229 return Counters.Set(ShaderInd, CurrValue + Val);
230 }
231
232 operator Uint8() const
233 {
234 return static_cast<const D3D11ResourceRangeCounters&>(Counters)[ShaderInd];
235 }
236
237 private:
238 D3D11ResourceRangeCounters& Counters;
239 const Uint32 ShaderInd;
240 };
241
242 public:
243 StageAccessor operator[](Uint32 ShaderInd)
244 {
245 return StageAccessor{*this, ShaderInd};
246 }
247
248
249 private:
250 Uint8 Set(Uint32 ShaderInd, Uint32 Counter)
251 {
252 VERIFY_EXPR(Counter <= MaxCounter);
253 const Uint64 BitOffset = NumBitsPerStage * ShaderInd;
254 PackedCounters &= ~(StageMask << BitOffset);
255 PackedCounters |= Uint64{Counter} << BitOffset;
256 return static_cast<Uint8>(Counter);
257 }
258
259 static constexpr Uint64 NumBitsPerStage = 8;
260 static constexpr Uint64 StageMask = (Uint64{1} << NumBitsPerStage) - 1;
261 static constexpr Uint32 MaxCounter = (Uint32{1} << NumBitsPerStage) - 1;
262
263 // 0 1 2 3 4 5 6 7 8
264 // | PS | VS | GS | HS | DS | CS |unused|unused|
265 Uint64 PackedCounters = 0;
266 };
267
170268 /// Resource counters for all shader stages and all resource types
171 using D3D11ShaderResourceCounters = std::array<std::array<Uint8, D3D11ResourceBindPoints::NumShaderTypes>, D3D11_RESOURCE_RANGE_COUNT>;
269 using D3D11ShaderResourceCounters = std::array<D3D11ResourceRangeCounters, D3D11_RESOURCE_RANGE_COUNT>;
172270
173271
174272 // sizeof(PipelineResourceAttribsD3D11) == 12, x64
8888
8989 __forceinline void ShiftBindings(D3D11ShaderResourceCounters& Bindings) const
9090 {
91 for (Uint32 r = 0; r < Bindings.size(); ++r)
92 {
93 for (Uint32 s = 0; s < Bindings[r].size(); ++s)
94 {
95 Uint32 Count = Bindings[r][s] + m_BindingCountPerStage[r][s];
96 VERIFY_EXPR(Count < std::numeric_limits<Uint8>::max());
97 Bindings[r][s] = static_cast<Uint8>(Count);
98 }
99 }
91 for (Uint32 r = 0; r < D3D11_RESOURCE_RANGE_COUNT; ++r)
92 Bindings[r] += m_ResourceCounters[r];
10093 }
10194
10295 void InitSRBResourceCache(ShaderResourceCacheD3D11& ResourceCache);
121114 void Destruct();
122115
123116 private:
124 D3D11ShaderResourceCounters m_BindingCountPerStage = {};
125 ResourceAttribs* m_pResourceAttribs = nullptr; // [m_Desc.NumResources]
126 ImmutableSamplerAttribs* m_ImmutableSamplers = nullptr; // [m_Desc.NumImmutableSamplers]
117 D3D11ShaderResourceCounters m_ResourceCounters = {};
118 ResourceAttribs* m_pResourceAttribs = nullptr; // [m_Desc.NumResources]
119 ImmutableSamplerAttribs* m_ImmutableSamplers = nullptr; // [m_Desc.NumImmutableSamplers]
127120 };
128121
129122 } // namespace Diligent
103103 ShaderVariableDataSizes[s] = ShaderVariableManagerD3D11::GetRequiredMemorySize(*this, AllowedVarTypes, _countof(AllowedVarTypes), GetActiveShaderStageType(s));
104104 }
105105
106 const size_t CacheMemorySize = ShaderResourceCacheD3D11::GetRequriedMemorySize(m_BindingCountPerStage);
106 const size_t CacheMemorySize = ShaderResourceCacheD3D11::GetRequriedMemorySize(m_ResourceCounters);
107107 m_SRBMemAllocator.Initialize(m_Desc.SRBAllocationGranularity, GetNumActiveShaderStages(), ShaderVariableDataSizes.data(), 1, &CacheMemorySize);
108108 }
109109
118118
119119 void PipelineResourceSignatureD3D11Impl::CreateLayout()
120120 {
121 const auto AllocBindPoints = [](D3D11ShaderResourceCounters& BindingPerStage, D3D11ResourceBindPoints& BindPoints, SHADER_TYPE ShaderStages, Uint32 ArraySize, D3D11_RESOURCE_RANGE Range) //
121 const auto AllocBindPoints = [](D3D11ShaderResourceCounters& ResCounters, D3D11ResourceBindPoints& BindPoints, SHADER_TYPE ShaderStages, Uint32 ArraySize, D3D11_RESOURCE_RANGE Range) //
122122 {
123123 while (ShaderStages != 0)
124124 {
125125 auto Stage = ExtractLSB(ShaderStages);
126126 auto ShaderInd = GetShaderTypeIndex(Stage);
127127
128 BindPoints[ShaderInd] = BindingPerStage[Range][ShaderInd];
129
130 using T = std::remove_reference<decltype(BindingPerStage[Range][ShaderInd])>::type;
131 VERIFY(Uint32{BindingPerStage[Range][ShaderInd]} + ArraySize < std::numeric_limits<T>::max(), "Binding value exceeds representable range");
132 BindingPerStage[Range][ShaderInd] += static_cast<Uint8>(ArraySize);
128 BindPoints[ShaderInd] = ResCounters[Range][ShaderInd];
129 ResCounters[Range][ShaderInd] += ArraySize;
133130 }
134131 };
135132
213210
214211 if (!ImtblSampAttribs.IsAllocated())
215212 {
216 AllocBindPoints(m_BindingCountPerStage, ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, D3D11_RESOURCE_RANGE_SAMPLER);
213 AllocBindPoints(m_ResourceCounters, ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, D3D11_RESOURCE_RANGE_SAMPLER);
217214 }
218215 }
219216
224221 AssignedSamplerInd,
225222 SrcImmutableSamplerInd != InvalidImmutableSamplerIndex //
226223 };
227 AllocBindPoints(m_BindingCountPerStage, pAttrib->BindPoints, ResDesc.ShaderStages, ResDesc.ArraySize, Range);
224 AllocBindPoints(m_ResourceCounters, pAttrib->BindPoints, ResDesc.ShaderStages, ResDesc.ArraySize, Range);
228225 }
229226 else
230227 {
257254 if (!ImtblSampAttribs.IsAllocated())
258255 {
259256 ImtblSampAttribs.ArraySize = 1;
260 AllocBindPoints(m_BindingCountPerStage, ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, Range);
257 AllocBindPoints(m_ResourceCounters, ImtblSampAttribs.BindPoints, ImtblSamp.ShaderStages, ImtblSampAttribs.ArraySize, Range);
261258 }
262259 }
263260 }
344341
345342 void PipelineResourceSignatureD3D11Impl::InitSRBResourceCache(ShaderResourceCacheD3D11& ResourceCache)
346343 {
347 ResourceCache.Initialize(m_BindingCountPerStage, m_SRBMemAllocator.GetResourceCacheDataAllocator(0));
344 ResourceCache.Initialize(m_ResourceCounters, m_SRBMemAllocator.GetResourceCacheDataAllocator(0));
348345 VERIFY_EXPR(ResourceCache.IsInitialized());
349346
350347 // Copy immutable samplers.