blob: 82fced549362f7831157c10f3c7bd481bfe527ad [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 Lange4a492b2014-06-19 14:14:41 -0400420static bool UnimplementedSupport(GLuint clientVersion, const Extensions &)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000421{
422 UNIMPLEMENTED();
423 return false;
424}
425
Geoff Lange4a492b2014-06-19 14:14:41 -0400426static bool NeverSupported(GLuint clientVersion, const Extensions &)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000427{
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000428 return false;
429}
430
Geoff Lange4a492b2014-06-19 14:14:41 -0400431template <GLuint minCoreGLVersion>
432static bool RequireESVersion(GLuint clientVersion, const Extensions &)
433{
434 return clientVersion >= minCoreGLVersion;
435}
436
Geoff Langcec35902014-04-16 10:52:36 -0400437// Pointer to a boolean memeber of the Extensions struct
438typedef bool(Extensions::*ExtensionBool);
439
440// Check support for a single extension
441template <ExtensionBool bool1>
Geoff Lange4a492b2014-06-19 14:14:41 -0400442static bool RequireExtension(GLuint, const Extensions & extensions)
Geoff Langcec35902014-04-16 10:52:36 -0400443{
Geoff Lange4a492b2014-06-19 14:14:41 -0400444 return extensions.*bool1;
445}
446
447// Check for a minimum client version or a single extension
448template <GLuint minCoreGLVersion, ExtensionBool bool1>
449static bool RequireESVersionOrExtension(GLuint clientVersion, const Extensions &extensions)
450{
451 return clientVersion >= minCoreGLVersion || extensions.*bool1;
452}
453
454// Check for a minimum client version or two extensions
455template <GLuint minCoreGLVersion, ExtensionBool bool1, ExtensionBool bool2>
456static bool RequireESVersionOrExtensions(GLuint clientVersion, const Extensions &extensions)
457{
458 return clientVersion >= minCoreGLVersion || (extensions.*bool1 || extensions.*bool2);
Geoff Langcec35902014-04-16 10:52:36 -0400459}
460
461// Check support for two extensions
462template <ExtensionBool bool1, ExtensionBool bool2>
Geoff Lange4a492b2014-06-19 14:14:41 -0400463static bool RequireExtensions(GLuint, const Extensions &extensions)
Geoff Langcec35902014-04-16 10:52:36 -0400464{
Geoff Lange4a492b2014-06-19 14:14:41 -0400465 return extensions.*bool1 || extensions.*bool2;
Geoff Langcec35902014-04-16 10:52:36 -0400466}
467
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000468struct InternalFormatInfo
469{
470 GLuint mRedBits;
471 GLuint mGreenBits;
472 GLuint mBlueBits;
473
474 GLuint mLuminanceBits;
475
476 GLuint mAlphaBits;
477 GLuint mSharedBits;
478
479 GLuint mDepthBits;
480 GLuint mStencilBits;
481
482 GLuint mPixelBits;
483
484 GLuint mComponentCount;
485
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000486 GLuint mCompressedBlockWidth;
487 GLuint mCompressedBlockHeight;
488
489 GLenum mFormat;
490 GLenum mType;
491
Geoff Langb2f3d052013-08-13 12:49:27 -0400492 GLenum mComponentType;
493 GLenum mColorEncoding;
shannonwoods@chromium.orge19409b2013-05-30 00:16:15 +0000494
Geoff Langb2f3d052013-08-13 12:49:27 -0400495 bool mIsCompressed;
shannonwoods@chromium.orge81ea502013-05-30 00:16:53 +0000496
Geoff Langcec35902014-04-16 10:52:36 -0400497 SupportCheckFunction mSupportFunction;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000498
499 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 +0000500 mPixelBits(0), mComponentCount(0), mCompressedBlockWidth(0), mCompressedBlockHeight(0), mFormat(GL_NONE), mType(GL_NONE),
Geoff Langcec35902014-04-16 10:52:36 -0400501 mComponentType(GL_NONE), mColorEncoding(GL_NONE), mIsCompressed(false), mSupportFunction(NeverSupported)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000502 {
503 }
504
Geoff Langcec35902014-04-16 10:52:36 -0400505 static InternalFormatInfo UnsizedFormat(GLenum format, SupportCheckFunction supportFunction)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000506 {
507 InternalFormatInfo formatInfo;
508 formatInfo.mFormat = format;
509 formatInfo.mSupportFunction = supportFunction;
510 return formatInfo;
511 }
512
513 static InternalFormatInfo RGBAFormat(GLuint red, GLuint green, GLuint blue, GLuint alpha, GLuint shared,
Geoff Langb2f3d052013-08-13 12:49:27 -0400514 GLenum format, GLenum type, GLenum componentType, bool srgb,
Geoff Langcec35902014-04-16 10:52:36 -0400515 SupportCheckFunction supportFunction)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000516 {
517 InternalFormatInfo formatInfo;
518 formatInfo.mRedBits = red;
519 formatInfo.mGreenBits = green;
520 formatInfo.mBlueBits = blue;
521 formatInfo.mAlphaBits = alpha;
522 formatInfo.mSharedBits = shared;
523 formatInfo.mPixelBits = red + green + blue + alpha + shared;
524 formatInfo.mComponentCount = ((red > 0) ? 1 : 0) + ((green > 0) ? 1 : 0) + ((blue > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
525 formatInfo.mFormat = format;
526 formatInfo.mType = type;
Geoff Langb2f3d052013-08-13 12:49:27 -0400527 formatInfo.mComponentType = componentType;
528 formatInfo.mColorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000529 formatInfo.mSupportFunction = supportFunction;
530 return formatInfo;
531 }
532
Geoff Langb2f3d052013-08-13 12:49:27 -0400533 static InternalFormatInfo LUMAFormat(GLuint luminance, GLuint alpha, GLenum format, GLenum type, GLenum componentType,
Geoff Langcec35902014-04-16 10:52:36 -0400534 SupportCheckFunction supportFunction)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000535 {
536 InternalFormatInfo formatInfo;
537 formatInfo.mLuminanceBits = luminance;
538 formatInfo.mAlphaBits = alpha;
539 formatInfo.mPixelBits = luminance + alpha;
540 formatInfo.mComponentCount = ((luminance > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
541 formatInfo.mFormat = format;
542 formatInfo.mType = type;
Geoff Langb2f3d052013-08-13 12:49:27 -0400543 formatInfo.mComponentType = componentType;
544 formatInfo.mColorEncoding = GL_LINEAR;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000545 formatInfo.mSupportFunction = supportFunction;
546 return formatInfo;
547 }
548
Geoff Lang85ea9ab2013-10-10 13:50:34 -0400549 static InternalFormatInfo DepthStencilFormat(GLuint depthBits, GLuint stencilBits, GLuint unusedBits, GLenum format,
Geoff Langcec35902014-04-16 10:52:36 -0400550 GLenum type, GLenum componentType, SupportCheckFunction supportFunction)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000551 {
552 InternalFormatInfo formatInfo;
Geoff Lang85ea9ab2013-10-10 13:50:34 -0400553 formatInfo.mDepthBits = depthBits;
554 formatInfo.mStencilBits = stencilBits;
555 formatInfo.mPixelBits = depthBits + stencilBits + unusedBits;
556 formatInfo.mComponentCount = ((depthBits > 0) ? 1 : 0) + ((stencilBits > 0) ? 1 : 0);
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000557 formatInfo.mFormat = format;
558 formatInfo.mType = type;
Geoff Langb2f3d052013-08-13 12:49:27 -0400559 formatInfo.mComponentType = componentType;
560 formatInfo.mColorEncoding = GL_LINEAR;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000561 formatInfo.mSupportFunction = supportFunction;
562 return formatInfo;
563 }
564
Geoff Langb2f3d052013-08-13 12:49:27 -0400565 static InternalFormatInfo CompressedFormat(GLuint compressedBlockWidth, GLuint compressedBlockHeight, GLuint compressedBlockSize,
566 GLuint componentCount, GLenum format, GLenum type, bool srgb,
Geoff Langcec35902014-04-16 10:52:36 -0400567 SupportCheckFunction supportFunction)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000568 {
569 InternalFormatInfo formatInfo;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000570 formatInfo.mCompressedBlockWidth = compressedBlockWidth;
571 formatInfo.mCompressedBlockHeight = compressedBlockHeight;
572 formatInfo.mPixelBits = compressedBlockSize;
573 formatInfo.mComponentCount = componentCount;
574 formatInfo.mFormat = format;
575 formatInfo.mType = type;
Geoff Langb2f3d052013-08-13 12:49:27 -0400576 formatInfo.mComponentType = GL_UNSIGNED_NORMALIZED;
577 formatInfo.mColorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
578 formatInfo.mIsCompressed = true;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000579 formatInfo.mSupportFunction = supportFunction;
580 return formatInfo;
581 }
582};
583
Geoff Lang005df412013-10-16 14:12:50 -0400584typedef std::pair<GLenum, InternalFormatInfo> InternalFormatInfoPair;
585typedef std::map<GLenum, InternalFormatInfo> InternalFormatInfoMap;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000586
Geoff Lange4a492b2014-06-19 14:14:41 -0400587static InternalFormatInfoMap BuildInternalFormatInfoMap()
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000588{
589 InternalFormatInfoMap map;
590
591 // From ES 3.0.1 spec, table 3.12
592 map.insert(InternalFormatInfoPair(GL_NONE, InternalFormatInfo()));
593
Geoff Lange4a492b2014-06-19 14:14:41 -0400594 // | Internal format | | R | G | B | A |S | Format | Type | Component type | SRGB | Supported |
595 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>)));
596 map.insert(InternalFormatInfoPair(GL_R8_SNORM, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireESVersion<3> )));
597 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>)));
598 map.insert(InternalFormatInfoPair(GL_RG8_SNORM, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireESVersion<3> )));
599 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>)));
600 map.insert(InternalFormatInfoPair(GL_RGB8_SNORM, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireESVersion<3> )));
601 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> )));
602 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> )));
603 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> )));
604 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>)));
605 map.insert(InternalFormatInfoPair(GL_RGBA8_SNORM, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireESVersion<3> )));
606 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> )));
607 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> )));
608 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>)));
609 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>)));
610 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> )));
611 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> )));
612 map.insert(InternalFormatInfoPair(GL_R8I, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_BYTE, GL_INT, false, RequireESVersion<3> )));
613 map.insert(InternalFormatInfoPair(GL_R8UI, InternalFormatInfo::RGBAFormat( 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireESVersion<3> )));
614 map.insert(InternalFormatInfoPair(GL_R16I, InternalFormatInfo::RGBAFormat(16, 0, 0, 0, 0, GL_RED_INTEGER, GL_SHORT, GL_INT, false, RequireESVersion<3> )));
615 map.insert(InternalFormatInfoPair(GL_R16UI, InternalFormatInfo::RGBAFormat(16, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireESVersion<3> )));
616 map.insert(InternalFormatInfoPair(GL_R32I, InternalFormatInfo::RGBAFormat(32, 0, 0, 0, 0, GL_RED_INTEGER, GL_INT, GL_INT, false, RequireESVersion<3> )));
617 map.insert(InternalFormatInfoPair(GL_R32UI, InternalFormatInfo::RGBAFormat(32, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireESVersion<3> )));
618 map.insert(InternalFormatInfoPair(GL_RG8I, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_BYTE, GL_INT, false, RequireESVersion<3> )));
619 map.insert(InternalFormatInfoPair(GL_RG8UI, InternalFormatInfo::RGBAFormat( 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireESVersion<3> )));
620 map.insert(InternalFormatInfoPair(GL_RG16I, InternalFormatInfo::RGBAFormat(16, 16, 0, 0, 0, GL_RG_INTEGER, GL_SHORT, GL_INT, false, RequireESVersion<3> )));
621 map.insert(InternalFormatInfoPair(GL_RG16UI, InternalFormatInfo::RGBAFormat(16, 16, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireESVersion<3> )));
622 map.insert(InternalFormatInfoPair(GL_RG32I, InternalFormatInfo::RGBAFormat(32, 32, 0, 0, 0, GL_RG_INTEGER, GL_INT, GL_INT, false, RequireESVersion<3> )));
623 map.insert(InternalFormatInfoPair(GL_RG32UI, InternalFormatInfo::RGBAFormat(32, 32, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireESVersion<3> )));
624 map.insert(InternalFormatInfoPair(GL_RGB8I, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_BYTE, GL_INT, false, RequireESVersion<3> )));
625 map.insert(InternalFormatInfoPair(GL_RGB8UI, InternalFormatInfo::RGBAFormat( 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireESVersion<3> )));
626 map.insert(InternalFormatInfoPair(GL_RGB16I, InternalFormatInfo::RGBAFormat(16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_SHORT, GL_INT, false, RequireESVersion<3> )));
627 map.insert(InternalFormatInfoPair(GL_RGB16UI, InternalFormatInfo::RGBAFormat(16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireESVersion<3> )));
628 map.insert(InternalFormatInfoPair(GL_RGB32I, InternalFormatInfo::RGBAFormat(32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_INT, GL_INT, false, RequireESVersion<3> )));
629 map.insert(InternalFormatInfoPair(GL_RGB32UI, InternalFormatInfo::RGBAFormat(32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireESVersion<3> )));
630 map.insert(InternalFormatInfoPair(GL_RGBA8I, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_BYTE, GL_INT, false, RequireESVersion<3> )));
631 map.insert(InternalFormatInfoPair(GL_RGBA8UI, InternalFormatInfo::RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireESVersion<3> )));
632 map.insert(InternalFormatInfoPair(GL_RGBA16I, InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT, GL_INT, false, RequireESVersion<3> )));
633 map.insert(InternalFormatInfoPair(GL_RGBA16UI, InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireESVersion<3> )));
634 map.insert(InternalFormatInfoPair(GL_RGBA32I, InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT, GL_INT, false, RequireESVersion<3> )));
635 map.insert(InternalFormatInfoPair(GL_RGBA32UI, InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireESVersion<3> )));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000636
Geoff Lange4a492b2014-06-19 14:14:41 -0400637 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>)));
638 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>)));
639 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>)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000640
641 // Floating point renderability and filtering is provided by OES_texture_float and OES_texture_half_float
Geoff Lange4a492b2014-06-19 14:14:41 -0400642 // | Internal format | | D |S | Format | Type | Comp | SRGB | Supported |
643 // | | | | | | | type | | |
644 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>)));
645 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>)));
646 map.insert(InternalFormatInfoPair(GL_RGB16F, InternalFormatInfo::RGBAFormat(16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureHalfFloat> )));
647 map.insert(InternalFormatInfoPair(GL_RGBA16F, InternalFormatInfo::RGBAFormat(16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureHalfFloat> )));
648 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> )));
649 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> )));
650 map.insert(InternalFormatInfoPair(GL_RGB32F, InternalFormatInfo::RGBAFormat(32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureFloat> )));
651 map.insert(InternalFormatInfoPair(GL_RGBA32F, InternalFormatInfo::RGBAFormat(32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, RequireESVersionOrExtension<3, &Extensions::textureFloat> )));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000652
653 // Depth stencil formats
Geoff Langcec35902014-04-16 10:52:36 -0400654 // | Internal format | | D |S | X | Format | Type | Component type | Supported |
Geoff Lange4a492b2014-06-19 14:14:41 -0400655 map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16, InternalFormatInfo::DepthStencilFormat(16, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, RequireESVersion<2> )));
656 map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT24, InternalFormatInfo::DepthStencilFormat(24, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireESVersion<3> )));
657 map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32F, InternalFormatInfo::DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, RequireESVersion<3> )));
658 map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES, InternalFormatInfo::DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::depthTextures>)));
659 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>)));
660 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> )));
661 map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8, InternalFormatInfo::DepthStencilFormat( 0, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, RequireESVersion<2> )));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000662
663 // Luminance alpha formats
Geoff Lange4a492b2014-06-19 14:14:41 -0400664 // | Internal format | | L | A | Format | Type | Component type | Supported |
665 map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT, InternalFormatInfo::LUMAFormat( 0, 8, GL_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage> )));
666 map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT, InternalFormatInfo::LUMAFormat( 8, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage> )));
667 map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat( 0, 32, GL_ALPHA, GL_FLOAT, GL_FLOAT, RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat> )));
668 map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT, InternalFormatInfo::LUMAFormat(32, 0, GL_LUMINANCE, GL_FLOAT, GL_FLOAT, RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat> )));
669 map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat( 0, 16, GL_ALPHA, GL_HALF_FLOAT, GL_FLOAT, RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>)));
670 map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT, InternalFormatInfo::LUMAFormat(16, 0, GL_LUMINANCE, GL_HALF_FLOAT, GL_FLOAT, RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>)));
671 map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT, InternalFormatInfo::LUMAFormat( 8, 8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExtension<&Extensions::textureStorage> )));
672 map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, InternalFormatInfo::LUMAFormat(32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_FLOAT, RequireExtensions<&Extensions::textureStorage, &Extensions::textureFloat> )));
673 map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, InternalFormatInfo::LUMAFormat(16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_FLOAT, RequireExtensions<&Extensions::textureStorage, &Extensions::textureHalfFloat>)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000674
675 // Unsized formats
Geoff Lange4a492b2014-06-19 14:14:41 -0400676 // | Internal format | | Format | Supported |
677 map.insert(InternalFormatInfoPair(GL_ALPHA, InternalFormatInfo::UnsizedFormat(GL_ALPHA, RequireESVersion<2> )));
678 map.insert(InternalFormatInfoPair(GL_LUMINANCE, InternalFormatInfo::UnsizedFormat(GL_LUMINANCE, RequireESVersion<2> )));
679 map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA, InternalFormatInfo::UnsizedFormat(GL_LUMINANCE_ALPHA, RequireESVersion<2> )));
680 map.insert(InternalFormatInfoPair(GL_RED, InternalFormatInfo::UnsizedFormat(GL_RED, RequireESVersionOrExtension<3, &Extensions::textureRG> )));
681 map.insert(InternalFormatInfoPair(GL_RG, InternalFormatInfo::UnsizedFormat(GL_RG, RequireESVersionOrExtension<3, &Extensions::textureRG> )));
682 map.insert(InternalFormatInfoPair(GL_RGB, InternalFormatInfo::UnsizedFormat(GL_RGB, RequireESVersion<2> )));
683 map.insert(InternalFormatInfoPair(GL_RGBA, InternalFormatInfo::UnsizedFormat(GL_RGBA, RequireESVersion<2> )));
684 map.insert(InternalFormatInfoPair(GL_RED_INTEGER, InternalFormatInfo::UnsizedFormat(GL_RED_INTEGER, RequireESVersion<3> )));
685 map.insert(InternalFormatInfoPair(GL_RG_INTEGER, InternalFormatInfo::UnsizedFormat(GL_RG_INTEGER, RequireESVersion<3> )));
686 map.insert(InternalFormatInfoPair(GL_RGB_INTEGER, InternalFormatInfo::UnsizedFormat(GL_RGB_INTEGER, RequireESVersion<3> )));
687 map.insert(InternalFormatInfoPair(GL_RGBA_INTEGER, InternalFormatInfo::UnsizedFormat(GL_RGBA_INTEGER, RequireESVersion<3> )));
688 map.insert(InternalFormatInfoPair(GL_BGRA_EXT, InternalFormatInfo::UnsizedFormat(GL_BGRA_EXT, RequireExtension<&Extensions::textureFormatBGRA8888> )));
689 map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT, InternalFormatInfo::UnsizedFormat(GL_DEPTH_COMPONENT, RequireESVersion<2> )));
690 map.insert(InternalFormatInfoPair(GL_DEPTH_STENCIL, InternalFormatInfo::UnsizedFormat(GL_DEPTH_STENCIL, RequireESVersionOrExtension<3, &Extensions::packedDepthStencil>)));
691 map.insert(InternalFormatInfoPair(GL_SRGB_EXT, InternalFormatInfo::UnsizedFormat(GL_RGB, RequireESVersionOrExtension<3, &Extensions::sRGB> )));
692 map.insert(InternalFormatInfoPair(GL_SRGB_ALPHA_EXT, InternalFormatInfo::UnsizedFormat(GL_RGBA, RequireESVersionOrExtension<3, &Extensions::sRGB> )));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000693
694 // Compressed formats, From ES 3.0.1 spec, table 3.16
Geoff Langb2f3d052013-08-13 12:49:27 -0400695 // | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported |
696 map.insert(InternalFormatInfoPair(GL_COMPRESSED_R11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
697 map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_R11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
698 map.insert(InternalFormatInfoPair(GL_COMPRESSED_RG11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
699 map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_RG11_EAC, InternalFormatInfo::CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
700 map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_ETC2, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
701 map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ETC2, InternalFormatInfo::CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE, true, UnimplementedSupport)));
702 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)));
703 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)));
704 map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA8_ETC2_EAC, InternalFormatInfo::CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport)));
705 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)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000706
707 // From GL_EXT_texture_compression_dxt1
Geoff Lange4a492b2014-06-19 14:14:41 -0400708 // | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported |
709 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>)));
710 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>)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000711
712 // From GL_ANGLE_texture_compression_dxt3
Geoff Lange4a492b2014-06-19 14:14:41 -0400713 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>)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000714
715 // From GL_ANGLE_texture_compression_dxt5
Geoff Lange4a492b2014-06-19 14:14:41 -0400716 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>)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000717
718 return map;
719}
720
Geoff Lange4a492b2014-06-19 14:14:41 -0400721static const InternalFormatInfoMap &GetInternalFormatMap()
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000722{
Geoff Lange4a492b2014-06-19 14:14:41 -0400723 static const InternalFormatInfoMap formatMap = BuildInternalFormatInfoMap();
724 return formatMap;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000725}
726
Geoff Lange4a492b2014-06-19 14:14:41 -0400727static bool GetInternalFormatInfo(GLenum internalFormat, InternalFormatInfo *outFormatInfo)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000728{
Geoff Lange4a492b2014-06-19 14:14:41 -0400729 const InternalFormatInfoMap &map = GetInternalFormatMap();
Geoff Langcec35902014-04-16 10:52:36 -0400730 InternalFormatInfoMap::const_iterator iter = map.find(internalFormat);
731 if (iter != map.end())
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000732 {
733 if (outFormatInfo)
734 {
735 *outFormatInfo = iter->second;
736 }
737 return true;
738 }
739 else
740 {
741 return false;
742 }
743}
744
Geoff Lange4a492b2014-06-19 14:14:41 -0400745static FormatSet BuildAllSizedInternalFormatSet()
Geoff Langcec35902014-04-16 10:52:36 -0400746{
747 FormatSet result;
748
Geoff Lange4a492b2014-06-19 14:14:41 -0400749 const InternalFormatInfoMap &formats = GetInternalFormatMap();
Geoff Langcec35902014-04-16 10:52:36 -0400750 for (InternalFormatInfoMap::const_iterator i = formats.begin(); i != formats.end(); i++)
751 {
752 if (i->second.mPixelBits > 0)
753 {
754 result.insert(i->first);
755 }
756 }
757
758 return result;
759}
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000760
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000761typedef std::set<GLenum> TypeSet;
762
Shannon Woods4d161ba2014-03-17 18:13:30 -0400763struct EffectiveInternalFormatInfo
764{
765 GLenum mEffectiveFormat;
766 GLenum mDestFormat;
767 GLuint mMinRedBits;
768 GLuint mMaxRedBits;
769 GLuint mMinGreenBits;
770 GLuint mMaxGreenBits;
771 GLuint mMinBlueBits;
772 GLuint mMaxBlueBits;
773 GLuint mMinAlphaBits;
774 GLuint mMaxAlphaBits;
775
776 EffectiveInternalFormatInfo(GLenum effectiveFormat, GLenum destFormat, GLuint minRedBits, GLuint maxRedBits,
777 GLuint minGreenBits, GLuint maxGreenBits, GLuint minBlueBits, GLuint maxBlueBits,
778 GLuint minAlphaBits, GLuint maxAlphaBits)
779 : mEffectiveFormat(effectiveFormat), mDestFormat(destFormat), mMinRedBits(minRedBits),
780 mMaxRedBits(maxRedBits), mMinGreenBits(minGreenBits), mMaxGreenBits(maxGreenBits),
781 mMinBlueBits(minBlueBits), mMaxBlueBits(maxBlueBits), mMinAlphaBits(minAlphaBits),
782 mMaxAlphaBits(maxAlphaBits) {};
783};
784
785typedef std::vector<EffectiveInternalFormatInfo> EffectiveInternalFormatList;
786
787static EffectiveInternalFormatList BuildSizedEffectiveInternalFormatList()
788{
789 EffectiveInternalFormatList list;
790
791 // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and
792 // linear source buffer component sizes.
793 // | Source channel min/max sizes |
794 // Effective Internal Format | N/A | R | G | B | A |
795 list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT, GL_NONE, 0, 0, 0, 0, 0, 0, 1, 8));
796 list.push_back(EffectiveInternalFormatInfo(GL_R8, GL_NONE, 1, 8, 0, 0, 0, 0, 0, 0));
797 list.push_back(EffectiveInternalFormatInfo(GL_RG8, GL_NONE, 1, 8, 1, 8, 0, 0, 0, 0));
798 list.push_back(EffectiveInternalFormatInfo(GL_RGB565, GL_NONE, 1, 5, 1, 6, 1, 5, 0, 0));
799 list.push_back(EffectiveInternalFormatInfo(GL_RGB8, GL_NONE, 6, 8, 7, 8, 6, 8, 0, 0));
800 list.push_back(EffectiveInternalFormatInfo(GL_RGBA4, GL_NONE, 1, 4, 1, 4, 1, 4, 1, 4));
801 list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1, GL_NONE, 5, 5, 5, 5, 5, 5, 1, 1));
802 list.push_back(EffectiveInternalFormatInfo(GL_RGBA8, GL_NONE, 5, 8, 5, 8, 5, 8, 2, 8));
803 list.push_back(EffectiveInternalFormatInfo(GL_RGB10_A2, GL_NONE, 9, 10, 9, 10, 9, 10, 2, 2));
804
805 return list;
806}
807
808
809static EffectiveInternalFormatList BuildUnsizedEffectiveInternalFormatList()
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 | Dest Format | R | G | B | A |
817 list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT, GL_ALPHA, 0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX, 1, 8));
818 list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_EXT, GL_LUMINANCE, 1, 8, 0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX));
819 list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, 1, 8, 0, UINT_MAX, 0, UINT_MAX, 1, 8));
820 list.push_back(EffectiveInternalFormatInfo(GL_RGB565, GL_RGB, 1, 5, 1, 6, 1, 5, 0, UINT_MAX));
821 list.push_back(EffectiveInternalFormatInfo(GL_RGB8, GL_RGB, 6, 8, 7, 8, 6, 8, 0, UINT_MAX));
822 list.push_back(EffectiveInternalFormatInfo(GL_RGBA4, GL_RGBA, 1, 4, 1, 4, 1, 4, 1, 4));
823 list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1, GL_RGBA, 5, 5, 5, 5, 5, 5, 1, 1));
824 list.push_back(EffectiveInternalFormatInfo(GL_RGBA8, GL_RGBA, 5, 8, 5, 8, 5, 8, 5, 8));
825
826 return list;
827}
828
829static bool GetEffectiveInternalFormat(const InternalFormatInfo &srcFormat, const InternalFormatInfo &destFormat,
Geoff Lange4a492b2014-06-19 14:14:41 -0400830 GLenum *outEffectiveFormat)
Shannon Woods4d161ba2014-03-17 18:13:30 -0400831{
832 const EffectiveInternalFormatList *list = NULL;
833 GLenum targetFormat = GL_NONE;
834
Geoff Lange4a492b2014-06-19 14:14:41 -0400835 if (gl::IsSizedInternalFormat(destFormat.mFormat))
Shannon Woods4d161ba2014-03-17 18:13:30 -0400836 {
837 static const EffectiveInternalFormatList sizedList = BuildSizedEffectiveInternalFormatList();
838 list = &sizedList;
839 }
840 else
841 {
842 static const EffectiveInternalFormatList unsizedList = BuildUnsizedEffectiveInternalFormatList();
843 list = &unsizedList;
844 targetFormat = destFormat.mFormat;
845 }
846
847 for (size_t curFormat = 0; curFormat < list->size(); ++curFormat)
848 {
849 const EffectiveInternalFormatInfo& formatInfo = list->at(curFormat);
850 if ((formatInfo.mDestFormat == targetFormat) &&
851 (formatInfo.mMinRedBits <= srcFormat.mRedBits && formatInfo.mMaxRedBits >= srcFormat.mRedBits) &&
852 (formatInfo.mMinGreenBits <= srcFormat.mGreenBits && formatInfo.mMaxGreenBits >= srcFormat.mGreenBits) &&
853 (formatInfo.mMinBlueBits <= srcFormat.mBlueBits && formatInfo.mMaxBlueBits >= srcFormat.mBlueBits) &&
854 (formatInfo.mMinAlphaBits <= srcFormat.mAlphaBits && formatInfo.mMaxAlphaBits >= srcFormat.mAlphaBits))
855 {
856 *outEffectiveFormat = formatInfo.mEffectiveFormat;
857 return true;
858 }
859 }
860
861 return false;
862}
863
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000864struct CopyConversion
865{
866 GLenum mTextureFormat;
867 GLenum mFramebufferFormat;
868
869 CopyConversion(GLenum textureFormat, GLenum framebufferFormat)
870 : mTextureFormat(textureFormat), mFramebufferFormat(framebufferFormat) { }
871
872 bool operator<(const CopyConversion& other) const
873 {
874 return memcmp(this, &other, sizeof(CopyConversion)) < 0;
875 }
876};
877
878typedef std::set<CopyConversion> CopyConversionSet;
879
Geoff Lang18591b72013-06-07 12:00:15 -0400880static CopyConversionSet BuildValidES3CopyTexImageCombinations()
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000881{
882 CopyConversionSet set;
883
884 // From ES 3.0.1 spec, table 3.15
885 set.insert(CopyConversion(GL_ALPHA, GL_RGBA));
886 set.insert(CopyConversion(GL_LUMINANCE, GL_RED));
887 set.insert(CopyConversion(GL_LUMINANCE, GL_RG));
888 set.insert(CopyConversion(GL_LUMINANCE, GL_RGB));
889 set.insert(CopyConversion(GL_LUMINANCE, GL_RGBA));
890 set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_RGBA));
891 set.insert(CopyConversion(GL_RED, GL_RED));
892 set.insert(CopyConversion(GL_RED, GL_RG));
893 set.insert(CopyConversion(GL_RED, GL_RGB));
894 set.insert(CopyConversion(GL_RED, GL_RGBA));
895 set.insert(CopyConversion(GL_RG, GL_RG));
896 set.insert(CopyConversion(GL_RG, GL_RGB));
897 set.insert(CopyConversion(GL_RG, GL_RGBA));
898 set.insert(CopyConversion(GL_RGB, GL_RGB));
899 set.insert(CopyConversion(GL_RGB, GL_RGBA));
900 set.insert(CopyConversion(GL_RGBA, GL_RGBA));
901
Jamie Madillb70e5f72013-07-10 16:57:52 -0400902 // Necessary for ANGLE back-buffers
903 set.insert(CopyConversion(GL_ALPHA, GL_BGRA_EXT));
904 set.insert(CopyConversion(GL_LUMINANCE, GL_BGRA_EXT));
905 set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_BGRA_EXT));
906 set.insert(CopyConversion(GL_RED, GL_BGRA_EXT));
907 set.insert(CopyConversion(GL_RG, GL_BGRA_EXT));
908 set.insert(CopyConversion(GL_RGB, GL_BGRA_EXT));
909 set.insert(CopyConversion(GL_RGBA, GL_BGRA_EXT));
910
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +0000911 set.insert(CopyConversion(GL_RED_INTEGER, GL_RED_INTEGER));
912 set.insert(CopyConversion(GL_RED_INTEGER, GL_RG_INTEGER));
913 set.insert(CopyConversion(GL_RED_INTEGER, GL_RGB_INTEGER));
914 set.insert(CopyConversion(GL_RED_INTEGER, GL_RGBA_INTEGER));
915 set.insert(CopyConversion(GL_RG_INTEGER, GL_RG_INTEGER));
916 set.insert(CopyConversion(GL_RG_INTEGER, GL_RGB_INTEGER));
917 set.insert(CopyConversion(GL_RG_INTEGER, GL_RGBA_INTEGER));
918 set.insert(CopyConversion(GL_RGB_INTEGER, GL_RGB_INTEGER));
919 set.insert(CopyConversion(GL_RGB_INTEGER, GL_RGBA_INTEGER));
920 set.insert(CopyConversion(GL_RGBA_INTEGER, GL_RGBA_INTEGER));
921
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000922 return set;
923}
924
Geoff Langcec35902014-04-16 10:52:36 -0400925bool IsValidInternalFormat(GLenum internalFormat, const Extensions &extensions, GLuint clientVersion)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000926{
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000927 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -0400928 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000929 {
930 ASSERT(internalFormatInfo.mSupportFunction != NULL);
Geoff Lange4a492b2014-06-19 14:14:41 -0400931 return internalFormatInfo.mSupportFunction(clientVersion, extensions);
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000932 }
933 else
934 {
935 return false;
936 }
937}
938
Geoff Lange4a492b2014-06-19 14:14:41 -0400939bool IsValidFormat(GLenum format, const Extensions &extensions, GLuint clientVersion)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000940{
Geoff Lange4a492b2014-06-19 14:14:41 -0400941 const InternalFormatInfoMap &internalFormats = GetInternalFormatMap();
942 for (InternalFormatInfoMap::const_iterator i = internalFormats.begin(); i != internalFormats.end(); i++)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000943 {
Geoff Lange4a492b2014-06-19 14:14:41 -0400944 if (i->second.mFormat == format && i->second.mSupportFunction(clientVersion, extensions))
945 {
946 return true;
947 }
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000948 }
Geoff Lange4a492b2014-06-19 14:14:41 -0400949
950 return false;
951}
952
953bool IsValidType(GLenum type, const Extensions &extensions, GLuint clientVersion)
954{
955 const InternalFormatInfoMap &internalFormats = GetInternalFormatMap();
956 for (InternalFormatInfoMap::const_iterator i = internalFormats.begin(); i != internalFormats.end(); i++)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000957 {
Geoff Lange4a492b2014-06-19 14:14:41 -0400958 if (i->second.mType == type && i->second.mSupportFunction(clientVersion, extensions))
959 {
960 return true;
961 }
962 }
963
964 return false;
965}
966
967bool IsValidFormatCombination(GLenum internalFormat, GLenum format, GLenum type, const Extensions &extensions, GLuint clientVersion)
968{
969 InternalFormatInfo internalFormatInfo;
970 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
971 {
972 if (!internalFormatInfo.mSupportFunction(clientVersion, extensions))
973 {
974 return false;
975 }
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000976 }
977 else
978 {
979 UNREACHABLE();
980 return false;
981 }
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000982
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000983 if (clientVersion == 2)
984 {
Geoff Lange4a492b2014-06-19 14:14:41 -0400985 static const FormatMap &formats = GetFormatMap();
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000986 FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
Geoff Langfe28ca02013-06-04 10:10:48 -0400987 return (iter != formats.end()) && ((internalFormat == (GLint)type) || (internalFormat == iter->second.mInternalFormat));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000988 }
989 else if (clientVersion == 3)
990 {
Geoff Lang18591b72013-06-07 12:00:15 -0400991 static const ES3FormatSet &formats = GetES3FormatSet();
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000992 return formats.find(FormatInfo(internalFormat, format, type)) != formats.end();
993 }
994 else
995 {
996 UNREACHABLE();
997 return false;
998 }
999}
1000
Shannon Woods4d161ba2014-03-17 18:13:30 -04001001bool IsValidCopyTexImageCombination(GLenum textureInternalFormat, GLenum frameBufferInternalFormat, GLuint readBufferHandle, GLuint clientVersion)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001002{
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +00001003 InternalFormatInfo textureInternalFormatInfo;
1004 InternalFormatInfo framebufferInternalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001005 if (GetInternalFormatInfo(textureInternalFormat, &textureInternalFormatInfo) &&
1006 GetInternalFormatInfo(frameBufferInternalFormat, &framebufferInternalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001007 {
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +00001008 if (clientVersion == 2)
1009 {
1010 UNIMPLEMENTED();
1011 return false;
1012 }
1013 else if (clientVersion == 3)
1014 {
Geoff Lang18591b72013-06-07 12:00:15 -04001015 static const CopyConversionSet conversionSet = BuildValidES3CopyTexImageCombinations();
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +00001016 const CopyConversion conversion = CopyConversion(textureInternalFormatInfo.mFormat,
1017 framebufferInternalFormatInfo.mFormat);
1018 if (conversionSet.find(conversion) != conversionSet.end())
1019 {
Shannon Woods4d161ba2014-03-17 18:13:30 -04001020 // Section 3.8.5 of the GLES 3.0.3 spec states that source and destination formats
1021 // must both be signed, unsigned, or fixed point and both source and destinations
1022 // must be either both SRGB or both not SRGB. EXT_color_buffer_float adds allowed
1023 // conversion between fixed and floating point.
shannonwoods@chromium.org96c62912013-05-30 00:17:00 +00001024
Geoff Langb2f3d052013-08-13 12:49:27 -04001025 if ((textureInternalFormatInfo.mColorEncoding == GL_SRGB) != (framebufferInternalFormatInfo.mColorEncoding == GL_SRGB))
shannonwoods@chromium.org96c62912013-05-30 00:17:00 +00001026 {
1027 return false;
1028 }
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +00001029
Shannon Woods4d161ba2014-03-17 18:13:30 -04001030 if (((textureInternalFormatInfo.mComponentType == GL_INT) != (framebufferInternalFormatInfo.mComponentType == GL_INT)) ||
1031 ((textureInternalFormatInfo.mComponentType == GL_UNSIGNED_INT) != (framebufferInternalFormatInfo.mComponentType == GL_UNSIGNED_INT)))
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +00001032 {
Shannon Woods4d161ba2014-03-17 18:13:30 -04001033 return false;
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +00001034 }
1035
Shannon Woods4d161ba2014-03-17 18:13:30 -04001036 if (gl::IsFloatOrFixedComponentType(textureInternalFormatInfo.mComponentType) &&
1037 !gl::IsFloatOrFixedComponentType(framebufferInternalFormatInfo.mComponentType))
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +00001038 {
Shannon Woods4d161ba2014-03-17 18:13:30 -04001039 return false;
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +00001040 }
Shannon Woods4d161ba2014-03-17 18:13:30 -04001041
1042 // GLES specification 3.0.3, sec 3.8.5, pg 139-140:
1043 // The effective internal format of the source buffer is determined with the following rules applied in order:
1044 // * If the source buffer is a texture or renderbuffer that was created with a sized internal format then the
1045 // effective internal format is the source buffer's sized internal format.
1046 // * If the source buffer is a texture that was created with an unsized base internal format, then the
1047 // effective internal format is the source image array's effective internal format, as specified by table
1048 // 3.12, which is determined from the <format> and <type> that were used when the source image array was
1049 // specified by TexImage*.
1050 // * Otherwise the effective internal format is determined by the row in table 3.17 or 3.18 where
1051 // Destination Internal Format matches internalformat and where the [source channel sizes] are consistent
1052 // with the values of the source buffer's [channel sizes]. Table 3.17 is used if the
1053 // FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the FRAMEBUFFER_ATTACHMENT_ENCODING
1054 // is SRGB.
1055 InternalFormatInfo sourceEffectiveFormat;
1056 if (readBufferHandle != 0)
1057 {
1058 // Not the default framebuffer, therefore the read buffer must be a user-created texture or renderbuffer
Geoff Lange4a492b2014-06-19 14:14:41 -04001059 if (gl::IsSizedInternalFormat(framebufferInternalFormatInfo.mFormat))
Shannon Woods4d161ba2014-03-17 18:13:30 -04001060 {
1061 sourceEffectiveFormat = framebufferInternalFormatInfo;
1062 }
1063 else
1064 {
1065 // Renderbuffers cannot be created with an unsized internal format, so this must be an unsized-format
1066 // texture. We can use the same table we use when creating textures to get its effective sized format.
1067 GLenum effectiveFormat = gl::GetSizedInternalFormat(framebufferInternalFormatInfo.mFormat,
Geoff Lange4a492b2014-06-19 14:14:41 -04001068 framebufferInternalFormatInfo.mType);
1069 gl::GetInternalFormatInfo(effectiveFormat, &sourceEffectiveFormat);
Shannon Woods4d161ba2014-03-17 18:13:30 -04001070 }
1071 }
1072 else
1073 {
1074 // The effective internal format must be derived from the source framebuffer's channel sizes.
1075 // This is done in GetEffectiveInternalFormat for linear buffers (table 3.17)
1076 if (framebufferInternalFormatInfo.mColorEncoding == GL_LINEAR)
1077 {
1078 GLenum effectiveFormat;
Geoff Lange4a492b2014-06-19 14:14:41 -04001079 if (GetEffectiveInternalFormat(framebufferInternalFormatInfo, textureInternalFormatInfo, &effectiveFormat))
Shannon Woods4d161ba2014-03-17 18:13:30 -04001080 {
Geoff Lange4a492b2014-06-19 14:14:41 -04001081 gl::GetInternalFormatInfo(effectiveFormat, &sourceEffectiveFormat);
Shannon Woods4d161ba2014-03-17 18:13:30 -04001082 }
1083 else
1084 {
1085 return false;
1086 }
1087 }
1088 else if (framebufferInternalFormatInfo.mColorEncoding == GL_SRGB)
1089 {
1090 // SRGB buffers can only be copied to sized format destinations according to table 3.18
Geoff Lange4a492b2014-06-19 14:14:41 -04001091 if (gl::IsSizedInternalFormat(textureInternalFormat) &&
Shannon Woods4d161ba2014-03-17 18:13:30 -04001092 (framebufferInternalFormatInfo.mRedBits >= 1 && framebufferInternalFormatInfo.mRedBits <= 8) &&
1093 (framebufferInternalFormatInfo.mGreenBits >= 1 && framebufferInternalFormatInfo.mGreenBits <= 8) &&
1094 (framebufferInternalFormatInfo.mBlueBits >= 1 && framebufferInternalFormatInfo.mBlueBits <= 8) &&
1095 (framebufferInternalFormatInfo.mAlphaBits >= 1 && framebufferInternalFormatInfo.mAlphaBits <= 8))
1096 {
Geoff Lange4a492b2014-06-19 14:14:41 -04001097 gl::GetInternalFormatInfo(GL_SRGB8_ALPHA8, &sourceEffectiveFormat);
Shannon Woods4d161ba2014-03-17 18:13:30 -04001098 }
1099 else
1100 {
1101 return false;
1102 }
1103 }
1104 else
1105 {
1106 UNREACHABLE();
1107 }
1108 }
1109
Geoff Lange4a492b2014-06-19 14:14:41 -04001110 if (gl::IsSizedInternalFormat(textureInternalFormatInfo.mFormat))
Shannon Woods4d161ba2014-03-17 18:13:30 -04001111 {
1112 // Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination format is sized,
1113 // component sizes of the source and destination formats must exactly match
1114 if (textureInternalFormatInfo.mRedBits != sourceEffectiveFormat.mRedBits ||
1115 textureInternalFormatInfo.mGreenBits != sourceEffectiveFormat.mGreenBits ||
1116 textureInternalFormatInfo.mBlueBits != sourceEffectiveFormat.mBlueBits ||
1117 textureInternalFormatInfo.mAlphaBits != sourceEffectiveFormat.mAlphaBits)
1118 {
1119 return false;
1120 }
1121 }
1122
1123
1124 return true; // A conversion function exists, and no rule in the specification has precluded conversion
1125 // between these formats.
shannonwoods@chromium.orgffab47d2013-05-30 00:16:22 +00001126 }
1127
1128 return false;
1129 }
1130 else
1131 {
1132 UNREACHABLE();
1133 return false;
1134 }
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001135 }
1136 else
1137 {
1138 UNREACHABLE();
1139 return false;
1140 }
1141}
1142
Geoff Lange4a492b2014-06-19 14:14:41 -04001143bool IsSizedInternalFormat(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001144{
1145 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001146 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001147 {
1148 return internalFormatInfo.mPixelBits > 0;
1149 }
1150 else
1151 {
1152 UNREACHABLE();
1153 return false;
1154 }
1155}
1156
Geoff Lange4a492b2014-06-19 14:14:41 -04001157GLenum GetSizedInternalFormat(GLenum format, GLenum type)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001158{
Geoff Lange4a492b2014-06-19 14:14:41 -04001159 const FormatMap &formats = GetFormatMap();
Geoff Langfe28ca02013-06-04 10:10:48 -04001160 FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
1161 return (iter != formats.end()) ? iter->second.mInternalFormat : GL_NONE;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001162}
1163
Geoff Lange4a492b2014-06-19 14:14:41 -04001164GLuint GetPixelBytes(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001165{
1166 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001167 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001168 {
1169 return internalFormatInfo.mPixelBits / 8;
1170 }
1171 else
1172 {
1173 UNREACHABLE();
1174 return 0;
1175 }
1176}
1177
Geoff Lange4a492b2014-06-19 14:14:41 -04001178GLuint GetAlphaBits(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001179{
1180 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001181 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001182 {
1183 return internalFormatInfo.mAlphaBits;
1184 }
1185 else
1186 {
1187 UNREACHABLE();
1188 return 0;
1189 }
1190}
1191
Geoff Lange4a492b2014-06-19 14:14:41 -04001192GLuint GetRedBits(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001193{
1194 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001195 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001196 {
1197 return internalFormatInfo.mRedBits;
1198 }
1199 else
1200 {
1201 UNREACHABLE();
1202 return 0;
1203 }
1204}
1205
Geoff Lange4a492b2014-06-19 14:14:41 -04001206GLuint GetGreenBits(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001207{
1208 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001209 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001210 {
1211 return internalFormatInfo.mGreenBits;
1212 }
1213 else
1214 {
1215 UNREACHABLE();
1216 return 0;
1217 }
1218}
1219
Geoff Lange4a492b2014-06-19 14:14:41 -04001220GLuint GetBlueBits(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001221{
1222 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001223 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001224 {
Geoff Lang24159222013-06-05 14:56:32 -04001225 return internalFormatInfo.mBlueBits;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001226 }
1227 else
1228 {
1229 UNREACHABLE();
1230 return 0;
1231 }
1232}
1233
Geoff Lange4a492b2014-06-19 14:14:41 -04001234GLuint GetLuminanceBits(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001235{
1236 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001237 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001238 {
1239 return internalFormatInfo.mLuminanceBits;
1240 }
1241 else
1242 {
1243 UNREACHABLE();
1244 return 0;
1245 }
1246}
1247
Geoff Lange4a492b2014-06-19 14:14:41 -04001248GLuint GetDepthBits(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001249{
1250 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001251 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001252 {
1253 return internalFormatInfo.mDepthBits;
1254 }
1255 else
1256 {
1257 UNREACHABLE();
1258 return 0;
1259 }
1260}
1261
Geoff Lange4a492b2014-06-19 14:14:41 -04001262GLuint GetStencilBits(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001263{
1264 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001265 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001266 {
1267 return internalFormatInfo.mStencilBits;
1268 }
1269 else
1270 {
1271 UNREACHABLE();
1272 return 0;
1273 }
1274}
1275
Geoff Langf23eb282013-07-22 10:52:19 -04001276GLuint GetTypeBytes(GLenum type)
1277{
1278 TypeInfo typeInfo;
1279 if (GetTypeInfo(type, &typeInfo))
1280 {
1281 return typeInfo.mTypeBytes;
1282 }
1283 else
1284 {
1285 UNREACHABLE();
1286 return 0;
1287 }
1288}
1289
1290bool IsSpecialInterpretationType(GLenum type)
1291{
1292 TypeInfo typeInfo;
1293 if (GetTypeInfo(type, &typeInfo))
1294 {
1295 return typeInfo.mSpecialInterpretation;
1296 }
1297 else
1298 {
1299 UNREACHABLE();
1300 return false;
1301 }
1302}
1303
Shannon Woods4d161ba2014-03-17 18:13:30 -04001304bool IsFloatOrFixedComponentType(GLenum type)
1305{
1306 if (type == GL_UNSIGNED_NORMALIZED ||
1307 type == GL_SIGNED_NORMALIZED ||
1308 type == GL_FLOAT)
1309 {
1310 return true;
1311 }
1312 else
1313 {
1314 return false;
1315 }
1316}
1317
Geoff Lange4a492b2014-06-19 14:14:41 -04001318GLenum GetFormat(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001319{
1320 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001321 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001322 {
1323 return internalFormatInfo.mFormat;
1324 }
1325 else
1326 {
1327 UNREACHABLE();
1328 return GL_NONE;
1329 }
1330}
1331
Geoff Lange4a492b2014-06-19 14:14:41 -04001332GLenum GetType(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001333{
1334 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001335 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001336 {
1337 return internalFormatInfo.mType;
1338 }
1339 else
1340 {
1341 UNREACHABLE();
1342 return GL_NONE;
1343 }
1344}
1345
Geoff Lange4a492b2014-06-19 14:14:41 -04001346GLenum GetComponentType(GLenum internalFormat)
shannonwoods@chromium.orge19409b2013-05-30 00:16:15 +00001347{
1348 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001349 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orge19409b2013-05-30 00:16:15 +00001350 {
Geoff Langb2f3d052013-08-13 12:49:27 -04001351 return internalFormatInfo.mComponentType;
shannonwoods@chromium.orge19409b2013-05-30 00:16:15 +00001352 }
1353 else
1354 {
1355 UNREACHABLE();
Nicolas Capens0027fa92014-02-20 14:26:42 -05001356 return GL_NONE;
shannonwoods@chromium.orge19409b2013-05-30 00:16:15 +00001357 }
1358}
1359
Geoff Lange4a492b2014-06-19 14:14:41 -04001360GLuint GetComponentCount(GLenum internalFormat)
Jamie Madill3466a4d2013-09-18 14:36:20 -04001361{
1362 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001363 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
Jamie Madill3466a4d2013-09-18 14:36:20 -04001364 {
1365 return internalFormatInfo.mComponentCount;
1366 }
1367 else
1368 {
1369 UNREACHABLE();
1370 return false;
1371 }
1372}
1373
Geoff Lange4a492b2014-06-19 14:14:41 -04001374GLenum GetColorEncoding(GLenum internalFormat)
shannonwoods@chromium.orge19409b2013-05-30 00:16:15 +00001375{
1376 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001377 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orge19409b2013-05-30 00:16:15 +00001378 {
Geoff Langb2f3d052013-08-13 12:49:27 -04001379 return internalFormatInfo.mColorEncoding;
shannonwoods@chromium.orge81ea502013-05-30 00:16:53 +00001380 }
1381 else
1382 {
1383 UNREACHABLE();
1384 return false;
1385 }
1386}
1387
Geoff Lange4a492b2014-06-19 14:14:41 -04001388GLuint GetRowPitch(GLenum internalFormat, GLenum type, GLsizei width, GLint alignment)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001389{
1390 ASSERT(alignment > 0 && isPow2(alignment));
Geoff Lange4a492b2014-06-19 14:14:41 -04001391 return rx::roundUp(GetBlockSize(internalFormat, type, width, 1), static_cast<GLuint>(alignment));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001392}
1393
Geoff Lange4a492b2014-06-19 14:14:41 -04001394GLuint GetDepthPitch(GLenum internalFormat, GLenum type, GLsizei width, GLsizei height, GLint alignment)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001395{
Geoff Lange4a492b2014-06-19 14:14:41 -04001396 return GetRowPitch(internalFormat, type, width, alignment) * height;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001397}
1398
Geoff Lange4a492b2014-06-19 14:14:41 -04001399GLuint GetBlockSize(GLenum internalFormat, GLenum type, GLsizei width, GLsizei height)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001400{
1401 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001402 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001403 {
Geoff Langb2f3d052013-08-13 12:49:27 -04001404 if (internalFormatInfo.mIsCompressed)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001405 {
1406 GLsizei numBlocksWide = (width + internalFormatInfo.mCompressedBlockWidth - 1) / internalFormatInfo.mCompressedBlockWidth;
1407 GLsizei numBlocksHight = (height + internalFormatInfo.mCompressedBlockHeight - 1) / internalFormatInfo.mCompressedBlockHeight;
1408
1409 return (internalFormatInfo.mPixelBits * numBlocksWide * numBlocksHight) / 8;
1410 }
1411 else
1412 {
1413 TypeInfo typeInfo;
Geoff Lang18591b72013-06-07 12:00:15 -04001414 if (GetTypeInfo(type, &typeInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001415 {
1416 if (typeInfo.mSpecialInterpretation)
1417 {
1418 return typeInfo.mTypeBytes * width * height;
1419 }
1420 else
1421 {
1422 return internalFormatInfo.mComponentCount * typeInfo.mTypeBytes * width * height;
1423 }
1424 }
1425 else
1426 {
1427 UNREACHABLE();
1428 return 0;
1429 }
1430 }
1431 }
1432 else
1433 {
1434 UNREACHABLE();
1435 return 0;
1436 }
1437}
1438
Geoff Lange4a492b2014-06-19 14:14:41 -04001439bool IsFormatCompressed(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001440{
1441 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001442 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001443 {
Geoff Langb2f3d052013-08-13 12:49:27 -04001444 return internalFormatInfo.mIsCompressed;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001445 }
1446 else
1447 {
1448 UNREACHABLE();
1449 return false;
1450 }
1451}
1452
Geoff Lange4a492b2014-06-19 14:14:41 -04001453GLuint GetCompressedBlockWidth(GLenum internalFormat)
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 {
1458 return internalFormatInfo.mCompressedBlockWidth;
1459 }
1460 else
1461 {
1462 UNREACHABLE();
1463 return 0;
1464 }
1465}
1466
Geoff Lange4a492b2014-06-19 14:14:41 -04001467GLuint GetCompressedBlockHeight(GLenum internalFormat)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001468{
1469 InternalFormatInfo internalFormatInfo;
Geoff Lange4a492b2014-06-19 14:14:41 -04001470 if (GetInternalFormatInfo(internalFormat, &internalFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001471 {
1472 return internalFormatInfo.mCompressedBlockHeight;
1473 }
1474 else
1475 {
1476 UNREACHABLE();
1477 return 0;
1478 }
1479}
1480
Geoff Lange4a492b2014-06-19 14:14:41 -04001481const FormatSet &GetAllSizedInternalFormats()
Geoff Langcec35902014-04-16 10:52:36 -04001482{
Geoff Lange4a492b2014-06-19 14:14:41 -04001483 static FormatSet formatSet = BuildAllSizedInternalFormatSet();
Geoff Langcec35902014-04-16 10:52:36 -04001484 return formatSet;
1485}
1486
Geoff Lange4a492b2014-06-19 14:14:41 -04001487ColorWriteFunction GetColorWriteFunction(GLenum format, GLenum type)
Geoff Langfe28ca02013-06-04 10:10:48 -04001488{
Geoff Lange4a492b2014-06-19 14:14:41 -04001489 static const FormatMap &formats = GetFormatMap();
Geoff Langfe28ca02013-06-04 10:10:48 -04001490 FormatMap::const_iterator iter = formats.find(FormatTypePair(format, type));
1491 return (iter != formats.end()) ? iter->second.mColorWriteFunction : NULL;
1492}
1493
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001494}