blob: 8cc2e19a835821189f30d730d53b537148dcedb5 [file] [log] [blame]
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001#include "precompiled.h"
2//
Geoff Langcec35902014-04-16 10:52:36 -04003// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00004// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7
8// formatutils.cpp: Queries for GL image formats.
9
Shannon Woods4d161ba2014-03-17 18:13:30 -040010#include "common/mathutil.h"
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000011#include "libGLESv2/formatutils.h"
12#include "libGLESv2/Context.h"
Shannon Woods4d161ba2014-03-17 18:13:30 -040013#include "libGLESv2/Framebuffer.h"
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000014#include "libGLESv2/renderer/Renderer.h"
Geoff Langfe28ca02013-06-04 10:10:48 -040015#include "libGLESv2/renderer/imageformats.h"
16#include "libGLESv2/renderer/copyimage.h"
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000017
18namespace gl
19{
20
21// ES2 requires that format is equal to internal format at all glTex*Image2D entry points and the implementation
22// can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid
23// format and type combinations.
24
Geoff Langfe28ca02013-06-04 10:10:48 -040025struct FormatTypeInfo
26{
Geoff Lang005df412013-10-16 14:12:50 -040027 GLenum mInternalFormat;
Geoff Langfe28ca02013-06-04 10:10:48 -040028 ColorWriteFunction mColorWriteFunction;
29
Geoff Lang005df412013-10-16 14:12:50 -040030 FormatTypeInfo(GLenum internalFormat, ColorWriteFunction writeFunc)
Geoff Langfe28ca02013-06-04 10:10:48 -040031 : mInternalFormat(internalFormat), mColorWriteFunction(writeFunc)
32 { }
33};
34
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000035typedef std::pair<GLenum, GLenum> FormatTypePair;
Geoff Langfe28ca02013-06-04 10:10:48 -040036typedef std::pair<FormatTypePair, FormatTypeInfo> FormatPair;
37typedef std::map<FormatTypePair, FormatTypeInfo> FormatMap;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000038
Jamie Madill89a0bf52013-09-18 14:36:24 -040039// A helper function to insert data into the format map with fewer characters.
Geoff Lang005df412013-10-16 14:12:50 -040040static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat, ColorWriteFunction writeFunc)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000041{
Geoff Langfe28ca02013-06-04 10:10:48 -040042 map->insert(FormatPair(FormatTypePair(format, type), FormatTypeInfo(internalFormat, writeFunc)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000043}
44
Geoff Lange4a492b2014-06-19 14:14:41 -040045FormatMap BuildFormatMap()
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000046{
47 FormatMap map;
48
Geoff Langfe28ca02013-06-04 10:10:48 -040049 using namespace rx;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000050
Geoff Langfe28ca02013-06-04 10:10:48 -040051 // | Format | Type | Internal format | Color write function |
52 InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8, WriteColor<R8G8B8A8, GLfloat> );
53 InsertFormatMapping(&map, GL_RGBA, GL_BYTE, GL_RGBA8_SNORM, WriteColor<R8G8B8A8S, GLfloat> );
54 InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4, WriteColor<R4G4B4A4, GLfloat> );
55 InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1, WriteColor<R5G5B5A1, GLfloat> );
56 InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2, WriteColor<R10G10B10A2, GLfloat> );
57 InsertFormatMapping(&map, GL_RGBA, GL_FLOAT, GL_RGBA32F, WriteColor<R32G32B32A32F, GLfloat>);
58 InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F, WriteColor<R16G16B16A16F, GLfloat>);
Geoff Lange4a492b2014-06-19 14:14:41 -040059 InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA16F, WriteColor<R16G16B16A16F, GLfloat>);
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000060
Geoff Langfe28ca02013-06-04 10:10:48 -040061 InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_RGBA8UI, WriteColor<R8G8B8A8, GLuint> );
62 InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_BYTE, GL_RGBA8I, WriteColor<R8G8B8A8S, GLint> );
63 InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_RGBA16UI, WriteColor<R16G16B16A16, GLuint> );
64 InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_SHORT, GL_RGBA16I, WriteColor<R16G16B16A16S, GLint> );
65 InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_RGBA32UI, WriteColor<R32G32B32A32, GLuint> );
66 InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_INT, GL_RGBA32I, WriteColor<R32G32B32A32S, GLint> );
Jamie Madill18a44702013-09-09 16:24:04 -040067 InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2UI, WriteColor<R10G10B10A2, GLuint> );
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000068
Geoff Langfe28ca02013-06-04 10:10:48 -040069 InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8, WriteColor<R8G8B8, GLfloat> );
70 InsertFormatMapping(&map, GL_RGB, GL_BYTE, GL_RGB8_SNORM, WriteColor<R8G8B8S, GLfloat> );
71 InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565, WriteColor<R5G6B5, GLfloat> );
72 InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_R11F_G11F_B10F, WriteColor<R11G11B10F, GLfloat> );
73 InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_RGB9_E5, WriteColor<R9G9B9E5, GLfloat> );
74 InsertFormatMapping(&map, GL_RGB, GL_FLOAT, GL_RGB32F, WriteColor<R32G32B32F, GLfloat> );
75 InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT, GL_RGB16F, WriteColor<R16G16B16F, GLfloat> );
Geoff Lange4a492b2014-06-19 14:14:41 -040076 InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT_OES, GL_RGB16F, WriteColor<R16G16B16F, GLfloat> );
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000077
Geoff Langfe28ca02013-06-04 10:10:48 -040078 InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_RGB8UI, WriteColor<R8G8B8, GLuint> );
79 InsertFormatMapping(&map, GL_RGB_INTEGER, GL_BYTE, GL_RGB8I, WriteColor<R8G8B8S, GLint> );
80 InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_RGB16UI, WriteColor<R16G16B16, GLuint> );
81 InsertFormatMapping(&map, GL_RGB_INTEGER, GL_SHORT, GL_RGB16I, WriteColor<R16G16B16S, GLint> );
82 InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_RGB32UI, WriteColor<R32G32B32, GLuint> );
83 InsertFormatMapping(&map, GL_RGB_INTEGER, GL_INT, GL_RGB32I, WriteColor<R32G32B32S, GLint> );
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000084
Geoff Langfe28ca02013-06-04 10:10:48 -040085 InsertFormatMapping(&map, GL_RG, GL_UNSIGNED_BYTE, GL_RG8, WriteColor<R8G8, GLfloat> );
86 InsertFormatMapping(&map, GL_RG, GL_BYTE, GL_RG8_SNORM, WriteColor<R8G8S, GLfloat> );
87 InsertFormatMapping(&map, GL_RG, GL_FLOAT, GL_RG32F, WriteColor<R32G32F, GLfloat> );
88 InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT, GL_RG16F, WriteColor<R16G16F, GLfloat> );
Geoff Lange4a492b2014-06-19 14:14:41 -040089 InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT_OES, GL_RG16F, WriteColor<R16G16F, GLfloat> );
Geoff Langfe28ca02013-06-04 10:10:48 -040090
91 InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_RG8UI, WriteColor<R8G8, GLuint> );
92 InsertFormatMapping(&map, GL_RG_INTEGER, GL_BYTE, GL_RG8I, WriteColor<R8G8S, GLint> );
93 InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_RG16UI, WriteColor<R16G16, GLuint> );
94 InsertFormatMapping(&map, GL_RG_INTEGER, GL_SHORT, GL_RG16I, WriteColor<R16G16S, GLint> );
95 InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_RG32UI, WriteColor<R32G32, GLuint> );
96 InsertFormatMapping(&map, GL_RG_INTEGER, GL_INT, GL_RG32I, WriteColor<R32G32S, GLint> );
97
98 InsertFormatMapping(&map, GL_RED, GL_UNSIGNED_BYTE, GL_R8, WriteColor<R8, GLfloat> );
99 InsertFormatMapping(&map, GL_RED, GL_BYTE, GL_R8_SNORM, WriteColor<R8S, GLfloat> );
100 InsertFormatMapping(&map, GL_RED, GL_FLOAT, GL_R32F, WriteColor<R32F, GLfloat> );
101 InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT, GL_R16F, WriteColor<R16F, GLfloat> );
Geoff Lange4a492b2014-06-19 14:14:41 -0400102 InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT_OES, GL_R16F, WriteColor<R16F, GLfloat> );
Geoff Langfe28ca02013-06-04 10:10:48 -0400103
104 InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_R8UI, WriteColor<R8, GLuint> );
105 InsertFormatMapping(&map, GL_RED_INTEGER, GL_BYTE, GL_R8I, WriteColor<R8S, GLint> );
106 InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_R16UI, WriteColor<R16, GLuint> );
107 InsertFormatMapping(&map, GL_RED_INTEGER, GL_SHORT, GL_R16I, WriteColor<R16S, GLint> );
108 InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_R32UI, WriteColor<R32, GLuint> );
109 InsertFormatMapping(&map, GL_RED_INTEGER, GL_INT, GL_R32I, WriteColor<R32S, GLint> );
110
111 InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8_EXT, WriteColor<L8A8, GLfloat> );
112 InsertFormatMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8_EXT, WriteColor<L8, GLfloat> );
113 InsertFormatMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8_EXT, WriteColor<A8, GLfloat> );
114 InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_LUMINANCE_ALPHA32F_EXT, WriteColor<L32A32F, GLfloat> );
115 InsertFormatMapping(&map, GL_LUMINANCE, GL_FLOAT, GL_LUMINANCE32F_EXT, WriteColor<L32F, GLfloat> );
116 InsertFormatMapping(&map, GL_ALPHA, GL_FLOAT, GL_ALPHA32F_EXT, WriteColor<A32F, GLfloat> );
117 InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_LUMINANCE_ALPHA16F_EXT, WriteColor<L16A16F, GLfloat> );
Geoff Lange4a492b2014-06-19 14:14:41 -0400118 InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_LUMINANCE_ALPHA16F_EXT, WriteColor<L16A16F, GLfloat> );
Geoff Langfe28ca02013-06-04 10:10:48 -0400119 InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT, GL_LUMINANCE16F_EXT, WriteColor<L16F, GLfloat> );
Geoff Lange4a492b2014-06-19 14:14:41 -0400120 InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_LUMINANCE16F_EXT, WriteColor<L16F, GLfloat> );
Geoff Langfe28ca02013-06-04 10:10:48 -0400121 InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT, GL_ALPHA16F_EXT, WriteColor<A16F, GLfloat> );
Geoff Lange4a492b2014-06-19 14:14:41 -0400122 InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT_OES, GL_ALPHA16F_EXT, WriteColor<A16F, GLfloat> );
Geoff Langfe28ca02013-06-04 10:10:48 -0400123
124 InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_BGRA8_EXT, WriteColor<B8G8R8A8, GLfloat> );
125 InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX, WriteColor<B4G4R4A4, GLfloat> );
126 InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX, WriteColor<B5G5R5A1, GLfloat> );
127
Geoff Lang05b05022014-06-11 15:31:45 -0400128 InsertFormatMapping(&map, GL_SRGB_EXT, GL_UNSIGNED_BYTE, GL_SRGB8, WriteColor<R8G8B8, GLfloat> );
129 InsertFormatMapping(&map, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, GL_SRGB8_ALPHA8, WriteColor<R8G8B8A8, GLfloat> );
130
Geoff Langcec35902014-04-16 10:52:36 -0400131 InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, NULL );
132 InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, NULL );
133 InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL );
134 InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL );
135
Geoff Langfe28ca02013-06-04 10:10:48 -0400136 InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16, NULL );
Geoff Lange4a492b2014-06-19 14:14:41 -0400137 InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT32_OES, NULL );
Geoff Langfe28ca02013-06-04 10:10:48 -0400138 InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT32F, NULL );
139
Geoff Lange4a492b2014-06-19 14:14:41 -0400140 InsertFormatMapping(&map, GL_STENCIL, GL_UNSIGNED_BYTE, GL_STENCIL_INDEX8, NULL );
141
Geoff Langfe28ca02013-06-04 10:10:48 -0400142 InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8, NULL );
143 InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8, NULL );
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000144
145 return map;
146}
147
Geoff Lange4a492b2014-06-19 14:14:41 -0400148static const FormatMap &GetFormatMap()
Geoff Langfe28ca02013-06-04 10:10:48 -0400149{
Geoff Lange4a492b2014-06-19 14:14:41 -0400150 static const FormatMap formatMap = BuildFormatMap();
151 return formatMap;
Geoff Langfe28ca02013-06-04 10:10:48 -0400152}
153
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000154struct FormatInfo
155{
Geoff Lang005df412013-10-16 14:12:50 -0400156 GLenum mInternalformat;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000157 GLenum mFormat;
158 GLenum mType;
159
Geoff Lang005df412013-10-16 14:12:50 -0400160 FormatInfo(GLenum internalformat, GLenum format, GLenum type)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000161 : mInternalformat(internalformat), mFormat(format), mType(type) { }
162
163 bool operator<(const FormatInfo& other) const
164 {
165 return memcmp(this, &other, sizeof(FormatInfo)) < 0;
166 }
167};
168
169// ES3 has a specific set of permutations of internal formats, formats and types which are acceptable.
170typedef std::set<FormatInfo> ES3FormatSet;
171
Geoff Lang18591b72013-06-07 12:00:15 -0400172ES3FormatSet BuildES3FormatSet()
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000173{
174 ES3FormatSet set;
175
176 // Format combinations from ES 3.0.1 spec, table 3.2
177
178 // | Internal format | Format | Type |
179 // | | | |
180 set.insert(FormatInfo(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE ));
181 set.insert(FormatInfo(GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE ));
182 set.insert(FormatInfo(GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE ));
183 set.insert(FormatInfo(GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE ));
184 set.insert(FormatInfo(GL_RGBA8_SNORM, GL_RGBA, GL_BYTE ));
185 set.insert(FormatInfo(GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 ));
186 set.insert(FormatInfo(GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV ));
187 set.insert(FormatInfo(GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV ));
shannonwoods@chromium.orgd03f8972013-05-30 00:17:07 +0000188 set.insert(FormatInfo(GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 ));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000189 set.insert(FormatInfo(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT ));
Geoff Lange4a492b2014-06-19 14:14:41 -0400190 set.insert(FormatInfo(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT_OES ));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000191 set.insert(FormatInfo(GL_RGBA32F, GL_RGBA, GL_FLOAT ));
192 set.insert(FormatInfo(GL_RGBA16F, GL_RGBA, GL_FLOAT ));
193 set.insert(FormatInfo(GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE ));
194 set.insert(FormatInfo(GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE ));
195 set.insert(FormatInfo(GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT ));
196 set.insert(FormatInfo(GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT ));
197 set.insert(FormatInfo(GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT ));
198 set.insert(FormatInfo(GL_RGBA32I, GL_RGBA_INTEGER, GL_INT ));
199 set.insert(FormatInfo(GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV ));
200 set.insert(FormatInfo(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE ));
201 set.insert(FormatInfo(GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE ));
202 set.insert(FormatInfo(GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE ));
203 set.insert(FormatInfo(GL_RGB8_SNORM, GL_RGB, GL_BYTE ));
204 set.insert(FormatInfo(GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5 ));
205 set.insert(FormatInfo(GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV ));
206 set.insert(FormatInfo(GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV ));
207 set.insert(FormatInfo(GL_RGB16F, GL_RGB, GL_HALF_FLOAT ));
Geoff Lange4a492b2014-06-19 14:14:41 -0400208 set.insert(FormatInfo(GL_RGB16F, GL_RGB, GL_HALF_FLOAT_OES ));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000209 set.insert(FormatInfo(GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT ));
Geoff Lange4a492b2014-06-19 14:14:41 -0400210 set.insert(FormatInfo(GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT_OES ));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000211 set.insert(FormatInfo(GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT ));
Geoff Lange4a492b2014-06-19 14:14:41 -0400212 set.insert(FormatInfo(GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT_OES ));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000213 set.insert(FormatInfo(GL_RGB32F, GL_RGB, GL_FLOAT ));
214 set.insert(FormatInfo(GL_RGB16F, GL_RGB, GL_FLOAT ));
215 set.insert(FormatInfo(GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT ));
216 set.insert(FormatInfo(GL_RGB9_E5, GL_RGB, GL_FLOAT ));
217 set.insert(FormatInfo(GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE ));
218 set.insert(FormatInfo(GL_RGB8I, GL_RGB_INTEGER, GL_BYTE ));
219 set.insert(FormatInfo(GL_RGB16UI, GL_RGB_INTEGER, GL_UNSIGNED_SHORT ));
220 set.insert(FormatInfo(GL_RGB16I, GL_RGB_INTEGER, GL_SHORT ));
221 set.insert(FormatInfo(GL_RGB32UI, GL_RGB_INTEGER, GL_UNSIGNED_INT ));
222 set.insert(FormatInfo(GL_RGB32I, GL_RGB_INTEGER, GL_INT ));
223 set.insert(FormatInfo(GL_RG8, GL_RG, GL_UNSIGNED_BYTE ));
224 set.insert(FormatInfo(GL_RG8_SNORM, GL_RG, GL_BYTE ));
225 set.insert(FormatInfo(GL_RG16F, GL_RG, GL_HALF_FLOAT ));
Geoff Lange4a492b2014-06-19 14:14:41 -0400226 set.insert(FormatInfo(GL_RG16F, GL_RG, GL_HALF_FLOAT_OES ));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000227 set.insert(FormatInfo(GL_RG32F, GL_RG, GL_FLOAT ));
228 set.insert(FormatInfo(GL_RG16F, GL_RG, GL_FLOAT ));
229 set.insert(FormatInfo(GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE ));
230 set.insert(FormatInfo(GL_RG8I, GL_RG_INTEGER, GL_BYTE ));
231 set.insert(FormatInfo(GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT ));
232 set.insert(FormatInfo(GL_RG16I, GL_RG_INTEGER, GL_SHORT ));
233 set.insert(FormatInfo(GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT ));
234 set.insert(FormatInfo(GL_RG32I, GL_RG_INTEGER, GL_INT ));
235 set.insert(FormatInfo(GL_R8, GL_RED, GL_UNSIGNED_BYTE ));
236 set.insert(FormatInfo(GL_R8_SNORM, GL_RED, GL_BYTE ));
237 set.insert(FormatInfo(GL_R16F, GL_RED, GL_HALF_FLOAT ));
Geoff Lange4a492b2014-06-19 14:14:41 -0400238 set.insert(FormatInfo(GL_R16F, GL_RED, GL_HALF_FLOAT_OES ));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000239 set.insert(FormatInfo(GL_R32F, GL_RED, GL_FLOAT ));
240 set.insert(FormatInfo(GL_R16F, GL_RED, GL_FLOAT ));
241 set.insert(FormatInfo(GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE ));
242 set.insert(FormatInfo(GL_R8I, GL_RED_INTEGER, GL_BYTE ));
243 set.insert(FormatInfo(GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT ));
244 set.insert(FormatInfo(GL_R16I, GL_RED_INTEGER, GL_SHORT ));
245 set.insert(FormatInfo(GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT ));
246 set.insert(FormatInfo(GL_R32I, GL_RED_INTEGER, GL_INT ));
247
248 // Unsized formats
249 set.insert(FormatInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE ));
250 set.insert(FormatInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 ));
251 set.insert(FormatInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 ));
252 set.insert(FormatInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE ));
253 set.insert(FormatInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5 ));
254 set.insert(FormatInfo(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE ));
255 set.insert(FormatInfo(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE ));
256 set.insert(FormatInfo(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE ));
Geoff Lang05b05022014-06-11 15:31:45 -0400257 set.insert(FormatInfo(GL_SRGB_ALPHA_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE ));
258 set.insert(FormatInfo(GL_SRGB_EXT, GL_SRGB_EXT, GL_UNSIGNED_BYTE ));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000259
260 // Depth stencil formats
261 set.insert(FormatInfo(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT ));
262 set.insert(FormatInfo(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT ));
263 set.insert(FormatInfo(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT ));
264 set.insert(FormatInfo(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT ));
265 set.insert(FormatInfo(GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8 ));
266 set.insert(FormatInfo(GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV));
267
Geoff Lang05b05022014-06-11 15:31:45 -0400268 // From GL_EXT_sRGB
269 set.insert(FormatInfo(GL_SRGB8_ALPHA8_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE ));
270 set.insert(FormatInfo(GL_SRGB8, GL_SRGB_EXT, GL_UNSIGNED_BYTE ));
271
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000272 // From GL_OES_texture_float
273 set.insert(FormatInfo(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT ));
274 set.insert(FormatInfo(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT ));
275 set.insert(FormatInfo(GL_ALPHA, GL_ALPHA, GL_FLOAT ));
276
277 // From GL_OES_texture_half_float
278 set.insert(FormatInfo(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT ));
Geoff Lange4a492b2014-06-19 14:14:41 -0400279 set.insert(FormatInfo(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES ));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000280 set.insert(FormatInfo(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT ));
Geoff Lange4a492b2014-06-19 14:14:41 -0400281 set.insert(FormatInfo(GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES ));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000282 set.insert(FormatInfo(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT ));
Geoff Lange4a492b2014-06-19 14:14:41 -0400283 set.insert(FormatInfo(GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES ));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000284
Geoff Langcdacacd2014-04-24 12:01:56 -0400285 // From GL_EXT_texture_format_BGRA8888
286 set.insert(FormatInfo(GL_BGRA_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE ));
287
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000288 // From GL_EXT_texture_storage
289 // | Internal format | Format | Type |
290 // | | | |
291 set.insert(FormatInfo(GL_ALPHA8_EXT, GL_ALPHA, GL_UNSIGNED_BYTE ));
292 set.insert(FormatInfo(GL_LUMINANCE8_EXT, GL_LUMINANCE, GL_UNSIGNED_BYTE ));
293 set.insert(FormatInfo(GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE ));
294 set.insert(FormatInfo(GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT ));
295 set.insert(FormatInfo(GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT ));
296 set.insert(FormatInfo(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT ));
297 set.insert(FormatInfo(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT ));
Geoff Lange4a492b2014-06-19 14:14:41 -0400298 set.insert(FormatInfo(GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT_OES ));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000299 set.insert(FormatInfo(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT ));
Geoff Lange4a492b2014-06-19 14:14:41 -0400300 set.insert(FormatInfo(GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT_OES ));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000301 set.insert(FormatInfo(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT ));
Geoff Lange4a492b2014-06-19 14:14:41 -0400302 set.insert(FormatInfo(GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES ));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000303
Geoff Langcdacacd2014-04-24 12:01:56 -0400304 // From GL_EXT_texture_storage and GL_EXT_texture_format_BGRA8888
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000305 set.insert(FormatInfo(GL_BGRA8_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE ));
306 set.insert(FormatInfo(GL_BGRA4_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT));
307 set.insert(FormatInfo(GL_BGRA4_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_BYTE ));
308 set.insert(FormatInfo(GL_BGR5_A1_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT));
309 set.insert(FormatInfo(GL_BGR5_A1_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_BYTE ));
310
311 // From GL_ANGLE_depth_texture
312 set.insert(FormatInfo(GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8_OES ));
313
314 // Compressed formats
315 // From ES 3.0.1 spec, table 3.16
316 // | Internal format | Format | Type |
317 // | | | |
318 set.insert(FormatInfo(GL_COMPRESSED_R11_EAC, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE));
319 set.insert(FormatInfo(GL_COMPRESSED_R11_EAC, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE));
320 set.insert(FormatInfo(GL_COMPRESSED_SIGNED_R11_EAC, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE));
321 set.insert(FormatInfo(GL_COMPRESSED_RG11_EAC, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE));
322 set.insert(FormatInfo(GL_COMPRESSED_SIGNED_RG11_EAC, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE));
323 set.insert(FormatInfo(GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE));
324 set.insert(FormatInfo(GL_COMPRESSED_SRGB8_ETC2, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE));
325 set.insert(FormatInfo(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE));
326 set.insert(FormatInfo(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE));
327 set.insert(FormatInfo(GL_COMPRESSED_RGBA8_ETC2_EAC, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE));
328 set.insert(FormatInfo(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_BYTE));
329
330
331 // From GL_EXT_texture_compression_dxt1
332 set.insert(FormatInfo(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE));
333 set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE));
334
335 // From GL_ANGLE_texture_compression_dxt3
336 set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE));
337
338 // From GL_ANGLE_texture_compression_dxt5
339 set.insert(FormatInfo(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE));
340
341 return set;
342}
343
Geoff Lang18591b72013-06-07 12:00:15 -0400344static const ES3FormatSet &GetES3FormatSet()
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000345{
Geoff Lang18591b72013-06-07 12:00:15 -0400346 static const ES3FormatSet es3FormatSet = BuildES3FormatSet();
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000347 return es3FormatSet;
348}
349
350// Map of sizes of input types
351struct TypeInfo
352{
353 GLuint mTypeBytes;
354 bool mSpecialInterpretation;
355
356 TypeInfo()
357 : mTypeBytes(0), mSpecialInterpretation(false) { }
358
359 TypeInfo(GLuint typeBytes, bool specialInterpretation)
360 : mTypeBytes(typeBytes), mSpecialInterpretation(specialInterpretation) { }
361
362 bool operator<(const TypeInfo& other) const
363 {
364 return memcmp(this, &other, sizeof(TypeInfo)) < 0;
365 }
366};
367
368typedef std::pair<GLenum, TypeInfo> TypeInfoPair;
369typedef std::map<GLenum, TypeInfo> TypeInfoMap;
370
Geoff Lang18591b72013-06-07 12:00:15 -0400371static TypeInfoMap BuildTypeInfoMap()
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000372{
373 TypeInfoMap map;
374
375 map.insert(TypeInfoPair(GL_UNSIGNED_BYTE, TypeInfo( 1, false)));
376 map.insert(TypeInfoPair(GL_BYTE, TypeInfo( 1, false)));
377 map.insert(TypeInfoPair(GL_UNSIGNED_SHORT, TypeInfo( 2, false)));
378 map.insert(TypeInfoPair(GL_SHORT, TypeInfo( 2, false)));
379 map.insert(TypeInfoPair(GL_UNSIGNED_INT, TypeInfo( 4, false)));
380 map.insert(TypeInfoPair(GL_INT, TypeInfo( 4, false)));
381 map.insert(TypeInfoPair(GL_HALF_FLOAT, TypeInfo( 2, false)));
Jamie Madilla940ae42013-07-08 17:48:34 -0400382 map.insert(TypeInfoPair(GL_HALF_FLOAT_OES, TypeInfo( 2, false)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000383 map.insert(TypeInfoPair(GL_FLOAT, TypeInfo( 4, false)));
384 map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_5_6_5, TypeInfo( 2, true )));
385 map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_4_4_4_4, TypeInfo( 2, true )));
386 map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_5_5_5_1, TypeInfo( 2, true )));
387 map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, TypeInfo( 2, true )));
388 map.insert(TypeInfoPair(GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, TypeInfo( 2, true )));
389 map.insert(TypeInfoPair(GL_UNSIGNED_INT_2_10_10_10_REV, TypeInfo( 4, true )));
390 map.insert(TypeInfoPair(GL_UNSIGNED_INT_24_8, TypeInfo( 4, true )));
391 map.insert(TypeInfoPair(GL_UNSIGNED_INT_10F_11F_11F_REV, TypeInfo( 4, true )));
392 map.insert(TypeInfoPair(GL_UNSIGNED_INT_5_9_9_9_REV, TypeInfo( 4, true )));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000393 map.insert(TypeInfoPair(GL_UNSIGNED_INT_24_8_OES, TypeInfo( 4, true )));
Geoff Lang85ea9ab2013-10-10 13:50:34 -0400394 map.insert(TypeInfoPair(GL_FLOAT_32_UNSIGNED_INT_24_8_REV, TypeInfo( 8, true )));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000395
396 return map;
397}
398
Geoff Lang18591b72013-06-07 12:00:15 -0400399static bool GetTypeInfo(GLenum type, TypeInfo *outTypeInfo)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000400{
Geoff Lang18591b72013-06-07 12:00:15 -0400401 static const TypeInfoMap infoMap = BuildTypeInfoMap();
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000402 TypeInfoMap::const_iterator iter = infoMap.find(type);
403 if (iter != infoMap.end())
404 {
405 if (outTypeInfo)
406 {
407 *outTypeInfo = iter->second;
408 }
409 return true;
410 }
411 else
412 {
413 return false;
414 }
415}
416
417// Information about internal formats
Geoff Lange4a492b2014-06-19 14:14:41 -0400418typedef bool(*SupportCheckFunction)(GLuint, const Extensions &);
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000419
Geoff Lang493daf52014-07-03 13:38:44 -0400420static bool AlwaysSupported(GLuint, const Extensions &)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000421{
Geoff Lang493daf52014-07-03 13:38:44 -0400422 return true;
423}
424
425static bool UnimplementedSupport(GLuint, const Extensions &)
426{
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000427 return false;
428}
429
Geoff Lang493daf52014-07-03 13:38:44 -0400430static bool NeverSupported(GLuint, const Extensions &)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000431{
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000432 return false;
433}
434
Geoff Lange4a492b2014-06-19 14:14:41 -0400435template <GLuint minCoreGLVersion>
436static bool RequireESVersion(GLuint clientVersion, const Extensions &)
437{
438 return clientVersion >= minCoreGLVersion;
439}
440
Geoff Langcec35902014-04-16 10:52:36 -0400441// Pointer to a boolean memeber of the Extensions struct
442typedef bool(Extensions::*ExtensionBool);
443
444// Check support for a single extension
445template <ExtensionBool bool1>
Geoff Lange4a492b2014-06-19 14:14:41 -0400446static bool RequireExtension(GLuint, const Extensions & extensions)
Geoff Langcec35902014-04-16 10:52:36 -0400447{
Geoff Lange4a492b2014-06-19 14:14:41 -0400448 return extensions.*bool1;
449}
450
451// Check for a minimum client version or a single extension
452template <GLuint minCoreGLVersion, ExtensionBool bool1>
453static bool RequireESVersionOrExtension(GLuint clientVersion, const Extensions &extensions)
454{
455 return clientVersion >= minCoreGLVersion || extensions.*bool1;
456}
457
458// Check for a minimum client version or two extensions
459template <GLuint minCoreGLVersion, ExtensionBool bool1, ExtensionBool bool2>
460static bool RequireESVersionOrExtensions(GLuint clientVersion, const Extensions &extensions)
461{
462 return clientVersion >= minCoreGLVersion || (extensions.*bool1 || extensions.*bool2);
Geoff Langcec35902014-04-16 10:52:36 -0400463}
464
465// Check support for two extensions
466template <ExtensionBool bool1, ExtensionBool bool2>
Geoff Lange4a492b2014-06-19 14:14:41 -0400467static bool RequireExtensions(GLuint, const Extensions &extensions)
Geoff Langcec35902014-04-16 10:52:36 -0400468{
Geoff Lange4a492b2014-06-19 14:14:41 -0400469 return extensions.*bool1 || extensions.*bool2;
Geoff Langcec35902014-04-16 10:52:36 -0400470}
471
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000472struct InternalFormatInfo
473{
474 GLuint mRedBits;
475 GLuint mGreenBits;
476 GLuint mBlueBits;
477
478 GLuint mLuminanceBits;
479
480 GLuint mAlphaBits;
481 GLuint mSharedBits;
482
483 GLuint mDepthBits;
484 GLuint mStencilBits;
485
486 GLuint mPixelBits;
487
488 GLuint mComponentCount;
489
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000490 GLuint mCompressedBlockWidth;
491 GLuint mCompressedBlockHeight;
492
493 GLenum mFormat;
494 GLenum mType;
495
Geoff Langb2f3d052013-08-13 12:49:27 -0400496 GLenum mComponentType;
497 GLenum mColorEncoding;
shannonwoods@chromium.orge19409b2013-05-30 00:16:15 +0000498
Geoff Langb2f3d052013-08-13 12:49:27 -0400499 bool mIsCompressed;
shannonwoods@chromium.orge81ea502013-05-30 00:16:53 +0000500
Geoff Lang493daf52014-07-03 13:38:44 -0400501 SupportCheckFunction mTextureSupportFunction;
502 SupportCheckFunction mRenderSupportFunction;
503 SupportCheckFunction mFilterSupportFunction;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000504
505 InternalFormatInfo() : mRedBits(0), mGreenBits(0), mBlueBits(0), mLuminanceBits(0), mAlphaBits(0), mSharedBits(0), mDepthBits(0), mStencilBits(0),
shannonwoods@chromium.orge19409b2013-05-30 00:16:15 +0000506 mPixelBits(0), mComponentCount(0), mCompressedBlockWidth(0), mCompressedBlockHeight(0), mFormat(GL_NONE), mType(GL_NONE),
Geoff Lang493daf52014-07-03 13:38:44 -0400507 mComponentType(GL_NONE), mColorEncoding(GL_NONE), mIsCompressed(false), mTextureSupportFunction(NeverSupported),
508 mRenderSupportFunction(NeverSupported), mFilterSupportFunction(NeverSupported)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000509 {
510 }
511
Geoff Lang493daf52014-07-03 13:38:44 -0400512 static InternalFormatInfo UnsizedFormat(GLenum format, SupportCheckFunction textureSupport, SupportCheckFunction renderSupport,
513 SupportCheckFunction filterSupport)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000514 {
515 InternalFormatInfo formatInfo;
516 formatInfo.mFormat = format;
Geoff Lang493daf52014-07-03 13:38:44 -0400517 formatInfo.mTextureSupportFunction = textureSupport;
518 formatInfo.mRenderSupportFunction = renderSupport;
519 formatInfo.mFilterSupportFunction = filterSupport;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000520 return formatInfo;
521 }
522
523 static InternalFormatInfo RGBAFormat(GLuint red, GLuint green, GLuint blue, GLuint alpha, GLuint shared,
Geoff Langb2f3d052013-08-13 12:49:27 -0400524 GLenum format, GLenum type, GLenum componentType, bool srgb,
Geoff Lang493daf52014-07-03 13:38:44 -0400525 SupportCheckFunction textureSupport, SupportCheckFunction renderSupport,
526 SupportCheckFunction filterSupport)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000527 {
528 InternalFormatInfo formatInfo;
529 formatInfo.mRedBits = red;
530 formatInfo.mGreenBits = green;
531 formatInfo.mBlueBits = blue;
532 formatInfo.mAlphaBits = alpha;
533 formatInfo.mSharedBits = shared;
534 formatInfo.mPixelBits = red + green + blue + alpha + shared;
535 formatInfo.mComponentCount = ((red > 0) ? 1 : 0) + ((green > 0) ? 1 : 0) + ((blue > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
536 formatInfo.mFormat = format;
537 formatInfo.mType = type;
Geoff Langb2f3d052013-08-13 12:49:27 -0400538 formatInfo.mComponentType = componentType;
539 formatInfo.mColorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
Geoff Lang493daf52014-07-03 13:38:44 -0400540 formatInfo.mTextureSupportFunction = textureSupport;
541 formatInfo.mRenderSupportFunction = renderSupport;
542 formatInfo.mFilterSupportFunction = filterSupport;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000543 return formatInfo;
544 }
545
Geoff Langb2f3d052013-08-13 12:49:27 -0400546 static InternalFormatInfo LUMAFormat(GLuint luminance, GLuint alpha, GLenum format, GLenum type, GLenum componentType,
Geoff Lang493daf52014-07-03 13:38:44 -0400547 SupportCheckFunction textureSupport, SupportCheckFunction renderSupport,
548 SupportCheckFunction filterSupport)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000549 {
550 InternalFormatInfo formatInfo;
551 formatInfo.mLuminanceBits = luminance;
552 formatInfo.mAlphaBits = alpha;
553 formatInfo.mPixelBits = luminance + alpha;
554 formatInfo.mComponentCount = ((luminance > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
555 formatInfo.mFormat = format;
556 formatInfo.mType = type;
Geoff Langb2f3d052013-08-13 12:49:27 -0400557 formatInfo.mComponentType = componentType;
558 formatInfo.mColorEncoding = GL_LINEAR;
Geoff Lang493daf52014-07-03 13:38:44 -0400559 formatInfo.mTextureSupportFunction = textureSupport;
560 formatInfo.mRenderSupportFunction = renderSupport;
561 formatInfo.mFilterSupportFunction = filterSupport;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000562 return formatInfo;
563 }
564
Geoff Lang85ea9ab2013-10-10 13:50:34 -0400565 static InternalFormatInfo DepthStencilFormat(GLuint depthBits, GLuint stencilBits, GLuint unusedBits, GLenum format,
Geoff Lang493daf52014-07-03 13:38:44 -0400566 GLenum type, GLenum componentType, SupportCheckFunction textureSupport,
567 SupportCheckFunction renderSupport, SupportCheckFunction filterSupport)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000568 {
569 InternalFormatInfo formatInfo;
Geoff Lang85ea9ab2013-10-10 13:50:34 -0400570 formatInfo.mDepthBits = depthBits;
571 formatInfo.mStencilBits = stencilBits;
572 formatInfo.mPixelBits = depthBits + stencilBits + unusedBits;
573 formatInfo.mComponentCount = ((depthBits > 0) ? 1 : 0) + ((stencilBits > 0) ? 1 : 0);
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000574 formatInfo.mFormat = format;
575 formatInfo.mType = type;
Geoff Langb2f3d052013-08-13 12:49:27 -0400576 formatInfo.mComponentType = componentType;
577 formatInfo.mColorEncoding = GL_LINEAR;
Geoff Lang493daf52014-07-03 13:38:44 -0400578 formatInfo.mTextureSupportFunction = textureSupport;
579 formatInfo.mRenderSupportFunction = renderSupport;
580 formatInfo.mFilterSupportFunction = filterSupport;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000581 return formatInfo;
582 }
583
Geoff Langb2f3d052013-08-13 12:49:27 -0400584 static InternalFormatInfo CompressedFormat(GLuint compressedBlockWidth, GLuint compressedBlockHeight, GLuint compressedBlockSize,
585 GLuint componentCount, GLenum format, GLenum type, bool srgb,
Geoff Lang493daf52014-07-03 13:38:44 -0400586 SupportCheckFunction textureSupport, SupportCheckFunction renderSupport,
587 SupportCheckFunction filterSupport)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000588 {
589 InternalFormatInfo formatInfo;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000590 formatInfo.mCompressedBlockWidth = compressedBlockWidth;
591 formatInfo.mCompressedBlockHeight = compressedBlockHeight;
592 formatInfo.mPixelBits = compressedBlockSize;
593 formatInfo.mComponentCount = componentCount;
594 formatInfo.mFormat = format;
595 formatInfo.mType = type;
Geoff Langb2f3d052013-08-13 12:49:27 -0400596 formatInfo.mComponentType = GL_UNSIGNED_NORMALIZED;
597 formatInfo.mColorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
598 formatInfo.mIsCompressed = true;
Geoff Lang493daf52014-07-03 13:38:44 -0400599 formatInfo.mTextureSupportFunction = textureSupport;
600 formatInfo.mRenderSupportFunction = renderSupport;
601 formatInfo.mFilterSupportFunction = filterSupport;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000602 return formatInfo;
603 }
604};
605
Geoff Lang005df412013-10-16 14:12:50 -0400606typedef std::pair<GLenum, InternalFormatInfo> InternalFormatInfoPair;
607typedef std::map<GLenum, InternalFormatInfo> InternalFormatInfoMap;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000608
Geoff Lange4a492b2014-06-19 14:14:41 -0400609static InternalFormatInfoMap BuildInternalFormatInfoMap()
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000610{
611 InternalFormatInfoMap map;
612
613 // From ES 3.0.1 spec, table 3.12
614 map.insert(InternalFormatInfoPair(GL_NONE, InternalFormatInfo()));
615
Geoff Lang493daf52014-07-03 13:38:44 -0400616 // | Internal format | | R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Renderable | Filterable |
617 map.insert(InternalFormatInfoPair(GL_R8, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::textureRG>, AlwaysSupported, AlwaysSupported)));
618 map.insert(InternalFormatInfoPair(GL_R8_SNORM, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireESVersion<3>, NeverSupported, AlwaysSupported)));
619 map.insert(InternalFormatInfoPair(GL_RG8, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::textureRG>, AlwaysSupported, AlwaysSupported)));
620 map.insert(InternalFormatInfoPair(GL_RG8_SNORM, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireESVersion<3>, NeverSupported, AlwaysSupported)));
621 map.insert(InternalFormatInfoPair(GL_RGB8, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::rgb8rgba8>, AlwaysSupported, AlwaysSupported)));
622 map.insert(InternalFormatInfoPair(GL_RGB8_SNORM, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireESVersion<3>, NeverSupported, AlwaysSupported)));
623 map.insert(InternalFormatInfoPair(GL_RGB565, InternalFormatInfo::RGBAFormat( 5, 6, 5, 0, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, RequireESVersion<2>, AlwaysSupported, AlwaysSupported)));
624 map.insert(InternalFormatInfoPair(GL_RGBA4, InternalFormatInfo::RGBAFormat( 4, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, RequireESVersion<2>, AlwaysSupported, AlwaysSupported)));
625 map.insert(InternalFormatInfoPair(GL_RGB5_A1, InternalFormatInfo::RGBAFormat( 5, 5, 5, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, RequireESVersion<2>, AlwaysSupported, AlwaysSupported)));
626 map.insert(InternalFormatInfoPair(GL_RGBA8, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESVersionOrExtension<3, &Extensions::rgb8rgba8>, AlwaysSupported, AlwaysSupported)));
627 map.insert(InternalFormatInfoPair(GL_RGBA8_SNORM, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireESVersion<3>, NeverSupported, AlwaysSupported)));
628 map.insert(InternalFormatInfoPair(GL_RGB10_A2, InternalFormatInfo::RGBAFormat(10, 10, 10, 2, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, RequireESVersion<3>, AlwaysSupported, AlwaysSupported)));
629 map.insert(InternalFormatInfoPair(GL_RGB10_A2UI, InternalFormatInfo::RGBAFormat(10, 10, 10, 2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT, false, RequireESVersion<3>, NeverSupported, NeverSupported)));
630 map.insert(InternalFormatInfoPair(GL_SRGB8, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESVersionOrExtension<3, &Extensions::sRGB>, NeverSupported, AlwaysSupported)));
631 map.insert(InternalFormatInfoPair(GL_SRGB8_ALPHA8, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESVersionOrExtension<3, &Extensions::sRGB>, AlwaysSupported, AlwaysSupported)));
632 map.insert(InternalFormatInfoPair(GL_R11F_G11F_B10F, InternalFormatInfo::RGBAFormat(11, 11, 10, 0, 0, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT, false, RequireESVersion<3>, RequireExtension<&Extensions::colorBufferFloat>, AlwaysSupported)));
633 map.insert(InternalFormatInfoPair(GL_RGB9_E5, InternalFormatInfo::RGBAFormat( 9, 9, 9, 0, 5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT, false, RequireESVersion<3>, NeverSupported, AlwaysSupported)));
634 map.insert(InternalFormatInfoPair(GL_R8I, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_BYTE, GL_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
635 map.insert(InternalFormatInfoPair(GL_R8UI, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
636 map.insert(InternalFormatInfoPair(GL_R16I, InternalFormatInfo::RGBAFormat(16, 0, 0, 0, 0, GL_RED_INTEGER, GL_SHORT, GL_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
637 map.insert(InternalFormatInfoPair(GL_R16UI, InternalFormatInfo::RGBAFormat(16, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
638 map.insert(InternalFormatInfoPair(GL_R32I, InternalFormatInfo::RGBAFormat(32, 0, 0, 0, 0, GL_RED_INTEGER, GL_INT, GL_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
639 map.insert(InternalFormatInfoPair(GL_R32UI, InternalFormatInfo::RGBAFormat(32, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
640 map.insert(InternalFormatInfoPair(GL_RG8I, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_BYTE, GL_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
641 map.insert(InternalFormatInfoPair(GL_RG8UI, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
642 map.insert(InternalFormatInfoPair(GL_RG16I, InternalFormatInfo::RGBAFormat(16, 16, 0, 0, 0, GL_RG_INTEGER, GL_SHORT, GL_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
643 map.insert(InternalFormatInfoPair(GL_RG16UI, InternalFormatInfo::RGBAFormat(16, 16, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
644 map.insert(InternalFormatInfoPair(GL_RG32I, InternalFormatInfo::RGBAFormat(32, 32, 0, 0, 0, GL_RG_INTEGER, GL_INT, GL_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
645 map.insert(InternalFormatInfoPair(GL_RG32UI, InternalFormatInfo::RGBAFormat(32, 32, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
646 map.insert(InternalFormatInfoPair(GL_RGB8I, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_BYTE, GL_INT, false, RequireESVersion<3>, NeverSupported, NeverSupported)));
647 map.insert(InternalFormatInfoPair(GL_RGB8UI, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireESVersion<3>, NeverSupported, NeverSupported)));
648 map.insert(InternalFormatInfoPair(GL_RGB16I, InternalFormatInfo::RGBAFormat(16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_SHORT, GL_INT, false, RequireESVersion<3>, NeverSupported, NeverSupported)));
649 map.insert(InternalFormatInfoPair(GL_RGB16UI, InternalFormatInfo::RGBAFormat(16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireESVersion<3>, NeverSupported, NeverSupported)));
650 map.insert(InternalFormatInfoPair(GL_RGB32I, InternalFormatInfo::RGBAFormat(32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_INT, GL_INT, false, RequireESVersion<3>, NeverSupported, NeverSupported)));
651 map.insert(InternalFormatInfoPair(GL_RGB32UI, InternalFormatInfo::RGBAFormat(32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireESVersion<3>, NeverSupported, NeverSupported)));
652 map.insert(InternalFormatInfoPair(GL_RGBA8I, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_BYTE, GL_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
653 map.insert(InternalFormatInfoPair(GL_RGBA8UI, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
654 map.insert(InternalFormatInfoPair(GL_RGBA16I, InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT, GL_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
655 map.insert(InternalFormatInfoPair(GL_RGBA16UI, InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
656 map.insert(InternalFormatInfoPair(GL_RGBA32I, InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT, GL_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
657 map.insert(InternalFormatInfoPair(GL_RGBA32UI, InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireESVersion<3>, AlwaysSupported, NeverSupported)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000658
Geoff Lang493daf52014-07-03 13:38:44 -0400659 map.insert(InternalFormatInfoPair(GL_BGRA8_EXT, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExtension<&Extensions::textureFormatBGRA8888>, AlwaysSupported, AlwaysSupported)));
660 map.insert(InternalFormatInfoPair(GL_BGRA4_ANGLEX, InternalFormatInfo::RGBAFormat( 4, 4, 4, 4, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExtension<&Extensions::textureFormatBGRA8888>, AlwaysSupported, AlwaysSupported)));
661 map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX, InternalFormatInfo::RGBAFormat( 5, 5, 5, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExtension<&Extensions::textureFormatBGRA8888>, AlwaysSupported, AlwaysSupported)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000662
663 // Floating point renderability and filtering is provided by OES_texture_float and OES_texture_half_float
Geoff Lang493daf52014-07-03 13:38:44 -0400664 // | Internal format | | D |S | Format | Type | Comp | SRGB | Texture supported | Renderable | Filterable |
665 // | | | | | | | type | | | | |
666 map.insert(InternalFormatInfoPair(GL_R16F, InternalFormatInfo::RGBAFormat(16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
667 map.insert(InternalFormatInfoPair(GL_RG16F, InternalFormatInfo::RGBAFormat(16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
668 map.insert(InternalFormatInfoPair(GL_RGB16F, InternalFormatInfo::RGBAFormat(16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureHalfFloat>, AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
669 map.insert(InternalFormatInfoPair(GL_RGBA16F, InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureHalfFloat>, AlwaysSupported, RequireExtension<&Extensions::textureHalfFloatLinear>)));
670 map.insert(InternalFormatInfoPair(GL_R32F, InternalFormatInfo::RGBAFormat(32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureFloat, &Extensions::textureRG>, AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear> )));
671 map.insert(InternalFormatInfoPair(GL_RG32F, InternalFormatInfo::RGBAFormat(32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, RequireESVersionOrExtensions<3, &Extensions::textureFloat, &Extensions::textureRG>, AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear> )));
672 map.insert(InternalFormatInfoPair(GL_RGB32F, InternalFormatInfo::RGBAFormat(32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureFloat>, AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear> )));
673 map.insert(InternalFormatInfoPair(GL_RGBA32F, InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureFloat>, AlwaysSupported, RequireExtension<&Extensions::textureFloatLinear> )));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000674
675 // Depth stencil formats
Geoff Langcec35902014-04-16 10:52:36 -0400676 // | Internal format | | D |S | X | Format | Type | Component type | Supported |
Geoff Lang493daf52014-07-03 13:38:44 -0400677 map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16, InternalFormatInfo::DepthStencilFormat(16, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, RequireESVersion<2>, AlwaysSupported, RequireESVersionOrExtension<3, &Extensions::depthTextures>)));
678 map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT24, InternalFormatInfo::DepthStencilFormat(24, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireESVersion<3>, AlwaysSupported, RequireESVersionOrExtension<3, &Extensions::depthTextures>)));
679 map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32F, InternalFormatInfo::DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, RequireESVersion<3>, AlwaysSupported, RequireESVersionOrExtension<3, &Extensions::depthTextures>)));
680 map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES, InternalFormatInfo::DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::depthTextures>, AlwaysSupported, AlwaysSupported )));
681 map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8, InternalFormatInfo::DepthStencilFormat(24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESVersionOrExtension<2, &Extensions::depthTextures>, AlwaysSupported, AlwaysSupported )));
682 map.insert(InternalFormatInfoPair(GL_DEPTH32F_STENCIL8, InternalFormatInfo::DepthStencilFormat(32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, RequireESVersion<3>, AlwaysSupported, AlwaysSupported )));
683 map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8, InternalFormatInfo::DepthStencilFormat( 0, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, RequireESVersion<2>, AlwaysSupported, NeverSupported )));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000684
685 // Luminance alpha formats
Geoff Lang493daf52014-07-03 13:38:44 -0400686 // | Internal format | | L | A | Format | Type | Component type | Supported | Renderable | Filterable |
687 map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT, InternalFormatInfo::LUMAFormat( 0, 8, GL_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>, NeverSupported, AlwaysSupported)));
688 map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT, InternalFormatInfo::LUMAFormat( 8, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>, NeverSupported, AlwaysSupported)));
689 map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat( 0, 32, GL_ALPHA, GL_FLOAT, GL_FLOAT, RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>, NeverSupported, AlwaysSupported)));
690 map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT, InternalFormatInfo::LUMAFormat(32, 0, GL_LUMINANCE, GL_FLOAT, GL_FLOAT, RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>, NeverSupported, AlwaysSupported)));
691 map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat( 0, 16, GL_ALPHA, GL_HALF_FLOAT, GL_FLOAT, RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
692 map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT, InternalFormatInfo::LUMAFormat(16, 0, GL_LUMINANCE, GL_HALF_FLOAT, GL_FLOAT, RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
693 map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT, InternalFormatInfo::LUMAFormat( 8, 8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage>, NeverSupported, AlwaysSupported)));
694 map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat(32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_FLOAT, RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat>, NeverSupported, AlwaysSupported)));
695 map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat(16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_FLOAT, RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000696
697 // Unsized formats
Geoff Lang493daf52014-07-03 13:38:44 -0400698 // | Internal format | | Format | Supported | Renderable | Filterable |
699 map.insert(InternalFormatInfoPair(GL_ALPHA, InternalFormatInfo::UnsizedFormat(GL_ALPHA, RequireESVersion<2>, NeverSupported, AlwaysSupported)));
700 map.insert(InternalFormatInfoPair(GL_LUMINANCE, InternalFormatInfo::UnsizedFormat(GL_LUMINANCE, RequireESVersion<2>, NeverSupported, AlwaysSupported)));
701 map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA, InternalFormatInfo::UnsizedFormat(GL_LUMINANCE_ALPHA, RequireESVersion<2>, NeverSupported, AlwaysSupported)));
702 map.insert(InternalFormatInfoPair(GL_RED, InternalFormatInfo::UnsizedFormat(GL_RED, RequireESVersionOrExtension<3, &Extensions::textureRG>, NeverSupported, AlwaysSupported)));
703 map.insert(InternalFormatInfoPair(GL_RG, InternalFormatInfo::UnsizedFormat(GL_RG, RequireESVersionOrExtension<3, &Extensions::textureRG>, NeverSupported, AlwaysSupported)));
704 map.insert(InternalFormatInfoPair(GL_RGB, InternalFormatInfo::UnsizedFormat(GL_RGB, RequireESVersion<2>, AlwaysSupported, AlwaysSupported)));
705 map.insert(InternalFormatInfoPair(GL_RGBA, InternalFormatInfo::UnsizedFormat(GL_RGBA, RequireESVersion<2>, AlwaysSupported, AlwaysSupported)));
706 map.insert(InternalFormatInfoPair(GL_RED_INTEGER, InternalFormatInfo::UnsizedFormat(GL_RED_INTEGER, RequireESVersion<3>, NeverSupported, NeverSupported )));
707 map.insert(InternalFormatInfoPair(GL_RG_INTEGER, InternalFormatInfo::UnsizedFormat(GL_RG_INTEGER, RequireESVersion<3>, NeverSupported, NeverSupported )));
708 map.insert(InternalFormatInfoPair(GL_RGB_INTEGER, InternalFormatInfo::UnsizedFormat(GL_RGB_INTEGER, RequireESVersion<3>, NeverSupported, NeverSupported )));
709 map.insert(InternalFormatInfoPair(GL_RGBA_INTEGER, InternalFormatInfo::UnsizedFormat(GL_RGBA_INTEGER, RequireESVersion<3>, NeverSupported, NeverSupported )));
710 map.insert(InternalFormatInfoPair(GL_BGRA_EXT, InternalFormatInfo::UnsizedFormat(GL_BGRA_EXT, RequireExtension<&Extensions::textureFormatBGRA8888>, AlwaysSupported, AlwaysSupported)));
711 map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT, InternalFormatInfo::UnsizedFormat(GL_DEPTH_COMPONENT, RequireESVersion<2>, AlwaysSupported, AlwaysSupported)));
712 map.insert(InternalFormatInfoPair(GL_DEPTH_STENCIL, InternalFormatInfo::UnsizedFormat(GL_DEPTH_STENCIL, RequireESVersionOrExtension<3, &Extensions::packedDepthStencil>, AlwaysSupported, AlwaysSupported)));
713 map.insert(InternalFormatInfoPair(GL_SRGB_EXT, InternalFormatInfo::UnsizedFormat(GL_RGB, RequireESVersionOrExtension<3, &Extensions::sRGB>, NeverSupported, AlwaysSupported)));
714 map.insert(InternalFormatInfoPair(GL_SRGB_ALPHA_EXT, InternalFormatInfo::UnsizedFormat(GL_RGBA, RequireESVersionOrExtension<3, &Extensions::sRGB>, AlwaysSupported, AlwaysSupported)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000715
716 // Compressed formats, From ES 3.0.1 spec, table 3.16
Geoff Lang493daf52014-07-03 13:38:44 -0400717 // | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable |
718 map.insert(InternalFormatInfoPair(GL_COMPRESSED_R11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
719 map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_R11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
720 map.insert(InternalFormatInfoPair(GL_COMPRESSED_RG11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
721 map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_RG11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
722 map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_ETC2, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
723 map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ETC2, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE, true, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
724 map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
725 map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, true, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
726 map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA8_ETC2_EAC, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport)));
727 map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, InternalFormatInfo::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 +0000728
729 // From GL_EXT_texture_compression_dxt1
Geoff Lang493daf52014-07-03 13:38:44 -0400730 // | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable |
731 map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT1>, NeverSupported, AlwaysSupported )));
732 map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, InternalFormatInfo::CompressedFormat(4, 4, 64, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT1>, NeverSupported, AlwaysSupported )));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000733
734 // From GL_ANGLE_texture_compression_dxt3
Geoff Lang493daf52014-07-03 13:38:44 -0400735 map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT5>, NeverSupported, AlwaysSupported )));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000736
737 // From GL_ANGLE_texture_compression_dxt5
Geoff Lang493daf52014-07-03 13:38:44 -0400738 map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, false, RequireExtension<&Extensions::textureCompressionDXT5>, NeverSupported, AlwaysSupported )));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000739
740 return map;
741}
742
Geoff Lange4a492b2014-06-19 14:14:41 -0400743static const InternalFormatInfoMap &GetInternalFormatMap()
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000744{
Geoff Lange4a492b2014-06-19 14:14:41 -0400745 static const InternalFormatInfoMap formatMap = BuildInternalFormatInfoMap();
746 return formatMap;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000747}
748
Geoff Lange4a492b2014-06-19 14:14:41 -0400749static bool GetInternalFormatInfo(GLenum internalFormat, InternalFormatInfo *outFormatInfo)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000750{
Geoff Lange4a492b2014-06-19 14:14:41 -0400751 const InternalFormatInfoMap &map = GetInternalFormatMap();
Geoff Langcec35902014-04-16 10:52:36 -0400752 InternalFormatInfoMap::const_iterator iter = map.find(internalFormat);
753 if (iter != map.end())
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000754 {
755 if (outFormatInfo)
756 {
757 *outFormatInfo = iter->second;
758 }
759 return true;
760 }
761 else
762 {
763 return false;
764 }
765}
766
Geoff Lange4a492b2014-06-19 14:14:41 -0400767static FormatSet BuildAllSizedInternalFormatSet()
Geoff Langcec35902014-04-16 10:52:36 -0400768{
769 FormatSet result;
770
Geoff Lange4a492b2014-06-19 14:14:41 -0400771 const InternalFormatInfoMap &formats = GetInternalFormatMap();
Geoff Langcec35902014-04-16 10:52:36 -0400772 for (InternalFormatInfoMap::const_iterator i = formats.begin(); i != formats.end(); i++)
773 {
774 if (i->second.mPixelBits > 0)
775 {
776 result.insert(i->first);
777 }
778 }
779
780 return result;
781}
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000782
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000783typedef std::set<GLenum> TypeSet;
784
Shannon Woods4d161ba2014-03-17 18:13:30 -0400785struct EffectiveInternalFormatInfo
786{
787 GLenum mEffectiveFormat;
788 GLenum mDestFormat;
789 GLuint mMinRedBits;
790 GLuint mMaxRedBits;
791 GLuint mMinGreenBits;
792 GLuint mMaxGreenBits;
793 GLuint mMinBlueBits;
794 GLuint mMaxBlueBits;
795 GLuint mMinAlphaBits;
796 GLuint mMaxAlphaBits;
797
798 EffectiveInternalFormatInfo(GLenum effectiveFormat, GLenum destFormat, GLuint minRedBits, GLuint maxRedBits,
799 GLuint minGreenBits, GLuint maxGreenBits, GLuint minBlueBits, GLuint maxBlueBits,
800 GLuint minAlphaBits, GLuint maxAlphaBits)
801 : mEffectiveFormat(effectiveFormat), mDestFormat(destFormat), mMinRedBits(minRedBits),
802 mMaxRedBits(maxRedBits), mMinGreenBits(minGreenBits), mMaxGreenBits(maxGreenBits),
803 mMinBlueBits(minBlueBits), mMaxBlueBits(maxBlueBits), mMinAlphaBits(minAlphaBits),
804 mMaxAlphaBits(maxAlphaBits) {};
805};
806
807typedef std::vector<EffectiveInternalFormatInfo> EffectiveInternalFormatList;
808
809static EffectiveInternalFormatList BuildSizedEffectiveInternalFormatList()
810{
811 EffectiveInternalFormatList list;
812
813 // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and
814 // linear source buffer component sizes.
815 // | Source channel min/max sizes |
816 // Effective Internal Format | N/A | R | G | B | A |
817 list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT, GL_NONE, 0, 0, 0, 0, 0, 0, 1, 8));
818 list.push_back(EffectiveInternalFormatInfo(GL_R8, GL_NONE, 1, 8, 0, 0, 0, 0, 0, 0));
819 list.push_back(EffectiveInternalFormatInfo(GL_RG8, GL_NONE, 1, 8, 1, 8, 0, 0, 0, 0));
820 list.push_back(EffectiveInternalFormatInfo(GL_RGB565, GL_NONE, 1, 5, 1, 6, 1, 5, 0, 0));
821 list.push_back(EffectiveInternalFormatInfo(GL_RGB8, GL_NONE, 6, 8, 7, 8, 6, 8, 0, 0));
822 list.push_back(EffectiveInternalFormatInfo(GL_RGBA4, GL_NONE, 1, 4, 1, 4, 1, 4, 1, 4));
823 list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1, GL_NONE, 5, 5, 5, 5, 5, 5, 1, 1));
824 list.push_back(EffectiveInternalFormatInfo(GL_RGBA8, GL_NONE, 5, 8, 5, 8, 5, 8, 2, 8));
825 list.push_back(EffectiveInternalFormatInfo(GL_RGB10_A2, GL_NONE, 9, 10, 9, 10, 9, 10, 2, 2));
826
827 return list;
828}
829
830
831static EffectiveInternalFormatList BuildUnsizedEffectiveInternalFormatList()
832{
833 EffectiveInternalFormatList list;
834
835 // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and
836 // linear source buffer component sizes.
837 // | Source channel min/max sizes |
838 // Effective Internal Format | Dest Format | R | G | B | A |
839 list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT, GL_ALPHA, 0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX, 1, 8));
840 list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_EXT, GL_LUMINANCE, 1, 8, 0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX));
841 list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, 1, 8, 0, UINT_MAX, 0, UINT_MAX, 1, 8));
842 list.push_back(EffectiveInternalFormatInfo(GL_RGB565, GL_RGB, 1, 5, 1, 6, 1, 5, 0, UINT_MAX));
843 list.push_back(EffectiveInternalFormatInfo(GL_RGB8, GL_RGB, 6, 8, 7, 8, 6, 8, 0, UINT_MAX));
844 list.push_back(EffectiveInternalFormatInfo(GL_RGBA4, GL_RGBA, 1, 4, 1, 4, 1, 4, 1, 4));
845 list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1, GL_RGBA, 5, 5, 5, 5, 5, 5, 1, 1));
846 list.push_back(EffectiveInternalFormatInfo(GL_RGBA8, GL_RGBA, 5, 8, 5, 8, 5, 8, 5, 8));
847
848 return list;
849}
850
851static bool GetEffectiveInternalFormat(const InternalFormatInfo &srcFormat, const InternalFormatInfo &destFormat,
Geoff Lange4a492b2014-06-19 14:14:41 -0400852 GLenum *outEffectiveFormat)
Shannon Woods4d161ba2014-03-17 18:13:30 -0400853{
854 const EffectiveInternalFormatList *list = NULL;
855 GLenum targetFormat = GL_NONE;
856
Geoff Lange4a492b2014-06-19 14:14:41 -0400857 if (gl::IsSizedInternalFormat(destFormat.mFormat))
Shannon Woods4d161ba2014-03-17 18:13:30 -0400858 {
859 static const EffectiveInternalFormatList sizedList = BuildSizedEffectiveInternalFormatList();
860 list = &sizedList;
861 }
862 else
863 {
864 static const EffectiveInternalFormatList unsizedList = BuildUnsizedEffectiveInternalFormatList();
865 list = &unsizedList;
866 targetFormat = destFormat.mFormat;
867 }
868
869 for (size_t curFormat = 0; curFormat < list->size(); ++curFormat)
870 {
871 const EffectiveInternalFormatInfo& formatInfo = list->at(curFormat);
872 if ((formatInfo.mDestFormat == targetFormat) &&
873 (formatInfo.mMinRedBits <= srcFormat.mRedBits && formatInfo.mMaxRedBits >= srcFormat.mRedBits) &&
874 (formatInfo.mMinGreenBits <= srcFormat.mGreenBits && formatInfo.mMaxGreenBits >= srcFormat.mGreenBits) &&
875 (formatInfo.mMinBlueBits <= srcFormat.mBlueBits && formatInfo.mMaxBlueBits >= srcFormat.mBlueBits) &&
876 (formatInfo.mMinAlphaBits <= srcFormat.mAlphaBits && formatInfo.mMaxAlphaBits >= srcFormat.mAlphaBits))
877 {
878 *outEffectiveFormat = formatInfo.mEffectiveFormat;
879 return true;
880 }
881 }
882
883 return false;
884}
885
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000886struct CopyConversion
887{
888 GLenum mTextureFormat;
889 GLenum mFramebufferFormat;
890
891 CopyConversion(GLenum textureFormat, GLenum framebufferFormat)
892 : mTextureFormat(textureFormat), mFramebufferFormat(framebufferFormat) { }
893
894 bool operator<(const CopyConversion& other) const
895 {
896 return memcmp(this, &other, sizeof(CopyConversion)) < 0;
897 }
898};
899
900typedef std::set<CopyConversion> CopyConversionSet;
901
Geoff Lang18591b72013-06-07 12:00:15 -0400902static CopyConversionSet BuildValidES3CopyTexImageCombinations()
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000903{
904 CopyConversionSet set;
905
906 // From ES 3.0.1 spec, table 3.15
907 set.insert(CopyConversion(GL_ALPHA, GL_RGBA));
908 set.insert(CopyConversion(GL_LUMINANCE, GL_RED));
909 set.insert(CopyConversion(GL_LUMINANCE, GL_RG));
910 set.insert(CopyConversion(GL_LUMINANCE, GL_RGB));
911 set.insert(CopyConversion(GL_LUMINANCE, GL_RGBA));
912 set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_RGBA));
913 set.insert(CopyConversion(GL_RED, GL_RED));
914 set.insert(CopyConversion(GL_RED, GL_RG));
915 set.insert(CopyConversion(GL_RED, GL_RGB));
916 set.insert(CopyConversion(GL_RED, GL_RGBA));
917 set.insert(CopyConversion(GL_RG, GL_RG));
918 set.insert(CopyConversion(GL_RG, GL_RGB));
919 set.insert(CopyConversion(GL_RG, GL_RGBA));
920 set.insert(CopyConversion(GL_RGB, GL_RGB));
921 set.insert(CopyConversion(GL_RGB, GL_RGBA));
922 set.insert(CopyConversion(GL_RGBA, GL_RGBA));
923
Jamie Madillb70e5f72013-07-10 16:57:52 -0400924 // Necessary for ANGLE back-buffers
925 set.insert(CopyConversion(GL_ALPHA, GL_BGRA_EXT));
926 set.insert(CopyConversion(GL_LUMINANCE, GL_BGRA_EXT));
927 set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_BGRA_EXT));
928 set.insert(CopyConversion(GL_RED, GL_BGRA_EXT));
929 set.insert(CopyConversion(GL_RG, GL_BGRA_EXT));
930 set.insert(CopyConversion(GL_RGB, GL_BGRA_EXT));
931 set.insert(CopyConversion(GL_RGBA, GL_BGRA_EXT));
932
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +0000933 set.insert(CopyConversion(GL_RED_INTEGER, GL_RED_INTEGER));
934 set.insert(CopyConversion(GL_RED_INTEGER, GL_RG_INTEGER));
935 set.insert(CopyConversion(GL_RED_INTEGER, GL_RGB_INTEGER));
936 set.insert(CopyConversion(GL_RED_INTEGER, GL_RGBA_INTEGER));
937 set.insert(CopyConversion(GL_RG_INTEGER, GL_RG_INTEGER));
938 set.insert(CopyConversion(GL_RG_INTEGER, GL_RGB_INTEGER));
939 set.insert(CopyConversion(GL_RG_INTEGER, GL_RGBA_INTEGER));
940 set.insert(CopyConversion(GL_RGB_INTEGER, GL_RGB_INTEGER));
941 set.insert(CopyConversion(GL_RGB_INTEGER, GL_RGBA_INTEGER));
942 set.insert(CopyConversion(GL_RGBA_INTEGER, GL_RGBA_INTEGER));
943
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000944 return set;
945}
946
Geoff Langcec35902014-04-16 10:52:36 -0400947bool IsValidInternalFormat(GLenum internalFormat, const Extensions &extensions, GLuint clientVersion)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000948{
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000949 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -0400950 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000951 {
Geoff Lang493daf52014-07-03 13:38:44 -0400952 ASSERT(internalFormatInfo.mTextureSupportFunction != NULL);
953 return internalFormatInfo.mTextureSupportFunction(clientVersion, extensions);
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000954 }
955 else
956 {
957 return false;
958 }
959}
960
Geoff Lange4a492b2014-06-19 14:14:41 -0400961bool IsValidFormat(GLenum format, const Extensions &extensions, GLuint clientVersion)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000962{
Geoff Lange4a492b2014-06-19 14:14:41 -0400963 const InternalFormatInfoMap &internalFormats = GetInternalFormatMap();
964 for (InternalFormatInfoMap::const_iterator i = internalFormats.begin(); i != internalFormats.end(); i++)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000965 {
Geoff Lang493daf52014-07-03 13:38:44 -0400966 if (i->second.mFormat == format && i->second.mTextureSupportFunction(clientVersion, extensions))
Geoff Lange4a492b2014-06-19 14:14:41 -0400967 {
968 return true;
969 }
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000970 }
Geoff Lange4a492b2014-06-19 14:14:41 -0400971
972 return false;
973}
974
975bool IsValidType(GLenum type, const Extensions &extensions, GLuint clientVersion)
976{
977 const InternalFormatInfoMap &internalFormats = GetInternalFormatMap();
978 for (InternalFormatInfoMap::const_iterator i = internalFormats.begin(); i != internalFormats.end(); i++)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000979 {
Geoff Lang493daf52014-07-03 13:38:44 -0400980 if (i->second.mType == type && i->second.mTextureSupportFunction(clientVersion, extensions))
Geoff Lange4a492b2014-06-19 14:14:41 -0400981 {
982 return true;
983 }
984 }
985
986 return false;
987}
988
989bool IsValidFormatCombination(GLenum internalFormat, GLenum format, GLenum type, const Extensions &extensions, GLuint clientVersion)
990{
991 InternalFormatInfo internalFormatInfo;
992 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
993 {
Geoff Lang493daf52014-07-03 13:38:44 -0400994 if (!internalFormatInfo.mTextureSupportFunction(clientVersion, extensions))
Geoff Lange4a492b2014-06-19 14:14:41 -0400995 {
996 return false;
997 }
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000998 }
999 else
1000 {
1001 UNREACHABLE();
1002 return false;
1003 }
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001004
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001005 if (clientVersion == 2)
1006 {
Geoff Lange4a492b2014-06-19 14:14:41 -04001007 static const FormatMap &formats = GetFormatMap();
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001008 FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
Geoff Langfe28ca02013-06-04 10:10:48 -04001009 return (iter != formats.end()) && ((internalFormat == (GLint)type) || (internalFormat == iter->second.mInternalFormat));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001010 }
1011 else if (clientVersion == 3)
1012 {
Geoff Lang18591b72013-06-07 12:00:15 -04001013 static const ES3FormatSet &formats = GetES3FormatSet();
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001014 return formats.find(FormatInfo(internalFormat, format, type)) != formats.end();
1015 }
1016 else
1017 {
1018 UNREACHABLE();
1019 return false;
1020 }
1021}
1022
Shannon Woods4d161ba2014-03-17 18:13:30 -04001023bool IsValidCopyTexImageCombination(GLenum textureInternalFormat, GLenum frameBufferInternalFormat, GLuint readBufferHandle, GLuint clientVersion)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001024{
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +00001025 InternalFormatInfo textureInternalFormatInfo;
1026 InternalFormatInfo framebufferInternalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001027 if (GetInternalFormatInfo(textureInternalFormat, &textureInternalFormatInfo) &&
1028 GetInternalFormatInfo(frameBufferInternalFormat, &framebufferInternalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001029 {
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +00001030 if (clientVersion == 2)
1031 {
1032 UNIMPLEMENTED();
1033 return false;
1034 }
1035 else if (clientVersion == 3)
1036 {
Geoff Lang18591b72013-06-07 12:00:15 -04001037 static const CopyConversionSet conversionSet = BuildValidES3CopyTexImageCombinations();
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +00001038 const CopyConversion conversion = CopyConversion(textureInternalFormatInfo.mFormat,
1039 framebufferInternalFormatInfo.mFormat);
1040 if (conversionSet.find(conversion) != conversionSet.end())
1041 {
Shannon Woods4d161ba2014-03-17 18:13:30 -04001042 // Section 3.8.5 of the GLES 3.0.3 spec states that source and destination formats
1043 // must both be signed, unsigned, or fixed point and both source and destinations
1044 // must be either both SRGB or both not SRGB. EXT_color_buffer_float adds allowed
1045 // conversion between fixed and floating point.
shannonwoods@chromium.org96c62912013-05-30 00:17:00 +00001046
Geoff Langb2f3d052013-08-13 12:49:27 -04001047 if ((textureInternalFormatInfo.mColorEncoding == GL_SRGB) != (framebufferInternalFormatInfo.mColorEncoding == GL_SRGB))
shannonwoods@chromium.org96c62912013-05-30 00:17:00 +00001048 {
1049 return false;
1050 }
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +00001051
Shannon Woods4d161ba2014-03-17 18:13:30 -04001052 if (((textureInternalFormatInfo.mComponentType == GL_INT) != (framebufferInternalFormatInfo.mComponentType == GL_INT)) ||
1053 ((textureInternalFormatInfo.mComponentType == GL_UNSIGNED_INT) != (framebufferInternalFormatInfo.mComponentType == GL_UNSIGNED_INT)))
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +00001054 {
Shannon Woods4d161ba2014-03-17 18:13:30 -04001055 return false;
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +00001056 }
1057
Shannon Woods4d161ba2014-03-17 18:13:30 -04001058 if (gl::IsFloatOrFixedComponentType(textureInternalFormatInfo.mComponentType) &&
1059 !gl::IsFloatOrFixedComponentType(framebufferInternalFormatInfo.mComponentType))
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +00001060 {
Shannon Woods4d161ba2014-03-17 18:13:30 -04001061 return false;
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +00001062 }
Shannon Woods4d161ba2014-03-17 18:13:30 -04001063
1064 // GLES specification 3.0.3, sec 3.8.5, pg 139-140:
1065 // The effective internal format of the source buffer is determined with the following rules applied in order:
1066 // * If the source buffer is a texture or renderbuffer that was created with a sized internal format then the
1067 // effective internal format is the source buffer's sized internal format.
1068 // * If the source buffer is a texture that was created with an unsized base internal format, then the
1069 // effective internal format is the source image array's effective internal format, as specified by table
1070 // 3.12, which is determined from the <format> and <type> that were used when the source image array was
1071 // specified by TexImage*.
1072 // * Otherwise the effective internal format is determined by the row in table 3.17 or 3.18 where
1073 // Destination Internal Format matches internalformat and where the [source channel sizes] are consistent
1074 // with the values of the source buffer's [channel sizes]. Table 3.17 is used if the
1075 // FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the FRAMEBUFFER_ATTACHMENT_ENCODING
1076 // is SRGB.
1077 InternalFormatInfo sourceEffectiveFormat;
1078 if (readBufferHandle != 0)
1079 {
1080 // Not the default framebuffer, therefore the read buffer must be a user-created texture or renderbuffer
Geoff Lange4a492b2014-06-19 14:14:41 -04001081 if (gl::IsSizedInternalFormat(framebufferInternalFormatInfo.mFormat))
Shannon Woods4d161ba2014-03-17 18:13:30 -04001082 {
1083 sourceEffectiveFormat = framebufferInternalFormatInfo;
1084 }
1085 else
1086 {
1087 // Renderbuffers cannot be created with an unsized internal format, so this must be an unsized-format
1088 // texture. We can use the same table we use when creating textures to get its effective sized format.
1089 GLenum effectiveFormat = gl::GetSizedInternalFormat(framebufferInternalFormatInfo.mFormat,
Geoff Lange4a492b2014-06-19 14:14:41 -04001090 framebufferInternalFormatInfo.mType);
1091 gl::GetInternalFormatInfo(effectiveFormat, &sourceEffectiveFormat);
Shannon Woods4d161ba2014-03-17 18:13:30 -04001092 }
1093 }
1094 else
1095 {
1096 // The effective internal format must be derived from the source framebuffer's channel sizes.
1097 // This is done in GetEffectiveInternalFormat for linear buffers (table 3.17)
1098 if (framebufferInternalFormatInfo.mColorEncoding == GL_LINEAR)
1099 {
1100 GLenum effectiveFormat;
Geoff Lange4a492b2014-06-19 14:14:41 -04001101 if (GetEffectiveInternalFormat(framebufferInternalFormatInfo, textureInternalFormatInfo, &effectiveFormat))
Shannon Woods4d161ba2014-03-17 18:13:30 -04001102 {
Geoff Lange4a492b2014-06-19 14:14:41 -04001103 gl::GetInternalFormatInfo(effectiveFormat, &sourceEffectiveFormat);
Shannon Woods4d161ba2014-03-17 18:13:30 -04001104 }
1105 else
1106 {
1107 return false;
1108 }
1109 }
1110 else if (framebufferInternalFormatInfo.mColorEncoding == GL_SRGB)
1111 {
1112 // SRGB buffers can only be copied to sized format destinations according to table 3.18
Geoff Lange4a492b2014-06-19 14:14:41 -04001113 if (gl::IsSizedInternalFormat(textureInternalFormat) &&
Shannon Woods4d161ba2014-03-17 18:13:30 -04001114 (framebufferInternalFormatInfo.mRedBits >= 1 && framebufferInternalFormatInfo.mRedBits <= 8) &&
1115 (framebufferInternalFormatInfo.mGreenBits >= 1 && framebufferInternalFormatInfo.mGreenBits <= 8) &&
1116 (framebufferInternalFormatInfo.mBlueBits >= 1 && framebufferInternalFormatInfo.mBlueBits <= 8) &&
1117 (framebufferInternalFormatInfo.mAlphaBits >= 1 && framebufferInternalFormatInfo.mAlphaBits <= 8))
1118 {
Geoff Lange4a492b2014-06-19 14:14:41 -04001119 gl::GetInternalFormatInfo(GL_SRGB8_ALPHA8, &sourceEffectiveFormat);
Shannon Woods4d161ba2014-03-17 18:13:30 -04001120 }
1121 else
1122 {
1123 return false;
1124 }
1125 }
1126 else
1127 {
1128 UNREACHABLE();
1129 }
1130 }
1131
Geoff Lange4a492b2014-06-19 14:14:41 -04001132 if (gl::IsSizedInternalFormat(textureInternalFormatInfo.mFormat))
Shannon Woods4d161ba2014-03-17 18:13:30 -04001133 {
1134 // Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination format is sized,
1135 // component sizes of the source and destination formats must exactly match
1136 if (textureInternalFormatInfo.mRedBits != sourceEffectiveFormat.mRedBits ||
1137 textureInternalFormatInfo.mGreenBits != sourceEffectiveFormat.mGreenBits ||
1138 textureInternalFormatInfo.mBlueBits != sourceEffectiveFormat.mBlueBits ||
1139 textureInternalFormatInfo.mAlphaBits != sourceEffectiveFormat.mAlphaBits)
1140 {
1141 return false;
1142 }
1143 }
1144
1145
1146 return true; // A conversion function exists, and no rule in the specification has precluded conversion
1147 // between these formats.
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +00001148 }
1149
1150 return false;
1151 }
1152 else
1153 {
1154 UNREACHABLE();
1155 return false;
1156 }
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001157 }
1158 else
1159 {
1160 UNREACHABLE();
1161 return false;
1162 }
1163}
1164
Geoff Lang493daf52014-07-03 13:38:44 -04001165bool IsRenderingSupported(GLenum internalFormat, const Extensions &extensions, GLuint clientVersion)
1166{
1167 InternalFormatInfo internalFormatInfo;
1168 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
1169 {
1170 ASSERT(internalFormatInfo.mTextureSupportFunction != NULL);
1171 ASSERT(internalFormatInfo.mRenderSupportFunction != NULL);
1172 return internalFormatInfo.mTextureSupportFunction(clientVersion, extensions) &&
1173 internalFormatInfo.mRenderSupportFunction(clientVersion, extensions);
1174 }
1175 else
1176 {
1177 return false;
1178 }
1179}
1180
1181bool IsFilteringSupported(GLenum internalFormat, const Extensions &extensions, GLuint clientVersion)
1182{
1183 InternalFormatInfo internalFormatInfo;
1184 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
1185 {
1186 ASSERT(internalFormatInfo.mTextureSupportFunction != NULL);
1187 ASSERT(internalFormatInfo.mFilterSupportFunction != NULL);
1188 return internalFormatInfo.mTextureSupportFunction(clientVersion, extensions) &&
1189 internalFormatInfo.mFilterSupportFunction(clientVersion, extensions);
1190 }
1191 else
1192 {
1193 return false;
1194 }
1195}
1196
Geoff Lange4a492b2014-06-19 14:14:41 -04001197bool IsSizedInternalFormat(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001198{
1199 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001200 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001201 {
1202 return internalFormatInfo.mPixelBits > 0;
1203 }
1204 else
1205 {
1206 UNREACHABLE();
1207 return false;
1208 }
1209}
1210
Geoff Lange4a492b2014-06-19 14:14:41 -04001211GLenum GetSizedInternalFormat(GLenum format, GLenum type)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001212{
Geoff Lange4a492b2014-06-19 14:14:41 -04001213 const FormatMap &formats = GetFormatMap();
Geoff Langfe28ca02013-06-04 10:10:48 -04001214 FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
1215 return (iter != formats.end()) ? iter->second.mInternalFormat : GL_NONE;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001216}
1217
Geoff Lange4a492b2014-06-19 14:14:41 -04001218GLuint GetPixelBytes(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001219{
1220 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001221 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001222 {
1223 return internalFormatInfo.mPixelBits / 8;
1224 }
1225 else
1226 {
1227 UNREACHABLE();
1228 return 0;
1229 }
1230}
1231
Geoff Lange4a492b2014-06-19 14:14:41 -04001232GLuint GetAlphaBits(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001233{
1234 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001235 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001236 {
1237 return internalFormatInfo.mAlphaBits;
1238 }
1239 else
1240 {
1241 UNREACHABLE();
1242 return 0;
1243 }
1244}
1245
Geoff Lange4a492b2014-06-19 14:14:41 -04001246GLuint GetRedBits(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001247{
1248 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001249 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001250 {
1251 return internalFormatInfo.mRedBits;
1252 }
1253 else
1254 {
1255 UNREACHABLE();
1256 return 0;
1257 }
1258}
1259
Geoff Lange4a492b2014-06-19 14:14:41 -04001260GLuint GetGreenBits(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001261{
1262 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001263 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001264 {
1265 return internalFormatInfo.mGreenBits;
1266 }
1267 else
1268 {
1269 UNREACHABLE();
1270 return 0;
1271 }
1272}
1273
Geoff Lange4a492b2014-06-19 14:14:41 -04001274GLuint GetBlueBits(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001275{
1276 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001277 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001278 {
Geoff Lang24159222013-06-05 14:56:32 -04001279 return internalFormatInfo.mBlueBits;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001280 }
1281 else
1282 {
1283 UNREACHABLE();
1284 return 0;
1285 }
1286}
1287
Geoff Lange4a492b2014-06-19 14:14:41 -04001288GLuint GetLuminanceBits(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001289{
1290 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001291 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001292 {
1293 return internalFormatInfo.mLuminanceBits;
1294 }
1295 else
1296 {
1297 UNREACHABLE();
1298 return 0;
1299 }
1300}
1301
Geoff Lange4a492b2014-06-19 14:14:41 -04001302GLuint GetDepthBits(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001303{
1304 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001305 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001306 {
1307 return internalFormatInfo.mDepthBits;
1308 }
1309 else
1310 {
1311 UNREACHABLE();
1312 return 0;
1313 }
1314}
1315
Geoff Lange4a492b2014-06-19 14:14:41 -04001316GLuint GetStencilBits(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001317{
1318 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001319 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001320 {
1321 return internalFormatInfo.mStencilBits;
1322 }
1323 else
1324 {
1325 UNREACHABLE();
1326 return 0;
1327 }
1328}
1329
Geoff Langf23eb282013-07-22 10:52:19 -04001330GLuint GetTypeBytes(GLenum type)
1331{
1332 TypeInfo typeInfo;
1333 if (GetTypeInfo(type, &typeInfo))
1334 {
1335 return typeInfo.mTypeBytes;
1336 }
1337 else
1338 {
1339 UNREACHABLE();
1340 return 0;
1341 }
1342}
1343
1344bool IsSpecialInterpretationType(GLenum type)
1345{
1346 TypeInfo typeInfo;
1347 if (GetTypeInfo(type, &typeInfo))
1348 {
1349 return typeInfo.mSpecialInterpretation;
1350 }
1351 else
1352 {
1353 UNREACHABLE();
1354 return false;
1355 }
1356}
1357
Shannon Woods4d161ba2014-03-17 18:13:30 -04001358bool IsFloatOrFixedComponentType(GLenum type)
1359{
1360 if (type == GL_UNSIGNED_NORMALIZED ||
1361 type == GL_SIGNED_NORMALIZED ||
1362 type == GL_FLOAT)
1363 {
1364 return true;
1365 }
1366 else
1367 {
1368 return false;
1369 }
1370}
1371
Geoff Lange4a492b2014-06-19 14:14:41 -04001372GLenum GetFormat(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001373{
1374 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001375 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001376 {
1377 return internalFormatInfo.mFormat;
1378 }
1379 else
1380 {
1381 UNREACHABLE();
1382 return GL_NONE;
1383 }
1384}
1385
Geoff Lange4a492b2014-06-19 14:14:41 -04001386GLenum GetType(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001387{
1388 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001389 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001390 {
1391 return internalFormatInfo.mType;
1392 }
1393 else
1394 {
1395 UNREACHABLE();
1396 return GL_NONE;
1397 }
1398}
1399
Geoff Lange4a492b2014-06-19 14:14:41 -04001400GLenum GetComponentType(GLenum internalFormat)
shannonwoods@chromium.orge19409b2013-05-30 00:16:15 +00001401{
1402 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001403 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orge19409b2013-05-30 00:16:15 +00001404 {
Geoff Langb2f3d052013-08-13 12:49:27 -04001405 return internalFormatInfo.mComponentType;
shannonwoods@chromium.orge19409b2013-05-30 00:16:15 +00001406 }
1407 else
1408 {
1409 UNREACHABLE();
Nicolas Capens0027fa92014-02-20 14:26:42 -05001410 return GL_NONE;
shannonwoods@chromium.orge19409b2013-05-30 00:16:15 +00001411 }
1412}
1413
Geoff Lange4a492b2014-06-19 14:14:41 -04001414GLuint GetComponentCount(GLenum internalFormat)
Jamie Madill3466a4d2013-09-18 14:36:20 -04001415{
1416 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001417 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
Jamie Madill3466a4d2013-09-18 14:36:20 -04001418 {
1419 return internalFormatInfo.mComponentCount;
1420 }
1421 else
1422 {
1423 UNREACHABLE();
1424 return false;
1425 }
1426}
1427
Geoff Lange4a492b2014-06-19 14:14:41 -04001428GLenum GetColorEncoding(GLenum internalFormat)
shannonwoods@chromium.orge19409b2013-05-30 00:16:15 +00001429{
1430 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001431 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orge19409b2013-05-30 00:16:15 +00001432 {
Geoff Langb2f3d052013-08-13 12:49:27 -04001433 return internalFormatInfo.mColorEncoding;
shannonwoods@chromium.orge81ea502013-05-30 00:16:53 +00001434 }
1435 else
1436 {
1437 UNREACHABLE();
1438 return false;
1439 }
1440}
1441
Geoff Lange4a492b2014-06-19 14:14:41 -04001442GLuint GetRowPitch(GLenum internalFormat, GLenum type, GLsizei width, GLint alignment)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001443{
1444 ASSERT(alignment > 0 && isPow2(alignment));
Geoff Lange4a492b2014-06-19 14:14:41 -04001445 return rx::roundUp(GetBlockSize(internalFormat, type, width, 1), static_cast<GLuint>(alignment));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001446}
1447
Geoff Lange4a492b2014-06-19 14:14:41 -04001448GLuint GetDepthPitch(GLenum internalFormat, GLenum type, GLsizei width, GLsizei height, GLint alignment)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001449{
Geoff Lange4a492b2014-06-19 14:14:41 -04001450 return GetRowPitch(internalFormat, type, width, alignment) * height;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001451}
1452
Geoff Lange4a492b2014-06-19 14:14:41 -04001453GLuint GetBlockSize(GLenum internalFormat, GLenum type, GLsizei width, GLsizei height)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001454{
1455 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001456 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001457 {
Geoff Langb2f3d052013-08-13 12:49:27 -04001458 if (internalFormatInfo.mIsCompressed)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001459 {
1460 GLsizei numBlocksWide = (width + internalFormatInfo.mCompressedBlockWidth - 1) / internalFormatInfo.mCompressedBlockWidth;
1461 GLsizei numBlocksHight = (height + internalFormatInfo.mCompressedBlockHeight - 1) / internalFormatInfo.mCompressedBlockHeight;
1462
1463 return (internalFormatInfo.mPixelBits * numBlocksWide * numBlocksHight) / 8;
1464 }
1465 else
1466 {
1467 TypeInfo typeInfo;
Geoff Lang18591b72013-06-07 12:00:15 -04001468 if (GetTypeInfo(type, &typeInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001469 {
1470 if (typeInfo.mSpecialInterpretation)
1471 {
1472 return typeInfo.mTypeBytes * width * height;
1473 }
1474 else
1475 {
1476 return internalFormatInfo.mComponentCount * typeInfo.mTypeBytes * width * height;
1477 }
1478 }
1479 else
1480 {
1481 UNREACHABLE();
1482 return 0;
1483 }
1484 }
1485 }
1486 else
1487 {
1488 UNREACHABLE();
1489 return 0;
1490 }
1491}
1492
Geoff Lange4a492b2014-06-19 14:14:41 -04001493bool IsFormatCompressed(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001494{
1495 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001496 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001497 {
Geoff Langb2f3d052013-08-13 12:49:27 -04001498 return internalFormatInfo.mIsCompressed;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001499 }
1500 else
1501 {
1502 UNREACHABLE();
1503 return false;
1504 }
1505}
1506
Geoff Lange4a492b2014-06-19 14:14:41 -04001507GLuint GetCompressedBlockWidth(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001508{
1509 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001510 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001511 {
1512 return internalFormatInfo.mCompressedBlockWidth;
1513 }
1514 else
1515 {
1516 UNREACHABLE();
1517 return 0;
1518 }
1519}
1520
Geoff Lange4a492b2014-06-19 14:14:41 -04001521GLuint GetCompressedBlockHeight(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001522{
1523 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001524 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001525 {
1526 return internalFormatInfo.mCompressedBlockHeight;
1527 }
1528 else
1529 {
1530 UNREACHABLE();
1531 return 0;
1532 }
1533}
1534
Geoff Lange4a492b2014-06-19 14:14:41 -04001535const FormatSet &GetAllSizedInternalFormats()
Geoff Langcec35902014-04-16 10:52:36 -04001536{
Geoff Lange4a492b2014-06-19 14:14:41 -04001537 static FormatSet formatSet = BuildAllSizedInternalFormatSet();
Geoff Langcec35902014-04-16 10:52:36 -04001538 return formatSet;
1539}
1540
Geoff Lange4a492b2014-06-19 14:14:41 -04001541ColorWriteFunction GetColorWriteFunction(GLenum format, GLenum type)
Geoff Langfe28ca02013-06-04 10:10:48 -04001542{
Geoff Lange4a492b2014-06-19 14:14:41 -04001543 static const FormatMap &formats = GetFormatMap();
Geoff Langfe28ca02013-06-04 10:10:48 -04001544 FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
1545 return (iter != formats.end()) ? iter->second.mColorWriteFunction : NULL;
1546}
1547
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001548}