1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "WebGLFormats.h"
10 #include "mozilla/gfx/Logging.h"
11 #include "mozilla/StaticMutex.h"
16 const char* ToString(const ComponentType type
) {
18 case ComponentType::Int
:
20 case ComponentType::UInt
:
22 case ComponentType::NormInt
:
24 case ComponentType::NormUInt
:
26 case ComponentType::Float
:
29 MOZ_CRASH("pacify gcc6 warning");
32 static TextureBaseType
ToBaseType(const ComponentType type
) {
34 case ComponentType::Int
:
35 return TextureBaseType::Int
;
36 case ComponentType::UInt
:
37 return TextureBaseType::UInt
;
38 case ComponentType::NormInt
:
39 case ComponentType::NormUInt
:
40 case ComponentType::Float
:
41 // case ComponentType::Depth:
42 return TextureBaseType::Float
;
44 MOZ_CRASH("pacify gcc6 warning");
47 const char* ToString(const TextureBaseType x
) {
49 case webgl::TextureBaseType::Float
:
51 case webgl::TextureBaseType::Int
:
53 case webgl::TextureBaseType::UInt
:
56 MOZ_CRASH("pacify gcc6 warning");
61 template <typename K
, typename V
, typename K2
, typename V2
>
62 static inline void AlwaysInsert(std::map
<K
, V
>& dest
, const K2
& key
,
64 auto res
= dest
.insert({key
, val
});
65 bool didInsert
= res
.second
;
66 MOZ_ALWAYS_TRUE(didInsert
);
69 template <typename K
, typename V
, typename K2
>
70 static inline V
* FindOrNull(const std::map
<K
, V
*>& dest
, const K2
& key
) {
71 auto itr
= dest
.find(key
);
72 if (itr
== dest
.end()) return nullptr;
77 // Returns a pointer to the in-place value for `key`.
78 template <typename K
, typename V
, typename K2
>
79 static inline V
* FindPtrOrNull(std::map
<K
, V
>& dest
, const K2
& key
) {
80 auto itr
= dest
.find(key
);
81 if (itr
== dest
.end()) return nullptr;
83 return &(itr
->second
);
86 //////////////////////////////////////////////////////////////////////////////////////////
88 std::map
<EffectiveFormat
, const CompressedFormatInfo
> gCompressedFormatInfoMap
;
89 std::map
<EffectiveFormat
, FormatInfo
> gFormatInfoMap
;
91 static inline const CompressedFormatInfo
* GetCompressedFormatInfo(
92 EffectiveFormat format
) {
93 MOZ_ASSERT(!gCompressedFormatInfoMap
.empty());
94 return FindPtrOrNull(gCompressedFormatInfoMap
, format
);
97 static inline FormatInfo
* GetFormatInfo_NoLock(EffectiveFormat format
) {
98 MOZ_ASSERT(!gFormatInfoMap
.empty());
99 return FindPtrOrNull(gFormatInfoMap
, format
);
102 //////////////////////////////////////////////////////////////////////////////////////////
104 static void AddCompressedFormatInfo(EffectiveFormat format
,
105 uint16_t bitsPerBlock
, uint8_t blockWidth
,
107 CompressionFamily family
) {
108 MOZ_ASSERT(bitsPerBlock
% 8 == 0);
109 uint16_t bytesPerBlock
= bitsPerBlock
/ 8; // The specs always state these in
110 // bits, but it's only ever useful
112 MOZ_ASSERT(bytesPerBlock
<= 255);
114 const CompressedFormatInfo info
= {format
, uint8_t(bytesPerBlock
), blockWidth
,
115 blockHeight
, family
};
116 AlwaysInsert(gCompressedFormatInfoMap
, format
, info
);
119 static void InitCompressedFormatInfo() {
122 // GLES 3.0.4, p147, table 3.19
123 // GLES 3.0.4, p286+, $C.1 "ETC Compressed Texture Image Formats"
124 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB8_ETC2
, 64, 4, 4, CompressionFamily::ES3
);
125 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ETC2
, 64, 4, 4, CompressionFamily::ES3
);
126 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA8_ETC2_EAC
, 128, 4, 4, CompressionFamily::ES3
);
127 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
, 128, 4, 4, CompressionFamily::ES3
);
128 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_R11_EAC
, 64, 4, 4, CompressionFamily::ES3
);
129 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RG11_EAC
, 128, 4, 4, CompressionFamily::ES3
);
130 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_R11_EAC
, 64, 4, 4, CompressionFamily::ES3
);
131 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_RG11_EAC
, 128, 4, 4, CompressionFamily::ES3
);
132 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
, 64, 4, 4, CompressionFamily::ES3
);
133 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
, 64, 4, 4, CompressionFamily::ES3
);
135 // EXT_texture_compression_bptc
136 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_BPTC_UNORM
, 16*8, 4, 4, CompressionFamily::BPTC
);
137 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_ALPHA_BPTC_UNORM
, 16*8, 4, 4, CompressionFamily::BPTC
);
138 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_BPTC_SIGNED_FLOAT
, 16*8, 4, 4, CompressionFamily::BPTC
);
139 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT
, 16*8, 4, 4, CompressionFamily::BPTC
);
141 // EXT_texture_compression_rgtc
142 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RED_RGTC1
, 8*8, 4, 4, CompressionFamily::RGTC
);
143 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_RED_RGTC1
, 8*8, 4, 4, CompressionFamily::RGTC
);
144 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RG_RGTC2
, 16*8, 4, 4, CompressionFamily::RGTC
);
145 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_RG_RGTC2
, 16*8, 4, 4, CompressionFamily::RGTC
);
147 // EXT_texture_compression_s3tc
148 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_S3TC_DXT1_EXT
, 64, 4, 4, CompressionFamily::S3TC
);
149 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT1_EXT
, 64, 4, 4, CompressionFamily::S3TC
);
150 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT3_EXT
, 128, 4, 4, CompressionFamily::S3TC
);
151 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT5_EXT
, 128, 4, 4, CompressionFamily::S3TC
);
153 // EXT_texture_compression_s3tc_srgb
154 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_S3TC_DXT1_EXT
, 64, 4, 4, CompressionFamily::S3TC
);
155 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
, 64, 4, 4, CompressionFamily::S3TC
);
156 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
, 128, 4, 4, CompressionFamily::S3TC
);
157 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
, 128, 4, 4, CompressionFamily::S3TC
);
159 // KHR_texture_compression_astc_ldr
160 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_4x4_KHR
, 128, 4, 4, CompressionFamily::ASTC
);
161 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_5x4_KHR
, 128, 5, 4, CompressionFamily::ASTC
);
162 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_5x5_KHR
, 128, 5, 5, CompressionFamily::ASTC
);
163 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_6x5_KHR
, 128, 6, 5, CompressionFamily::ASTC
);
164 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_6x6_KHR
, 128, 6, 6, CompressionFamily::ASTC
);
165 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_8x5_KHR
, 128, 8, 5, CompressionFamily::ASTC
);
166 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_8x6_KHR
, 128, 8, 6, CompressionFamily::ASTC
);
167 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_8x8_KHR
, 128, 8, 8, CompressionFamily::ASTC
);
168 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_10x5_KHR
, 128, 10, 5, CompressionFamily::ASTC
);
169 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_10x6_KHR
, 128, 10, 6, CompressionFamily::ASTC
);
170 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_10x8_KHR
, 128, 10, 8, CompressionFamily::ASTC
);
171 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_10x10_KHR
, 128, 10, 10, CompressionFamily::ASTC
);
172 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_12x10_KHR
, 128, 12, 10, CompressionFamily::ASTC
);
173 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_12x12_KHR
, 128, 12, 12, CompressionFamily::ASTC
);
175 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR
, 128, 4, 4, CompressionFamily::ASTC
);
176 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR
, 128, 5, 4, CompressionFamily::ASTC
);
177 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR
, 128, 5, 5, CompressionFamily::ASTC
);
178 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR
, 128, 6, 5, CompressionFamily::ASTC
);
179 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR
, 128, 6, 6, CompressionFamily::ASTC
);
180 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR
, 128, 8, 5, CompressionFamily::ASTC
);
181 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR
, 128, 8, 6, CompressionFamily::ASTC
);
182 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR
, 128, 8, 8, CompressionFamily::ASTC
);
183 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR
, 128, 10, 5, CompressionFamily::ASTC
);
184 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR
, 128, 10, 6, CompressionFamily::ASTC
);
185 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR
, 128, 10, 8, CompressionFamily::ASTC
);
186 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR
, 128, 10, 10, CompressionFamily::ASTC
);
187 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR
, 128, 12, 10, CompressionFamily::ASTC
);
188 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR
, 128, 12, 12, CompressionFamily::ASTC
);
190 // IMG_texture_compression_pvrtc
191 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_PVRTC_4BPPV1
, 256, 8, 8, CompressionFamily::PVRTC
);
192 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_PVRTC_4BPPV1
, 256, 8, 8, CompressionFamily::PVRTC
);
193 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_PVRTC_2BPPV1
, 256, 16, 8, CompressionFamily::PVRTC
);
194 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_PVRTC_2BPPV1
, 256, 16, 8, CompressionFamily::PVRTC
);
196 // OES_compressed_ETC1_RGB8_texture
197 AddCompressedFormatInfo(EffectiveFormat::ETC1_RGB8_OES
, 64, 4, 4, CompressionFamily::ETC1
);
202 //////////////////////////////////////////////////////////////////////////////////////////
204 static void AddFormatInfo(EffectiveFormat format
, const char* name
,
205 GLenum sizedFormat
, uint8_t bytesPerPixel
, uint8_t r
,
206 uint8_t g
, uint8_t b
, uint8_t a
, uint8_t d
, uint8_t s
,
207 UnsizedFormat unsizedFormat
, bool isSRGB
,
208 ComponentType componentType
) {
209 switch (unsizedFormat
) {
210 case UnsizedFormat::R
:
211 MOZ_ASSERT(r
&& !g
&& !b
&& !a
&& !d
&& !s
);
214 case UnsizedFormat::RG
:
215 MOZ_ASSERT(r
&& g
&& !b
&& !a
&& !d
&& !s
);
218 case UnsizedFormat::RGB
:
219 MOZ_ASSERT(r
&& g
&& b
&& !a
&& !d
&& !s
);
222 case UnsizedFormat::RGBA
:
223 MOZ_ASSERT(r
&& g
&& b
&& a
&& !d
&& !s
);
226 case UnsizedFormat::L
:
227 MOZ_ASSERT(r
&& !g
&& !b
&& !a
&& !d
&& !s
);
230 case UnsizedFormat::A
:
231 MOZ_ASSERT(!r
&& !g
&& !b
&& a
&& !d
&& !s
);
234 case UnsizedFormat::LA
:
235 MOZ_ASSERT(r
&& !g
&& !b
&& a
&& !d
&& !s
);
238 case UnsizedFormat::D
:
239 MOZ_ASSERT(!r
&& !g
&& !b
&& !a
&& d
&& !s
);
242 case UnsizedFormat::S
:
243 MOZ_ASSERT(!r
&& !g
&& !b
&& !a
&& !d
&& s
);
246 case UnsizedFormat::DEPTH_STENCIL
:
247 MOZ_ASSERT(!r
&& !g
&& !b
&& !a
&& d
&& s
);
251 const CompressedFormatInfo
* compressedFormatInfo
=
252 GetCompressedFormatInfo(format
);
253 MOZ_ASSERT(!bytesPerPixel
== bool(compressedFormatInfo
));
256 uint8_t totalBits
= r
+ g
+ b
+ a
+ d
+ s
;
257 if (format
== EffectiveFormat::RGB9_E5
) {
258 totalBits
= 9 + 9 + 9 + 5;
261 if (compressedFormatInfo
) {
262 MOZ_ASSERT(totalBits
);
263 MOZ_ASSERT(!bytesPerPixel
);
265 MOZ_ASSERT(totalBits
== bytesPerPixel
* 8);
269 const FormatInfo info
= {format
,
274 ToBaseType(componentType
),
276 compressedFormatInfo
,
284 AlwaysInsert(gFormatInfoMap
, format
, info
);
287 static void InitFormatInfo() {
288 // This function is full of expressive formatting, so:
291 #define FOO(x) EffectiveFormat::x, #x, LOCAL_GL_ ## x
293 // GLES 3.0.4, p130-132, table 3.13
294 AddFormatInfo(FOO(R8
), 1, 8, 0, 0, 0, 0,0, UnsizedFormat::R
, false, ComponentType::NormUInt
);
295 AddFormatInfo(FOO(R8_SNORM
), 1, 8, 0, 0, 0, 0,0, UnsizedFormat::R
, false, ComponentType::NormInt
);
296 AddFormatInfo(FOO(RG8
), 2, 8, 8, 0, 0, 0,0, UnsizedFormat::RG
, false, ComponentType::NormUInt
);
297 AddFormatInfo(FOO(RG8_SNORM
), 2, 8, 8, 0, 0, 0,0, UnsizedFormat::RG
, false, ComponentType::NormInt
);
298 AddFormatInfo(FOO(RGB8
), 3, 8, 8, 8, 0, 0,0, UnsizedFormat::RGB
, false, ComponentType::NormUInt
);
299 AddFormatInfo(FOO(RGB8_SNORM
), 3, 8, 8, 8, 0, 0,0, UnsizedFormat::RGB
, false, ComponentType::NormInt
);
300 AddFormatInfo(FOO(RGB565
), 2, 5, 6, 5, 0, 0,0, UnsizedFormat::RGB
, false, ComponentType::NormUInt
);
301 AddFormatInfo(FOO(RGBA4
), 2, 4, 4, 4, 4, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
302 AddFormatInfo(FOO(RGB5_A1
), 2, 5, 5, 5, 1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
303 AddFormatInfo(FOO(RGBA8
), 4, 8, 8, 8, 8, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
304 AddFormatInfo(FOO(RGBA8_SNORM
), 4, 8, 8, 8, 8, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormInt
);
305 AddFormatInfo(FOO(RGB10_A2
), 4, 10,10,10, 2, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
306 AddFormatInfo(FOO(RGB10_A2UI
), 4, 10,10,10, 2, 0,0, UnsizedFormat::RGBA
, false, ComponentType::UInt
);
308 AddFormatInfo(FOO(SRGB8
), 3, 8, 8, 8, 0, 0,0, UnsizedFormat::RGB
, true , ComponentType::NormUInt
);
309 AddFormatInfo(FOO(SRGB8_ALPHA8
), 4, 8, 8, 8, 8, 0,0, UnsizedFormat::RGBA
, true , ComponentType::NormUInt
);
311 AddFormatInfo(FOO(R16F
), 2, 16, 0, 0, 0, 0,0, UnsizedFormat::R
, false, ComponentType::Float
);
312 AddFormatInfo(FOO(RG16F
), 4, 16,16, 0, 0, 0,0, UnsizedFormat::RG
, false, ComponentType::Float
);
313 AddFormatInfo(FOO(RGB16F
), 6, 16,16,16, 0, 0,0, UnsizedFormat::RGB
, false, ComponentType::Float
);
314 AddFormatInfo(FOO(RGBA16F
), 8, 16,16,16,16, 0,0, UnsizedFormat::RGBA
, false, ComponentType::Float
);
315 AddFormatInfo(FOO(R32F
), 4, 32, 0, 0, 0, 0,0, UnsizedFormat::R
, false, ComponentType::Float
);
316 AddFormatInfo(FOO(RG32F
), 8, 32,32, 0, 0, 0,0, UnsizedFormat::RG
, false, ComponentType::Float
);
317 AddFormatInfo(FOO(RGB32F
), 12, 32,32,32, 0, 0,0, UnsizedFormat::RGB
, false, ComponentType::Float
);
318 AddFormatInfo(FOO(RGBA32F
), 16, 32,32,32,32, 0,0, UnsizedFormat::RGBA
, false, ComponentType::Float
);
320 AddFormatInfo(FOO(R11F_G11F_B10F
), 4, 11,11,10, 0, 0,0, UnsizedFormat::RGB
, false, ComponentType::Float
);
321 AddFormatInfo(FOO(RGB9_E5
), 4, 14,14,14, 0, 0,0, UnsizedFormat::RGB
, false, ComponentType::Float
);
323 AddFormatInfo(FOO(R8I
), 1, 8, 0, 0, 0, 0,0, UnsizedFormat::R
, false, ComponentType::Int
);
324 AddFormatInfo(FOO(R8UI
), 1, 8, 0, 0, 0, 0,0, UnsizedFormat::R
, false, ComponentType::UInt
);
325 AddFormatInfo(FOO(R16I
), 2, 16, 0, 0, 0, 0,0, UnsizedFormat::R
, false, ComponentType::Int
);
326 AddFormatInfo(FOO(R16UI
), 2, 16, 0, 0, 0, 0,0, UnsizedFormat::R
, false, ComponentType::UInt
);
327 AddFormatInfo(FOO(R32I
), 4, 32, 0, 0, 0, 0,0, UnsizedFormat::R
, false, ComponentType::Int
);
328 AddFormatInfo(FOO(R32UI
), 4, 32, 0, 0, 0, 0,0, UnsizedFormat::R
, false, ComponentType::UInt
);
330 AddFormatInfo(FOO(RG8I
), 2, 8, 8, 0, 0, 0,0, UnsizedFormat::RG
, false, ComponentType::Int
);
331 AddFormatInfo(FOO(RG8UI
), 2, 8, 8, 0, 0, 0,0, UnsizedFormat::RG
, false, ComponentType::UInt
);
332 AddFormatInfo(FOO(RG16I
), 4, 16,16, 0, 0, 0,0, UnsizedFormat::RG
, false, ComponentType::Int
);
333 AddFormatInfo(FOO(RG16UI
), 4, 16,16, 0, 0, 0,0, UnsizedFormat::RG
, false, ComponentType::UInt
);
334 AddFormatInfo(FOO(RG32I
), 8, 32,32, 0, 0, 0,0, UnsizedFormat::RG
, false, ComponentType::Int
);
335 AddFormatInfo(FOO(RG32UI
), 8, 32,32, 0, 0, 0,0, UnsizedFormat::RG
, false, ComponentType::UInt
);
337 AddFormatInfo(FOO(RGB8I
), 3, 8, 8, 8, 0, 0,0, UnsizedFormat::RGB
, false, ComponentType::Int
);
338 AddFormatInfo(FOO(RGB8UI
), 3, 8, 8, 8, 0, 0,0, UnsizedFormat::RGB
, false, ComponentType::UInt
);
339 AddFormatInfo(FOO(RGB16I
), 6, 16,16,16, 0, 0,0, UnsizedFormat::RGB
, false, ComponentType::Int
);
340 AddFormatInfo(FOO(RGB16UI
), 6, 16,16,16, 0, 0,0, UnsizedFormat::RGB
, false, ComponentType::UInt
);
341 AddFormatInfo(FOO(RGB32I
), 12, 32,32,32, 0, 0,0, UnsizedFormat::RGB
, false, ComponentType::Int
);
342 AddFormatInfo(FOO(RGB32UI
), 12, 32,32,32, 0, 0,0, UnsizedFormat::RGB
, false, ComponentType::UInt
);
344 AddFormatInfo(FOO(RGBA8I
), 4, 8, 8, 8, 8, 0,0, UnsizedFormat::RGBA
, false, ComponentType::Int
);
345 AddFormatInfo(FOO(RGBA8UI
), 4, 8, 8, 8, 8, 0,0, UnsizedFormat::RGBA
, false, ComponentType::UInt
);
346 AddFormatInfo(FOO(RGBA16I
), 8, 16,16,16,16, 0,0, UnsizedFormat::RGBA
, false, ComponentType::Int
);
347 AddFormatInfo(FOO(RGBA16UI
), 8, 16,16,16,16, 0,0, UnsizedFormat::RGBA
, false, ComponentType::UInt
);
348 AddFormatInfo(FOO(RGBA32I
), 16, 32,32,32,32, 0,0, UnsizedFormat::RGBA
, false, ComponentType::Int
);
349 AddFormatInfo(FOO(RGBA32UI
), 16, 32,32,32,32, 0,0, UnsizedFormat::RGBA
, false, ComponentType::UInt
);
351 // GLES 3.0.4, p133, table 3.14
352 AddFormatInfo(FOO(DEPTH_COMPONENT16
), 2, 0,0,0,0, 16,0, UnsizedFormat::D
, false, ComponentType::NormUInt
);
353 AddFormatInfo(FOO(DEPTH_COMPONENT24
), 3, 0,0,0,0, 24,0, UnsizedFormat::D
, false, ComponentType::NormUInt
);
354 AddFormatInfo(FOO(DEPTH_COMPONENT32F
), 4, 0,0,0,0, 32,0, UnsizedFormat::D
, false, ComponentType::Float
);
355 // DEPTH_STENCIL types are sampled as their depth component.
356 AddFormatInfo(FOO(DEPTH24_STENCIL8
), 4, 0,0,0,0, 24,8, UnsizedFormat::DEPTH_STENCIL
, false, ComponentType::NormUInt
);
357 AddFormatInfo(FOO(DEPTH32F_STENCIL8
), 5, 0,0,0,0, 32,8, UnsizedFormat::DEPTH_STENCIL
, false, ComponentType::Float
);
359 // GLES 3.0.4, p205-206, "Required Renderbuffer Formats"
360 AddFormatInfo(FOO(STENCIL_INDEX8
), 1, 0,0,0,0, 0,8, UnsizedFormat::S
, false, ComponentType::Int
);
362 // GLES 3.0.4, p147, table 3.19
363 // GLES 3.0.4 p286+ $C.1 "ETC Compressed Texture Image Formats"
364 AddFormatInfo(FOO(COMPRESSED_RGB8_ETC2
), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB
, false, ComponentType::NormUInt
);
365 AddFormatInfo(FOO(COMPRESSED_SRGB8_ETC2
), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB
, true , ComponentType::NormUInt
);
366 AddFormatInfo(FOO(COMPRESSED_RGBA8_ETC2_EAC
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
367 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true , ComponentType::NormUInt
);
368 AddFormatInfo(FOO(COMPRESSED_R11_EAC
), 0, 1,0,0,0, 0,0, UnsizedFormat::R
, false, ComponentType::NormUInt
);
369 AddFormatInfo(FOO(COMPRESSED_RG11_EAC
), 0, 1,1,0,0, 0,0, UnsizedFormat::RG
, false, ComponentType::NormUInt
);
370 AddFormatInfo(FOO(COMPRESSED_SIGNED_R11_EAC
), 0, 1,0,0,0, 0,0, UnsizedFormat::R
, false, ComponentType::NormInt
);
371 AddFormatInfo(FOO(COMPRESSED_SIGNED_RG11_EAC
), 0, 1,1,0,0, 0,0, UnsizedFormat::RG
, false, ComponentType::NormInt
);
372 AddFormatInfo(FOO(COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
373 AddFormatInfo(FOO(COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true , ComponentType::NormUInt
);
375 // EXT_texture_compression_bptc
376 AddFormatInfo(FOO(COMPRESSED_RGBA_BPTC_UNORM
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
377 AddFormatInfo(FOO(COMPRESSED_SRGB_ALPHA_BPTC_UNORM
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true , ComponentType::NormUInt
);
378 AddFormatInfo(FOO(COMPRESSED_RGB_BPTC_SIGNED_FLOAT
), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB
, false, ComponentType::Float
);
379 AddFormatInfo(FOO(COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT
), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB
, false, ComponentType::Float
);
381 // EXT_texture_compression_rgtc
382 AddFormatInfo(FOO(COMPRESSED_RED_RGTC1
), 0, 1,0,0,0, 0,0, UnsizedFormat::R
, false, ComponentType::NormUInt
);
383 AddFormatInfo(FOO(COMPRESSED_SIGNED_RED_RGTC1
), 0, 1,0,0,0, 0,0, UnsizedFormat::R
, false, ComponentType::NormInt
);
384 AddFormatInfo(FOO(COMPRESSED_RG_RGTC2
), 0, 1,1,0,0, 0,0, UnsizedFormat::RG
, false, ComponentType::NormUInt
);
385 AddFormatInfo(FOO(COMPRESSED_SIGNED_RG_RGTC2
), 0, 1,1,0,0, 0,0, UnsizedFormat::RG
, false, ComponentType::NormInt
);
387 // EXT_texture_compression_s3tc
388 AddFormatInfo(FOO(COMPRESSED_RGB_S3TC_DXT1_EXT
), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB
, false, ComponentType::NormUInt
);
389 AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT1_EXT
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
390 AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT3_EXT
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
391 AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT5_EXT
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
393 // EXT_texture_compression_s3tc_srgb
394 AddFormatInfo(FOO(COMPRESSED_SRGB_S3TC_DXT1_EXT
), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB
, true, ComponentType::NormUInt
);
395 AddFormatInfo(FOO(COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true, ComponentType::NormUInt
);
396 AddFormatInfo(FOO(COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true, ComponentType::NormUInt
);
397 AddFormatInfo(FOO(COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true, ComponentType::NormUInt
);
399 // KHR_texture_compression_astc_ldr
400 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_4x4_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
401 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_5x4_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
402 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_5x5_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
403 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_6x5_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
404 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_6x6_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
405 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_8x5_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
406 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_8x6_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
407 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_8x8_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
408 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_10x5_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
409 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_10x6_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
410 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_10x8_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
411 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_10x10_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
412 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_12x10_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
413 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_12x12_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
415 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true , ComponentType::NormUInt
);
416 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true , ComponentType::NormUInt
);
417 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true , ComponentType::NormUInt
);
418 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true , ComponentType::NormUInt
);
419 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true , ComponentType::NormUInt
);
420 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true , ComponentType::NormUInt
);
421 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true , ComponentType::NormUInt
);
422 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true , ComponentType::NormUInt
);
423 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true , ComponentType::NormUInt
);
424 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true , ComponentType::NormUInt
);
425 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true , ComponentType::NormUInt
);
426 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true , ComponentType::NormUInt
);
427 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true , ComponentType::NormUInt
);
428 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, true , ComponentType::NormUInt
);
430 // IMG_texture_compression_pvrtc
431 AddFormatInfo(FOO(COMPRESSED_RGB_PVRTC_4BPPV1
), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB
, false, ComponentType::NormUInt
);
432 AddFormatInfo(FOO(COMPRESSED_RGBA_PVRTC_4BPPV1
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
433 AddFormatInfo(FOO(COMPRESSED_RGB_PVRTC_2BPPV1
), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB
, false, ComponentType::NormUInt
);
434 AddFormatInfo(FOO(COMPRESSED_RGBA_PVRTC_2BPPV1
), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
436 // OES_compressed_ETC1_RGB8_texture
437 AddFormatInfo(FOO(ETC1_RGB8_OES
), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB
, false, ComponentType::NormUInt
);
441 // 'Virtual' effective formats have no sizedFormat.
442 #define FOO(x) EffectiveFormat::x, #x, 0
444 // GLES 3.0.4, p128, table 3.12.
445 AddFormatInfo(FOO(Luminance8Alpha8
), 2, 8,0,0,8, 0,0, UnsizedFormat::LA
, false, ComponentType::NormUInt
);
446 AddFormatInfo(FOO(Luminance8
), 1, 8,0,0,0, 0,0, UnsizedFormat::L
, false, ComponentType::NormUInt
);
447 AddFormatInfo(FOO(Alpha8
), 1, 0,0,0,8, 0,0, UnsizedFormat::A
, false, ComponentType::NormUInt
);
450 AddFormatInfo(FOO(Luminance32FAlpha32F
), 8, 32,0,0,32, 0,0, UnsizedFormat::LA
, false, ComponentType::Float
);
451 AddFormatInfo(FOO(Luminance32F
), 4, 32,0,0, 0, 0,0, UnsizedFormat::L
, false, ComponentType::Float
);
452 AddFormatInfo(FOO(Alpha32F
), 4, 0,0,0,32, 0,0, UnsizedFormat::A
, false, ComponentType::Float
);
454 // OES_texture_half_float
455 AddFormatInfo(FOO(Luminance16FAlpha16F
), 4, 16,0,0,16, 0,0, UnsizedFormat::LA
, false, ComponentType::Float
);
456 AddFormatInfo(FOO(Luminance16F
), 2, 16,0,0, 0, 0,0, UnsizedFormat::L
, false, ComponentType::Float
);
457 AddFormatInfo(FOO(Alpha16F
), 2, 0,0,0,16, 0,0, UnsizedFormat::A
, false, ComponentType::Float
);
461 ////////////////////////////////////////////////////////////////////////////
463 const auto fnSetCopyDecay
= [](EffectiveFormat src
, EffectiveFormat asR
,
464 EffectiveFormat asRG
, EffectiveFormat asRGB
,
465 EffectiveFormat asRGBA
, EffectiveFormat asL
,
466 EffectiveFormat asA
, EffectiveFormat asLA
)
468 auto& map
= GetFormatInfo_NoLock(src
)->copyDecayFormats
;
470 const auto fnSet
= [&map
](UnsizedFormat uf
, EffectiveFormat ef
) {
471 if (ef
== EffectiveFormat::MAX
)
474 const auto* format
= GetFormatInfo_NoLock(ef
);
475 MOZ_ASSERT(format
->unsizedFormat
== uf
);
476 AlwaysInsert(map
, uf
, format
);
479 fnSet(UnsizedFormat::R
, asR
);
480 fnSet(UnsizedFormat::RG
, asRG
);
481 fnSet(UnsizedFormat::RGB
, asRGB
);
482 fnSet(UnsizedFormat::RGBA
, asRGBA
);
483 fnSet(UnsizedFormat::L
, asL
);
484 fnSet(UnsizedFormat::A
, asA
);
485 fnSet(UnsizedFormat::LA
, asLA
);
488 #define SET_COPY_DECAY(src,asR,asRG,asRGB,asRGBA,asL,asA,asLA) \
489 fnSetCopyDecay(EffectiveFormat::src, EffectiveFormat::asR, EffectiveFormat::asRG, \
490 EffectiveFormat::asRGB, EffectiveFormat::asRGBA, EffectiveFormat::asL, \
491 EffectiveFormat::asA, EffectiveFormat::asLA);
495 #define SET_BY_SUFFIX(X) \
496 SET_COPY_DECAY( R##X, R##X, MAX, MAX, MAX, Luminance##X, MAX, MAX) \
497 SET_COPY_DECAY( RG##X, R##X, RG##X, MAX, MAX, Luminance##X, MAX, MAX) \
498 SET_COPY_DECAY( RGB##X, R##X, RG##X, RGB##X, MAX, Luminance##X, MAX, MAX) \
499 SET_COPY_DECAY(RGBA##X, R##X, RG##X, RGB##X, RGBA##X, Luminance##X, Alpha##X, Luminance##X##Alpha##X)
501 SET_BY_SUFFIX(8) // WebGL decided that RGB8 should be guaranteed renderable.
502 SET_BY_SUFFIX(16F
) // RGB16F is renderable in EXT_color_buffer_half_float, though not
503 // EXT_color_buffer_float.
504 SET_BY_SUFFIX(32F
) // Technically RGB32F is never renderable, but no harm here.
511 #define SET_BY_SUFFIX(X) \
512 SET_COPY_DECAY( R##X, R##X, MAX, MAX, MAX, MAX, MAX, MAX) \
513 SET_COPY_DECAY( RG##X, R##X, RG##X, MAX, MAX, MAX, MAX, MAX) \
514 SET_COPY_DECAY(RGBA##X, R##X, RG##X, RGB##X, RGBA##X, MAX, MAX, MAX)
529 SET_COPY_DECAY( RGB565
, R8
, RG8
, RGB565
, MAX
, Luminance8
, MAX
, MAX
)
530 SET_COPY_DECAY( RGBA4
, R8
, RG8
, RGB565
, RGBA4
, Luminance8
, Alpha8
, Luminance8Alpha8
)
531 SET_COPY_DECAY( RGB5_A1
, R8
, RG8
, RGB565
, RGB5_A1
, Luminance8
, Alpha8
, Luminance8Alpha8
)
532 SET_COPY_DECAY( RGB10_A2
, R8
, RG8
, RGB8
, RGB10_A2
, Luminance8
, Alpha8
, MAX
)
534 SET_COPY_DECAY(RGB10_A2UI
, R8UI
, RG8UI
, RGB8UI
, RGB10_A2UI
, MAX
, MAX
, MAX
)
536 SET_COPY_DECAY(SRGB8_ALPHA8
, MAX
, MAX
, MAX
, SRGB8_ALPHA8
, MAX
, Alpha8
, MAX
)
538 SET_COPY_DECAY(R11F_G11F_B10F
, R16F
, RG16F
, R11F_G11F_B10F
, MAX
, Luminance16F
, MAX
, MAX
)
540 #undef SET_COPY_DECAY
545 //////////////////////////////////////////////////////////////////////////////////////////
547 bool gAreFormatTablesInitialized
= false;
549 static void EnsureInitFormatTables(
550 const StaticMutexAutoLock
&) // Prove that you locked it!
552 if (MOZ_LIKELY(gAreFormatTablesInitialized
)) return;
554 gAreFormatTablesInitialized
= true;
556 InitCompressedFormatInfo();
560 //////////////////////////////////////////////////////////////////////////////////////////
563 StaticMutex gFormatMapMutex
;
565 const FormatInfo
* GetFormat(EffectiveFormat format
) {
566 StaticMutexAutoLock
lock(gFormatMapMutex
);
567 EnsureInitFormatTables(lock
);
569 return GetFormatInfo_NoLock(format
);
572 //////////////////////////////////////////////////////////////////////////////////////////
574 const FormatInfo
* FormatInfo::GetCopyDecayFormat(UnsizedFormat uf
) const {
575 return FindOrNull(this->copyDecayFormats
, uf
);
578 bool GetBytesPerPixel(const PackingInfo
& packing
, uint8_t* const out_bytes
) {
579 uint8_t bytesPerChannel
;
581 switch (packing
.type
) {
582 case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4
:
583 case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1
:
584 case LOCAL_GL_UNSIGNED_SHORT_5_6_5
:
588 case LOCAL_GL_UNSIGNED_INT_10F_11F_11F_REV
:
589 case LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV
:
590 case LOCAL_GL_UNSIGNED_INT_24_8
:
591 case LOCAL_GL_UNSIGNED_INT_5_9_9_9_REV
:
595 case LOCAL_GL_FLOAT_32_UNSIGNED_INT_24_8_REV
:
599 // Alright, that's all the fixed-size unpackTypes.
602 case LOCAL_GL_UNSIGNED_BYTE
:
607 case LOCAL_GL_UNSIGNED_SHORT
:
608 case LOCAL_GL_HALF_FLOAT
:
609 case LOCAL_GL_HALF_FLOAT_OES
:
614 case LOCAL_GL_UNSIGNED_INT
:
625 switch (packing
.format
) {
627 case LOCAL_GL_RED_INTEGER
:
628 case LOCAL_GL_LUMINANCE
:
630 case LOCAL_GL_DEPTH_COMPONENT
:
635 case LOCAL_GL_RG_INTEGER
:
636 case LOCAL_GL_LUMINANCE_ALPHA
:
641 case LOCAL_GL_RGB_INTEGER
:
648 case LOCAL_GL_RGBA_INTEGER
:
649 case LOCAL_GL_SRGB_ALPHA
:
657 *out_bytes
= bytesPerChannel
* channels
;
661 uint8_t BytesPerPixel(const PackingInfo
& packing
) {
663 if (MOZ_LIKELY(GetBytesPerPixel(packing
, &ret
))) return ret
;
665 gfxCriticalError() << "Bad `packing`: " << gfx::hexa(packing
.format
) << ", "
666 << gfx::hexa(packing
.type
);
667 MOZ_CRASH("Bad `packing`.");
670 //////////////////////////////////////////////////////////////////////////////////////////
671 //////////////////////////////////////////////////////////////////////////////////////////
672 //////////////////////////////////////////////////////////////////////////////////////////
673 //////////////////////////////////////////////////////////////////////////////////////////
674 //////////////////////////////////////////////////////////////////////////////////////////
675 //////////////////////////////////////////////////////////////////////////////////////////
676 //////////////////////////////////////////////////////////////////////////////////////////
677 //////////////////////////////////////////////////////////////////////////////////////////
678 // FormatUsageAuthority
680 bool FormatUsageInfo::IsUnpackValid(
681 const PackingInfo
& key
, const DriverUnpackInfo
** const out_value
) const {
682 auto itr
= validUnpacks
.find(key
);
683 if (itr
== validUnpacks
.end()) return false;
685 *out_value
= &(itr
->second
);
689 void FormatUsageInfo::ResolveMaxSamples(gl::GLContext
& gl
) const {
690 MOZ_ASSERT(gl
.IsCurrent());
691 MOZ_ASSERT(!this->maxSamplesKnown
);
692 MOZ_ASSERT(!this->maxSamples
);
693 this->maxSamplesKnown
= true;
695 const GLenum internalFormat
= this->format
->sizedFormat
;
696 if (!internalFormat
) return;
697 if (!gl
.IsSupported(gl::GLFeature::internalformat_query
)) return;
699 // GL_SAMPLES returns a list in descending order, so ask for just one elem to
701 gl
.fGetInternalformativ(LOCAL_GL_RENDERBUFFER
, internalFormat
,
703 reinterpret_cast<GLint
*>(&this->maxSamples
));
706 ////////////////////////////////////////
708 static void AddSimpleUnsized(FormatUsageAuthority
* fua
, GLenum unpackFormat
,
709 GLenum unpackType
, EffectiveFormat effFormat
) {
710 auto usage
= fua
->EditUsage(effFormat
);
711 usage
->isFilterable
= true;
713 const PackingInfo pi
= {unpackFormat
, unpackType
};
714 const DriverUnpackInfo dui
= {unpackFormat
, unpackFormat
, unpackType
};
715 fua
->AddTexUnpack(usage
, pi
, dui
);
717 fua
->AllowUnsizedTexFormat(pi
, usage
);
720 /*static*/ const GLint
FormatUsageInfo::kLuminanceSwizzleRGBA
[4] = {
721 LOCAL_GL_RED
, LOCAL_GL_RED
, LOCAL_GL_RED
, LOCAL_GL_ONE
};
722 /*static*/ const GLint
FormatUsageInfo::kAlphaSwizzleRGBA
[4] = {
723 LOCAL_GL_ZERO
, LOCAL_GL_ZERO
, LOCAL_GL_ZERO
, LOCAL_GL_RED
};
724 /*static*/ const GLint
FormatUsageInfo::kLumAlphaSwizzleRGBA
[4] = {
725 LOCAL_GL_RED
, LOCAL_GL_RED
, LOCAL_GL_RED
, LOCAL_GL_GREEN
};
727 static bool AddLegacyFormats_LA8(FormatUsageAuthority
* fua
, gl::GLContext
* gl
) {
728 if (gl
->IsCoreProfile()) {
729 if (!gl
->IsSupported(gl::GLFeature::texture_swizzle
)) return false;
732 DriverUnpackInfo dui
;
734 const auto fnAdd
= [fua
, &pi
, &dui
](EffectiveFormat effFormat
,
735 const GLint
* swizzle
) {
736 auto usage
= fua
->EditUsage(effFormat
);
737 usage
->isFilterable
= true;
738 usage
->textureSwizzleRGBA
= swizzle
;
740 fua
->AddTexUnpack(usage
, pi
, dui
);
742 fua
->AllowUnsizedTexFormat(pi
, usage
);
745 pi
= {LOCAL_GL_LUMINANCE
, LOCAL_GL_UNSIGNED_BYTE
};
746 dui
= {LOCAL_GL_R8
, LOCAL_GL_RED
, LOCAL_GL_UNSIGNED_BYTE
};
747 fnAdd(EffectiveFormat::Luminance8
, FormatUsageInfo::kLuminanceSwizzleRGBA
);
749 pi
= {LOCAL_GL_ALPHA
, LOCAL_GL_UNSIGNED_BYTE
};
750 dui
= {LOCAL_GL_R8
, LOCAL_GL_RED
, LOCAL_GL_UNSIGNED_BYTE
};
751 fnAdd(EffectiveFormat::Alpha8
, FormatUsageInfo::kAlphaSwizzleRGBA
);
753 pi
= {LOCAL_GL_LUMINANCE_ALPHA
, LOCAL_GL_UNSIGNED_BYTE
};
754 dui
= {LOCAL_GL_RG8
, LOCAL_GL_RG
, LOCAL_GL_UNSIGNED_BYTE
};
755 fnAdd(EffectiveFormat::Luminance8Alpha8
,
756 FormatUsageInfo::kLumAlphaSwizzleRGBA
);
759 AddSimpleUnsized(fua
, LOCAL_GL_LUMINANCE
, LOCAL_GL_UNSIGNED_BYTE
, EffectiveFormat::Luminance8
);
760 AddSimpleUnsized(fua
, LOCAL_GL_ALPHA
, LOCAL_GL_UNSIGNED_BYTE
, EffectiveFormat::Alpha8
);
761 AddSimpleUnsized(fua
, LOCAL_GL_LUMINANCE_ALPHA
, LOCAL_GL_UNSIGNED_BYTE
, EffectiveFormat::Luminance8Alpha8
);
768 static bool AddUnsizedFormats(FormatUsageAuthority
* fua
, gl::GLContext
* gl
) {
771 // GLES 2.0.25, p63, Table 3.4
772 AddSimpleUnsized(fua
, LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_BYTE
, EffectiveFormat::RGBA8
);
773 AddSimpleUnsized(fua
, LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_SHORT_4_4_4_4
, EffectiveFormat::RGBA4
);
774 AddSimpleUnsized(fua
, LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_SHORT_5_5_5_1
, EffectiveFormat::RGB5_A1
);
775 AddSimpleUnsized(fua
, LOCAL_GL_RGB
, LOCAL_GL_UNSIGNED_BYTE
, EffectiveFormat::RGB8
);
776 AddSimpleUnsized(fua
, LOCAL_GL_RGB
, LOCAL_GL_UNSIGNED_SHORT_5_6_5
, EffectiveFormat::RGB565
);
779 return AddLegacyFormats_LA8(fua
, gl
);
784 void FormatUsageInfo::SetRenderable(const FormatRenderableState
& state
) {
785 if (!renderableState
.IsExplicit()) {
786 renderableState
= state
;
790 const auto format
= this->format
;
791 if (format
->IsColorFormat()) {
792 const auto& map
= format
->copyDecayFormats
;
793 const auto itr
= map
.find(format
->unsizedFormat
);
794 MOZ_ASSERT(itr
!= map
.end(),
795 "Renderable formats must be in copyDecayFormats.");
796 MOZ_ASSERT(itr
->second
== format
);
801 UniquePtr
<FormatUsageAuthority
> FormatUsageAuthority::CreateForWebGL1(
803 UniquePtr
<FormatUsageAuthority
> ret(new FormatUsageAuthority
);
804 const auto ptr
= ret
.get();
806 ////////////////////////////////////////////////////////////////////////////
809 const auto fnSet
= [ptr
](EffectiveFormat effFormat
, bool isRenderable
,
811 MOZ_ASSERT(!ptr
->GetUsage(effFormat
));
813 auto usage
= ptr
->EditUsage(effFormat
);
814 usage
->isFilterable
= isFilterable
;
817 usage
->SetRenderable();
821 // GLES 2.0.25, p117, Table 4.5
822 // RGBA8 is made renderable in WebGL 1.0, "Framebuffer Object Attachments"
825 fnSet(EffectiveFormat::RGBA8
, true, true);
826 fnSet(EffectiveFormat::RGBA4
, true, true);
827 fnSet(EffectiveFormat::RGB5_A1
, true, true);
828 fnSet(EffectiveFormat::RGB565
, true, true);
830 // RGB8 is not guaranteed to be renderable, but we should allow it for
831 // web-compat. Min-capability mode should mark this as non-renderable.
832 fnSet(EffectiveFormat::RGB8
, true, true);
834 fnSet(EffectiveFormat::Luminance8Alpha8
, false, true);
835 fnSet(EffectiveFormat::Luminance8
, false, true);
836 fnSet(EffectiveFormat::Alpha8
, false, true);
838 fnSet(EffectiveFormat::DEPTH_COMPONENT16
, true, true);
839 fnSet(EffectiveFormat::DEPTH_COMPONENT24
, true,
840 true); // Requires WEBGL_depth_texture.
841 fnSet(EffectiveFormat::STENCIL_INDEX8
, true, false);
843 // Added in WebGL 1.0 spec:
844 fnSet(EffectiveFormat::DEPTH24_STENCIL8
, true, true);
846 ////////////////////////////////////
850 ptr->AllowRBFormat(LOCAL_GL_##x, ptr->GetUsage(EffectiveFormat::x))
855 FOO(DEPTH_COMPONENT16
);
857 // FOO(DEPTH24_STENCIL8 ); // WebGL 1 uses DEPTH_STENCIL instead of
862 ptr
->AllowRBFormat(LOCAL_GL_DEPTH_STENCIL
,
863 ptr
->GetUsage(EffectiveFormat::DEPTH24_STENCIL8
));
865 ////////////////////////////////////////////////////////////////////////////
867 if (!AddUnsizedFormats(ptr
, gl
)) return nullptr;
872 UniquePtr
<FormatUsageAuthority
> FormatUsageAuthority::CreateForWebGL2(
874 UniquePtr
<FormatUsageAuthority
> ret(new FormatUsageAuthority
);
875 const auto ptr
= ret
.get();
877 ////////////////////////////////////////////////////////////////////////////
878 // GLES 3.0.4 p111-113
880 const auto fnAddSizedUnpack
= [ptr
](EffectiveFormat effFormat
,
881 GLenum internalFormat
,
882 GLenum unpackFormat
, GLenum unpackType
) {
883 auto usage
= ptr
->EditUsage(effFormat
);
885 const PackingInfo pi
= {unpackFormat
, unpackType
};
886 const DriverUnpackInfo dui
= {internalFormat
, unpackFormat
, unpackType
};
887 ptr
->AddTexUnpack(usage
, pi
, dui
);
891 #define FOO(x) EffectiveFormat::x, LOCAL_GL_ ## x
894 fnAddSizedUnpack(FOO(RGBA8
), LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_BYTE
);
895 fnAddSizedUnpack(FOO(RGBA4
), LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_SHORT_4_4_4_4
);
896 fnAddSizedUnpack(FOO(RGBA4
), LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_BYTE
);
897 fnAddSizedUnpack(FOO(RGB5_A1
), LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_SHORT_5_5_5_1
);
898 fnAddSizedUnpack(FOO(RGB5_A1
), LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_BYTE
);
899 fnAddSizedUnpack(FOO(RGB5_A1
), LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV
);
900 fnAddSizedUnpack(FOO(SRGB8_ALPHA8
), LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_BYTE
);
901 fnAddSizedUnpack(FOO(RGBA8_SNORM
), LOCAL_GL_RGBA
, LOCAL_GL_BYTE
);
902 fnAddSizedUnpack(FOO(RGB10_A2
), LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV
);
903 fnAddSizedUnpack(FOO(RGBA16F
), LOCAL_GL_RGBA
, LOCAL_GL_HALF_FLOAT
);
904 fnAddSizedUnpack(FOO(RGBA16F
), LOCAL_GL_RGBA
, LOCAL_GL_FLOAT
);
905 fnAddSizedUnpack(FOO(RGBA32F
), LOCAL_GL_RGBA
, LOCAL_GL_FLOAT
);
908 fnAddSizedUnpack(FOO(RGBA8UI
), LOCAL_GL_RGBA_INTEGER
, LOCAL_GL_UNSIGNED_BYTE
);
909 fnAddSizedUnpack(FOO(RGBA8I
), LOCAL_GL_RGBA_INTEGER
, LOCAL_GL_BYTE
);
910 fnAddSizedUnpack(FOO(RGBA16UI
), LOCAL_GL_RGBA_INTEGER
, LOCAL_GL_UNSIGNED_SHORT
);
911 fnAddSizedUnpack(FOO(RGBA16I
), LOCAL_GL_RGBA_INTEGER
, LOCAL_GL_SHORT
);
912 fnAddSizedUnpack(FOO(RGBA32UI
), LOCAL_GL_RGBA_INTEGER
, LOCAL_GL_UNSIGNED_INT
);
913 fnAddSizedUnpack(FOO(RGBA32I
), LOCAL_GL_RGBA_INTEGER
, LOCAL_GL_INT
);
914 fnAddSizedUnpack(FOO(RGB10_A2UI
), LOCAL_GL_RGBA_INTEGER
, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV
);
917 fnAddSizedUnpack(FOO(RGB8
), LOCAL_GL_RGB
, LOCAL_GL_UNSIGNED_BYTE
);
918 fnAddSizedUnpack(FOO(SRGB8
), LOCAL_GL_RGB
, LOCAL_GL_UNSIGNED_BYTE
);
919 fnAddSizedUnpack(FOO(RGB565
), LOCAL_GL_RGB
, LOCAL_GL_UNSIGNED_SHORT_5_6_5
);
920 fnAddSizedUnpack(FOO(RGB565
), LOCAL_GL_RGB
, LOCAL_GL_UNSIGNED_BYTE
);
921 fnAddSizedUnpack(FOO(RGB8_SNORM
), LOCAL_GL_RGB
, LOCAL_GL_BYTE
);
922 fnAddSizedUnpack(FOO(R11F_G11F_B10F
), LOCAL_GL_RGB
, LOCAL_GL_UNSIGNED_INT_10F_11F_11F_REV
);
923 fnAddSizedUnpack(FOO(R11F_G11F_B10F
), LOCAL_GL_RGB
, LOCAL_GL_HALF_FLOAT
);
924 fnAddSizedUnpack(FOO(R11F_G11F_B10F
), LOCAL_GL_RGB
, LOCAL_GL_FLOAT
);
925 fnAddSizedUnpack(FOO(RGB16F
), LOCAL_GL_RGB
, LOCAL_GL_HALF_FLOAT
);
926 fnAddSizedUnpack(FOO(RGB16F
), LOCAL_GL_RGB
, LOCAL_GL_FLOAT
);
927 fnAddSizedUnpack(FOO(RGB9_E5
), LOCAL_GL_RGB
, LOCAL_GL_UNSIGNED_INT_5_9_9_9_REV
);
928 fnAddSizedUnpack(FOO(RGB9_E5
), LOCAL_GL_RGB
, LOCAL_GL_HALF_FLOAT
);
929 fnAddSizedUnpack(FOO(RGB9_E5
), LOCAL_GL_RGB
, LOCAL_GL_FLOAT
);
930 fnAddSizedUnpack(FOO(RGB32F
), LOCAL_GL_RGB
, LOCAL_GL_FLOAT
);
933 fnAddSizedUnpack(FOO(RGB8UI
), LOCAL_GL_RGB_INTEGER
, LOCAL_GL_UNSIGNED_BYTE
);
934 fnAddSizedUnpack(FOO(RGB8I
), LOCAL_GL_RGB_INTEGER
, LOCAL_GL_BYTE
);
935 fnAddSizedUnpack(FOO(RGB16UI
), LOCAL_GL_RGB_INTEGER
, LOCAL_GL_UNSIGNED_SHORT
);
936 fnAddSizedUnpack(FOO(RGB16I
), LOCAL_GL_RGB_INTEGER
, LOCAL_GL_SHORT
);
937 fnAddSizedUnpack(FOO(RGB32UI
), LOCAL_GL_RGB_INTEGER
, LOCAL_GL_UNSIGNED_INT
);
938 fnAddSizedUnpack(FOO(RGB32I
), LOCAL_GL_RGB_INTEGER
, LOCAL_GL_INT
);
941 fnAddSizedUnpack(FOO(RG8
), LOCAL_GL_RG
, LOCAL_GL_UNSIGNED_BYTE
);
942 fnAddSizedUnpack(FOO(RG8_SNORM
), LOCAL_GL_RG
, LOCAL_GL_BYTE
);
943 fnAddSizedUnpack(FOO(RG16F
), LOCAL_GL_RG
, LOCAL_GL_HALF_FLOAT
);
944 fnAddSizedUnpack(FOO(RG16F
), LOCAL_GL_RG
, LOCAL_GL_FLOAT
);
945 fnAddSizedUnpack(FOO(RG32F
), LOCAL_GL_RG
, LOCAL_GL_FLOAT
);
948 fnAddSizedUnpack(FOO(RG8UI
), LOCAL_GL_RG_INTEGER
, LOCAL_GL_UNSIGNED_BYTE
);
949 fnAddSizedUnpack(FOO(RG8I
), LOCAL_GL_RG_INTEGER
, LOCAL_GL_BYTE
);
950 fnAddSizedUnpack(FOO(RG16UI
), LOCAL_GL_RG_INTEGER
, LOCAL_GL_UNSIGNED_SHORT
);
951 fnAddSizedUnpack(FOO(RG16I
), LOCAL_GL_RG_INTEGER
, LOCAL_GL_SHORT
);
952 fnAddSizedUnpack(FOO(RG32UI
), LOCAL_GL_RG_INTEGER
, LOCAL_GL_UNSIGNED_INT
);
953 fnAddSizedUnpack(FOO(RG32I
), LOCAL_GL_RG_INTEGER
, LOCAL_GL_INT
);
956 fnAddSizedUnpack(FOO(R8
), LOCAL_GL_RED
, LOCAL_GL_UNSIGNED_BYTE
);
957 fnAddSizedUnpack(FOO(R8_SNORM
), LOCAL_GL_RED
, LOCAL_GL_BYTE
);
958 fnAddSizedUnpack(FOO(R16F
), LOCAL_GL_RED
, LOCAL_GL_HALF_FLOAT
);
959 fnAddSizedUnpack(FOO(R16F
), LOCAL_GL_RED
, LOCAL_GL_FLOAT
);
960 fnAddSizedUnpack(FOO(R32F
), LOCAL_GL_RED
, LOCAL_GL_FLOAT
);
963 fnAddSizedUnpack(FOO(R8UI
), LOCAL_GL_RED_INTEGER
, LOCAL_GL_UNSIGNED_BYTE
);
964 fnAddSizedUnpack(FOO(R8I
), LOCAL_GL_RED_INTEGER
, LOCAL_GL_BYTE
);
965 fnAddSizedUnpack(FOO(R16UI
), LOCAL_GL_RED_INTEGER
, LOCAL_GL_UNSIGNED_SHORT
);
966 fnAddSizedUnpack(FOO(R16I
), LOCAL_GL_RED_INTEGER
, LOCAL_GL_SHORT
);
967 fnAddSizedUnpack(FOO(R32UI
), LOCAL_GL_RED_INTEGER
, LOCAL_GL_UNSIGNED_INT
);
968 fnAddSizedUnpack(FOO(R32I
), LOCAL_GL_RED_INTEGER
, LOCAL_GL_INT
);
971 fnAddSizedUnpack(FOO(DEPTH_COMPONENT16
), LOCAL_GL_DEPTH_COMPONENT
, LOCAL_GL_UNSIGNED_SHORT
);
972 fnAddSizedUnpack(FOO(DEPTH_COMPONENT16
), LOCAL_GL_DEPTH_COMPONENT
, LOCAL_GL_UNSIGNED_INT
);
973 fnAddSizedUnpack(FOO(DEPTH_COMPONENT24
), LOCAL_GL_DEPTH_COMPONENT
, LOCAL_GL_UNSIGNED_INT
);
974 fnAddSizedUnpack(FOO(DEPTH_COMPONENT32F
), LOCAL_GL_DEPTH_COMPONENT
, LOCAL_GL_FLOAT
);
977 fnAddSizedUnpack(FOO(DEPTH24_STENCIL8
), LOCAL_GL_DEPTH_STENCIL
, LOCAL_GL_UNSIGNED_INT_24_8
);
978 fnAddSizedUnpack(FOO(DEPTH32F_STENCIL8
), LOCAL_GL_DEPTH_STENCIL
, LOCAL_GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
983 ////////////////////////////////////////////////////////////////////////////
985 // For renderable, see GLES 3.0.4, p212 "Framebuffer Completeness"
986 // For filterable, see GLES 3.0.4, p161 "...a texture is complete unless..."
988 const auto fnAllowES3TexFormat
= [ptr
](GLenum sizedFormat
,
989 EffectiveFormat effFormat
,
990 bool isRenderable
, bool isFilterable
) {
991 auto usage
= ptr
->EditUsage(effFormat
);
992 usage
->isFilterable
= isFilterable
;
995 usage
->SetRenderable();
998 ptr
->AllowSizedTexFormat(sizedFormat
, usage
);
1001 ptr
->AllowRBFormat(sizedFormat
, usage
);
1005 #define FOO(x) LOCAL_GL_##x, EffectiveFormat::x
1007 // GLES 3.0.4, p128-129 "Required Texture Formats"
1008 // GLES 3.0.4, p130-132, table 3.13
1011 fnAllowES3TexFormat(FOO(R8
), true, true);
1012 fnAllowES3TexFormat(FOO(R8_SNORM
), false, true);
1013 fnAllowES3TexFormat(FOO(RG8
), true, true);
1014 fnAllowES3TexFormat(FOO(RG8_SNORM
), false, true);
1015 fnAllowES3TexFormat(FOO(RGB8
), true, true);
1016 fnAllowES3TexFormat(FOO(RGB8_SNORM
), false, true);
1017 fnAllowES3TexFormat(FOO(RGB565
), true, true);
1018 fnAllowES3TexFormat(FOO(RGBA4
), true, true);
1019 fnAllowES3TexFormat(FOO(RGB5_A1
), true, true);
1020 fnAllowES3TexFormat(FOO(RGBA8
), true, true);
1021 fnAllowES3TexFormat(FOO(RGBA8_SNORM
), false, true);
1022 fnAllowES3TexFormat(FOO(RGB10_A2
), true, true);
1023 fnAllowES3TexFormat(FOO(RGB10_A2UI
), true, false);
1025 fnAllowES3TexFormat(FOO(SRGB8
), false, true);
1026 fnAllowES3TexFormat(FOO(SRGB8_ALPHA8
), true, true);
1028 fnAllowES3TexFormat(FOO(R16F
), false, true);
1029 fnAllowES3TexFormat(FOO(RG16F
), false, true);
1030 fnAllowES3TexFormat(FOO(RGB16F
), false, true);
1031 fnAllowES3TexFormat(FOO(RGBA16F
), false, true);
1033 fnAllowES3TexFormat(FOO(R32F
), false, false);
1034 fnAllowES3TexFormat(FOO(RG32F
), false, false);
1035 fnAllowES3TexFormat(FOO(RGB32F
), false, false);
1036 fnAllowES3TexFormat(FOO(RGBA32F
), false, false);
1038 fnAllowES3TexFormat(FOO(R11F_G11F_B10F
), false, true);
1039 fnAllowES3TexFormat(FOO(RGB9_E5
), false, true);
1041 fnAllowES3TexFormat(FOO(R8I
), true, false);
1042 fnAllowES3TexFormat(FOO(R8UI
), true, false);
1043 fnAllowES3TexFormat(FOO(R16I
), true, false);
1044 fnAllowES3TexFormat(FOO(R16UI
), true, false);
1045 fnAllowES3TexFormat(FOO(R32I
), true, false);
1046 fnAllowES3TexFormat(FOO(R32UI
), true, false);
1048 fnAllowES3TexFormat(FOO(RG8I
), true, false);
1049 fnAllowES3TexFormat(FOO(RG8UI
), true, false);
1050 fnAllowES3TexFormat(FOO(RG16I
), true, false);
1051 fnAllowES3TexFormat(FOO(RG16UI
), true, false);
1052 fnAllowES3TexFormat(FOO(RG32I
), true, false);
1053 fnAllowES3TexFormat(FOO(RG32UI
), true, false);
1055 fnAllowES3TexFormat(FOO(RGB8I
), false, false);
1056 fnAllowES3TexFormat(FOO(RGB8UI
), false, false);
1057 fnAllowES3TexFormat(FOO(RGB16I
), false, false);
1058 fnAllowES3TexFormat(FOO(RGB16UI
), false, false);
1059 fnAllowES3TexFormat(FOO(RGB32I
), false, false);
1060 fnAllowES3TexFormat(FOO(RGB32UI
), false, false);
1062 fnAllowES3TexFormat(FOO(RGBA8I
), true, false);
1063 fnAllowES3TexFormat(FOO(RGBA8UI
), true, false);
1064 fnAllowES3TexFormat(FOO(RGBA16I
), true, false);
1065 fnAllowES3TexFormat(FOO(RGBA16UI
), true, false);
1066 fnAllowES3TexFormat(FOO(RGBA32I
), true, false);
1067 fnAllowES3TexFormat(FOO(RGBA32UI
), true, false);
1069 // GLES 3.0.4, p133, table 3.14
1071 // Depth textures and the depth components of depth/stencil textures can be
1072 // treated as `RED` textures during texture filtering and application.
1073 fnAllowES3TexFormat(FOO(DEPTH_COMPONENT16
), true, true);
1074 fnAllowES3TexFormat(FOO(DEPTH_COMPONENT24
), true, true);
1075 fnAllowES3TexFormat(FOO(DEPTH_COMPONENT32F
), true, true);
1076 fnAllowES3TexFormat(FOO(DEPTH24_STENCIL8
), true, true);
1077 fnAllowES3TexFormat(FOO(DEPTH32F_STENCIL8
), true, true);
1081 // GLES 3.0.4, p206, "Required Renderbuffer Formats":
1082 // "Implementations are also required to support STENCIL_INDEX8. Requesting
1083 // this internal format for a renderbuffer will allocate at least 8 stencil
1086 auto usage
= ptr
->EditUsage(EffectiveFormat::STENCIL_INDEX8
);
1087 usage
->SetRenderable();
1088 ptr
->AllowRBFormat(LOCAL_GL_STENCIL_INDEX8
, usage
);
1093 if (!AddUnsizedFormats(ptr
, gl
)) return nullptr;
1095 ptr
->AllowRBFormat(LOCAL_GL_DEPTH_STENCIL
,
1096 ptr
->GetUsage(EffectiveFormat::DEPTH24_STENCIL8
));
1098 ////////////////////////////////////
1103 //////////////////////////////////////////////////////////////////////////////////////////
1105 void FormatUsageAuthority::AddTexUnpack(FormatUsageInfo
* usage
,
1106 const PackingInfo
& pi
,
1107 const DriverUnpackInfo
& dui
) {
1108 // Don't AlwaysInsert here, since we'll see duplicates from sized and unsized
1110 auto res
= usage
->validUnpacks
.insert({pi
, dui
});
1111 auto itr
= res
.first
;
1113 if (!usage
->idealUnpack
) {
1115 usage
->idealUnpack
= &(itr
->second
);
1118 mValidTexUnpackFormats
.insert(pi
.format
);
1119 mValidTexUnpackTypes
.insert(pi
.type
);
1122 static bool Contains(const std::set
<GLenum
>& set
, GLenum key
) {
1123 return set
.find(key
) != set
.end();
1126 bool FormatUsageAuthority::IsInternalFormatEnumValid(
1127 GLenum internalFormat
) const {
1128 return Contains(mValidTexInternalFormats
, internalFormat
);
1131 bool FormatUsageAuthority::AreUnpackEnumsValid(GLenum unpackFormat
,
1132 GLenum unpackType
) const {
1133 return (Contains(mValidTexUnpackFormats
, unpackFormat
) &&
1134 Contains(mValidTexUnpackTypes
, unpackType
));
1137 ////////////////////
1139 void FormatUsageAuthority::AllowRBFormat(GLenum sizedFormat
,
1140 const FormatUsageInfo
* usage
,
1141 const bool expectRenderable
) {
1142 MOZ_ASSERT(!usage
->format
->compression
);
1143 MOZ_ASSERT(usage
->format
->sizedFormat
);
1144 MOZ_ASSERT(usage
->IsRenderable() || !expectRenderable
);
1146 const auto& found
= mRBFormatMap
.find(sizedFormat
);
1147 if (found
!= mRBFormatMap
.end()) {
1148 MOZ_ASSERT(found
->second
== usage
);
1151 AlwaysInsert(mRBFormatMap
, sizedFormat
, usage
);
1154 void FormatUsageAuthority::AllowSizedTexFormat(GLenum sizedFormat
,
1155 const FormatUsageInfo
* usage
) {
1156 if (usage
->format
->compression
) {
1157 MOZ_ASSERT(usage
->isFilterable
, "Compressed formats should be filterable.");
1159 MOZ_ASSERT(usage
->validUnpacks
.size() && usage
->idealUnpack
,
1160 "AddTexUnpack() first.");
1163 AlwaysInsert(mSizedTexFormatMap
, sizedFormat
, usage
);
1165 mValidTexInternalFormats
.insert(sizedFormat
);
1168 void FormatUsageAuthority::AllowUnsizedTexFormat(const PackingInfo
& pi
,
1169 const FormatUsageInfo
* usage
) {
1170 MOZ_ASSERT(!usage
->format
->compression
);
1171 MOZ_ASSERT(usage
->validUnpacks
.size() && usage
->idealUnpack
,
1172 "AddTexUnpack() first.");
1174 AlwaysInsert(mUnsizedTexFormatMap
, pi
, usage
);
1176 mValidTexInternalFormats
.insert(pi
.format
);
1177 mValidTexUnpackFormats
.insert(pi
.format
);
1178 mValidTexUnpackTypes
.insert(pi
.type
);
1181 const FormatUsageInfo
* FormatUsageAuthority::GetRBUsage(
1182 GLenum sizedFormat
) const {
1183 return FindOrNull(mRBFormatMap
, sizedFormat
);
1186 const FormatUsageInfo
* FormatUsageAuthority::GetSizedTexUsage(
1187 GLenum sizedFormat
) const {
1188 return FindOrNull(mSizedTexFormatMap
, sizedFormat
);
1191 const FormatUsageInfo
* FormatUsageAuthority::GetUnsizedTexUsage(
1192 const PackingInfo
& pi
) const {
1193 return FindOrNull(mUnsizedTexFormatMap
, pi
);
1196 FormatUsageInfo
* FormatUsageAuthority::EditUsage(EffectiveFormat format
) {
1197 auto itr
= mUsageMap
.find(format
);
1199 if (itr
== mUsageMap
.end()) {
1200 const FormatInfo
* formatInfo
= GetFormat(format
);
1201 MOZ_RELEASE_ASSERT(formatInfo
, "GFX: no format info set.");
1203 FormatUsageInfo
usage(formatInfo
);
1205 auto res
= mUsageMap
.insert({format
, usage
});
1206 DebugOnly
<bool> didInsert
= res
.second
;
1207 MOZ_ASSERT(didInsert
);
1212 return &(itr
->second
);
1215 const FormatUsageInfo
* FormatUsageAuthority::GetUsage(
1216 EffectiveFormat format
) const {
1217 auto itr
= mUsageMap
.find(format
);
1218 if (itr
== mUsageMap
.end()) return nullptr;
1220 return &(itr
->second
);
1223 ////////////////////////////////////////////////////////////////////////////////
1225 } // namespace webgl
1226 } // namespace mozilla