• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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