• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "util/shader_saver.h"
17 
18 #include <array>
19 
20 template<typename Key, typename Value>
21 struct PairLike {
22     Key first;
23     Value second;
24 };
25 
26 template<typename Key, typename Value, size_t Size>
27 struct CTMap {
28     std::array<PairLike<Key, Value>, Size> data;
atCTMap29     constexpr const Value& at(const Key& key) const
30     {
31         for (size_t i = 0; i < Size; ++i) {
32             if (data[i].first == key) {
33                 return data[i].second;
34             }
35         }
36         return defaultValue;
37     }
38     static constexpr Value defaultValue {};
39 };
40 
41 using namespace BASE_NS;
42 using namespace CORE_NS;
43 
44 RENDER_BEGIN_NAMESPACE()
45 namespace {
46 constexpr CTMap<BlendOp, const char*, 5U> blendOpToString { { PairLike<BlendOp, const char*> {
47                                                                   CORE_BLEND_OP_ADD, "add" },
48     PairLike<BlendOp, const char*> { CORE_BLEND_OP_SUBTRACT, "subtract" },
49     PairLike<BlendOp, const char*> { CORE_BLEND_OP_REVERSE_SUBTRACT, "reverse_subtract" },
50     PairLike<BlendOp, const char*> { CORE_BLEND_OP_MIN, "min" },
51     PairLike<BlendOp, const char*> { CORE_BLEND_OP_MAX, "max" } } };
52 
53 constexpr CTMap<BlendFactor, const char*, 19U> blendFactorToString { { PairLike<BlendFactor, const char*> {
54                                                                            CORE_BLEND_FACTOR_ZERO, "zero" },
55     PairLike<BlendFactor, const char*> { CORE_BLEND_FACTOR_ONE, "one" },
56     PairLike<BlendFactor, const char*> { CORE_BLEND_FACTOR_SRC_COLOR, "src_color" },
57     PairLike<BlendFactor, const char*> { CORE_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, "one_minus_src_color" },
58     PairLike<BlendFactor, const char*> { CORE_BLEND_FACTOR_DST_COLOR, "dst_color" },
59     PairLike<BlendFactor, const char*> { CORE_BLEND_FACTOR_ONE_MINUS_DST_COLOR, "one_minus_dst_color" },
60     PairLike<BlendFactor, const char*> { CORE_BLEND_FACTOR_SRC_ALPHA, "src_alpha" },
61     PairLike<BlendFactor, const char*> { CORE_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, "one_minus_src_alpha" },
62     PairLike<BlendFactor, const char*> { CORE_BLEND_FACTOR_DST_ALPHA, "dst_alpha" },
63     PairLike<BlendFactor, const char*> { CORE_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, "one_minus_dst_alpha" },
64     PairLike<BlendFactor, const char*> { CORE_BLEND_FACTOR_CONSTANT_COLOR, "constant_color" },
65     PairLike<BlendFactor, const char*> { CORE_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, "one_minus_constant_color" },
66     PairLike<BlendFactor, const char*> { CORE_BLEND_FACTOR_CONSTANT_ALPHA, "constant_alpha" },
67     PairLike<BlendFactor, const char*> { CORE_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, "one_minus_constant_alpha" },
68     PairLike<BlendFactor, const char*> { CORE_BLEND_FACTOR_SRC_ALPHA_SATURATE, "src_alpha_saturate" },
69     PairLike<BlendFactor, const char*> { CORE_BLEND_FACTOR_SRC1_COLOR, "src1_color" },
70     PairLike<BlendFactor, const char*> { CORE_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, "one_minus_src1_color" },
71     PairLike<BlendFactor, const char*> { CORE_BLEND_FACTOR_SRC1_ALPHA, "src1_alpha" },
72     PairLike<BlendFactor, const char*> { CORE_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, "one_minus_src1_alpha" } } };
73 
74 constexpr CTMap<Format, const char*, 192U> formatToString { { PairLike<Format, const char*> {
75                                                                   BASE_FORMAT_UNDEFINED, "undefined" },
76     PairLike<Format, const char*> { BASE_FORMAT_R4G4_UNORM_PACK8, "r4g4_unorm_pack8" },
77     PairLike<Format, const char*> { BASE_FORMAT_R4G4B4A4_UNORM_PACK16, "r4g4b4a4_unorm_pack16" },
78     PairLike<Format, const char*> { BASE_FORMAT_B4G4R4A4_UNORM_PACK16, "b4g4r4a4_unorm_pack16" },
79     PairLike<Format, const char*> { BASE_FORMAT_R5G6B5_UNORM_PACK16, "r5g6b5_unorm_pack16" },
80     PairLike<Format, const char*> { BASE_FORMAT_B5G6R5_UNORM_PACK16, "b5g6r5_unorm_pack16" },
81     PairLike<Format, const char*> { BASE_FORMAT_R5G5B5A1_UNORM_PACK16, "r5g5b5a1_unorm_pack16" },
82     PairLike<Format, const char*> { BASE_FORMAT_B5G5R5A1_UNORM_PACK16, "b5g5r5a1_unorm_pack16" },
83     PairLike<Format, const char*> { BASE_FORMAT_A1R5G5B5_UNORM_PACK16, "a1r5g5b5_unorm_pack16" },
84     PairLike<Format, const char*> { BASE_FORMAT_R8_UNORM, "r8_unorm" },
85     PairLike<Format, const char*> { BASE_FORMAT_R8_SNORM, "r8_snorm" },
86     PairLike<Format, const char*> { BASE_FORMAT_R8_USCALED, "r8_uscaled" },
87     PairLike<Format, const char*> { BASE_FORMAT_R8_SSCALED, "r8_sscaled" },
88     PairLike<Format, const char*> { BASE_FORMAT_R8_UINT, "r8_uint" },
89     PairLike<Format, const char*> { BASE_FORMAT_R8_SINT, "r8_sint" },
90     PairLike<Format, const char*> { BASE_FORMAT_R8_SRGB, "r8_srgb" },
91     PairLike<Format, const char*> { BASE_FORMAT_R8G8_UNORM, "r8g8_unorm" },
92     PairLike<Format, const char*> { BASE_FORMAT_R8G8_SNORM, "r8g8_snorm" },
93     PairLike<Format, const char*> { BASE_FORMAT_R8G8_USCALED, "r8g8_uscaled" },
94     PairLike<Format, const char*> { BASE_FORMAT_R8G8_SSCALED, "r8g8_sscaled" },
95     PairLike<Format, const char*> { BASE_FORMAT_R8G8_UINT, "r8g8_uint" },
96     PairLike<Format, const char*> { BASE_FORMAT_R8G8_SINT, "r8g8_sint" },
97     PairLike<Format, const char*> { BASE_FORMAT_R8G8_SRGB, "r8g8_srgb" },
98     PairLike<Format, const char*> { BASE_FORMAT_R8G8B8_UNORM, "r8g8b8_unorm" },
99     PairLike<Format, const char*> { BASE_FORMAT_R8G8B8_SNORM, "r8g8b8_snorm" },
100     PairLike<Format, const char*> { BASE_FORMAT_R8G8B8_USCALED, "r8g8b8_uscaled" },
101     PairLike<Format, const char*> { BASE_FORMAT_R8G8B8_SSCALED, "r8g8b8_sscaled" },
102     PairLike<Format, const char*> { BASE_FORMAT_R8G8B8_UINT, "r8g8b8_uint" },
103     PairLike<Format, const char*> { BASE_FORMAT_R8G8B8_SINT, "r8g8b8_sint" },
104     PairLike<Format, const char*> { BASE_FORMAT_R8G8B8_SRGB, "r8g8b8_srgb" },
105     PairLike<Format, const char*> { BASE_FORMAT_B8G8R8_UNORM, "b8g8r8_unorm" },
106     PairLike<Format, const char*> { BASE_FORMAT_B8G8R8_SNORM, "b8g8r8_snorm" },
107     PairLike<Format, const char*> { BASE_FORMAT_B8G8R8_USCALED, "b8g8r8_uscaled" },
108     PairLike<Format, const char*> { BASE_FORMAT_B8G8R8_SSCALED, "b8g8r8_sscaled" },
109     PairLike<Format, const char*> { BASE_FORMAT_B8G8R8_UINT, "b8g8r8_uint" },
110     PairLike<Format, const char*> { BASE_FORMAT_B8G8R8_SINT, "b8g8r8_sint" },
111     PairLike<Format, const char*> { BASE_FORMAT_B8G8R8_SRGB, "b8g8r8_srgb" },
112     PairLike<Format, const char*> { BASE_FORMAT_R8G8B8A8_UNORM, "r8g8b8a8_unorm" },
113     PairLike<Format, const char*> { BASE_FORMAT_R8G8B8A8_SNORM, "r8g8b8a8_snorm" },
114     PairLike<Format, const char*> { BASE_FORMAT_R8G8B8A8_USCALED, "r8g8b8a8_uscaled" },
115     PairLike<Format, const char*> { BASE_FORMAT_R8G8B8A8_SSCALED, "r8g8b8a8_sscaled" },
116     PairLike<Format, const char*> { BASE_FORMAT_R8G8B8A8_UINT, "r8g8b8a8_uint" },
117     PairLike<Format, const char*> { BASE_FORMAT_R8G8B8A8_SINT, "r8g8b8a8_sint" },
118     PairLike<Format, const char*> { BASE_FORMAT_R8G8B8A8_SRGB, "r8g8b8a8_srgb" },
119     PairLike<Format, const char*> { BASE_FORMAT_B8G8R8A8_UNORM, "b8g8r8a8_unorm" },
120     PairLike<Format, const char*> { BASE_FORMAT_B8G8R8A8_SNORM, "b8g8r8a8_snorm" },
121     PairLike<Format, const char*> { BASE_FORMAT_B8G8R8A8_USCALED, "b8g8r8a8_uscaled" },
122     PairLike<Format, const char*> { BASE_FORMAT_B8G8R8A8_SSCALED, "b8g8r8a8_sscaled" },
123     PairLike<Format, const char*> { BASE_FORMAT_B8G8R8A8_UINT, "b8g8r8a8_uint" },
124     PairLike<Format, const char*> { BASE_FORMAT_B8G8R8A8_SINT, "b8g8r8a8_sint" },
125     PairLike<Format, const char*> { BASE_FORMAT_B8G8R8A8_SRGB, "b8g8r8a8_srgb" },
126     PairLike<Format, const char*> { BASE_FORMAT_A8B8G8R8_UNORM_PACK32, "a8b8g8r8_unorm_pack32" },
127     PairLike<Format, const char*> { BASE_FORMAT_A8B8G8R8_SNORM_PACK32, "a8b8g8r8_snorm_pack32" },
128     PairLike<Format, const char*> { BASE_FORMAT_A8B8G8R8_USCALED_PACK32, "a8b8g8r8_uscaled_pack32" },
129     PairLike<Format, const char*> { BASE_FORMAT_A8B8G8R8_SSCALED_PACK32, "a8b8g8r8_sscaled_pack32" },
130     PairLike<Format, const char*> { BASE_FORMAT_A8B8G8R8_UINT_PACK32, "a8b8g8r8_uint_pack32" },
131     PairLike<Format, const char*> { BASE_FORMAT_A8B8G8R8_SINT_PACK32, "a8b8g8r8_sint_pack32" },
132     PairLike<Format, const char*> { BASE_FORMAT_A8B8G8R8_SRGB_PACK32, "a8b8g8r8_srgb_pack32" },
133     PairLike<Format, const char*> { BASE_FORMAT_A2R10G10B10_UNORM_PACK32, "a2r10g10b10_unorm_pack32" },
134     PairLike<Format, const char*> { BASE_FORMAT_A2R10G10B10_SNORM_PACK32, "a2r10g10b10_snorm_pack32" },
135     PairLike<Format, const char*> { BASE_FORMAT_A2R10G10B10_USCALED_PACK32, "a2r10g10b10_uscaled_pack32" },
136     PairLike<Format, const char*> { BASE_FORMAT_A2R10G10B10_SSCALED_PACK32, "a2r10g10b10_sscaled_pack32" },
137     PairLike<Format, const char*> { BASE_FORMAT_A2R10G10B10_UINT_PACK32, "a2r10g10b10_uint_pack32" },
138     PairLike<Format, const char*> { BASE_FORMAT_A2R10G10B10_SINT_PACK32, "a2r10g10b10_sint_pack32" },
139     PairLike<Format, const char*> { BASE_FORMAT_A2B10G10R10_UNORM_PACK32, "a2b10g10r10_unorm_pack32" },
140     PairLike<Format, const char*> { BASE_FORMAT_A2B10G10R10_SNORM_PACK32, "a2b10g10r10_snorm_pack32" },
141     PairLike<Format, const char*> { BASE_FORMAT_A2B10G10R10_USCALED_PACK32, "a2b10g10r10_uscaled_pack32" },
142     PairLike<Format, const char*> { BASE_FORMAT_A2B10G10R10_SSCALED_PACK32, "a2b10g10r10_sscaled_pack32" },
143     PairLike<Format, const char*> { BASE_FORMAT_A2B10G10R10_UINT_PACK32, "a2b10g10r10_uint_pack32" },
144     PairLike<Format, const char*> { BASE_FORMAT_A2B10G10R10_SINT_PACK32, "a2b10g10r10_sint_pack32" },
145     PairLike<Format, const char*> { BASE_FORMAT_R16_UNORM, "r16_unorm" },
146     PairLike<Format, const char*> { BASE_FORMAT_R16_SNORM, "r16_snorm" },
147     PairLike<Format, const char*> { BASE_FORMAT_R16_USCALED, "r16_uscaled" },
148     PairLike<Format, const char*> { BASE_FORMAT_R16_SSCALED, "r16_sscaled" },
149     PairLike<Format, const char*> { BASE_FORMAT_R16_UINT, "r16_uint" },
150     PairLike<Format, const char*> { BASE_FORMAT_R16_SINT, "r16_sint" },
151     PairLike<Format, const char*> { BASE_FORMAT_R16_SFLOAT, "r16_sfloat" },
152     PairLike<Format, const char*> { BASE_FORMAT_R16G16_UNORM, "r16g16_unorm" },
153     PairLike<Format, const char*> { BASE_FORMAT_R16G16_SNORM, "r16g16_snorm" },
154     PairLike<Format, const char*> { BASE_FORMAT_R16G16_USCALED, "r16g16_uscaled" },
155     PairLike<Format, const char*> { BASE_FORMAT_R16G16_SSCALED, "r16g16_sscaled" },
156     PairLike<Format, const char*> { BASE_FORMAT_R16G16_UINT, "r16g16_uint" },
157     PairLike<Format, const char*> { BASE_FORMAT_R16G16_SINT, "r16g16_sint" },
158     PairLike<Format, const char*> { BASE_FORMAT_R16G16_SFLOAT, "r16g16_sfloat" },
159     PairLike<Format, const char*> { BASE_FORMAT_R16G16B16_UNORM, "r16g16b16_unorm" },
160     PairLike<Format, const char*> { BASE_FORMAT_R16G16B16_SNORM, "r16g16b16_snorm" },
161     PairLike<Format, const char*> { BASE_FORMAT_R16G16B16_USCALED, "r16g16b16_uscaled" },
162     PairLike<Format, const char*> { BASE_FORMAT_R16G16B16_SSCALED, "r16g16b16_sscaled" },
163     PairLike<Format, const char*> { BASE_FORMAT_R16G16B16_UINT, "r16g16b16_uint" },
164     PairLike<Format, const char*> { BASE_FORMAT_R16G16B16_SINT, "r16g16b16_sint" },
165     PairLike<Format, const char*> { BASE_FORMAT_R16G16B16_SFLOAT, "r16g16b16_sfloat" },
166     PairLike<Format, const char*> { BASE_FORMAT_R16G16B16A16_UNORM, "r16g16b16a16_unorm" },
167     PairLike<Format, const char*> { BASE_FORMAT_R16G16B16A16_SNORM, "r16g16b16a16_snorm" },
168     PairLike<Format, const char*> { BASE_FORMAT_R16G16B16A16_USCALED, "r16g16b16a16_uscaled" },
169     PairLike<Format, const char*> { BASE_FORMAT_R16G16B16A16_SSCALED, "r16g16b16a16_sscaled" },
170     PairLike<Format, const char*> { BASE_FORMAT_R16G16B16A16_UINT, "r16g16b16a16_uint" },
171     PairLike<Format, const char*> { BASE_FORMAT_R16G16B16A16_SINT, "r16g16b16a16_sint" },
172     PairLike<Format, const char*> { BASE_FORMAT_R16G16B16A16_SFLOAT, "r16g16b16a16_sfloat" },
173     PairLike<Format, const char*> { BASE_FORMAT_R32_UINT, "r32_uint" },
174     PairLike<Format, const char*> { BASE_FORMAT_R32_SINT, "r32_sint" },
175     PairLike<Format, const char*> { BASE_FORMAT_R32_SFLOAT, "r32_sfloat" },
176     PairLike<Format, const char*> { BASE_FORMAT_R32G32_UINT, "r32g32_uint" },
177     PairLike<Format, const char*> { BASE_FORMAT_R32G32_SINT, "r32g32_sint" },
178     PairLike<Format, const char*> { BASE_FORMAT_R32G32_SFLOAT, "r32g32_sfloat" },
179     PairLike<Format, const char*> { BASE_FORMAT_R32G32B32_UINT, "r32g32b32_uint" },
180     PairLike<Format, const char*> { BASE_FORMAT_R32G32B32_SINT, "r32g32b32_sint" },
181     PairLike<Format, const char*> { BASE_FORMAT_R32G32B32_SFLOAT, "r32g32b32_sfloat" },
182     PairLike<Format, const char*> { BASE_FORMAT_R32G32B32A32_UINT, "r32g32b32a32_uint" },
183     PairLike<Format, const char*> { BASE_FORMAT_R32G32B32A32_SINT, "r32g32b32a32_sint" },
184     PairLike<Format, const char*> { BASE_FORMAT_R32G32B32A32_SFLOAT, "r32g32b32a32_sfloat" },
185     PairLike<Format, const char*> { BASE_FORMAT_R64_UINT, "r64_uint" },
186     PairLike<Format, const char*> { BASE_FORMAT_R64_SINT, "r64_sint" },
187     PairLike<Format, const char*> { BASE_FORMAT_R64_SFLOAT, "r64_sfloat" },
188     PairLike<Format, const char*> { BASE_FORMAT_R64G64_UINT, "r64g64_uint" },
189     PairLike<Format, const char*> { BASE_FORMAT_R64G64_SINT, "r64g64_sint" },
190     PairLike<Format, const char*> { BASE_FORMAT_R64G64_SFLOAT, "r64g64_sfloat" },
191     PairLike<Format, const char*> { BASE_FORMAT_R64G64B64_UINT, "r64g64b64_uint" },
192     PairLike<Format, const char*> { BASE_FORMAT_R64G64B64_SINT, "r64g64b64_sint" },
193     PairLike<Format, const char*> { BASE_FORMAT_R64G64B64_SFLOAT, "r64g64b64_sfloat" },
194     PairLike<Format, const char*> { BASE_FORMAT_R64G64B64A64_UINT, "r64g64b64a64_uint" },
195     PairLike<Format, const char*> { BASE_FORMAT_R64G64B64A64_SINT, "r64g64b64a64_sint" },
196     PairLike<Format, const char*> { BASE_FORMAT_R64G64B64A64_SFLOAT, "r64g64b64a64_sfloat" },
197     PairLike<Format, const char*> { BASE_FORMAT_B10G11R11_UFLOAT_PACK32, "b10g11r11_ufloat_pack32" },
198     PairLike<Format, const char*> { BASE_FORMAT_E5B9G9R9_UFLOAT_PACK32, "e5b9g9r9_ufloat_pack32" },
199     PairLike<Format, const char*> { BASE_FORMAT_D16_UNORM, "d16_unorm" },
200     PairLike<Format, const char*> { BASE_FORMAT_X8_D24_UNORM_PACK32, "x8_d24_unorm_pack32" },
201     PairLike<Format, const char*> { BASE_FORMAT_D32_SFLOAT, "d32_sfloat" },
202     PairLike<Format, const char*> { BASE_FORMAT_S8_UINT, "s8_uint" },
203     PairLike<Format, const char*> { BASE_FORMAT_D16_UNORM_S8_UINT, "d16_unorm_s8_uint" },
204     PairLike<Format, const char*> { BASE_FORMAT_D24_UNORM_S8_UINT, "d24_unorm_s8_uint" },
205     PairLike<Format, const char*> { BASE_FORMAT_D32_SFLOAT_S8_UINT, "d32_sfloat_s8_uint" },
206     PairLike<Format, const char*> { BASE_FORMAT_BC1_RGB_UNORM_BLOCK, "bc1_rgb_unorm_block" },
207     PairLike<Format, const char*> { BASE_FORMAT_BC1_RGB_SRGB_BLOCK, "bc1_rgb_srgb_block" },
208     PairLike<Format, const char*> { BASE_FORMAT_BC1_RGBA_UNORM_BLOCK, "bc1_rgba_unorm_block" },
209     PairLike<Format, const char*> { BASE_FORMAT_BC1_RGBA_SRGB_BLOCK, "bc1_rgba_srgb_block" },
210     PairLike<Format, const char*> { BASE_FORMAT_BC2_UNORM_BLOCK, "bc2_unorm_block" },
211     PairLike<Format, const char*> { BASE_FORMAT_BC2_SRGB_BLOCK, "bc2_srgb_block" },
212     PairLike<Format, const char*> { BASE_FORMAT_BC3_UNORM_BLOCK, "bc3_unorm_block" },
213     PairLike<Format, const char*> { BASE_FORMAT_BC3_SRGB_BLOCK, "bc3_srgb_block" },
214     PairLike<Format, const char*> { BASE_FORMAT_BC4_UNORM_BLOCK, "bc4_unorm_block" },
215     PairLike<Format, const char*> { BASE_FORMAT_BC4_SNORM_BLOCK, "bc4_snorm_block" },
216     PairLike<Format, const char*> { BASE_FORMAT_BC5_UNORM_BLOCK, "bc5_unorm_block" },
217     PairLike<Format, const char*> { BASE_FORMAT_BC5_SNORM_BLOCK, "bc5_snorm_block" },
218     PairLike<Format, const char*> { BASE_FORMAT_BC6H_UFLOAT_BLOCK, "bc6h_ufloat_block" },
219     PairLike<Format, const char*> { BASE_FORMAT_BC6H_SFLOAT_BLOCK, "bc6h_sfloat_block" },
220     PairLike<Format, const char*> { BASE_FORMAT_BC7_UNORM_BLOCK, "bc7_unorm_block" },
221     PairLike<Format, const char*> { BASE_FORMAT_BC7_SRGB_BLOCK, "bc7_srgb_block" },
222     PairLike<Format, const char*> { BASE_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, "etc2_r8g8b8_unorm_block" },
223     PairLike<Format, const char*> { BASE_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, "etc2_r8g8b8_srgb_block" },
224     PairLike<Format, const char*> { BASE_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, "etc2_r8g8b8a1_unorm_block" },
225     PairLike<Format, const char*> { BASE_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, "etc2_r8g8b8a1_srgb_block" },
226     PairLike<Format, const char*> { BASE_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, "etc2_r8g8b8a8_unorm_block" },
227     PairLike<Format, const char*> { BASE_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, "etc2_r8g8b8a8_srgb_block" },
228     PairLike<Format, const char*> { BASE_FORMAT_EAC_R11_UNORM_BLOCK, "eac_r11_unorm_block" },
229     PairLike<Format, const char*> { BASE_FORMAT_EAC_R11_SNORM_BLOCK, "eac_r11_snorm_block" },
230     PairLike<Format, const char*> { BASE_FORMAT_EAC_R11G11_UNORM_BLOCK, "eac_r11g11_unorm_block" },
231     PairLike<Format, const char*> { BASE_FORMAT_EAC_R11G11_SNORM_BLOCK, "eac_r11g11_snorm_block" },
232     PairLike<Format, const char*> { BASE_FORMAT_ASTC_4x4_UNORM_BLOCK, "astc_4x4_unorm_block" },
233     PairLike<Format, const char*> { BASE_FORMAT_ASTC_4x4_SRGB_BLOCK, "astc_4x4_srgb_block" },
234     PairLike<Format, const char*> { BASE_FORMAT_ASTC_5x4_UNORM_BLOCK, "astc_5x4_unorm_block" },
235     PairLike<Format, const char*> { BASE_FORMAT_ASTC_5x4_SRGB_BLOCK, "astc_5x4_srgb_block" },
236     PairLike<Format, const char*> { BASE_FORMAT_ASTC_5x5_UNORM_BLOCK, "astc_5x5_unorm_block" },
237     PairLike<Format, const char*> { BASE_FORMAT_ASTC_5x5_SRGB_BLOCK, "astc_5x5_srgb_block" },
238     PairLike<Format, const char*> { BASE_FORMAT_ASTC_6x5_UNORM_BLOCK, "astc_6x5_unorm_block" },
239     PairLike<Format, const char*> { BASE_FORMAT_ASTC_6x5_SRGB_BLOCK, "astc_6x5_srgb_block" },
240     PairLike<Format, const char*> { BASE_FORMAT_ASTC_6x6_UNORM_BLOCK, "astc_6x6_unorm_block" },
241     PairLike<Format, const char*> { BASE_FORMAT_ASTC_6x6_SRGB_BLOCK, "astc_6x6_srgb_block" },
242     PairLike<Format, const char*> { BASE_FORMAT_ASTC_8x5_UNORM_BLOCK, "astc_8x5_unorm_block" },
243     PairLike<Format, const char*> { BASE_FORMAT_ASTC_8x5_SRGB_BLOCK, "astc_8x5_srgb_block" },
244     PairLike<Format, const char*> { BASE_FORMAT_ASTC_8x6_UNORM_BLOCK, "astc_8x6_unorm_block" },
245     PairLike<Format, const char*> { BASE_FORMAT_ASTC_8x6_SRGB_BLOCK, "astc_8x6_srgb_block" },
246     PairLike<Format, const char*> { BASE_FORMAT_ASTC_8x8_UNORM_BLOCK, "astc_8x8_unorm_block" },
247     PairLike<Format, const char*> { BASE_FORMAT_ASTC_8x8_SRGB_BLOCK, "astc_8x8_srgb_block" },
248     PairLike<Format, const char*> { BASE_FORMAT_ASTC_10x5_UNORM_BLOCK, "astc_10x5_unorm_block" },
249     PairLike<Format, const char*> { BASE_FORMAT_ASTC_10x5_SRGB_BLOCK, "astc_10x5_srgb_block" },
250     PairLike<Format, const char*> { BASE_FORMAT_ASTC_10x6_UNORM_BLOCK, "astc_10x6_unorm_block" },
251     PairLike<Format, const char*> { BASE_FORMAT_ASTC_10x6_SRGB_BLOCK, "astc_10x6_srgb_block" },
252     PairLike<Format, const char*> { BASE_FORMAT_ASTC_10x8_UNORM_BLOCK, "astc_10x8_unorm_block" },
253     PairLike<Format, const char*> { BASE_FORMAT_ASTC_10x8_SRGB_BLOCK, "astc_10x8_srgb_block" },
254     PairLike<Format, const char*> { BASE_FORMAT_ASTC_10x10_UNORM_BLOCK, "astc_10x10_unorm_block" },
255     PairLike<Format, const char*> { BASE_FORMAT_ASTC_10x10_SRGB_BLOCK, "astc_10x10_srgb_block" },
256     PairLike<Format, const char*> { BASE_FORMAT_ASTC_12x10_UNORM_BLOCK, "astc_12x10_unorm_block" },
257     PairLike<Format, const char*> { BASE_FORMAT_ASTC_12x10_SRGB_BLOCK, "astc_12x10_srgb_block" },
258     PairLike<Format, const char*> { BASE_FORMAT_ASTC_12x12_UNORM_BLOCK, "astc_12x12_unorm_block" },
259     PairLike<Format, const char*> { BASE_FORMAT_ASTC_12x12_SRGB_BLOCK, "astc_12x12_srgb_block" },
260     PairLike<Format, const char*> { BASE_FORMAT_G8B8G8R8_422_UNORM, "g8b8g8r8_422_unorm" },
261     PairLike<Format, const char*> { BASE_FORMAT_B8G8R8G8_422_UNORM, "b8g8r8g8_422_unorm" },
262     PairLike<Format, const char*> { BASE_FORMAT_G8_B8_R8_3PLANE_420_UNORM, "g8_b8_r8_3plane_420_unorm" },
263     PairLike<Format, const char*> { BASE_FORMAT_G8_B8R8_2PLANE_420_UNORM, "g8_b8r8_2plane_420_unorm" },
264     PairLike<Format, const char*> { BASE_FORMAT_G8_B8_R8_3PLANE_422_UNORM, "g8_b8_r8_3plane_422_unorm" },
265     PairLike<Format, const char*> { BASE_FORMAT_G8_B8R8_2PLANE_422_UNORM, "g8_b8r8_2plane_422_unorm" },
266     PairLike<Format, const char*> { BASE_FORMAT_G8_B8_R8_3PLANE_444_UNORM, "g8_b8_r8_3plane_444_unorm" } } };
267 
268 constexpr CTMap<StencilOp, const char*, 8U> stencilOpToString { { PairLike<StencilOp, const char*> {
269                                                                       CORE_STENCIL_OP_KEEP, "keep" },
270     PairLike<StencilOp, const char*> { CORE_STENCIL_OP_ZERO, "zero" },
271     PairLike<StencilOp, const char*> { CORE_STENCIL_OP_REPLACE, "replace" },
272     PairLike<StencilOp, const char*> { CORE_STENCIL_OP_INCREMENT_AND_CLAMP, "increment_and_clamp" },
273     PairLike<StencilOp, const char*> { CORE_STENCIL_OP_DECREMENT_AND_CLAMP, "decrement_and_clamp" },
274     PairLike<StencilOp, const char*> { CORE_STENCIL_OP_INVERT, "invert" },
275     PairLike<StencilOp, const char*> { CORE_STENCIL_OP_INCREMENT_AND_WRAP, "increment_and_wrap" },
276     PairLike<StencilOp, const char*> { CORE_STENCIL_OP_DECREMENT_AND_WRAP, "decrement_and_wrap" } } };
277 
278 constexpr CTMap<CompareOp, const char*, 8U> compareOpToString { { PairLike<CompareOp, const char*> {
279                                                                       CORE_COMPARE_OP_NEVER, "never" },
280     PairLike<CompareOp, const char*> { CORE_COMPARE_OP_LESS, "less" },
281     PairLike<CompareOp, const char*> { CORE_COMPARE_OP_EQUAL, "equal" },
282     PairLike<CompareOp, const char*> { CORE_COMPARE_OP_LESS_OR_EQUAL, "less_or_equal" },
283     PairLike<CompareOp, const char*> { CORE_COMPARE_OP_GREATER, "greater" },
284     PairLike<CompareOp, const char*> { CORE_COMPARE_OP_NOT_EQUAL, "not_equal" },
285     PairLike<CompareOp, const char*> { CORE_COMPARE_OP_GREATER_OR_EQUAL, "greater_or_equal" },
286     PairLike<CompareOp, const char*> { CORE_COMPARE_OP_ALWAYS, "always" } } };
287 
288 constexpr CTMap<LogicOp, const char*, 16U> logicOpToString { { PairLike<LogicOp, const char*> {
289                                                                    CORE_LOGIC_OP_CLEAR, "clear" },
290     PairLike<LogicOp, const char*> { CORE_LOGIC_OP_AND, "and" },
291     PairLike<LogicOp, const char*> { CORE_LOGIC_OP_AND_REVERSE, "and_reverse" },
292     PairLike<LogicOp, const char*> { CORE_LOGIC_OP_COPY, "copy" },
293     PairLike<LogicOp, const char*> { CORE_LOGIC_OP_AND_INVERTED, "and_inverted" },
294     PairLike<LogicOp, const char*> { CORE_LOGIC_OP_NO_OP, "no_op" },
295     PairLike<LogicOp, const char*> { CORE_LOGIC_OP_XOR, "xor" },
296     PairLike<LogicOp, const char*> { CORE_LOGIC_OP_OR, "or" },
297     PairLike<LogicOp, const char*> { CORE_LOGIC_OP_NOR, "nor" },
298     PairLike<LogicOp, const char*> { CORE_LOGIC_OP_EQUIVALENT, "equivalent" },
299     PairLike<LogicOp, const char*> { CORE_LOGIC_OP_INVERT, "invert" },
300     PairLike<LogicOp, const char*> { CORE_LOGIC_OP_OR_REVERSE, "or_reverse" },
301     PairLike<LogicOp, const char*> { CORE_LOGIC_OP_COPY_INVERTED, "copy_inverted" },
302     PairLike<LogicOp, const char*> { CORE_LOGIC_OP_OR_INVERTED, "or_inverted" },
303     PairLike<LogicOp, const char*> { CORE_LOGIC_OP_NAND, "nand" },
304     PairLike<LogicOp, const char*> { CORE_LOGIC_OP_SET, "set" } } };
305 
306 constexpr CTMap<PrimitiveTopology, const char*, 12U> primitiveTopologyToString { {
307     PairLike<PrimitiveTopology, const char*> { CORE_PRIMITIVE_TOPOLOGY_POINT_LIST, "point_list" },
308     PairLike<PrimitiveTopology, const char*> { CORE_PRIMITIVE_TOPOLOGY_LINE_LIST, "line_list" },
309     PairLike<PrimitiveTopology, const char*> { CORE_PRIMITIVE_TOPOLOGY_LINE_STRIP, "line_strip" },
310     PairLike<PrimitiveTopology, const char*> { CORE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, "triangle_list" },
311     PairLike<PrimitiveTopology, const char*> { CORE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, "triangle_strip" },
312     PairLike<PrimitiveTopology, const char*> { CORE_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, "triangle_fan" },
313     PairLike<PrimitiveTopology, const char*> {
314         CORE_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, "line_list_with_adjacency" },
315     PairLike<PrimitiveTopology, const char*> {
316         CORE_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY, "line_strip_with_adjacency" },
317     PairLike<PrimitiveTopology, const char*> {
318         CORE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY, "triangle_list_with_adjacency" },
319     PairLike<PrimitiveTopology, const char*> {
320         CORE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY, "triangle_strip_with_adjacency" },
321     PairLike<PrimitiveTopology, const char*> { CORE_PRIMITIVE_TOPOLOGY_PATCH_LIST, "patch_list" },
322     PairLike<PrimitiveTopology, const char*> { CORE_PRIMITIVE_TOPOLOGY_MAX_ENUM, "max_enum" },
323 
324 } };
325 
326 constexpr CTMap<DescriptorType, const char*, 13U> descriptorTypeToString { {
327     PairLike<DescriptorType, const char*> { CORE_DESCRIPTOR_TYPE_SAMPLER, "sampler" },
328     PairLike<DescriptorType, const char*> { CORE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler" },
329     PairLike<DescriptorType, const char*> { CORE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, "sampled_image" },
330     PairLike<DescriptorType, const char*> { CORE_DESCRIPTOR_TYPE_STORAGE_IMAGE, "storage_image" },
331     PairLike<DescriptorType, const char*> { CORE_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, "uniform_texel_buffer" },
332     PairLike<DescriptorType, const char*> { CORE_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, "storage_texel_buffer" },
333     PairLike<DescriptorType, const char*> { CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "uniform_buffer" },
334     PairLike<DescriptorType, const char*> { CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER, "storage_buffer" },
335     PairLike<DescriptorType, const char*> { CORE_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, "uniform_buffer_dynamic" },
336     PairLike<DescriptorType, const char*> { CORE_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, "storage_buffer_dynamic" },
337     PairLike<DescriptorType, const char*> { CORE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, "input_attachment" },
338     PairLike<DescriptorType, const char*> { CORE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE, "acceleration_structure" },
339     PairLike<DescriptorType, const char*> { CORE_DESCRIPTOR_TYPE_MAX_ENUM, "max_enum" },
340 } };
341 
342 constexpr const char* rgbaBitNames[] = { "r_bit", "g_bit", "b_bit", "a_bit" };
343 
344 constexpr const char* graphicsStateBitNames[] = {
345     "input_assembly_bit",
346     "rasterization_state_bit",
347     "depth_stencil_state_bit",
348     "color_blend_state_bit",
349 };
350 
351 constexpr const char* cullModeBitNames[] = {
352     "none",
353     "front_bit",
354     "back_bit",
355     "front_and_back",
356 };
357 
358 // generic bits to string helper, takes in the nameSet that is used to output string
359 // (assumes non skipping bit order)
BitsToString(uint32_t field,array_view<const char * const> nameSet)360 string BitsToString(uint32_t field, array_view<const char* const> nameSet)
361 {
362     bool isFirst = true;
363     string ret;
364     for (uint32_t i = 0; i < nameSet.size(); ++i) {
365         if (field & (1 << i)) {
366             if (!isFirst) {
367                 ret.append("|");
368             }
369             ret.append(nameSet[i]);
370             isFirst = false;
371         }
372     }
373 
374     return ret;
375 }
376 
ShaderStageBitsToString(uint32_t field)377 string ShaderStageBitsToString(uint32_t field)
378 {
379     if (field == 0x0000001f) {
380         return "all_graphics";
381     } else if (field == 0x7fffffff) {
382         return "all";
383     }
384 
385     string ret {};
386     if (field & 0x00000001) {
387         ret.append("vertex_bit");
388     }
389     if (field & 0x00000010) {
390         if (!ret.empty()) {
391             ret.append("|");
392         }
393         ret.append("fragment_bit");
394     }
395     if (field & 0x00000020) {
396         if (!ret.empty()) {
397             ret.append("|");
398         }
399         ret.append("compute_bit");
400     }
401 
402     return ret;
403 }
404 
CullModeToString(uint32_t mode)405 string CullModeToString(uint32_t mode)
406 {
407     for (uint32_t i = 0; i < 4U; ++i) {
408         if (mode == i) {
409             return cullModeBitNames[i];
410         }
411     }
412     return {};
413 }
414 
MakeRasterizationStateJson(const GraphicsState::RasterizationState & rasterizationState)415 json::standalone_value MakeRasterizationStateJson(const GraphicsState::RasterizationState& rasterizationState)
416 {
417     json::standalone_value rasterizationStateJson = json::standalone_value::object();
418     rasterizationStateJson["cullModeFlags"] = CullModeToString(rasterizationState.cullModeFlags);
419     rasterizationStateJson["depthBiasClamp"] = rasterizationState.depthBiasClamp;
420     rasterizationStateJson["depthBiasConstantFactor"] = rasterizationState.depthBiasConstantFactor;
421     rasterizationStateJson["depthBiasSlopeFactor"] = rasterizationState.depthBiasSlopeFactor;
422     rasterizationStateJson["enableDepthBias"] = json::standalone_value(rasterizationState.enableDepthBias);
423     rasterizationStateJson["enableDepthClamp"] = json::standalone_value(rasterizationState.enableDepthClamp);
424     rasterizationStateJson["enableRasterizerDiscard"] =
425         json::standalone_value(rasterizationState.enableRasterizerDiscard);
426     rasterizationStateJson["lineWidth"] = rasterizationState.lineWidth;
427 
428     switch (rasterizationState.frontFace) {
429         case CORE_FRONT_FACE_CLOCKWISE:
430             rasterizationStateJson["frontFace"] = "clockwise";
431             break;
432         case CORE_FRONT_FACE_COUNTER_CLOCKWISE:
433         default:
434             rasterizationStateJson["frontFace"] = "counter_clockwise";
435             break;
436     }
437     switch (rasterizationState.polygonMode) {
438         case CORE_POLYGON_MODE_FILL:
439         default:
440             rasterizationStateJson["polygonMode"] = "fill";
441             break;
442         case CORE_POLYGON_MODE_LINE:
443             rasterizationStateJson["polygonMode"] = "line";
444             break;
445         case CORE_POLYGON_MODE_POINT:
446             rasterizationStateJson["polygonMode"] = "point";
447             break;
448     }
449 
450     return rasterizationStateJson;
451 }
452 
MakeDepthStencilStateJson(const GraphicsState::DepthStencilState & depthStencilState)453 json::standalone_value MakeDepthStencilStateJson(const GraphicsState::DepthStencilState& depthStencilState)
454 {
455     json::standalone_value depthStencilStateJson = json::standalone_value::object();
456     depthStencilStateJson["depthCompareOp"] = compareOpToString.at(depthStencilState.depthCompareOp);
457     depthStencilStateJson["enableDepthBoundsTest"] = json::standalone_value(depthStencilState.enableDepthBoundsTest);
458     depthStencilStateJson["enableDepthTest"] = json::standalone_value(depthStencilState.enableDepthTest);
459     depthStencilStateJson["enableDepthWrite"] = json::standalone_value(depthStencilState.enableDepthWrite);
460     depthStencilStateJson["enableStencilTest"] = json::standalone_value(depthStencilState.enableStencilTest);
461     depthStencilStateJson["maxDepthBounds"] = depthStencilState.maxDepthBounds;
462     depthStencilStateJson["minDepthBounds"] = depthStencilState.minDepthBounds;
463 
464     json::standalone_value backStencilOpStateJson = json::standalone_value::object();
465     backStencilOpStateJson["compareOp"] = compareOpToString.at(depthStencilState.backStencilOpState.compareOp);
466     backStencilOpStateJson["depthFailOp"] = stencilOpToString.at(depthStencilState.backStencilOpState.depthFailOp);
467     backStencilOpStateJson["failOp"] = stencilOpToString.at(depthStencilState.backStencilOpState.failOp);
468     backStencilOpStateJson["passOp"] = stencilOpToString.at(depthStencilState.backStencilOpState.passOp);
469     backStencilOpStateJson["compareMask"] = string(BASE_NS::to_hex(depthStencilState.backStencilOpState.compareMask));
470     backStencilOpStateJson["reference"] = string(BASE_NS::to_hex(depthStencilState.backStencilOpState.reference));
471     backStencilOpStateJson["writeMask"] = BitsToString(depthStencilState.backStencilOpState.writeMask, rgbaBitNames);
472     depthStencilStateJson["backStencilOpState"] = backStencilOpStateJson;
473 
474     json::standalone_value frontStencilOpStateJson = json::standalone_value::object();
475     frontStencilOpStateJson["compareOp"] = compareOpToString.at(depthStencilState.frontStencilOpState.compareOp);
476     frontStencilOpStateJson["depthFailOp"] = stencilOpToString.at(depthStencilState.frontStencilOpState.depthFailOp);
477     frontStencilOpStateJson["failOp"] = stencilOpToString.at(depthStencilState.frontStencilOpState.failOp);
478     frontStencilOpStateJson["passOp"] = stencilOpToString.at(depthStencilState.frontStencilOpState.passOp);
479     frontStencilOpStateJson["compareMask"] = string(BASE_NS::to_hex(depthStencilState.frontStencilOpState.compareMask));
480     frontStencilOpStateJson["reference"] = string(BASE_NS::to_hex(depthStencilState.frontStencilOpState.reference));
481     frontStencilOpStateJson["writeMask"] = BitsToString(depthStencilState.frontStencilOpState.writeMask, rgbaBitNames);
482     depthStencilStateJson["frontStencilOpState"] = frontStencilOpStateJson;
483 
484     return depthStencilStateJson;
485 }
486 
MakeColorBlendStateJson(const GraphicsState::ColorBlendState & colorBlendState)487 json::standalone_value MakeColorBlendStateJson(const GraphicsState::ColorBlendState& colorBlendState)
488 {
489     json::standalone_value colorBlendStateJson = json::standalone_value::object();
490     colorBlendStateJson["colorAttachments"] = json::standalone_value::array();
491     for (uint32_t i = 0; i < colorBlendState.colorAttachmentCount; ++i) {
492         json::standalone_value attachmentJson = json::standalone_value::object();
493         attachmentJson["alphaBlendOp"] = blendOpToString.at(colorBlendState.colorAttachments[i].alphaBlendOp);
494         attachmentJson["colorBlendOp"] = blendOpToString.at(colorBlendState.colorAttachments[i].colorBlendOp);
495         attachmentJson["colorWriteMask"] =
496             BitsToString(colorBlendState.colorAttachments[i].colorWriteMask, rgbaBitNames);
497         attachmentJson["dstAlphaBlendFactor"] =
498             blendFactorToString.at(colorBlendState.colorAttachments[i].dstAlphaBlendFactor);
499         attachmentJson["dstColorBlendFactor"] =
500             blendFactorToString.at(colorBlendState.colorAttachments[i].dstColorBlendFactor);
501         attachmentJson["enableBlend"] = json::standalone_value(colorBlendState.colorAttachments[i].enableBlend);
502         attachmentJson["srcAlphaBlendFactor"] =
503             blendFactorToString.at(colorBlendState.colorAttachments[i].srcAlphaBlendFactor);
504         attachmentJson["srcColorBlendFactor"] =
505             blendFactorToString.at(colorBlendState.colorAttachments[i].srcColorBlendFactor);
506 
507         colorBlendStateJson["colorAttachments"].array_.emplace_back(attachmentJson);
508     }
509     colorBlendStateJson["colorBlendConstants"] = colorBlendState.colorBlendConstants;
510     colorBlendStateJson["enableLogicOp"] = json::standalone_value(colorBlendState.enableLogicOp);
511     colorBlendStateJson["logicOp"] = logicOpToString.at(colorBlendState.logicOp);
512 
513     return colorBlendStateJson;
514 }
515 
MakeInputAssemblyJson(const GraphicsState::InputAssembly & inputAssembly)516 json::standalone_value MakeInputAssemblyJson(const GraphicsState::InputAssembly& inputAssembly)
517 {
518     json::standalone_value inputAssemblyJson = json::standalone_value::object();
519     inputAssemblyJson["enablePrimitiveRestart"] = json::standalone_value(inputAssembly.enablePrimitiveRestart);
520     inputAssemblyJson["primitiveTopology"] = primitiveTopologyToString.at(inputAssembly.primitiveTopology);
521 
522     return inputAssemblyJson;
523 }
524 } // namespace
525 
SaveGraphicsState(const IShaderManager::ShaderGraphicsStateSaveInfo & saveInfo)526 IShaderManager::ShaderOutWriteResult SaveGraphicsState(const IShaderManager::ShaderGraphicsStateSaveInfo& saveInfo)
527 {
528     // .shadergs file type
529     IShaderManager::ShaderOutWriteResult r;
530     if (saveInfo.states.size() != saveInfo.stateVariants.size()) {
531         r.error = "ShaderLoader::SaveShaderStates - states and stateVariants are not equal in size.\n";
532         r.success = false;
533         return r;
534     }
535 
536     json::standalone_value sgJson = json::standalone_value::object();
537     sgJson["combatibility_info"] = json::standalone_value::object();
538     sgJson["combatibility_info"]["version"] = "22.00";
539     sgJson["combatibility_info"]["type"] = "shaderstate";
540     sgJson["shaderStates"] = json::standalone_value::array();
541 
542     // each GraphicsState is serialized with VariantData(ShaderStateLoaderVariantData)
543     for (uint32_t i = 0; i < saveInfo.stateVariants.size(); ++i) {
544         json::standalone_value stateInfoJson = json::standalone_value::object();
545         const auto& stateVariant = saveInfo.stateVariants.at(i);
546         stateInfoJson["baseShaderState"] = stateVariant.baseShaderState;
547         stateInfoJson["baseVariantName"] = stateVariant.baseVariantName;
548         stateInfoJson["variantName"] = stateVariant.variantName;
549         stateInfoJson["renderSlot"] = stateVariant.renderSlot;
550         stateInfoJson["renderSlotDefaultState"] = json::standalone_value(stateVariant.renderSlotDefaultState);
551         stateInfoJson["stateFlags"] = BitsToString(stateVariant.stateFlags, graphicsStateBitNames);
552 
553         // NOTE: assume that there is same amount of states as variants.
554         const auto& state = saveInfo.states.at(i);
555         json::standalone_value singleStateJson = json::standalone_value::object();
556 
557         // rasterization state
558         singleStateJson["rasterizationState"] = MakeRasterizationStateJson(state.rasterizationState);
559         // depth stencil state
560         singleStateJson["depthStencilState"] = MakeDepthStencilStateJson(state.depthStencilState);
561         // color blend state
562         singleStateJson["colorBlendState"] = MakeColorBlendStateJson(state.colorBlendState);
563         // input assembly
564         singleStateJson["inputAssembly"] = MakeInputAssemblyJson(state.inputAssembly);
565 
566         stateInfoJson["state"] = BASE_NS::move(singleStateJson);
567         sgJson["shaderStates"].array_.push_back(BASE_NS::move(stateInfoJson));
568     }
569 
570     r.result = to_string(sgJson);
571     r.success = true;
572 
573     return r;
574 }
575 
SaveVextexInputDeclarations(const IShaderManager::ShaderVertexInputDeclarationsSaveInfo & saveInfo)576 IShaderManager::ShaderOutWriteResult SaveVextexInputDeclarations(
577     const IShaderManager::ShaderVertexInputDeclarationsSaveInfo& saveInfo)
578 {
579     // .shadervid file type
580     IShaderManager::ShaderOutWriteResult r;
581 
582     json::standalone_value vidsJson = json::standalone_value::object();
583     vidsJson["combatibility_info"] = json::standalone_value::object();
584     vidsJson["combatibility_info"]["version"] = "22.00";
585     vidsJson["combatibility_info"]["type"] = "vertexinputdeclaration";
586     vidsJson["vertexInputState"] = json::standalone_value::object();
587     json::standalone_value vertexInputStateJson = vidsJson["vertexInputState"];
588     vertexInputStateJson["vertexInputBindingDescriptions"] = json::standalone_value::array();
589     vertexInputStateJson["vertexInputAttributeDescriptions"] = json::standalone_value::array();
590 
591     const auto& vid = saveInfo.vid;
592     for (auto bd : vid.bindingDescriptions) {
593         json::standalone_value bindingDescriptionJson = json::standalone_value::object();
594         bindingDescriptionJson["binding"] = bd.binding;
595         bindingDescriptionJson["stride"] = bd.stride;
596         switch (bd.vertexInputRate) {
597             case CORE_VERTEX_INPUT_RATE_VERTEX:
598                 bindingDescriptionJson["vertexInputRate"] = "vertex";
599                 break;
600             case CORE_VERTEX_INPUT_RATE_INSTANCE:
601                 bindingDescriptionJson["vertexInputRate"] = "instance";
602                 break;
603             default:
604                 bindingDescriptionJson["vertexInputRate"] = "vertex";
605                 break;
606         }
607         vertexInputStateJson["vertexInputBindingDescriptions"].array_.emplace_back(bindingDescriptionJson);
608     }
609 
610     for (auto ad : vid.attributeDescriptions) {
611         json::standalone_value attrDescriptionJson = json::standalone_value::object();
612         attrDescriptionJson["location"] = ad.location;
613         attrDescriptionJson["binding"] = ad.binding;
614         attrDescriptionJson["format"] = formatToString.at(ad.format);
615         attrDescriptionJson["offset"] = ad.offset;
616         vertexInputStateJson["vertexInputAttributeDescriptions"].array_.emplace_back(attrDescriptionJson);
617     }
618 
619     vidsJson["vertexInputState"] = BASE_NS::move(vertexInputStateJson);
620 
621     r.result = to_string(vidsJson);
622     r.success = true;
623 
624     return r;
625 }
626 
SavePipelineLayouts(const IShaderManager::ShaderPipelineLayoutSaveInfo & saveInfo)627 IShaderManager::ShaderOutWriteResult SavePipelineLayouts(const IShaderManager::ShaderPipelineLayoutSaveInfo& saveInfo)
628 {
629     // .shaderpl file type
630     IShaderManager::ShaderOutWriteResult r;
631 
632     json::standalone_value pipelineLayoutJson = json::standalone_value::object();
633     pipelineLayoutJson["combatibility_info"] = json::standalone_value::object();
634     pipelineLayoutJson["combatibility_info"]["version"] = "22.00";
635     pipelineLayoutJson["combatibility_info"]["type"] = "pipelinelayout";
636     pipelineLayoutJson["descriptorSetLayouts"] = json::standalone_value::array();
637 
638     for (const auto& descriptorSetLayout : saveInfo.layout.descriptorSetLayouts) {
639         if (descriptorSetLayout.set == PipelineLayoutConstants::INVALID_INDEX) {
640             continue;
641         }
642         json::standalone_value descriptorSetJson = json::standalone_value::object();
643         descriptorSetJson["set"] = descriptorSetLayout.set;
644         descriptorSetJson["bindings"] = json::standalone_value::array();
645         for (const auto& binding : descriptorSetLayout.bindings) {
646             json::standalone_value bindingJson = json::standalone_value::object();
647             bindingJson["binding"] = binding.binding;
648             bindingJson["descriptorType"] = descriptorTypeToString.at(binding.descriptorType);
649             bindingJson["descriptorCount"] = binding.descriptorCount;
650             bindingJson["shaderStageFlags"] = ShaderStageBitsToString(binding.shaderStageFlags);
651             descriptorSetJson["bindings"].array_.emplace_back(bindingJson);
652         }
653 
654         descriptorSetJson["byteSize"] = saveInfo.layout.pushConstant.byteSize;
655 
656         descriptorSetJson["shaderStageFlags"] = ShaderStageBitsToString(saveInfo.layout.pushConstant.shaderStageFlags);
657 
658         pipelineLayoutJson["descriptorSetLayouts"].array_.push_back(BASE_NS::move(descriptorSetJson));
659     }
660 
661     r.result = to_string(pipelineLayoutJson);
662     r.success = true;
663 
664     return r;
665 }
666 
SaveVariants(const IShaderManager::ShaderVariantsSaveInfo & saveInfo)667 IShaderManager::ShaderOutWriteResult SaveVariants(const IShaderManager::ShaderVariantsSaveInfo& saveInfo)
668 {
669     // .shader file type
670     IShaderManager::ShaderOutWriteResult r;
671     json::standalone_value shadersJson = json::standalone_value::object();
672     shadersJson["combatibility_info"] = json::standalone_value::object();
673     shadersJson["combatibility_info"]["version"] = "22.00";
674     shadersJson["combatibility_info"]["type"] = "shader";
675     shadersJson["category"] = string(saveInfo.category);
676     // empty means that it is itself, NOTE: will be adjusted later.
677     shadersJson["baseShader"] = "";
678     shadersJson["shaders"] = json::standalone_value::array();
679 
680     for (const auto& shader : saveInfo.shaders) {
681         json::standalone_value shaderJson = json::standalone_value::object();
682         shaderJson["materialMetadata"] = shader.materialMetadata;
683         shaderJson["displayName"] = shader.displayName;
684         shaderJson["variantName"] = shader.variantName;
685         shaderJson["renderSlot"] = shader.renderSlot;
686         shaderJson["renderSlotDefaultShader"] = json::standalone_value(shader.renderSlotDefaultShader);
687         for (const auto& s : shader.shaders) {
688             switch (s.shaderType) {
689                 case CORE_SHADER_STAGE_VERTEX_BIT:
690                     shaderJson["vert"] = s.shaderSpvPath;
691                     break;
692                 case CORE_SHADER_STAGE_FRAGMENT_BIT:
693                     shaderJson["frag"] = s.shaderSpvPath;
694                     break;
695                 case CORE_SHADER_STAGE_COMPUTE_BIT:
696                     shaderJson["comp"] = s.shaderSpvPath;
697                     break;
698             }
699         }
700         shaderJson["vertexInputDeclaration"] = shader.vertexInputDeclaration;
701         shaderJson["pipelineLayout"] = shader.pipelineLayout;
702         shaderJson["state"] = json::standalone_value::object();
703         // graphicsState
704         shaderJson["state"]["rasterizationState"] = MakeRasterizationStateJson(shader.graphicsState.rasterizationState);
705         shaderJson["state"]["depthStencilState"] = MakeDepthStencilStateJson(shader.graphicsState.depthStencilState);
706         shaderJson["state"]["colorBlendState"] = MakeColorBlendStateJson(shader.graphicsState.colorBlendState);
707         shaderJson["state"]["inputAssembly"] = MakeInputAssemblyJson(shader.graphicsState.inputAssembly);
708         shaderJson["stateFlags"] = BitsToString(shader.stateFlags, graphicsStateBitNames);
709         shadersJson["shaders"].array_.push_back(BASE_NS::move(shaderJson));
710     }
711 
712     r.result = to_string(shadersJson);
713     r.success = true;
714     return r;
715 }
716 
717 RENDER_END_NAMESPACE()
718