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