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