• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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