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_format_sRGB_override and EXT_texture_sRGB_decode
243 // A texture may be forced to decode to a nonlinear colorspace, to a linear colorspace, or to the
244 // default colorspace of its current format.
245 //
246 // Default corresponds to "the texture should use the imageview that corresponds to its format"
247 // Linear corresponds to "the texture has sRGB decoding disabled by extension, and should use a
248 // linear imageview even if it is in a nonlinear format" NonLinear corresponds to "the texture has
249 // sRGB override enabled by extension, and should use a nonlinear imageview even if it is in a
250 // linear format"
251 enum class SrgbOverride
252 {
253 Default = 0,
254 SRGB,
255 Linear
256 };
257
258 // For use with EXT_sRGB_write_control
259 // A render target may be forced to convert to a linear colorspace, or may be allowed to do whatever
260 // colorspace conversion is appropriate for its format. There is no option to force linear->sRGB, it
261 // can only convert from sRGB->linear
262 enum class SrgbWriteControlMode
263 {
264 Default = 0,
265 Linear = 1
266 };
267
268 // For use with EXT_YUV_target
269 // A sampler of external YUV textures may either implicitly perform RGB conversion (regular
270 // samplerExternalOES) or skip the conversion and sample raw YUV values (__samplerExternal2DY2Y).
271 enum class YuvSamplingMode
272 {
273 Default = 0,
274 Y2Y = 1
275 };
276
277 ShaderType GetShaderTypeFromBitfield(size_t singleShaderType);
278 GLbitfield GetBitfieldFromShaderType(ShaderType shaderType);
279 bool ShaderTypeSupportsTransformFeedback(ShaderType shaderType);
280 // Given a set of shader stages, returns the last vertex processing stage. This is the stage that
281 // interfaces the fragment shader.
282 ShaderType GetLastPreFragmentStage(ShaderBitSet shaderTypes);
283
284 } // namespace gl
285
286 namespace egl
287 {
288 static const EGLenum FirstCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR;
289 static const EGLenum LastCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR;
290 bool IsCubeMapTextureTarget(EGLenum target);
291 size_t CubeMapTextureTargetToLayerIndex(EGLenum target);
292 EGLenum LayerIndexToCubeMapTextureTarget(size_t index);
293 bool IsTextureTarget(EGLenum target);
294 bool IsRenderbufferTarget(EGLenum target);
295 bool IsExternalImageTarget(EGLenum target);
296
297 const char *GetGenericErrorMessage(EGLint error);
298 } // namespace egl
299
300 namespace egl_gl
301 {
302 GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer);
303 }
304
305 namespace gl_egl
306 {
307 EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType);
308 EGLClientBuffer GLObjectHandleToEGLClientBuffer(GLuint handle);
309 } // namespace gl_egl
310
311 namespace angle
312 {
313
314 template <typename T>
ConstStrLen(T s)315 constexpr size_t ConstStrLen(T s)
316 {
317 if (s == nullptr)
318 {
319 return 0;
320 }
321 return std::char_traits<char>::length(s);
322 }
323
324 bool IsDrawEntryPoint(EntryPoint entryPoint);
325 bool IsDispatchEntryPoint(EntryPoint entryPoint);
326 bool IsClearEntryPoint(EntryPoint entryPoint);
327 bool IsQueryEntryPoint(EntryPoint entryPoint);
328
329 template <typename T>
FillWithNullptr(T * array)330 void FillWithNullptr(T *array)
331 {
332 // std::array::fill(nullptr) yields unoptimized, unrolled loop over array items
333 memset(array->data(), 0, array->size() * sizeof(*array->data()));
334 // sanity check for non-0 nullptr
335 ASSERT(array->data()[0] == nullptr);
336 }
337 } // namespace angle
338
339 void writeFile(const char *path, const void *data, size_t size);
340
341 // Get the underlying type. Useful for indexing into arrays with enum values by avoiding the clutter
342 // of the extraneous static_cast<>() calls.
343 // https://stackoverflow.com/a/8357462
344 template <typename E>
ToUnderlying(E e)345 constexpr typename std::underlying_type<E>::type ToUnderlying(E e) noexcept
346 {
347 return static_cast<typename std::underlying_type<E>::type>(e);
348 }
349
350 #endif // COMMON_UTILITIES_H_
351