1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "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_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 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_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 CORE_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 CORE_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 CORE_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, "fragment_shading_rate_attachment" },
120 })
121
122 CORE_JSON_SERIALIZE_ENUM(ImageCreateFlagBits,
123 {
124 { (ImageCreateFlagBits)0, nullptr },
125 { ImageCreateFlagBits::CORE_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, "cube_compatible" },
126 { ImageCreateFlagBits::CORE_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, "2d_array_compatible" },
127 })
128
129 CORE_JSON_SERIALIZE_ENUM(EngineImageCreationFlagBits,
130 {
131 { (EngineImageCreationFlagBits)0, nullptr },
132 { EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_DYNAMIC_BARRIERS, "dynamic_barriers" },
133 { EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_RESET_STATE_ON_FRAME_BORDERS,
134 "reset_state_on_frame_borders" },
135 { EngineImageCreationFlagBits::CORE_ENGINE_IMAGE_CREATION_GENERATE_MIPS, "generate_mips" },
136 })
137
138 CORE_JSON_SERIALIZE_ENUM(SampleCountFlagBits,
139 {
140 { (SampleCountFlagBits)0, nullptr },
141 { SampleCountFlagBits::CORE_SAMPLE_COUNT_1_BIT, "1bit" },
142 { SampleCountFlagBits::CORE_SAMPLE_COUNT_2_BIT, "2bit" },
143 { SampleCountFlagBits::CORE_SAMPLE_COUNT_4_BIT, "4bit" },
144 { SampleCountFlagBits::CORE_SAMPLE_COUNT_8_BIT, "8bit" },
145 { SampleCountFlagBits::CORE_SAMPLE_COUNT_16_BIT, "16bit" },
146 { SampleCountFlagBits::CORE_SAMPLE_COUNT_32_BIT, "32bit" },
147 { SampleCountFlagBits::CORE_SAMPLE_COUNT_64_BIT, "64bit" },
148 })
149
150 CORE_JSON_SERIALIZE_ENUM(MemoryPropertyFlagBits,
151 {
152 { (MemoryPropertyFlagBits)0, nullptr },
153 { MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, "device_local" },
154 { MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_HOST_VISIBLE_BIT, "host_visible" },
155 { MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_HOST_COHERENT_BIT, "host_coherent" },
156 { MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_HOST_CACHED_BIT, "host_cached" },
157 { MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, "lazily_allocated" },
158 { MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_PROTECTED_BIT, "protected" },
159 })
160
161 CORE_JSON_SERIALIZE_ENUM(EngineBufferCreationFlagBits,
162 {
163 { (EngineBufferCreationFlagBits)0, nullptr },
164 { EngineBufferCreationFlagBits::CORE_ENGINE_BUFFER_CREATION_DYNAMIC_BARRIERS, "dynamic_barriers" },
165 })
166
167 CORE_JSON_SERIALIZE_ENUM(BufferUsageFlagBits,
168 {
169 { (BufferUsageFlagBits)0, nullptr },
170 { BufferUsageFlagBits::CORE_BUFFER_USAGE_TRANSFER_SRC_BIT, "transfer_src" },
171 { BufferUsageFlagBits::CORE_BUFFER_USAGE_TRANSFER_DST_BIT, "transfer_dst" },
172 { BufferUsageFlagBits::CORE_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, "uniform_texel" },
173 { BufferUsageFlagBits::CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT, "uniform" },
174 { BufferUsageFlagBits::CORE_BUFFER_USAGE_STORAGE_BUFFER_BIT, "storage_texel" },
175 { BufferUsageFlagBits::CORE_BUFFER_USAGE_STORAGE_BUFFER_BIT, "storage" },
176 { BufferUsageFlagBits::CORE_BUFFER_USAGE_INDEX_BUFFER_BIT, "index" },
177 { BufferUsageFlagBits::CORE_BUFFER_USAGE_VERTEX_BUFFER_BIT, "vertex" },
178 { BufferUsageFlagBits::CORE_BUFFER_USAGE_INDIRECT_BUFFER_BIT, "indirect" },
179 { BufferUsageFlagBits::CORE_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT, "shader_binding_table" },
180 { BufferUsageFlagBits::CORE_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, "shader_device_address" },
181 { BufferUsageFlagBits::CORE_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT, "acceleration_structure_build_input_read_only" },
182 { BufferUsageFlagBits::CORE_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT, "acceleration_structure_storage" },
183 })
184
185 CORE_JSON_SERIALIZE_ENUM(RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits,
186 {
187 { RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits::MAX_DEPENDENCY_FLAG_ENUM, nullptr },
188 { RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits::FORMAT, "format" },
189 { RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits::SIZE, "size" },
190 { RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits::MIP_COUNT, "mipCount" },
191 { RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits::LAYER_COUNT, "layerCount" },
192 { RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits::SAMPLES, "samples" },
193 })
194
195 CORE_JSON_SERIALIZE_ENUM(RenderNodeGraphResourceLocationType,
196 {
197 { RenderNodeGraphResourceLocationType::DEFAULT, "default" },
198 { RenderNodeGraphResourceLocationType::FROM_RENDER_GRAPH_INPUT, "from_render_graph_input" },
199 { RenderNodeGraphResourceLocationType::FROM_RENDER_GRAPH_OUTPUT, "from_render_graph_output" },
200 { RenderNodeGraphResourceLocationType::FROM_PREVIOUS_RENDER_NODE_OUTPUT, "from_previous_render_node_output" },
201 { RenderNodeGraphResourceLocationType::FROM_NAMED_RENDER_NODE_OUTPUT, "from_named_render_node_output" },
202 { RenderNodeGraphResourceLocationType::FROM_PREVIOUS_RENDER_NODE_GRAPH_OUTPUT, "from_previous_render_node_graph_output" },
203 })
204
205 CORE_JSON_SERIALIZE_ENUM(ResolveModeFlagBits,
206 {
207 { ResolveModeFlagBits::CORE_RESOLVE_MODE_NONE, "none" },
208 { ResolveModeFlagBits::CORE_RESOLVE_MODE_SAMPLE_ZERO_BIT, "sample_zero" },
209 { ResolveModeFlagBits::CORE_RESOLVE_MODE_AVERAGE_BIT, "average" },
210 { ResolveModeFlagBits::CORE_RESOLVE_MODE_MIN_BIT, "min" },
211 { ResolveModeFlagBits::CORE_RESOLVE_MODE_MAX_BIT, "max" },
212 })
213
214 CORE_JSON_SERIALIZE_ENUM(SubpassContents,
215 {
216 { SubpassContents::CORE_SUBPASS_CONTENTS_INLINE, "inline" },
217 { SubpassContents::CORE_SUBPASS_CONTENTS_SECONDARY_COMMAND_LISTS, "secondary_command_lists" },
218 })
219 // clang-format on
220 inline void FromJson(const json::value& jsonData, JsonContext<RenderNodeGraphInputs::Resource>& context)
221 {
222 SafeGetJsonValue(jsonData, "set", context.error, context.data.set);
223 SafeGetJsonValue(jsonData, "binding", context.error, context.data.binding);
224 SafeGetJsonValue(jsonData, "name", context.error, context.data.name);
225 SafeGetJsonEnum(jsonData, "resourceLocation", context.error, context.data.resourceLocation);
226 SafeGetJsonValue(jsonData, "resourceIndex", context.error, context.data.resourceIndex);
227 SafeGetJsonValue(jsonData, "nodeName", context.error, context.data.nodeName);
228 SafeGetJsonValue(jsonData, "usageName", context.error, context.data.usageName);
229 SafeGetJsonValue(jsonData, "mip", context.error, context.data.mip);
230 SafeGetJsonValue(jsonData, "layer", context.error, context.data.layer);
231 }
232
FromJson(const json::value & jsonData,JsonContext<RenderNodeGraphInputs::Attachment> & context)233 inline void FromJson(const json::value& jsonData, JsonContext<RenderNodeGraphInputs::Attachment>& context)
234 {
235 SafeGetJsonEnum(jsonData, "loadOp", context.error, context.data.loadOp);
236 SafeGetJsonEnum(jsonData, "storeOp", context.error, context.data.storeOp);
237 SafeGetJsonEnum(jsonData, "stencilLoadOp", context.error, context.data.stencilLoadOp);
238 SafeGetJsonEnum(jsonData, "stencilStoreOp", context.error, context.data.stencilStoreOp);
239 if (auto const pos = jsonData.find("clearColor"); pos) {
240 if (pos->is_array() && pos->array_.size() == 4) {
241 FromJson(*pos, context.data.clearValue.color.float32);
242 } else {
243 const auto asString = to_string(*pos);
244 context.error +=
245 "clearColor must be an array of length 4 : (" + string_view(asString.data(), asString.size()) + ")\n";
246 }
247 }
248 if (auto const pos = jsonData.find("clearDepth"); pos) {
249 if (pos->is_array() && pos->array_.size() == 2) {
250 if (pos->array_[0].is_number()) {
251 context.data.clearValue.depthStencil.depth = pos->array_[0].as_number<float>();
252 } else {
253 const auto asString = to_string(*pos);
254 context.error += "depthAttachment.clearValue[0] must be a float: (" +
255 string_view(asString.data(), asString.size()) + ")\n";
256 }
257
258 if (pos->array_[1].is_number()) {
259 context.data.clearValue.depthStencil.stencil = pos->array_[1].as_number<uint32_t>();
260 } else {
261 const auto asString = to_string(*pos);
262 context.error += "depthAttachment.clearValue[1] must be an uint: (" +
263 string_view(asString.data(), asString.size()) + ")\n";
264 }
265 } else {
266 const auto asString = to_string(*pos);
267 context.error += "Failed to read depthAttachment.clearValue, invalid datatype: (" +
268 string_view(asString.data(), asString.size()) + ")\n";
269 }
270 }
271 SafeGetJsonValue(jsonData, "name", context.error, context.data.name);
272 SafeGetJsonEnum(jsonData, "resourceLocation", context.error, context.data.resourceLocation);
273 SafeGetJsonValue(jsonData, "resourceIndex", context.error, context.data.resourceIndex);
274 SafeGetJsonValue(jsonData, "nodeName", context.error, context.data.nodeName);
275
276 SafeGetJsonValue(jsonData, "mip", context.error, context.data.mip);
277 SafeGetJsonValue(jsonData, "layer", context.error, context.data.layer);
278 }
279
FromJson(const json::value & jsonData,JsonContext<RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc> & context)280 inline void FromJson(
281 const json::value& jsonData, JsonContext<RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc>& context)
282 {
283 SafeGetJsonValue(jsonData, "name", context.error, context.data.name);
284 SafeGetJsonValue(jsonData, "shareName", context.error, context.data.shareName);
285 SafeGetJsonValue(jsonData, "dependencyImageName", context.error, context.data.dependencyImageName);
286
287 SafeGetJsonEnum(jsonData, "imageType", context.error, context.data.desc.imageType);
288 SafeGetJsonEnum(jsonData, "imageViewType", context.error, context.data.desc.imageViewType);
289 SafeGetJsonEnum(jsonData, "format", context.error, context.data.desc.format);
290 SafeGetJsonEnum(jsonData, "imageTiling", context.error, context.data.desc.imageTiling);
291 SafeGetJsonBitfield<ImageUsageFlagBits>(jsonData, "usageFlags", context.error, context.data.desc.usageFlags);
292 SafeGetJsonBitfield<MemoryPropertyFlagBits>(
293 jsonData, "memoryPropertyFlags", context.error, context.data.desc.memoryPropertyFlags);
294 SafeGetJsonBitfield<ImageCreateFlagBits>(jsonData, "createFlags", context.error, context.data.desc.createFlags);
295 SafeGetJsonBitfield<EngineImageCreationFlagBits>(
296 jsonData, "engineCreationFlags", context.error, context.data.desc.engineCreationFlags);
297 SafeGetJsonValue(jsonData, "width", context.error, context.data.desc.width);
298 SafeGetJsonValue(jsonData, "height", context.error, context.data.desc.height);
299 SafeGetJsonValue(jsonData, "depth", context.error, context.data.desc.depth);
300 SafeGetJsonValue(jsonData, "mipCount", context.error, context.data.desc.mipCount);
301 SafeGetJsonValue(jsonData, "layerCount", context.error, context.data.desc.layerCount);
302 SafeGetJsonBitfield<SampleCountFlagBits>(
303 jsonData, "sampleCountFlags", context.error, context.data.desc.sampleCountFlags);
304
305 SafeGetJsonBitfield<RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc::DependencyFlagBits>(
306 jsonData, "dependencyFlags", context.error, context.data.dependencyFlags);
307 SafeGetJsonValue(jsonData, "dependencySizeScale", context.error, context.data.dependencySizeScale);
308
309 if (auto const pos = jsonData.find("shadingRateTexelSize"); pos) {
310 if (pos->is_array() && pos->array_.size() == 2) {
311 if (pos->array_[0].is_number() && pos->array_[1u].is_number()) {
312 context.data.shadingRateTexelSize.width = pos->array_[0].as_number<uint32_t>();
313 context.data.shadingRateTexelSize.height = pos->array_[1].as_number<uint32_t>();
314 }
315 }
316 }
317
318 if ((context.data.desc.format == Format::BASE_FORMAT_UNDEFINED) && context.data.dependencyImageName.empty()) {
319 context.error += "undefined gpu image desc format\n";
320 }
321 }
322
FromJson(const json::value & jsonData,JsonContext<RenderNodeGraphInputs::RenderNodeGraphGpuBufferDesc> & context)323 inline void FromJson(
324 const json::value& jsonData, JsonContext<RenderNodeGraphInputs::RenderNodeGraphGpuBufferDesc>& context)
325 {
326 SafeGetJsonValue(jsonData, "name", context.error, context.data.name);
327 SafeGetJsonValue(jsonData, "shareName", context.error, context.data.shareName);
328 SafeGetJsonValue(jsonData, "dependencyBufferName", context.error, context.data.dependencyBufferName);
329
330 SafeGetJsonBitfield<BufferUsageFlagBits>(jsonData, "usageFlags", context.error, context.data.desc.usageFlags);
331 SafeGetJsonBitfield<EngineBufferCreationFlagBits>(
332 jsonData, "engineCreationFlags", context.error, context.data.desc.engineCreationFlags);
333 SafeGetJsonBitfield<MemoryPropertyFlagBits>(
334 jsonData, "memoryPropertyFlags", context.error, context.data.desc.memoryPropertyFlags);
335 SafeGetJsonValue(jsonData, "byteSize", context.error, context.data.desc.byteSize);
336 }
337
FromJson(const json::value & jsonData,JsonContext<DescriptorCounts::TypedCount> & context)338 inline void FromJson(const json::value& jsonData, JsonContext<DescriptorCounts::TypedCount>& context)
339 {
340 SafeGetJsonEnum(jsonData, "type", context.error, context.data.type);
341 SafeGetJsonValue(jsonData, "count", context.error, context.data.count);
342 }
343
344 namespace {
345 struct LoadResult {
346 string error;
347 };
348
ParseRenderpass(const string_view name,const json::value & node,RenderNodeGraphInputs::InputRenderPass & renderPass,LoadResult & result)349 void ParseRenderpass(const string_view name, const json::value& node,
350 RenderNodeGraphInputs::InputRenderPass& renderPass, LoadResult& result)
351 {
352 if (auto const rp = node.find(name); rp) {
353 ParseArray<decltype(renderPass.attachments)::value_type>(*rp, "attachments", renderPass.attachments, result);
354 SafeGetJsonValue(*rp, "subpassIndex", result.error, renderPass.subpassIndex);
355 SafeGetJsonValue(*rp, "subpassCount", result.error, renderPass.subpassCount);
356 SafeGetJsonEnum(*rp, "subpassContents", result.error, renderPass.subpassContents);
357 #if (RENDER_VALIDATION_ENABLED == 1)
358 if (renderPass.subpassIndex >= renderPass.subpassCount) {
359 PLUGIN_LOG_E("RENDER_VALIDATION: render pass subpass index must be smaller than subpass index");
360 }
361 #endif
362 if (auto const sp = rp->find("subpass"); sp) {
363 SafeGetJsonValue(*sp, "depthAttachmentIndex", result.error, renderPass.depthAttachmentIndex);
364 SafeGetJsonValue(*sp, "depthResolveAttachmentIndex", result.error, renderPass.depthResolveAttachmentIndex);
365 SafeGetJsonEnum(*sp, "depthResolveModeFlagBit", result.error, renderPass.depthResolveModeFlagBit);
366 SafeGetJsonEnum(*sp, "stencilResolveModeFlagBit", result.error, renderPass.stencilResolveModeFlagBit);
367 SafeGetJsonEnum(
368 *sp, "fragmentShadingRateAttachmentIndex", result.error, renderPass.fragmentShadingRateAttachmentIndex);
369 #if (RENDER_VALIDATION_ENABLED == 1)
370 if ((renderPass.depthResolveAttachmentIndex != ~0u) &&
371 ((renderPass.depthResolveModeFlagBit | renderPass.stencilResolveModeFlagBit) == 0)) {
372 PLUGIN_LOG_W("RENDER_VALIDATION: depth resolve mode flags not set for depth resolve image");
373 }
374 #endif
375
376 const auto getAttachmentIndices = [](const char* attachmentName, const auto& subpass,
377 auto& attachmentVector) {
378 if (auto const iIter = subpass.find(attachmentName); iIter) {
379 if (iIter->is_array()) {
380 std::transform(iIter->array_.begin(), iIter->array_.end(), std::back_inserter(attachmentVector),
381 [](const json::value& value) {
382 if (value.is_number()) {
383 return value.template as_number<uint32_t>();
384 }
385 return 0u;
386 });
387 } else {
388 attachmentVector = { iIter->template as_number<uint32_t>() };
389 }
390 }
391 };
392
393 getAttachmentIndices("inputAttachmentIndices", *sp, renderPass.inputAttachmentIndices);
394 getAttachmentIndices("colorAttachmentIndices", *sp, renderPass.colorAttachmentIndices);
395 getAttachmentIndices("resolveAttachmentIndices", *sp, renderPass.resolveAttachmentIndices);
396
397 if (auto const pos = sp->find("shadingRateTexelSize"); pos) {
398 if (pos->is_array() && pos->array_.size() == 2) { // 2 :size
399 if (pos->array_[0].is_number() && pos->array_[1u].is_number()) {
400 renderPass.shadingRateTexelSize.width = pos->array_[0].as_number<uint32_t>();
401 renderPass.shadingRateTexelSize.height = pos->array_[1].as_number<uint32_t>();
402 }
403 }
404 }
405
406 SafeGetJsonValue(*sp, "viewMask", result.error, renderPass.viewMask);
407 }
408 }
409 }
410
ParseResources(const string_view name,const json::value & node,RenderNodeGraphInputs::InputResources & resources,LoadResult & result)411 void ParseResources(const string_view name, const json::value& node, RenderNodeGraphInputs::InputResources& resources,
412 LoadResult& result)
413 {
414 if (auto const res = node.find(name); res) {
415 ParseArray<decltype(resources.buffers)::value_type>(*res, "buffers", resources.buffers, result);
416 ParseArray<decltype(resources.images)::value_type>(*res, "images", resources.images, result);
417 ParseArray<decltype(resources.samplers)::value_type>(*res, "samplers", resources.samplers, result);
418
419 ParseArray<decltype(resources.customInputBuffers)::value_type>(
420 *res, "customInputBuffers", resources.customInputBuffers, result);
421 ParseArray<decltype(resources.customOutputBuffers)::value_type>(
422 *res, "customOutputBuffers", resources.customOutputBuffers, result);
423
424 ParseArray<decltype(resources.customInputImages)::value_type>(
425 *res, "customInputImages", resources.customInputImages, result);
426 ParseArray<decltype(resources.customOutputImages)::value_type>(
427 *res, "customOutputImages", resources.customOutputImages, result);
428 }
429 }
430 } // namespace
431
RenderNodeParserUtil(const CreateInfo & createInfo)432 RenderNodeParserUtil::RenderNodeParserUtil(const CreateInfo& createInfo) {}
433
434 RenderNodeParserUtil::~RenderNodeParserUtil() = default;
435
GetUintValue(const json::value & jsonValue,const string_view name) const436 uint64_t RenderNodeParserUtil::GetUintValue(const json::value& jsonValue, const string_view name) const
437 {
438 uint64_t val = std::numeric_limits<uint64_t>::max();
439 string error;
440 if (!SafeGetJsonValue(jsonValue, name, error, val)) {
441 PLUGIN_LOG_W("GetUintValue: %s", error.c_str());
442 }
443 return val;
444 }
445
GetIntValue(const json::value & jsonValue,const string_view name) const446 int64_t RenderNodeParserUtil::GetIntValue(const json::value& jsonValue, const string_view name) const
447 {
448 int64_t val = std::numeric_limits<int64_t>::max();
449 string error;
450 if (!SafeGetJsonValue(jsonValue, name, error, val)) {
451 PLUGIN_LOG_W("GetIntValue: %s", error.c_str());
452 }
453 return val;
454 }
455
GetFloatValue(const json::value & jsonValue,const string_view name) const456 float RenderNodeParserUtil::GetFloatValue(const json::value& jsonValue, const string_view name) const
457 {
458 float val = std::numeric_limits<float>::max();
459 string error;
460 if (!SafeGetJsonValue(jsonValue, name, error, val)) {
461 PLUGIN_LOG_W("GetFloatValue: %s", error.c_str());
462 }
463 return val;
464 }
465
GetStringValue(const json::value & jsonValue,const string_view name) const466 string RenderNodeParserUtil::GetStringValue(const json::value& jsonValue, const string_view name) const
467 {
468 string parsedString;
469 string error;
470 if (!SafeGetJsonValue(jsonValue, name, error, parsedString)) {
471 PLUGIN_LOG_W("GetStringValue: %s", error.c_str());
472 }
473 return parsedString;
474 }
475
GetInputRenderPass(const json::value & jsonValue,const string_view name) const476 RenderNodeGraphInputs::InputRenderPass RenderNodeParserUtil::GetInputRenderPass(
477 const json::value& jsonValue, const string_view name) const
478 {
479 RenderNodeGraphInputs::InputRenderPass renderPass;
480 LoadResult result;
481 ParseRenderpass(name, jsonValue, renderPass, result);
482 if (!result.error.empty()) {
483 PLUGIN_LOG_W("GetInputRenderPass: %s", result.error.c_str());
484 }
485 return renderPass;
486 }
487
GetInputResources(const json::value & jsonValue,const string_view name) const488 RenderNodeGraphInputs::InputResources RenderNodeParserUtil::GetInputResources(
489 const json::value& jsonValue, const string_view name) const
490 {
491 RenderNodeGraphInputs::InputResources resources;
492 LoadResult result;
493 ParseResources(name, jsonValue, resources, result);
494 if (!result.error.empty()) {
495 PLUGIN_LOG_W("GetInputResources: %s", result.error.c_str());
496 }
497 return resources;
498 }
499
GetRenderDataStore(const json::value & jsonValue,const string_view name) const500 RenderNodeGraphInputs::RenderDataStore RenderNodeParserUtil::GetRenderDataStore(
501 const json::value& jsonValue, const string_view name) const
502 {
503 RenderNodeGraphInputs::RenderDataStore renderDataStore;
504 LoadResult result;
505 if (auto const dataStore = jsonValue.find(name); dataStore) {
506 SafeGetJsonValue(*dataStore, "dataStoreName", result.error, renderDataStore.dataStoreName);
507 SafeGetJsonValue(*dataStore, "typeName", result.error, renderDataStore.typeName);
508 SafeGetJsonValue(*dataStore, "configurationName", result.error, renderDataStore.configurationName);
509 }
510 if (!result.error.empty()) {
511 PLUGIN_LOG_W("GetRenderDataStore: %s", result.error.c_str());
512 }
513 return renderDataStore;
514 }
515
GetGpuImageDescs(const json::value & jsonValue,const string_view name) const516 vector<RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc> RenderNodeParserUtil::GetGpuImageDescs(
517 const json::value& jsonValue, const string_view name) const
518 {
519 vector<RenderNodeGraphInputs::RenderNodeGraphGpuImageDesc> resources;
520 LoadResult result;
521 if (const auto ref = jsonValue.find(name); ref) {
522 if (ref->is_array()) {
523 ParseArray<decltype(resources)::value_type>(jsonValue, name.data(), resources, result);
524 } else {
525 result.error += "expecting array";
526 }
527 }
528 if (!result.error.empty()) {
529 PLUGIN_LOG_W("GetGpuImageDescs: %s", result.error.c_str());
530 }
531 return resources;
532 }
533
GetGpuBufferDescs(const json::value & jsonValue,const string_view name) const534 vector<RenderNodeGraphInputs::RenderNodeGraphGpuBufferDesc> RenderNodeParserUtil::GetGpuBufferDescs(
535 const json::value& jsonValue, const string_view name) const
536 {
537 vector<RenderNodeGraphInputs::RenderNodeGraphGpuBufferDesc> resources;
538 LoadResult result;
539 if (const auto ref = jsonValue.find(name); ref) {
540 if (ref->is_array()) {
541 ParseArray<decltype(resources)::value_type>(jsonValue, name.data(), resources, result);
542 } else {
543 result.error += "expecting array";
544 }
545 }
546 if (!result.error.empty()) {
547 PLUGIN_LOG_W("GetGpuBufferDescs: %s", result.error.c_str());
548 }
549 return resources;
550 }
551
GetRenderSlotSortType(const json::value & jsonValue,const string_view name) const552 RenderSlotSortType RenderNodeParserUtil::GetRenderSlotSortType(
553 const json::value& jsonValue, const string_view name) const
554 {
555 RenderSlotSortType sortType = RenderSlotSortType::NONE;
556 string error;
557 if (!SafeGetJsonEnum(jsonValue, name, error, sortType)) {
558 PLUGIN_LOG_W("GetRenderSlotSortType: %s", error.c_str());
559 }
560 return sortType;
561 }
562
GetRenderSlotCullType(const json::value & jsonValue,const string_view name) const563 RenderSlotCullType RenderNodeParserUtil::GetRenderSlotCullType(
564 const json::value& jsonValue, const string_view name) const
565 {
566 RenderSlotCullType cullType = RenderSlotCullType::NONE;
567 string error;
568 if (!SafeGetJsonEnum(jsonValue, name, error, cullType)) {
569 PLUGIN_LOG_W("GetRenderSlotCullType: %s", error.c_str());
570 }
571 return cullType;
572 }
573
GetInterface(const BASE_NS::Uid & uid) const574 const CORE_NS::IInterface* RenderNodeParserUtil::GetInterface(const BASE_NS::Uid& uid) const
575 {
576 if ((uid == IRenderNodeParserUtil::UID) || (uid == IInterface::UID)) {
577 return this;
578 }
579 return nullptr;
580 }
581
GetInterface(const BASE_NS::Uid & uid)582 CORE_NS::IInterface* RenderNodeParserUtil::GetInterface(const BASE_NS::Uid& uid)
583 {
584 if ((uid == IRenderNodeParserUtil::UID) || (uid == IInterface::UID)) {
585 return this;
586 }
587 return nullptr;
588 }
589
Ref()590 void RenderNodeParserUtil::Ref() {}
591
Unref()592 void RenderNodeParserUtil::Unref() {}
593 RENDER_END_NAMESPACE()
594