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