1 //
2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // utilities.h: Conversion functions and other utility routines.
8
9 #ifndef COMMON_UTILITIES_H_
10 #define COMMON_UTILITIES_H_
11
12 #include <EGL/egl.h>
13 #include <EGL/eglext.h>
14 #include <GLSLANG/ShaderLang.h>
15
16 #include <math.h>
17 #include <string>
18 #include <vector>
19
20 #include "angle_gl.h"
21
22 #include "common/PackedEnums.h"
23 #include "common/mathutil.h"
24 #include "common/platform.h"
25
26 namespace sh
27 {
28 struct ShaderVariable;
29 }
30
31 namespace gl
32 {
33
34 int VariableComponentCount(GLenum type);
35 GLenum VariableComponentType(GLenum type);
36 size_t VariableComponentSize(GLenum type);
37 size_t VariableInternalSize(GLenum type);
38 size_t VariableExternalSize(GLenum type);
39 int VariableRowCount(GLenum type);
40 int VariableColumnCount(GLenum type);
41 bool IsSamplerType(GLenum type);
42 bool IsSamplerCubeType(GLenum type);
43 bool IsSamplerYUVType(GLenum type);
44 bool IsImageType(GLenum type);
45 bool IsImage2DType(GLenum type);
46 bool IsAtomicCounterType(GLenum type);
47 bool IsOpaqueType(GLenum type);
48 bool IsMatrixType(GLenum type);
49 GLenum TransposeMatrixType(GLenum type);
50 int VariableRegisterCount(GLenum type);
51 int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix);
52 int MatrixComponentCount(GLenum type, bool isRowMajorMatrix);
53 int VariableSortOrder(GLenum type);
54 GLenum VariableBoolVectorType(GLenum type);
55 std::string GetGLSLTypeString(GLenum type);
56
57 int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
58
59 // Parse the base resource name and array indices. Returns the base name of the resource.
60 // If the provided name doesn't index an array, the outSubscripts vector will be empty.
61 // If the provided name indexes an array, the outSubscripts vector will contain indices with
62 // outermost array indices in the back. If an array index is invalid, GL_INVALID_INDEX is added to
63 // outSubscripts.
64 std::string ParseResourceName(const std::string &name, std::vector<unsigned int> *outSubscripts);
65
66 bool IsBuiltInName(const char *name);
IsBuiltInName(const std::string & name)67 ANGLE_INLINE bool IsBuiltInName(const std::string &name)
68 {
69 return IsBuiltInName(name.c_str());
70 }
71
72 // Strips only the last array index from a resource name.
73 std::string StripLastArrayIndex(const std::string &name);
74
75 bool SamplerNameContainsNonZeroArrayElement(const std::string &name);
76
77 // Find the range of index values in the provided indices pointer. Primitive restart indices are
78 // only counted in the range if primitive restart is disabled.
79 IndexRange ComputeIndexRange(DrawElementsType indexType,
80 const GLvoid *indices,
81 size_t count,
82 bool primitiveRestartEnabled);
83
84 // Get the primitive restart index value for the given index type.
85 GLuint GetPrimitiveRestartIndex(DrawElementsType indexType);
86
87 // Get the primitive restart index value with the given C++ type.
88 template <typename T>
GetPrimitiveRestartIndexFromType()89 constexpr T GetPrimitiveRestartIndexFromType()
90 {
91 return std::numeric_limits<T>::max();
92 }
93
94 static_assert(GetPrimitiveRestartIndexFromType<uint8_t>() == 0xFF,
95 "verify restart index for uint8_t values");
96 static_assert(GetPrimitiveRestartIndexFromType<uint16_t>() == 0xFFFF,
97 "verify restart index for uint8_t values");
98 static_assert(GetPrimitiveRestartIndexFromType<uint32_t>() == 0xFFFFFFFF,
99 "verify restart index for uint8_t values");
100
101 bool IsTriangleMode(PrimitiveMode drawMode);
102 bool IsPolygonMode(PrimitiveMode mode);
103
104 namespace priv
105 {
106 extern const angle::PackedEnumMap<PrimitiveMode, bool> gLineModes;
107 } // namespace priv
108
IsLineMode(PrimitiveMode primitiveMode)109 ANGLE_INLINE bool IsLineMode(PrimitiveMode primitiveMode)
110 {
111 return priv::gLineModes[primitiveMode];
112 }
113
114 bool IsIntegerFormat(GLenum unsizedFormat);
115
116 // Returns the product of the sizes in the vector, or 1 if the vector is empty. Doesn't currently
117 // perform overflow checks.
118 unsigned int ArraySizeProduct(const std::vector<unsigned int> &arraySizes);
119 // Returns the product of the sizes in the vector except for the outermost dimension, or 1 if the
120 // vector is empty.
121 unsigned int InnerArraySizeProduct(const std::vector<unsigned int> &arraySizes);
122 // Returns the outermost array dimension, or 1 if the vector is empty.
123 unsigned int OutermostArraySize(const std::vector<unsigned int> &arraySizes);
124
125 // Return the array index at the end of name, and write the length of name before the final array
126 // index into nameLengthWithoutArrayIndexOut. In case name doesn't include an array index, return
127 // GL_INVALID_INDEX and write the length of the original string.
128 unsigned int ParseArrayIndex(const std::string &name, size_t *nameLengthWithoutArrayIndexOut);
129
130 enum class SamplerFormat : uint8_t
131 {
132 Float = 0,
133 Unsigned = 1,
134 Signed = 2,
135 Shadow = 3,
136
137 InvalidEnum = 4,
138 EnumCount = 4,
139 };
140
141 struct UniformTypeInfo final : angle::NonCopyable
142 {
143 inline constexpr UniformTypeInfo(GLenum type,
144 GLenum componentType,
145 GLenum textureType,
146 GLenum transposedMatrixType,
147 GLenum boolVectorType,
148 SamplerFormat samplerFormat,
149 int rowCount,
150 int columnCount,
151 int componentCount,
152 size_t componentSize,
153 size_t internalSize,
154 size_t externalSize,
155 bool isSampler,
156 bool isMatrixType,
157 bool isImageType);
158
159 GLenum type;
160 GLenum componentType;
161 GLenum textureType;
162 GLenum transposedMatrixType;
163 GLenum boolVectorType;
164 SamplerFormat samplerFormat;
165 int rowCount;
166 int columnCount;
167 int componentCount;
168 size_t componentSize;
169 size_t internalSize;
170 size_t externalSize;
171 bool isSampler;
172 bool isMatrixType;
173 bool isImageType;
174 };
175
UniformTypeInfo(GLenum type,GLenum componentType,GLenum textureType,GLenum transposedMatrixType,GLenum boolVectorType,SamplerFormat samplerFormat,int rowCount,int columnCount,int componentCount,size_t componentSize,size_t internalSize,size_t externalSize,bool isSampler,bool isMatrixType,bool isImageType)176 inline constexpr UniformTypeInfo::UniformTypeInfo(GLenum type,
177 GLenum componentType,
178 GLenum textureType,
179 GLenum transposedMatrixType,
180 GLenum boolVectorType,
181 SamplerFormat samplerFormat,
182 int rowCount,
183 int columnCount,
184 int componentCount,
185 size_t componentSize,
186 size_t internalSize,
187 size_t externalSize,
188 bool isSampler,
189 bool isMatrixType,
190 bool isImageType)
191 : type(type),
192 componentType(componentType),
193 textureType(textureType),
194 transposedMatrixType(transposedMatrixType),
195 boolVectorType(boolVectorType),
196 samplerFormat(samplerFormat),
197 rowCount(rowCount),
198 columnCount(columnCount),
199 componentCount(componentCount),
200 componentSize(componentSize),
201 internalSize(internalSize),
202 externalSize(externalSize),
203 isSampler(isSampler),
204 isMatrixType(isMatrixType),
205 isImageType(isImageType)
206 {}
207
208 const UniformTypeInfo &GetUniformTypeInfo(GLenum uniformType);
209
210 const char *GetGenericErrorMessage(GLenum error);
211
212 unsigned int ElementTypeSize(GLenum elementType);
213
214 bool IsMipmapFiltered(GLenum minFilterMode);
215
216 template <typename T>
GetClampedVertexCount(size_t vertexCount)217 T GetClampedVertexCount(size_t vertexCount)
218 {
219 static constexpr size_t kMax = static_cast<size_t>(std::numeric_limits<T>::max());
220 return static_cast<T>(vertexCount > kMax ? kMax : vertexCount);
221 }
222
223 enum class PipelineType
224 {
225 GraphicsPipeline = 0,
226 ComputePipeline = 1,
227 };
228
229 PipelineType GetPipelineType(ShaderType shaderType);
230
231 // For use with KHR_debug.
232 const char *GetDebugMessageSourceString(GLenum source);
233 const char *GetDebugMessageTypeString(GLenum type);
234 const char *GetDebugMessageSeverityString(GLenum severity);
235
236 // For use with EXT_texture_format_sRGB_override and EXT_texture_sRGB_decode
237 // A texture may be forced to decode to a nonlinear colorspace, to a linear colorspace, or to the
238 // default colorspace of its current format.
239 //
240 // Default corresponds to "the texture should use the imageview that corresponds to its format"
241 // Linear corresponds to "the texture has sRGB decoding disabled by extension, and should use a
242 // linear imageview even if it is in a nonlinear format" NonLinear corresponds to "the texture has
243 // sRGB override enabled by extension, and should use a nonlinear imageview even if it is in a
244 // linear format"
245 enum class SrgbOverride
246 {
247 Default = 0,
248 SRGB,
249 Linear
250 };
251
252 // For use with EXT_sRGB_write_control
253 // A render target may be forced to convert to a linear colorspace, or may be allowed to do whatever
254 // colorspace conversion is appropriate for its format. There is no option to force linear->sRGB, it
255 // can only convert from sRGB->linear
256 enum class SrgbWriteControlMode
257 {
258 Default = 0,
259 Linear = 1
260 };
261
262 // For use with EXT_YUV_target
263 // A sampler of external YUV textures may either implicitly perform RGB conversion (regular
264 // samplerExternalOES) or skip the conversion and sample raw YUV values (__samplerExternal2DY2Y).
265 enum class YuvSamplingMode
266 {
267 Default = 0,
268 Y2Y = 1
269 };
270
271 ShaderType GetShaderTypeFromBitfield(size_t singleShaderType);
272 GLbitfield GetBitfieldFromShaderType(ShaderType shaderType);
273 bool ShaderTypeSupportsTransformFeedback(ShaderType shaderType);
274 // Given a set of shader stages, returns the last vertex processing stage. This is the stage that
275 // interfaces the fragment shader.
276 ShaderType GetLastPreFragmentStage(ShaderBitSet shaderTypes);
277
278 } // namespace gl
279
280 namespace egl
281 {
282 static const EGLenum FirstCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR;
283 static const EGLenum LastCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR;
284 bool IsCubeMapTextureTarget(EGLenum target);
285 size_t CubeMapTextureTargetToLayerIndex(EGLenum target);
286 EGLenum LayerIndexToCubeMapTextureTarget(size_t index);
287 bool IsTextureTarget(EGLenum target);
288 bool IsRenderbufferTarget(EGLenum target);
289 bool IsExternalImageTarget(EGLenum target);
290
291 const char *GetGenericErrorMessage(EGLint error);
292 } // namespace egl
293
294 namespace egl_gl
295 {
296 GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer);
297 }
298
299 namespace gl_egl
300 {
301 EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType);
302 EGLClientBuffer GLObjectHandleToEGLClientBuffer(GLuint handle);
303 } // namespace gl_egl
304
305 namespace angle
306 {
307 bool IsDrawEntryPoint(EntryPoint entryPoint);
308 bool IsDispatchEntryPoint(EntryPoint entryPoint);
309 bool IsClearEntryPoint(EntryPoint entryPoint);
310 bool IsQueryEntryPoint(EntryPoint entryPoint);
311 } // namespace angle
312
313 void writeFile(const char *path, const void *data, size_t size);
314
315 // Get the underlying type. Useful for indexing into arrays with enum values by avoiding the clutter
316 // of the extraneous static_cast<>() calls.
317 // https://stackoverflow.com/a/8357462
318 template <typename E>
ToUnderlying(E e)319 constexpr typename std::underlying_type<E>::type ToUnderlying(E e) noexcept
320 {
321 return static_cast<typename std::underlying_type<E>::type>(e);
322 }
323
324 #endif // COMMON_UTILITIES_H_
325