1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "node_context_descriptor_set_manager.h"
17
18 #include <cstddef>
19 #include <cstdint>
20
21 #include <base/containers/vector.h>
22 #include <base/math/mathf.h>
23 #include <render/device/pipeline_state_desc.h>
24 #include <render/namespace.h>
25
26 #include "device/device.h"
27 #include "device/gpu_resource_handle_util.h"
28 #include "device/gpu_resource_manager.h"
29 #include "nodecontext/pipeline_descriptor_set_binder.h"
30 #include "resource_handle_impl.h"
31 #include "util/log.h"
32
33 using namespace BASE_NS;
34
35 RENDER_BEGIN_NAMESPACE()
36 namespace {
37 #if (RENDER_VALIDATION_ENABLED == 1)
ReduceAndValidateDescriptorCounts(const DescriptorType descriptorType,const uint32_t descriptorCount,NodeContextDescriptorSetManager::DescriptorCountValidation & countValidation)38 void ReduceAndValidateDescriptorCounts(const DescriptorType descriptorType, const uint32_t descriptorCount,
39 NodeContextDescriptorSetManager::DescriptorCountValidation& countValidation)
40 {
41 auto& valRef = countValidation.typeToCount[static_cast<uint32_t>(descriptorType)];
42 valRef -= descriptorCount;
43 if (valRef < 0) {
44 string typeName;
45 if (descriptorType == CORE_DESCRIPTOR_TYPE_SAMPLER) {
46 typeName = "CORE_DESCRIPTOR_TYPE_SAMPLER";
47 } else if (descriptorType == CORE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
48 typeName = "CORE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER";
49 } else if (descriptorType == CORE_DESCRIPTOR_TYPE_SAMPLED_IMAGE) {
50 typeName = "CORE_DESCRIPTOR_TYPE_SAMPLED_IMAGE";
51 } else if (descriptorType == CORE_DESCRIPTOR_TYPE_STORAGE_IMAGE) {
52 typeName = "CORE_DESCRIPTOR_TYPE_STORAGE_IMAGE";
53 } else if (descriptorType == CORE_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) {
54 typeName = "CORE_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER";
55 } else if (descriptorType == CORE_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) {
56 typeName = "CORE_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER";
57 } else if (descriptorType == CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
58 typeName = "CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER";
59 } else if (descriptorType == CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER) {
60 typeName = "CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER";
61 } else if (descriptorType == CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
62 typeName = "CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC";
63 } else if (descriptorType == CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
64 typeName = "CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC";
65 } else if (descriptorType == CORE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) {
66 typeName = "CORE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT";
67 } else if (descriptorType == CORE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE) {
68 typeName = "CORE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE";
69 }
70 PLUGIN_LOG_E(
71 "RENDER_VALIDATION: Not enough descriptors available (count: %i) (type: %s)", valRef, typeName.c_str());
72 }
73 }
74 #endif
75
76 constexpr uint64_t RENDER_HANDLE_REMAPPABLE_MASK_ID { (
77 uint64_t(RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_SHALLOW_RESOURCE |
78 RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_SWAPCHAIN_RESOURCE |
79 RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_PLATFORM_CONVERSION)
80 << RenderHandleUtil::RES_HANDLE_ADDITIONAL_INFO_SHIFT) };
81
IsTheSameBufferBinding(const BindableBuffer & src,const BindableBuffer & dst,const EngineResourceHandle & srcHandle,const EngineResourceHandle & dstHandle)82 inline bool IsTheSameBufferBinding(const BindableBuffer& src, const BindableBuffer& dst,
83 const EngineResourceHandle& srcHandle, const EngineResourceHandle& dstHandle)
84 {
85 return (src.handle == dst.handle) && (srcHandle.id == dstHandle.id) && (src.byteOffset == dst.byteOffset) &&
86 (src.byteSize == dst.byteSize) && ((src.handle.id & RENDER_HANDLE_REMAPPABLE_MASK_ID) == 0);
87 }
88
IsTheSameImageBinding(const BindableImage & src,const BindableImage & dst,const EngineResourceHandle & srcHandle,const EngineResourceHandle & dstHandle,const EngineResourceHandle & srcSamplerHandle,const EngineResourceHandle & dstSamplerHandle)89 inline bool IsTheSameImageBinding(const BindableImage& src, const BindableImage& dst,
90 const EngineResourceHandle& srcHandle, const EngineResourceHandle& dstHandle,
91 const EngineResourceHandle& srcSamplerHandle, const EngineResourceHandle& dstSamplerHandle)
92 {
93 return (src.handle == dst.handle) && (srcHandle.id == dstHandle.id) && (src.mip == dst.mip) &&
94 (src.layer == dst.layer) && (src.imageLayout == dst.imageLayout) &&
95 (srcSamplerHandle.id == dstSamplerHandle.id) && ((src.handle.id & RENDER_HANDLE_REMAPPABLE_MASK_ID) == 0);
96 }
97
IsTheSameSamplerBinding(const BindableSampler & src,const BindableSampler & dst,const EngineResourceHandle & srcHandle,const EngineResourceHandle & dstHandle)98 inline bool IsTheSameSamplerBinding(const BindableSampler& src, const BindableSampler& dst,
99 const EngineResourceHandle& srcHandle, const EngineResourceHandle& dstHandle)
100 {
101 return (src.handle == dst.handle) && (srcHandle.id == dstHandle.id) &&
102 ((src.handle.id & RENDER_HANDLE_REMAPPABLE_MASK_ID) == 0);
103 }
104
CopyAndProcessBuffers(const GpuResourceManager & gpuResourceMgr,const DescriptorSetLayoutBindingResources & src,const GpuQueue & gpuQueue,CpuDescriptorSet & dst)105 DescriptorSetUpdateInfoFlags CopyAndProcessBuffers(const GpuResourceManager& gpuResourceMgr,
106 const DescriptorSetLayoutBindingResources& src, const GpuQueue& gpuQueue, CpuDescriptorSet& dst)
107 {
108 const auto maxCount = static_cast<uint32_t>(src.buffers.size());
109 dst.buffers.resize(maxCount);
110 uint32_t dynamicOffsetIndex = 0U;
111 DescriptorSetUpdateInfoFlags updateFlags = 0U;
112 for (uint32_t idx = 0; idx < maxCount; ++idx) {
113 const auto& srcRef = src.buffers[idx];
114 auto& dstRef = dst.buffers[idx].desc;
115 auto& dstHandle = dst.buffers[idx].handle;
116 // we need to get the correct (the latest) generation id from the gpu resource manager
117 const EngineResourceHandle srcHandle = gpuResourceMgr.GetGpuHandle(srcRef.resource.handle);
118 if ((!IsTheSameBufferBinding(srcRef.resource, dstRef.resource, srcHandle, dstHandle))) {
119 updateFlags |= DescriptorSetUpdateInfoFlagBits::DESCRIPTOR_SET_UPDATE_INFO_NEW_BIT;
120 }
121 dstRef = srcRef;
122 dstHandle = srcHandle;
123 dstRef.state.gpuQueue = gpuQueue;
124 if (!RenderHandleUtil::IsGpuBuffer(dstRef.resource.handle)) {
125 updateFlags |= DescriptorSetUpdateInfoFlagBits::DESCRIPTOR_SET_UPDATE_INFO_INVALID_BIT;
126 }
127 if (RenderHandleUtil::IsDynamicResource(dstRef.resource.handle)) {
128 dst.hasDynamicBarrierResources = true;
129 }
130 if (NodeContextDescriptorSetManager::IsDynamicDescriptor(dstRef.binding.descriptorType)) {
131 PLUGIN_ASSERT(dynamicOffsetIndex < (uint32_t)dst.dynamicOffsetDescriptors.size());
132 dst.dynamicOffsetDescriptors[dynamicOffsetIndex++] = dstRef.resource.handle;
133 }
134 }
135 return updateFlags;
136 }
137
CopyAndProcessImages(const GpuResourceManager & gpuResourceMgr,const DescriptorSetLayoutBindingResources & src,const GpuQueue & gpuQueue,CpuDescriptorSet & dst)138 DescriptorSetUpdateInfoFlags CopyAndProcessImages(const GpuResourceManager& gpuResourceMgr,
139 const DescriptorSetLayoutBindingResources& src, const GpuQueue& gpuQueue, CpuDescriptorSet& dst)
140 {
141 const auto maxCount = static_cast<uint32_t>(src.images.size());
142 dst.images.resize(maxCount);
143 DescriptorSetUpdateInfoFlags updateFlags = 0U;
144 for (uint32_t idx = 0; idx < maxCount; ++idx) {
145 const auto& srcRef = src.images[idx];
146 auto& dstRef = dst.images[idx].desc;
147 auto& dstHandle = dst.images[idx].handle;
148 auto& dstSamplerHandle = dst.images[idx].samplerHandle;
149 // we need to get the correct (the latest) generation id from the gpu resource manager
150 const EngineResourceHandle srcHandle = gpuResourceMgr.GetGpuHandle(srcRef.resource.handle);
151 const EngineResourceHandle srcSamplerHandle = gpuResourceMgr.GetGpuHandle(srcRef.resource.samplerHandle);
152 if ((!IsTheSameImageBinding(
153 srcRef.resource, dstRef.resource, srcHandle, dstHandle, srcSamplerHandle, dstSamplerHandle))) {
154 updateFlags |= DescriptorSetUpdateInfoFlagBits::DESCRIPTOR_SET_UPDATE_INFO_NEW_BIT;
155 }
156 dstRef = srcRef;
157 dstHandle = srcHandle;
158 dstSamplerHandle = srcSamplerHandle;
159 dstRef.state.gpuQueue = gpuQueue;
160 if (!RenderHandleUtil::IsGpuImage(dstRef.resource.handle)) {
161 updateFlags |= DescriptorSetUpdateInfoFlagBits::DESCRIPTOR_SET_UPDATE_INFO_INVALID_BIT;
162 }
163 if (RenderHandleUtil::IsDynamicResource(dstRef.resource.handle)) {
164 dst.hasDynamicBarrierResources = true;
165 }
166 if (dstRef.additionalFlags & CORE_ADDITIONAL_DESCRIPTOR_IMMUTABLE_SAMPLER_BIT) {
167 dst.hasImmutableSamplers = true;
168 }
169 if (RenderHandleUtil::IsPlatformConversionResource(dstRef.resource.handle)) {
170 if (dstRef.binding.descriptorType == DescriptorType::CORE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
171 dst.hasPlatformConversionBindings = true;
172 }
173 #if (RENDER_VALIDATION_ENABLED == 1)
174 if (dstRef.binding.descriptorType != DescriptorType::CORE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
175 PLUGIN_LOG_ONCE_W("core_validation_plat_conv_desc_set",
176 "RENDER_VALIDATION: automatic platform conversion only supported for "
177 "CORE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER");
178 }
179 if (dstRef.binding.descriptorCount > 1) {
180 PLUGIN_LOG_ONCE_W("core_validation_plat_conv_desc_set_arr",
181 "RENDER_VALIDATION: array of platform special image formats not supported");
182 }
183 #endif
184 }
185 }
186 return updateFlags;
187 }
188
CopyAndProcessSamplers(const GpuResourceManager & gpuResourceMgr,const DescriptorSetLayoutBindingResources & src,CpuDescriptorSet & dst)189 DescriptorSetUpdateInfoFlags CopyAndProcessSamplers(
190 const GpuResourceManager& gpuResourceMgr, const DescriptorSetLayoutBindingResources& src, CpuDescriptorSet& dst)
191 {
192 const auto maxCount = static_cast<uint32_t>(src.samplers.size());
193 dst.samplers.resize(maxCount);
194 DescriptorSetUpdateInfoFlags updateFlags = 0U;
195 for (uint32_t idx = 0; idx < maxCount; ++idx) {
196 const auto& srcRef = src.samplers[idx];
197 auto& dstRef = dst.samplers[idx].desc;
198 auto& dstHandle = dst.samplers[idx].handle;
199 // we need to get the correct (the latest) generation id from the gpu resource manager
200 const EngineResourceHandle srcHandle = gpuResourceMgr.GetGpuHandle(srcRef.resource.handle);
201 // we need to get the correct (the latest) generation id from the gpu resource manager
202 if ((!IsTheSameSamplerBinding(srcRef.resource, dstRef.resource, srcHandle, dstHandle))) {
203 updateFlags |= DescriptorSetUpdateInfoFlagBits::DESCRIPTOR_SET_UPDATE_INFO_NEW_BIT;
204 }
205 dstRef = srcRef;
206 dstHandle = srcHandle;
207
208 if (!RenderHandleUtil::IsGpuSampler(dstRef.resource.handle)) {
209 updateFlags |= DescriptorSetUpdateInfoFlagBits::DESCRIPTOR_SET_UPDATE_INFO_INVALID_BIT;
210 }
211 if (dstRef.additionalFlags & CORE_ADDITIONAL_DESCRIPTOR_IMMUTABLE_SAMPLER_BIT) {
212 dst.hasImmutableSamplers = true;
213 }
214 }
215 return updateFlags;
216 }
217
UpdateCpuDescriptorSetFunc(const GpuResourceManager & gpuResourceMgr,const DescriptorSetLayoutBindingResources & bindingResources,const GpuQueue & gpuQueue,CpuDescriptorSet & cpuSet,bool & hasPlatformConversionBindings)218 DescriptorSetUpdateInfoFlags UpdateCpuDescriptorSetFunc(const GpuResourceManager& gpuResourceMgr,
219 const DescriptorSetLayoutBindingResources& bindingResources, const GpuQueue& gpuQueue, CpuDescriptorSet& cpuSet,
220 bool& hasPlatformConversionBindings)
221 {
222 DescriptorSetUpdateInfoFlags updateFlags = 0U;
223 #if (RENDER_VALIDATION_ENABLED == 1)
224 if (cpuSet.bindings.size() != bindingResources.bindings.size()) {
225 PLUGIN_LOG_E("RENDER_VALIDATION: sizes must match; update all bindings always in a single set");
226 }
227 #endif
228 cpuSet.hasDynamicBarrierResources = false;
229 cpuSet.hasPlatformConversionBindings = false;
230 cpuSet.hasImmutableSamplers = false;
231 cpuSet.isDirty = true;
232
233 // NOTE: GPU queue patching could be moved to render graph
234 // copy from src to dst and check flags
235 updateFlags |= CopyAndProcessBuffers(gpuResourceMgr, bindingResources, gpuQueue, cpuSet);
236 updateFlags |= CopyAndProcessImages(gpuResourceMgr, bindingResources, gpuQueue, cpuSet);
237 // samplers don't have state and dynamic resources, but we check for immutable samplers
238 updateFlags |= CopyAndProcessSamplers(gpuResourceMgr, bindingResources, cpuSet);
239
240 // cpuSet.isDirty = ((updateFlags & DescriptorSetUpdateInfoFlagBits::DESCRIPTOR_SET_UPDATE_INFO_NEW_BIT) != 0);
241
242 for (size_t idx = 0; idx < bindingResources.bindings.size(); ++idx) {
243 const DescriptorSetLayoutBindingResource& refBinding = bindingResources.bindings[idx];
244 // the actual binding index is not important here (refBinding.binding.binding)
245 PLUGIN_ASSERT(idx < cpuSet.bindings.size());
246 DescriptorSetLayoutBindingResource& refCpuBinding = cpuSet.bindings[idx];
247 refCpuBinding.resourceIndex = refBinding.resourceIndex;
248 }
249 hasPlatformConversionBindings = (hasPlatformConversionBindings || cpuSet.hasPlatformConversionBindings);
250 return updateFlags;
251 }
252 } // namespace
253
DescriptorSetManager(Device & device)254 DescriptorSetManager::DescriptorSetManager(Device& device) : device_(device) {}
255
BeginFrame()256 void DescriptorSetManager::BeginFrame()
257 {
258 descriptorSetHandlesForUpdate_.clear();
259
260 creationLocked_ = false;
261 }
262
LockFrameCreation()263 void DescriptorSetManager::LockFrameCreation()
264 {
265 creationLocked_ = true;
266 }
267
CreateDescriptorSets(const string_view name,const array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings,const uint32_t descCount)268 vector<RenderHandleReference> DescriptorSetManager::CreateDescriptorSets(const string_view name,
269 const array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings, const uint32_t descCount)
270 {
271 if (creationLocked_) {
272 PLUGIN_LOG_W("Global descriptor set can only be created in Init or PreExecute (%s)", string(name).c_str());
273 return {};
274 }
275 vector<RenderHandleReference> createdDescriptorSets;
276 if (!name.empty()) {
277 uint32_t arrayIndex = ~0U;
278 uint32_t generationCounter = 0U;
279 {
280 if (const auto iter = nameToIndex_.find(name); iter != nameToIndex_.cend()) {
281 arrayIndex = iter->second;
282 if (arrayIndex >= descriptorSets_.size()) {
283 #if (RENDER_VALIDATION_ENABLED == 1)
284 PLUGIN_LOG_W("RENDER_VALIDATION: Global descriptor set name/index missmatch.");
285 #endif
286 arrayIndex = ~0U;
287 PLUGIN_LOG_W("Overwriting named global descriptor set (name: %s)", string(name).c_str());
288 }
289 }
290 if (arrayIndex == ~0U) {
291 if (!availableHandles_.empty()) {
292 // re-use with generation counter
293 const RenderHandle reuseHandle = availableHandles_.back();
294 availableHandles_.pop_back();
295 arrayIndex = RenderHandleUtil::GetIndexPart(reuseHandle);
296 generationCounter = RenderHandleUtil::GetGenerationIndexPart(reuseHandle) + 1;
297 }
298 if (arrayIndex == ~0U) {
299 arrayIndex = static_cast<uint32_t>(descriptorSets_.size());
300 descriptorSets_.push_back({});
301 }
302 }
303
304 // now, match our name to array index of vector
305 nameToIndex_.insert_or_assign(name, arrayIndex);
306
307 // now, create all similar descriptor sets for this global name with changing additional index
308 if (arrayIndex < descriptorSets_.size()) {
309 auto& ref = descriptorSets_[arrayIndex];
310 if (!ref) {
311 ref = make_unique<GlobalDescriptorSetBase>();
312 }
313 if (ref) {
314 ref->name = name;
315 createdDescriptorSets.resize(descCount);
316
317 constexpr uint32_t additionalData = NodeContextDescriptorSetManager::GLOBAL_DESCRIPTOR_BIT;
318 ref->handles.resize(descCount);
319 ref->data.resize(descCount);
320 for (uint32_t idx = 0; idx < descCount; ++idx) {
321 const uint32_t additionalIndex = idx;
322 const RenderHandle rawHandle = RenderHandleUtil::CreateHandle(RenderHandleType::DESCRIPTOR_SET,
323 arrayIndex, generationCounter, additionalData, additionalIndex);
324 ref->data[idx].frameWriteLocked = false;
325 ref->data[idx].renderHandleReference = RenderHandleReference(
326 rawHandle, IRenderReferenceCounter::Ptr(new RenderReferenceCounter()));
327
328 ref->handles[idx] = rawHandle;
329 createdDescriptorSets[idx] = ref->data[idx].renderHandleReference;
330 }
331 CreateDescriptorSets(arrayIndex, descCount, descriptorSetLayoutBindings);
332 }
333 }
334 }
335 }
336
337 return createdDescriptorSets;
338 }
339
CreateDescriptorSet(const string_view name,const array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings)340 RenderHandleReference DescriptorSetManager::CreateDescriptorSet(
341 const string_view name, const array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings)
342 {
343 const auto handles = CreateDescriptorSets(name, descriptorSetLayoutBindings, 1U);
344 if (!handles.empty()) {
345 return handles[0U];
346 } else {
347 return {};
348 }
349 }
350
GetDescriptorSetHandle(const string_view name) const351 RenderHandle DescriptorSetManager::GetDescriptorSetHandle(const string_view name) const
352 {
353 if (!creationLocked_) {
354 PLUGIN_LOG_W("Fetch global descriptor set in ExecuteFrame (%s)", string(name).c_str());
355 return {};
356 }
357
358 if (!name.empty()) {
359 if (const auto iter = nameToIndex_.find(name); iter != nameToIndex_.cend()) {
360 const uint32_t index = iter->second;
361 #if (RENDER_VALIDATION_ENABLED == 1)
362 if (index >= descriptorSets_.size()) {
363 PLUGIN_LOG_W("RENDER_VALIDATION: Global descriptor set name/index missmatch.");
364 }
365 #endif
366 if ((index < descriptorSets_.size()) && descriptorSets_[index] &&
367 (!descriptorSets_[index]->handles.empty())) {
368 // return the first
369 return descriptorSets_[index]->handles[0U];
370 }
371 }
372 }
373 return {};
374 }
375
GetDescriptorSetHandles(const string_view name) const376 array_view<const RenderHandle> DescriptorSetManager::GetDescriptorSetHandles(const string_view name) const
377 {
378 if (!creationLocked_) {
379 PLUGIN_LOG_W("Fetch global descriptor sets in ExecuteFrame (%s)", string(name).c_str());
380 return {};
381 }
382
383 if (!name.empty()) {
384 if (const auto iter = nameToIndex_.find(name); iter != nameToIndex_.cend()) {
385 const uint32_t index = iter->second;
386 #if (RENDER_VALIDATION_ENABLED == 1)
387 if (index >= descriptorSets_.size()) {
388 PLUGIN_LOG_W("RENDER_VALIDATION: Global descriptor set name/index missmatch.");
389 }
390 #endif
391 if ((index < descriptorSets_.size()) && descriptorSets_[index] &&
392 (!descriptorSets_[index]->handles.empty())) {
393 return descriptorSets_[index]->handles;
394 }
395 }
396 }
397
398 return {};
399 }
400
GetCpuDescriptorSet(const RenderHandle & handle)401 CpuDescriptorSet* DescriptorSetManager::GetCpuDescriptorSet(const RenderHandle& handle)
402 {
403 PLUGIN_ASSERT(RenderHandleUtil::GetHandleType(handle) == RenderHandleType::DESCRIPTOR_SET);
404
405 const uint32_t index = RenderHandleUtil::GetIndexPart(handle);
406 const uint32_t additionalIndex = RenderHandleUtil::GetAdditionalIndexPart(handle);
407
408 CpuDescriptorSet* cpuDescriptorSet = nullptr;
409 {
410 if ((index < descriptorSets_.size()) && descriptorSets_[index] &&
411 (additionalIndex < descriptorSets_[index]->data.size())) {
412 PLUGIN_ASSERT(descriptorSets_[index]->data.size() == descriptorSets_[index]->handles.size());
413
414 cpuDescriptorSet = &descriptorSets_[index]->data[additionalIndex].cpuDescriptorSet;
415 }
416 }
417 return cpuDescriptorSet;
418 }
419
GetCpuDescriptorSetData(const RenderHandle & handle)420 DescriptorSetLayoutBindingResourcesHandler DescriptorSetManager::GetCpuDescriptorSetData(const RenderHandle& handle)
421 {
422 if (const CpuDescriptorSet* cpuDescriptorSet = GetCpuDescriptorSet(handle); cpuDescriptorSet) {
423 return DescriptorSetLayoutBindingResourcesHandler {
424 cpuDescriptorSet->bindings,
425 cpuDescriptorSet->buffers,
426 cpuDescriptorSet->images,
427 cpuDescriptorSet->samplers,
428 };
429 } else {
430 #if (RENDER_VALIDATION_ENABLED == 1)
431 PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to GetCpuDescriptorSetData");
432 #endif
433 return {};
434 }
435 }
436
GetDynamicOffsetDescriptors(const RenderHandle & handle)437 DynamicOffsetDescriptors DescriptorSetManager::GetDynamicOffsetDescriptors(const RenderHandle& handle)
438 {
439 if (const CpuDescriptorSet* cpuDescriptorSet = GetCpuDescriptorSet(handle); cpuDescriptorSet) {
440 return DynamicOffsetDescriptors {
441 array_view<const RenderHandle>(
442 cpuDescriptorSet->dynamicOffsetDescriptors.data(), cpuDescriptorSet->dynamicOffsetDescriptors.size()),
443 };
444 } else {
445 return {};
446 }
447 }
448
HasDynamicBarrierResources(const RenderHandle & handle)449 bool DescriptorSetManager::HasDynamicBarrierResources(const RenderHandle& handle)
450 {
451 // NOTE: this method cannot provide up-to-date information during ExecuteFrame
452 // some render node task will update the dynamicity data in parallel
453
454 if (const CpuDescriptorSet* cpuDescriptorSet = GetCpuDescriptorSet(handle); cpuDescriptorSet) {
455 return cpuDescriptorSet->hasDynamicBarrierResources;
456 } else {
457 return false;
458 }
459 }
460
GetDynamicOffsetDescriptorCount(const RenderHandle & handle)461 uint32_t DescriptorSetManager::GetDynamicOffsetDescriptorCount(const RenderHandle& handle)
462 {
463 if (const CpuDescriptorSet* cpuDescriptorSet = GetCpuDescriptorSet(handle); cpuDescriptorSet) {
464 return static_cast<uint32_t>(cpuDescriptorSet->dynamicOffsetDescriptors.size());
465 } else {
466 #if (RENDER_VALIDATION_ENABLED == 1)
467 PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to GetDynamicOffsetDescriptorCount");
468 #endif
469 return 0U;
470 }
471 }
472
UpdateCpuDescriptorSet(const RenderHandle & handle,const DescriptorSetLayoutBindingResources & bindingResources,const GpuQueue & gpuQueue)473 DescriptorSetUpdateInfoFlags DescriptorSetManager::UpdateCpuDescriptorSet(
474 const RenderHandle& handle, const DescriptorSetLayoutBindingResources& bindingResources, const GpuQueue& gpuQueue)
475 {
476 PLUGIN_ASSERT(RenderHandleUtil::GetHandleType(handle) == RenderHandleType::DESCRIPTOR_SET);
477
478 // NOTE: needs locks for global data access
479 // the local data, which is inside vector(s) do not need locks
480 // the global vectors are only resized when new descriptor sets are created ->
481 // and only from PreExecuteFrame (single thread)
482
483 DescriptorSetUpdateInfoFlags updateFlags = 0U;
484 constexpr uint32_t validUpdateFlags = DescriptorSetUpdateInfoFlagBits::DESCRIPTOR_SET_UPDATE_INFO_NEW_BIT;
485 {
486 const uint32_t index = RenderHandleUtil::GetIndexPart(handle);
487 const uint32_t additionalIndex = RenderHandleUtil::GetAdditionalIndexPart(handle);
488 if ((index < descriptorSets_.size()) && descriptorSets_[index] &&
489 (additionalIndex < descriptorSets_[index]->data.size())) {
490 auto& ref = descriptorSets_[index]->data[additionalIndex];
491 bool validWrite = false;
492 {
493 // lock global mutex for shared data and for the boolean inside vectors
494 const auto lock = std::lock_guard(mutex_);
495
496 if (!ref.frameWriteLocked) {
497 // NOTE: not used at the moment
498 bool hasPlatformConversionBindings = false;
499 updateFlags = UpdateCpuDescriptorSetFunc((const GpuResourceManager&)device_.GetGpuResourceManager(),
500 bindingResources, gpuQueue, ref.cpuDescriptorSet, hasPlatformConversionBindings);
501 // set for update, these needs to be locked
502 if ((updateFlags & 0xFFFFffffU) == validUpdateFlags) {
503 descriptorSetHandlesForUpdate_.push_back(handle);
504 UpdateCpuDescriptorSetPlatform(bindingResources);
505 // mark as write locked for this frame
506 ref.frameWriteLocked = true;
507 }
508 validWrite =
509 ((updateFlags & DescriptorSetUpdateInfoFlagBits::DESCRIPTOR_SET_UPDATE_INFO_INVALID_BIT) == 0U);
510 }
511 }
512 // the following do not need locks
513 #if (RENDER_VALIDATION_ENABLED)
514 if (!validWrite) {
515 const string tmpName = string(to_string(handle.id)) + descriptorSets_[index]->name.c_str();
516 PLUGIN_LOG_ONCE_W(tmpName, "RENDER_VALIDATION: Global descriptor set already updated this frame (%s)",
517 descriptorSets_[index]->name.c_str());
518 }
519 #else
520 PLUGIN_UNUSED(validWrite);
521 #endif
522 }
523 }
524 return updateFlags;
525 }
526
GetUpdateDescriptorSetHandles() const527 array_view<const RenderHandle> DescriptorSetManager::GetUpdateDescriptorSetHandles() const
528 {
529 return { descriptorSetHandlesForUpdate_.data(), descriptorSetHandlesForUpdate_.size() };
530 }
531
NodeContextDescriptorSetManager(Device & device)532 NodeContextDescriptorSetManager::NodeContextDescriptorSetManager(Device& device)
533 : device_(device), globalDescriptorSetMgr_(device.GetDescriptorSetManager())
534 {}
535
ResetAndReserve(const DescriptorCounts & descriptorCounts)536 void NodeContextDescriptorSetManager::ResetAndReserve(const DescriptorCounts& descriptorCounts)
537 {
538 // method
539 // prepare and create descriptor set pool
540 maxSets_ = 0;
541 auto& cpuDescriptorSets = cpuDescriptorSets_[DESCRIPTOR_SET_INDEX_TYPE_STATIC];
542 cpuDescriptorSets.clear();
543 #if (RENDER_VALIDATION_ENABLED == 1)
544 descriptorCountValidation_ = {};
545 #endif
546 for (const auto& ref : descriptorCounts.counts) {
547 maxSets_ += ref.count;
548 #if (RENDER_VALIDATION_ENABLED == 1)
549 auto& valRef = descriptorCountValidation_.typeToCount[static_cast<uint32_t>(ref.type)];
550 valRef += static_cast<int32_t>(ref.count);
551 #endif
552 }
553
554 if (maxSets_ > 0) {
555 // usually there are less descriptor sets than max sets count
556 // due to maxsets count has been calculated for single descriptors
557 // (one descriptor set has multiple descriptors)
558 const uint32_t reserveCount = maxSets_ / 2u;
559 cpuDescriptorSets.reserve(reserveCount);
560 }
561 }
562
ResetAndReserve(const BASE_NS::array_view<DescriptorCounts> descriptorCounts)563 void NodeContextDescriptorSetManager::ResetAndReserve(const BASE_NS::array_view<DescriptorCounts> descriptorCounts)
564 {
565 DescriptorCounts dc;
566 dc.counts.reserve(descriptorCounts.size());
567 for (const auto& descriptorCount : descriptorCounts) {
568 const auto& ref = descriptorCount.counts;
569 if (!ref.empty()) {
570 dc.counts.append(ref.begin(), ref.end());
571 }
572 }
573 ResetAndReserve(dc);
574 }
575
BeginFrame()576 void NodeContextDescriptorSetManager::BeginFrame()
577 {
578 cpuDescriptorSets_[DESCRIPTOR_SET_INDEX_TYPE_ONE_FRAME].clear();
579 hasPlatformConversionBindings_ = false;
580 }
581
CreateDescriptorSets(const array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings)582 vector<RenderHandle> NodeContextDescriptorSetManager::CreateDescriptorSets(
583 const array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings)
584 {
585 vector<RenderHandle> handles;
586 handles.reserve(descriptorSetsLayoutBindings.size());
587 for (const auto& ref : descriptorSetsLayoutBindings) {
588 #if (RENDER_VALIDATION_ENABLED == 1)
589 for (const auto& bindingRef : ref.binding) {
590 ReduceAndValidateDescriptorCounts(
591 bindingRef.descriptorType, bindingRef.descriptorCount, descriptorCountValidation_);
592 }
593 #endif
594 handles.push_back(CreateDescriptorSet(ref.binding));
595 }
596 return handles;
597 }
598
CreateDescriptorSet(const uint32_t set,const PipelineLayout & pipelineLayout)599 RenderHandle NodeContextDescriptorSetManager::CreateDescriptorSet(
600 const uint32_t set, const PipelineLayout& pipelineLayout)
601 {
602 if (set < PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT) {
603 const auto& ref = pipelineLayout.descriptorSetLayouts[set];
604 if (ref.set == set) {
605 #if (RENDER_VALIDATION_ENABLED == 1)
606 for (const auto& bindingRef : ref.bindings) {
607 ReduceAndValidateDescriptorCounts(
608 bindingRef.descriptorType, bindingRef.descriptorCount, descriptorCountValidation_);
609 }
610 #endif
611 return CreateDescriptorSet(ref.bindings);
612 } else {
613 PLUGIN_LOG_E("CreateDescriptorSet: sets needs to be sorted in PipelineLayout");
614 }
615 }
616 PLUGIN_LOG_E("set index needs to be valid in PipelineLayout");
617 return {};
618 }
619
CreateOneFrameDescriptorSets(const array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings)620 vector<RenderHandle> NodeContextDescriptorSetManager::CreateOneFrameDescriptorSets(
621 const array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings)
622 {
623 vector<RenderHandle> handles;
624 handles.reserve(descriptorSetsLayoutBindings.size());
625 for (const auto& ref : descriptorSetsLayoutBindings) {
626 handles.push_back(CreateOneFrameDescriptorSet(ref.binding));
627 }
628 return handles;
629 }
630
CreateOneFrameDescriptorSet(const uint32_t set,const PipelineLayout & pipelineLayout)631 RenderHandle NodeContextDescriptorSetManager::CreateOneFrameDescriptorSet(
632 const uint32_t set, const PipelineLayout& pipelineLayout)
633 {
634 if (set < PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT) {
635 const auto& ref = pipelineLayout.descriptorSetLayouts[set];
636 if (ref.set == set) {
637 return CreateOneFrameDescriptorSet(ref.bindings);
638 } else {
639 PLUGIN_LOG_E("CreateOneFrameDescriptorSet: sets needs to be sorted in PipelineLayout");
640 }
641 }
642 PLUGIN_LOG_E("set index needs to be valid in PipelineLayout");
643 return {};
644 }
645
CreateGlobalDescriptorSets(const BASE_NS::string_view name,const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings,const uint32_t descriptorSetCount)646 vector<RenderHandleReference> NodeContextDescriptorSetManager::CreateGlobalDescriptorSets(
647 const BASE_NS::string_view name,
648 const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings,
649 const uint32_t descriptorSetCount)
650 {
651 if ((!name.empty()) && (!descriptorSetLayoutBindings.empty())) {
652 return globalDescriptorSetMgr_.CreateDescriptorSets(name, descriptorSetLayoutBindings, descriptorSetCount);
653 } else {
654 return {};
655 }
656 }
657
CreateGlobalDescriptorSet(const BASE_NS::string_view name,const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings)658 RenderHandleReference NodeContextDescriptorSetManager::CreateGlobalDescriptorSet(const BASE_NS::string_view name,
659 const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings)
660 {
661 RenderHandleReference handle;
662 if ((!name.empty()) && (!descriptorSetLayoutBindings.empty())) {
663 handle = globalDescriptorSetMgr_.CreateDescriptorSet(name, descriptorSetLayoutBindings);
664 }
665 return handle;
666 }
667
GetGlobalDescriptorSet(const BASE_NS::string_view name) const668 RenderHandle NodeContextDescriptorSetManager::GetGlobalDescriptorSet(const BASE_NS::string_view name) const
669 {
670 return globalDescriptorSetMgr_.GetDescriptorSetHandle(name);
671 }
672
GetGlobalDescriptorSets(const BASE_NS::string_view name) const673 array_view<const RenderHandle> NodeContextDescriptorSetManager::GetGlobalDescriptorSets(
674 const BASE_NS::string_view name) const
675 {
676 return globalDescriptorSetMgr_.GetDescriptorSetHandles(name);
677 }
678
CreateDescriptorSetBinder(const RenderHandle handle,const array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings)679 IDescriptorSetBinder::Ptr NodeContextDescriptorSetManager::CreateDescriptorSetBinder(
680 const RenderHandle handle, const array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings)
681 {
682 return IDescriptorSetBinder::Ptr { new DescriptorSetBinder(handle, descriptorSetLayoutBindings) };
683 }
684
CreateDescriptorSetBinder(const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings)685 IDescriptorSetBinder::Ptr NodeContextDescriptorSetManager::CreateDescriptorSetBinder(
686 const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings)
687 {
688 const RenderHandle handle = CreateDescriptorSet(descriptorSetLayoutBindings);
689 return CreateDescriptorSetBinder(handle, descriptorSetLayoutBindings);
690 }
691
CreatePipelineDescriptorSetBinder(const PipelineLayout & pipelineLayout)692 IPipelineDescriptorSetBinder::Ptr NodeContextDescriptorSetManager::CreatePipelineDescriptorSetBinder(
693 const PipelineLayout& pipelineLayout)
694 {
695 DescriptorSetLayoutBindings descriptorSetLayoutBindings[PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT];
696 RenderHandle handles[PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT];
697 for (uint32_t idx = 0; idx < PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT; ++idx) {
698 if (pipelineLayout.descriptorSetLayouts[idx].set < PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT) {
699 descriptorSetLayoutBindings[idx] = { pipelineLayout.descriptorSetLayouts[idx].bindings };
700 handles[idx] = CreateDescriptorSet(descriptorSetLayoutBindings[idx].binding);
701 #if (RENDER_VALIDATION_ENABLED == 1)
702 for (const auto& bindingRef : descriptorSetLayoutBindings[idx].binding) {
703 ReduceAndValidateDescriptorCounts(
704 bindingRef.descriptorType, bindingRef.descriptorCount, descriptorCountValidation_);
705 }
706 #endif
707 }
708 }
709 // pass max amount to binder, it will check validity of sets and their set indices
710 return IPipelineDescriptorSetBinder::Ptr { new PipelineDescriptorSetBinder(
711 pipelineLayout, handles, descriptorSetLayoutBindings) };
712 }
713
CreatePipelineDescriptorSetBinder(const PipelineLayout & pipelineLayout,const array_view<const RenderHandle> handles,const array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings)714 IPipelineDescriptorSetBinder::Ptr NodeContextDescriptorSetManager::CreatePipelineDescriptorSetBinder(
715 const PipelineLayout& pipelineLayout, const array_view<const RenderHandle> handles,
716 const array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings)
717 {
718 return IPipelineDescriptorSetBinder::Ptr { new PipelineDescriptorSetBinder(
719 pipelineLayout, handles, descriptorSetsLayoutBindings) };
720 }
721
GetCpuDescriptorSetData(const RenderHandle handle) const722 DescriptorSetLayoutBindingResourcesHandler NodeContextDescriptorSetManager::GetCpuDescriptorSetData(
723 const RenderHandle handle) const
724 {
725 const uint32_t descSetIdx = GetCpuDescriptorSetIndex(handle);
726 if (descSetIdx == ~0U) {
727 return globalDescriptorSetMgr_.GetCpuDescriptorSetData(handle);
728 } else {
729 PLUGIN_ASSERT(descSetIdx < DESCRIPTOR_SET_INDEX_TYPE_COUNT);
730 const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle);
731 const auto& cpuDescSets = cpuDescriptorSets_[descSetIdx];
732 return GetCpuDescriptorSetDataImpl(arrayIndex, cpuDescSets);
733 }
734 }
735
GetDynamicOffsetDescriptors(const RenderHandle handle) const736 DynamicOffsetDescriptors NodeContextDescriptorSetManager::GetDynamicOffsetDescriptors(const RenderHandle handle) const
737 {
738 const uint32_t descSetIdx = GetCpuDescriptorSetIndex(handle);
739 if (descSetIdx == ~0U) {
740 return globalDescriptorSetMgr_.GetDynamicOffsetDescriptors(handle);
741 } else {
742 PLUGIN_ASSERT(descSetIdx < DESCRIPTOR_SET_INDEX_TYPE_COUNT);
743 const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle);
744 const auto& cpuDescSets = cpuDescriptorSets_[descSetIdx];
745 return GetDynamicOffsetDescriptorsImpl(arrayIndex, cpuDescSets);
746 }
747 }
748
HasDynamicBarrierResources(const RenderHandle handle) const749 bool NodeContextDescriptorSetManager::HasDynamicBarrierResources(const RenderHandle handle) const
750 {
751 const uint32_t descSetIdx = GetCpuDescriptorSetIndex(handle);
752 if (descSetIdx == ~0U) {
753 return globalDescriptorSetMgr_.HasDynamicBarrierResources(handle);
754 } else {
755 PLUGIN_ASSERT(descSetIdx < DESCRIPTOR_SET_INDEX_TYPE_COUNT);
756 const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle);
757 const auto& cpuDescSets = cpuDescriptorSets_[descSetIdx];
758 return HasDynamicBarrierResourcesImpl(arrayIndex, cpuDescSets);
759 }
760 }
761
GetDynamicOffsetDescriptorCount(const RenderHandle handle) const762 uint32_t NodeContextDescriptorSetManager::GetDynamicOffsetDescriptorCount(const RenderHandle handle) const
763 {
764 const uint32_t descSetIdx = GetCpuDescriptorSetIndex(handle);
765 if (descSetIdx == ~0U) {
766 return globalDescriptorSetMgr_.GetDynamicOffsetDescriptorCount(handle);
767 } else {
768 PLUGIN_ASSERT(descSetIdx < DESCRIPTOR_SET_INDEX_TYPE_COUNT);
769 const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle);
770 const auto& cpuDescSets = cpuDescriptorSets_[descSetIdx];
771 return GetDynamicOffsetDescriptorCountImpl(arrayIndex, cpuDescSets);
772 }
773 }
774
UpdateCpuDescriptorSet(const RenderHandle handle,const DescriptorSetLayoutBindingResources & bindingResources,const GpuQueue & gpuQueue)775 DescriptorSetUpdateInfoFlags NodeContextDescriptorSetManager::UpdateCpuDescriptorSet(
776 const RenderHandle handle, const DescriptorSetLayoutBindingResources& bindingResources, const GpuQueue& gpuQueue)
777 {
778 const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle);
779 const uint32_t descSetIdx = GetCpuDescriptorSetIndex(handle);
780 if (descSetIdx == ~0U) {
781 return globalDescriptorSetMgr_.UpdateCpuDescriptorSet(handle, bindingResources, gpuQueue);
782 } else {
783 PLUGIN_ASSERT(descSetIdx < DESCRIPTOR_SET_INDEX_TYPE_COUNT);
784 auto& cpuDescSets = cpuDescriptorSets_[descSetIdx];
785 return UpdateCpuDescriptorSetImpl(arrayIndex, bindingResources, gpuQueue, cpuDescSets);
786 }
787 }
788
UpdateCpuDescriptorSetImpl(const uint32_t index,const DescriptorSetLayoutBindingResources & bindingResources,const GpuQueue & gpuQueue,vector<CpuDescriptorSet> & cpuDescriptorSets)789 DescriptorSetUpdateInfoFlags NodeContextDescriptorSetManager::UpdateCpuDescriptorSetImpl(const uint32_t index,
790 const DescriptorSetLayoutBindingResources& bindingResources, const GpuQueue& gpuQueue,
791 vector<CpuDescriptorSet>& cpuDescriptorSets)
792 {
793 DescriptorSetUpdateInfoFlags updateFlags = 0U;
794 if (index < (uint32_t)cpuDescriptorSets.size()) {
795 auto& refCpuSet = cpuDescriptorSets[index];
796 updateFlags = UpdateCpuDescriptorSetFunc((const GpuResourceManager&)device_.GetGpuResourceManager(),
797 bindingResources, gpuQueue, refCpuSet, hasPlatformConversionBindings_);
798 // update platform data for local
799 UpdateCpuDescriptorSetPlatform(bindingResources);
800 } else {
801 #if (RENDER_VALIDATION_ENABLED == 1)
802 PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to UpdateCpuDescriptorSet");
803 #endif
804 }
805 return updateFlags;
806 }
807
GetCpuDescriptorSetDataImpl(const uint32_t index,const vector<CpuDescriptorSet> & cpuDescriptorSet)808 DescriptorSetLayoutBindingResourcesHandler NodeContextDescriptorSetManager::GetCpuDescriptorSetDataImpl(
809 const uint32_t index, const vector<CpuDescriptorSet>& cpuDescriptorSet)
810 {
811 if (index < cpuDescriptorSet.size()) {
812 return DescriptorSetLayoutBindingResourcesHandler {
813 cpuDescriptorSet[index].bindings,
814 cpuDescriptorSet[index].buffers,
815 cpuDescriptorSet[index].images,
816 cpuDescriptorSet[index].samplers,
817 };
818 } else {
819 #if (RENDER_VALIDATION_ENABLED == 1)
820 PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to GetCpuDescriptorSetData");
821 #endif
822 return {};
823 }
824 }
825
GetDynamicOffsetDescriptorsImpl(const uint32_t index,const vector<CpuDescriptorSet> & cpuDescriptorSet)826 DynamicOffsetDescriptors NodeContextDescriptorSetManager::GetDynamicOffsetDescriptorsImpl(
827 const uint32_t index, const vector<CpuDescriptorSet>& cpuDescriptorSet)
828 {
829 if (index < cpuDescriptorSet.size()) {
830 return DynamicOffsetDescriptors {
831 array_view<const RenderHandle>(cpuDescriptorSet[index].dynamicOffsetDescriptors.data(),
832 cpuDescriptorSet[index].dynamicOffsetDescriptors.size()),
833 };
834 } else {
835 #if (RENDER_VALIDATION_ENABLED == 1)
836 PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to GetDynamicOffsetDescriptors");
837 #endif
838 return {};
839 }
840 }
841
HasDynamicBarrierResourcesImpl(const uint32_t index,const vector<CpuDescriptorSet> & cpuDescriptorSet)842 bool NodeContextDescriptorSetManager::HasDynamicBarrierResourcesImpl(
843 const uint32_t index, const vector<CpuDescriptorSet>& cpuDescriptorSet)
844 {
845 if (index < (uint32_t)cpuDescriptorSet.size()) {
846 return cpuDescriptorSet[index].hasDynamicBarrierResources;
847 } else {
848 #if (RENDER_VALIDATION_ENABLED == 1)
849 PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to HasDynamicBarrierResources");
850 #endif
851 return false;
852 }
853 }
854
GetDynamicOffsetDescriptorCountImpl(const uint32_t index,const vector<CpuDescriptorSet> & cpuDescriptorSet)855 uint32_t NodeContextDescriptorSetManager::GetDynamicOffsetDescriptorCountImpl(
856 const uint32_t index, const vector<CpuDescriptorSet>& cpuDescriptorSet)
857 {
858 if (index < (uint32_t)cpuDescriptorSet.size()) {
859 return (uint32_t)cpuDescriptorSet[index].dynamicOffsetDescriptors.size();
860 } else {
861 #if (RENDER_VALIDATION_ENABLED == 1)
862 PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to GetDynamicOffsetDescriptorCount");
863 #endif
864 return 0;
865 }
866 }
867
IncreaseDescriptorSetCounts(const DescriptorSetLayoutBinding & refBinding,LowLevelDescriptorCounts & descSetCounts,uint32_t & dynamicOffsetCount)868 void NodeContextDescriptorSetManager::IncreaseDescriptorSetCounts(
869 const DescriptorSetLayoutBinding& refBinding, LowLevelDescriptorCounts& descSetCounts, uint32_t& dynamicOffsetCount)
870 {
871 if (NodeContextDescriptorSetManager::IsDynamicDescriptor(refBinding.descriptorType)) {
872 dynamicOffsetCount++;
873 }
874 const uint32_t descriptorCount = refBinding.descriptorCount;
875 if (refBinding.descriptorType == CORE_DESCRIPTOR_TYPE_SAMPLER) {
876 descSetCounts.samplerCount += descriptorCount;
877 } else if (((refBinding.descriptorType >= CORE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) &&
878 (refBinding.descriptorType <= CORE_DESCRIPTOR_TYPE_STORAGE_IMAGE)) ||
879 (refBinding.descriptorType == CORE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
880 descSetCounts.imageCount += descriptorCount;
881 } else if (((refBinding.descriptorType >= CORE_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) &&
882 (refBinding.descriptorType <= CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) ||
883 (refBinding.descriptorType == CORE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE)) {
884 descSetCounts.bufferCount += descriptorCount;
885 }
886 #if (RENDER_VALIDATION_ENABLED == 1)
887 if (!((refBinding.descriptorType <= CORE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) ||
888 (refBinding.descriptorType == CORE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE))) {
889 PLUGIN_LOG_W("RENDER_VALIDATION: descriptor type not found");
890 }
891 #endif
892 }
893
894 #if ((RENDER_VALIDATION_ENABLED == 1) || (RENDER_VULKAN_VALIDATION_ENABLED == 1))
SetValidationDebugName(const string_view debugName)895 void NodeContextDescriptorSetManager::SetValidationDebugName(const string_view debugName)
896 {
897 debugName_ = debugName;
898 }
899 #endif
900 RENDER_END_NAMESPACE()
901