• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "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 RENDER_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 RENDER_JSON_SERIALIZE_ENUM(RenderSlotCullType,
45     {
46         { RenderSlotCullType::NONE, "none" },
47         { RenderSlotCullType::VIEW_FRUSTUM_CULL, "view_frustum_cull" },
48     })
49 
50 RENDER_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 RENDER_JSON_SERIALIZE_ENUM(DescriptorType,
55     {
56         { DescriptorType::CORE_DESCRIPTOR_TYPE_MAX_ENUM, nullptr },
57         { DescriptorType::CORE_DESCRIPTOR_TYPE_SAMPLER, "sampler" },
58         { DescriptorType::CORE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler" },
59         { DescriptorType::CORE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, "sampled_image" },
60         { DescriptorType::CORE_DESCRIPTOR_TYPE_STORAGE_IMAGE, "storage_image" },
61         { DescriptorType::CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "uniform_texel_buffer" },
62         { DescriptorType::CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER, "storage_texel_buffer" },
63         { DescriptorType::CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "uniform_buffer" },
64         { DescriptorType::CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER, "storage_buffer" },
65         { DescriptorType::CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, "uniform_buffer_dynamic" },
66         { DescriptorType::CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, "storage_buffer_dynamic" },
67         { DescriptorType::CORE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, "input_attachment" },
68     })
69 
70 RENDER_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 RENDER_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 RENDER_JSON_SERIALIZE_ENUM(ImageType,
84     {
85         { ImageType::CORE_IMAGE_TYPE_2D, nullptr }, // default
86         { ImageType::CORE_IMAGE_TYPE_1D, "1d" },
87         { ImageType::CORE_IMAGE_TYPE_2D, "2d" },
88         { ImageType::CORE_IMAGE_TYPE_3D, "3d" },
89     })
90 
91 RENDER_JSON_SERIALIZE_ENUM(ImageViewType,
92     {
93         { ImageViewType::CORE_IMAGE_VIEW_TYPE_2D, nullptr }, // default
94         { ImageViewType::CORE_IMAGE_VIEW_TYPE_1D, "1d" }, { ImageViewType::CORE_IMAGE_VIEW_TYPE_2D, "2d" },
95         { ImageViewType::CORE_IMAGE_VIEW_TYPE_3D, "3d" }, { ImageViewType::CORE_IMAGE_VIEW_TYPE_CUBE, "cube" },
96         { ImageViewType::CORE_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array" },
97         { ImageViewType::CORE_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array" },
98         { ImageViewType::CORE_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array" },
99     })
100 
101 RENDER_JSON_SERIALIZE_ENUM(ImageTiling,
102     {
103         { ImageTiling::CORE_IMAGE_TILING_OPTIMAL, nullptr }, // default
104         { ImageTiling::CORE_IMAGE_TILING_OPTIMAL, "optimal" },
105         { ImageTiling::CORE_IMAGE_TILING_LINEAR, "linear" },
106     })
107 
108 RENDER_JSON_SERIALIZE_ENUM(ImageUsageFlagBits,
109     {
110         { (ImageUsageFlagBits)0, nullptr },
111         { ImageUsageFlagBits::CORE_IMAGE_USAGE_TRANSFER_SRC_BIT, "transfer_src" },
112         { ImageUsageFlagBits::CORE_IMAGE_USAGE_TRANSFER_DST_BIT, "transfer_dst" },
113         { ImageUsageFlagBits::CORE_IMAGE_USAGE_SAMPLED_BIT, "sampled" },
114         { ImageUsageFlagBits::CORE_IMAGE_USAGE_STORAGE_BIT, "storage" },
115         { ImageUsageFlagBits::CORE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, "color_attachment" },
116         { ImageUsageFlagBits::CORE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, "depth_stencil_attachment" },
117         { ImageUsageFlagBits::CORE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, "transient_attachment" },
118         { ImageUsageFlagBits::CORE_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, "input_attachment" },
119         { ImageUsageFlagBits::CORE_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT,
120             "fragment_shading_rate_attachment" },
121     })
122 
123 RENDER_JSON_SERIALIZE_ENUM(ImageCreateFlagBits,
124     {
125         { (ImageCreateFlagBits)0, nullptr },
126         { ImageCreateFlagBits::CORE_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, "cube_compatible" },
127         { ImageCreateFlagBits::CORE_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, "2d_array_compatible" },
128     })
129 
130 RENDER_JSON_SERIALIZE_ENUM(EngineImageCreationFlagBits,
131     {
132         { (EngineImageCreationFlagBits)0, nullptr },
133         { EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, "dynamic_barriers" },
134         { EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_RESET_STATE_ON_FRAME_BORDERS,
135             "reset_state_on_frame_borders" },
136         { EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_GENERATE_MIPS, "generate_mips" },
137     })
138 
139 RENDER_JSON_SERIALIZE_ENUM(SampleCountFlagBits,
140     {
141         { (SampleCountFlagBits)0, nullptr },
142         { SampleCountFlagBits::CORE_SAMPLE_COUNT_1_BIT, "1bit" },
143         { SampleCountFlagBits::CORE_SAMPLE_COUNT_2_BIT, "2bit" },
144         { SampleCountFlagBits::CORE_SAMPLE_COUNT_4_BIT, "4bit" },
145         { SampleCountFlagBits::CORE_SAMPLE_COUNT_8_BIT, "8bit" },
146         { SampleCountFlagBits::CORE_SAMPLE_COUNT_16_BIT, "16bit" },
147         { SampleCountFlagBits::CORE_SAMPLE_COUNT_32_BIT, "32bit" },
148         { SampleCountFlagBits::CORE_SAMPLE_COUNT_64_BIT, "64bit" },
149     })
150 
151 RENDER_JSON_SERIALIZE_ENUM(MemoryPropertyFlagBits,
152     {
153         { (MemoryPropertyFlagBits)0, nullptr },
154         { MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, "device_local" },
155         { MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_HOST_VISIBLE_BIT, "host_visible" },
156         { MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_HOST_COHERENT_BIT, "host_coherent" },
157         { MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_HOST_CACHED_BIT, "host_cached" },
158         { MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, "lazily_allocated" },
159         { MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_PROTECTED_BIT, "protected" },
160     })
161 
162 RENDER_JSON_SERIALIZE_ENUM(EngineBufferCreationFlagBits,
163     {
164         { (EngineBufferCreationFlagBits)0, nullptr },
165         { EngineBufferCreationFlagBits::CORE_ENGINE_BUFFER_CREATION_DYNAMIC_BARRIERS, "dynamic_barriers" },
166     })
167 
168 RENDER_JSON_SERIALIZE_ENUM(BufferUsageFlagBits,
169     {
170         { (BufferUsageFlagBits)0, nullptr },
171         { BufferUsageFlagBits::CORE_BUFFER_USAGE_TRANSFER_SRC_BIT, "transfer_src" },
172         { BufferUsageFlagBits::CORE_BUFFER_USAGE_TRANSFER_DST_BIT, "transfer_dst" },
173         { BufferUsageFlagBits::CORE_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, "uniform_texel" },
174         { BufferUsageFlagBits::CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT, "uniform" },
175         { BufferUsageFlagBits::CORE_BUFFER_USAGE_STORAGE_BUFFER_BIT, "storage_texel" },
176         { BufferUsageFlagBits::CORE_BUFFER_USAGE_STORAGE_BUFFER_BIT, "storage" },
177         { BufferUsageFlagBits::CORE_BUFFER_USAGE_INDEX_BUFFER_BIT, "index" },
178         { BufferUsageFlagBits::CORE_BUFFER_USAGE_VERTEX_BUFFER_BIT, "vertex" },
179         { BufferUsageFlagBits::CORE_BUFFER_USAGE_INDIRECT_BUFFER_BIT, "indirect" },
180         { BufferUsageFlagBits::CORE_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT, "shader_binding_table" },
181         { BufferUsageFlagBits::CORE_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, "shader_device_address" },
182         { BufferUsageFlagBits::CORE_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT,
183             "acceleration_structure_build_input_read_only" },
184         { BufferUsageFlagBits::CORE_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT, "acceleration_structure_storage" },
185     })
186 
187 RENDER_JSON_SERIALIZE_ENUM(RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits,
188     {
189         { RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits::MAX_DEPENDENCY_FLAG_ENUM, nullptr },
190         { RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits::FORMAT, "format" },
191         { RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits::SIZE, "size" },
192         { RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits::MIP_COUNT, "mipCount" },
193         { RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits::LAYER_COUNT, "layerCount" },
194         { RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits::SAMPLES, "samples" },
195     })
196 
197 RENDER_JSON_SERIALIZE_ENUM(RenderNodeGraphResourceLocationType,
198     {
199         { RenderNodeGraphResourceLocationType::DEFAULT, "default" },
200         { RenderNodeGraphResourceLocationType::FROM_RENDER_GRAPH_INPUT, "from_render_graph_input" },
201         { RenderNodeGraphResourceLocationType::FROM_RENDER_GRAPH_OUTPUT, "from_render_graph_output" },
202         { RenderNodeGraphResourceLocationType::FROM_PREVIOUS_RENDER_NODE_OUTPUT, "from_previous_render_node_output" },
203         { RenderNodeGraphResourceLocationType::FROM_NAMED_RENDER_NODE_OUTPUT, "from_named_render_node_output" },
204         { RenderNodeGraphResourceLocationType::FROM_PREVIOUS_RENDER_NODE_GRAPH_OUTPUT,
205             "from_previous_render_node_graph_output" },
206     })
207 
208 RENDER_JSON_SERIALIZE_ENUM(ResolveModeFlagBits,
209     {
210         { ResolveModeFlagBits::CORE_RESOLVE_MODE_NONE, "none" },
211         { ResolveModeFlagBits::CORE_RESOLVE_MODE_SAMPLE_ZERO_BIT, "sample_zero" },
212         { ResolveModeFlagBits::CORE_RESOLVE_MODE_AVERAGE_BIT, "average" },
213         { ResolveModeFlagBits::CORE_RESOLVE_MODE_MIN_BIT, "min" },
214         { ResolveModeFlagBits::CORE_RESOLVE_MODE_MAX_BIT, "max" },
215     })
216 
217 RENDER_JSON_SERIALIZE_ENUM(SubpassContents,
218     {
219         { SubpassContents::CORE_SUBPASS_CONTENTS_INLINE, "inline" },
220         { SubpassContents::CORE_SUBPASS_CONTENTS_SECONDARY_COMMAND_LISTS, "secondary_command_lists" },
221     })
222 
223 RENDER_JSON_SERIALIZE_ENUM(SubpassFlagBits,
224     {
225         { (SubpassFlagBits)0, nullptr },
226         { SubpassFlagBits::CORE_SUBPASS_MERGE_BIT, "merge" },
227         { SubpassFlagBits::CORE_SUBPASS_MERGE_BIT, "merge_bit" },
228     })
229 // clang-format on
FromJson(const json::value & jsonData,JsonContext<RenderNodeGraphInputs::Resource> & context)230 inline void FromJson(const json::value& jsonData, JsonContext<RenderNodeGraphInputs::Resource>& context)
231 {
232     SafeGetJsonValue(jsonData, "set", context.error, context.data.set);
233     SafeGetJsonValue(jsonData, "binding", context.error, context.data.binding);
234     SafeGetJsonValue(jsonData, "name", context.error, context.data.name);
235     SafeGetJsonEnum(jsonData, "resourceLocation", context.error, context.data.resourceLocation);
236     SafeGetJsonValue(jsonData, "resourceIndex", context.error, context.data.resourceIndex);
237     SafeGetJsonValue(jsonData, "nodeName", context.error, context.data.nodeName);
238     SafeGetJsonValue(jsonData, "usageName", context.error, context.data.usageName);
239     SafeGetJsonValue(jsonData, "mip", context.error, context.data.mip);
240     SafeGetJsonValue(jsonData, "layer", context.error, context.data.layer);
241 }
242 
FromJson(const json::value & jsonData,JsonContext<RenderNodeGraphInputs::Attachment> & context)243 inline void FromJson(const json::value& jsonData, JsonContext<RenderNodeGraphInputs::Attachment>& context)
244 {
245     SafeGetJsonEnum(jsonData, "loadOp", context.error, context.data.loadOp);
246     SafeGetJsonEnum(jsonData, "storeOp", context.error, context.data.storeOp);
247     SafeGetJsonEnum(jsonData, "stencilLoadOp", context.error, context.data.stencilLoadOp);
248     SafeGetJsonEnum(jsonData, "stencilStoreOp", context.error, context.data.stencilStoreOp);
249     if (auto const pos = jsonData.find("clearColor"); pos) {
250         if (pos->is_array() && pos->array_.size() == 4) { // 4: array size
251             FromJson(*pos, context.data.clearValue.color.float32);
252         } else {
253             const auto asString = to_string(*pos);
254             context.error +=
255                 "clearColor must be an array of length 4 : (" + string_view(asString.data(), asString.size()) + ")\n";
256         }
257     }
258     if (auto const pos = jsonData.find("clearDepth"); pos) {
259         if (pos->is_array() && pos->array_.size() == 2) { // 2: array size
260             if (pos->array_[0].is_number()) {
261                 context.data.clearValue.depthStencil.depth = pos->array_[0].as_number<float>();
262             } else {
263                 const auto asString = to_string(*pos);
264                 context.error += "depthAttachment.clearValue[0] must be a float: (" +
265                                  string_view(asString.data(), asString.size()) + ")\n";
266             }
267 
268             if (pos->array_[1].is_number()) {
269                 context.data.clearValue.depthStencil.stencil = pos->array_[1].as_number<uint32_t>();
270             } else {
271                 const auto asString = to_string(*pos);
272                 context.error += "depthAttachment.clearValue[1] must be an uint: (" +
273                                  string_view(asString.data(), asString.size()) + ")\n";
274             }
275         } else {
276             const auto asString = to_string(*pos);
277             context.error += "Failed to read depthAttachment.clearValue, invalid datatype: (" +
278                              string_view(asString.data(), asString.size()) + ")\n";
279         }
280     }
281     SafeGetJsonValue(jsonData, "name", context.error, context.data.name);
282     SafeGetJsonEnum(jsonData, "resourceLocation", context.error, context.data.resourceLocation);
283     SafeGetJsonValue(jsonData, "resourceIndex", context.error, context.data.resourceIndex);
284     SafeGetJsonValue(jsonData, "nodeName", context.error, context.data.nodeName);
285 
286     SafeGetJsonValue(jsonData, "mip", context.error, context.data.mip);
287     SafeGetJsonValue(jsonData, "layer", context.error, context.data.layer);
288 }
289 
FromJson(const json::value & jsonData,JsonContext<RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc> & context)290 inline void FromJson(
291     const json::value& jsonData, JsonContext<RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc>& context)
292 {
293     SafeGetJsonValue(jsonData, "name", context.error, context.data.name);
294     SafeGetJsonValue(jsonData, "shareName", context.error, context.data.shareName);
295     SafeGetJsonValue(jsonData, "dependencyImageName", context.error, context.data.dependencyImageName);
296 
297     SafeGetJsonEnum(jsonData, "imageType", context.error, context.data.desc.imageType);
298     SafeGetJsonEnum(jsonData, "imageViewType", context.error, context.data.desc.imageViewType);
299     SafeGetJsonEnum(jsonData, "format", context.error, context.data.desc.format);
300     SafeGetJsonEnum(jsonData, "imageTiling", context.error, context.data.desc.imageTiling);
301     SafeGetJsonBitfield<ImageUsageFlagBits>(jsonData, "usageFlags", context.error, context.data.desc.usageFlags);
302     SafeGetJsonBitfield<MemoryPropertyFlagBits>(
303         jsonData, "memoryPropertyFlags", context.error, context.data.desc.memoryPropertyFlags);
304     SafeGetJsonBitfield<ImageCreateFlagBits>(jsonData, "createFlags", context.error, context.data.desc.createFlags);
305     SafeGetJsonBitfield<EngineImageCreationFlagBits>(
306         jsonData, "engineCreationFlags", context.error, context.data.desc.engineCreationFlags);
307     SafeGetJsonValue(jsonData, "width", context.error, context.data.desc.width);
308     SafeGetJsonValue(jsonData, "height", context.error, context.data.desc.height);
309     SafeGetJsonValue(jsonData, "depth", context.error, context.data.desc.depth);
310     SafeGetJsonValue(jsonData, "mipCount", context.error, context.data.desc.mipCount);
311     SafeGetJsonValue(jsonData, "layerCount", context.error, context.data.desc.layerCount);
312     SafeGetJsonBitfield<SampleCountFlagBits>(
313         jsonData, "sampleCountFlags", context.error, context.data.desc.sampleCountFlags);
314 
315     SafeGetJsonBitfield<RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits>(
316         jsonData, "dependencyFlags", context.error, context.data.dependencyFlags);
317     SafeGetJsonValue(jsonData, "dependencySizeScale", context.error, context.data.dependencySizeScale);
318 
319     if (auto const pos = jsonData.find("shadingRateTexelSize"); pos) {
320         if (pos->is_array() && pos->array_.size() == 2) { // 2: array size
321             if (pos->array_[0].is_number() && pos->array_[1u].is_number()) {
322                 context.data.shadingRateTexelSize.width = pos->array_[0].as_number<uint32_t>();
323                 context.data.shadingRateTexelSize.height = pos->array_[1].as_number<uint32_t>();
324             }
325         }
326     }
327 
328     if ((context.data.desc.format == Format::BASE_FORMAT_UNDEFINED) && context.data.dependencyImageName.empty()) {
329         context.error += "undefined gpu image desc format\n";
330     }
331 }
332 
FromJson(const json::value & jsonData,JsonContext<RenderNodeGraphInputs::RenderNodeGraphGpuBufferDesc> & context)333 inline void FromJson(
334     const json::value& jsonData, JsonContext<RenderNodeGraphInputs::RenderNodeGraphGpuBufferDesc>& context)
335 {
336     SafeGetJsonValue(jsonData, "name", context.error, context.data.name);
337     SafeGetJsonValue(jsonData, "shareName", context.error, context.data.shareName);
338     SafeGetJsonValue(jsonData, "dependencyBufferName", context.error, context.data.dependencyBufferName);
339 
340     SafeGetJsonBitfield<BufferUsageFlagBits>(jsonData, "usageFlags", context.error, context.data.desc.usageFlags);
341     SafeGetJsonBitfield<EngineBufferCreationFlagBits>(
342         jsonData, "engineCreationFlags", context.error, context.data.desc.engineCreationFlags);
343     SafeGetJsonBitfield<MemoryPropertyFlagBits>(
344         jsonData, "memoryPropertyFlags", context.error, context.data.desc.memoryPropertyFlags);
345     SafeGetJsonValue(jsonData, "byteSize", context.error, context.data.desc.byteSize);
346 }
347 
FromJson(const json::value & jsonData,JsonContext<DescriptorCounts::TypedCount> & context)348 inline void FromJson(const json::value& jsonData, JsonContext<DescriptorCounts::TypedCount>& context)
349 {
350     SafeGetJsonEnum(jsonData, "type", context.error, context.data.type);
351     SafeGetJsonValue(jsonData, "count", context.error, context.data.count);
352 }
353 
354 namespace {
355 struct LoadResult {
356     string error;
357 };
358 
359 static constexpr size_t MAX_RNG_RENDER_PASS_SUBPASS_COUNT { 64 };
360 
SafetyCheckRenderPassVectors(RenderNodeGraphInputs::InputRenderPass & renderPass)361 void SafetyCheckRenderPassVectors(RenderNodeGraphInputs::InputRenderPass& renderPass)
362 {
363     if (renderPass.attachments.size() > PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT) {
364         renderPass.attachments.resize(PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT);
365 #if (RENDER_VALIDATION_ENABLED == 1)
366         PLUGIN_LOG_W("Render node graph render pass attachment count exceeded");
367 #endif
368     }
369     if (renderPass.colorAttachmentIndices.size() > PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT) {
370         renderPass.colorAttachmentIndices.resize(PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT);
371 #if (RENDER_VALIDATION_ENABLED == 1)
372         PLUGIN_LOG_W("Render node graph render pass color attachment count exceeded");
373 #endif
374     }
375     if (renderPass.inputAttachmentIndices.size() > PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT) {
376         renderPass.inputAttachmentIndices.resize(PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT);
377 #if (RENDER_VALIDATION_ENABLED == 1)
378         PLUGIN_LOG_W("Render node graph render pass input attachment count exceeded");
379 #endif
380     }
381     if (renderPass.resolveAttachmentIndices.size() > PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT) {
382         renderPass.resolveAttachmentIndices.resize(PipelineStateConstants::MAX_RENDER_PASS_ATTACHMENT_COUNT);
383 #if (RENDER_VALIDATION_ENABLED == 1)
384         PLUGIN_LOG_W("Render node graph render pass resolve attachment count exceeded");
385 #endif
386     }
387 }
388 
GetAttachmentIndices(const char * attachmentName,const json::value & subpass,vector<uint32_t> & attachmentVector)389 void GetAttachmentIndices(const char* attachmentName, const json::value& subpass, vector<uint32_t>& attachmentVector)
390 {
391     if (auto const iIter = subpass.find(attachmentName); iIter) {
392         if (iIter->is_array()) {
393             std::transform(iIter->array_.begin(), iIter->array_.end(), std::back_inserter(attachmentVector),
394                 [](const json::value& value) {
395                     if (value.is_number()) {
396                         return value.template as_number<uint32_t>();
397                     }
398                     return 0u;
399                 });
400         } else {
401             attachmentVector = { iIter->template as_number<uint32_t>() };
402         }
403     }
404 }
405 
ParseRenderpass(const string_view name,const json::value & node,RenderNodeGraphInputs::InputRenderPass & renderPass,LoadResult & result)406 void ParseRenderpass(const string_view name, const json::value& node,
407     RenderNodeGraphInputs::InputRenderPass& renderPass, LoadResult& result)
408 {
409     auto const rp = node.find(name);
410     if (!rp) {
411         return; // early out
412     }
413     ParseArray<decltype(renderPass.attachments)::value_type>(*rp, "attachments", renderPass.attachments, result);
414     SafeGetJsonValue(*rp, "subpassIndex", result.error, renderPass.subpassIndex);
415     SafeGetJsonValue(*rp, "subpassCount", result.error, renderPass.subpassCount);
416     SafeGetJsonEnum(*rp, "subpassContents", result.error, renderPass.subpassContents);
417 
418     if (renderPass.subpassCount > MAX_RNG_RENDER_PASS_SUBPASS_COUNT) {
419         renderPass.subpassCount = MAX_RNG_RENDER_PASS_SUBPASS_COUNT;
420 #if (RENDER_VALIDATION_ENABLED == 1)
421         PLUGIN_LOG_E("RENDER_VALIDATION: render pass max subpass count exceeded");
422 #endif
423     }
424     if (renderPass.subpassIndex >= renderPass.subpassCount) {
425         renderPass.subpassIndex = Math::min(renderPass.subpassIndex, renderPass.subpassCount - 1);
426 #if (RENDER_VALIDATION_ENABLED == 1)
427         PLUGIN_LOG_E("RENDER_VALIDATION: render pass subpass index must be smaller than subpass index");
428 #endif
429     }
430     if (auto const sp = rp->find("subpass"); sp) {
431         SafeGetJsonValue(*sp, "depthAttachmentIndex", result.error, renderPass.depthAttachmentIndex);
432         SafeGetJsonValue(*sp, "depthResolveAttachmentIndex", result.error, renderPass.depthResolveAttachmentIndex);
433         // deprecated
434         SafeGetJsonBitfield<ResolveModeFlagBits>(
435             *sp, "depthResolveModeFlagBit", result.error, renderPass.depthResolveModeFlags);
436         SafeGetJsonBitfield<ResolveModeFlagBits>(
437             *sp, "stencilResolveModeFlagBit", result.error, renderPass.stencilResolveModeFlags);
438 #if (RENDER_VALIDATION_ENABLED == 1)
439         if ((renderPass.depthResolveModeFlags != 0) || (renderPass.stencilResolveModeFlags != 0)) {
440             PLUGIN_LOG_W("RENDER_VALIDATION: depthResolveModeFlagBit and stencilResolveModeFlagBit are deprecated, "
441                          "use depthResolveModeFlags and stencilResolveModeFlags");
442         }
443 #endif
444 
445         SafeGetJsonBitfield<ResolveModeFlagBits>(
446             *sp, "depthResolveModeFlags", result.error, renderPass.depthResolveModeFlags);
447         SafeGetJsonBitfield<ResolveModeFlagBits>(
448             *sp, "stencilResolveModeFlags", result.error, renderPass.stencilResolveModeFlags);
449         SafeGetJsonEnum(
450             *sp, "fragmentShadingRateAttachmentIndex", result.error, renderPass.fragmentShadingRateAttachmentIndex);
451         SafeGetJsonBitfield<SubpassFlagBits>(*sp, "subpassFlags", result.error, renderPass.subpassFlags);
452 #if (RENDER_VALIDATION_ENABLED == 1)
453         if ((renderPass.depthResolveAttachmentIndex != ~0u) &&
454             ((renderPass.depthResolveModeFlags | renderPass.stencilResolveModeFlags) == 0)) {
455             PLUGIN_LOG_W("RENDER_VALIDATION: depth resolve mode flags not set for depth resolve image");
456         }
457 #endif
458 
459         GetAttachmentIndices("inputAttachmentIndices", *sp, renderPass.inputAttachmentIndices);
460         GetAttachmentIndices("colorAttachmentIndices", *sp, renderPass.colorAttachmentIndices);
461         GetAttachmentIndices("resolveAttachmentIndices", *sp, renderPass.resolveAttachmentIndices);
462 
463         SafetyCheckRenderPassVectors(renderPass);
464 
465         if (auto const pos = sp->find("shadingRateTexelSize"); pos) {
466             if ((pos->is_array() && pos->array_.size() == 2) && // 2: size
467                 (pos->array_[0].is_number() && pos->array_[1u].is_number())) {
468                 renderPass.shadingRateTexelSize.width = pos->array_[0].as_number<uint32_t>();
469                 renderPass.shadingRateTexelSize.height = pos->array_[1].as_number<uint32_t>();
470             }
471         }
472 
473         SafeGetJsonValue(*sp, "viewMask", result.error, renderPass.viewMask);
474     }
475 }
476 
ParseResources(const string_view name,const json::value & node,RenderNodeGraphInputs::InputResources & resources,LoadResult & result)477 void ParseResources(const string_view name, const json::value& node, RenderNodeGraphInputs::InputResources& resources,
478     LoadResult& result)
479 {
480     if (auto const res = node.find(name); res) {
481         ParseArray<decltype(resources.buffers)::value_type>(*res, "buffers", resources.buffers, result);
482         ParseArray<decltype(resources.images)::value_type>(*res, "images", resources.images, result);
483         ParseArray<decltype(resources.samplers)::value_type>(*res, "samplers", resources.samplers, result);
484 
485         ParseArray<decltype(resources.customInputBuffers)::value_type>(
486             *res, "customInputBuffers", resources.customInputBuffers, result);
487         ParseArray<decltype(resources.customOutputBuffers)::value_type>(
488             *res, "customOutputBuffers", resources.customOutputBuffers, result);
489 
490         ParseArray<decltype(resources.customInputImages)::value_type>(
491             *res, "customInputImages", resources.customInputImages, result);
492         ParseArray<decltype(resources.customOutputImages)::value_type>(
493             *res, "customOutputImages", resources.customOutputImages, result);
494     }
495 }
496 } // namespace
497 
RenderNodeParserUtil(const CreateInfo & createInfo)498 RenderNodeParserUtil::RenderNodeParserUtil(const CreateInfo& createInfo) {}
499 
500 RenderNodeParserUtil::~RenderNodeParserUtil() = default;
501 
GetUintValue(const json::value & jsonValue,const string_view name) const502 uint64_t RenderNodeParserUtil::GetUintValue(const json::value& jsonValue, const string_view name) const
503 {
504     uint64_t val = std::numeric_limits<uint64_t>::max();
505     string error;
506     if (!SafeGetJsonValue(jsonValue, name, error, val)) {
507         PLUGIN_LOG_W("GetUintValue: %s", error.c_str());
508     }
509     return val;
510 }
511 
GetIntValue(const json::value & jsonValue,const string_view name) const512 int64_t RenderNodeParserUtil::GetIntValue(const json::value& jsonValue, const string_view name) const
513 {
514     int64_t val = std::numeric_limits<int64_t>::max();
515     string error;
516     if (!SafeGetJsonValue(jsonValue, name, error, val)) {
517         PLUGIN_LOG_W("GetIntValue: %s", error.c_str());
518     }
519     return val;
520 }
521 
GetFloatValue(const json::value & jsonValue,const string_view name) const522 float RenderNodeParserUtil::GetFloatValue(const json::value& jsonValue, const string_view name) const
523 {
524     float val = std::numeric_limits<float>::max();
525     string error;
526     if (!SafeGetJsonValue(jsonValue, name, error, val)) {
527         PLUGIN_LOG_W("GetFloatValue: %s", error.c_str());
528     }
529     return val;
530 }
531 
GetStringValue(const json::value & jsonValue,const string_view name) const532 string RenderNodeParserUtil::GetStringValue(const json::value& jsonValue, const string_view name) const
533 {
534     string parsedString;
535     string error;
536     if (!SafeGetJsonValue(jsonValue, name, error, parsedString)) {
537         PLUGIN_LOG_W("GetStringValue: %s", error.c_str());
538     }
539     return parsedString;
540 }
541 
GetInputRenderPass(const json::value & jsonValue,const string_view name) const542 RenderNodeGraphInputs::InputRenderPass RenderNodeParserUtil::GetInputRenderPass(
543     const json::value& jsonValue, const string_view name) const
544 {
545     RenderNodeGraphInputs::InputRenderPass renderPass;
546     LoadResult result;
547     ParseRenderpass(name, jsonValue, renderPass, result);
548     if (!result.error.empty()) {
549         PLUGIN_LOG_W("GetInputRenderPass: %s", result.error.c_str());
550     }
551     return renderPass;
552 }
553 
GetInputResources(const json::value & jsonValue,const string_view name) const554 RenderNodeGraphInputs::InputResources RenderNodeParserUtil::GetInputResources(
555     const json::value& jsonValue, const string_view name) const
556 {
557     RenderNodeGraphInputs::InputResources resources;
558     LoadResult result;
559     ParseResources(name, jsonValue, resources, result);
560     if (!result.error.empty()) {
561         PLUGIN_LOG_W("GetInputResources: %s", result.error.c_str());
562     }
563     return resources;
564 }
565 
GetRenderDataStore(const json::value & jsonValue,const string_view name) const566 RenderNodeGraphInputs::RenderDataStore RenderNodeParserUtil::GetRenderDataStore(
567     const json::value& jsonValue, const string_view name) const
568 {
569     RenderNodeGraphInputs::RenderDataStore renderDataStore;
570     LoadResult result;
571     if (auto const dataStore = jsonValue.find(name); dataStore) {
572         SafeGetJsonValue(*dataStore, "dataStoreName", result.error, renderDataStore.dataStoreName);
573         SafeGetJsonValue(*dataStore, "typeName", result.error, renderDataStore.typeName);
574         SafeGetJsonValue(*dataStore, "configurationName", result.error, renderDataStore.configurationName);
575     }
576     if (!result.error.empty()) {
577         PLUGIN_LOG_W("GetRenderDataStore: %s", result.error.c_str());
578     }
579     return renderDataStore;
580 }
581 
GetGpuImageDescs(const json::value & jsonValue,const string_view name) const582 vector<RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc> RenderNodeParserUtil::GetGpuImageDescs(
583     const json::value& jsonValue, const string_view name) const
584 {
585     vector<RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc> resources;
586     LoadResult result;
587     if (const auto ref = jsonValue.find(name); ref) {
588         if (ref->is_array()) {
589             ParseArray<decltype(resources)::value_type>(jsonValue, name.data(), resources, result);
590         } else {
591             result.error += "expecting array";
592         }
593     }
594     if (!result.error.empty()) {
595         PLUGIN_LOG_W("GetGpuImageDescs: %s", result.error.c_str());
596     }
597     return resources;
598 }
599 
GetGpuBufferDescs(const json::value & jsonValue,const string_view name) const600 vector<RenderNodeGraphInputs::RenderNodeGraphGpuBufferDesc> RenderNodeParserUtil::GetGpuBufferDescs(
601     const json::value& jsonValue, const string_view name) const
602 {
603     vector<RenderNodeGraphInputs::RenderNodeGraphGpuBufferDesc> resources;
604     LoadResult result;
605     if (const auto ref = jsonValue.find(name); ref) {
606         if (ref->is_array()) {
607             ParseArray<decltype(resources)::value_type>(jsonValue, name.data(), resources, result);
608         } else {
609             result.error += "expecting array";
610         }
611     }
612     if (!result.error.empty()) {
613         PLUGIN_LOG_W("GetGpuBufferDescs: %s", result.error.c_str());
614     }
615     return resources;
616 }
617 
GetRenderSlotSortType(const json::value & jsonValue,const string_view name) const618 RenderSlotSortType RenderNodeParserUtil::GetRenderSlotSortType(
619     const json::value& jsonValue, const string_view name) const
620 {
621     RenderSlotSortType sortType = RenderSlotSortType::NONE;
622     string error;
623     if (!SafeGetJsonEnum(jsonValue, name, error, sortType)) {
624         PLUGIN_LOG_W("GetRenderSlotSortType: %s", error.c_str());
625     }
626     return sortType;
627 }
628 
GetRenderSlotCullType(const json::value & jsonValue,const string_view name) const629 RenderSlotCullType RenderNodeParserUtil::GetRenderSlotCullType(
630     const json::value& jsonValue, const string_view name) const
631 {
632     RenderSlotCullType cullType = RenderSlotCullType::NONE;
633     string error;
634     if (!SafeGetJsonEnum(jsonValue, name, error, cullType)) {
635         PLUGIN_LOG_W("GetRenderSlotCullType: %s", error.c_str());
636     }
637     return cullType;
638 }
639 
GetInterface(const BASE_NS::Uid & uid) const640 const CORE_NS::IInterface* RenderNodeParserUtil::GetInterface(const BASE_NS::Uid& uid) const
641 {
642     if ((uid == IRenderNodeParserUtil::UID) || (uid == IInterface::UID)) {
643         return this;
644     }
645     return nullptr;
646 }
647 
GetInterface(const BASE_NS::Uid & uid)648 CORE_NS::IInterface* RenderNodeParserUtil::GetInterface(const BASE_NS::Uid& uid)
649 {
650     if ((uid == IRenderNodeParserUtil::UID) || (uid == IInterface::UID)) {
651         return this;
652     }
653     return nullptr;
654 }
655 
Ref()656 void RenderNodeParserUtil::Ref() {}
657 
Unref()658 void RenderNodeParserUtil::Unref() {}
659 RENDER_END_NAMESPACE()
660