• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 == dstHandle) && (src.mip == dst.mip) && (src.layer == dst.layer) &&
94            (src.imageLayout == dst.imageLayout) && (srcSamplerHandle == dstSamplerHandle) &&
95            ((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) const401 CpuDescriptorSet* DescriptorSetManager::GetCpuDescriptorSet(const RenderHandle& handle) const
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) const420 DescriptorSetLayoutBindingResourcesHandler DescriptorSetManager::GetCpuDescriptorSetData(
421     const RenderHandle& handle) const
422 {
423     if (const CpuDescriptorSet* cpuDescriptorSet = GetCpuDescriptorSet(handle); cpuDescriptorSet) {
424         return DescriptorSetLayoutBindingResourcesHandler {
425             cpuDescriptorSet->bindings,
426             cpuDescriptorSet->buffers,
427             cpuDescriptorSet->images,
428             cpuDescriptorSet->samplers,
429         };
430     } else {
431 #if (RENDER_VALIDATION_ENABLED == 1)
432         PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to GetCpuDescriptorSetData");
433 #endif
434         return {};
435     }
436 }
437 
GetDynamicOffsetDescriptors(const RenderHandle & handle) const438 DynamicOffsetDescriptors DescriptorSetManager::GetDynamicOffsetDescriptors(const RenderHandle& handle) const
439 {
440     if (const CpuDescriptorSet* cpuDescriptorSet = GetCpuDescriptorSet(handle); cpuDescriptorSet) {
441         return DynamicOffsetDescriptors {
442             array_view<const RenderHandle>(
443                 cpuDescriptorSet->dynamicOffsetDescriptors.data(), cpuDescriptorSet->dynamicOffsetDescriptors.size()),
444         };
445     } else {
446         return {};
447     }
448 }
449 
HasDynamicBarrierResources(const RenderHandle & handle) const450 bool DescriptorSetManager::HasDynamicBarrierResources(const RenderHandle& handle) const
451 {
452     // NOTE: this method cannot provide up-to-date information during ExecuteFrame
453     // some render node task will update the dynamicity data in parallel
454 
455     if (const CpuDescriptorSet* cpuDescriptorSet = GetCpuDescriptorSet(handle); cpuDescriptorSet) {
456         return cpuDescriptorSet->hasDynamicBarrierResources;
457     } else {
458         return false;
459     }
460 }
461 
GetDynamicOffsetDescriptorCount(const RenderHandle & handle) const462 uint32_t DescriptorSetManager::GetDynamicOffsetDescriptorCount(const RenderHandle& handle) const
463 {
464     if (const CpuDescriptorSet* cpuDescriptorSet = GetCpuDescriptorSet(handle); cpuDescriptorSet) {
465         return static_cast<uint32_t>(cpuDescriptorSet->dynamicOffsetDescriptors.size());
466     } else {
467 #if (RENDER_VALIDATION_ENABLED == 1)
468         PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to GetDynamicOffsetDescriptorCount");
469 #endif
470         return 0U;
471     }
472 }
473 
HasPlatformConversionBindings(const RenderHandle & handle) const474 bool DescriptorSetManager::HasPlatformConversionBindings(const RenderHandle& handle) const
475 {
476     // NOTE: this method cannot provide up-to-date information during ExecuteFrame
477     // some render node task will update the dynamicity data in parallel
478 
479     if (const CpuDescriptorSet* cpuDescriptorSet = GetCpuDescriptorSet(handle); cpuDescriptorSet) {
480         return cpuDescriptorSet->hasPlatformConversionBindings;
481     } else {
482         return false;
483     }
484 }
485 
UpdateCpuDescriptorSet(const RenderHandle & handle,const DescriptorSetLayoutBindingResources & bindingResources,const GpuQueue & gpuQueue)486 DescriptorSetUpdateInfoFlags DescriptorSetManager::UpdateCpuDescriptorSet(
487     const RenderHandle& handle, const DescriptorSetLayoutBindingResources& bindingResources, const GpuQueue& gpuQueue)
488 {
489     PLUGIN_ASSERT(RenderHandleUtil::GetHandleType(handle) == RenderHandleType::DESCRIPTOR_SET);
490 
491     // NOTE: needs locks for global data access
492     // the local data, which is inside vector(s) do not need locks
493     // the global vectors are only resized when new descriptor sets are created ->
494     // and only from PreExecuteFrame (single thread)
495 
496     DescriptorSetUpdateInfoFlags updateFlags = 0U;
497     constexpr uint32_t validUpdateFlags = DescriptorSetUpdateInfoFlagBits::DESCRIPTOR_SET_UPDATE_INFO_NEW_BIT;
498     {
499         const uint32_t index = RenderHandleUtil::GetIndexPart(handle);
500         const uint32_t additionalIndex = RenderHandleUtil::GetAdditionalIndexPart(handle);
501         if ((index < descriptorSets_.size()) && descriptorSets_[index] &&
502             (additionalIndex < descriptorSets_[index]->data.size())) {
503             auto& ref = descriptorSets_[index]->data[additionalIndex];
504 
505             bool validWrite = false;
506             {
507                 // lock global mutex for shared data and for the boolean inside vectors
508                 const auto lock = std::lock_guard(mutex_);
509 
510                 if (!ref.frameWriteLocked) {
511                     // NOTE: not used at the moment
512                     bool hasPlatformConversionBindings = false;
513                     updateFlags = UpdateCpuDescriptorSetFunc((const GpuResourceManager&)device_.GetGpuResourceManager(),
514                         bindingResources, gpuQueue, ref.cpuDescriptorSet, hasPlatformConversionBindings);
515                     // set for update, these needs to be locked
516                     if ((updateFlags & 0xFFFFffffU) == validUpdateFlags) {
517                         descriptorSetHandlesForUpdate_.push_back(handle);
518                         UpdateCpuDescriptorSetPlatform(bindingResources);
519                         // mark as write locked for this frame
520                         ref.frameWriteLocked = true;
521                     }
522                     validWrite =
523                         ((updateFlags & DescriptorSetUpdateInfoFlagBits::DESCRIPTOR_SET_UPDATE_INFO_INVALID_BIT) == 0U);
524                 }
525             }
526             // the following do not need locks
527 #if (RENDER_VALIDATION_ENABLED)
528             if (!validWrite) {
529                 const string tmpName = string(to_string(handle.id)) + descriptorSets_[index]->name.c_str();
530                 PLUGIN_LOG_ONCE_W(tmpName, "RENDER_VALIDATION: Global descriptor set already updated this frame (%s)",
531                     descriptorSets_[index]->name.c_str());
532             }
533 #else
534             PLUGIN_UNUSED(validWrite);
535 #endif
536         }
537     }
538     return updateFlags;
539 }
540 
GetUpdateDescriptorSetHandles() const541 array_view<const RenderHandle> DescriptorSetManager::GetUpdateDescriptorSetHandles() const
542 {
543     return { descriptorSetHandlesForUpdate_.data(), descriptorSetHandlesForUpdate_.size() };
544 }
545 
NodeContextDescriptorSetManager(Device & device)546 NodeContextDescriptorSetManager::NodeContextDescriptorSetManager(Device& device)
547     : device_(device), globalDescriptorSetMgr_(device.GetDescriptorSetManager())
548 {}
549 
ResetAndReserve(const DescriptorCounts & descriptorCounts)550 void NodeContextDescriptorSetManager::ResetAndReserve(const DescriptorCounts& descriptorCounts)
551 {
552     // method
553     // prepare and create descriptor set pool
554     maxSets_ = 0;
555     auto& cpuDescriptorSets = cpuDescriptorSets_[DESCRIPTOR_SET_INDEX_TYPE_STATIC];
556     cpuDescriptorSets.clear();
557 #if (RENDER_VALIDATION_ENABLED == 1)
558     descriptorCountValidation_ = {};
559 #endif
560     for (const auto& ref : descriptorCounts.counts) {
561         maxSets_ += ref.count;
562 #if (RENDER_VALIDATION_ENABLED == 1)
563         auto& valRef = descriptorCountValidation_.typeToCount[static_cast<uint32_t>(ref.type)];
564         valRef += static_cast<int32_t>(ref.count);
565 #endif
566     }
567 
568     if (maxSets_ > 0) {
569         // usually there are less descriptor sets than max sets count
570         // due to maxsets count has been calculated for single descriptors
571         // (one descriptor set has multiple descriptors)
572         const uint32_t reserveCount = maxSets_ / 2u;
573         cpuDescriptorSets.reserve(reserveCount);
574     }
575 }
576 
ResetAndReserve(const BASE_NS::array_view<DescriptorCounts> descriptorCounts)577 void NodeContextDescriptorSetManager::ResetAndReserve(const BASE_NS::array_view<DescriptorCounts> descriptorCounts)
578 {
579     DescriptorCounts dc;
580     dc.counts.reserve(descriptorCounts.size());
581     for (const auto& descriptorCount : descriptorCounts) {
582         const auto& ref = descriptorCount.counts;
583         if (!ref.empty()) {
584             dc.counts.append(ref.begin(), ref.end());
585         }
586     }
587     ResetAndReserve(dc);
588 }
589 
BeginFrame()590 void NodeContextDescriptorSetManager::BeginFrame()
591 {
592     cpuDescriptorSets_[DESCRIPTOR_SET_INDEX_TYPE_ONE_FRAME].clear();
593     hasPlatformConversionBindings_ = false;
594 }
595 
CreateDescriptorSets(const array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings)596 vector<RenderHandle> NodeContextDescriptorSetManager::CreateDescriptorSets(
597     const array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings)
598 {
599     vector<RenderHandle> handles;
600     handles.reserve(descriptorSetsLayoutBindings.size());
601     for (const auto& ref : descriptorSetsLayoutBindings) {
602 #if (RENDER_VALIDATION_ENABLED == 1)
603         for (const auto& bindingRef : ref.binding) {
604             ReduceAndValidateDescriptorCounts(
605                 bindingRef.descriptorType, bindingRef.descriptorCount, descriptorCountValidation_);
606         }
607 #endif
608         handles.push_back(CreateDescriptorSet(ref.binding));
609     }
610     return handles;
611 }
612 
CreateDescriptorSet(const uint32_t set,const PipelineLayout & pipelineLayout)613 RenderHandle NodeContextDescriptorSetManager::CreateDescriptorSet(
614     const uint32_t set, const PipelineLayout& pipelineLayout)
615 {
616     if (set < PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT) {
617         const auto& ref = pipelineLayout.descriptorSetLayouts[set];
618         if (ref.set == set) {
619 #if (RENDER_VALIDATION_ENABLED == 1)
620             for (const auto& bindingRef : ref.bindings) {
621                 ReduceAndValidateDescriptorCounts(
622                     bindingRef.descriptorType, bindingRef.descriptorCount, descriptorCountValidation_);
623             }
624 #endif
625             return CreateDescriptorSet(ref.bindings);
626         } else {
627             PLUGIN_LOG_E("CreateDescriptorSet: sets needs to be sorted in PipelineLayout");
628         }
629     }
630     PLUGIN_LOG_E("set index needs to be valid in PipelineLayout");
631     return {};
632 }
633 
CreateOneFrameDescriptorSets(const array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings)634 vector<RenderHandle> NodeContextDescriptorSetManager::CreateOneFrameDescriptorSets(
635     const array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings)
636 {
637     vector<RenderHandle> handles;
638     handles.reserve(descriptorSetsLayoutBindings.size());
639     for (const auto& ref : descriptorSetsLayoutBindings) {
640         handles.push_back(CreateOneFrameDescriptorSet(ref.binding));
641     }
642     return handles;
643 }
644 
CreateOneFrameDescriptorSet(const uint32_t set,const PipelineLayout & pipelineLayout)645 RenderHandle NodeContextDescriptorSetManager::CreateOneFrameDescriptorSet(
646     const uint32_t set, const PipelineLayout& pipelineLayout)
647 {
648     if (set < PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT) {
649         const auto& ref = pipelineLayout.descriptorSetLayouts[set];
650         if (ref.set == set) {
651             return CreateOneFrameDescriptorSet(ref.bindings);
652         } else {
653             PLUGIN_LOG_E("CreateOneFrameDescriptorSet: sets needs to be sorted in PipelineLayout");
654         }
655     }
656     PLUGIN_LOG_E("set index needs to be valid in PipelineLayout");
657     return {};
658 }
659 
CreateGlobalDescriptorSets(const BASE_NS::string_view name,const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings,const uint32_t descriptorSetCount)660 vector<RenderHandleReference> NodeContextDescriptorSetManager::CreateGlobalDescriptorSets(
661     const BASE_NS::string_view name,
662     const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings,
663     const uint32_t descriptorSetCount)
664 {
665     if ((!name.empty()) && (!descriptorSetLayoutBindings.empty())) {
666         return globalDescriptorSetMgr_.CreateDescriptorSets(name, descriptorSetLayoutBindings, descriptorSetCount);
667     } else {
668         return {};
669     }
670 }
671 
CreateGlobalDescriptorSet(const BASE_NS::string_view name,const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings)672 RenderHandleReference NodeContextDescriptorSetManager::CreateGlobalDescriptorSet(const BASE_NS::string_view name,
673     const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings)
674 {
675     RenderHandleReference handle;
676     if ((!name.empty()) && (!descriptorSetLayoutBindings.empty())) {
677         handle = globalDescriptorSetMgr_.CreateDescriptorSet(name, descriptorSetLayoutBindings);
678     }
679     return handle;
680 }
681 
GetGlobalDescriptorSet(const BASE_NS::string_view name) const682 RenderHandle NodeContextDescriptorSetManager::GetGlobalDescriptorSet(const BASE_NS::string_view name) const
683 {
684     return globalDescriptorSetMgr_.GetDescriptorSetHandle(name);
685 }
686 
GetGlobalDescriptorSets(const BASE_NS::string_view name) const687 array_view<const RenderHandle> NodeContextDescriptorSetManager::GetGlobalDescriptorSets(
688     const BASE_NS::string_view name) const
689 {
690     return globalDescriptorSetMgr_.GetDescriptorSetHandles(name);
691 }
692 
CreateDescriptorSetBinder(const RenderHandle handle,const array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings)693 IDescriptorSetBinder::Ptr NodeContextDescriptorSetManager::CreateDescriptorSetBinder(
694     const RenderHandle handle, const array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings)
695 {
696     return IDescriptorSetBinder::Ptr { new DescriptorSetBinder(handle, descriptorSetLayoutBindings) };
697 }
698 
CreateDescriptorSetBinder(const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings)699 IDescriptorSetBinder::Ptr NodeContextDescriptorSetManager::CreateDescriptorSetBinder(
700     const BASE_NS::array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings)
701 {
702     const RenderHandle handle = CreateDescriptorSet(descriptorSetLayoutBindings);
703     return CreateDescriptorSetBinder(handle, descriptorSetLayoutBindings);
704 }
705 
CreatePipelineDescriptorSetBinder(const PipelineLayout & pipelineLayout)706 IPipelineDescriptorSetBinder::Ptr NodeContextDescriptorSetManager::CreatePipelineDescriptorSetBinder(
707     const PipelineLayout& pipelineLayout)
708 {
709     DescriptorSetLayoutBindings descriptorSetLayoutBindings[PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT];
710     RenderHandle handles[PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT];
711     for (uint32_t idx = 0; idx < PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT; ++idx) {
712         if (pipelineLayout.descriptorSetLayouts[idx].set < PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT) {
713             descriptorSetLayoutBindings[idx] = { pipelineLayout.descriptorSetLayouts[idx].bindings };
714             handles[idx] = CreateDescriptorSet(descriptorSetLayoutBindings[idx].binding);
715 #if (RENDER_VALIDATION_ENABLED == 1)
716             for (const auto& bindingRef : descriptorSetLayoutBindings[idx].binding) {
717                 ReduceAndValidateDescriptorCounts(
718                     bindingRef.descriptorType, bindingRef.descriptorCount, descriptorCountValidation_);
719             }
720 #endif
721         }
722     }
723     // pass max amount to binder, it will check validity of sets and their set indices
724     return IPipelineDescriptorSetBinder::Ptr { new PipelineDescriptorSetBinder(
725         pipelineLayout, handles, descriptorSetLayoutBindings) };
726 }
727 
CreatePipelineDescriptorSetBinder(const PipelineLayout & pipelineLayout,const array_view<const RenderHandle> handles,const array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings)728 IPipelineDescriptorSetBinder::Ptr NodeContextDescriptorSetManager::CreatePipelineDescriptorSetBinder(
729     const PipelineLayout& pipelineLayout, const array_view<const RenderHandle> handles,
730     const array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings)
731 {
732     return IPipelineDescriptorSetBinder::Ptr { new PipelineDescriptorSetBinder(
733         pipelineLayout, handles, descriptorSetsLayoutBindings) };
734 }
735 
GetCpuDescriptorSetData(const RenderHandle handle) const736 DescriptorSetLayoutBindingResourcesHandler NodeContextDescriptorSetManager::GetCpuDescriptorSetData(
737     const RenderHandle handle) const
738 {
739     const uint32_t descSetIdx = GetCpuDescriptorSetIndex(handle);
740     if (descSetIdx == ~0U) {
741         return globalDescriptorSetMgr_.GetCpuDescriptorSetData(handle);
742     } else {
743         PLUGIN_ASSERT(descSetIdx < DESCRIPTOR_SET_INDEX_TYPE_COUNT);
744         const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle);
745         const auto& cpuDescSets = cpuDescriptorSets_[descSetIdx];
746         return GetCpuDescriptorSetDataImpl(arrayIndex, cpuDescSets);
747     }
748 }
749 
GetDynamicOffsetDescriptors(const RenderHandle handle) const750 DynamicOffsetDescriptors NodeContextDescriptorSetManager::GetDynamicOffsetDescriptors(const RenderHandle handle) const
751 {
752     const uint32_t descSetIdx = GetCpuDescriptorSetIndex(handle);
753     if (descSetIdx == ~0U) {
754         return globalDescriptorSetMgr_.GetDynamicOffsetDescriptors(handle);
755     } else {
756         PLUGIN_ASSERT(descSetIdx < DESCRIPTOR_SET_INDEX_TYPE_COUNT);
757         const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle);
758         const auto& cpuDescSets = cpuDescriptorSets_[descSetIdx];
759         return GetDynamicOffsetDescriptorsImpl(arrayIndex, cpuDescSets);
760     }
761 }
762 
HasDynamicBarrierResources(const RenderHandle handle) const763 bool NodeContextDescriptorSetManager::HasDynamicBarrierResources(const RenderHandle handle) const
764 {
765     const uint32_t descSetIdx = GetCpuDescriptorSetIndex(handle);
766     if (descSetIdx == ~0U) {
767         return globalDescriptorSetMgr_.HasDynamicBarrierResources(handle);
768     } else {
769         PLUGIN_ASSERT(descSetIdx < DESCRIPTOR_SET_INDEX_TYPE_COUNT);
770         const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle);
771         const auto& cpuDescSets = cpuDescriptorSets_[descSetIdx];
772         return HasDynamicBarrierResourcesImpl(arrayIndex, cpuDescSets);
773     }
774 }
775 
GetDynamicOffsetDescriptorCount(const RenderHandle handle) const776 uint32_t NodeContextDescriptorSetManager::GetDynamicOffsetDescriptorCount(const RenderHandle handle) const
777 {
778     const uint32_t descSetIdx = GetCpuDescriptorSetIndex(handle);
779     if (descSetIdx == ~0U) {
780         return globalDescriptorSetMgr_.GetDynamicOffsetDescriptorCount(handle);
781     } else {
782         PLUGIN_ASSERT(descSetIdx < DESCRIPTOR_SET_INDEX_TYPE_COUNT);
783         const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle);
784         const auto& cpuDescSets = cpuDescriptorSets_[descSetIdx];
785         return GetDynamicOffsetDescriptorCountImpl(arrayIndex, cpuDescSets);
786     }
787 }
788 
HasPlatformConversionBindings(const RenderHandle handle) const789 bool NodeContextDescriptorSetManager::HasPlatformConversionBindings(const RenderHandle handle) const
790 
791 {
792     const uint32_t descSetIdx = GetCpuDescriptorSetIndex(handle);
793     if (descSetIdx == ~0U) {
794         return globalDescriptorSetMgr_.HasPlatformConversionBindings(handle);
795     } else {
796         PLUGIN_ASSERT(descSetIdx < DESCRIPTOR_SET_INDEX_TYPE_COUNT);
797         const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle);
798         const auto& cpuDescSets = cpuDescriptorSets_[descSetIdx];
799         return HasPlatformConversionBindingsImpl(arrayIndex, cpuDescSets);
800     }
801 }
802 
UpdateCpuDescriptorSet(const RenderHandle handle,const DescriptorSetLayoutBindingResources & bindingResources,const GpuQueue & gpuQueue)803 DescriptorSetUpdateInfoFlags NodeContextDescriptorSetManager::UpdateCpuDescriptorSet(
804     const RenderHandle handle, const DescriptorSetLayoutBindingResources& bindingResources, const GpuQueue& gpuQueue)
805 {
806     const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle);
807     const uint32_t descSetIdx = GetCpuDescriptorSetIndex(handle);
808     if (descSetIdx == ~0U) {
809         return globalDescriptorSetMgr_.UpdateCpuDescriptorSet(handle, bindingResources, gpuQueue);
810     } else {
811         PLUGIN_ASSERT(descSetIdx < DESCRIPTOR_SET_INDEX_TYPE_COUNT);
812         auto& cpuDescSets = cpuDescriptorSets_[descSetIdx];
813         return UpdateCpuDescriptorSetImpl(arrayIndex, bindingResources, gpuQueue, cpuDescSets);
814     }
815 }
816 
UpdateCpuDescriptorSetImpl(const uint32_t index,const DescriptorSetLayoutBindingResources & bindingResources,const GpuQueue & gpuQueue,array_view<CpuDescriptorSet> cpuDescriptorSets)817 DescriptorSetUpdateInfoFlags NodeContextDescriptorSetManager::UpdateCpuDescriptorSetImpl(const uint32_t index,
818     const DescriptorSetLayoutBindingResources& bindingResources, const GpuQueue& gpuQueue,
819     array_view<CpuDescriptorSet> cpuDescriptorSets)
820 {
821     DescriptorSetUpdateInfoFlags updateFlags = 0U;
822     if (index < (uint32_t)cpuDescriptorSets.size()) {
823         auto& refCpuSet = cpuDescriptorSets[index];
824         updateFlags = UpdateCpuDescriptorSetFunc((const GpuResourceManager&)device_.GetGpuResourceManager(),
825             bindingResources, gpuQueue, refCpuSet, hasPlatformConversionBindings_);
826         // update platform data for local
827         UpdateCpuDescriptorSetPlatform(bindingResources);
828     } else {
829 #if (RENDER_VALIDATION_ENABLED == 1)
830         PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to UpdateCpuDescriptorSet");
831 #endif
832     }
833     return updateFlags;
834 }
835 
GetCpuDescriptorSetDataImpl(const uint32_t index,const vector<CpuDescriptorSet> & cpuDescriptorSet)836 DescriptorSetLayoutBindingResourcesHandler NodeContextDescriptorSetManager::GetCpuDescriptorSetDataImpl(
837     const uint32_t index, const vector<CpuDescriptorSet>& cpuDescriptorSet)
838 {
839     if (index < cpuDescriptorSet.size()) {
840         return DescriptorSetLayoutBindingResourcesHandler {
841             cpuDescriptorSet[index].bindings,
842             cpuDescriptorSet[index].buffers,
843             cpuDescriptorSet[index].images,
844             cpuDescriptorSet[index].samplers,
845         };
846     } else {
847 #if (RENDER_VALIDATION_ENABLED == 1)
848         PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to GetCpuDescriptorSetData");
849 #endif
850         return {};
851     }
852 }
853 
GetDynamicOffsetDescriptorsImpl(const uint32_t index,const vector<CpuDescriptorSet> & cpuDescriptorSet)854 DynamicOffsetDescriptors NodeContextDescriptorSetManager::GetDynamicOffsetDescriptorsImpl(
855     const uint32_t index, const vector<CpuDescriptorSet>& cpuDescriptorSet)
856 {
857     if (index < cpuDescriptorSet.size()) {
858         return DynamicOffsetDescriptors {
859             array_view<const RenderHandle>(cpuDescriptorSet[index].dynamicOffsetDescriptors.data(),
860                 cpuDescriptorSet[index].dynamicOffsetDescriptors.size()),
861         };
862     } else {
863 #if (RENDER_VALIDATION_ENABLED == 1)
864         PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to GetDynamicOffsetDescriptors");
865 #endif
866         return {};
867     }
868 }
869 
HasDynamicBarrierResourcesImpl(const uint32_t index,const vector<CpuDescriptorSet> & cpuDescriptorSet)870 bool NodeContextDescriptorSetManager::HasDynamicBarrierResourcesImpl(
871     const uint32_t index, const vector<CpuDescriptorSet>& cpuDescriptorSet)
872 {
873     if (index < (uint32_t)cpuDescriptorSet.size()) {
874         return cpuDescriptorSet[index].hasDynamicBarrierResources;
875     } else {
876 #if (RENDER_VALIDATION_ENABLED == 1)
877         PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to HasDynamicBarrierResources");
878 #endif
879         return false;
880     }
881 }
HasPlatformConversionBindingsImpl(const uint32_t index,const BASE_NS::vector<CpuDescriptorSet> & cpuDescriptorSet)882 bool NodeContextDescriptorSetManager::HasPlatformConversionBindingsImpl(
883     const uint32_t index, const BASE_NS::vector<CpuDescriptorSet>& cpuDescriptorSet)
884 {
885     if (index < (uint32_t)cpuDescriptorSet.size()) {
886         return cpuDescriptorSet[index].hasPlatformConversionBindings;
887     } else {
888 #if (RENDER_VALIDATION_ENABLED == 1)
889         PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to HasPlatformConversionBindings");
890 #endif
891         return false;
892     }
893 }
894 
GetDynamicOffsetDescriptorCountImpl(const uint32_t index,const vector<CpuDescriptorSet> & cpuDescriptorSet)895 uint32_t NodeContextDescriptorSetManager::GetDynamicOffsetDescriptorCountImpl(
896     const uint32_t index, const vector<CpuDescriptorSet>& cpuDescriptorSet)
897 {
898     if (index < (uint32_t)cpuDescriptorSet.size()) {
899         return (uint32_t)cpuDescriptorSet[index].dynamicOffsetDescriptors.size();
900     } else {
901 #if (RENDER_VALIDATION_ENABLED == 1)
902         PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to GetDynamicOffsetDescriptorCount");
903 #endif
904         return 0;
905     }
906 }
907 
IncreaseDescriptorSetCounts(const DescriptorSetLayoutBinding & refBinding,LowLevelDescriptorCounts & descSetCounts,uint32_t & dynamicOffsetCount)908 void NodeContextDescriptorSetManager::IncreaseDescriptorSetCounts(
909     const DescriptorSetLayoutBinding& refBinding, LowLevelDescriptorCounts& descSetCounts, uint32_t& dynamicOffsetCount)
910 {
911     if (NodeContextDescriptorSetManager::IsDynamicDescriptor(refBinding.descriptorType)) {
912         dynamicOffsetCount++;
913     }
914     const uint32_t descriptorCount = refBinding.descriptorCount;
915     if (refBinding.descriptorType == CORE_DESCRIPTOR_TYPE_SAMPLER) {
916         descSetCounts.samplerCount += descriptorCount;
917     } else if (((refBinding.descriptorType >= CORE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) &&
918                    (refBinding.descriptorType <= CORE_DESCRIPTOR_TYPE_STORAGE_IMAGE)) ||
919                (refBinding.descriptorType == CORE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
920         descSetCounts.imageCount += descriptorCount;
921     } else if (((refBinding.descriptorType >= CORE_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) &&
922                    (refBinding.descriptorType <= CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) ||
923                (refBinding.descriptorType == CORE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE)) {
924         descSetCounts.bufferCount += descriptorCount;
925     }
926 #if (RENDER_VALIDATION_ENABLED == 1)
927     if (!((refBinding.descriptorType <= CORE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) ||
928             (refBinding.descriptorType == CORE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE))) {
929         PLUGIN_LOG_W("RENDER_VALIDATION: descriptor type not found");
930     }
931 #endif
932 }
933 
934 #if ((RENDER_VALIDATION_ENABLED == 1) || (RENDER_VULKAN_VALIDATION_ENABLED == 1))
SetValidationDebugName(const string_view debugName)935 void NodeContextDescriptorSetManager::SetValidationDebugName(const string_view debugName)
936 {
937     debugName_ = debugName;
938 }
939 #endif
940 RENDER_END_NAMESPACE()
941