Backed out changeset 7b83373f7a9e (bug 1883860) for causing build bustages @ caps...
[gecko.git] / dom / canvas / WebGLFormats.h
blob9bee5bfef93c392da835e40af2291b76134af6e8
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_
9 #include <map>
10 #include <set>
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"
22 RGBA32I,
23 RGBA32UI,
24 RGBA16I,
25 RGBA16UI,
26 RGBA8,
27 RGBA8I,
28 RGBA8UI,
29 SRGB8_ALPHA8,
30 RGB10_A2,
31 RGB10_A2UI,
32 RGBA4,
33 RGB5_A1,
35 RGB8,
36 RGB565,
38 RG32I,
39 RG32UI,
40 RG16I,
41 RG16UI,
42 RG8,
43 RG8I,
44 RG8UI,
46 R32I,
47 R32UI,
48 R16I,
49 R16UI,
50 R8,
51 R8I,
52 R8UI,
54 // "Texture-only color formats"
55 RGBA32F,
56 RGBA16F,
57 RGBA8_SNORM,
59 RGB32F,
60 RGB32I,
61 RGB32UI,
63 RGB16F,
64 RGB16I,
65 RGB16UI,
67 RGB8_SNORM,
68 RGB8I,
69 RGB8UI,
70 SRGB8,
72 R11F_G11F_B10F,
73 RGB9_E5,
75 RG32F,
76 RG16F,
77 RG8_SNORM,
79 R32F,
80 R16F,
81 R8_SNORM,
83 // "Depth formats"
84 DEPTH_COMPONENT32F,
85 DEPTH_COMPONENT24,
86 DEPTH_COMPONENT16,
88 // "Combined depth+stencil formats"
89 DEPTH32F_STENCIL8,
90 DEPTH24_STENCIL8,
92 // GLES 3.0.4, p205-206, "Required Renderbuffer Formats"
93 STENCIL_INDEX8,
95 ////////////////////////////////////
97 // GLES 3.0.4, p147, table 3.19
98 // GLES 3.0.4, p286+, $C.1 "ETC Compressed Texture Image Formats"
99 COMPRESSED_R11_EAC,
100 COMPRESSED_SIGNED_R11_EAC,
101 COMPRESSED_RG11_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,
119 COMPRESSED_RG_RGTC2,
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,
128 // EXT_texture_sRGB
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
172 ETC1_RGB8_OES,
174 ////////////////////////////////////
176 // GLES 3.0.4, p128, table 3.12.
177 Luminance8Alpha8,
178 Luminance8,
179 Alpha8,
181 // OES_texture_float
182 Luminance32FAlpha32F,
183 Luminance32F,
184 Alpha32F,
186 // OES_texture_half_float
187 Luminance16FAlpha16F,
188 Luminance16F,
189 Alpha16F,
191 // EXT_texture_norm16
192 R16,
193 RG16,
194 RGB16,
195 RGBA16,
196 R16_SNORM,
197 RG16_SNORM,
198 RGB16_SNORM,
199 RGBA16_SNORM,
201 MAX,
204 enum class UnsizedFormat : uint8_t {
207 RGB,
208 RGBA,
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 {
219 Int, // RGBA32I
220 UInt, // RGBA32UI
221 NormInt, // RGBA8_SNORM
222 NormUInt, // RGBA8
223 Float, // RGBA32F
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 {
236 ASTC,
237 BPTC,
238 ES3, // ETC2 or EAC
239 ETC1,
240 PVRTC,
241 RGTC,
242 S3TC,
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;
255 struct FormatInfo {
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;
262 const bool isSRGB;
264 const CompressedFormatInfo* const compression;
266 const uint8_t estimatedBytesPerPixel; // 0 iff bool(compression).
268 // In bits. Iff bool(compression), active channels are 1.
269 const uint8_t r;
270 const uint8_t g;
271 const uint8_t b;
272 const uint8_t a;
273 const uint8_t d;
274 const uint8_t s;
276 //////
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 {
319 private:
320 enum class RenderableState {
321 Disabled,
322 Implicit,
323 Explicit,
326 public:
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;
345 private:
346 FormatRenderableState renderableState;
348 public:
349 bool isFilterable = false;
351 std::map<PackingInfo, DriverUnpackInfo> validUnpacks;
352 const DriverUnpackInfo* idealUnpack = nullptr;
354 const GLint* textureSwizzleRGBA = nullptr;
356 private:
357 mutable bool maxSamplesKnown = false;
358 mutable uint32_t maxSamples = 0;
360 public:
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(); }
372 void SetRenderable(
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;
383 private:
384 void ResolveMaxSamples(gl::GLContext& gl) const;
386 public:
387 uint32_t MaxSamples(gl::GLContext& gl) const {
388 if (!maxSamplesKnown) {
389 ResolveMaxSamples(gl);
391 return maxSamples;
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;
406 public:
407 static UniquePtr<FormatUsageAuthority> CreateForWebGL1(gl::GLContext* gl);
408 static UniquePtr<FormatUsageAuthority> CreateForWebGL2(gl::GLContext* gl);
410 private:
411 FormatUsageAuthority() = default;
413 public:
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_