1 //
2 // Copyright 2016 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 // Format:
7 //   A universal description of typed GPU storage. Across multiple
8 //   renderer back-ends, there are common formats and some distinct
9 //   permutations, this enum encapsulates them all. Formats apply to
10 //   textures, but could also apply to any typed data.
11 
12 #ifndef LIBANGLE_RENDERER_FORMAT_H_
13 #define LIBANGLE_RENDERER_FORMAT_H_
14 
15 #include "libANGLE/renderer/FormatID_autogen.h"
16 #include "libANGLE/renderer/renderer_utils.h"
17 
18 namespace angle
19 {
20 enum class FormatID;
21 
22 extern const Format gFormatInfoTable[];
23 
24 struct Format final : private angle::NonCopyable
25 {
26     inline constexpr Format(FormatID id,
27                             GLenum glFormat,
28                             GLenum fboFormat,
29                             rx::MipGenerationFunction mipGen,
30                             const rx::FastCopyFunctionMap &fastCopyFunctions,
31                             rx::PixelReadFunction colorRead,
32                             rx::PixelWriteFunction colorWrite,
33                             GLenum componentType,
34                             GLuint redBits,
35                             GLuint greenBits,
36                             GLuint blueBits,
37                             GLuint alphaBits,
38                             GLuint luminanceBits,
39                             GLuint depthBits,
40                             GLuint stencilBits,
41                             GLuint pixelBytes,
42                             GLuint componentAlignmentMask,
43                             bool isBlock,
44                             bool isFixed,
45                             bool isScaled,
46                             bool isSRGB,
47                             bool isYUV,
48                             gl::VertexAttribType vertexAttribType);
49 
Getfinal50     static const Format &Get(FormatID id) { return gFormatInfoTable[static_cast<int>(id)]; }
51 
52     static FormatID InternalFormatToID(GLenum internalFormat);
53 
54     constexpr bool hasDepthOrStencilBits() const;
55     constexpr bool isLUMA() const;
56     constexpr bool isBGRA() const;
57 
58     constexpr bool isSint() const;
59     constexpr bool isUint() const;
60     constexpr bool isSnorm() const;
61     constexpr bool isUnorm() const;
62     constexpr bool isFloat() const;
63     constexpr bool isVertexTypeHalfFloat() const;
64 
isIntfinal65     constexpr bool isInt() const { return isSint() || isUint(); }
isNormfinal66     constexpr bool isNorm() const { return isSnorm() || isUnorm(); }
isPureIntfinal67     constexpr bool isPureInt() const { return isInt() && !isScaled; }
68 
69     bool operator==(const Format &other) const { return this->id == other.id; }
70 
71     FormatID id;
72 
73     // The closest matching GL internal format for the storage this format uses. Note that this
74     // may be a different internal format than the one this ANGLE format is used for.
75     GLenum glInternalFormat;
76 
77     // The format we should report to the GL layer when querying implementation formats from a FBO.
78     // This might not be the same as the glInternalFormat, since some DXGI formats don't have
79     // matching GL format enums, like BGRA4, BGR5A1 and B5G6R6.
80     GLenum fboImplementationInternalFormat;
81 
82     rx::MipGenerationFunction mipGenerationFunction;
83     rx::PixelReadFunction pixelReadFunction;
84     rx::PixelWriteFunction pixelWriteFunction;
85 
86     // A map from a gl::FormatType to a fast pixel copy function for this format.
87     const rx::FastCopyFunctionMap &fastCopyFunctions;
88 
89     GLenum componentType;
90 
91     GLuint redBits;
92     GLuint greenBits;
93     GLuint blueBits;
94     GLuint alphaBits;
95     GLuint luminanceBits;
96     GLuint depthBits;
97     GLuint stencilBits;
98 
99     GLuint pixelBytes;
100 
101     // For 1-byte components, is 0x0. For 2-byte, is 0x1. For 4-byte, is 0x3. For all others,
102     // MAX_UINT.
103     GLuint componentAlignmentMask;
104 
105     GLuint channelCount;
106 
107     bool isBlock;
108     bool isFixed;
109     bool isScaled;
110     bool isSRGB;
111     bool isYUV;
112 
113     // For vertex formats only. Returns the "type" value for glVertexAttribPointer etc.
114     gl::VertexAttribType vertexAttribType;
115 };
116 
GetChannelCount(GLuint redBits,GLuint greenBits,GLuint blueBits,GLuint alphaBits,GLuint luminanceBits,GLuint depthBits,GLuint stencilBits)117 constexpr GLuint GetChannelCount(GLuint redBits,
118                                  GLuint greenBits,
119                                  GLuint blueBits,
120                                  GLuint alphaBits,
121                                  GLuint luminanceBits,
122                                  GLuint depthBits,
123                                  GLuint stencilBits)
124 {
125     return (redBits > 0 ? 1 : 0) + (greenBits > 0 ? 1 : 0) + (blueBits > 0 ? 1 : 0) +
126            (alphaBits > 0 ? 1 : 0) + (luminanceBits > 0 ? 1 : 0) + (depthBits > 0 ? 1 : 0) +
127            (stencilBits > 0 ? 1 : 0);
128 }
129 
Format(FormatID id,GLenum glFormat,GLenum fboFormat,rx::MipGenerationFunction mipGen,const rx::FastCopyFunctionMap & fastCopyFunctions,rx::PixelReadFunction colorRead,rx::PixelWriteFunction colorWrite,GLenum componentType,GLuint redBits,GLuint greenBits,GLuint blueBits,GLuint alphaBits,GLuint luminanceBits,GLuint depthBits,GLuint stencilBits,GLuint pixelBytes,GLuint componentAlignmentMask,bool isBlock,bool isFixed,bool isScaled,bool isSRGB,bool isYUV,gl::VertexAttribType vertexAttribType)130 constexpr Format::Format(FormatID id,
131                          GLenum glFormat,
132                          GLenum fboFormat,
133                          rx::MipGenerationFunction mipGen,
134                          const rx::FastCopyFunctionMap &fastCopyFunctions,
135                          rx::PixelReadFunction colorRead,
136                          rx::PixelWriteFunction colorWrite,
137                          GLenum componentType,
138                          GLuint redBits,
139                          GLuint greenBits,
140                          GLuint blueBits,
141                          GLuint alphaBits,
142                          GLuint luminanceBits,
143                          GLuint depthBits,
144                          GLuint stencilBits,
145                          GLuint pixelBytes,
146                          GLuint componentAlignmentMask,
147                          bool isBlock,
148                          bool isFixed,
149                          bool isScaled,
150                          bool isSRGB,
151                          bool isYUV,
152                          gl::VertexAttribType vertexAttribType)
153     : id(id),
154       glInternalFormat(glFormat),
155       fboImplementationInternalFormat(fboFormat),
156       mipGenerationFunction(mipGen),
157       pixelReadFunction(colorRead),
158       pixelWriteFunction(colorWrite),
159       fastCopyFunctions(fastCopyFunctions),
160       componentType(componentType),
161       redBits(redBits),
162       greenBits(greenBits),
163       blueBits(blueBits),
164       alphaBits(alphaBits),
165       luminanceBits(luminanceBits),
166       depthBits(depthBits),
167       stencilBits(stencilBits),
168       pixelBytes(pixelBytes),
169       componentAlignmentMask(componentAlignmentMask),
170       channelCount(GetChannelCount(redBits,
171                                    greenBits,
172                                    blueBits,
173                                    alphaBits,
174                                    luminanceBits,
175                                    depthBits,
176                                    stencilBits)),
177       isBlock(isBlock),
178       isFixed(isFixed),
179       isScaled(isScaled),
180       isSRGB(isSRGB),
181       isYUV(isYUV),
182       vertexAttribType(vertexAttribType)
183 {}
184 
hasDepthOrStencilBits()185 constexpr bool Format::hasDepthOrStencilBits() const
186 {
187     return depthBits > 0 || stencilBits > 0;
188 }
189 
isLUMA()190 constexpr bool Format::isLUMA() const
191 {
192     // There's no format with G or B without R
193     ASSERT(redBits > 0 || (greenBits == 0 && blueBits == 0));
194     return redBits == 0 && (luminanceBits > 0 || alphaBits > 0);
195 }
196 
isBGRA()197 constexpr bool Format::isBGRA() const
198 {
199     return id == FormatID::B8G8R8A8_UNORM || id == FormatID::B8G8R8A8_UNORM_SRGB ||
200            id == FormatID::B8G8R8A8_TYPELESS || id == FormatID::B8G8R8A8_TYPELESS_SRGB;
201 }
202 
isSint()203 constexpr bool Format::isSint() const
204 {
205     return componentType == GL_INT;
206 }
207 
isUint()208 constexpr bool Format::isUint() const
209 {
210     return componentType == GL_UNSIGNED_INT;
211 }
212 
isSnorm()213 constexpr bool Format::isSnorm() const
214 {
215     return componentType == GL_SIGNED_NORMALIZED;
216 }
217 
isUnorm()218 constexpr bool Format::isUnorm() const
219 {
220     return componentType == GL_UNSIGNED_NORMALIZED;
221 }
222 
isFloat()223 constexpr bool Format::isFloat() const
224 {
225     return componentType == GL_FLOAT;
226 }
227 
isVertexTypeHalfFloat()228 constexpr bool Format::isVertexTypeHalfFloat() const
229 {
230     return vertexAttribType == gl::VertexAttribType::HalfFloat;
231 }
232 
233 template <typename T>
234 using FormatMap = PackedEnumMap<FormatID, T, kNumANGLEFormats>;
235 
236 }  // namespace angle
237 
238 #endif  // LIBANGLE_RENDERER_FORMAT_H_
239