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 #ifndef GLES_SPIRV_CROSS_HELPER_STRUCTS_H
16 #define GLES_SPIRV_CROSS_HELPER_STRUCTS_H
17 
18 #include <string>
19 
20 #include "array_view.h"
21 #include "shader_type.h"
22 
23 /** Shader stage flag bits */
24 enum class ShaderStageFlagBits {
25     /** Vertex bit */
26     VERTEX_BIT = 0x00000001,
27     /** Fragment bit */
28     FRAGMENT_BIT = 0x00000010,
29     /** Compute bit */
30     COMPUTE_BIT = 0x00000020,
31     /** All graphics */
32     ALL_GRAPHICS = 0x0000001F,
33     /** All */
34     ALL = 0x7FFFFFFF,
35     /** Max enumeration */
36     FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
37 };
38 
ShaderKindToStageFlags(ShaderKind kind)39 inline ShaderStageFlagBits ShaderKindToStageFlags(ShaderKind kind)
40 {
41     switch (kind) {
42         case ShaderKind::VERTEX:
43             return ShaderStageFlagBits::VERTEX_BIT;
44         case ShaderKind::FRAGMENT:
45             return ShaderStageFlagBits::FRAGMENT_BIT;
46         case ShaderKind::COMPUTE:
47             return ShaderStageFlagBits::COMPUTE_BIT;
48         default:
49             return ShaderStageFlagBits::ALL_GRAPHICS;
50     }
51 }
52 
53 constexpr ShaderStageFlagBits operator~(ShaderStageFlagBits bits) noexcept
54 {
55     return static_cast<ShaderStageFlagBits>(~static_cast<std::underlying_type_t<ShaderStageFlagBits>>(bits));
56 }
57 
58 /** Shader stage flags */
59 struct ShaderStageFlags {
60     ShaderStageFlagBits flags {};
61 
62     ShaderStageFlags() noexcept = default;
ShaderStageFlagsShaderStageFlags63     ShaderStageFlags(ShaderStageFlagBits bits) noexcept : flags(bits) {}
ShaderStageFlagsShaderStageFlags64     ShaderStageFlags(ShaderKind kind) noexcept
65     {
66         flags = ShaderKindToStageFlags(kind);
67     }
68 
69     ShaderStageFlags operator&(ShaderStageFlagBits rhs) const noexcept
70     {
71         return { static_cast<ShaderStageFlagBits>(static_cast<std::underlying_type_t<ShaderStageFlagBits>>(flags) &
72                                                   static_cast<std::underlying_type_t<ShaderStageFlagBits>>(rhs)) };
73     }
74 
75     ShaderStageFlags operator~() const noexcept
76     {
77         return { static_cast<ShaderStageFlagBits>(~static_cast<std::underlying_type_t<ShaderStageFlagBits>>(flags)) };
78     }
79 
80     ShaderStageFlags& operator&=(ShaderStageFlagBits rhs) noexcept
81     {
82         flags = static_cast<ShaderStageFlagBits>(static_cast<std::underlying_type_t<ShaderStageFlagBits>>(flags) &
83                                                  static_cast<std::underlying_type_t<ShaderStageFlagBits>>(rhs));
84         return *this;
85     }
86 
87     ShaderStageFlags& operator|=(ShaderStageFlagBits rhs) noexcept
88     {
89         flags = static_cast<ShaderStageFlagBits>(static_cast<std::underlying_type_t<ShaderStageFlagBits>>(flags) |
90                                                  static_cast<std::underlying_type_t<ShaderStageFlagBits>>(rhs));
91         return *this;
92     }
93 
94     ShaderStageFlags& operator|=(ShaderStageFlags rhs) noexcept
95     {
96         flags = static_cast<ShaderStageFlagBits>(static_cast<std::underlying_type_t<ShaderStageFlagBits>>(flags) |
97                                                  static_cast<std::underlying_type_t<ShaderStageFlagBits>>(rhs.flags));
98         return *this;
99     }
100 
101     bool operator==(ShaderStageFlagBits rhs) const noexcept
102     {
103         return static_cast<std::underlying_type_t<ShaderStageFlagBits>>(flags) ==
104                static_cast<std::underlying_type_t<ShaderStageFlagBits>>(rhs);
105     }
106 
107     operator bool() const noexcept
108     {
109         return static_cast<std::underlying_type_t<ShaderStageFlagBits>>(flags) != 0;
110     }
111 };
112 
113 /** Constant */
114 struct ShaderSpecializationConstant {
115     enum class Type : uint32_t {
116         INVALID = 0,
117         BOOL,
118         UINT32,
119         INT32,
120         FLOAT,
121     };
122     /** Shader stage */
123     ShaderStageFlags shaderStage;
124     /** ID */
125     uint32_t id;
126     /** Size */
127     Type type;
128     /** Offset */
129     uint32_t offset;
130 };
131 
132 /** Shader specialization constant data view */
133 struct ShaderSpecializationConstantDataView {
134     /** Array of shader specialization constants */
135     array_view<const ShaderSpecializationConstant> constants;
136     /** Data */
137     array_view<const uint32_t> data;
138 };
139 
140 namespace Gles {
141 // Bind limits.
142 // https://www.khronos.org/registry/vulkan/specs/1.1/html/chap31.html#limits-minmax
143 // maxBoundDescriptorSets                is 4     (so there can be at most 4 sets...)
144 // maxPerStageDescriptorUniformBuffers   is 12
145 // maxPerStageDescriptorStorageBuffers   is 4
146 // maxPerStageDescriptorStorageImages    is 4
147 // maxPerStageDescriptorSamplers         is 16
148 // maxPerStageDescriptorSampledImages    is 16
149 // maxDescriptorSetSamplers              is 96    (all stages)
150 // maxDescriptorSetSampledImages         is 96    (all stages)
151 // maxColorAttachments                   is 4     (subpass inputs?)
152 // maxVertexInputAttributes              is 16
153 // maxVertexInputBindings                is 16
154 // gles = GL_MAX_TEXTURE_IMAGE_UNITS 16 (so 16 texture units can be active, ie combined samplers/sampledimages and
155 // subpass inputs) NOTE: The macro allows for 16 sets, with 16 binds per type (uniform buffer, storage buffer)
156 struct ResourceLimits {
157     // 4 slots and 16 binds = 64 possible binds.
158     static constexpr uint32_t MAX_SETS { 4 };
159     static constexpr uint32_t MAX_BIND_IN_SET { 16 };
160     static constexpr uint32_t MAX_BINDS { MAX_SETS * MAX_BIND_IN_SET };
161 
162     static constexpr uint32_t MAX_VERTEXINPUT_ATTRIBUTES { 16 };
163     static constexpr uint32_t MAX_UNIFORM_BUFFERS_IN_STAGE { 12 };
164     static constexpr uint32_t MAX_STORAGE_BUFFERS_IN_STAGE { 4 };
165     static constexpr uint32_t MAX_SAMPLERS_IN_STAGE { 16 };
166     static constexpr uint32_t MAX_IMAGES_IN_STAGE { 16 };
167     static constexpr uint32_t MAX_STORAGE_IMAGES_IN_STAGE { 4 };
168     static constexpr uint32_t MAX_INPUT_ATTACHMENTS_IN_STAGE { 4 };
169     static constexpr uint32_t MAX_SAMPLERS_IN_PROGRAM { MAX_SAMPLERS_IN_STAGE + MAX_SAMPLERS_IN_STAGE };
170     static constexpr uint32_t MAX_IMAGES_IN_PROGRAM { MAX_IMAGES_IN_STAGE + MAX_IMAGES_IN_STAGE };
171 };
172 static constexpr int32_t INVALID_LOCATION = -1;
173 struct SpecConstantInfo {
174     enum class Types { INVALID = 0, BOOL, UINT32, INT32, FLOAT };
175     Types constantType = Types::INVALID;
176     uint32_t constantId;
177     uint32_t vectorSize;
178     uint32_t columns;
179     uint32_t offset;
180     std::string name;
181 };
182 struct PushConstantReflection {
183     ShaderStageFlags stage;
184     int32_t location { INVALID_LOCATION };
185     uint32_t type;
186     std::string name;
187     size_t offset;
188     size_t size;
189     size_t arraySize;
190     size_t arrayStride;
191     size_t matrixStride;
192 };
193 } // namespace Gles
194 
195 #endif // GLES_SPIRV_CROSS_HELPER_STRUCTS_H
196