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