• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 "render_node_parser_util.h"
17 
18 #include <cstdint>
19 
20 #include <base/containers/fixed_string.h>
21 #include <base/containers/string.h>
22 #include <render/device/pipeline_state_desc.h>
23 #include <render/namespace.h>
24 #include <render/render_data_structures.h>
25 
26 #include "device/gpu_resource_manager.h"
27 #include "device/shader_manager.h"
28 #include "loader/json_format_serialization.h"
29 #include "loader/json_util.h"
30 
31 using namespace BASE_NS;
32 using namespace CORE_NS;
33 
34 RENDER_BEGIN_NAMESPACE()
35 // clang-format off
36 CORE_JSON_SERIALIZE_ENUM(RenderSlotSortType,
37     {
38         { RenderSlotSortType::NONE, "none" },
39         { RenderSlotSortType::FRONT_TO_BACK, "front_to_back" },
40         { RenderSlotSortType::BACK_TO_FRONT, "back_to_front" },
41         { RenderSlotSortType::BY_MATERIAL, "by_material" },
42     })
43 
44 CORE_JSON_SERIALIZE_ENUM(RenderSlotCullType,
45     {
46         { RenderSlotCullType::NONE, "none" },
47         { RenderSlotCullType::VIEW_FRUSTUM_CULL, "view_frustum_cull" },
48     })
49 
50 CORE_JSON_SERIALIZE_ENUM(GpuQueue::QueueType,
51     { { GpuQueue::QueueType::UNDEFINED, nullptr }, { GpuQueue::QueueType::GRAPHICS, "graphics" },
52         { GpuQueue::QueueType::COMPUTE, "compute" }, { GpuQueue::QueueType::TRANSFER, "transfer" } })
53 
54 CORE_JSON_SERIALIZE_ENUM(DescriptorType,
55     {
56         { DescriptorType::CORE_DESCRIPTOR_TYPE_SAMPLER, "sampler" },
57         { DescriptorType::CORE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler" },
58         { DescriptorType::CORE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, "sampled_image" },
59         { DescriptorType::CORE_DESCRIPTOR_TYPE_STORAGE_IMAGE, "storage_image" },
60         { DescriptorType::CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "uniform_texel_buffer" },
61         { DescriptorType::CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER, "storage_texel_buffer" },
62         { DescriptorType::CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "uniform_buffer" },
63         { DescriptorType::CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER, "storage_buffer" },
64         { DescriptorType::CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, "uniform_buffer_dynamic" },
65         { DescriptorType::CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, "storage_buffer_dynamic" },
66         { DescriptorType::CORE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, "input_attachment" },
67         { DescriptorType::CORE_DESCRIPTOR_TYPE_MAX_ENUM, nullptr },
68     })
69 
70 CORE_JSON_SERIALIZE_ENUM(AttachmentLoadOp,
71     {
72         { AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_LOAD, "load" },
73         { AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_CLEAR, "clear" },
74         { AttachmentLoadOp::CORE_ATTACHMENT_LOAD_OP_DONT_CARE, "dont_care" },
75     })
76 
77 CORE_JSON_SERIALIZE_ENUM(AttachmentStoreOp,
78     {
79         { AttachmentStoreOp::CORE_ATTACHMENT_STORE_OP_STORE, "store" },
80         { AttachmentStoreOp::CORE_ATTACHMENT_STORE_OP_DONT_CARE, "dont_care" },
81     })
82 
83 CORE_JSON_SERIALIZE_ENUM(ImageType,
84     {
85         { ImageType::CORE_IMAGE_TYPE_1D, "1d" },
86         { ImageType::CORE_IMAGE_TYPE_2D, "2d" },
87         { ImageType::CORE_IMAGE_TYPE_3D, "3d" },
88         { ImageType::CORE_IMAGE_TYPE_MAX_ENUM, nullptr },
89     })
90 
91 CORE_JSON_SERIALIZE_ENUM(ImageViewType,
92     { { ImageViewType::CORE_IMAGE_VIEW_TYPE_1D, "1d" }, { ImageViewType::CORE_IMAGE_VIEW_TYPE_2D, "2d" },
93         { ImageViewType::CORE_IMAGE_VIEW_TYPE_3D, "3d" }, { ImageViewType::CORE_IMAGE_VIEW_TYPE_CUBE, "cube" },
94         { ImageViewType::CORE_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array" },
95         { ImageViewType::CORE_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array" },
96         { ImageViewType::CORE_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array" },
97         { ImageViewType::CORE_IMAGE_VIEW_TYPE_MAX_ENUM, nullptr } })
98 
99 CORE_JSON_SERIALIZE_ENUM(ImageTiling,
100     {
101         { ImageTiling::CORE_IMAGE_TILING_OPTIMAL, "optimal" },
102         { ImageTiling::CORE_IMAGE_TILING_LINEAR, "linear" },
103         { ImageTiling::CORE_IMAGE_TILING_MAX_ENUM, nullptr },
104     })
105 
106 CORE_JSON_SERIALIZE_ENUM(ImageUsageFlagBits,
107     {
108         { ImageUsageFlagBits::CORE_IMAGE_USAGE_TRANSFER_SRC_BIT, "transfer_src" },
109         { ImageUsageFlagBits::CORE_IMAGE_USAGE_TRANSFER_DST_BIT, "transfer_dst" },
110         { ImageUsageFlagBits::CORE_IMAGE_USAGE_SAMPLED_BIT, "sampled" },
111         { ImageUsageFlagBits::CORE_IMAGE_USAGE_STORAGE_BIT, "storage" },
112         { ImageUsageFlagBits::CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, "color_attachment" },
113         { ImageUsageFlagBits::CORE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, "depth_stencil_attachment" },
114         { ImageUsageFlagBits::CORE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, "transient_attachment" },
115         { ImageUsageFlagBits::CORE_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, "input_attachment" },
116         { (ImageUsageFlagBits)0, nullptr },
117     })
118 
119 CORE_JSON_SERIALIZE_ENUM(ImageCreateFlagBits,
120     {
121         { ImageCreateFlagBits::CORE_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, "cube_compatible" },
122         { ImageCreateFlagBits::CORE_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, "2d_array_compatible" },
123         { (ImageCreateFlagBits)0, nullptr },
124     })
125 
126 CORE_JSON_SERIALIZE_ENUM(EngineImageCreationFlagBits,
127     {
128         { EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, "dynamic_barriers" },
129         { EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_RESET_STATE_ON_FRAME_BORDERS,
130             "reset_state_on_frame_borders" },
131         { EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_GENERATE_MIPS, "generate_mips" },
132         { (EngineImageCreationFlagBits)0, nullptr },
133     })
134 
135 CORE_JSON_SERIALIZE_ENUM(SampleCountFlagBits,
136     {
137         { SampleCountFlagBits::CORE_SAMPLE_COUNT_1_BIT, "1bit" },
138         { SampleCountFlagBits::CORE_SAMPLE_COUNT_2_BIT, "2bit" },
139         { SampleCountFlagBits::CORE_SAMPLE_COUNT_4_BIT, "4bit" },
140         { SampleCountFlagBits::CORE_SAMPLE_COUNT_8_BIT, "8bit" },
141         { SampleCountFlagBits::CORE_SAMPLE_COUNT_16_BIT, "16bit" },
142         { SampleCountFlagBits::CORE_SAMPLE_COUNT_32_BIT, "32bit" },
143         { SampleCountFlagBits::CORE_SAMPLE_COUNT_64_BIT, "64bit" },
144         { (SampleCountFlagBits)0, nullptr },
145     })
146 
147 CORE_JSON_SERIALIZE_ENUM(MemoryPropertyFlagBits,
148     {
149         { MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, "device_local" },
150         { MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_HOST_VISIBLE_BIT, "host_visible" },
151         { MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_HOST_COHERENT_BIT, "host_coherent" },
152         { MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_HOST_CACHED_BIT, "host_cached" },
153         { MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, "lazily_allocated" },
154         { MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_PROTECTED_BIT, "protected" },
155         { MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM, nullptr },
156     })
157 
158 CORE_JSON_SERIALIZE_ENUM(EngineBufferCreationFlagBits,
159     {
160         { EngineBufferCreationFlagBits::CORE_ENGINE_BUFFER_CREATION_DYNAMIC_BARRIERS, "dynamic_barriers" },
161         { (EngineBufferCreationFlagBits)0, nullptr },
162     })
163 
164 CORE_JSON_SERIALIZE_ENUM(BufferUsageFlagBits,
165     {
166         { BufferUsageFlagBits::CORE_BUFFER_USAGE_TRANSFER_SRC_BIT, "transfer_src" },
167         { BufferUsageFlagBits::CORE_BUFFER_USAGE_TRANSFER_DST_BIT, "transfer_dst" },
168         { BufferUsageFlagBits::CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT, "uniform" },
169         { BufferUsageFlagBits::CORE_BUFFER_USAGE_STORAGE_BUFFER_BIT, "storage" },
170         { BufferUsageFlagBits::CORE_BUFFER_USAGE_INDEX_BUFFER_BIT, "index" },
171         { BufferUsageFlagBits::CORE_BUFFER_USAGE_VERTEX_BUFFER_BIT, "vertex" },
172         { BufferUsageFlagBits::CORE_BUFFER_USAGE_INDIRECT_BUFFER_BIT, "indirect" },
173     })
174 
175 CORE_JSON_SERIALIZE_ENUM(RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits,
176     {
177         { RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits::FORMAT, "format" },
178         { RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits::SIZE, "size" },
179         { RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits::MIP_COUNT, "mipCount" },
180         { RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits::LAYER_COUNT, "layerCount" },
181         { RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits::SAMPLES, "samples" },
182         { RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits::MAX_DEPENDENCY_FLAG_ENUM, nullptr },
183     })
184 
185 CORE_JSON_SERIALIZE_ENUM(RenderNodeGraphResourceLocationType,
186     {
187         { RenderNodeGraphResourceLocationType::DEFAULT, "default" },
188         { RenderNodeGraphResourceLocationType::FROM_RENDER_GRAPH_INPUT, "from_render_graph_input" },
189         { RenderNodeGraphResourceLocationType::FROM_RENDER_GRAPH_OUTPUT, "from_render_graph_output" },
190         { RenderNodeGraphResourceLocationType::FROM_PREVIOUS_RENDER_NODE_OUTPUT, "from_previous_render_node_output" },
191         { RenderNodeGraphResourceLocationType::FROM_NAMED_RENDER_NODE_OUTPUT, "from_named_render_node_output" },
192     })
193 
194 CORE_JSON_SERIALIZE_ENUM(ResolveModeFlagBits,
195     {
196         { ResolveModeFlagBits::CORE_RESOLVE_MODE_NONE, "none" },
197         { ResolveModeFlagBits::CORE_RESOLVE_MODE_SAMPLE_ZERO_BIT, "sample_zero" },
198         { ResolveModeFlagBits::CORE_RESOLVE_MODE_AVERAGE_BIT, "average" },
199         { ResolveModeFlagBits::CORE_RESOLVE_MODE_MIN_BIT, "min" },
200         { ResolveModeFlagBits::CORE_RESOLVE_MODE_MAX_BIT, "max" },
201     })
202 // clang-format on
FromJson(const json::value & jsonData,JsonContext<RenderNodeGraphInputs::Resource> & context)203 inline void FromJson(const json::value& jsonData, JsonContext<RenderNodeGraphInputs::Resource>& context)
204 {
205     SafeGetJsonValue(jsonData, "set", context.error, context.data.set);
206     SafeGetJsonValue(jsonData, "binding", context.error, context.data.binding);
207     SafeGetJsonValue(jsonData, "name", context.error, context.data.name);
208     SafeGetJsonEnum(jsonData, "resourceLocation", context.error, context.data.resourceLocation);
209     SafeGetJsonValue(jsonData, "resourceIndex", context.error, context.data.resourceIndex);
210     SafeGetJsonValue(jsonData, "nodeName", context.error, context.data.nodeName);
211     SafeGetJsonValue(jsonData, "usageName", context.error, context.data.usageName);
212 }
213 
FromJson(const json::value & jsonData,JsonContext<RenderNodeGraphInputs::Attachment> & context)214 inline void FromJson(const json::value& jsonData, JsonContext<RenderNodeGraphInputs::Attachment>& context)
215 {
216     SafeGetJsonEnum(jsonData, "loadOp", context.error, context.data.loadOp);
217     SafeGetJsonEnum(jsonData, "storeOp", context.error, context.data.storeOp);
218     SafeGetJsonEnum(jsonData, "stencilLoadOp", context.error, context.data.stencilLoadOp);
219     SafeGetJsonEnum(jsonData, "stencilStoreOp", context.error, context.data.stencilStoreOp);
220     if (auto const pos = jsonData.find("clearColor"); pos) {
221         if (pos->is_array() && pos->array_.size() == 4) {
222             FromJson(*pos, context.data.clearValue.color.float32);
223         } else {
224             const auto asString = to_string(*pos);
225             context.error +=
226                 "clearColor must be an array of length 4 : (" + string_view(asString.data(), asString.size()) + ")\n";
227         }
228     }
229     if (auto const pos = jsonData.find("clearDepth"); pos) {
230         if (pos->is_array() && pos->array_.size() == 2) {
231             if (pos->array_[0].is_number()) {
232                 context.data.clearValue.depthStencil.depth = pos->array_[0].as_number<float>();
233             } else {
234                 const auto asString = to_string(*pos);
235                 context.error += "depthAttachment.clearValue[0] must be a float: (" +
236                                  string_view(asString.data(), asString.size()) + ")\n";
237             }
238 
239             if (pos->array_[1].is_number()) {
240                 context.data.clearValue.depthStencil.stencil = pos->array_[1].as_number<uint32_t>();
241             } else {
242                 const auto asString = to_string(*pos);
243                 context.error += "depthAttachment.clearValue[1] must be an uint: (" +
244                                  string_view(asString.data(), asString.size()) + ")\n";
245             }
246         } else {
247             const auto asString = to_string(*pos);
248             context.error += "Failed to read depthAttachment.clearValue, invalid datatype: (" +
249                              string_view(asString.data(), asString.size()) + ")\n";
250         }
251     }
252     SafeGetJsonValue(jsonData, "name", context.error, context.data.name);
253     SafeGetJsonEnum(jsonData, "resourceLocation", context.error, context.data.resourceLocation);
254     SafeGetJsonValue(jsonData, "resourceIndex", context.error, context.data.resourceIndex);
255     SafeGetJsonValue(jsonData, "nodeName", context.error, context.data.nodeName);
256 }
257 
FromJson(const json::value & jsonData,JsonContext<RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc> & context)258 inline void FromJson(
259     const json::value& jsonData, JsonContext<RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc>& context)
260 {
261     SafeGetJsonValue(jsonData, "name", context.error, context.data.name);
262     SafeGetJsonValue(jsonData, "shareName", context.error, context.data.shareName);
263     SafeGetJsonValue(jsonData, "dependencyImageName", context.error, context.data.dependencyImageName);
264 
265     SafeGetJsonEnum(jsonData, "imageType", context.error, context.data.desc.imageType);
266     SafeGetJsonEnum(jsonData, "imageViewType", context.error, context.data.desc.imageViewType);
267     SafeGetJsonEnum(jsonData, "format", context.error, context.data.desc.format);
268     SafeGetJsonEnum(jsonData, "imageTiling", context.error, context.data.desc.imageTiling);
269     SafeGetJsonBitfield<ImageUsageFlagBits>(jsonData, "usageFlags", context.error, context.data.desc.usageFlags);
270     SafeGetJsonBitfield<MemoryPropertyFlagBits>(
271         jsonData, "memoryPropertyFlags", context.error, context.data.desc.memoryPropertyFlags);
272     SafeGetJsonBitfield<ImageCreateFlagBits>(jsonData, "createFlags", context.error, context.data.desc.createFlags);
273     SafeGetJsonBitfield<EngineImageCreationFlagBits>(
274         jsonData, "engineCreationFlags", context.error, context.data.desc.engineCreationFlags);
275     SafeGetJsonValue(jsonData, "width", context.error, context.data.desc.width);
276     SafeGetJsonValue(jsonData, "height", context.error, context.data.desc.height);
277     SafeGetJsonValue(jsonData, "depth", context.error, context.data.desc.depth);
278     SafeGetJsonValue(jsonData, "mipCount", context.error, context.data.desc.mipCount);
279     SafeGetJsonValue(jsonData, "layerCount", context.error, context.data.desc.layerCount);
280     SafeGetJsonBitfield<SampleCountFlagBits>(
281         jsonData, "sampleCountFlags", context.error, context.data.desc.sampleCountFlags);
282 
283     SafeGetJsonBitfield<RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits>(
284         jsonData, "dependencyFlags", context.error, context.data.dependencyFlags);
285     SafeGetJsonValue(jsonData, "dependencySizeScale", context.error, context.data.dependencySizeScale);
286 
287     if ((context.data.desc.format == Format::BASE_FORMAT_UNDEFINED) && context.data.dependencyImageName.empty()) {
288         context.error += "undefined gpu image desc format\n";
289     }
290 }
291 
FromJson(const json::value & jsonData,JsonContext<RenderNodeGraphInputs::RenderNodeGraphGpuBufferDesc> & context)292 inline void FromJson(
293     const json::value& jsonData, JsonContext<RenderNodeGraphInputs::RenderNodeGraphGpuBufferDesc>& context)
294 {
295     SafeGetJsonValue(jsonData, "name", context.error, context.data.name);
296     SafeGetJsonValue(jsonData, "shareName", context.error, context.data.shareName);
297     SafeGetJsonValue(jsonData, "dependencyBufferName", context.error, context.data.dependencyBufferName);
298 
299     SafeGetJsonBitfield<BufferUsageFlagBits>(jsonData, "usageFlags", context.error, context.data.desc.usageFlags);
300     SafeGetJsonBitfield<EngineBufferCreationFlagBits>(
301         jsonData, "engineCreationFlags", context.error, context.data.desc.engineCreationFlags);
302     SafeGetJsonBitfield<MemoryPropertyFlagBits>(
303         jsonData, "memoryPropertyFlags", context.error, context.data.desc.memoryPropertyFlags);
304     SafeGetJsonValue(jsonData, "byteSize", context.error, context.data.desc.byteSize);
305 }
306 
FromJson(const json::value & jsonData,JsonContext<DescriptorCounts::TypedCount> & context)307 inline void FromJson(const json::value& jsonData, JsonContext<DescriptorCounts::TypedCount>& context)
308 {
309     SafeGetJsonEnum(jsonData, "type", context.error, context.data.type);
310     SafeGetJsonValue(jsonData, "count", context.error, context.data.count);
311 }
312 
313 namespace {
314 struct LoadResult {
315     string error;
316 };
317 
ParseRenderpass(const string_view name,const json::value & node,RenderNodeGraphInputs::InputRenderPass & renderPass,LoadResult & result)318 void ParseRenderpass(const string_view name, const json::value& node,
319     RenderNodeGraphInputs::InputRenderPass& renderPass, LoadResult& result)
320 {
321     if (auto const rp = node.find(name); rp) {
322         ParseArray<decltype(renderPass.attachments)::value_type>(*rp, "attachments", renderPass.attachments, result);
323         SafeGetJsonValue(*rp, "subpassIndex", result.error, renderPass.subpassIndex);
324         SafeGetJsonValue(*rp, "subpassCount", result.error, renderPass.subpassCount);
325 #if (RENDER_VALIDATION_ENABLED == 1)
326         if (renderPass.subpassIndex >= renderPass.subpassCount) {
327             PLUGIN_LOG_E("RENDER_VALIDATION: render pass subpass index must be smaller than subpass index");
328         }
329 #endif
330         if (auto const sp = rp->find("subpass"); sp) {
331             SafeGetJsonValue(*sp, "depthAttachmentIndex", result.error, renderPass.depthAttachmentIndex);
332             SafeGetJsonValue(*sp, "depthResolveAttachmentIndex", result.error, renderPass.depthResolveAttachmentIndex);
333             SafeGetJsonEnum(*sp, "depthResolveModeFlagBit", result.error, renderPass.depthResolveModeFlagBit);
334             SafeGetJsonEnum(*sp, "stencilResolveModeFlagBit", result.error, renderPass.stencilResolveModeFlagBit);
335 #if (RENDER_VALIDATION_ENABLED == 1)
336             if ((renderPass.depthResolveAttachmentIndex != ~0u) &&
337                 ((renderPass.depthResolveModeFlagBit | renderPass.stencilResolveModeFlagBit) == 0)) {
338                 PLUGIN_LOG_W("RENDER_VALIDATION: depth resolve mode flags not set for depth resolve image");
339             }
340 #endif
341 
342             const auto getAttachmentIndices = [](const char* attachmentName, const auto& subpass,
343                                                   auto& attachmentVector) {
344                 if (auto const iIter = subpass.find(attachmentName); iIter) {
345                     if (iIter->is_array()) {
346                         std::transform(iIter->array_.begin(), iIter->array_.end(), std::back_inserter(attachmentVector),
347                             [](const json::value& value) {
348                                 if (value.is_number()) {
349                                     return value.template as_number<uint32_t>();
350                                 }
351                                 return 0u;
352                             });
353                     } else {
354                         attachmentVector = { iIter->template as_number<uint32_t>() };
355                     }
356                 }
357             };
358 
359             getAttachmentIndices("inputAttachmentIndices", *sp, renderPass.inputAttachmentIndices);
360             getAttachmentIndices("colorAttachmentIndices", *sp, renderPass.colorAttachmentIndices);
361             getAttachmentIndices("resolveAttachmentIndices", *sp, renderPass.resolveAttachmentIndices);
362         }
363     }
364 }
365 
ParseResources(const string_view name,const json::value & node,RenderNodeGraphInputs::InputResources & resources,LoadResult & result)366 void ParseResources(const string_view name, const json::value& node, RenderNodeGraphInputs::InputResources& resources,
367     LoadResult& result)
368 {
369     if (auto const res = node.find("resources"); res) {
370         ParseArray<decltype(resources.buffers)::value_type>(*res, "buffers", resources.buffers, result);
371         ParseArray<decltype(resources.images)::value_type>(*res, "images", resources.images, result);
372         ParseArray<decltype(resources.samplers)::value_type>(*res, "samplers", resources.samplers, result);
373 
374         ParseArray<decltype(resources.customInputBuffers)::value_type>(
375             *res, "customInputBuffers", resources.customInputBuffers, result);
376         ParseArray<decltype(resources.customOutputBuffers)::value_type>(
377             *res, "customOutputBuffers", resources.customOutputBuffers, result);
378 
379         ParseArray<decltype(resources.customInputImages)::value_type>(
380             *res, "customInputImages", resources.customInputImages, result);
381         ParseArray<decltype(resources.customOutputImages)::value_type>(
382             *res, "customOutputImages", resources.customOutputImages, result);
383     }
384 }
385 } // namespace
386 
RenderNodeParserUtil(const CreateInfo & createInfo)387 RenderNodeParserUtil::RenderNodeParserUtil(const CreateInfo& createInfo) {}
388 
389 RenderNodeParserUtil::~RenderNodeParserUtil() = default;
390 
GetUintValue(const json::value & jsonValue,const string_view name) const391 uint64_t RenderNodeParserUtil::GetUintValue(const json::value& jsonValue, const string_view name) const
392 {
393     uint64_t val = std::numeric_limits<uint64_t>::max();
394     LoadResult result;
395     SafeGetJsonValue(jsonValue, name, result.error, val);
396     if (!result.error.empty()) {
397         PLUGIN_LOG_W("GetUintValue: %s", result.error.c_str());
398     }
399     return val;
400 }
401 
GetIntValue(const json::value & jsonValue,const string_view name) const402 int64_t RenderNodeParserUtil::GetIntValue(const json::value& jsonValue, const string_view name) const
403 {
404     int64_t val = std::numeric_limits<int64_t>::max();
405     LoadResult result;
406     SafeGetJsonValue(jsonValue, name, result.error, val);
407     if (!result.error.empty()) {
408         PLUGIN_LOG_W("GetIntValue: %s", result.error.c_str());
409     }
410     return val;
411 }
412 
GetFloatValue(const json::value & jsonValue,const string_view name) const413 float RenderNodeParserUtil::GetFloatValue(const json::value& jsonValue, const string_view name) const
414 {
415     float val = std::numeric_limits<float>::max();
416     LoadResult result;
417     SafeGetJsonValue(jsonValue, name, result.error, val);
418     if (!result.error.empty()) {
419         PLUGIN_LOG_W("GetFloatValue: %s", result.error.c_str());
420     }
421     return val;
422 }
423 
GetStringValue(const json::value & jsonValue,const string_view name) const424 string RenderNodeParserUtil::GetStringValue(const json::value& jsonValue, const string_view name) const
425 {
426     string parsedString;
427     LoadResult result;
428     SafeGetJsonValue(jsonValue, name, result.error, parsedString);
429     if (!result.error.empty()) {
430         PLUGIN_LOG_W("GetStringValue: %s", result.error.c_str());
431     }
432     return parsedString;
433 }
434 
GetInputRenderPass(const json::value & jsonValue,const string_view name) const435 RenderNodeGraphInputs::InputRenderPass RenderNodeParserUtil::GetInputRenderPass(
436     const json::value& jsonValue, const string_view name) const
437 {
438     LoadResult result;
439     RenderNodeGraphInputs::InputRenderPass renderPass;
440     ParseRenderpass(name, jsonValue, renderPass, result);
441     if (!result.error.empty()) {
442         PLUGIN_LOG_W("GetInputRenderPass: %s", result.error.c_str());
443     }
444     return renderPass;
445 }
446 
GetInputResources(const json::value & jsonValue,const string_view name) const447 RenderNodeGraphInputs::InputResources RenderNodeParserUtil::GetInputResources(
448     const json::value& jsonValue, const string_view name) const
449 {
450     LoadResult result;
451     RenderNodeGraphInputs::InputResources resources;
452     ParseResources(name, jsonValue, resources, result);
453     if (!result.error.empty()) {
454         PLUGIN_LOG_W("GetInputResources: %s", result.error.c_str());
455     }
456     return resources;
457 }
458 
GetRenderDataStore(const json::value & jsonValue,const string_view name) const459 RenderNodeGraphInputs::RenderDataStore RenderNodeParserUtil::GetRenderDataStore(
460     const json::value& jsonValue, const string_view name) const
461 {
462     LoadResult result;
463     RenderNodeGraphInputs::RenderDataStore renderDataStore;
464     if (auto const dataStore = jsonValue.find("renderDataStore"); dataStore) {
465         SafeGetJsonValue(*dataStore, "dataStoreName", result.error, renderDataStore.dataStoreName);
466         SafeGetJsonValue(*dataStore, "typeName", result.error, renderDataStore.typeName);
467         SafeGetJsonValue(*dataStore, "configurationName", result.error, renderDataStore.configurationName);
468     }
469     if (!result.error.empty()) {
470         PLUGIN_LOG_W("GetRenderDataStore: %s", result.error.c_str());
471     }
472     return renderDataStore;
473 }
474 
GetGpuImageDescs(const json::value & jsonValue,const string_view name) const475 vector<RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc> RenderNodeParserUtil::GetGpuImageDescs(
476     const json::value& jsonValue, const string_view name) const
477 {
478     LoadResult result;
479     vector<RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc> resources;
480     if (const auto ref = jsonValue.find(name); ref) {
481         if (ref->is_array()) {
482             ParseArray<decltype(resources)::value_type>(jsonValue, name.data(), resources, result);
483         } else {
484             result.error += "expecting array";
485         }
486     }
487     if (!result.error.empty()) {
488         PLUGIN_LOG_W("GetGpuImageDescs: %s", result.error.c_str());
489     }
490     return resources;
491 }
492 
GetGpuBufferDescs(const json::value & jsonValue,const string_view name) const493 vector<RenderNodeGraphInputs::RenderNodeGraphGpuBufferDesc> RenderNodeParserUtil::GetGpuBufferDescs(
494     const json::value& jsonValue, const string_view name) const
495 {
496     LoadResult result;
497     vector<RenderNodeGraphInputs::RenderNodeGraphGpuBufferDesc> resources;
498     if (const auto ref = jsonValue.find(name); ref) {
499         if (ref->is_array()) {
500             ParseArray<decltype(resources)::value_type>(jsonValue, name.data(), resources, result);
501         } else {
502             result.error += "expecting array";
503         }
504     }
505     if (!result.error.empty()) {
506         PLUGIN_LOG_W("GetGpuBufferDescs: %s", result.error.c_str());
507     }
508     return resources;
509 }
510 
GetRenderSlotSortType(const json::value & jsonValue,const string_view name) const511 RenderSlotSortType RenderNodeParserUtil::GetRenderSlotSortType(
512     const json::value& jsonValue, const string_view name) const
513 {
514     LoadResult result;
515     RenderSlotSortType sortType;
516     SafeGetJsonEnum(jsonValue, "renderSlotSortType", result.error, sortType);
517     if (!result.error.empty()) {
518         PLUGIN_LOG_W("GetRenderSlotSortType: %s", result.error.c_str());
519     }
520     return sortType;
521 }
522 
GetRenderSlotCullType(const json::value & jsonValue,const string_view name) const523 RenderSlotCullType RenderNodeParserUtil::GetRenderSlotCullType(
524     const json::value& jsonValue, const string_view name) const
525 {
526     LoadResult result;
527     RenderSlotCullType cullType;
528     SafeGetJsonEnum(jsonValue, "renderSlotCullType", result.error, cullType);
529     if (!result.error.empty()) {
530         PLUGIN_LOG_W("GetRenderSlotCullType: %s", result.error.c_str());
531     }
532     return cullType;
533 }
534 RENDER_END_NAMESPACE()
535