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"
13 namespace mozilla::webgl
{
15 const char* ToString(const ComponentType type
) {
17 case ComponentType::Int
:
19 case ComponentType::UInt
:
21 case ComponentType::NormInt
:
23 case ComponentType::NormUInt
:
25 case ComponentType::Float
:
28 MOZ_CRASH("pacify gcc6 warning");
31 static TextureBaseType
ToBaseType(const ComponentType type
) {
33 case ComponentType::Int
:
34 return TextureBaseType::Int
;
35 case ComponentType::UInt
:
36 return TextureBaseType::UInt
;
37 case ComponentType::NormInt
:
38 case ComponentType::NormUInt
:
39 case ComponentType::Float
:
40 // case ComponentType::Depth:
41 return TextureBaseType::Float
;
43 MOZ_CRASH("pacify gcc6 warning");
46 const char* ToString(const TextureBaseType x
) {
48 case webgl::TextureBaseType::Float
:
50 case webgl::TextureBaseType::Int
:
52 case webgl::TextureBaseType::UInt
:
55 MOZ_CRASH("pacify gcc6 warning");
60 template <typename K
, typename V
, typename K2
, typename V2
>
61 static inline void AlwaysInsert(std::map
<K
, V
>& dest
, const K2
& key
,
63 auto res
= dest
.insert({key
, val
});
64 bool didInsert
= res
.second
;
65 MOZ_ALWAYS_TRUE(didInsert
);
68 template <typename K
, typename V
, typename K2
>
69 static inline V
* FindOrNull(const std::map
<K
, V
*>& dest
, const K2
& key
) {
70 auto itr
= dest
.find(key
);
71 if (itr
== dest
.end()) return nullptr;
76 // Returns a pointer to the in-place value for `key`.
77 template <typename C
, typename K2
>
78 static inline auto FindPtrOrNull(C
& container
, const K2
& key
) {
79 auto itr
= container
.find(key
);
80 using R
= decltype(&(itr
->second
));
81 if (itr
== container
.end()) return R
{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
);
439 // EXT_texture_norm16
440 AddFormatInfo(FOO(R16
), 2, 16, 0, 0, 0, 0,0, UnsizedFormat::R
, false, ComponentType::NormUInt
);
441 AddFormatInfo(FOO(RG16
), 4, 16,16, 0, 0, 0,0, UnsizedFormat::RG
, false, ComponentType::NormUInt
);
442 AddFormatInfo(FOO(RGB16
), 6, 16,16,16, 0, 0,0, UnsizedFormat::RGB
, false, ComponentType::NormUInt
);
443 AddFormatInfo(FOO(RGBA16
), 8, 16,16,16,16, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormUInt
);
445 AddFormatInfo(FOO(R16_SNORM
), 2, 16, 0, 0, 0, 0,0, UnsizedFormat::R
, false, ComponentType::NormInt
);
446 AddFormatInfo(FOO(RG16_SNORM
), 4, 16,16, 0, 0, 0,0, UnsizedFormat::RG
, false, ComponentType::NormInt
);
447 AddFormatInfo(FOO(RGB16_SNORM
), 6, 16,16,16, 0, 0,0, UnsizedFormat::RGB
, false, ComponentType::NormInt
);
448 AddFormatInfo(FOO(RGBA16_SNORM
), 8, 16,16,16,16, 0,0, UnsizedFormat::RGBA
, false, ComponentType::NormInt
);
452 // 'Virtual' effective formats have no sizedFormat.
453 #define FOO(x) EffectiveFormat::x, #x, 0
455 // GLES 3.0.4, p128, table 3.12.
456 AddFormatInfo(FOO(Luminance8Alpha8
), 2, 8,0,0,8, 0,0, UnsizedFormat::LA
, false, ComponentType::NormUInt
);
457 AddFormatInfo(FOO(Luminance8
), 1, 8,0,0,0, 0,0, UnsizedFormat::L
, false, ComponentType::NormUInt
);
458 AddFormatInfo(FOO(Alpha8
), 1, 0,0,0,8, 0,0, UnsizedFormat::A
, false, ComponentType::NormUInt
);
461 AddFormatInfo(FOO(Luminance32FAlpha32F
), 8, 32,0,0,32, 0,0, UnsizedFormat::LA
, false, ComponentType::Float
);
462 AddFormatInfo(FOO(Luminance32F
), 4, 32,0,0, 0, 0,0, UnsizedFormat::L
, false, ComponentType::Float
);
463 AddFormatInfo(FOO(Alpha32F
), 4, 0,0,0,32, 0,0, UnsizedFormat::A
, false, ComponentType::Float
);
465 // OES_texture_half_float
466 AddFormatInfo(FOO(Luminance16FAlpha16F
), 4, 16,0,0,16, 0,0, UnsizedFormat::LA
, false, ComponentType::Float
);
467 AddFormatInfo(FOO(Luminance16F
), 2, 16,0,0, 0, 0,0, UnsizedFormat::L
, false, ComponentType::Float
);
468 AddFormatInfo(FOO(Alpha16F
), 2, 0,0,0,16, 0,0, UnsizedFormat::A
, false, ComponentType::Float
);
472 ////////////////////////////////////////////////////////////////////////////
474 const auto fnSetCopyDecay
= [](EffectiveFormat src
, EffectiveFormat asR
,
475 EffectiveFormat asRG
, EffectiveFormat asRGB
,
476 EffectiveFormat asRGBA
, EffectiveFormat asL
,
477 EffectiveFormat asA
, EffectiveFormat asLA
)
479 auto& map
= GetFormatInfo_NoLock(src
)->copyDecayFormats
;
481 const auto fnSet
= [&map
](UnsizedFormat uf
, EffectiveFormat ef
) {
482 if (ef
== EffectiveFormat::MAX
)
485 const auto* format
= GetFormatInfo_NoLock(ef
);
486 MOZ_ASSERT(format
->unsizedFormat
== uf
);
487 AlwaysInsert(map
, uf
, format
);
490 fnSet(UnsizedFormat::R
, asR
);
491 fnSet(UnsizedFormat::RG
, asRG
);
492 fnSet(UnsizedFormat::RGB
, asRGB
);
493 fnSet(UnsizedFormat::RGBA
, asRGBA
);
494 fnSet(UnsizedFormat::L
, asL
);
495 fnSet(UnsizedFormat::A
, asA
);
496 fnSet(UnsizedFormat::LA
, asLA
);
499 #define SET_COPY_DECAY(src,asR,asRG,asRGB,asRGBA,asL,asA,asLA) \
500 fnSetCopyDecay(EffectiveFormat::src, EffectiveFormat::asR, EffectiveFormat::asRG, \
501 EffectiveFormat::asRGB, EffectiveFormat::asRGBA, EffectiveFormat::asL, \
502 EffectiveFormat::asA, EffectiveFormat::asLA);
506 #define SET_BY_SUFFIX(X) \
507 SET_COPY_DECAY( R##X, R##X, MAX, MAX, MAX, Luminance##X, MAX, MAX) \
508 SET_COPY_DECAY( RG##X, R##X, RG##X, MAX, MAX, Luminance##X, MAX, MAX) \
509 SET_COPY_DECAY( RGB##X, R##X, RG##X, RGB##X, MAX, Luminance##X, MAX, MAX) \
510 SET_COPY_DECAY(RGBA##X, R##X, RG##X, RGB##X, RGBA##X, Luminance##X, Alpha##X, Luminance##X##Alpha##X)
512 SET_BY_SUFFIX(8) // WebGL decided that RGB8 should be guaranteed renderable.
513 SET_BY_SUFFIX(16F
) // RGB16F is renderable in EXT_color_buffer_half_float, though not
514 // EXT_color_buffer_float.
515 SET_BY_SUFFIX(32F
) // Technically RGB32F is never renderable, but no harm here.
522 #define SET_BY_SUFFIX(X) \
523 SET_COPY_DECAY( R##X, R##X, MAX, MAX, MAX, MAX, MAX, MAX) \
524 SET_COPY_DECAY( RG##X, R##X, RG##X, MAX, MAX, MAX, MAX, MAX) \
525 SET_COPY_DECAY(RGBA##X, R##X, RG##X, RGB##X, RGBA##X, MAX, MAX, MAX)
541 SET_COPY_DECAY( RGB565
, R8
, RG8
, RGB565
, MAX
, Luminance8
, MAX
, MAX
)
542 SET_COPY_DECAY( RGBA4
, R8
, RG8
, RGB565
, RGBA4
, Luminance8
, Alpha8
, Luminance8Alpha8
)
543 SET_COPY_DECAY( RGB5_A1
, R8
, RG8
, RGB565
, RGB5_A1
, Luminance8
, Alpha8
, Luminance8Alpha8
)
544 SET_COPY_DECAY( RGB10_A2
, R8
, RG8
, RGB8
, RGB10_A2
, Luminance8
, Alpha8
, MAX
)
546 SET_COPY_DECAY(RGB10_A2UI
, R8UI
, RG8UI
, RGB8UI
, RGB10_A2UI
, MAX
, MAX
, MAX
)
548 SET_COPY_DECAY(SRGB8_ALPHA8
, MAX
, MAX
, MAX
, SRGB8_ALPHA8
, MAX
, Alpha8
, MAX
)
550 SET_COPY_DECAY(R11F_G11F_B10F
, R16F
, RG16F
, R11F_G11F_B10F
, MAX
, Luminance16F
, MAX
, MAX
)
552 #undef SET_COPY_DECAY
557 //////////////////////////////////////////////////////////////////////////////////////////
559 bool gAreFormatTablesInitialized
= false;
561 static void EnsureInitFormatTables(
562 const StaticMutexAutoLock
&) // Prove that you locked it!
564 if (MOZ_LIKELY(gAreFormatTablesInitialized
)) return;
566 gAreFormatTablesInitialized
= true;
568 InitCompressedFormatInfo();
572 //////////////////////////////////////////////////////////////////////////////////////////
575 StaticMutex gFormatMapMutex
;
577 const FormatInfo
* GetFormat(EffectiveFormat format
) {
578 StaticMutexAutoLock
lock(gFormatMapMutex
);
579 EnsureInitFormatTables(lock
);
581 return GetFormatInfo_NoLock(format
);
584 //////////////////////////////////////////////////////////////////////////////////////////
586 const FormatInfo
* FormatInfo::GetCopyDecayFormat(UnsizedFormat uf
) const {
587 return FindOrNull(this->copyDecayFormats
, uf
);
590 Maybe
<PackingInfoInfo
> PackingInfoInfo::For(const PackingInfo
& pi
) {
591 PackingInfoInfo ret
{};
594 case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4
:
595 case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1
:
596 case LOCAL_GL_UNSIGNED_SHORT_5_6_5
:
600 case LOCAL_GL_UNSIGNED_INT_10F_11F_11F_REV
:
601 case LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV
:
602 case LOCAL_GL_UNSIGNED_INT_24_8
:
603 case LOCAL_GL_UNSIGNED_INT_5_9_9_9_REV
:
607 case LOCAL_GL_FLOAT_32_UNSIGNED_INT_24_8_REV
:
611 // Alright, that's all the fixed-size unpackTypes.
614 case LOCAL_GL_UNSIGNED_BYTE
:
619 case LOCAL_GL_UNSIGNED_SHORT
:
620 case LOCAL_GL_HALF_FLOAT
:
621 case LOCAL_GL_HALF_FLOAT_OES
:
626 case LOCAL_GL_UNSIGNED_INT
:
638 case LOCAL_GL_RED_INTEGER
:
639 case LOCAL_GL_LUMINANCE
:
641 case LOCAL_GL_DEPTH_COMPONENT
:
642 ret
.elementsPerPixel
= 1;
646 case LOCAL_GL_RG_INTEGER
:
647 case LOCAL_GL_LUMINANCE_ALPHA
:
648 ret
.elementsPerPixel
= 2;
652 case LOCAL_GL_RGB_INTEGER
:
654 ret
.elementsPerPixel
= 3;
659 case LOCAL_GL_RGBA_INTEGER
:
660 case LOCAL_GL_SRGB_ALPHA
:
661 ret
.elementsPerPixel
= 4;
672 bool GetBytesPerPixel(const PackingInfo
& packing
, uint8_t* const out_bytes
) {
673 const auto pii
= PackingInfoInfo::For(packing
);
674 if (!pii
) return false;
675 *out_bytes
= pii
->BytesPerPixel();
679 uint8_t BytesPerPixel(const PackingInfo
& packing
) {
681 if (MOZ_LIKELY(GetBytesPerPixel(packing
, &ret
))) return ret
;
683 gfxCriticalError() << "Bad `packing`: " << gfx::hexa(packing
.format
) << ", "
684 << gfx::hexa(packing
.type
);
685 MOZ_CRASH("Bad `packing`.");
688 //////////////////////////////////////////////////////////////////////////////////////////
689 //////////////////////////////////////////////////////////////////////////////////////////
690 //////////////////////////////////////////////////////////////////////////////////////////
691 //////////////////////////////////////////////////////////////////////////////////////////
692 //////////////////////////////////////////////////////////////////////////////////////////
693 //////////////////////////////////////////////////////////////////////////////////////////
694 //////////////////////////////////////////////////////////////////////////////////////////
695 //////////////////////////////////////////////////////////////////////////////////////////
696 // FormatUsageAuthority
698 bool FormatUsageInfo::IsUnpackValid(
699 const PackingInfo
& key
, const DriverUnpackInfo
** const out_value
) const {
700 auto itr
= validUnpacks
.find(key
);
701 if (itr
== validUnpacks
.end()) return false;
703 *out_value
= &(itr
->second
);
707 void FormatUsageInfo::ResolveMaxSamples(gl::GLContext
& gl
) const {
708 MOZ_ASSERT(gl
.IsCurrent());
709 MOZ_ASSERT(!this->maxSamplesKnown
);
710 MOZ_ASSERT(!this->maxSamples
);
711 this->maxSamplesKnown
= true;
713 const GLenum internalFormat
= this->format
->sizedFormat
;
714 if (!internalFormat
) return;
715 if (!gl
.IsSupported(gl::GLFeature::internalformat_query
)) return;
717 // GL_SAMPLES returns a list in descending order, so ask for just one elem to
719 gl
.fGetInternalformativ(LOCAL_GL_RENDERBUFFER
, internalFormat
,
721 reinterpret_cast<GLint
*>(&this->maxSamples
));
724 ////////////////////////////////////////
726 static void AddSimpleUnsized(FormatUsageAuthority
* fua
, GLenum unpackFormat
,
727 GLenum unpackType
, EffectiveFormat effFormat
) {
728 auto usage
= fua
->EditUsage(effFormat
);
729 usage
->isFilterable
= true;
731 const PackingInfo pi
= {unpackFormat
, unpackType
};
732 const DriverUnpackInfo dui
= {unpackFormat
, unpackFormat
, unpackType
};
733 fua
->AddTexUnpack(usage
, pi
, dui
);
735 fua
->AllowUnsizedTexFormat(pi
, usage
);
738 /*static*/ const GLint
FormatUsageInfo::kLuminanceSwizzleRGBA
[4] = {
739 LOCAL_GL_RED
, LOCAL_GL_RED
, LOCAL_GL_RED
, LOCAL_GL_ONE
};
740 /*static*/ const GLint
FormatUsageInfo::kAlphaSwizzleRGBA
[4] = {
741 LOCAL_GL_ZERO
, LOCAL_GL_ZERO
, LOCAL_GL_ZERO
, LOCAL_GL_RED
};
742 /*static*/ const GLint
FormatUsageInfo::kLumAlphaSwizzleRGBA
[4] = {
743 LOCAL_GL_RED
, LOCAL_GL_RED
, LOCAL_GL_RED
, LOCAL_GL_GREEN
};
745 static bool AddLegacyFormats_LA8(FormatUsageAuthority
* fua
, gl::GLContext
* gl
) {
746 if (gl
->IsCoreProfile()) {
747 if (!gl
->IsSupported(gl::GLFeature::texture_swizzle
)) return false;
750 DriverUnpackInfo dui
;
752 const auto fnAdd
= [fua
, &pi
, &dui
](EffectiveFormat effFormat
,
753 const GLint
* swizzle
) {
754 auto usage
= fua
->EditUsage(effFormat
);
755 usage
->isFilterable
= true;
756 usage
->textureSwizzleRGBA
= swizzle
;
758 fua
->AddTexUnpack(usage
, pi
, dui
);
760 fua
->AllowUnsizedTexFormat(pi
, usage
);
763 pi
= {LOCAL_GL_LUMINANCE
, LOCAL_GL_UNSIGNED_BYTE
};
764 dui
= {LOCAL_GL_R8
, LOCAL_GL_RED
, LOCAL_GL_UNSIGNED_BYTE
};
765 fnAdd(EffectiveFormat::Luminance8
, FormatUsageInfo::kLuminanceSwizzleRGBA
);
767 pi
= {LOCAL_GL_ALPHA
, LOCAL_GL_UNSIGNED_BYTE
};
768 dui
= {LOCAL_GL_R8
, LOCAL_GL_RED
, LOCAL_GL_UNSIGNED_BYTE
};
769 fnAdd(EffectiveFormat::Alpha8
, FormatUsageInfo::kAlphaSwizzleRGBA
);
771 pi
= {LOCAL_GL_LUMINANCE_ALPHA
, LOCAL_GL_UNSIGNED_BYTE
};
772 dui
= {LOCAL_GL_RG8
, LOCAL_GL_RG
, LOCAL_GL_UNSIGNED_BYTE
};
773 fnAdd(EffectiveFormat::Luminance8Alpha8
,
774 FormatUsageInfo::kLumAlphaSwizzleRGBA
);
777 AddSimpleUnsized(fua
, LOCAL_GL_LUMINANCE
, LOCAL_GL_UNSIGNED_BYTE
, EffectiveFormat::Luminance8
);
778 AddSimpleUnsized(fua
, LOCAL_GL_ALPHA
, LOCAL_GL_UNSIGNED_BYTE
, EffectiveFormat::Alpha8
);
779 AddSimpleUnsized(fua
, LOCAL_GL_LUMINANCE_ALPHA
, LOCAL_GL_UNSIGNED_BYTE
, EffectiveFormat::Luminance8Alpha8
);
786 static bool AddUnsizedFormats(FormatUsageAuthority
* fua
, gl::GLContext
* gl
) {
789 // GLES 2.0.25, p63, Table 3.4
790 AddSimpleUnsized(fua
, LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_BYTE
, EffectiveFormat::RGBA8
);
791 AddSimpleUnsized(fua
, LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_SHORT_4_4_4_4
, EffectiveFormat::RGBA4
);
792 AddSimpleUnsized(fua
, LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_SHORT_5_5_5_1
, EffectiveFormat::RGB5_A1
);
793 AddSimpleUnsized(fua
, LOCAL_GL_RGB
, LOCAL_GL_UNSIGNED_BYTE
, EffectiveFormat::RGB8
);
794 AddSimpleUnsized(fua
, LOCAL_GL_RGB
, LOCAL_GL_UNSIGNED_SHORT_5_6_5
, EffectiveFormat::RGB565
);
797 return AddLegacyFormats_LA8(fua
, gl
);
802 void FormatUsageInfo::SetRenderable(const FormatRenderableState
& state
) {
803 if (!renderableState
.IsExplicit()) {
804 renderableState
= state
;
808 const auto format
= this->format
;
809 if (format
->IsColorFormat()) {
810 const auto& map
= format
->copyDecayFormats
;
811 const auto itr
= map
.find(format
->unsizedFormat
);
812 MOZ_ASSERT(itr
!= map
.end(),
813 "Renderable formats must be in copyDecayFormats.");
814 MOZ_ASSERT(itr
->second
== format
);
819 UniquePtr
<FormatUsageAuthority
> FormatUsageAuthority::CreateForWebGL1(
821 UniquePtr
<FormatUsageAuthority
> ret(new FormatUsageAuthority
);
822 const auto ptr
= ret
.get();
824 ////////////////////////////////////////////////////////////////////////////
827 const auto fnSet
= [ptr
](EffectiveFormat effFormat
, bool isRenderable
,
829 MOZ_ASSERT(!ptr
->GetUsage(effFormat
));
831 auto usage
= ptr
->EditUsage(effFormat
);
832 usage
->isFilterable
= isFilterable
;
835 usage
->SetRenderable();
839 // GLES 2.0.25, p117, Table 4.5
840 // RGBA8 is made renderable in WebGL 1.0, "Framebuffer Object Attachments"
843 fnSet(EffectiveFormat::RGBA8
, true, true);
844 fnSet(EffectiveFormat::RGBA4
, true, true);
845 fnSet(EffectiveFormat::RGB5_A1
, true, true);
846 fnSet(EffectiveFormat::RGB565
, true, true);
848 // RGB8 is not guaranteed to be renderable, but we should allow it for
849 // web-compat. Min-capability mode should mark this as non-renderable.
850 fnSet(EffectiveFormat::RGB8
, true, true);
852 fnSet(EffectiveFormat::Luminance8Alpha8
, false, true);
853 fnSet(EffectiveFormat::Luminance8
, false, true);
854 fnSet(EffectiveFormat::Alpha8
, false, true);
856 fnSet(EffectiveFormat::DEPTH_COMPONENT16
, true, true);
857 fnSet(EffectiveFormat::DEPTH_COMPONENT24
, true,
858 true); // Requires WEBGL_depth_texture.
859 fnSet(EffectiveFormat::STENCIL_INDEX8
, true, false);
861 // Added in WebGL 1.0 spec:
862 fnSet(EffectiveFormat::DEPTH24_STENCIL8
, true, true);
864 ////////////////////////////////////
868 ptr->AllowRBFormat(LOCAL_GL_##x, ptr->GetUsage(EffectiveFormat::x))
873 FOO(DEPTH_COMPONENT16
);
875 // FOO(DEPTH24_STENCIL8 ); // WebGL 1 uses DEPTH_STENCIL instead of
880 ptr
->AllowRBFormat(LOCAL_GL_DEPTH_STENCIL
,
881 ptr
->GetUsage(EffectiveFormat::DEPTH24_STENCIL8
));
883 ////////////////////////////////////////////////////////////////////////////
885 if (!AddUnsizedFormats(ptr
, gl
)) return nullptr;
890 UniquePtr
<FormatUsageAuthority
> FormatUsageAuthority::CreateForWebGL2(
892 UniquePtr
<FormatUsageAuthority
> ret(new FormatUsageAuthority
);
893 const auto ptr
= ret
.get();
895 ////////////////////////////////////////////////////////////////////////////
896 // GLES 3.0.4 p111-113
898 const auto fnAddSizedUnpack
= [ptr
](EffectiveFormat effFormat
,
899 GLenum internalFormat
,
900 GLenum unpackFormat
, GLenum unpackType
) {
901 auto usage
= ptr
->EditUsage(effFormat
);
903 const PackingInfo pi
= {unpackFormat
, unpackType
};
904 const DriverUnpackInfo dui
= {internalFormat
, unpackFormat
, unpackType
};
905 ptr
->AddTexUnpack(usage
, pi
, dui
);
909 #define FOO(x) EffectiveFormat::x, LOCAL_GL_ ## x
912 fnAddSizedUnpack(FOO(RGBA8
), LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_BYTE
);
913 fnAddSizedUnpack(FOO(RGBA4
), LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_SHORT_4_4_4_4
);
914 fnAddSizedUnpack(FOO(RGBA4
), LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_BYTE
);
915 fnAddSizedUnpack(FOO(RGB5_A1
), LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_SHORT_5_5_5_1
);
916 fnAddSizedUnpack(FOO(RGB5_A1
), LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_BYTE
);
917 fnAddSizedUnpack(FOO(RGB5_A1
), LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV
);
918 fnAddSizedUnpack(FOO(SRGB8_ALPHA8
), LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_BYTE
);
919 fnAddSizedUnpack(FOO(RGBA8_SNORM
), LOCAL_GL_RGBA
, LOCAL_GL_BYTE
);
920 fnAddSizedUnpack(FOO(RGB10_A2
), LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV
);
921 fnAddSizedUnpack(FOO(RGBA16F
), LOCAL_GL_RGBA
, LOCAL_GL_HALF_FLOAT
);
922 fnAddSizedUnpack(FOO(RGBA16F
), LOCAL_GL_RGBA
, LOCAL_GL_FLOAT
);
923 fnAddSizedUnpack(FOO(RGBA32F
), LOCAL_GL_RGBA
, LOCAL_GL_FLOAT
);
926 fnAddSizedUnpack(FOO(RGBA8UI
), LOCAL_GL_RGBA_INTEGER
, LOCAL_GL_UNSIGNED_BYTE
);
927 fnAddSizedUnpack(FOO(RGBA8I
), LOCAL_GL_RGBA_INTEGER
, LOCAL_GL_BYTE
);
928 fnAddSizedUnpack(FOO(RGBA16UI
), LOCAL_GL_RGBA_INTEGER
, LOCAL_GL_UNSIGNED_SHORT
);
929 fnAddSizedUnpack(FOO(RGBA16I
), LOCAL_GL_RGBA_INTEGER
, LOCAL_GL_SHORT
);
930 fnAddSizedUnpack(FOO(RGBA32UI
), LOCAL_GL_RGBA_INTEGER
, LOCAL_GL_UNSIGNED_INT
);
931 fnAddSizedUnpack(FOO(RGBA32I
), LOCAL_GL_RGBA_INTEGER
, LOCAL_GL_INT
);
932 fnAddSizedUnpack(FOO(RGB10_A2UI
), LOCAL_GL_RGBA_INTEGER
, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV
);
935 fnAddSizedUnpack(FOO(RGB8
), LOCAL_GL_RGB
, LOCAL_GL_UNSIGNED_BYTE
);
936 fnAddSizedUnpack(FOO(SRGB8
), LOCAL_GL_RGB
, LOCAL_GL_UNSIGNED_BYTE
);
937 fnAddSizedUnpack(FOO(RGB565
), LOCAL_GL_RGB
, LOCAL_GL_UNSIGNED_SHORT_5_6_5
);
938 fnAddSizedUnpack(FOO(RGB565
), LOCAL_GL_RGB
, LOCAL_GL_UNSIGNED_BYTE
);
939 fnAddSizedUnpack(FOO(RGB8_SNORM
), LOCAL_GL_RGB
, LOCAL_GL_BYTE
);
940 fnAddSizedUnpack(FOO(R11F_G11F_B10F
), LOCAL_GL_RGB
, LOCAL_GL_UNSIGNED_INT_10F_11F_11F_REV
);
941 fnAddSizedUnpack(FOO(R11F_G11F_B10F
), LOCAL_GL_RGB
, LOCAL_GL_HALF_FLOAT
);
942 fnAddSizedUnpack(FOO(R11F_G11F_B10F
), LOCAL_GL_RGB
, LOCAL_GL_FLOAT
);
943 fnAddSizedUnpack(FOO(RGB16F
), LOCAL_GL_RGB
, LOCAL_GL_HALF_FLOAT
);
944 fnAddSizedUnpack(FOO(RGB16F
), LOCAL_GL_RGB
, LOCAL_GL_FLOAT
);
945 fnAddSizedUnpack(FOO(RGB9_E5
), LOCAL_GL_RGB
, LOCAL_GL_UNSIGNED_INT_5_9_9_9_REV
);
946 fnAddSizedUnpack(FOO(RGB9_E5
), LOCAL_GL_RGB
, LOCAL_GL_HALF_FLOAT
);
947 fnAddSizedUnpack(FOO(RGB9_E5
), LOCAL_GL_RGB
, LOCAL_GL_FLOAT
);
948 fnAddSizedUnpack(FOO(RGB32F
), LOCAL_GL_RGB
, LOCAL_GL_FLOAT
);
951 fnAddSizedUnpack(FOO(RGB8UI
), LOCAL_GL_RGB_INTEGER
, LOCAL_GL_UNSIGNED_BYTE
);
952 fnAddSizedUnpack(FOO(RGB8I
), LOCAL_GL_RGB_INTEGER
, LOCAL_GL_BYTE
);
953 fnAddSizedUnpack(FOO(RGB16UI
), LOCAL_GL_RGB_INTEGER
, LOCAL_GL_UNSIGNED_SHORT
);
954 fnAddSizedUnpack(FOO(RGB16I
), LOCAL_GL_RGB_INTEGER
, LOCAL_GL_SHORT
);
955 fnAddSizedUnpack(FOO(RGB32UI
), LOCAL_GL_RGB_INTEGER
, LOCAL_GL_UNSIGNED_INT
);
956 fnAddSizedUnpack(FOO(RGB32I
), LOCAL_GL_RGB_INTEGER
, LOCAL_GL_INT
);
959 fnAddSizedUnpack(FOO(RG8
), LOCAL_GL_RG
, LOCAL_GL_UNSIGNED_BYTE
);
960 fnAddSizedUnpack(FOO(RG8_SNORM
), LOCAL_GL_RG
, LOCAL_GL_BYTE
);
961 fnAddSizedUnpack(FOO(RG16F
), LOCAL_GL_RG
, LOCAL_GL_HALF_FLOAT
);
962 fnAddSizedUnpack(FOO(RG16F
), LOCAL_GL_RG
, LOCAL_GL_FLOAT
);
963 fnAddSizedUnpack(FOO(RG32F
), LOCAL_GL_RG
, LOCAL_GL_FLOAT
);
966 fnAddSizedUnpack(FOO(RG8UI
), LOCAL_GL_RG_INTEGER
, LOCAL_GL_UNSIGNED_BYTE
);
967 fnAddSizedUnpack(FOO(RG8I
), LOCAL_GL_RG_INTEGER
, LOCAL_GL_BYTE
);
968 fnAddSizedUnpack(FOO(RG16UI
), LOCAL_GL_RG_INTEGER
, LOCAL_GL_UNSIGNED_SHORT
);
969 fnAddSizedUnpack(FOO(RG16I
), LOCAL_GL_RG_INTEGER
, LOCAL_GL_SHORT
);
970 fnAddSizedUnpack(FOO(RG32UI
), LOCAL_GL_RG_INTEGER
, LOCAL_GL_UNSIGNED_INT
);
971 fnAddSizedUnpack(FOO(RG32I
), LOCAL_GL_RG_INTEGER
, LOCAL_GL_INT
);
974 fnAddSizedUnpack(FOO(R8
), LOCAL_GL_RED
, LOCAL_GL_UNSIGNED_BYTE
);
975 fnAddSizedUnpack(FOO(R8_SNORM
), LOCAL_GL_RED
, LOCAL_GL_BYTE
);
976 fnAddSizedUnpack(FOO(R16F
), LOCAL_GL_RED
, LOCAL_GL_HALF_FLOAT
);
977 fnAddSizedUnpack(FOO(R16F
), LOCAL_GL_RED
, LOCAL_GL_FLOAT
);
978 fnAddSizedUnpack(FOO(R32F
), LOCAL_GL_RED
, LOCAL_GL_FLOAT
);
981 fnAddSizedUnpack(FOO(R8UI
), LOCAL_GL_RED_INTEGER
, LOCAL_GL_UNSIGNED_BYTE
);
982 fnAddSizedUnpack(FOO(R8I
), LOCAL_GL_RED_INTEGER
, LOCAL_GL_BYTE
);
983 fnAddSizedUnpack(FOO(R16UI
), LOCAL_GL_RED_INTEGER
, LOCAL_GL_UNSIGNED_SHORT
);
984 fnAddSizedUnpack(FOO(R16I
), LOCAL_GL_RED_INTEGER
, LOCAL_GL_SHORT
);
985 fnAddSizedUnpack(FOO(R32UI
), LOCAL_GL_RED_INTEGER
, LOCAL_GL_UNSIGNED_INT
);
986 fnAddSizedUnpack(FOO(R32I
), LOCAL_GL_RED_INTEGER
, LOCAL_GL_INT
);
989 fnAddSizedUnpack(FOO(DEPTH_COMPONENT16
), LOCAL_GL_DEPTH_COMPONENT
, LOCAL_GL_UNSIGNED_SHORT
);
990 fnAddSizedUnpack(FOO(DEPTH_COMPONENT16
), LOCAL_GL_DEPTH_COMPONENT
, LOCAL_GL_UNSIGNED_INT
);
991 fnAddSizedUnpack(FOO(DEPTH_COMPONENT24
), LOCAL_GL_DEPTH_COMPONENT
, LOCAL_GL_UNSIGNED_INT
);
992 fnAddSizedUnpack(FOO(DEPTH_COMPONENT32F
), LOCAL_GL_DEPTH_COMPONENT
, LOCAL_GL_FLOAT
);
995 fnAddSizedUnpack(FOO(DEPTH24_STENCIL8
), LOCAL_GL_DEPTH_STENCIL
, LOCAL_GL_UNSIGNED_INT_24_8
);
996 fnAddSizedUnpack(FOO(DEPTH32F_STENCIL8
), LOCAL_GL_DEPTH_STENCIL
, LOCAL_GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
1001 ////////////////////////////////////////////////////////////////////////////
1003 // For renderable, see GLES 3.0.4, p212 "Framebuffer Completeness"
1004 // For filterable, see GLES 3.0.4, p161 "...a texture is complete unless..."
1006 const auto fnAllowES3TexFormat
= [ptr
](GLenum sizedFormat
,
1007 EffectiveFormat effFormat
,
1008 bool isRenderable
, bool isFilterable
) {
1009 auto usage
= ptr
->EditUsage(effFormat
);
1010 usage
->isFilterable
= isFilterable
;
1013 usage
->SetRenderable();
1016 ptr
->AllowSizedTexFormat(sizedFormat
, usage
);
1019 ptr
->AllowRBFormat(sizedFormat
, usage
);
1023 #define FOO(x) LOCAL_GL_##x, EffectiveFormat::x
1025 // GLES 3.0.4, p128-129 "Required Texture Formats"
1026 // GLES 3.0.4, p130-132, table 3.13
1029 fnAllowES3TexFormat(FOO(R8
), true, true);
1030 fnAllowES3TexFormat(FOO(R8_SNORM
), false, true);
1031 fnAllowES3TexFormat(FOO(RG8
), true, true);
1032 fnAllowES3TexFormat(FOO(RG8_SNORM
), false, true);
1033 fnAllowES3TexFormat(FOO(RGB8
), true, true);
1034 fnAllowES3TexFormat(FOO(RGB8_SNORM
), false, true);
1035 fnAllowES3TexFormat(FOO(RGB565
), true, true);
1036 fnAllowES3TexFormat(FOO(RGBA4
), true, true);
1037 fnAllowES3TexFormat(FOO(RGB5_A1
), true, true);
1038 fnAllowES3TexFormat(FOO(RGBA8
), true, true);
1039 fnAllowES3TexFormat(FOO(RGBA8_SNORM
), false, true);
1040 fnAllowES3TexFormat(FOO(RGB10_A2
), true, true);
1041 fnAllowES3TexFormat(FOO(RGB10_A2UI
), true, false);
1043 fnAllowES3TexFormat(FOO(SRGB8
), false, true);
1044 fnAllowES3TexFormat(FOO(SRGB8_ALPHA8
), true, true);
1046 fnAllowES3TexFormat(FOO(R16F
), false, true);
1047 fnAllowES3TexFormat(FOO(RG16F
), false, true);
1048 fnAllowES3TexFormat(FOO(RGB16F
), false, true);
1049 fnAllowES3TexFormat(FOO(RGBA16F
), false, true);
1051 fnAllowES3TexFormat(FOO(R32F
), false, false);
1052 fnAllowES3TexFormat(FOO(RG32F
), false, false);
1053 fnAllowES3TexFormat(FOO(RGB32F
), false, false);
1054 fnAllowES3TexFormat(FOO(RGBA32F
), false, false);
1056 fnAllowES3TexFormat(FOO(R11F_G11F_B10F
), false, true);
1057 fnAllowES3TexFormat(FOO(RGB9_E5
), false, true);
1059 fnAllowES3TexFormat(FOO(R8I
), true, false);
1060 fnAllowES3TexFormat(FOO(R8UI
), true, false);
1061 fnAllowES3TexFormat(FOO(R16I
), true, false);
1062 fnAllowES3TexFormat(FOO(R16UI
), true, false);
1063 fnAllowES3TexFormat(FOO(R32I
), true, false);
1064 fnAllowES3TexFormat(FOO(R32UI
), true, false);
1066 fnAllowES3TexFormat(FOO(RG8I
), true, false);
1067 fnAllowES3TexFormat(FOO(RG8UI
), true, false);
1068 fnAllowES3TexFormat(FOO(RG16I
), true, false);
1069 fnAllowES3TexFormat(FOO(RG16UI
), true, false);
1070 fnAllowES3TexFormat(FOO(RG32I
), true, false);
1071 fnAllowES3TexFormat(FOO(RG32UI
), true, false);
1073 fnAllowES3TexFormat(FOO(RGB8I
), false, false);
1074 fnAllowES3TexFormat(FOO(RGB8UI
), false, false);
1075 fnAllowES3TexFormat(FOO(RGB16I
), false, false);
1076 fnAllowES3TexFormat(FOO(RGB16UI
), false, false);
1077 fnAllowES3TexFormat(FOO(RGB32I
), false, false);
1078 fnAllowES3TexFormat(FOO(RGB32UI
), false, false);
1080 fnAllowES3TexFormat(FOO(RGBA8I
), true, false);
1081 fnAllowES3TexFormat(FOO(RGBA8UI
), true, false);
1082 fnAllowES3TexFormat(FOO(RGBA16I
), true, false);
1083 fnAllowES3TexFormat(FOO(RGBA16UI
), true, false);
1084 fnAllowES3TexFormat(FOO(RGBA32I
), true, false);
1085 fnAllowES3TexFormat(FOO(RGBA32UI
), true, false);
1087 // Sized depth or depth-stencil formats are not filterable
1088 // per GLES 3.0.6 p161.
1089 // Specifically, they're texture-incomplete if depth-compare:none and
1091 fnAllowES3TexFormat(FOO(DEPTH_COMPONENT16
), true, false);
1092 fnAllowES3TexFormat(FOO(DEPTH_COMPONENT24
), true, false);
1093 fnAllowES3TexFormat(FOO(DEPTH_COMPONENT32F
), true, false);
1094 fnAllowES3TexFormat(FOO(DEPTH24_STENCIL8
), true, false);
1095 fnAllowES3TexFormat(FOO(DEPTH32F_STENCIL8
), true, false);
1099 // GLES 3.0.4, p206, "Required Renderbuffer Formats":
1100 // "Implementations are also required to support STENCIL_INDEX8. Requesting
1101 // this internal format for a renderbuffer will allocate at least 8 stencil
1104 auto usage
= ptr
->EditUsage(EffectiveFormat::STENCIL_INDEX8
);
1105 usage
->SetRenderable();
1106 ptr
->AllowRBFormat(LOCAL_GL_STENCIL_INDEX8
, usage
);
1111 if (!AddUnsizedFormats(ptr
, gl
)) return nullptr;
1113 ptr
->AllowRBFormat(LOCAL_GL_DEPTH_STENCIL
,
1114 ptr
->GetUsage(EffectiveFormat::DEPTH24_STENCIL8
));
1116 ////////////////////////////////////
1121 //////////////////////////////////////////////////////////////////////////////////////////
1123 void FormatUsageAuthority::AddTexUnpack(FormatUsageInfo
* usage
,
1124 const PackingInfo
& pi
,
1125 const DriverUnpackInfo
& dui
) {
1126 // Don't AlwaysInsert here, since we'll see duplicates from sized and unsized
1128 auto res
= usage
->validUnpacks
.insert({pi
, dui
});
1129 auto itr
= res
.first
;
1131 if (!usage
->idealUnpack
) {
1133 usage
->idealUnpack
= &(itr
->second
);
1136 mValidTexUnpackFormats
.insert(pi
.format
);
1137 mValidTexUnpackTypes
.insert(pi
.type
);
1140 static bool Contains(const std::set
<GLenum
>& set
, GLenum key
) {
1141 return set
.find(key
) != set
.end();
1144 bool FormatUsageAuthority::IsInternalFormatEnumValid(
1145 GLenum internalFormat
) const {
1146 return Contains(mValidTexInternalFormats
, internalFormat
);
1149 bool FormatUsageAuthority::AreUnpackEnumsValid(GLenum unpackFormat
,
1150 GLenum unpackType
) const {
1151 return (Contains(mValidTexUnpackFormats
, unpackFormat
) &&
1152 Contains(mValidTexUnpackTypes
, unpackType
));
1155 ////////////////////
1157 void FormatUsageAuthority::AllowRBFormat(GLenum sizedFormat
,
1158 const FormatUsageInfo
* usage
,
1159 const bool expectRenderable
) {
1160 MOZ_ASSERT(!usage
->format
->compression
);
1161 MOZ_ASSERT(usage
->format
->sizedFormat
);
1162 MOZ_ASSERT(usage
->IsRenderable() || !expectRenderable
);
1164 const auto& found
= mRBFormatMap
.find(sizedFormat
);
1165 if (found
!= mRBFormatMap
.end()) {
1166 MOZ_ASSERT(found
->second
== usage
);
1169 AlwaysInsert(mRBFormatMap
, sizedFormat
, usage
);
1172 void FormatUsageAuthority::AllowSizedTexFormat(GLenum sizedFormat
,
1173 const FormatUsageInfo
* usage
) {
1174 if (usage
->format
->compression
) {
1175 MOZ_ASSERT(usage
->isFilterable
, "Compressed formats should be filterable.");
1177 MOZ_ASSERT(!usage
->validUnpacks
.empty() && usage
->idealUnpack
,
1178 "AddTexUnpack() first.");
1181 AlwaysInsert(mSizedTexFormatMap
, sizedFormat
, usage
);
1183 mValidTexInternalFormats
.insert(sizedFormat
);
1186 void FormatUsageAuthority::AllowUnsizedTexFormat(const PackingInfo
& pi
,
1187 const FormatUsageInfo
* usage
) {
1188 MOZ_ASSERT(!usage
->format
->compression
);
1189 MOZ_ASSERT(!usage
->validUnpacks
.empty() && usage
->idealUnpack
,
1190 "AddTexUnpack() first.");
1192 AlwaysInsert(mUnsizedTexFormatMap
, pi
, usage
);
1194 mValidTexInternalFormats
.insert(pi
.format
);
1195 mValidTexUnpackFormats
.insert(pi
.format
);
1196 mValidTexUnpackTypes
.insert(pi
.type
);
1199 const FormatUsageInfo
* FormatUsageAuthority::GetRBUsage(
1200 GLenum sizedFormat
) const {
1201 return FindOrNull(mRBFormatMap
, sizedFormat
);
1204 const FormatUsageInfo
* FormatUsageAuthority::GetSizedTexUsage(
1205 GLenum sizedFormat
) const {
1206 return FindOrNull(mSizedTexFormatMap
, sizedFormat
);
1209 const FormatUsageInfo
* FormatUsageAuthority::GetUnsizedTexUsage(
1210 const PackingInfo
& pi
) const {
1211 return FindOrNull(mUnsizedTexFormatMap
, pi
);
1214 FormatUsageInfo
* FormatUsageAuthority::EditUsage(EffectiveFormat format
) {
1215 auto itr
= mUsageMap
.find(format
);
1217 if (itr
== mUsageMap
.end()) {
1218 const FormatInfo
* formatInfo
= GetFormat(format
);
1219 MOZ_RELEASE_ASSERT(formatInfo
, "GFX: no format info set.");
1221 FormatUsageInfo
usage(formatInfo
);
1223 auto res
= mUsageMap
.insert({format
, usage
});
1224 DebugOnly
<bool> didInsert
= res
.second
;
1225 MOZ_ASSERT(didInsert
);
1230 return &(itr
->second
);
1233 const FormatUsageInfo
* FormatUsageAuthority::GetUsage(
1234 EffectiveFormat format
) const {
1235 auto itr
= mUsageMap
.find(format
);
1236 if (itr
== mUsageMap
.end()) return nullptr;
1238 return &(itr
->second
);
1241 ////////////////////////////////////////////////////////////////////////////////
1243 } // namespace mozilla::webgl