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 #ifndef WEBGL_FORMATS_H_
7 #define WEBGL_FORMATS_H_
12 #include "mozilla/UniquePtr.h"
13 #include "WebGLTypes.h"
15 namespace mozilla::webgl
{
17 using EffectiveFormatValueT
= uint8_t;
19 enum class EffectiveFormat
: EffectiveFormatValueT
{
20 // GLES 3.0.4, p128-129, "Required Texture Formats"
21 // "Texture and renderbuffer color formats"
54 // "Texture-only color formats"
88 // "Combined depth+stencil formats"
92 // GLES 3.0.4, p205-206, "Required Renderbuffer Formats"
95 ////////////////////////////////////
97 // GLES 3.0.4, p147, table 3.19
98 // GLES 3.0.4, p286+, $C.1 "ETC Compressed Texture Image Formats"
100 COMPRESSED_SIGNED_R11_EAC
,
102 COMPRESSED_SIGNED_RG11_EAC
,
103 COMPRESSED_RGB8_ETC2
,
104 COMPRESSED_SRGB8_ETC2
,
105 COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
,
106 COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
,
107 COMPRESSED_RGBA8_ETC2_EAC
,
108 COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
,
110 // EXT_texture_compression_bptc
111 COMPRESSED_RGBA_BPTC_UNORM
,
112 COMPRESSED_SRGB_ALPHA_BPTC_UNORM
,
113 COMPRESSED_RGB_BPTC_SIGNED_FLOAT
,
114 COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT
,
116 // EXT_texture_compression_rgtc
117 COMPRESSED_RED_RGTC1
,
118 COMPRESSED_SIGNED_RED_RGTC1
,
120 COMPRESSED_SIGNED_RG_RGTC2
,
122 // EXT_texture_compression_s3tc
123 COMPRESSED_RGB_S3TC_DXT1_EXT
,
124 COMPRESSED_RGBA_S3TC_DXT1_EXT
,
125 COMPRESSED_RGBA_S3TC_DXT3_EXT
,
126 COMPRESSED_RGBA_S3TC_DXT5_EXT
,
129 COMPRESSED_SRGB_S3TC_DXT1_EXT
,
130 COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
,
131 COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
,
132 COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
,
134 // KHR_texture_compression_astc_ldr
135 COMPRESSED_RGBA_ASTC_4x4_KHR
,
136 COMPRESSED_RGBA_ASTC_5x4_KHR
,
137 COMPRESSED_RGBA_ASTC_5x5_KHR
,
138 COMPRESSED_RGBA_ASTC_6x5_KHR
,
139 COMPRESSED_RGBA_ASTC_6x6_KHR
,
140 COMPRESSED_RGBA_ASTC_8x5_KHR
,
141 COMPRESSED_RGBA_ASTC_8x6_KHR
,
142 COMPRESSED_RGBA_ASTC_8x8_KHR
,
143 COMPRESSED_RGBA_ASTC_10x5_KHR
,
144 COMPRESSED_RGBA_ASTC_10x6_KHR
,
145 COMPRESSED_RGBA_ASTC_10x8_KHR
,
146 COMPRESSED_RGBA_ASTC_10x10_KHR
,
147 COMPRESSED_RGBA_ASTC_12x10_KHR
,
148 COMPRESSED_RGBA_ASTC_12x12_KHR
,
150 COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR
,
151 COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR
,
152 COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR
,
153 COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR
,
154 COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR
,
155 COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR
,
156 COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR
,
157 COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR
,
158 COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR
,
159 COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR
,
160 COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR
,
161 COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR
,
162 COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR
,
163 COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR
,
165 // IMG_texture_compression_pvrtc
166 COMPRESSED_RGB_PVRTC_4BPPV1
,
167 COMPRESSED_RGBA_PVRTC_4BPPV1
,
168 COMPRESSED_RGB_PVRTC_2BPPV1
,
169 COMPRESSED_RGBA_PVRTC_2BPPV1
,
171 // OES_compressed_ETC1_RGB8_texture
174 ////////////////////////////////////
176 // GLES 3.0.4, p128, table 3.12.
182 Luminance32FAlpha32F
,
186 // OES_texture_half_float
187 Luminance16FAlpha16F
,
191 // EXT_texture_norm16
204 enum class UnsizedFormat
: uint8_t {
214 DEPTH_STENCIL
, // `DS` is a macro on Solaris. (regset.h)
217 // GLES 3.0.4 p114 Table 3.4, p240
218 enum class ComponentType
: uint8_t {
221 NormInt
, // RGBA8_SNORM
225 const char* ToString(ComponentType
);
227 enum class TextureBaseType
: uint8_t {
228 Int
= uint8_t(ComponentType::Int
),
229 UInt
= uint8_t(ComponentType::UInt
),
230 Float
= uint8_t(ComponentType::Float
), // Also includes NormU?Int and Depth
233 const char* ToString(TextureBaseType
);
235 enum class CompressionFamily
: uint8_t {
245 ////////////////////////////////////////////////////////////////////////////////
247 struct CompressedFormatInfo
{
248 const EffectiveFormat effectiveFormat
;
249 const uint8_t bytesPerBlock
;
250 const uint8_t blockWidth
;
251 const uint8_t blockHeight
;
252 const CompressionFamily family
;
256 const EffectiveFormat effectiveFormat
;
257 const char* const name
;
258 const GLenum sizedFormat
;
259 const UnsizedFormat unsizedFormat
;
260 const ComponentType componentType
;
261 const TextureBaseType baseType
;
264 const CompressedFormatInfo
* const compression
;
266 const uint8_t estimatedBytesPerPixel
; // 0 iff bool(compression).
268 // In bits. Iff bool(compression), active channels are 1.
278 std::map
<UnsizedFormat
, const FormatInfo
*> copyDecayFormats
;
280 const FormatInfo
* GetCopyDecayFormat(UnsizedFormat
) const;
282 bool IsColorFormat() const {
283 // Alpha is a 'color format' since it's 'color-attachable'.
284 return bool(compression
) || bool(r
| g
| b
| a
);
288 //////////////////////////////////////////////////////////////////////////////////////////
290 struct PackingInfoInfo final
{
291 uint8_t bytesPerElement
= 0;
292 uint8_t elementsPerPixel
= 0; // E.g. 1 for LOCAL_GL_UNSIGNED_SHORT_4_4_4_4
293 bool isPacked
= false;
295 static Maybe
<PackingInfoInfo
> For(const PackingInfo
&);
297 inline uint8_t BytesPerPixel() const {
298 return bytesPerElement
* elementsPerPixel
;
302 const FormatInfo
* GetFormat(EffectiveFormat format
);
304 inline uint8_t BytesPerPixel(const PackingInfo
& packing
) {
305 const auto pii
= PackingInfoInfo::For(packing
);
306 if (MOZ_LIKELY(pii
)) return pii
->BytesPerPixel();
308 gfxCriticalError() << "Bad BytesPerPixel(" << packing
<< ")";
309 MOZ_CRASH("Bad `packing`.");
313 GLint ComponentSize(const FormatInfo* format, GLenum component);
314 GLenum ComponentType(const FormatInfo* format);
316 ////////////////////////////////////////
318 struct FormatRenderableState final
{
320 enum class RenderableState
{
327 RenderableState state
= RenderableState::Disabled
;
328 WebGLExtensionID extid
= WebGLExtensionID::Max
;
330 static FormatRenderableState
Explicit() {
331 return {RenderableState::Explicit
};
334 static FormatRenderableState
Implicit(WebGLExtensionID extid
) {
335 return {RenderableState::Implicit
, extid
};
338 bool IsRenderable() const { return state
!= RenderableState::Disabled
; }
339 bool IsExplicit() const { return state
== RenderableState::Explicit
; }
342 struct FormatUsageInfo
{
343 const FormatInfo
* const format
;
346 FormatRenderableState renderableState
;
349 bool isFilterable
= false;
351 std::map
<PackingInfo
, DriverUnpackInfo
> validUnpacks
;
352 const DriverUnpackInfo
* idealUnpack
= nullptr;
354 const GLint
* textureSwizzleRGBA
= nullptr;
357 mutable bool maxSamplesKnown
= false;
358 mutable uint32_t maxSamples
= 0;
361 static const GLint kLuminanceSwizzleRGBA
[4];
362 static const GLint kAlphaSwizzleRGBA
[4];
363 static const GLint kLumAlphaSwizzleRGBA
[4];
365 explicit FormatUsageInfo(const FormatInfo
* const _format
) : format(_format
) {
366 if (format
->IsColorFormat() && format
->baseType
!= TextureBaseType::Float
) {
367 maxSamplesKnown
= true;
371 bool IsRenderable() const { return renderableState
.IsRenderable(); }
373 const FormatRenderableState
& state
= FormatRenderableState::Explicit());
374 bool IsExplicitlyRenderable() const { return renderableState
.IsExplicit(); }
375 WebGLExtensionID
GetExtensionID() const {
376 MOZ_ASSERT(renderableState
.extid
!= WebGLExtensionID::Max
);
377 return renderableState
.extid
;
380 bool IsUnpackValid(const PackingInfo
& key
,
381 const DriverUnpackInfo
** const out_value
) const;
384 void ResolveMaxSamples(gl::GLContext
& gl
) const;
387 uint32_t MaxSamples(gl::GLContext
& gl
) const {
388 if (!maxSamplesKnown
) {
389 ResolveMaxSamples(gl
);
395 class FormatUsageAuthority
{
396 std::map
<EffectiveFormat
, FormatUsageInfo
> mUsageMap
;
398 std::map
<GLenum
, const FormatUsageInfo
*> mRBFormatMap
;
399 std::map
<GLenum
, const FormatUsageInfo
*> mSizedTexFormatMap
;
400 std::map
<PackingInfo
, const FormatUsageInfo
*> mUnsizedTexFormatMap
;
402 std::set
<GLenum
> mValidTexInternalFormats
;
403 std::set
<GLenum
> mValidTexUnpackFormats
;
404 std::set
<GLenum
> mValidTexUnpackTypes
;
407 static UniquePtr
<FormatUsageAuthority
> CreateForWebGL1(gl::GLContext
* gl
);
408 static UniquePtr
<FormatUsageAuthority
> CreateForWebGL2(gl::GLContext
* gl
);
411 FormatUsageAuthority() = default;
414 FormatUsageInfo
* EditUsage(EffectiveFormat format
);
415 const FormatUsageInfo
* GetUsage(EffectiveFormat format
) const;
417 void AddTexUnpack(FormatUsageInfo
* usage
, const PackingInfo
& pi
,
418 const DriverUnpackInfo
& dui
);
420 bool IsInternalFormatEnumValid(GLenum internalFormat
) const;
421 bool AreUnpackEnumsValid(GLenum unpackFormat
, GLenum unpackType
) const;
423 void AllowRBFormat(GLenum sizedFormat
, const FormatUsageInfo
* usage
,
424 bool expectRenderable
= true);
425 void AllowSizedTexFormat(GLenum sizedFormat
, const FormatUsageInfo
* usage
);
426 void AllowUnsizedTexFormat(const PackingInfo
& pi
,
427 const FormatUsageInfo
* usage
);
429 const FormatUsageInfo
* GetRBUsage(GLenum sizedFormat
) const;
430 const FormatUsageInfo
* GetSizedTexUsage(GLenum sizedFormat
) const;
431 const FormatUsageInfo
* GetUnsizedTexUsage(const PackingInfo
& pi
) const;
434 } // namespace mozilla::webgl
436 #endif // WEBGL_FORMATS_H_