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 <algorithm>
19 #include <cstddef>
20 #include <cstdint>
21 
22 #include <base/containers/vector.h>
23 #include <base/math/mathf.h>
24 #include <render/device/pipeline_state_desc.h>
25 #include <render/namespace.h>
26 
27 #include "device/device.h"
28 #include "device/gpu_resource_handle_util.h"
29 #include "nodecontext/pipeline_descriptor_set_binder.h"
30 #include "util/log.h"
31 
32 using namespace BASE_NS;
33 
34 RENDER_BEGIN_NAMESPACE()
35 namespace {
36 #if (RENDER_VALIDATION_ENABLED == 1)
ReduceAndValidateDescriptorCounts(const DescriptorType descriptorType,const uint32_t descriptorCount,NodeContextDescriptorSetManager::DescriptorCountValidation & countValidation)37 void ReduceAndValidateDescriptorCounts(const DescriptorType descriptorType, const uint32_t descriptorCount,
38     NodeContextDescriptorSetManager::DescriptorCountValidation& countValidation)
39 {
40     auto& valRef = countValidation.typeToCount[static_cast<uint32_t>(descriptorType)];
41     valRef -= descriptorCount;
42     if (valRef < 0) {
43         string typeName;
44         if (descriptorType == CORE_DESCRIPTOR_TYPE_SAMPLER) {
45             typeName = "CORE_DESCRIPTOR_TYPE_SAMPLER";
46         } else if (descriptorType == CORE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
47             typeName = "CORE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER";
48         } else if (descriptorType == CORE_DESCRIPTOR_TYPE_SAMPLED_IMAGE) {
49             typeName = "CORE_DESCRIPTOR_TYPE_SAMPLED_IMAGE";
50         } else if (descriptorType == CORE_DESCRIPTOR_TYPE_STORAGE_IMAGE) {
51             typeName = "CORE_DESCRIPTOR_TYPE_STORAGE_IMAGE";
52         } else if (descriptorType == CORE_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) {
53             typeName = "CORE_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER";
54         } else if (descriptorType == CORE_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) {
55             typeName = "CORE_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER";
56         } else if (descriptorType == CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
57             typeName = "CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER";
58         } else if (descriptorType == CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER) {
59             typeName = "CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER";
60         } else if (descriptorType == CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
61             typeName = "CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC";
62         } else if (descriptorType == CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
63             typeName = "CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC";
64         } else if (descriptorType == CORE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) {
65             typeName = "CORE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT";
66         } else if (descriptorType == CORE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE) {
67             typeName = "CORE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE";
68         }
69         PLUGIN_LOG_E(
70             "RENDER_VALIDATION: Not enough descriptors available (count: %i) (type: %s)", valRef, typeName.c_str());
71     }
72 }
73 #endif
74 
CopyAndProcessBuffers(const DescriptorSetLayoutBindingResources & src,const GpuQueue & gpuQueue,NodeContextDescriptorSetManager::CpuDescriptorSet & dst)75 bool CopyAndProcessBuffers(const DescriptorSetLayoutBindingResources& src, const GpuQueue& gpuQueue,
76     NodeContextDescriptorSetManager::CpuDescriptorSet& dst)
77 {
78     const uint32_t maxCount = static_cast<uint32_t>(Math::min(src.buffers.size(), dst.buffers.size()));
79     dst.buffers.clear();
80     dst.buffers.insert(dst.buffers.end(), src.buffers.begin(), src.buffers.begin() + maxCount);
81     uint32_t dynamicOffsetIndex = 0;
82     bool valid = true;
83     for (uint32_t idx = 0; idx < maxCount; ++idx) {
84         auto& dstRef = dst.buffers[idx];
85         dstRef.state.gpuQueue = gpuQueue;
86         if (!RenderHandleUtil::IsGpuBuffer(dstRef.resource.handle)) {
87             valid = false;
88         }
89         if (RenderHandleUtil::IsDynamicResource(dstRef.resource.handle)) {
90             dst.hasDynamicBarrierResources = true;
91         }
92         if (NodeContextDescriptorSetManager::IsDynamicDescriptor(dstRef.binding.descriptorType)) {
93             PLUGIN_ASSERT(dynamicOffsetIndex < static_cast<uint32_t>(dst.dynamicOffsetDescriptors.size()));
94             dst.dynamicOffsetDescriptors[dynamicOffsetIndex++] = dstRef.resource.handle;
95         }
96     }
97     return valid;
98 }
99 
CopyAndProcessImages(const DescriptorSetLayoutBindingResources & src,const GpuQueue & gpuQueue,NodeContextDescriptorSetManager::CpuDescriptorSet & dst)100 bool CopyAndProcessImages(const DescriptorSetLayoutBindingResources& src, const GpuQueue& gpuQueue,
101     NodeContextDescriptorSetManager::CpuDescriptorSet& dst)
102 {
103     const uint32_t maxCount = static_cast<uint32_t>(Math::min(src.images.size(), dst.images.size()));
104     dst.images.clear();
105     dst.images.insert(dst.images.end(), src.images.begin(), src.images.begin() + maxCount);
106     bool valid = true;
107     for (uint32_t idx = 0; idx < maxCount; ++idx) {
108         auto& dstRef = dst.images[idx];
109         dstRef.state.gpuQueue = gpuQueue;
110         if (!RenderHandleUtil::IsGpuImage(dstRef.resource.handle)) {
111             valid = false;
112         }
113         if (RenderHandleUtil::IsDynamicResource(dstRef.resource.handle)) {
114             dst.hasDynamicBarrierResources = true;
115         }
116         if (dstRef.additionalFlags & CORE_ADDITIONAL_DESCRIPTOR_IMMUTABLE_SAMPLER_BIT) {
117             dst.hasImmutableSamplers = true;
118         }
119         if (RenderHandleUtil::IsPlatformConversionResource(dstRef.resource.handle)) {
120             if (dstRef.binding.descriptorType == DescriptorType::CORE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
121                 dst.hasPlatformConversionBindings = true;
122             }
123 #if (RENDER_VALIDATION_ENABLED == 1)
124             if (dstRef.binding.descriptorType != DescriptorType::CORE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
125                 PLUGIN_LOG_ONCE_W("core_validation_plat_conv_desc_set",
126                     "RENDER_VALIDATION: automatic platform conversion only supported for "
127                     "CORE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER");
128             }
129             if (dstRef.binding.descriptorCount > 1) {
130                 PLUGIN_LOG_ONCE_W("core_validation_plat_conv_desc_set_arr",
131                     "RENDER_VALIDATION: array of platform special image formats not supported");
132             }
133 #endif
134         }
135     }
136     return valid;
137 }
138 
CopyAndProcessSamplers(const DescriptorSetLayoutBindingResources & src,NodeContextDescriptorSetManager::CpuDescriptorSet & dst)139 bool CopyAndProcessSamplers(
140     const DescriptorSetLayoutBindingResources& src, NodeContextDescriptorSetManager::CpuDescriptorSet& dst)
141 {
142     const uint32_t maxCount = static_cast<uint32_t>(Math::min(src.samplers.size(), dst.samplers.size()));
143     dst.samplers.clear();
144     dst.samplers.insert(dst.samplers.end(), src.samplers.begin(), src.samplers.begin() + maxCount);
145     bool valid = true;
146     for (uint32_t idx = 0; idx < maxCount; ++idx) {
147         auto& dstRef = dst.samplers[idx];
148         if (!RenderHandleUtil::IsGpuSampler(dstRef.resource.handle)) {
149             valid = false;
150         }
151         if (dstRef.additionalFlags & CORE_ADDITIONAL_DESCRIPTOR_IMMUTABLE_SAMPLER_BIT) {
152             dst.hasImmutableSamplers = true;
153         }
154     }
155     return valid;
156 }
157 } // namespace
158 
ResetAndReserve(const DescriptorCounts & descriptorCounts)159 void NodeContextDescriptorSetManager::ResetAndReserve(const DescriptorCounts& descriptorCounts)
160 {
161     // method
162     // prepare and create descriptor set pool
163     maxSets_ = 0;
164     auto& cpuDescriptorSets = cpuDescriptorSets_[DESCRIPTOR_SET_INDEX_TYPE_STATIC];
165     cpuDescriptorSets.clear();
166 #if (RENDER_VALIDATION_ENABLED == 1)
167     descriptorCountValidation_ = {};
168 #endif
169     for (const auto& ref : descriptorCounts.counts) {
170         maxSets_ += ref.count;
171 #if (RENDER_VALIDATION_ENABLED == 1)
172         auto& valRef = descriptorCountValidation_.typeToCount[static_cast<uint32_t>(ref.type)];
173         valRef += static_cast<int32_t>(ref.count);
174 #endif
175     }
176 
177     if (maxSets_ > 0) {
178         // usually there are less descriptor sets than max sets count
179         // due to maxsets count has been calculated for single descriptors
180         // (one descriptor set has multiple descriptors)
181         const uint32_t reserveCount = maxSets_ / 2u;
182         cpuDescriptorSets.reserve(reserveCount);
183     }
184 }
185 
ResetAndReserve(const BASE_NS::array_view<DescriptorCounts> descriptorCounts)186 void NodeContextDescriptorSetManager::ResetAndReserve(const BASE_NS::array_view<DescriptorCounts> descriptorCounts)
187 {
188     DescriptorCounts dc;
189     dc.counts.reserve(descriptorCounts.size());
190     for (size_t idx = 0; idx < descriptorCounts.size(); idx++) {
191         const auto& ref = descriptorCounts[idx].counts;
192         if (!ref.empty()) {
193             dc.counts.insert(dc.counts.end(), ref.begin(), ref.end());
194         }
195     }
196     ResetAndReserve(dc);
197 }
198 
BeginFrame()199 void NodeContextDescriptorSetManager::BeginFrame()
200 {
201     cpuDescriptorSets_[DESCRIPTOR_SET_INDEX_TYPE_ONE_FRAME].clear();
202     hasPlatformConversionBindings_ = false;
203 }
204 
CreateDescriptorSets(const array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings)205 vector<RenderHandle> NodeContextDescriptorSetManager::CreateDescriptorSets(
206     const array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings)
207 {
208     vector<RenderHandle> handles;
209     handles.reserve(descriptorSetsLayoutBindings.size());
210     for (const auto& ref : descriptorSetsLayoutBindings) {
211 #if (RENDER_VALIDATION_ENABLED == 1)
212         for (const auto& bindingRef : ref.binding) {
213             ReduceAndValidateDescriptorCounts(
214                 bindingRef.descriptorType, bindingRef.descriptorCount, descriptorCountValidation_);
215         }
216 #endif
217         handles.push_back(CreateDescriptorSet(ref.binding));
218     }
219     return handles;
220 }
221 
CreateDescriptorSet(const uint32_t set,const PipelineLayout & pipelineLayout)222 RenderHandle NodeContextDescriptorSetManager::CreateDescriptorSet(
223     const uint32_t set, const PipelineLayout& pipelineLayout)
224 {
225     if (set < pipelineLayout.descriptorSetCount) {
226         const auto& ref = pipelineLayout.descriptorSetLayouts[set];
227         if (ref.set == set) {
228 #if (RENDER_VALIDATION_ENABLED == 1)
229             for (const auto& bindingRef : ref.bindings) {
230                 ReduceAndValidateDescriptorCounts(
231                     bindingRef.descriptorType, bindingRef.descriptorCount, descriptorCountValidation_);
232             }
233 #endif
234             return CreateDescriptorSet(ref.bindings);
235         } else {
236             PLUGIN_LOG_E("CreateDescriptorSet: sets needs to be sorted in PipelineLayout");
237         }
238     }
239     PLUGIN_LOG_E("set index needs to be valid in PipelineLayout");
240     return {};
241 }
242 
CreateOneFrameDescriptorSets(const array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings)243 vector<RenderHandle> NodeContextDescriptorSetManager::CreateOneFrameDescriptorSets(
244     const array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings)
245 {
246     vector<RenderHandle> handles;
247     handles.reserve(descriptorSetsLayoutBindings.size());
248     for (const auto& ref : descriptorSetsLayoutBindings) {
249         handles.push_back(CreateOneFrameDescriptorSet(ref.binding));
250     }
251     return handles;
252 }
253 
CreateOneFrameDescriptorSet(const uint32_t set,const PipelineLayout & pipelineLayout)254 RenderHandle NodeContextDescriptorSetManager::CreateOneFrameDescriptorSet(
255     const uint32_t set, const PipelineLayout& pipelineLayout)
256 {
257     if (set < pipelineLayout.descriptorSetCount) {
258         const auto& ref = pipelineLayout.descriptorSetLayouts[set];
259         if (ref.set == set) {
260             return CreateOneFrameDescriptorSet(ref.bindings);
261         } else {
262             PLUGIN_LOG_E("CreateOneFrameDescriptorSet: sets needs to be sorted in PipelineLayout");
263         }
264     }
265     PLUGIN_LOG_E("set index needs to be valid in PipelineLayout");
266     return {};
267 }
268 
CreateDescriptorSetBinder(const RenderHandle handle,const array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings)269 IDescriptorSetBinder::Ptr NodeContextDescriptorSetManager::CreateDescriptorSetBinder(
270     const RenderHandle handle, const array_view<const DescriptorSetLayoutBinding> descriptorSetLayoutBindings)
271 {
272     return IDescriptorSetBinder::Ptr { new DescriptorSetBinder(handle, descriptorSetLayoutBindings) };
273 }
274 
CreatePipelineDescriptorSetBinder(const PipelineLayout & pipelineLayout)275 IPipelineDescriptorSetBinder::Ptr NodeContextDescriptorSetManager::CreatePipelineDescriptorSetBinder(
276     const PipelineLayout& pipelineLayout)
277 {
278     DescriptorSetLayoutBindings descriptorSetLayoutBindings[PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT];
279     RenderHandle handles[PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT];
280     for (uint32_t idx = 0; idx < PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT; ++idx) {
281         if (pipelineLayout.descriptorSetLayouts[idx].set < PipelineLayoutConstants::MAX_DESCRIPTOR_SET_COUNT) {
282             descriptorSetLayoutBindings[idx] = { pipelineLayout.descriptorSetLayouts[idx].bindings };
283             handles[idx] = CreateDescriptorSet(descriptorSetLayoutBindings[idx].binding);
284 #if (RENDER_VALIDATION_ENABLED == 1)
285             for (const auto& bindingRef : descriptorSetLayoutBindings[idx].binding) {
286                 ReduceAndValidateDescriptorCounts(
287                     bindingRef.descriptorType, bindingRef.descriptorCount, descriptorCountValidation_);
288             }
289 #endif
290         }
291     }
292     // pass max amount to binder, it will check validity of sets and their set indices
293     return IPipelineDescriptorSetBinder::Ptr { new PipelineDescriptorSetBinder(
294         pipelineLayout, handles, descriptorSetLayoutBindings) };
295 }
296 
CreatePipelineDescriptorSetBinder(const PipelineLayout & pipelineLayout,const array_view<const RenderHandle> handles,const array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings)297 IPipelineDescriptorSetBinder::Ptr NodeContextDescriptorSetManager::CreatePipelineDescriptorSetBinder(
298     const PipelineLayout& pipelineLayout, const array_view<const RenderHandle> handles,
299     const array_view<const DescriptorSetLayoutBindings> descriptorSetsLayoutBindings)
300 {
301     return IPipelineDescriptorSetBinder::Ptr { new PipelineDescriptorSetBinder(
302         pipelineLayout, handles, descriptorSetsLayoutBindings) };
303 }
304 
GetCpuDescriptorSetData(const RenderHandle handle) const305 DescriptorSetLayoutBindingResources NodeContextDescriptorSetManager::GetCpuDescriptorSetData(
306     const RenderHandle handle) const
307 {
308     const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle);
309     const uint32_t oneFrameDescBit = RenderHandleUtil::GetAdditionalData(handle);
310     const uint32_t descSetIdx = (oneFrameDescBit == ONE_FRAME_DESC_SET_BIT) ? DESCRIPTOR_SET_INDEX_TYPE_ONE_FRAME
311                                                                             : DESCRIPTOR_SET_INDEX_TYPE_STATIC;
312     const auto& cpuDescSets = cpuDescriptorSets_[descSetIdx];
313     return GetCpuDescriptorSetDataImpl(arrayIndex, cpuDescSets);
314 }
315 
GetDynamicOffsetDescriptors(const RenderHandle handle) const316 DynamicOffsetDescriptors NodeContextDescriptorSetManager::GetDynamicOffsetDescriptors(const RenderHandle handle) const
317 {
318     const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle);
319     const uint32_t oneFrameDescBit = RenderHandleUtil::GetAdditionalData(handle);
320     const uint32_t descSetIdx = (oneFrameDescBit == ONE_FRAME_DESC_SET_BIT) ? DESCRIPTOR_SET_INDEX_TYPE_ONE_FRAME
321                                                                             : DESCRIPTOR_SET_INDEX_TYPE_STATIC;
322     const auto& cpuDescSets = cpuDescriptorSets_[descSetIdx];
323     return GetDynamicOffsetDescriptorsImpl(arrayIndex, cpuDescSets);
324 }
325 
HasDynamicBarrierResources(const RenderHandle handle) const326 bool NodeContextDescriptorSetManager::HasDynamicBarrierResources(const RenderHandle handle) const
327 {
328     const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle);
329     const uint32_t oneFrameDescBit = RenderHandleUtil::GetAdditionalData(handle);
330     const uint32_t descSetIdx = (oneFrameDescBit == ONE_FRAME_DESC_SET_BIT) ? DESCRIPTOR_SET_INDEX_TYPE_ONE_FRAME
331                                                                             : DESCRIPTOR_SET_INDEX_TYPE_STATIC;
332     const auto& cpuDescSets = cpuDescriptorSets_[descSetIdx];
333     return HasDynamicBarrierResourcesImpl(arrayIndex, cpuDescSets);
334 }
335 
GetDynamicOffsetDescriptorCount(const RenderHandle handle) const336 uint32_t NodeContextDescriptorSetManager::GetDynamicOffsetDescriptorCount(const RenderHandle handle) const
337 {
338     const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle);
339     const uint32_t oneFrameDescBit = RenderHandleUtil::GetAdditionalData(handle);
340     const uint32_t descSetIdx = (oneFrameDescBit == ONE_FRAME_DESC_SET_BIT) ? DESCRIPTOR_SET_INDEX_TYPE_ONE_FRAME
341                                                                             : DESCRIPTOR_SET_INDEX_TYPE_STATIC;
342     const auto& cpuDescSets = cpuDescriptorSets_[descSetIdx];
343     return GetDynamicOffsetDescriptorCountImpl(arrayIndex, cpuDescSets);
344 }
345 
HasPlatformBufferBindings(const RenderHandle handle) const346 bool NodeContextDescriptorSetManager::HasPlatformBufferBindings(const RenderHandle handle) const
347 {
348     const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle);
349     const uint32_t oneFrameDescBit = RenderHandleUtil::GetAdditionalData(handle);
350     const uint32_t descSetIdx = (oneFrameDescBit == ONE_FRAME_DESC_SET_BIT) ? DESCRIPTOR_SET_INDEX_TYPE_ONE_FRAME
351                                                                             : DESCRIPTOR_SET_INDEX_TYPE_STATIC;
352     const auto& cpuDescSets = cpuDescriptorSets_[descSetIdx];
353     return HasPlatformBufferBindingsImpl(arrayIndex, cpuDescSets);
354 }
355 
UpdateCpuDescriptorSet(const RenderHandle handle,const DescriptorSetLayoutBindingResources & bindingResources,const GpuQueue & gpuQueue)356 bool NodeContextDescriptorSetManager::UpdateCpuDescriptorSet(
357     const RenderHandle handle, const DescriptorSetLayoutBindingResources& bindingResources, const GpuQueue& gpuQueue)
358 {
359     const uint32_t arrayIndex = RenderHandleUtil::GetIndexPart(handle);
360     const uint32_t oneFrameDescBit = RenderHandleUtil::GetAdditionalData(handle);
361     const uint32_t descSetIdx = (oneFrameDescBit == ONE_FRAME_DESC_SET_BIT) ? DESCRIPTOR_SET_INDEX_TYPE_ONE_FRAME
362                                                                             : DESCRIPTOR_SET_INDEX_TYPE_STATIC;
363     auto& cpuDescSets = cpuDescriptorSets_[descSetIdx];
364     return UpdateCpuDescriptorSetImpl(arrayIndex, bindingResources, gpuQueue, cpuDescSets);
365 }
366 
UpdateCpuDescriptorSetImpl(const uint32_t index,const DescriptorSetLayoutBindingResources & bindingResources,const GpuQueue & gpuQueue,vector<CpuDescriptorSet> & cpuDescriptorSets)367 bool NodeContextDescriptorSetManager::UpdateCpuDescriptorSetImpl(const uint32_t index,
368     const DescriptorSetLayoutBindingResources& bindingResources, const GpuQueue& gpuQueue,
369     vector<CpuDescriptorSet>& cpuDescriptorSets)
370 {
371     bool valid = true;
372     if (index < static_cast<uint32_t>(cpuDescriptorSets.size())) {
373         auto& refCpuSet = cpuDescriptorSets[index];
374 #if (RENDER_VALIDATION_ENABLED == 1)
375         if (refCpuSet.bindings.size() != bindingResources.bindings.size()) {
376             PLUGIN_LOG_E("RENDER_VALIDATION: sizes must match; update all bindings always in a single set");
377         }
378 #endif
379 
380         refCpuSet.isDirty = true;
381         refCpuSet.hasDynamicBarrierResources = false;
382         refCpuSet.hasPlatformConversionBindings = false;
383         refCpuSet.hasImmutableSamplers = false;
384 
385         // NOTE: GPU queue patching could be moved to render graph
386         // copy from src to dst and check flags
387         valid = valid && CopyAndProcessBuffers(bindingResources, gpuQueue, refCpuSet);
388         valid = valid && CopyAndProcessImages(bindingResources, gpuQueue, refCpuSet);
389         // samplers don't have state and dynamic resources, but we check for immutable samplers
390         valid = valid && CopyAndProcessSamplers(bindingResources, refCpuSet);
391 
392         for (size_t idx = 0; idx < bindingResources.bindings.size(); ++idx) {
393             const DescriptorSetLayoutBindingResource& refBinding = bindingResources.bindings[idx];
394             // the actual binding index is not important here (refBinding.binding.binding)
395             PLUGIN_ASSERT(idx < refCpuSet.bindings.size());
396             DescriptorSetLayoutBindingResource& refCpuBinding = refCpuSet.bindings[idx];
397             refCpuBinding.resourceIndex = refBinding.resourceIndex;
398         }
399         hasPlatformConversionBindings_ = (hasPlatformConversionBindings_ || refCpuSet.hasPlatformConversionBindings);
400 
401         // update platform data
402         UpdateCpuDescriptorSetPlatform(bindingResources);
403     } else {
404 #if (RENDER_VALIDATION_ENABLED == 1)
405         PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to UpdateCpuDescriptorSet");
406 #endif
407     }
408     return valid;
409 }
410 
GetCpuDescriptorSetDataImpl(const uint32_t index,const vector<CpuDescriptorSet> & cpuDescriptorSet) const411 DescriptorSetLayoutBindingResources NodeContextDescriptorSetManager::GetCpuDescriptorSetDataImpl(
412     const uint32_t index, const vector<CpuDescriptorSet>& cpuDescriptorSet) const
413 {
414     if (index < cpuDescriptorSet.size()) {
415         return DescriptorSetLayoutBindingResources {
416             cpuDescriptorSet[index].bindings,
417             cpuDescriptorSet[index].buffers,
418             cpuDescriptorSet[index].images,
419             cpuDescriptorSet[index].samplers,
420         };
421     } else {
422 #if (RENDER_VALIDATION_ENABLED == 1)
423         PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to GetCpuDescriptorSetData");
424 #endif
425         return {};
426     }
427 }
428 
GetDynamicOffsetDescriptorsImpl(const uint32_t index,const vector<CpuDescriptorSet> & cpuDescriptorSet) const429 DynamicOffsetDescriptors NodeContextDescriptorSetManager::GetDynamicOffsetDescriptorsImpl(
430     const uint32_t index, const vector<CpuDescriptorSet>& cpuDescriptorSet) const
431 {
432     if (index < cpuDescriptorSet.size()) {
433         return DynamicOffsetDescriptors {
434             array_view<const RenderHandle>(cpuDescriptorSet[index].dynamicOffsetDescriptors.data(),
435                 cpuDescriptorSet[index].dynamicOffsetDescriptors.size()),
436         };
437     } else {
438 #if (RENDER_VALIDATION_ENABLED == 1)
439         PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to GetDynamicOffsetDescriptors");
440 #endif
441         return {};
442     }
443 }
444 
HasDynamicBarrierResourcesImpl(const uint32_t index,const vector<CpuDescriptorSet> & cpuDescriptorSet) const445 bool NodeContextDescriptorSetManager::HasDynamicBarrierResourcesImpl(
446     const uint32_t index, const vector<CpuDescriptorSet>& cpuDescriptorSet) const
447 {
448     if (index < static_cast<uint32_t>(cpuDescriptorSet.size())) {
449         return cpuDescriptorSet[index].hasDynamicBarrierResources;
450     } else {
451 #if (RENDER_VALIDATION_ENABLED == 1)
452         PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to HasDynamicBarrierResources");
453 #endif
454         return false;
455     }
456 }
457 
HasPlatformBufferBindingsImpl(const uint32_t index,const vector<CpuDescriptorSet> & cpuDescriptorSet) const458 bool NodeContextDescriptorSetManager::HasPlatformBufferBindingsImpl(
459     const uint32_t index, const vector<CpuDescriptorSet>& cpuDescriptorSet) const
460 {
461     if (index < static_cast<uint32_t>(cpuDescriptorSet.size())) {
462         return cpuDescriptorSet[index].hasPlatformConversionBindings;
463     } else {
464 #if (RENDER_VALIDATION_ENABLED == 1)
465         PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to HasPlatformBufferBindingsImpl");
466 #endif
467         return false;
468     }
469 }
470 
GetDynamicOffsetDescriptorCountImpl(const uint32_t index,const vector<CpuDescriptorSet> & cpuDescriptorSet) const471 uint32_t NodeContextDescriptorSetManager::GetDynamicOffsetDescriptorCountImpl(
472     const uint32_t index, const vector<CpuDescriptorSet>& cpuDescriptorSet) const
473 {
474     if (index < static_cast<uint32_t>(cpuDescriptorSet.size())) {
475         return static_cast<uint32_t>(cpuDescriptorSet[index].dynamicOffsetDescriptors.size());
476     } else {
477 #if (RENDER_VALIDATION_ENABLED == 1)
478         PLUGIN_LOG_E("RENDER_VALIDATION: invalid handle to GetDynamicOffsetDescriptorCount");
479 #endif
480         return 0;
481     }
482 }
483 
484 #if ((RENDER_VALIDATION_ENABLED == 1) || (RENDER_VULKAN_VALIDATION_ENABLED == 1))
SetValidationDebugName(const string_view debugName)485 void NodeContextDescriptorSetManager::SetValidationDebugName(const string_view debugName)
486 {
487     debugName_ = debugName;
488 }
489 #endif
490 RENDER_END_NAMESPACE()
491