Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/. */
5 :
6 : #ifndef WEBGL_FORMATS_H_
7 : #define WEBGL_FORMATS_H_
8 :
9 : #include <map>
10 : #include <set>
11 :
12 : #include "mozilla/UniquePtr.h"
13 : #include "WebGLTypes.h"
14 :
15 : namespace mozilla {
16 : namespace webgl {
17 :
18 : typedef uint8_t EffectiveFormatValueT;
19 :
20 : enum class EffectiveFormat : EffectiveFormatValueT {
21 : // GLES 3.0.4, p128-129, "Required Texture Formats"
22 : // "Texture and renderbuffer color formats"
23 : RGBA32I,
24 : RGBA32UI,
25 : RGBA16I,
26 : RGBA16UI,
27 : RGBA8,
28 : RGBA8I,
29 : RGBA8UI,
30 : SRGB8_ALPHA8,
31 : RGB10_A2,
32 : RGB10_A2UI,
33 : RGBA4,
34 : RGB5_A1,
35 :
36 : RGB8,
37 : RGB565,
38 :
39 : RG32I,
40 : RG32UI,
41 : RG16I,
42 : RG16UI,
43 : RG8,
44 : RG8I,
45 : RG8UI,
46 :
47 : R32I,
48 : R32UI,
49 : R16I,
50 : R16UI,
51 : R8,
52 : R8I,
53 : R8UI,
54 :
55 : // "Texture-only color formats"
56 : RGBA32F,
57 : RGBA16F,
58 : RGBA8_SNORM,
59 :
60 : RGB32F,
61 : RGB32I,
62 : RGB32UI,
63 :
64 : RGB16F,
65 : RGB16I,
66 : RGB16UI,
67 :
68 : RGB8_SNORM,
69 : RGB8I,
70 : RGB8UI,
71 : SRGB8,
72 :
73 : R11F_G11F_B10F,
74 : RGB9_E5,
75 :
76 : RG32F,
77 : RG16F,
78 : RG8_SNORM,
79 :
80 : R32F,
81 : R16F,
82 : R8_SNORM,
83 :
84 : // "Depth formats"
85 : DEPTH_COMPONENT32F,
86 : DEPTH_COMPONENT24,
87 : DEPTH_COMPONENT16,
88 :
89 : // "Combined depth+stencil formats"
90 : DEPTH32F_STENCIL8,
91 : DEPTH24_STENCIL8,
92 :
93 : // GLES 3.0.4, p205-206, "Required Renderbuffer Formats"
94 : STENCIL_INDEX8,
95 :
96 : ////////////////////////////////////
97 :
98 : // GLES 3.0.4, p147, table 3.19
99 : // GLES 3.0.4, p286+, $C.1 "ETC Compressed Texture Image Formats"
100 : COMPRESSED_R11_EAC,
101 : COMPRESSED_SIGNED_R11_EAC,
102 : COMPRESSED_RG11_EAC,
103 : COMPRESSED_SIGNED_RG11_EAC,
104 : COMPRESSED_RGB8_ETC2,
105 : COMPRESSED_SRGB8_ETC2,
106 : COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
107 : COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
108 : COMPRESSED_RGBA8_ETC2_EAC,
109 : COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
110 :
111 : // AMD_compressed_ATC_texture
112 : ATC_RGB_AMD,
113 : ATC_RGBA_EXPLICIT_ALPHA_AMD,
114 : ATC_RGBA_INTERPOLATED_ALPHA_AMD,
115 :
116 : // EXT_texture_compression_s3tc
117 : COMPRESSED_RGB_S3TC_DXT1_EXT,
118 : COMPRESSED_RGBA_S3TC_DXT1_EXT,
119 : COMPRESSED_RGBA_S3TC_DXT3_EXT,
120 : COMPRESSED_RGBA_S3TC_DXT5_EXT,
121 :
122 : // EXT_texture_sRGB
123 : COMPRESSED_SRGB_S3TC_DXT1_EXT,
124 : COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,
125 : COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,
126 : COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,
127 :
128 : // KHR_texture_compression_astc_ldr
129 : COMPRESSED_RGBA_ASTC_4x4_KHR,
130 : COMPRESSED_RGBA_ASTC_5x4_KHR,
131 : COMPRESSED_RGBA_ASTC_5x5_KHR,
132 : COMPRESSED_RGBA_ASTC_6x5_KHR,
133 : COMPRESSED_RGBA_ASTC_6x6_KHR,
134 : COMPRESSED_RGBA_ASTC_8x5_KHR,
135 : COMPRESSED_RGBA_ASTC_8x6_KHR,
136 : COMPRESSED_RGBA_ASTC_8x8_KHR,
137 : COMPRESSED_RGBA_ASTC_10x5_KHR,
138 : COMPRESSED_RGBA_ASTC_10x6_KHR,
139 : COMPRESSED_RGBA_ASTC_10x8_KHR,
140 : COMPRESSED_RGBA_ASTC_10x10_KHR,
141 : COMPRESSED_RGBA_ASTC_12x10_KHR,
142 : COMPRESSED_RGBA_ASTC_12x12_KHR,
143 :
144 : COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR,
145 : COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,
146 : COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR,
147 : COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,
148 : COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR,
149 : COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,
150 : COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR,
151 : COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,
152 : COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR,
153 : COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,
154 : COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR,
155 : COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,
156 : COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR,
157 : COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR,
158 :
159 : // IMG_texture_compression_pvrtc
160 : COMPRESSED_RGB_PVRTC_4BPPV1,
161 : COMPRESSED_RGBA_PVRTC_4BPPV1,
162 : COMPRESSED_RGB_PVRTC_2BPPV1,
163 : COMPRESSED_RGBA_PVRTC_2BPPV1,
164 :
165 : // OES_compressed_ETC1_RGB8_texture
166 : ETC1_RGB8_OES,
167 :
168 : ////////////////////////////////////
169 :
170 : // GLES 3.0.4, p128, table 3.12.
171 : Luminance8Alpha8,
172 : Luminance8,
173 : Alpha8,
174 :
175 : // OES_texture_float
176 : Luminance32FAlpha32F,
177 : Luminance32F,
178 : Alpha32F,
179 :
180 : // OES_texture_half_float
181 : Luminance16FAlpha16F,
182 : Luminance16F,
183 : Alpha16F,
184 :
185 : MAX,
186 : };
187 :
188 : enum class UnsizedFormat : uint8_t {
189 : R,
190 : RG,
191 : RGB,
192 : RGBA,
193 : LA,
194 : L,
195 : A,
196 : D,
197 : S,
198 : DEPTH_STENCIL, // `DS` is a macro on Solaris. (regset.h)
199 : };
200 :
201 : // GLES 3.0.4 p114 Table 3.4, p240
202 : enum class ComponentType : uint8_t {
203 : None,
204 : Int, // RGBA32I
205 : UInt, // RGBA32UI, STENCIL_INDEX8
206 : NormInt, // RGBA8_SNORM
207 : NormUInt, // RGBA8, DEPTH_COMPONENT16
208 : Float, // RGBA32F
209 : Special, // DEPTH24_STENCIL8
210 : };
211 :
212 : enum class CompressionFamily : uint8_t {
213 : ASTC,
214 : ATC,
215 : ES3, // ETC2 or EAC
216 : ETC1,
217 : PVRTC,
218 : S3TC,
219 : };
220 :
221 : ////////////////////////////////////////////////////////////////////////////////
222 :
223 : struct CompressedFormatInfo
224 : {
225 : const EffectiveFormat effectiveFormat;
226 : const uint8_t bytesPerBlock;
227 : const uint8_t blockWidth;
228 : const uint8_t blockHeight;
229 : const CompressionFamily family;
230 : };
231 :
232 0 : struct FormatInfo
233 : {
234 : const EffectiveFormat effectiveFormat;
235 : const char* const name;
236 : const GLenum sizedFormat;
237 : const UnsizedFormat unsizedFormat;
238 : const ComponentType componentType;
239 : const bool isSRGB;
240 :
241 : const CompressedFormatInfo* const compression;
242 :
243 : const uint8_t estimatedBytesPerPixel; // 0 iff bool(compression).
244 :
245 : // In bits. Iff bool(compression), active channels are 1.
246 : const uint8_t r;
247 : const uint8_t g;
248 : const uint8_t b;
249 : const uint8_t a;
250 : const uint8_t d;
251 : const uint8_t s;
252 :
253 : //////
254 :
255 : std::map<UnsizedFormat, const FormatInfo*> copyDecayFormats;
256 :
257 : const FormatInfo* GetCopyDecayFormat(UnsizedFormat) const;
258 :
259 0 : bool IsColorFormat() const {
260 : // Alpha is a 'color format' since it's 'color-attachable'.
261 0 : return bool(compression) ||
262 0 : bool(r | g | b | a);
263 : }
264 : };
265 :
266 : struct PackingInfo
267 : {
268 : GLenum format;
269 : GLenum type;
270 :
271 0 : bool operator <(const PackingInfo& x) const
272 : {
273 0 : if (format != x.format)
274 0 : return format < x.format;
275 :
276 0 : return type < x.type;
277 : }
278 :
279 0 : bool operator ==(const PackingInfo& x) const {
280 0 : return (format == x.format &&
281 0 : type == x.type);
282 : }
283 : };
284 :
285 : struct DriverUnpackInfo
286 : {
287 : GLenum internalFormat;
288 : GLenum unpackFormat;
289 : GLenum unpackType;
290 :
291 0 : PackingInfo ToPacking() const {
292 0 : return {unpackFormat, unpackType};
293 : }
294 : };
295 :
296 : //////////////////////////////////////////////////////////////////////////////////////////
297 :
298 : const FormatInfo* GetFormat(EffectiveFormat format);
299 : uint8_t BytesPerPixel(const PackingInfo& packing);
300 : bool GetBytesPerPixel(const PackingInfo& packing, uint8_t* const out_bytes);
301 : /*
302 : GLint ComponentSize(const FormatInfo* format, GLenum component);
303 : GLenum ComponentType(const FormatInfo* format);
304 : */
305 : ////////////////////////////////////////
306 :
307 0 : struct FormatUsageInfo
308 : {
309 : const FormatInfo* const format;
310 : private:
311 : bool isRenderable;
312 : public:
313 : bool isFilterable;
314 :
315 : std::map<PackingInfo, DriverUnpackInfo> validUnpacks;
316 : const DriverUnpackInfo* idealUnpack;
317 :
318 : const GLint* textureSwizzleRGBA;
319 :
320 : bool maxSamplesKnown;
321 : uint32_t maxSamples;
322 :
323 : static const GLint kLuminanceSwizzleRGBA[4];
324 : static const GLint kAlphaSwizzleRGBA[4];
325 : static const GLint kLumAlphaSwizzleRGBA[4];
326 :
327 0 : explicit FormatUsageInfo(const FormatInfo* _format)
328 0 : : format(_format)
329 : , isRenderable(false)
330 : , isFilterable(false)
331 : , idealUnpack(nullptr)
332 : , textureSwizzleRGBA(nullptr)
333 : , maxSamplesKnown(false)
334 0 : , maxSamples(0)
335 0 : { }
336 :
337 0 : bool IsRenderable() const { return isRenderable; }
338 : void SetRenderable();
339 :
340 : bool IsUnpackValid(const PackingInfo& key,
341 : const DriverUnpackInfo** const out_value) const;
342 :
343 : void ResolveMaxSamples(gl::GLContext* gl);
344 : };
345 :
346 0 : class FormatUsageAuthority
347 : {
348 : std::map<EffectiveFormat, FormatUsageInfo> mUsageMap;
349 :
350 : std::map<GLenum, const FormatUsageInfo*> mRBFormatMap;
351 : std::map<GLenum, const FormatUsageInfo*> mSizedTexFormatMap;
352 : std::map<PackingInfo, const FormatUsageInfo*> mUnsizedTexFormatMap;
353 :
354 : std::set<GLenum> mValidTexInternalFormats;
355 : std::set<GLenum> mValidTexUnpackFormats;
356 : std::set<GLenum> mValidTexUnpackTypes;
357 :
358 : public:
359 : static UniquePtr<FormatUsageAuthority> CreateForWebGL1(gl::GLContext* gl);
360 : static UniquePtr<FormatUsageAuthority> CreateForWebGL2(gl::GLContext* gl);
361 :
362 : private:
363 0 : FormatUsageAuthority() { }
364 :
365 : public:
366 : FormatUsageInfo* EditUsage(EffectiveFormat format);
367 : const FormatUsageInfo* GetUsage(EffectiveFormat format) const;
368 :
369 : void AddTexUnpack(FormatUsageInfo* usage, const PackingInfo& pi,
370 : const DriverUnpackInfo& dui);
371 :
372 : bool IsInternalFormatEnumValid(GLenum internalFormat) const;
373 : bool AreUnpackEnumsValid(GLenum unpackFormat, GLenum unpackType) const;
374 :
375 : void AllowRBFormat(GLenum sizedFormat, const FormatUsageInfo* usage);
376 : void AllowSizedTexFormat(GLenum sizedFormat, const FormatUsageInfo* usage);
377 : void AllowUnsizedTexFormat(const PackingInfo& pi, const FormatUsageInfo* usage);
378 :
379 : const FormatUsageInfo* GetRBUsage(GLenum sizedFormat) const;
380 : const FormatUsageInfo* GetSizedTexUsage(GLenum sizedFormat) const;
381 : const FormatUsageInfo* GetUnsizedTexUsage(const PackingInfo& pi) const;
382 : };
383 :
384 : } // namespace webgl
385 : } // namespace mozilla
386 :
387 : #endif // WEBGL_FORMATS_H_
|