blob: c822a969edad42d242208bdb28caed9cc8904be3 [file] [log] [blame]
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00003// 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.cpp: Queries for GL image formats.
8
Shannon Woods4d161ba2014-03-17 18:13:30 -04009#include "common/mathutil.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/formatutils.h"
11#include "libANGLE/Context.h"
12#include "libANGLE/Framebuffer.h"
13#include "libANGLE/renderer/Renderer.h"
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000014
15namespace gl
16{
17
18// ES2 requires that format is equal to internal format at all glTex*Image2D entry points and the implementation
19// can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid
20// format and type combinations.
21
22typedef std::pair<GLenum, GLenum> FormatTypePair;
Geoff Lang051dbc72015-01-05 15:48:58 -050023typedef std::pair<FormatTypePair, GLenum> FormatPair;
24typedef std::map<FormatTypePair, GLenum> FormatMap;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000025
Jamie Madill89a0bf52013-09-18 14:36:24 -040026// A helper function to insert data into the format map with fewer characters.
Geoff Lang051dbc72015-01-05 15:48:58 -050027static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000028{
Geoff Lang051dbc72015-01-05 15:48:58 -050029 map->insert(FormatPair(FormatTypePair(format, type), internalFormat));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000030}
31
Geoff Lange4a492b2014-06-19 14:14:41 -040032FormatMap BuildFormatMap()
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000033{
34 FormatMap map;
35
Geoff Lang051dbc72015-01-05 15:48:58 -050036 // | Format | Type | Internal format |
37 InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8);
38 InsertFormatMapping(&map, GL_RGBA, GL_BYTE, GL_RGBA8_SNORM);
39 InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4);
40 InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1);
41 InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2);
42 InsertFormatMapping(&map, GL_RGBA, GL_FLOAT, GL_RGBA32F);
43 InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F);
44 InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA16F);
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000045
Geoff Lang051dbc72015-01-05 15:48:58 -050046 InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_RGBA8UI);
47 InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_BYTE, GL_RGBA8I);
48 InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_RGBA16UI);
49 InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_SHORT, GL_RGBA16I);
50 InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_RGBA32UI);
51 InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_INT, GL_RGBA32I);
52 InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2UI);
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000053
Geoff Lang051dbc72015-01-05 15:48:58 -050054 InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8);
55 InsertFormatMapping(&map, GL_RGB, GL_BYTE, GL_RGB8_SNORM);
56 InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565);
57 InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_R11F_G11F_B10F);
58 InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_RGB9_E5);
59 InsertFormatMapping(&map, GL_RGB, GL_FLOAT, GL_RGB32F);
60 InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT, GL_RGB16F);
61 InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT_OES, GL_RGB16F);
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000062
Geoff Lang051dbc72015-01-05 15:48:58 -050063 InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_RGB8UI);
64 InsertFormatMapping(&map, GL_RGB_INTEGER, GL_BYTE, GL_RGB8I);
65 InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_RGB16UI);
66 InsertFormatMapping(&map, GL_RGB_INTEGER, GL_SHORT, GL_RGB16I);
67 InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_RGB32UI);
68 InsertFormatMapping(&map, GL_RGB_INTEGER, GL_INT, GL_RGB32I);
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000069
Geoff Lang051dbc72015-01-05 15:48:58 -050070 InsertFormatMapping(&map, GL_RG, GL_UNSIGNED_BYTE, GL_RG8);
71 InsertFormatMapping(&map, GL_RG, GL_BYTE, GL_RG8_SNORM);
72 InsertFormatMapping(&map, GL_RG, GL_FLOAT, GL_RG32F);
73 InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT, GL_RG16F);
74 InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT_OES, GL_RG16F);
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000075
Geoff Lang051dbc72015-01-05 15:48:58 -050076 InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_RG8UI);
77 InsertFormatMapping(&map, GL_RG_INTEGER, GL_BYTE, GL_RG8I);
78 InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_RG16UI);
79 InsertFormatMapping(&map, GL_RG_INTEGER, GL_SHORT, GL_RG16I);
80 InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_RG32UI);
81 InsertFormatMapping(&map, GL_RG_INTEGER, GL_INT, GL_RG32I);
Geoff Langfe28ca02013-06-04 10:10:48 -040082
Geoff Lang051dbc72015-01-05 15:48:58 -050083 InsertFormatMapping(&map, GL_RED, GL_UNSIGNED_BYTE, GL_R8);
84 InsertFormatMapping(&map, GL_RED, GL_BYTE, GL_R8_SNORM);
85 InsertFormatMapping(&map, GL_RED, GL_FLOAT, GL_R32F);
86 InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT, GL_R16F);
87 InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT_OES, GL_R16F);
Geoff Langfe28ca02013-06-04 10:10:48 -040088
Geoff Lang051dbc72015-01-05 15:48:58 -050089 InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_R8UI);
90 InsertFormatMapping(&map, GL_RED_INTEGER, GL_BYTE, GL_R8I);
91 InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_R16UI);
92 InsertFormatMapping(&map, GL_RED_INTEGER, GL_SHORT, GL_R16I);
93 InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_R32UI);
94 InsertFormatMapping(&map, GL_RED_INTEGER, GL_INT, GL_R32I);
Geoff Langfe28ca02013-06-04 10:10:48 -040095
Geoff Lang051dbc72015-01-05 15:48:58 -050096 InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8_EXT);
97 InsertFormatMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8_EXT);
98 InsertFormatMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8_EXT);
99 InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_LUMINANCE_ALPHA32F_EXT);
100 InsertFormatMapping(&map, GL_LUMINANCE, GL_FLOAT, GL_LUMINANCE32F_EXT);
101 InsertFormatMapping(&map, GL_ALPHA, GL_FLOAT, GL_ALPHA32F_EXT);
102 InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_LUMINANCE_ALPHA16F_EXT);
103 InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_LUMINANCE_ALPHA16F_EXT);
104 InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT, GL_LUMINANCE16F_EXT);
105 InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_LUMINANCE16F_EXT);
106 InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT, GL_ALPHA16F_EXT);
107 InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT_OES, GL_ALPHA16F_EXT);
Geoff Langfe28ca02013-06-04 10:10:48 -0400108
Geoff Lang051dbc72015-01-05 15:48:58 -0500109 InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_BGRA8_EXT);
110 InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX);
111 InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX);
Geoff Langfe28ca02013-06-04 10:10:48 -0400112
Geoff Lang051dbc72015-01-05 15:48:58 -0500113 InsertFormatMapping(&map, GL_SRGB_EXT, GL_UNSIGNED_BYTE, GL_SRGB8);
114 InsertFormatMapping(&map, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, GL_SRGB8_ALPHA8);
Geoff Langfe28ca02013-06-04 10:10:48 -0400115
Geoff Lang051dbc72015-01-05 15:48:58 -0500116 InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
117 InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
118 InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);
119 InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);
Geoff Lang05b05022014-06-11 15:31:45 -0400120
Geoff Lang051dbc72015-01-05 15:48:58 -0500121 InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16);
122 InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT32_OES);
123 InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT32F);
Geoff Langcec35902014-04-16 10:52:36 -0400124
Geoff Lang051dbc72015-01-05 15:48:58 -0500125 InsertFormatMapping(&map, GL_STENCIL, GL_UNSIGNED_BYTE, GL_STENCIL_INDEX8);
Geoff Langfe28ca02013-06-04 10:10:48 -0400126
Geoff Lang051dbc72015-01-05 15:48:58 -0500127 InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8);
128 InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8);
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000129
130 return map;
131}
132
Geoff Lang5d601382014-07-22 15:14:06 -0400133Type::Type()
134 : bytes(0),
135 specialInterpretation(false)
Geoff Langfe28ca02013-06-04 10:10:48 -0400136{
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000137}
138
139// Map of sizes of input types
Geoff Lang5d601382014-07-22 15:14:06 -0400140typedef std::pair<GLenum, Type> TypeInfoPair;
141typedef std::map<GLenum, Type> TypeInfoMap;
142
143static inline void InsertTypeInfo(TypeInfoMap *map, GLenum type, GLuint bytes, bool specialInterpretation)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000144{
Geoff Lang5d601382014-07-22 15:14:06 -0400145 Type info;
146 info.bytes = bytes;
147 info.specialInterpretation = specialInterpretation;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000148
Geoff Lang5d601382014-07-22 15:14:06 -0400149 map->insert(std::make_pair(type, info));
150}
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000151
Geoff Lang5d601382014-07-22 15:14:06 -0400152bool operator<(const Type& a, const Type& b)
153{
154 return memcmp(&a, &b, sizeof(Type)) < 0;
155}
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000156
Geoff Lang18591b72013-06-07 12:00:15 -0400157static TypeInfoMap BuildTypeInfoMap()
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000158{
159 TypeInfoMap map;
160
Geoff Lang5d601382014-07-22 15:14:06 -0400161 InsertTypeInfo(&map, GL_UNSIGNED_BYTE, 1, false);
162 InsertTypeInfo(&map, GL_BYTE, 1, false);
163 InsertTypeInfo(&map, GL_UNSIGNED_SHORT, 2, false);
164 InsertTypeInfo(&map, GL_SHORT, 2, false);
165 InsertTypeInfo(&map, GL_UNSIGNED_INT, 4, false);
166 InsertTypeInfo(&map, GL_INT, 4, false);
167 InsertTypeInfo(&map, GL_HALF_FLOAT, 2, false);
168 InsertTypeInfo(&map, GL_HALF_FLOAT_OES, 2, false);
169 InsertTypeInfo(&map, GL_FLOAT, 4, false);
170 InsertTypeInfo(&map, GL_UNSIGNED_SHORT_5_6_5, 2, true );
171 InsertTypeInfo(&map, GL_UNSIGNED_SHORT_4_4_4_4, 2, true );
172 InsertTypeInfo(&map, GL_UNSIGNED_SHORT_5_5_5_1, 2, true );
173 InsertTypeInfo(&map, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, 2, true );
174 InsertTypeInfo(&map, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, 2, true );
175 InsertTypeInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, 4, true );
176 InsertTypeInfo(&map, GL_UNSIGNED_INT_24_8, 4, true );
177 InsertTypeInfo(&map, GL_UNSIGNED_INT_10F_11F_11F_REV, 4, true );
178 InsertTypeInfo(&map, GL_UNSIGNED_INT_5_9_9_9_REV, 4, true );
179 InsertTypeInfo(&map, GL_UNSIGNED_INT_24_8_OES, 4, true );
180 InsertTypeInfo(&map, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8, true );
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000181
182 return map;
183}
184
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000185// Information about internal formats
Geoff Lang493daf52014-07-03 13:38:44 -0400186static bool AlwaysSupported(GLuint, const Extensions &)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000187{
Geoff Lang493daf52014-07-03 13:38:44 -0400188 return true;
189}
190
191static bool UnimplementedSupport(GLuint, const Extensions &)
192{
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000193 return false;
194}
195
Geoff Lang493daf52014-07-03 13:38:44 -0400196static bool NeverSupported(GLuint, const Extensions &)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000197{
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000198 return false;
199}
200
Geoff Lange4a492b2014-06-19 14:14:41 -0400201template <GLuint minCoreGLVersion>
Geoff Langabce7622014-09-19 16:13:00 -0400202static bool RequireES(GLuint clientVersion, const Extensions &)
Geoff Lange4a492b2014-06-19 14:14:41 -0400203{
204 return clientVersion >= minCoreGLVersion;
205}
206
Geoff Langcec35902014-04-16 10:52:36 -0400207// Pointer to a boolean memeber of the Extensions struct
208typedef bool(Extensions::*ExtensionBool);
209
210// Check support for a single extension
211template <ExtensionBool bool1>
Geoff Langabce7622014-09-19 16:13:00 -0400212static bool RequireExt(GLuint, const Extensions & extensions)
Geoff Langcec35902014-04-16 10:52:36 -0400213{
Geoff Lange4a492b2014-06-19 14:14:41 -0400214 return extensions.*bool1;
215}
216
217// Check for a minimum client version or a single extension
218template <GLuint minCoreGLVersion, ExtensionBool bool1>
Geoff Langabce7622014-09-19 16:13:00 -0400219static bool RequireESOrExt(GLuint clientVersion, const Extensions &extensions)
Geoff Lange4a492b2014-06-19 14:14:41 -0400220{
221 return clientVersion >= minCoreGLVersion || extensions.*bool1;
222}
223
224// Check for a minimum client version or two extensions
225template <GLuint minCoreGLVersion, ExtensionBool bool1, ExtensionBool bool2>
Geoff Langabce7622014-09-19 16:13:00 -0400226static bool RequireESOrExtAndExt(GLuint clientVersion, const Extensions &extensions)
Geoff Lange4a492b2014-06-19 14:14:41 -0400227{
Geoff Langabce7622014-09-19 16:13:00 -0400228 return clientVersion >= minCoreGLVersion || (extensions.*bool1 && extensions.*bool2);
229}
230
231// Check for a minimum client version or at least one of two extensions
232template <GLuint minCoreGLVersion, ExtensionBool bool1, ExtensionBool bool2>
233static bool RequireESOrExtOrExt(GLuint clientVersion, const Extensions &extensions)
234{
235 return clientVersion >= minCoreGLVersion || extensions.*bool1 || extensions.*bool2;
Geoff Langcec35902014-04-16 10:52:36 -0400236}
237
238// Check support for two extensions
239template <ExtensionBool bool1, ExtensionBool bool2>
Geoff Langabce7622014-09-19 16:13:00 -0400240static bool RequireExtAndExt(GLuint, const Extensions &extensions)
Geoff Langcec35902014-04-16 10:52:36 -0400241{
Geoff Langabce7622014-09-19 16:13:00 -0400242 return extensions.*bool1 && extensions.*bool2;
Geoff Langcec35902014-04-16 10:52:36 -0400243}
244
Geoff Lang5d601382014-07-22 15:14:06 -0400245InternalFormat::InternalFormat()
246 : redBits(0),
247 greenBits(0),
248 blueBits(0),
249 luminanceBits(0),
250 alphaBits(0),
251 sharedBits(0),
252 depthBits(0),
253 stencilBits(0),
254 pixelBytes(0),
255 componentCount(0),
256 compressedBlockWidth(0),
257 compressedBlockHeight(0),
258 format(GL_NONE),
259 type(GL_NONE),
260 componentType(GL_NONE),
261 colorEncoding(GL_NONE),
262 compressed(false),
263 textureSupport(NeverSupported),
264 renderSupport(NeverSupported),
265 filterSupport(NeverSupported)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000266{
Geoff Lang5d601382014-07-22 15:14:06 -0400267}
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000268
Geoff Lang5d601382014-07-22 15:14:06 -0400269static InternalFormat UnsizedFormat(GLenum format, InternalFormat::SupportCheckFunction textureSupport,
270 InternalFormat::SupportCheckFunction renderSupport,
271 InternalFormat::SupportCheckFunction filterSupport)
272{
273 InternalFormat formatInfo;
274 formatInfo.format = format;
275 formatInfo.textureSupport = textureSupport;
276 formatInfo.renderSupport = renderSupport;
277 formatInfo.filterSupport = filterSupport;
278 return formatInfo;
279}
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000280
Geoff Lang5d601382014-07-22 15:14:06 -0400281static InternalFormat RGBAFormat(GLuint red, GLuint green, GLuint blue, GLuint alpha, GLuint shared,
282 GLenum format, GLenum type, GLenum componentType, bool srgb,
283 InternalFormat::SupportCheckFunction textureSupport,
284 InternalFormat::SupportCheckFunction renderSupport,
285 InternalFormat::SupportCheckFunction filterSupport)
286{
287 InternalFormat formatInfo;
288 formatInfo.redBits = red;
289 formatInfo.greenBits = green;
290 formatInfo.blueBits = blue;
291 formatInfo.alphaBits = alpha;
292 formatInfo.sharedBits = shared;
293 formatInfo.pixelBytes = (red + green + blue + alpha + shared) / 8;
294 formatInfo.componentCount = ((red > 0) ? 1 : 0) + ((green > 0) ? 1 : 0) + ((blue > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
295 formatInfo.format = format;
296 formatInfo.type = type;
297 formatInfo.componentType = componentType;
298 formatInfo.colorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
299 formatInfo.textureSupport = textureSupport;
300 formatInfo.renderSupport = renderSupport;
301 formatInfo.filterSupport = filterSupport;
302 return formatInfo;
303}
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000304
Geoff Lang5d601382014-07-22 15:14:06 -0400305static InternalFormat LUMAFormat(GLuint luminance, GLuint alpha, GLenum format, GLenum type, GLenum componentType,
306 InternalFormat::SupportCheckFunction textureSupport,
307 InternalFormat::SupportCheckFunction renderSupport,
308 InternalFormat::SupportCheckFunction filterSupport)
309{
310 InternalFormat formatInfo;
311 formatInfo.luminanceBits = luminance;
312 formatInfo.alphaBits = alpha;
313 formatInfo.pixelBytes = (luminance + alpha) / 8;
314 formatInfo.componentCount = ((luminance > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
315 formatInfo.format = format;
316 formatInfo.type = type;
317 formatInfo.componentType = componentType;
318 formatInfo.colorEncoding = GL_LINEAR;
319 formatInfo.textureSupport = textureSupport;
320 formatInfo.renderSupport = renderSupport;
321 formatInfo.filterSupport = filterSupport;
322 return formatInfo;
323}
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000324
Geoff Lang5d601382014-07-22 15:14:06 -0400325static InternalFormat DepthStencilFormat(GLuint depthBits, GLuint stencilBits, GLuint unusedBits, GLenum format,
326 GLenum type, GLenum componentType, InternalFormat::SupportCheckFunction textureSupport,
327 InternalFormat::SupportCheckFunction renderSupport,
328 InternalFormat::SupportCheckFunction filterSupport)
329{
330 InternalFormat formatInfo;
331 formatInfo.depthBits = depthBits;
332 formatInfo.stencilBits = stencilBits;
333 formatInfo.pixelBytes = (depthBits + stencilBits + unusedBits) / 8;
334 formatInfo.componentCount = ((depthBits > 0) ? 1 : 0) + ((stencilBits > 0) ? 1 : 0);
335 formatInfo.format = format;
336 formatInfo.type = type;
337 formatInfo.componentType = componentType;
338 formatInfo.colorEncoding = GL_LINEAR;
339 formatInfo.textureSupport = textureSupport;
340 formatInfo.renderSupport = renderSupport;
341 formatInfo.filterSupport = filterSupport;
342 return formatInfo;
343}
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000344
Geoff Lang5d601382014-07-22 15:14:06 -0400345static InternalFormat CompressedFormat(GLuint compressedBlockWidth, GLuint compressedBlockHeight, GLuint compressedBlockSize,
346 GLuint componentCount, GLenum format, GLenum type, bool srgb,
347 InternalFormat::SupportCheckFunction textureSupport,
348 InternalFormat::SupportCheckFunction renderSupport,
349 InternalFormat::SupportCheckFunction filterSupport)
350{
351 InternalFormat formatInfo;
352 formatInfo.compressedBlockWidth = compressedBlockWidth;
353 formatInfo.compressedBlockHeight = compressedBlockHeight;
354 formatInfo.pixelBytes = compressedBlockSize / 8;
355 formatInfo.componentCount = componentCount;
356 formatInfo.format = format;
357 formatInfo.type = type;
358 formatInfo.componentType = GL_UNSIGNED_NORMALIZED;
359 formatInfo.colorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
360 formatInfo.compressed = true;
361 formatInfo.textureSupport = textureSupport;
362 formatInfo.renderSupport = renderSupport;
363 formatInfo.filterSupport = filterSupport;
364 return formatInfo;
365}
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000366
Geoff Lang5d601382014-07-22 15:14:06 -0400367typedef std::pair<GLenum, InternalFormat> InternalFormatInfoPair;
368typedef std::map<GLenum, InternalFormat> InternalFormatInfoMap;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000369
Geoff Lange4a492b2014-06-19 14:14:41 -0400370static InternalFormatInfoMap BuildInternalFormatInfoMap()
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000371{
372 InternalFormatInfoMap map;
373
374 // From ES 3.0.1 spec, table 3.12
Geoff Lang5d601382014-07-22 15:14:06 -0400375 map.insert(InternalFormatInfoPair(GL_NONE, InternalFormat()));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000376
Geoff Langabce7622014-09-19 16:13:00 -0400377 // | Internal format | | R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Renderable | Filterable |
378 map.insert(InternalFormatInfoPair(GL_R8, RGBAFormat( 8, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::textureRG>, RequireESOrExt<3, &Extensions::textureRG>, AlwaysSupported)));
379 map.insert(InternalFormatInfoPair(GL_R8_SNORM, RGBAFormat( 8, 0, 0, 0, 0, GL_RED, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported)));
380 map.insert(InternalFormatInfoPair(GL_RG8, RGBAFormat( 8, 8, 0, 0, 0, GL_RG, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::textureRG>, RequireESOrExt<3, &Extensions::textureRG>, AlwaysSupported)));
381 map.insert(InternalFormatInfoPair(GL_RG8_SNORM, RGBAFormat( 8, 8, 0, 0, 0, GL_RG, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported)));
382 map.insert(InternalFormatInfoPair(GL_RGB8, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::rgb8rgba8>, RequireESOrExt<3, &Extensions::rgb8rgba8>, AlwaysSupported)));
383 map.insert(InternalFormatInfoPair(GL_RGB8_SNORM, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported)));
384 map.insert(InternalFormatInfoPair(GL_RGB565, RGBAFormat( 5, 6, 5, 0, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, RequireES<2>, RequireES<2>, AlwaysSupported)));
385 map.insert(InternalFormatInfoPair(GL_RGBA4, RGBAFormat( 4, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, RequireES<2>, RequireES<2>, AlwaysSupported)));
386 map.insert(InternalFormatInfoPair(GL_RGB5_A1, RGBAFormat( 5, 5, 5, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, RequireES<2>, RequireES<2>, AlwaysSupported)));
387 map.insert(InternalFormatInfoPair(GL_RGBA8, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::rgb8rgba8>, RequireESOrExt<3, &Extensions::rgb8rgba8>, AlwaysSupported)));
388 map.insert(InternalFormatInfoPair(GL_RGBA8_SNORM, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported)));
389 map.insert(InternalFormatInfoPair(GL_RGB10_A2, RGBAFormat(10, 10, 10, 2, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, RequireES<3>, RequireES<3>, AlwaysSupported)));
390 map.insert(InternalFormatInfoPair(GL_RGB10_A2UI, RGBAFormat(10, 10, 10, 2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT, false, RequireES<3>, NeverSupported, NeverSupported)));
391 map.insert(InternalFormatInfoPair(GL_SRGB8, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESOrExt<3, &Extensions::sRGB>, NeverSupported, AlwaysSupported)));
392 map.insert(InternalFormatInfoPair(GL_SRGB8_ALPHA8, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESOrExt<3, &Extensions::sRGB>, RequireESOrExt<3, &Extensions::sRGB>, AlwaysSupported)));
393 map.insert(InternalFormatInfoPair(GL_R11F_G11F_B10F, RGBAFormat(11, 11, 10, 0, 0, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT, false, RequireES<3>, RequireExt<&Extensions::colorBufferFloat>, AlwaysSupported)));
394 map.insert(InternalFormatInfoPair(GL_RGB9_E5, RGBAFormat( 9, 9, 9, 0, 5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT, false, RequireES<3>, NeverSupported, AlwaysSupported)));
395 map.insert(InternalFormatInfoPair(GL_R8I, RGBAFormat( 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
396 map.insert(InternalFormatInfoPair(GL_R8UI, RGBAFormat( 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
397 map.insert(InternalFormatInfoPair(GL_R16I, RGBAFormat(16, 0, 0, 0, 0, GL_RED_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
398 map.insert(InternalFormatInfoPair(GL_R16UI, RGBAFormat(16, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
399 map.insert(InternalFormatInfoPair(GL_R32I, RGBAFormat(32, 0, 0, 0, 0, GL_RED_INTEGER, GL_INT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
400 map.insert(InternalFormatInfoPair(GL_R32UI, RGBAFormat(32, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
401 map.insert(InternalFormatInfoPair(GL_RG8I, RGBAFormat( 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
402 map.insert(InternalFormatInfoPair(GL_RG8UI, RGBAFormat( 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
403 map.insert(InternalFormatInfoPair(GL_RG16I, RGBAFormat(16, 16, 0, 0, 0, GL_RG_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
404 map.insert(InternalFormatInfoPair(GL_RG16UI, RGBAFormat(16, 16, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
405 map.insert(InternalFormatInfoPair(GL_RG32I, RGBAFormat(32, 32, 0, 0, 0, GL_RG_INTEGER, GL_INT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
406 map.insert(InternalFormatInfoPair(GL_RG32UI, RGBAFormat(32, 32, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
407 map.insert(InternalFormatInfoPair(GL_RGB8I, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, NeverSupported, NeverSupported)));
408 map.insert(InternalFormatInfoPair(GL_RGB8UI, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, NeverSupported, NeverSupported)));
409 map.insert(InternalFormatInfoPair(GL_RGB16I, RGBAFormat(16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, NeverSupported, NeverSupported)));
410 map.insert(InternalFormatInfoPair(GL_RGB16UI, RGBAFormat(16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, NeverSupported, NeverSupported)));
411 map.insert(InternalFormatInfoPair(GL_RGB32I, RGBAFormat(32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_INT, GL_INT, false, RequireES<3>, NeverSupported, NeverSupported)));
412 map.insert(InternalFormatInfoPair(GL_RGB32UI, RGBAFormat(32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, NeverSupported, NeverSupported)));
413 map.insert(InternalFormatInfoPair(GL_RGBA8I, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
414 map.insert(InternalFormatInfoPair(GL_RGBA8UI, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
415 map.insert(InternalFormatInfoPair(GL_RGBA16I, RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
416 map.insert(InternalFormatInfoPair(GL_RGBA16UI, RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
417 map.insert(InternalFormatInfoPair(GL_RGBA32I, RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
418 map.insert(InternalFormatInfoPair(GL_RGBA32UI, RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000419
Geoff Langabce7622014-09-19 16:13:00 -0400420 map.insert(InternalFormatInfoPair(GL_BGRA8_EXT, RGBAFormat( 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported)));
421 map.insert(InternalFormatInfoPair(GL_BGRA4_ANGLEX, RGBAFormat( 4, 4, 4, 4, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported)));
422 map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX, RGBAFormat( 5, 5, 5, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000423
424 // Floating point renderability and filtering is provided by OES_texture_float and OES_texture_half_float
Geoff Langabce7622014-09-19 16:13:00 -0400425 // | Internal format | | D |S | Format | Type | Comp | SRGB | Texture supported | Renderable | Filterable |
426 // | | | | | | | type | | | | |
427 map.insert(InternalFormatInfoPair(GL_R16F, RGBAFormat(16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, GL_FLOAT, false, RequireESOrExtAndExt<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, RequireESOrExtAndExt<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, RequireExt<&Extensions::textureHalfFloatLinear>)));
428 map.insert(InternalFormatInfoPair(GL_RG16F, RGBAFormat(16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, GL_FLOAT, false, RequireESOrExtAndExt<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, RequireESOrExtAndExt<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, RequireExt<&Extensions::textureHalfFloatLinear>)));
429 map.insert(InternalFormatInfoPair(GL_RGB16F, RGBAFormat(16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, RequireESOrExt<3, &Extensions::textureHalfFloat>, RequireESOrExt<3, &Extensions::textureHalfFloat>, RequireExt<&Extensions::textureHalfFloatLinear>)));
430 map.insert(InternalFormatInfoPair(GL_RGBA16F, RGBAFormat(16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, RequireESOrExt<3, &Extensions::textureHalfFloat>, RequireESOrExt<3, &Extensions::textureHalfFloat>, RequireExt<&Extensions::textureHalfFloatLinear>)));
431 map.insert(InternalFormatInfoPair(GL_R32F, RGBAFormat(32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, RequireESOrExtAndExt<3, &Extensions::textureFloat, &Extensions::textureRG>, RequireESOrExtAndExt<3, &Extensions::textureFloat, &Extensions::textureRG>, RequireExt<&Extensions::textureFloatLinear> )));
432 map.insert(InternalFormatInfoPair(GL_RG32F, RGBAFormat(32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, RequireESOrExtAndExt<3, &Extensions::textureFloat, &Extensions::textureRG>, RequireESOrExtAndExt<3, &Extensions::textureFloat, &Extensions::textureRG>, RequireExt<&Extensions::textureFloatLinear> )));
433 map.insert(InternalFormatInfoPair(GL_RGB32F, RGBAFormat(32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, RequireESOrExt<3, &Extensions::textureFloat>, RequireESOrExt<3, &Extensions::textureFloat>, RequireExt<&Extensions::textureFloatLinear> )));
434 map.insert(InternalFormatInfoPair(GL_RGBA32F, RGBAFormat(32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, RequireESOrExt<3, &Extensions::textureFloat>, RequireESOrExt<3, &Extensions::textureFloat>, RequireExt<&Extensions::textureFloatLinear> )));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000435
436 // Depth stencil formats
Geoff Langabce7622014-09-19 16:13:00 -0400437 // | Internal format | | D |S | X | Format | Type | Component type | Supported | Renderable | Filterable |
438 map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16, DepthStencilFormat(16, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, RequireES<2>, RequireES<2>, RequireESOrExt<3, &Extensions::depthTextures>)));
439 map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT24, DepthStencilFormat(24, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireES<3>, RequireES<3>, RequireESOrExt<3, &Extensions::depthTextures>)));
440 map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32F, DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, RequireES<3>, RequireES<3>, RequireESOrExt<3, &Extensions::depthTextures>)));
441 map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES, DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::depthTextures>, RequireExt<&Extensions::depthTextures>, AlwaysSupported )));
442 map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8, DepthStencilFormat(24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, &Extensions::depthTextures>, RequireESOrExtOrExt<3, &Extensions::depthTextures, &Extensions::packedDepthStencil>, AlwaysSupported )));
443 map.insert(InternalFormatInfoPair(GL_DEPTH32F_STENCIL8, DepthStencilFormat(32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, RequireES<3>, RequireES<3>, AlwaysSupported )));
Corentin Walleze0902642014-11-04 12:32:15 -0800444 // STENCIL_INDEX8 is special-cased, see around the bottom of the list.
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000445
446 // Luminance alpha formats
Geoff Lang5d601382014-07-22 15:14:06 -0400447 // | Internal format | | L | A | Format | Type | Component type | Supported | Renderable | Filterable |
Geoff Langabce7622014-09-19 16:13:00 -0400448 map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT, LUMAFormat( 0, 8, GL_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorage>, NeverSupported, AlwaysSupported)));
449 map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT, LUMAFormat( 8, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorage>, NeverSupported, AlwaysSupported)));
450 map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT, LUMAFormat( 0, 32, GL_ALPHA, GL_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureFloat>, NeverSupported, AlwaysSupported)));
451 map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT, LUMAFormat(32, 0, GL_LUMINANCE, GL_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureFloat>, NeverSupported, AlwaysSupported)));
452 map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT, LUMAFormat( 0, 16, GL_ALPHA, GL_HALF_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
453 map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT, LUMAFormat(16, 0, GL_LUMINANCE, GL_HALF_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
454 map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT, LUMAFormat( 8, 8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorage>, NeverSupported, AlwaysSupported)));
455 map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, LUMAFormat(32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureFloat>, NeverSupported, AlwaysSupported)));
456 map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, LUMAFormat(16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000457
458 // Unsized formats
Geoff Langabce7622014-09-19 16:13:00 -0400459 // | Internal format | | Format | Supported | Renderable | Filterable |
460 map.insert(InternalFormatInfoPair(GL_ALPHA, UnsizedFormat(GL_ALPHA, RequireES<2>, NeverSupported, AlwaysSupported)));
461 map.insert(InternalFormatInfoPair(GL_LUMINANCE, UnsizedFormat(GL_LUMINANCE, RequireES<2>, NeverSupported, AlwaysSupported)));
462 map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA, UnsizedFormat(GL_LUMINANCE_ALPHA, RequireES<2>, NeverSupported, AlwaysSupported)));
463 map.insert(InternalFormatInfoPair(GL_RED, UnsizedFormat(GL_RED, RequireESOrExt<3, &Extensions::textureRG>, NeverSupported, AlwaysSupported)));
464 map.insert(InternalFormatInfoPair(GL_RG, UnsizedFormat(GL_RG, RequireESOrExt<3, &Extensions::textureRG>, NeverSupported, AlwaysSupported)));
465 map.insert(InternalFormatInfoPair(GL_RGB, UnsizedFormat(GL_RGB, RequireES<2>, RequireES<2>, AlwaysSupported)));
466 map.insert(InternalFormatInfoPair(GL_RGBA, UnsizedFormat(GL_RGBA, RequireES<2>, RequireES<2>, AlwaysSupported)));
467 map.insert(InternalFormatInfoPair(GL_RED_INTEGER, UnsizedFormat(GL_RED_INTEGER, RequireES<3>, NeverSupported, NeverSupported )));
468 map.insert(InternalFormatInfoPair(GL_RG_INTEGER, UnsizedFormat(GL_RG_INTEGER, RequireES<3>, NeverSupported, NeverSupported )));
469 map.insert(InternalFormatInfoPair(GL_RGB_INTEGER, UnsizedFormat(GL_RGB_INTEGER, RequireES<3>, NeverSupported, NeverSupported )));
470 map.insert(InternalFormatInfoPair(GL_RGBA_INTEGER, UnsizedFormat(GL_RGBA_INTEGER, RequireES<3>, NeverSupported, NeverSupported )));
471 map.insert(InternalFormatInfoPair(GL_BGRA_EXT, UnsizedFormat(GL_BGRA_EXT, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported)));
472 map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT, UnsizedFormat(GL_DEPTH_COMPONENT, RequireES<2>, RequireES<2>, AlwaysSupported)));
473 map.insert(InternalFormatInfoPair(GL_DEPTH_STENCIL, UnsizedFormat(GL_DEPTH_STENCIL, RequireESOrExt<3, &Extensions::packedDepthStencil>, RequireESOrExt<3, &Extensions::packedDepthStencil>, AlwaysSupported)));
474 map.insert(InternalFormatInfoPair(GL_SRGB_EXT, UnsizedFormat(GL_RGB, RequireESOrExt<3, &Extensions::sRGB>, NeverSupported, AlwaysSupported)));
475 map.insert(InternalFormatInfoPair(GL_SRGB_ALPHA_EXT, UnsizedFormat(GL_RGBA, RequireESOrExt<3, &Extensions::sRGB>, RequireESOrExt<3, &Extensions::sRGB>, AlwaysSupported)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000476
477 // Compressed formats, From ES 3.0.1 spec, table 3.16
Geoff Lang5d601382014-07-22 15:14:06 -0400478 // | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable |
479 map.insert(InternalFormatInfoPair(GL_COMPRESSED_R11_EAC, CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
480 map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_R11_EAC, CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
481 map.insert(InternalFormatInfoPair(GL_COMPRESSED_RG11_EAC, CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
482 map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_RG11_EAC, CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
483 map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
484 map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE, true, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
485 map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
486 map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, true, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
487 map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA8_ETC2_EAC, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
488 map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_BYTE, true, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000489
490 // From GL_EXT_texture_compression_dxt1
Geoff Langabce7622014-09-19 16:13:00 -0400491 // | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable |
492 map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT1>, NeverSupported, AlwaysSupported)));
493 map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, CompressedFormat(4, 4, 64, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT1>, NeverSupported, AlwaysSupported)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000494
495 // From GL_ANGLE_texture_compression_dxt3
Geoff Langabce7622014-09-19 16:13:00 -0400496 map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT5>, NeverSupported, AlwaysSupported)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000497
498 // From GL_ANGLE_texture_compression_dxt5
Geoff Langabce7622014-09-19 16:13:00 -0400499 map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT5>, NeverSupported, AlwaysSupported)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000500
Corentin Walleze0902642014-11-04 12:32:15 -0800501 // For STENCIL_INDEX8 we chose a normalized component type for the following reasons:
502 // - Multisampled buffer are disallowed for non-normalized integer component types and we want to support it for STENCIL_INDEX8
503 // - All other stencil formats (all depth-stencil) are either float or normalized
504 // - It affects only validation of internalformat in RenderbufferStorageMultisample.
505 // | Internal format | |D |S |X | Format | Type | Component type | Supported | Renderable | Filterable |
506 map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8, DepthStencilFormat(0, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<2>, RequireES<2>, NeverSupported)));
507
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000508 return map;
509}
510
Geoff Lange4a492b2014-06-19 14:14:41 -0400511static const InternalFormatInfoMap &GetInternalFormatMap()
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000512{
Geoff Lange4a492b2014-06-19 14:14:41 -0400513 static const InternalFormatInfoMap formatMap = BuildInternalFormatInfoMap();
514 return formatMap;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000515}
516
Geoff Lange4a492b2014-06-19 14:14:41 -0400517static FormatSet BuildAllSizedInternalFormatSet()
Geoff Langcec35902014-04-16 10:52:36 -0400518{
519 FormatSet result;
520
Geoff Lange4a492b2014-06-19 14:14:41 -0400521 const InternalFormatInfoMap &formats = GetInternalFormatMap();
Geoff Langcec35902014-04-16 10:52:36 -0400522 for (InternalFormatInfoMap::const_iterator i = formats.begin(); i != formats.end(); i++)
523 {
Geoff Lang5d601382014-07-22 15:14:06 -0400524 if (i->second.pixelBytes > 0)
Geoff Langcec35902014-04-16 10:52:36 -0400525 {
526 result.insert(i->first);
527 }
528 }
529
530 return result;
531}
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000532
Geoff Lang5d601382014-07-22 15:14:06 -0400533const Type &GetTypeInfo(GLenum type)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000534{
Geoff Lang5d601382014-07-22 15:14:06 -0400535 static const TypeInfoMap infoMap = BuildTypeInfoMap();
536 TypeInfoMap::const_iterator iter = infoMap.find(type);
537 if (iter != infoMap.end())
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000538 {
Geoff Lang5d601382014-07-22 15:14:06 -0400539 return iter->second;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000540 }
541 else
542 {
Geoff Lang5d601382014-07-22 15:14:06 -0400543 static const Type defaultInfo;
544 return defaultInfo;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000545 }
546}
547
Geoff Lang5d601382014-07-22 15:14:06 -0400548const InternalFormat &GetInternalFormatInfo(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000549{
Geoff Lang5d601382014-07-22 15:14:06 -0400550 const InternalFormatInfoMap &formatMap = GetInternalFormatMap();
551 InternalFormatInfoMap::const_iterator iter = formatMap.find(internalFormat);
552 if (iter != formatMap.end())
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000553 {
Geoff Lang5d601382014-07-22 15:14:06 -0400554 return iter->second;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000555 }
556 else
557 {
Geoff Lang5d601382014-07-22 15:14:06 -0400558 static const InternalFormat defaultInternalFormat;
559 return defaultInternalFormat;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000560 }
561}
562
Minmin Gongb8aee3b2015-01-27 14:42:36 -0800563GLuint InternalFormat::computeRowPitch(GLenum formatType, GLsizei width, GLint alignment, GLint rowLength) const
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000564{
565 ASSERT(alignment > 0 && isPow2(alignment));
Minmin Gongb8aee3b2015-01-27 14:42:36 -0800566 GLuint rowBytes;
567 if (rowLength > 0)
568 {
569 ASSERT(!compressed);
570 rowBytes = pixelBytes * rowLength;
571 }
572 else
573 {
574 rowBytes = computeBlockSize(formatType, width, 1);
575 }
576 return rx::roundUp(rowBytes, static_cast<GLuint>(alignment));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000577}
578
Minmin Gongb8aee3b2015-01-27 14:42:36 -0800579GLuint InternalFormat::computeDepthPitch(GLenum formatType, GLsizei width, GLsizei height, GLint alignment, GLint rowLength) const
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000580{
Minmin Gongb8aee3b2015-01-27 14:42:36 -0800581 return computeRowPitch(formatType, width, alignment, rowLength) * height;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000582}
583
Austin Kinross3ae64652015-01-26 15:51:39 -0800584GLuint InternalFormat::computeBlockSize(GLenum formatType, GLsizei width, GLsizei height) const
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000585{
Geoff Lang5d601382014-07-22 15:14:06 -0400586 if (compressed)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000587 {
Geoff Lang5d601382014-07-22 15:14:06 -0400588 GLsizei numBlocksWide = (width + compressedBlockWidth - 1) / compressedBlockWidth;
589 GLsizei numBlocksHight = (height + compressedBlockHeight - 1) / compressedBlockHeight;
590 return (pixelBytes * numBlocksWide * numBlocksHight);
591 }
592 else
593 {
Austin Kinross3ae64652015-01-26 15:51:39 -0800594 const Type &typeInfo = GetTypeInfo(formatType);
Geoff Lang5d601382014-07-22 15:14:06 -0400595 if (typeInfo.specialInterpretation)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000596 {
Geoff Lang5d601382014-07-22 15:14:06 -0400597 return typeInfo.bytes * width * height;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000598 }
599 else
600 {
Geoff Lang5d601382014-07-22 15:14:06 -0400601 return componentCount * typeInfo.bytes * width * height;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000602 }
603 }
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000604}
605
Geoff Lang5d601382014-07-22 15:14:06 -0400606GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000607{
Geoff Lang5d601382014-07-22 15:14:06 -0400608 const InternalFormat& formatInfo = GetInternalFormatInfo(internalFormat);
Geoff Lang051dbc72015-01-05 15:48:58 -0500609 if (formatInfo.pixelBytes > 0)
610 {
611 return internalFormat;
612 }
613 else
614 {
615 static const FormatMap formatMap = BuildFormatMap();
616 FormatMap::const_iterator iter = formatMap.find(FormatTypePair(internalFormat, type));
617 if (iter != formatMap.end())
618 {
619 return iter->second;
620 }
621 else
622 {
623 return GL_NONE;
624 }
625 }
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000626}
627
Geoff Lange4a492b2014-06-19 14:14:41 -0400628const FormatSet &GetAllSizedInternalFormats()
Geoff Langcec35902014-04-16 10:52:36 -0400629{
Geoff Lange4a492b2014-06-19 14:14:41 -0400630 static FormatSet formatSet = BuildAllSizedInternalFormatSet();
Geoff Langcec35902014-04-16 10:52:36 -0400631 return formatSet;
632}
633
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000634}