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/. */ 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 // EXT_texture_compression_bptc 112 COMPRESSED_RGBA_BPTC_UNORM, 113 COMPRESSED_SRGB_ALPHA_BPTC_UNORM, 114 COMPRESSED_RGB_BPTC_SIGNED_FLOAT, 115 COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, 116 117 // EXT_texture_compression_rgtc 118 COMPRESSED_RED_RGTC1, 119 COMPRESSED_SIGNED_RED_RGTC1, 120 COMPRESSED_RG_RGTC2, 121 COMPRESSED_SIGNED_RG_RGTC2, 122 123 // EXT_texture_compression_s3tc 124 COMPRESSED_RGB_S3TC_DXT1_EXT, 125 COMPRESSED_RGBA_S3TC_DXT1_EXT, 126 COMPRESSED_RGBA_S3TC_DXT3_EXT, 127 COMPRESSED_RGBA_S3TC_DXT5_EXT, 128 129 // EXT_texture_sRGB 130 COMPRESSED_SRGB_S3TC_DXT1_EXT, 131 COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 132 COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 133 COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 134 135 // KHR_texture_compression_astc_ldr 136 COMPRESSED_RGBA_ASTC_4x4_KHR, 137 COMPRESSED_RGBA_ASTC_5x4_KHR, 138 COMPRESSED_RGBA_ASTC_5x5_KHR, 139 COMPRESSED_RGBA_ASTC_6x5_KHR, 140 COMPRESSED_RGBA_ASTC_6x6_KHR, 141 COMPRESSED_RGBA_ASTC_8x5_KHR, 142 COMPRESSED_RGBA_ASTC_8x6_KHR, 143 COMPRESSED_RGBA_ASTC_8x8_KHR, 144 COMPRESSED_RGBA_ASTC_10x5_KHR, 145 COMPRESSED_RGBA_ASTC_10x6_KHR, 146 COMPRESSED_RGBA_ASTC_10x8_KHR, 147 COMPRESSED_RGBA_ASTC_10x10_KHR, 148 COMPRESSED_RGBA_ASTC_12x10_KHR, 149 COMPRESSED_RGBA_ASTC_12x12_KHR, 150 151 COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, 152 COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, 153 COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, 154 COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, 155 COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, 156 COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, 157 COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, 158 COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, 159 COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, 160 COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, 161 COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, 162 COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, 163 COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, 164 COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, 165 166 // IMG_texture_compression_pvrtc 167 COMPRESSED_RGB_PVRTC_4BPPV1, 168 COMPRESSED_RGBA_PVRTC_4BPPV1, 169 COMPRESSED_RGB_PVRTC_2BPPV1, 170 COMPRESSED_RGBA_PVRTC_2BPPV1, 171 172 // OES_compressed_ETC1_RGB8_texture 173 ETC1_RGB8_OES, 174 175 //////////////////////////////////// 176 177 // GLES 3.0.4, p128, table 3.12. 178 Luminance8Alpha8, 179 Luminance8, 180 Alpha8, 181 182 // OES_texture_float 183 Luminance32FAlpha32F, 184 Luminance32F, 185 Alpha32F, 186 187 // OES_texture_half_float 188 Luminance16FAlpha16F, 189 Luminance16F, 190 Alpha16F, 191 192 // EXT_texture_norm16 193 R16, 194 RG16, 195 RGB16, 196 RGBA16, 197 R16_SNORM, 198 RG16_SNORM, 199 RGB16_SNORM, 200 RGBA16_SNORM, 201 202 MAX, 203 }; 204 205 enum class UnsizedFormat : uint8_t { 206 R, 207 RG, 208 RGB, 209 RGBA, 210 LA, 211 L, 212 A, 213 D, 214 S, 215 DEPTH_STENCIL, // `DS` is a macro on Solaris. (regset.h) 216 }; 217 218 // GLES 3.0.4 p114 Table 3.4, p240 219 enum class ComponentType : uint8_t { 220 Int, // RGBA32I 221 UInt, // RGBA32UI 222 NormInt, // RGBA8_SNORM 223 NormUInt, // RGBA8 224 Float, // RGBA32F 225 }; 226 const char* ToString(ComponentType); 227 228 enum class TextureBaseType : uint8_t { 229 Int = uint8_t(ComponentType::Int), 230 UInt = uint8_t(ComponentType::UInt), 231 Float = uint8_t(ComponentType::Float), // Also includes NormU?Int and Depth 232 }; 233 234 const char* ToString(TextureBaseType); 235 236 enum class CompressionFamily : uint8_t { 237 ASTC, 238 BPTC, 239 ES3, // ETC2 or EAC 240 ETC1, 241 PVRTC, 242 RGTC, 243 S3TC, 244 }; 245 246 //////////////////////////////////////////////////////////////////////////////// 247 248 struct CompressedFormatInfo { 249 const EffectiveFormat effectiveFormat; 250 const uint8_t bytesPerBlock; 251 const uint8_t blockWidth; 252 const uint8_t blockHeight; 253 const CompressionFamily family; 254 }; 255 256 struct FormatInfo { 257 const EffectiveFormat effectiveFormat; 258 const char* const name; 259 const GLenum sizedFormat; 260 const UnsizedFormat unsizedFormat; 261 const ComponentType componentType; 262 const TextureBaseType baseType; 263 const bool isSRGB; 264 265 const CompressedFormatInfo* const compression; 266 267 const uint8_t estimatedBytesPerPixel; // 0 iff bool(compression). 268 269 // In bits. Iff bool(compression), active channels are 1. 270 const uint8_t r; 271 const uint8_t g; 272 const uint8_t b; 273 const uint8_t a; 274 const uint8_t d; 275 const uint8_t s; 276 277 ////// 278 279 std::map<UnsizedFormat, const FormatInfo*> copyDecayFormats; 280 281 const FormatInfo* GetCopyDecayFormat(UnsizedFormat) const; 282 IsColorFormatFormatInfo283 bool IsColorFormat() const { 284 // Alpha is a 'color format' since it's 'color-attachable'. 285 return bool(compression) || bool(r | g | b | a); 286 } 287 }; 288 289 ////////////////////////////////////////////////////////////////////////////////////////// 290 291 const FormatInfo* GetFormat(EffectiveFormat format); 292 uint8_t BytesPerPixel(const PackingInfo& packing); 293 bool GetBytesPerPixel(const PackingInfo& packing, uint8_t* const out_bytes); 294 /* 295 GLint ComponentSize(const FormatInfo* format, GLenum component); 296 GLenum ComponentType(const FormatInfo* format); 297 */ 298 //////////////////////////////////////// 299 300 struct FormatRenderableState final { 301 private: 302 enum class RenderableState { 303 Disabled, 304 Implicit, 305 Explicit, 306 }; 307 308 public: 309 RenderableState state = RenderableState::Disabled; 310 WebGLExtensionID extid = WebGLExtensionID::Max; 311 Explicitfinal312 static FormatRenderableState Explicit() { 313 return {RenderableState::Explicit}; 314 } 315 Implicitfinal316 static FormatRenderableState Implicit(WebGLExtensionID extid) { 317 return {RenderableState::Implicit, extid}; 318 } 319 IsRenderablefinal320 bool IsRenderable() const { return state != RenderableState::Disabled; } IsExplicitfinal321 bool IsExplicit() const { return state == RenderableState::Explicit; } 322 }; 323 324 struct FormatUsageInfo { 325 const FormatInfo* const format; 326 327 private: 328 FormatRenderableState renderableState; 329 330 public: 331 bool isFilterable = false; 332 333 std::map<PackingInfo, DriverUnpackInfo> validUnpacks; 334 const DriverUnpackInfo* idealUnpack = nullptr; 335 336 const GLint* textureSwizzleRGBA = nullptr; 337 338 private: 339 mutable bool maxSamplesKnown = false; 340 mutable uint32_t maxSamples = 0; 341 342 public: 343 static const GLint kLuminanceSwizzleRGBA[4]; 344 static const GLint kAlphaSwizzleRGBA[4]; 345 static const GLint kLumAlphaSwizzleRGBA[4]; 346 FormatUsageInfoFormatUsageInfo347 explicit FormatUsageInfo(const FormatInfo* const _format) : format(_format) { 348 if (format->IsColorFormat() && format->baseType != TextureBaseType::Float) { 349 maxSamplesKnown = true; 350 } 351 } 352 IsRenderableFormatUsageInfo353 bool IsRenderable() const { return renderableState.IsRenderable(); } 354 void SetRenderable( 355 const FormatRenderableState& state = FormatRenderableState::Explicit()); IsExplicitlyRenderableFormatUsageInfo356 bool IsExplicitlyRenderable() const { return renderableState.IsExplicit(); } GetExtensionIDFormatUsageInfo357 WebGLExtensionID GetExtensionID() const { 358 MOZ_ASSERT(renderableState.extid != WebGLExtensionID::Max); 359 return renderableState.extid; 360 } 361 362 bool IsUnpackValid(const PackingInfo& key, 363 const DriverUnpackInfo** const out_value) const; 364 365 private: 366 void ResolveMaxSamples(gl::GLContext& gl) const; 367 368 public: MaxSamplesFormatUsageInfo369 uint32_t MaxSamples(gl::GLContext& gl) const { 370 if (!maxSamplesKnown) { 371 ResolveMaxSamples(gl); 372 } 373 return maxSamples; 374 } 375 }; 376 377 class FormatUsageAuthority { 378 std::map<EffectiveFormat, FormatUsageInfo> mUsageMap; 379 380 std::map<GLenum, const FormatUsageInfo*> mRBFormatMap; 381 std::map<GLenum, const FormatUsageInfo*> mSizedTexFormatMap; 382 std::map<PackingInfo, const FormatUsageInfo*> mUnsizedTexFormatMap; 383 384 std::set<GLenum> mValidTexInternalFormats; 385 std::set<GLenum> mValidTexUnpackFormats; 386 std::set<GLenum> mValidTexUnpackTypes; 387 388 public: 389 static UniquePtr<FormatUsageAuthority> CreateForWebGL1(gl::GLContext* gl); 390 static UniquePtr<FormatUsageAuthority> CreateForWebGL2(gl::GLContext* gl); 391 392 private: 393 FormatUsageAuthority() = default; 394 395 public: 396 FormatUsageInfo* EditUsage(EffectiveFormat format); 397 const FormatUsageInfo* GetUsage(EffectiveFormat format) const; 398 399 void AddTexUnpack(FormatUsageInfo* usage, const PackingInfo& pi, 400 const DriverUnpackInfo& dui); 401 402 bool IsInternalFormatEnumValid(GLenum internalFormat) const; 403 bool AreUnpackEnumsValid(GLenum unpackFormat, GLenum unpackType) const; 404 405 void AllowRBFormat(GLenum sizedFormat, const FormatUsageInfo* usage, 406 bool expectRenderable = true); 407 void AllowSizedTexFormat(GLenum sizedFormat, const FormatUsageInfo* usage); 408 void AllowUnsizedTexFormat(const PackingInfo& pi, 409 const FormatUsageInfo* usage); 410 411 const FormatUsageInfo* GetRBUsage(GLenum sizedFormat) const; 412 const FormatUsageInfo* GetSizedTexUsage(GLenum sizedFormat) const; 413 const FormatUsageInfo* GetUnsizedTexUsage(const PackingInfo& pi) const; 414 }; 415 416 } // namespace webgl 417 } // namespace mozilla 418 419 #endif // WEBGL_FORMATS_H_ 420