1 //
2 // Copyright 2013 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 // formatutils.h: Queries for GL image formats.
8
9 #ifndef LIBANGLE_FORMATUTILS_H_
10 #define LIBANGLE_FORMATUTILS_H_
11
12 #include <stdint.h>
13 #include <cstddef>
14 #include <ostream>
15
16 #include "angle_gl.h"
17 #include "libANGLE/Caps.h"
18 #include "libANGLE/Error.h"
19 #include "libANGLE/Version.h"
20 #include "libANGLE/VertexAttribute.h"
21 #include "libANGLE/angletypes.h"
22
23 namespace gl
24 {
25 struct VertexAttribute;
26
27 struct FormatType final
28 {
29 FormatType();
30 FormatType(GLenum format_, GLenum type_);
31 FormatType(const FormatType &other) = default;
32 FormatType &operator=(const FormatType &other) = default;
33
34 bool operator<(const FormatType &other) const;
35
36 GLenum format;
37 GLenum type;
38 };
39
40 struct Type
41 {
TypeType42 Type() : bytes(0), bytesShift(0), specialInterpretation(0) {}
43
TypeType44 explicit Type(uint32_t packedTypeInfo)
45 : bytes(packedTypeInfo & 0xff),
46 bytesShift((packedTypeInfo >> 8) & 0xff),
47 specialInterpretation((packedTypeInfo >> 16) & 1)
48 {}
49
50 GLuint bytes;
51 GLuint bytesShift; // Bit shift by this value to effectively divide/multiply by "bytes" in a
52 // more optimal way
53 bool specialInterpretation;
54 };
55
56 uint32_t GetPackedTypeInfo(GLenum type);
57
GetTypeInfo(GLenum type)58 ANGLE_INLINE const Type GetTypeInfo(GLenum type)
59 {
60 return Type(GetPackedTypeInfo(type));
61 }
62
63 // This helpers use tricks based on the assumption that the type has certain values.
64 static_assert(static_cast<GLuint>(DrawElementsType::UnsignedByte) == 0, "Please update this code.");
65 static_assert(static_cast<GLuint>(DrawElementsType::UnsignedShort) == 1,
66 "Please update this code.");
67 static_assert(static_cast<GLuint>(DrawElementsType::UnsignedInt) == 2, "Please update this code.");
GetDrawElementsTypeSize(DrawElementsType type)68 ANGLE_INLINE GLuint GetDrawElementsTypeSize(DrawElementsType type)
69 {
70 return (1 << static_cast<GLuint>(type));
71 }
72
GetDrawElementsTypeShift(DrawElementsType type)73 ANGLE_INLINE GLuint GetDrawElementsTypeShift(DrawElementsType type)
74 {
75 return static_cast<GLuint>(type);
76 }
77
78 // Information about an OpenGL internal format. Can be keyed on the internalFormat and type
79 // members.
80 struct InternalFormat
81 {
82 InternalFormat();
83 InternalFormat(const InternalFormat &other);
84
85 GLuint computePixelBytes(GLenum formatType) const;
86
87 ANGLE_NO_DISCARD bool computeRowPitch(GLenum formatType,
88 GLsizei width,
89 GLint alignment,
90 GLint rowLength,
91 GLuint *resultOut) const;
92 ANGLE_NO_DISCARD bool computeDepthPitch(GLsizei height,
93 GLint imageHeight,
94 GLuint rowPitch,
95 GLuint *resultOut) const;
96 ANGLE_NO_DISCARD bool computeDepthPitch(GLenum formatType,
97 GLsizei width,
98 GLsizei height,
99 GLint alignment,
100 GLint rowLength,
101 GLint imageHeight,
102 GLuint *resultOut) const;
103
104 ANGLE_NO_DISCARD bool computeCompressedImageSize(const Extents &size, GLuint *resultOut) const;
105
106 ANGLE_NO_DISCARD bool computeSkipBytes(GLenum formatType,
107 GLuint rowPitch,
108 GLuint depthPitch,
109 const PixelStoreStateBase &state,
110 bool is3D,
111 GLuint *resultOut) const;
112
113 ANGLE_NO_DISCARD bool computePackUnpackEndByte(GLenum formatType,
114 const Extents &size,
115 const PixelStoreStateBase &state,
116 bool is3D,
117 GLuint *resultOut) const;
118
119 bool isLUMA() const;
120 GLenum getReadPixelsFormat() const;
121 GLenum getReadPixelsType(const Version &version) const;
122
123 // Return true if the format is a required renderbuffer format in the given version of the core
124 // spec. Note that it isn't always clear whether all the rules that apply to core required
125 // renderbuffer formats also apply to additional formats added by extensions. Because of this
126 // extension formats are conservatively not included.
127 bool isRequiredRenderbufferFormat(const Version &version) const;
128
129 bool isInt() const;
130 bool isDepthOrStencil() const;
131
132 bool operator==(const InternalFormat &other) const;
133 bool operator!=(const InternalFormat &other) const;
134
135 GLenum internalFormat;
136
137 bool sized;
138 GLenum sizedInternalFormat;
139
140 GLuint redBits;
141 GLuint greenBits;
142 GLuint blueBits;
143
144 GLuint luminanceBits;
145
146 GLuint alphaBits;
147 GLuint sharedBits;
148
149 GLuint depthBits;
150 GLuint stencilBits;
151
152 GLuint pixelBytes;
153
154 GLuint componentCount;
155
156 bool compressed;
157 GLuint compressedBlockWidth;
158 GLuint compressedBlockHeight;
159 GLuint compressedBlockDepth;
160
161 GLenum format;
162 GLenum type;
163
164 GLenum componentType;
165 GLenum colorEncoding;
166
167 typedef bool (*SupportCheckFunction)(const Version &, const Extensions &);
168 SupportCheckFunction textureSupport;
169 SupportCheckFunction filterSupport;
170 SupportCheckFunction textureAttachmentSupport; // glFramebufferTexture2D
171 SupportCheckFunction renderbufferSupport; // glFramebufferRenderbuffer
172 };
173
174 // A "Format" wraps an InternalFormat struct, querying it from either a sized internal format or
175 // unsized internal format and type.
176 // TODO(geofflang): Remove this, it doesn't add any more information than the InternalFormat object.
177 struct Format
178 {
179 // Sized types only.
180 explicit Format(GLenum internalFormat);
181
182 // Sized or unsized types.
183 explicit Format(const InternalFormat &internalFormat);
184 Format(GLenum internalFormat, GLenum type);
185
186 Format(const Format &other);
187 Format &operator=(const Format &other);
188
189 bool valid() const;
190
191 static Format Invalid();
192 static bool SameSized(const Format &a, const Format &b);
193 static bool EquivalentForBlit(const Format &a, const Format &b);
194
195 friend std::ostream &operator<<(std::ostream &os, const Format &fmt);
196
197 // This is the sized info.
198 const InternalFormat *info;
199 };
200
201 const InternalFormat &GetSizedInternalFormatInfo(GLenum internalFormat);
202 const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, GLenum type);
203
204 // Strip sizing information from an internal format. Doesn't necessarily validate that the internal
205 // format is valid.
206 GLenum GetUnsizedFormat(GLenum internalFormat);
207
208 typedef std::set<GLenum> FormatSet;
209 const FormatSet &GetAllSizedInternalFormats();
210
211 // From the ESSL 3.00.4 spec:
212 // Vertex shader inputs can only be float, floating-point vectors, matrices, signed and unsigned
213 // integers and integer vectors. Vertex shader inputs cannot be arrays or structures.
214
215 enum AttributeType
216 {
217 ATTRIBUTE_FLOAT,
218 ATTRIBUTE_VEC2,
219 ATTRIBUTE_VEC3,
220 ATTRIBUTE_VEC4,
221 ATTRIBUTE_INT,
222 ATTRIBUTE_IVEC2,
223 ATTRIBUTE_IVEC3,
224 ATTRIBUTE_IVEC4,
225 ATTRIBUTE_UINT,
226 ATTRIBUTE_UVEC2,
227 ATTRIBUTE_UVEC3,
228 ATTRIBUTE_UVEC4,
229 ATTRIBUTE_MAT2,
230 ATTRIBUTE_MAT3,
231 ATTRIBUTE_MAT4,
232 ATTRIBUTE_MAT2x3,
233 ATTRIBUTE_MAT2x4,
234 ATTRIBUTE_MAT3x2,
235 ATTRIBUTE_MAT3x4,
236 ATTRIBUTE_MAT4x2,
237 ATTRIBUTE_MAT4x3,
238 };
239
240 AttributeType GetAttributeType(GLenum enumValue);
241
242 typedef std::vector<angle::FormatID> InputLayout;
243
244 struct VertexFormat : private angle::NonCopyable
245 {
246 VertexFormat(GLenum typeIn, GLboolean normalizedIn, GLuint componentsIn, bool pureIntegerIn);
247
248 GLenum type;
249 GLboolean normalized;
250 GLuint components;
251 bool pureInteger;
252 };
253
254 angle::FormatID GetVertexFormatID(VertexAttribType type,
255 GLboolean normalized,
256 GLuint components,
257 bool pureInteger);
258
259 angle::FormatID GetVertexFormatID(const VertexAttribute &attrib, VertexAttribType currentValueType);
260 angle::FormatID GetCurrentValueFormatID(VertexAttribType currentValueType);
261 const VertexFormat &GetVertexFormatFromID(angle::FormatID vertexFormatID);
262 size_t GetVertexFormatSize(angle::FormatID vertexFormatID);
263
264 // Check if an internal format is ever valid in ES3. Makes no checks about support for a specific
265 // context.
266 bool ValidES3InternalFormat(GLenum internalFormat);
267
268 // Implemented in format_map_autogen.cpp
269 bool ValidES3Format(GLenum format);
270 bool ValidES3Type(GLenum type);
271 bool ValidES3FormatCombination(GLenum format, GLenum type, GLenum internalFormat);
272
273 // Implemented in format_map_desktop.cpp
274 bool ValidDesktopFormat(GLenum format);
275 bool ValidDesktopType(GLenum type);
276 bool ValidDesktopFormatCombination(GLenum format, GLenum type, GLenum internalFormat);
277
278 // Implemented in es3_copy_conversion_table_autogen.cpp
279 bool ValidES3CopyConversion(GLenum textureFormat, GLenum framebufferFormat);
280
GetVertexAttributeComponentType(bool pureInteger,VertexAttribType type)281 ANGLE_INLINE ComponentType GetVertexAttributeComponentType(bool pureInteger, VertexAttribType type)
282 {
283 if (pureInteger)
284 {
285 switch (type)
286 {
287 case VertexAttribType::Byte:
288 case VertexAttribType::Short:
289 case VertexAttribType::Int:
290 return ComponentType::Int;
291
292 case VertexAttribType::UnsignedByte:
293 case VertexAttribType::UnsignedShort:
294 case VertexAttribType::UnsignedInt:
295 return ComponentType::UnsignedInt;
296
297 default:
298 UNREACHABLE();
299 return ComponentType::NoType;
300 }
301 }
302 else
303 {
304 return ComponentType::Float;
305 }
306 }
307 } // namespace gl
308
309 #endif // LIBANGLE_FORMATUTILS_H_
310