• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "shader_state_loader_util.h"
17 
18 #include <core/namespace.h>
19 
20 #include "json_util.h"
21 #include "shader_state_loader.h"
22 #include "util/log.h"
23 
24 using namespace BASE_NS;
25 using namespace CORE_NS;
26 
27 RENDER_BEGIN_NAMESPACE()
28 // clang-format off
29 CORE_JSON_SERIALIZE_ENUM(PrimitiveTopology,
30     {
31         { CORE_PRIMITIVE_TOPOLOGY_MAX_ENUM, nullptr },
32         { CORE_PRIMITIVE_TOPOLOGY_POINT_LIST, "point_list" },
33         { CORE_PRIMITIVE_TOPOLOGY_LINE_LIST, "line_list" },
34         { CORE_PRIMITIVE_TOPOLOGY_LINE_STRIP, "line_strip" },
35         { CORE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, "triangle_list" },
36         { CORE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, "triangle_strip" },
37         { CORE_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, "triangle_fan" },
38         { CORE_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, "line_list_with_adjacency" },
39         { CORE_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY, "line_strip_with_adjacency" },
40         { CORE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY, "triangle_list_with_adjacency" },
41         { CORE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY, "triangle_strip_with_adjacency" },
42         { CORE_PRIMITIVE_TOPOLOGY_PATCH_LIST, "patch_list" },
43     })
44 
45 CORE_JSON_SERIALIZE_ENUM(PolygonMode,
46     {
47         { CORE_POLYGON_MODE_MAX_ENUM, nullptr },
48         { CORE_POLYGON_MODE_FILL, "fill" },
49         { CORE_POLYGON_MODE_LINE, "line" },
50         { CORE_POLYGON_MODE_POINT, "point" },
51     })
52 
53 CORE_JSON_SERIALIZE_ENUM(CullModeFlagBits,
54     {
55         { CORE_CULL_MODE_FLAG_BITS_MAX_ENUM, nullptr },
56         { CORE_CULL_MODE_NONE, "none" },
57         { CORE_CULL_MODE_FRONT_BIT, "front" },
58         { CORE_CULL_MODE_BACK_BIT, "back" },
59         { CORE_CULL_MODE_FRONT_AND_BACK, "front_and_back" },
60     })
61 
62 CORE_JSON_SERIALIZE_ENUM(FrontFace,
63     {
64         { CORE_FRONT_FACE_MAX_ENUM, nullptr },
65         { CORE_FRONT_FACE_COUNTER_CLOCKWISE, "counter_clockwise" },
66         { CORE_FRONT_FACE_CLOCKWISE, "clockwise" },
67     })
68 
69 CORE_JSON_SERIALIZE_ENUM(CompareOp,
70     {
71         { CORE_COMPARE_OP_MAX_ENUM, nullptr },
72         { CORE_COMPARE_OP_NEVER, "never" },
73         { CORE_COMPARE_OP_LESS, "less" },
74         { CORE_COMPARE_OP_EQUAL, "equal" },
75         { CORE_COMPARE_OP_LESS_OR_EQUAL, "less_or_equal" },
76         { CORE_COMPARE_OP_GREATER, "greater" },
77         { CORE_COMPARE_OP_NOT_EQUAL, "not_equal" },
78         { CORE_COMPARE_OP_GREATER_OR_EQUAL, "greater_or_equal" },
79         { CORE_COMPARE_OP_ALWAYS, "always" },
80     })
81 
82 CORE_JSON_SERIALIZE_ENUM(StencilOp,
83     {
84         { CORE_STENCIL_OP_MAX_ENUM, nullptr },
85         { CORE_STENCIL_OP_KEEP, "keep" },
86         { CORE_STENCIL_OP_ZERO, "zero" },
87         { CORE_STENCIL_OP_REPLACE, "replace" },
88         { CORE_STENCIL_OP_INCREMENT_AND_CLAMP, "increment_and_clamp" },
89         { CORE_STENCIL_OP_DECREMENT_AND_CLAMP, "decrement_and_clamp" },
90         { CORE_STENCIL_OP_INVERT, "invert" },
91         { CORE_STENCIL_OP_INCREMENT_AND_WRAP, "increment_and_wrap" },
92         { CORE_STENCIL_OP_DECREMENT_AND_WRAP, "decrement_and_wrap" },
93     })
94 
95 CORE_JSON_SERIALIZE_ENUM(BlendFactor,
96     {
97         { CORE_BLEND_FACTOR_MAX_ENUM, nullptr },
98         { CORE_BLEND_FACTOR_ZERO, "zero" },
99         { CORE_BLEND_FACTOR_ONE, "one" },
100         { CORE_BLEND_FACTOR_SRC_COLOR, "src_color" },
101         { CORE_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, "one_minus_src_color" },
102         { CORE_BLEND_FACTOR_DST_COLOR, "dst_color" },
103         { CORE_BLEND_FACTOR_ONE_MINUS_DST_COLOR, "one_minus_dst_color" },
104         { CORE_BLEND_FACTOR_SRC_ALPHA, "src_alpha" },
105         { CORE_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, "one_minus_src_alpha" },
106         { CORE_BLEND_FACTOR_DST_ALPHA, "dst_alpha" },
107         { CORE_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, "one_minus_dst_alpha" },
108         { CORE_BLEND_FACTOR_CONSTANT_COLOR, "constant_color" },
109         { CORE_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, "one_minus_constant_color" },
110         { CORE_BLEND_FACTOR_CONSTANT_ALPHA, "constant_alpha" },
111         { CORE_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, "one_minus_constant_alpha" },
112         { CORE_BLEND_FACTOR_SRC_ALPHA_SATURATE, "src_alpha_saturate" },
113         { CORE_BLEND_FACTOR_SRC1_COLOR, "src1_color" },
114         { CORE_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, "one_minus_src1_color" },
115         { CORE_BLEND_FACTOR_SRC1_ALPHA, "src1_alpha" },
116         { CORE_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, "one_minus_src1_alpha" },
117     })
118 
119 CORE_JSON_SERIALIZE_ENUM(BlendOp,
120     {
121         { CORE_BLEND_OP_MAX_ENUM, nullptr },
122         { CORE_BLEND_OP_ADD, "add" },
123         { CORE_BLEND_OP_SUBTRACT, "subtract" },
124         { CORE_BLEND_OP_REVERSE_SUBTRACT, "reverse_subtract" },
125         { CORE_BLEND_OP_MIN, "min" },
126         { CORE_BLEND_OP_MAX, "max" },
127     })
128 
129 CORE_JSON_SERIALIZE_ENUM(ColorComponentFlagBits,
130     {
131         { CORE_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM, nullptr },
132         { CORE_COLOR_COMPONENT_R_BIT, "r_bit" },
133         { CORE_COLOR_COMPONENT_G_BIT, "g_bit" },
134         { CORE_COLOR_COMPONENT_B_BIT, "b_bit" },
135         { CORE_COLOR_COMPONENT_A_BIT, "a_bit" },
136     })
137 
138 CORE_JSON_SERIALIZE_ENUM(LogicOp,
139     {
140         { CORE_LOGIC_OP_MAX_ENUM, nullptr },
141         { CORE_LOGIC_OP_CLEAR, "clear" },
142         { CORE_LOGIC_OP_AND, "and" },
143         { CORE_LOGIC_OP_AND_REVERSE, "and_reverse" },
144         { CORE_LOGIC_OP_COPY, "copy" },
145         { CORE_LOGIC_OP_AND_INVERTED, "and_inverted" },
146         { CORE_LOGIC_OP_NO_OP, "no_op" },
147         { CORE_LOGIC_OP_XOR, "xor" },
148         { CORE_LOGIC_OP_OR, "or" },
149         { CORE_LOGIC_OP_NOR, "nor" },
150         { CORE_LOGIC_OP_EQUIVALENT, "equivalent" },
151         { CORE_LOGIC_OP_INVERT, "invert" },
152         { CORE_LOGIC_OP_OR_REVERSE, "or_reverse" },
153         { CORE_LOGIC_OP_COPY_INVERTED, "copy_inverted" },
154         { CORE_LOGIC_OP_OR_INVERTED, "or_inverted" },
155         { CORE_LOGIC_OP_NAND, "nand" },
156         { CORE_LOGIC_OP_SET, "set" },
157     })
158 // clang-format on
FromJson(const json::value & jsonData,JsonContext<GraphicsState::InputAssembly> & context)159 void FromJson(const json::value& jsonData, JsonContext<GraphicsState::InputAssembly>& context)
160 {
161     SafeGetJsonValue(jsonData, "enablePrimitiveRestart", context.error, context.data.enablePrimitiveRestart);
162     SafeGetJsonEnum(jsonData, "primitiveTopology", context.error, context.data.primitiveTopology);
163 }
164 
FromJson(const json::value & jsonData,JsonContext<GraphicsState::RasterizationState> & context)165 void FromJson(const json::value& jsonData, JsonContext<GraphicsState::RasterizationState>& context)
166 {
167     SafeGetJsonValue(jsonData, "enableDepthClamp", context.error, context.data.enableDepthClamp);
168     SafeGetJsonValue(jsonData, "enableDepthBias", context.error, context.data.enableDepthBias);
169     SafeGetJsonValue(jsonData, "enableRasterizerDiscard", context.error, context.data.enableRasterizerDiscard);
170 
171     SafeGetJsonEnum(jsonData, "polygonMode", context.error, context.data.polygonMode);
172     SafeGetJsonBitfield<CullModeFlagBits>(jsonData, "cullModeFlags", context.error, context.data.cullModeFlags);
173     SafeGetJsonEnum(jsonData, "frontFace", context.error, context.data.frontFace);
174 
175     SafeGetJsonValue(jsonData, "depthBiasConstantFactor", context.error, context.data.depthBiasConstantFactor);
176     SafeGetJsonValue(jsonData, "depthBiasClamp", context.error, context.data.depthBiasClamp);
177     SafeGetJsonValue(jsonData, "depthBiasSlopeFactor", context.error, context.data.depthBiasSlopeFactor);
178 
179     SafeGetJsonValue(jsonData, "lineWidth", context.error, context.data.lineWidth);
180 }
181 
FromJson(const json::value & jsonData,JsonContext<GraphicsState::StencilOpState> & context)182 void FromJson(const json::value& jsonData, JsonContext<GraphicsState::StencilOpState>& context)
183 {
184     SafeGetJsonEnum(jsonData, "failOp", context.error, context.data.failOp);
185     SafeGetJsonEnum(jsonData, "passOp", context.error, context.data.passOp);
186     SafeGetJsonEnum(jsonData, "depthFailOp", context.error, context.data.depthFailOp);
187     SafeGetJsonEnum(jsonData, "compareOp", context.error, context.data.compareOp);
188     SafeGetJsonMask(jsonData, "compareMask", context.error, context.data.compareMask);
189     SafeGetJsonMask(jsonData, "writeMask", context.error, context.data.writeMask);
190     SafeGetJsonMask(jsonData, "reference", context.error, context.data.reference);
191 }
192 
FromJson(const json::value & jsonData,JsonContext<GraphicsState::DepthStencilState> & context)193 void FromJson(const json::value& jsonData, JsonContext<GraphicsState::DepthStencilState>& context)
194 {
195     SafeGetJsonValue(jsonData, "enableDepthTest", context.error, context.data.enableDepthTest);
196     SafeGetJsonValue(jsonData, "enableDepthWrite", context.error, context.data.enableDepthWrite);
197     SafeGetJsonValue(jsonData, "enableDepthBoundsTest", context.error, context.data.enableDepthBoundsTest);
198     SafeGetJsonValue(jsonData, "enableStencilTest", context.error, context.data.enableStencilTest);
199 
200     SafeGetJsonValue(jsonData, "minDepthBounds", context.error, context.data.minDepthBounds);
201     SafeGetJsonValue(jsonData, "maxDepthBounds", context.error, context.data.maxDepthBounds);
202 
203     SafeGetJsonEnum(jsonData, "depthCompareOp", context.error, context.data.depthCompareOp);
204 
205     if (const json::value* frontStencilStateIt = jsonData.find("frontStencilOpState"); frontStencilStateIt) {
206         JsonContext<GraphicsState::StencilOpState> stencilContext;
207         FromJson(*frontStencilStateIt, stencilContext);
208         context.data.frontStencilOpState = stencilContext.data;
209         if (!stencilContext.error.empty()) {
210             context.error = stencilContext.error;
211         }
212     }
213 
214     if (const json::value* backStencilStateIt = jsonData.find("backStencilOpState"); backStencilStateIt) {
215         JsonContext<GraphicsState::StencilOpState> stencilContext;
216         FromJson(*backStencilStateIt, stencilContext);
217         context.data.backStencilOpState = stencilContext.data;
218         if (!stencilContext.error.empty()) {
219             context.error = stencilContext.error;
220         }
221     }
222 }
223 
FromJson(const json::value & jsonData,JsonContext<GraphicsState::ColorBlendState::Attachment> & context)224 void FromJson(const json::value& jsonData, JsonContext<GraphicsState::ColorBlendState::Attachment>& context)
225 {
226     SafeGetJsonValue(jsonData, "enableBlend", context.error, context.data.enableBlend);
227     SafeGetJsonBitfield<ColorComponentFlagBits>(jsonData, "colorWriteMask", context.error, context.data.colorWriteMask);
228 
229     SafeGetJsonEnum(jsonData, "srcColorBlendFactor", context.error, context.data.srcColorBlendFactor);
230     SafeGetJsonEnum(jsonData, "dstColorBlendFactor", context.error, context.data.dstColorBlendFactor);
231     SafeGetJsonEnum(jsonData, "colorBlendOp", context.error, context.data.colorBlendOp);
232 
233     SafeGetJsonEnum(jsonData, "srcAlphaBlendFactor", context.error, context.data.srcAlphaBlendFactor);
234     SafeGetJsonEnum(jsonData, "dstAlphaBlendFactor", context.error, context.data.dstAlphaBlendFactor);
235     SafeGetJsonEnum(jsonData, "alphaBlendOp", context.error, context.data.alphaBlendOp);
236 }
237 
FromJson(const json::value & jsonData,JsonContext<GraphicsState::ColorBlendState> & context)238 void FromJson(const json::value& jsonData, JsonContext<GraphicsState::ColorBlendState>& context)
239 {
240     SafeGetJsonValue(jsonData, "enableLogicOp", context.error, context.data.enableLogicOp);
241     SafeGetJsonEnum(jsonData, "logicOp", context.error, context.data.logicOp);
242 
243     if (const json::value* colorBlendConstantsIt = jsonData.find("colorBlendConstants"); colorBlendConstantsIt) {
244         FromJson(*colorBlendConstantsIt, context.data.colorBlendConstants);
245     }
246 
247     if (const json::value* colorAttachmentsIt = jsonData.find("colorAttachments"); colorAttachmentsIt) {
248         vector<JsonContext<GraphicsState::ColorBlendState::Attachment>> colorContexts;
249         FromJson(*colorAttachmentsIt, colorContexts);
250         context.data.colorAttachmentCount = 0;
251         for (auto& colorContext : colorContexts) {
252             context.data.colorAttachments[context.data.colorAttachmentCount] = colorContext.data;
253             context.data.colorAttachmentCount++;
254 
255             if (!colorContext.error.empty()) {
256                 context.error = colorContext.error;
257             }
258         }
259     }
260 }
261 
262 namespace ShaderStateLoaderUtil {
ParseSingleState(const json::value & jsonData,ShaderStateResult & ssr)263 void ParseSingleState(const json::value& jsonData, ShaderStateResult& ssr)
264 {
265     GraphicsState graphicsState;
266     // Read input assembly.
267     if (const json::value* inputAssemblyIt = jsonData.find("inputAssembly"); inputAssemblyIt) {
268         JsonContext<GraphicsState::InputAssembly> context;
269         FromJson(*inputAssemblyIt, context);
270         graphicsState.inputAssembly = context.data;
271 
272         if (!context.error.empty()) {
273             ssr.res.error += context.error;
274         }
275     }
276 
277     // Read rasterization state.
278     if (const json::value* rasterizationStateIt = jsonData.find("rasterizationState"); rasterizationStateIt) {
279         JsonContext<GraphicsState::RasterizationState> context;
280         FromJson(*rasterizationStateIt, context);
281         graphicsState.rasterizationState = context.data;
282 
283         if (!context.error.empty()) {
284             ssr.res.error += context.error;
285         }
286     }
287 
288     // Read depth stencil state
289     if (const json::value* depthStencilStateIt = jsonData.find("depthStencilState"); depthStencilStateIt) {
290         JsonContext<GraphicsState::DepthStencilState> context;
291         FromJson(*depthStencilStateIt, context);
292         graphicsState.depthStencilState = context.data;
293 
294         if (!context.error.empty()) {
295             ssr.res.error += context.error;
296         }
297     }
298 
299     // Read depth color blend state.
300     if (const json::value* colorBlendStateIt = jsonData.find("colorBlendState"); colorBlendStateIt) {
301         JsonContext<GraphicsState::ColorBlendState> context;
302         FromJson(*colorBlendStateIt, context);
303         graphicsState.colorBlendState = context.data;
304 
305         if (!context.error.empty()) {
306             ssr.res.error += context.error;
307         }
308     }
309 
310     ssr.res.success = ssr.res.error.empty();
311     if (ssr.res.success) {
312         ssr.states.states.emplace_back(move(graphicsState));
313     }
314 }
315 
LoadStates(const json::value & jsonData)316 ShaderStateResult LoadStates(const json::value& jsonData)
317 {
318     ShaderStateResult ssr;
319     if (const json::value* iter = jsonData.find("shaderStates"); iter) {
320         const auto& allStates = iter->array_;
321         ssr.states.states.reserve(allStates.size());
322         for (auto const& state : allStates) {
323             ShaderStateLoaderVariantData variant;
324             SafeGetJsonValue(state, "variantName", ssr.res.error, variant.variantName);
325             if (variant.variantName.empty()) {
326                 ssr.res.error += "graphics state variant name needs to be given\n";
327             }
328             if (ssr.res.error.empty()) {
329                 if (const json::value* graphicsStateIt = state.find("state"); graphicsStateIt) {
330                     ParseSingleState(*graphicsStateIt, ssr);
331                     if (ssr.res.error.empty()) {
332                         SafeGetJsonValue(state, "baseShaderState", ssr.res.error, variant.baseShaderState);
333                         SafeGetJsonValue(state, "baseVariantName", ssr.res.error, variant.baseVariantName);
334                         SafeGetJsonValue(state, "renderSlot", ssr.res.error, variant.renderSlot);
335                         SafeGetJsonValue(
336                             state, "renderSlotDefaultShaderState", ssr.res.error, variant.renderSlotDefaultState);
337                         ssr.states.variantData.emplace_back(move(variant));
338                     }
339                 }
340             }
341         }
342     }
343 
344     ssr.res.success = ssr.res.error.empty();
345     if (!ssr.res.success) {
346         ssr.res.error += "error loading shader states\n";
347         PLUGIN_LOG_E("error loading shader states: %s", ssr.res.error.c_str());
348         ssr.states.states.clear();
349     }
350     return ssr;
351 }
352 } // namespace ShaderStateLoaderUtil
353 RENDER_END_NAMESPACE()
354