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