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 struct UniformTypeIndex
209 {
210 uint16_t value;
211 };
212 const UniformTypeInfo &GetUniformTypeInfo(GLenum uniformType);
213 UniformTypeIndex GetUniformTypeIndex(GLenum uniformType);
214 const UniformTypeInfo &GetUniformTypeInfoFromIndex(UniformTypeIndex index);
215
216 const char *GetGenericErrorMessage(GLenum error);
217
218 unsigned int ElementTypeSize(GLenum elementType);
219
220 bool IsMipmapFiltered(GLenum minFilterMode);
221
222 template <typename T>
GetClampedVertexCount(size_t vertexCount)223 T GetClampedVertexCount(size_t vertexCount)
224 {
225 static constexpr size_t kMax = static_cast<size_t>(std::numeric_limits<T>::max());
226 return static_cast<T>(vertexCount > kMax ? kMax : vertexCount);
227 }
228
229 enum class PipelineType
230 {
231 GraphicsPipeline = 0,
232 ComputePipeline = 1,
233 };
234
235 PipelineType GetPipelineType(ShaderType shaderType);
236
237 // For use with KHR_debug.
238 const char *GetDebugMessageSourceString(GLenum source);
239 const char *GetDebugMessageTypeString(GLenum type);
240 const char *GetDebugMessageSeverityString(GLenum severity);
241
242 // For use with EXT_texture_sRGB_decode
243 // A texture may be forced to skip decoding to a linear colorspace even if its format
244 // is in sRGB colorspace.
245 //
246 // Default - decode data according to the image's format's colorspace
247 // Skip - data is not decoded during sampling
248 enum class SrgbDecode
249 {
250 Default = 0,
251 Skip
252 };
253
254 // For use with EXT_texture_format_sRGB_override
255 // A texture may be forced to decode data to linear colorspace even if its format
256 // is in linear colorspace.
257 //
258 // Default - decode data according to the image's format's colorspace
259 // SRGB - data will be decoded to linear colorspace irrespective of texture's format
260 enum class SrgbOverride
261 {
262 Default = 0,
263 SRGB
264 };
265
266 // For use with EXT_sRGB_write_control
267 // A framebuffer may be forced to not encode data to sRGB colorspace even if its format
268 // is in sRGB colorspace.
269 //
270 // Default - encode data according to the image's format's colorspace
271 // Linear - data will not be encoded into sRGB colorspace
272 enum class SrgbWriteControlMode
273 {
274 Default = 0,
275 Linear = 1
276 };
277
278 // For use with EXT_YUV_target
279 // A sampler of external YUV textures may either implicitly perform RGB conversion (regular
280 // samplerExternalOES) or skip the conversion and sample raw YUV values (__samplerExternal2DY2Y).
281 enum class YuvSamplingMode
282 {
283 Default = 0,
284 Y2Y = 1
285 };
286
287 ShaderType GetShaderTypeFromBitfield(size_t singleShaderType);
288 GLbitfield GetBitfieldFromShaderType(ShaderType shaderType);
289 bool ShaderTypeSupportsTransformFeedback(ShaderType shaderType);
290 // Given a set of shader stages, returns the last vertex processing stage. This is the stage that
291 // interfaces the fragment shader.
292 ShaderType GetLastPreFragmentStage(ShaderBitSet shaderTypes);
293
294 } // namespace gl
295
296 namespace egl
297 {
298 // For use with EGL_EXT_image_gl_colorspace
299 // An EGLImage can be created with attributes that override the color space of underlying image data
300 // when rendering to the image, or sampling from the image. The possible values are -
301 // Default - EGLImage source's colorspace should be preserved
302 // sRGB - EGLImage targets will assume sRGB colorspace
303 // Linear - EGLImage targets will assume linear colorspace
304 enum class ImageColorspace
305 {
306 Default = 0,
307 SRGB,
308 Linear
309 };
310
311 static const EGLenum FirstCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR;
312 static const EGLenum LastCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR;
313 bool IsCubeMapTextureTarget(EGLenum target);
314 size_t CubeMapTextureTargetToLayerIndex(EGLenum target);
315 EGLenum LayerIndexToCubeMapTextureTarget(size_t index);
316 bool IsTextureTarget(EGLenum target);
317 bool IsRenderbufferTarget(EGLenum target);
318 bool IsExternalImageTarget(EGLenum target);
319
320 const char *GetGenericErrorMessage(EGLint error);
321 } // namespace egl
322
323 namespace egl_gl
324 {
325 GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer);
326 }
327
328 namespace gl_egl
329 {
330 EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType);
331 EGLClientBuffer GLObjectHandleToEGLClientBuffer(GLuint handle);
332 } // namespace gl_egl
333
334 namespace angle
335 {
336
337 // All state that modify attachment's colorspace
338 struct ColorspaceState
339 {
340 public:
ColorspaceStateColorspaceState341 ColorspaceState() { reset(); }
resetColorspaceState342 void reset()
343 {
344 hasStaticTexelFetchAccess = false;
345 srgbDecode = gl::SrgbDecode::Default;
346 srgbOverride = gl::SrgbOverride::Default;
347 srgbWriteControl = gl::SrgbWriteControlMode::Default;
348 eglImageColorspace = egl::ImageColorspace::Default;
349 }
350
351 // States that affect read operations
352 bool hasStaticTexelFetchAccess;
353 gl::SrgbDecode srgbDecode;
354 gl::SrgbOverride srgbOverride;
355
356 // States that affect write operations
357 gl::SrgbWriteControlMode srgbWriteControl;
358
359 // States that affect both read and write operations
360 egl::ImageColorspace eglImageColorspace;
361 };
362
363 template <typename T>
ConstStrLen(T s)364 constexpr size_t ConstStrLen(T s)
365 {
366 if (s == nullptr)
367 {
368 return 0;
369 }
370 return std::char_traits<char>::length(s);
371 }
372
373 bool IsDrawEntryPoint(EntryPoint entryPoint);
374 bool IsDispatchEntryPoint(EntryPoint entryPoint);
375 bool IsClearEntryPoint(EntryPoint entryPoint);
376 bool IsQueryEntryPoint(EntryPoint entryPoint);
377
378 template <typename T>
FillWithNullptr(T * array)379 void FillWithNullptr(T *array)
380 {
381 // std::array::fill(nullptr) yields unoptimized, unrolled loop over array items
382 memset(array->data(), 0, array->size() * sizeof(*array->data()));
383 // sanity check for non-0 nullptr
384 ASSERT(array->data()[0] == nullptr);
385 }
386 } // namespace angle
387
388 void writeFile(const char *path, const void *data, size_t size);
389
390 // Get the underlying type. Useful for indexing into arrays with enum values by avoiding the clutter
391 // of the extraneous static_cast<>() calls.
392 // https://stackoverflow.com/a/8357462
393 template <typename E>
ToUnderlying(E e)394 constexpr typename std::underlying_type<E>::type ToUnderlying(E e) noexcept
395 {
396 return static_cast<typename std::underlying_type<E>::type>(e);
397 }
398
399 #endif // COMMON_UTILITIES_H_
400