summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/libANGLE/renderer/Format.h
blob: 1974381f53a8b9fb2224a15fe976fca13f8a42d4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Format:
//   A universal description of typed GPU storage. Across multiple
//   renderer back-ends, there are common formats and some distinct
//   permutations, this enum encapsulates them all. Formats apply to
//   textures, but could also apply to any typed data.

#ifndef LIBANGLE_RENDERER_FORMAT_H_
#define LIBANGLE_RENDERER_FORMAT_H_

#include "libANGLE/renderer/FormatID_autogen.h"
#include "libANGLE/renderer/renderer_utils.h"

namespace angle
{
enum class FormatID;

extern const Format gFormatInfoTable[];

struct Format final : private angle::NonCopyable
{
    inline constexpr 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);

    static const Format &Get(FormatID id) { return gFormatInfoTable[static_cast<int>(id)]; }

    static FormatID InternalFormatToID(GLenum internalFormat);

    constexpr bool hasDepthOrStencilBits() const;
    constexpr bool isLUMA() const;
    constexpr bool isBGRA() const;

    constexpr bool isSint() const;
    constexpr bool isUint() const;
    constexpr bool isSnorm() const;
    constexpr bool isUnorm() const;
    constexpr bool isFloat() const;
    constexpr bool isVertexTypeHalfFloat() const;

    constexpr bool isInt() const { return isSint() || isUint(); }
    constexpr bool isNorm() const { return isSnorm() || isUnorm(); }
    constexpr bool isPureInt() const { return isInt() && !isScaled; }

    bool operator==(const Format &other) const { return this->id == other.id; }

    FormatID id;

    // The closest matching GL internal format for the storage this format uses. Note that this
    // may be a different internal format than the one this ANGLE format is used for.
    GLenum glInternalFormat;

    // The format we should report to the GL layer when querying implementation formats from a FBO.
    // This might not be the same as the glInternalFormat, since some DXGI formats don't have
    // matching GL format enums, like BGRA4, BGR5A1 and B5G6R6.
    GLenum fboImplementationInternalFormat;

    rx::MipGenerationFunction mipGenerationFunction;
    rx::PixelReadFunction pixelReadFunction;
    rx::PixelWriteFunction pixelWriteFunction;

    // A map from a gl::FormatType to a fast pixel copy function for this format.
    const rx::FastCopyFunctionMap &fastCopyFunctions;

    GLenum componentType;

    GLuint redBits;
    GLuint greenBits;
    GLuint blueBits;
    GLuint alphaBits;
    GLuint luminanceBits;
    GLuint depthBits;
    GLuint stencilBits;

    GLuint pixelBytes;

    // For 1-byte components, is 0x0. For 2-byte, is 0x1. For 4-byte, is 0x3. For all others,
    // MAX_UINT.
    GLuint componentAlignmentMask;

    GLuint channelCount;

    bool isBlock;
    bool isFixed;
    bool isScaled;
    bool isSRGB;
    bool isYUV;

    // For vertex formats only. Returns the "type" value for glVertexAttribPointer etc.
    gl::VertexAttribType vertexAttribType;
};

constexpr GLuint GetChannelCount(GLuint redBits,
                                 GLuint greenBits,
                                 GLuint blueBits,
                                 GLuint alphaBits,
                                 GLuint luminanceBits,
                                 GLuint depthBits,
                                 GLuint stencilBits)
{
    return (redBits > 0 ? 1 : 0) + (greenBits > 0 ? 1 : 0) + (blueBits > 0 ? 1 : 0) +
           (alphaBits > 0 ? 1 : 0) + (luminanceBits > 0 ? 1 : 0) + (depthBits > 0 ? 1 : 0) +
           (stencilBits > 0 ? 1 : 0);
}

constexpr Format::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)
    : id(id),
      glInternalFormat(glFormat),
      fboImplementationInternalFormat(fboFormat),
      mipGenerationFunction(mipGen),
      pixelReadFunction(colorRead),
      pixelWriteFunction(colorWrite),
      fastCopyFunctions(fastCopyFunctions),
      componentType(componentType),
      redBits(redBits),
      greenBits(greenBits),
      blueBits(blueBits),
      alphaBits(alphaBits),
      luminanceBits(luminanceBits),
      depthBits(depthBits),
      stencilBits(stencilBits),
      pixelBytes(pixelBytes),
      componentAlignmentMask(componentAlignmentMask),
      channelCount(GetChannelCount(redBits,
                                   greenBits,
                                   blueBits,
                                   alphaBits,
                                   luminanceBits,
                                   depthBits,
                                   stencilBits)),
      isBlock(isBlock),
      isFixed(isFixed),
      isScaled(isScaled),
      isSRGB(isSRGB),
      isYUV(isYUV),
      vertexAttribType(vertexAttribType)
{}

constexpr bool Format::hasDepthOrStencilBits() const
{
    return depthBits > 0 || stencilBits > 0;
}

constexpr bool Format::isLUMA() const
{
    // There's no format with G or B without R
    ASSERT(redBits > 0 || (greenBits == 0 && blueBits == 0));
    return redBits == 0 && (luminanceBits > 0 || alphaBits > 0);
}

constexpr bool Format::isBGRA() const
{
    return id == FormatID::B8G8R8A8_UNORM || id == FormatID::B8G8R8A8_UNORM_SRGB ||
           id == FormatID::B8G8R8A8_TYPELESS || id == FormatID::B8G8R8A8_TYPELESS_SRGB;
}

constexpr bool Format::isSint() const
{
    return componentType == GL_INT;
}

constexpr bool Format::isUint() const
{
    return componentType == GL_UNSIGNED_INT;
}

constexpr bool Format::isSnorm() const
{
    return componentType == GL_SIGNED_NORMALIZED;
}

constexpr bool Format::isUnorm() const
{
    return componentType == GL_UNSIGNED_NORMALIZED;
}

constexpr bool Format::isFloat() const
{
    return componentType == GL_FLOAT;
}

constexpr bool Format::isVertexTypeHalfFloat() const
{
    return vertexAttribType == gl::VertexAttribType::HalfFloat;
}

template <typename T>
using FormatMap = PackedEnumMap<FormatID, T, kNumANGLEFormats>;

}  // namespace angle

#endif  // LIBANGLE_RENDERER_FORMAT_H_