WebGLFormats.cpp (62165B)
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 #include "WebGLFormats.h" 7 8 #include "GLContext.h" 9 #include "GLDefs.h" 10 #include "mozilla/StaticMutex.h" 11 #include "mozilla/gfx/Logging.h" 12 13 namespace mozilla::webgl { 14 15 const char* ToString(const ComponentType type) { 16 switch (type) { 17 case ComponentType::Int: 18 return "Int"; 19 case ComponentType::UInt: 20 return "UInt"; 21 case ComponentType::NormInt: 22 return "NormInt"; 23 case ComponentType::NormUInt: 24 return "NormUInt"; 25 case ComponentType::Float: 26 return "Float"; 27 } 28 MOZ_CRASH("pacify gcc6 warning"); 29 } 30 31 static TextureBaseType ToBaseType(const ComponentType type) { 32 switch (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; 42 } 43 MOZ_CRASH("pacify gcc6 warning"); 44 } 45 46 const char* ToString(const TextureBaseType x) { 47 switch (x) { 48 case webgl::TextureBaseType::Float: 49 return "FLOAT"; 50 case webgl::TextureBaseType::Int: 51 return "INT"; 52 case webgl::TextureBaseType::UInt: 53 return "UINT"; 54 } 55 MOZ_CRASH("pacify gcc6 warning"); 56 } 57 58 // - 59 60 template <typename K, typename V, typename K2, typename V2> 61 static inline void AlwaysInsert(std::map<K, V>& dest, const K2& key, 62 const V2& val) { 63 auto res = dest.insert({key, val}); 64 bool didInsert = res.second; 65 MOZ_ALWAYS_TRUE(didInsert); 66 } 67 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; 72 73 return itr->second; 74 } 75 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}; 82 83 return &(itr->second); 84 } 85 86 ////////////////////////////////////////////////////////////////////////////////////////// 87 88 MOZ_RUNINIT std::map<EffectiveFormat, const CompressedFormatInfo> 89 gCompressedFormatInfoMap; 90 MOZ_RUNINIT std::map<EffectiveFormat, FormatInfo> gFormatInfoMap; 91 92 static inline const CompressedFormatInfo* GetCompressedFormatInfo( 93 EffectiveFormat format) { 94 MOZ_ASSERT(!gCompressedFormatInfoMap.empty()); 95 return FindPtrOrNull(gCompressedFormatInfoMap, format); 96 } 97 98 static inline FormatInfo* GetFormatInfo_NoLock(EffectiveFormat format) { 99 MOZ_ASSERT(!gFormatInfoMap.empty()); 100 return FindPtrOrNull(gFormatInfoMap, format); 101 } 102 103 ////////////////////////////////////////////////////////////////////////////////////////// 104 105 static void AddCompressedFormatInfo(EffectiveFormat format, 106 uint16_t bitsPerBlock, uint8_t blockWidth, 107 uint8_t blockHeight, 108 CompressionFamily family) { 109 MOZ_ASSERT(bitsPerBlock % 8 == 0); 110 uint16_t bytesPerBlock = bitsPerBlock / 8; // The specs always state these in 111 // bits, but it's only ever useful 112 // to us as bytes. 113 MOZ_ASSERT(bytesPerBlock <= 255); 114 115 const CompressedFormatInfo info = {format, uint8_t(bytesPerBlock), blockWidth, 116 blockHeight, family}; 117 AlwaysInsert(gCompressedFormatInfoMap, format, info); 118 } 119 120 static void InitCompressedFormatInfo() { 121 // clang-format off 122 123 // GLES 3.0.4, p147, table 3.19 124 // GLES 3.0.4, p286+, $C.1 "ETC Compressed Texture Image Formats" 125 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB8_ETC2 , 64, 4, 4, CompressionFamily::ES3); 126 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ETC2 , 64, 4, 4, CompressionFamily::ES3); 127 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA8_ETC2_EAC , 128, 4, 4, CompressionFamily::ES3); 128 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC , 128, 4, 4, CompressionFamily::ES3); 129 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_R11_EAC , 64, 4, 4, CompressionFamily::ES3); 130 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RG11_EAC , 128, 4, 4, CompressionFamily::ES3); 131 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_R11_EAC , 64, 4, 4, CompressionFamily::ES3); 132 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_RG11_EAC , 128, 4, 4, CompressionFamily::ES3); 133 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 , 64, 4, 4, CompressionFamily::ES3); 134 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 64, 4, 4, CompressionFamily::ES3); 135 136 // EXT_texture_compression_bptc 137 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_BPTC_UNORM , 16*8, 4, 4, CompressionFamily::BPTC); 138 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_ALPHA_BPTC_UNORM , 16*8, 4, 4, CompressionFamily::BPTC); 139 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_BPTC_SIGNED_FLOAT , 16*8, 4, 4, CompressionFamily::BPTC); 140 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, 16*8, 4, 4, CompressionFamily::BPTC); 141 142 // EXT_texture_compression_rgtc 143 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RED_RGTC1 , 8*8, 4, 4, CompressionFamily::RGTC); 144 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_RED_RGTC1, 8*8, 4, 4, CompressionFamily::RGTC); 145 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RG_RGTC2 , 16*8, 4, 4, CompressionFamily::RGTC); 146 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_RG_RGTC2 , 16*8, 4, 4, CompressionFamily::RGTC); 147 148 // EXT_texture_compression_s3tc 149 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_S3TC_DXT1_EXT , 64, 4, 4, CompressionFamily::S3TC); 150 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT1_EXT, 64, 4, 4, CompressionFamily::S3TC); 151 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT3_EXT, 128, 4, 4, CompressionFamily::S3TC); 152 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT5_EXT, 128, 4, 4, CompressionFamily::S3TC); 153 154 // EXT_texture_compression_s3tc_srgb 155 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_S3TC_DXT1_EXT , 64, 4, 4, CompressionFamily::S3TC); 156 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 64, 4, 4, CompressionFamily::S3TC); 157 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 128, 4, 4, CompressionFamily::S3TC); 158 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 128, 4, 4, CompressionFamily::S3TC); 159 160 // KHR_texture_compression_astc_ldr 161 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_4x4_KHR , 128, 4, 4, CompressionFamily::ASTC); 162 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_5x4_KHR , 128, 5, 4, CompressionFamily::ASTC); 163 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_5x5_KHR , 128, 5, 5, CompressionFamily::ASTC); 164 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_6x5_KHR , 128, 6, 5, CompressionFamily::ASTC); 165 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_6x6_KHR , 128, 6, 6, CompressionFamily::ASTC); 166 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_8x5_KHR , 128, 8, 5, CompressionFamily::ASTC); 167 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_8x6_KHR , 128, 8, 6, CompressionFamily::ASTC); 168 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_8x8_KHR , 128, 8, 8, CompressionFamily::ASTC); 169 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_10x5_KHR , 128, 10, 5, CompressionFamily::ASTC); 170 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_10x6_KHR , 128, 10, 6, CompressionFamily::ASTC); 171 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_10x8_KHR , 128, 10, 8, CompressionFamily::ASTC); 172 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_10x10_KHR , 128, 10, 10, CompressionFamily::ASTC); 173 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_12x10_KHR , 128, 12, 10, CompressionFamily::ASTC); 174 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_12x12_KHR , 128, 12, 12, CompressionFamily::ASTC); 175 176 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR , 128, 4, 4, CompressionFamily::ASTC); 177 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR , 128, 5, 4, CompressionFamily::ASTC); 178 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR , 128, 5, 5, CompressionFamily::ASTC); 179 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR , 128, 6, 5, CompressionFamily::ASTC); 180 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR , 128, 6, 6, CompressionFamily::ASTC); 181 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR , 128, 8, 5, CompressionFamily::ASTC); 182 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR , 128, 8, 6, CompressionFamily::ASTC); 183 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR , 128, 8, 8, CompressionFamily::ASTC); 184 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR , 128, 10, 5, CompressionFamily::ASTC); 185 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR , 128, 10, 6, CompressionFamily::ASTC); 186 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR , 128, 10, 8, CompressionFamily::ASTC); 187 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, 128, 10, 10, CompressionFamily::ASTC); 188 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, 128, 12, 10, CompressionFamily::ASTC); 189 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, 128, 12, 12, CompressionFamily::ASTC); 190 191 // IMG_texture_compression_pvrtc 192 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_PVRTC_4BPPV1 , 256, 8, 8, CompressionFamily::PVRTC); 193 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_PVRTC_4BPPV1, 256, 8, 8, CompressionFamily::PVRTC); 194 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_PVRTC_2BPPV1 , 256, 16, 8, CompressionFamily::PVRTC); 195 AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_PVRTC_2BPPV1, 256, 16, 8, CompressionFamily::PVRTC); 196 197 // OES_compressed_ETC1_RGB8_texture 198 AddCompressedFormatInfo(EffectiveFormat::ETC1_RGB8_OES, 64, 4, 4, CompressionFamily::ETC1); 199 200 // clang-format on 201 } 202 203 ////////////////////////////////////////////////////////////////////////////////////////// 204 205 static void AddFormatInfo(EffectiveFormat format, const char* name, 206 GLenum sizedFormat, uint8_t bytesPerPixel, uint8_t r, 207 uint8_t g, uint8_t b, uint8_t a, uint8_t d, uint8_t s, 208 UnsizedFormat unsizedFormat, bool isSRGB, 209 ComponentType componentType) { 210 switch (unsizedFormat) { 211 case UnsizedFormat::R: 212 MOZ_ASSERT(r && !g && !b && !a && !d && !s); 213 break; 214 215 case UnsizedFormat::RG: 216 MOZ_ASSERT(r && g && !b && !a && !d && !s); 217 break; 218 219 case UnsizedFormat::RGB: 220 MOZ_ASSERT(r && g && b && !a && !d && !s); 221 break; 222 223 case UnsizedFormat::RGBA: 224 MOZ_ASSERT(r && g && b && a && !d && !s); 225 break; 226 227 case UnsizedFormat::L: 228 MOZ_ASSERT(r && !g && !b && !a && !d && !s); 229 break; 230 231 case UnsizedFormat::A: 232 MOZ_ASSERT(!r && !g && !b && a && !d && !s); 233 break; 234 235 case UnsizedFormat::LA: 236 MOZ_ASSERT(r && !g && !b && a && !d && !s); 237 break; 238 239 case UnsizedFormat::D: 240 MOZ_ASSERT(!r && !g && !b && !a && d && !s); 241 break; 242 243 case UnsizedFormat::S: 244 MOZ_ASSERT(!r && !g && !b && !a && !d && s); 245 break; 246 247 case UnsizedFormat::DEPTH_STENCIL: 248 MOZ_ASSERT(!r && !g && !b && !a && d && s); 249 break; 250 } 251 252 const CompressedFormatInfo* compressedFormatInfo = 253 GetCompressedFormatInfo(format); 254 MOZ_ASSERT(!bytesPerPixel == bool(compressedFormatInfo)); 255 256 #ifdef DEBUG 257 uint8_t totalBits = r + g + b + a + d + s; 258 if (format == EffectiveFormat::RGB9_E5) { 259 totalBits = 9 + 9 + 9 + 5; 260 } 261 262 if (compressedFormatInfo) { 263 MOZ_ASSERT(totalBits); 264 MOZ_ASSERT(!bytesPerPixel); 265 } else { 266 MOZ_ASSERT(totalBits == bytesPerPixel * 8); 267 } 268 #endif 269 270 const FormatInfo info = {format, 271 name, 272 sizedFormat, 273 unsizedFormat, 274 componentType, 275 ToBaseType(componentType), 276 isSRGB, 277 compressedFormatInfo, 278 bytesPerPixel, 279 r, 280 g, 281 b, 282 a, 283 d, 284 s}; 285 AlwaysInsert(gFormatInfoMap, format, info); 286 } 287 288 static void InitFormatInfo() { 289 // This function is full of expressive formatting, so: 290 // clang-format off 291 292 #define FOO(x) EffectiveFormat::x, #x, LOCAL_GL_ ## x 293 294 // GLES 3.0.4, p130-132, table 3.13 295 // | format | renderable | filterable | 296 AddFormatInfo(FOO(R8 ), 1, 8, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::NormUInt); 297 AddFormatInfo(FOO(R8_SNORM ), 1, 8, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::NormInt ); 298 AddFormatInfo(FOO(RG8 ), 2, 8, 8, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::NormUInt); 299 AddFormatInfo(FOO(RG8_SNORM ), 2, 8, 8, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::NormInt ); 300 AddFormatInfo(FOO(RGB8 ), 3, 8, 8, 8, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt); 301 AddFormatInfo(FOO(RGB8_SNORM ), 3, 8, 8, 8, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormInt ); 302 AddFormatInfo(FOO(RGB565 ), 2, 5, 6, 5, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt); 303 AddFormatInfo(FOO(RGBA4 ), 2, 4, 4, 4, 4, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 304 AddFormatInfo(FOO(RGB5_A1 ), 2, 5, 5, 5, 1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 305 AddFormatInfo(FOO(RGBA8 ), 4, 8, 8, 8, 8, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 306 AddFormatInfo(FOO(RGBA8_SNORM ), 4, 8, 8, 8, 8, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormInt ); 307 AddFormatInfo(FOO(RGB10_A2 ), 4, 10,10,10, 2, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 308 AddFormatInfo(FOO(RGB10_A2UI ), 4, 10,10,10, 2, 0,0, UnsizedFormat::RGBA, false, ComponentType::UInt ); 309 310 AddFormatInfo(FOO(SRGB8 ), 3, 8, 8, 8, 0, 0,0, UnsizedFormat::RGB , true , ComponentType::NormUInt); 311 AddFormatInfo(FOO(SRGB8_ALPHA8 ), 4, 8, 8, 8, 8, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt); 312 313 AddFormatInfo(FOO(R16F ), 2, 16, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::Float ); 314 AddFormatInfo(FOO(RG16F ), 4, 16,16, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::Float ); 315 AddFormatInfo(FOO(RGB16F ), 6, 16,16,16, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::Float ); 316 AddFormatInfo(FOO(RGBA16F ), 8, 16,16,16,16, 0,0, UnsizedFormat::RGBA, false, ComponentType::Float ); 317 AddFormatInfo(FOO(R32F ), 4, 32, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::Float ); 318 AddFormatInfo(FOO(RG32F ), 8, 32,32, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::Float ); 319 AddFormatInfo(FOO(RGB32F ), 12, 32,32,32, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::Float ); 320 AddFormatInfo(FOO(RGBA32F ), 16, 32,32,32,32, 0,0, UnsizedFormat::RGBA, false, ComponentType::Float ); 321 322 AddFormatInfo(FOO(R11F_G11F_B10F), 4, 11,11,10, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::Float ); 323 AddFormatInfo(FOO(RGB9_E5 ), 4, 14,14,14, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::Float ); 324 325 AddFormatInfo(FOO(R8I ), 1, 8, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::Int ); 326 AddFormatInfo(FOO(R8UI ), 1, 8, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::UInt ); 327 AddFormatInfo(FOO(R16I ), 2, 16, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::Int ); 328 AddFormatInfo(FOO(R16UI ), 2, 16, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::UInt ); 329 AddFormatInfo(FOO(R32I ), 4, 32, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::Int ); 330 AddFormatInfo(FOO(R32UI ), 4, 32, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::UInt ); 331 332 AddFormatInfo(FOO(RG8I ), 2, 8, 8, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::Int ); 333 AddFormatInfo(FOO(RG8UI ), 2, 8, 8, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::UInt ); 334 AddFormatInfo(FOO(RG16I ), 4, 16,16, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::Int ); 335 AddFormatInfo(FOO(RG16UI ), 4, 16,16, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::UInt ); 336 AddFormatInfo(FOO(RG32I ), 8, 32,32, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::Int ); 337 AddFormatInfo(FOO(RG32UI ), 8, 32,32, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::UInt ); 338 339 AddFormatInfo(FOO(RGB8I ), 3, 8, 8, 8, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::Int ); 340 AddFormatInfo(FOO(RGB8UI ), 3, 8, 8, 8, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::UInt ); 341 AddFormatInfo(FOO(RGB16I ), 6, 16,16,16, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::Int ); 342 AddFormatInfo(FOO(RGB16UI ), 6, 16,16,16, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::UInt ); 343 AddFormatInfo(FOO(RGB32I ), 12, 32,32,32, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::Int ); 344 AddFormatInfo(FOO(RGB32UI ), 12, 32,32,32, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::UInt ); 345 346 AddFormatInfo(FOO(RGBA8I ), 4, 8, 8, 8, 8, 0,0, UnsizedFormat::RGBA, false, ComponentType::Int ); 347 AddFormatInfo(FOO(RGBA8UI ), 4, 8, 8, 8, 8, 0,0, UnsizedFormat::RGBA, false, ComponentType::UInt ); 348 AddFormatInfo(FOO(RGBA16I ), 8, 16,16,16,16, 0,0, UnsizedFormat::RGBA, false, ComponentType::Int ); 349 AddFormatInfo(FOO(RGBA16UI ), 8, 16,16,16,16, 0,0, UnsizedFormat::RGBA, false, ComponentType::UInt ); 350 AddFormatInfo(FOO(RGBA32I ), 16, 32,32,32,32, 0,0, UnsizedFormat::RGBA, false, ComponentType::Int ); 351 AddFormatInfo(FOO(RGBA32UI ), 16, 32,32,32,32, 0,0, UnsizedFormat::RGBA, false, ComponentType::UInt ); 352 353 // GLES 3.0.4, p133, table 3.14 354 AddFormatInfo(FOO(DEPTH_COMPONENT16 ), 2, 0,0,0,0, 16,0, UnsizedFormat::D , false, ComponentType::NormUInt); 355 AddFormatInfo(FOO(DEPTH_COMPONENT24 ), 3, 0,0,0,0, 24,0, UnsizedFormat::D , false, ComponentType::NormUInt); 356 AddFormatInfo(FOO(DEPTH_COMPONENT32F), 4, 0,0,0,0, 32,0, UnsizedFormat::D , false, ComponentType::Float); 357 // DEPTH_STENCIL types are sampled as their depth component. 358 AddFormatInfo(FOO(DEPTH24_STENCIL8 ), 4, 0,0,0,0, 24,8, UnsizedFormat::DEPTH_STENCIL, false, ComponentType::NormUInt); 359 AddFormatInfo(FOO(DEPTH32F_STENCIL8 ), 5, 0,0,0,0, 32,8, UnsizedFormat::DEPTH_STENCIL, false, ComponentType::Float); 360 361 // GLES 3.0.4, p205-206, "Required Renderbuffer Formats" 362 AddFormatInfo(FOO(STENCIL_INDEX8), 1, 0,0,0,0, 0,8, UnsizedFormat::S, false, ComponentType::Int); 363 364 // GLES 3.0.4, p147, table 3.19 365 // GLES 3.0.4 p286+ $C.1 "ETC Compressed Texture Image Formats" 366 AddFormatInfo(FOO(COMPRESSED_RGB8_ETC2 ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt); 367 AddFormatInfo(FOO(COMPRESSED_SRGB8_ETC2 ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , true , ComponentType::NormUInt); 368 AddFormatInfo(FOO(COMPRESSED_RGBA8_ETC2_EAC ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 369 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ETC2_EAC ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt); 370 AddFormatInfo(FOO(COMPRESSED_R11_EAC ), 0, 1,0,0,0, 0,0, UnsizedFormat::R , false, ComponentType::NormUInt); 371 AddFormatInfo(FOO(COMPRESSED_RG11_EAC ), 0, 1,1,0,0, 0,0, UnsizedFormat::RG , false, ComponentType::NormUInt); 372 AddFormatInfo(FOO(COMPRESSED_SIGNED_R11_EAC ), 0, 1,0,0,0, 0,0, UnsizedFormat::R , false, ComponentType::NormInt ); 373 AddFormatInfo(FOO(COMPRESSED_SIGNED_RG11_EAC ), 0, 1,1,0,0, 0,0, UnsizedFormat::RG , false, ComponentType::NormInt ); 374 AddFormatInfo(FOO(COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 375 AddFormatInfo(FOO(COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt); 376 377 // EXT_texture_compression_bptc 378 AddFormatInfo(FOO(COMPRESSED_RGBA_BPTC_UNORM ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 379 AddFormatInfo(FOO(COMPRESSED_SRGB_ALPHA_BPTC_UNORM ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt); 380 AddFormatInfo(FOO(COMPRESSED_RGB_BPTC_SIGNED_FLOAT ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::Float ); 381 AddFormatInfo(FOO(COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::Float ); 382 383 // EXT_texture_compression_rgtc 384 AddFormatInfo(FOO(COMPRESSED_RED_RGTC1 ), 0, 1,0,0,0, 0,0, UnsizedFormat::R , false, ComponentType::NormUInt); 385 AddFormatInfo(FOO(COMPRESSED_SIGNED_RED_RGTC1), 0, 1,0,0,0, 0,0, UnsizedFormat::R , false, ComponentType::NormInt ); 386 AddFormatInfo(FOO(COMPRESSED_RG_RGTC2 ), 0, 1,1,0,0, 0,0, UnsizedFormat::RG, false, ComponentType::NormUInt); 387 AddFormatInfo(FOO(COMPRESSED_SIGNED_RG_RGTC2 ), 0, 1,1,0,0, 0,0, UnsizedFormat::RG, false, ComponentType::NormInt ); 388 389 // EXT_texture_compression_s3tc 390 AddFormatInfo(FOO(COMPRESSED_RGB_S3TC_DXT1_EXT ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt); 391 AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT1_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 392 AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT3_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 393 AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT5_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 394 395 // EXT_texture_compression_s3tc_srgb 396 AddFormatInfo(FOO(COMPRESSED_SRGB_S3TC_DXT1_EXT ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , true, ComponentType::NormUInt); 397 AddFormatInfo(FOO(COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true, ComponentType::NormUInt); 398 AddFormatInfo(FOO(COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true, ComponentType::NormUInt); 399 AddFormatInfo(FOO(COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true, ComponentType::NormUInt); 400 401 // KHR_texture_compression_astc_ldr 402 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_4x4_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 403 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_5x4_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 404 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_5x5_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 405 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_6x5_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 406 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_6x6_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 407 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_8x5_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 408 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_8x6_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 409 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_8x8_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 410 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_10x5_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 411 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_10x6_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 412 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_10x8_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 413 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_10x10_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 414 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_12x10_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 415 AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_12x12_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 416 417 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt); 418 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt); 419 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt); 420 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt); 421 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt); 422 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt); 423 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt); 424 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt); 425 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt); 426 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt); 427 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt); 428 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt); 429 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt); 430 AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt); 431 432 // IMG_texture_compression_pvrtc 433 AddFormatInfo(FOO(COMPRESSED_RGB_PVRTC_4BPPV1 ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt); 434 AddFormatInfo(FOO(COMPRESSED_RGBA_PVRTC_4BPPV1), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 435 AddFormatInfo(FOO(COMPRESSED_RGB_PVRTC_2BPPV1 ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt); 436 AddFormatInfo(FOO(COMPRESSED_RGBA_PVRTC_2BPPV1), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 437 438 // OES_compressed_ETC1_RGB8_texture 439 AddFormatInfo(FOO(ETC1_RGB8_OES), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB, false, ComponentType::NormUInt); 440 441 // EXT_texture_norm16 442 AddFormatInfo(FOO(R16 ), 2, 16, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::NormUInt); 443 AddFormatInfo(FOO(RG16 ), 4, 16,16, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::NormUInt); 444 AddFormatInfo(FOO(RGB16 ), 6, 16,16,16, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt); 445 AddFormatInfo(FOO(RGBA16), 8, 16,16,16,16, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt); 446 447 AddFormatInfo(FOO(R16_SNORM ), 2, 16, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::NormInt); 448 AddFormatInfo(FOO(RG16_SNORM ), 4, 16,16, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::NormInt); 449 AddFormatInfo(FOO(RGB16_SNORM ), 6, 16,16,16, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormInt); 450 AddFormatInfo(FOO(RGBA16_SNORM), 8, 16,16,16,16, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormInt); 451 452 #undef FOO 453 454 // 'Virtual' effective formats have no sizedFormat. 455 #define FOO(x) EffectiveFormat::x, #x, 0 456 457 // GLES 3.0.4, p128, table 3.12. 458 AddFormatInfo(FOO(Luminance8Alpha8), 2, 8,0,0,8, 0,0, UnsizedFormat::LA, false, ComponentType::NormUInt); 459 AddFormatInfo(FOO(Luminance8 ), 1, 8,0,0,0, 0,0, UnsizedFormat::L , false, ComponentType::NormUInt); 460 AddFormatInfo(FOO(Alpha8 ), 1, 0,0,0,8, 0,0, UnsizedFormat::A , false, ComponentType::NormUInt); 461 462 // OES_texture_float 463 AddFormatInfo(FOO(Luminance32FAlpha32F), 8, 32,0,0,32, 0,0, UnsizedFormat::LA, false, ComponentType::Float); 464 AddFormatInfo(FOO(Luminance32F ), 4, 32,0,0, 0, 0,0, UnsizedFormat::L , false, ComponentType::Float); 465 AddFormatInfo(FOO(Alpha32F ), 4, 0,0,0,32, 0,0, UnsizedFormat::A , false, ComponentType::Float); 466 467 // OES_texture_half_float 468 AddFormatInfo(FOO(Luminance16FAlpha16F), 4, 16,0,0,16, 0,0, UnsizedFormat::LA, false, ComponentType::Float); 469 AddFormatInfo(FOO(Luminance16F ), 2, 16,0,0, 0, 0,0, UnsizedFormat::L , false, ComponentType::Float); 470 AddFormatInfo(FOO(Alpha16F ), 2, 0,0,0,16, 0,0, UnsizedFormat::A , false, ComponentType::Float); 471 472 #undef FOO 473 474 //////////////////////////////////////////////////////////////////////////// 475 476 const auto fnSetCopyDecay = [](EffectiveFormat src, EffectiveFormat asR, 477 EffectiveFormat asRG, EffectiveFormat asRGB, 478 EffectiveFormat asRGBA, EffectiveFormat asL, 479 EffectiveFormat asA, EffectiveFormat asLA) 480 { 481 auto& map = GetFormatInfo_NoLock(src)->copyDecayFormats; 482 483 const auto fnSet = [&map](UnsizedFormat uf, EffectiveFormat ef) { 484 if (ef == EffectiveFormat::MAX) 485 return; 486 487 const auto* format = GetFormatInfo_NoLock(ef); 488 MOZ_ASSERT(format->unsizedFormat == uf); 489 AlwaysInsert(map, uf, format); 490 }; 491 492 fnSet(UnsizedFormat::R , asR); 493 fnSet(UnsizedFormat::RG , asRG); 494 fnSet(UnsizedFormat::RGB , asRGB); 495 fnSet(UnsizedFormat::RGBA, asRGBA); 496 fnSet(UnsizedFormat::L , asL); 497 fnSet(UnsizedFormat::A , asA); 498 fnSet(UnsizedFormat::LA , asLA); 499 }; 500 501 #define SET_COPY_DECAY(src,asR,asRG,asRGB,asRGBA,asL,asA,asLA) \ 502 fnSetCopyDecay(EffectiveFormat::src, EffectiveFormat::asR, EffectiveFormat::asRG, \ 503 EffectiveFormat::asRGB, EffectiveFormat::asRGBA, EffectiveFormat::asL, \ 504 EffectiveFormat::asA, EffectiveFormat::asLA); 505 506 ////// 507 508 #define SET_BY_SUFFIX(X) \ 509 SET_COPY_DECAY( R##X, R##X, MAX, MAX, MAX, Luminance##X, MAX, MAX) \ 510 SET_COPY_DECAY( RG##X, R##X, RG##X, MAX, MAX, Luminance##X, MAX, MAX) \ 511 SET_COPY_DECAY( RGB##X, R##X, RG##X, RGB##X, MAX, Luminance##X, MAX, MAX) \ 512 SET_COPY_DECAY(RGBA##X, R##X, RG##X, RGB##X, RGBA##X, Luminance##X, Alpha##X, Luminance##X##Alpha##X) 513 514 SET_BY_SUFFIX(8) // WebGL decided that RGB8 should be guaranteed renderable. 515 SET_BY_SUFFIX(16F) // RGB16F is renderable in EXT_color_buffer_half_float, though not 516 // EXT_color_buffer_float. 517 SET_BY_SUFFIX(32F) // Technically RGB32F is never renderable, but no harm here. 518 519 #undef SET_BY_SUFFIX 520 521 522 ////// 523 524 #define SET_BY_SUFFIX(X) \ 525 SET_COPY_DECAY( R##X, R##X, MAX, MAX, MAX, MAX, MAX, MAX) \ 526 SET_COPY_DECAY( RG##X, R##X, RG##X, MAX, MAX, MAX, MAX, MAX) \ 527 SET_COPY_DECAY(RGBA##X, R##X, RG##X, RGB##X, RGBA##X, MAX, MAX, MAX) 528 529 SET_BY_SUFFIX(8I) 530 SET_BY_SUFFIX(8UI) 531 532 SET_BY_SUFFIX(16) 533 SET_BY_SUFFIX(16I) 534 SET_BY_SUFFIX(16UI) 535 536 SET_BY_SUFFIX(32I) 537 SET_BY_SUFFIX(32UI) 538 539 #undef SET_BY_SUFFIX 540 541 ////// 542 543 SET_COPY_DECAY( RGB565, R8, RG8, RGB565, MAX, Luminance8, MAX, MAX) 544 SET_COPY_DECAY( RGBA4, R8, RG8, RGB565, RGBA4, Luminance8, Alpha8, Luminance8Alpha8) 545 SET_COPY_DECAY( RGB5_A1, R8, RG8, RGB565, RGB5_A1, Luminance8, Alpha8, Luminance8Alpha8) 546 SET_COPY_DECAY( RGB10_A2, R8, RG8, RGB8, RGB10_A2, Luminance8, Alpha8, MAX) 547 548 SET_COPY_DECAY(RGB10_A2UI, R8UI, RG8UI, RGB8UI, RGB10_A2UI, MAX, MAX, MAX) 549 550 SET_COPY_DECAY(SRGB8_ALPHA8, MAX, MAX, MAX, SRGB8_ALPHA8, MAX, Alpha8, MAX) 551 552 SET_COPY_DECAY(R11F_G11F_B10F, R16F, RG16F, R11F_G11F_B10F, MAX, Luminance16F, MAX, MAX) 553 554 #undef SET_COPY_DECAY 555 556 // clang-format on 557 } 558 559 ////////////////////////////////////////////////////////////////////////////////////////// 560 561 bool gAreFormatTablesInitialized = false; 562 563 static void EnsureInitFormatTables( 564 const StaticMutexAutoLock&) // Prove that you locked it! 565 { 566 if (MOZ_LIKELY(gAreFormatTablesInitialized)) return; 567 568 gAreFormatTablesInitialized = true; 569 570 InitCompressedFormatInfo(); 571 InitFormatInfo(); 572 } 573 574 ////////////////////////////////////////////////////////////////////////////////////////// 575 // Public funcs 576 577 StaticMutex gFormatMapMutex; 578 579 const FormatInfo* GetFormat(EffectiveFormat format) { 580 StaticMutexAutoLock lock(gFormatMapMutex); 581 EnsureInitFormatTables(lock); 582 583 return GetFormatInfo_NoLock(format); 584 } 585 586 ////////////////////////////////////////////////////////////////////////////////////////// 587 588 const FormatInfo* FormatInfo::GetCopyDecayFormat(UnsizedFormat uf) const { 589 return FindOrNull(this->copyDecayFormats, uf); 590 } 591 592 Maybe<PackingInfoInfo> PackingInfoInfo::For(const PackingInfo& pi) { 593 PackingInfoInfo ret{}; 594 595 switch (pi.type) { 596 case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4: 597 case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1: 598 case LOCAL_GL_UNSIGNED_SHORT_5_6_5: 599 ret = {2, 1, true}; 600 break; 601 602 case LOCAL_GL_UNSIGNED_INT_10F_11F_11F_REV: 603 case LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV: 604 case LOCAL_GL_UNSIGNED_INT_24_8: 605 case LOCAL_GL_UNSIGNED_INT_5_9_9_9_REV: 606 ret = {4, 1, true}; 607 break; 608 609 case LOCAL_GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 610 ret = {8, 1, true}; 611 break; 612 613 // Alright, that's all the fixed-size unpackTypes. 614 615 case LOCAL_GL_BYTE: 616 case LOCAL_GL_UNSIGNED_BYTE: 617 ret = {1, 0, false}; 618 break; 619 620 case LOCAL_GL_SHORT: 621 case LOCAL_GL_UNSIGNED_SHORT: 622 case LOCAL_GL_HALF_FLOAT: 623 case LOCAL_GL_HALF_FLOAT_OES: 624 ret = {2, 0, false}; 625 break; 626 627 case LOCAL_GL_INT: 628 case LOCAL_GL_UNSIGNED_INT: 629 case LOCAL_GL_FLOAT: 630 ret = {4, 0, false}; 631 break; 632 633 default: 634 return {}; 635 } 636 637 if (!ret.isPacked) { 638 switch (pi.format) { 639 case LOCAL_GL_RED: 640 case LOCAL_GL_RED_INTEGER: 641 case LOCAL_GL_LUMINANCE: 642 case LOCAL_GL_ALPHA: 643 case LOCAL_GL_DEPTH_COMPONENT: 644 ret.elementsPerPixel = 1; 645 break; 646 647 case LOCAL_GL_RG: 648 case LOCAL_GL_RG_INTEGER: 649 case LOCAL_GL_LUMINANCE_ALPHA: 650 ret.elementsPerPixel = 2; 651 break; 652 653 case LOCAL_GL_RGB: 654 case LOCAL_GL_RGB_INTEGER: 655 case LOCAL_GL_SRGB: 656 ret.elementsPerPixel = 3; 657 break; 658 659 case LOCAL_GL_BGRA: 660 case LOCAL_GL_RGBA: 661 case LOCAL_GL_RGBA_INTEGER: 662 case LOCAL_GL_SRGB_ALPHA: 663 ret.elementsPerPixel = 4; 664 break; 665 666 default: 667 return {}; 668 } 669 } 670 671 return Some(ret); 672 } 673 674 ////////////////////////////////////////////////////////////////////////////////////////// 675 ////////////////////////////////////////////////////////////////////////////////////////// 676 ////////////////////////////////////////////////////////////////////////////////////////// 677 ////////////////////////////////////////////////////////////////////////////////////////// 678 ////////////////////////////////////////////////////////////////////////////////////////// 679 ////////////////////////////////////////////////////////////////////////////////////////// 680 ////////////////////////////////////////////////////////////////////////////////////////// 681 ////////////////////////////////////////////////////////////////////////////////////////// 682 // FormatUsageAuthority 683 684 bool FormatUsageInfo::IsUnpackValid( 685 const PackingInfo& key, const DriverUnpackInfo** const out_value) const { 686 auto itr = validUnpacks.find(key); 687 if (itr == validUnpacks.end()) return false; 688 689 *out_value = &(itr->second); 690 return true; 691 } 692 693 void FormatUsageInfo::ResolveMaxSamples(gl::GLContext& gl) const { 694 MOZ_ASSERT(gl.IsCurrent()); 695 MOZ_ASSERT(!this->maxSamplesKnown); 696 MOZ_ASSERT(!this->maxSamples); 697 this->maxSamplesKnown = true; 698 699 const GLenum internalFormat = this->format->sizedFormat; 700 if (!internalFormat) return; 701 if (!gl.IsSupported(gl::GLFeature::internalformat_query)) return; 702 703 // GL_SAMPLES returns a list in descending order, so ask for just one elem to 704 // get the max. 705 gl.fGetInternalformativ(LOCAL_GL_RENDERBUFFER, internalFormat, 706 LOCAL_GL_SAMPLES, 1, 707 reinterpret_cast<GLint*>(&this->maxSamples)); 708 } 709 710 //////////////////////////////////////// 711 712 static void AddSimpleUnsized(FormatUsageAuthority* fua, GLenum unpackFormat, 713 GLenum unpackType, EffectiveFormat effFormat) { 714 auto usage = fua->EditUsage(effFormat); 715 usage->isFilterable = true; 716 717 const PackingInfo pi = {unpackFormat, unpackType}; 718 const DriverUnpackInfo dui = {unpackFormat, unpackFormat, unpackType}; 719 fua->AddTexUnpack(usage, pi, dui); 720 721 fua->AllowUnsizedTexFormat(pi, usage); 722 }; 723 724 /*static*/ const GLint FormatUsageInfo::kLuminanceSwizzleRGBA[4] = { 725 LOCAL_GL_RED, LOCAL_GL_RED, LOCAL_GL_RED, LOCAL_GL_ONE}; 726 /*static*/ const GLint FormatUsageInfo::kAlphaSwizzleRGBA[4] = { 727 LOCAL_GL_ZERO, LOCAL_GL_ZERO, LOCAL_GL_ZERO, LOCAL_GL_RED}; 728 /*static*/ const GLint FormatUsageInfo::kLumAlphaSwizzleRGBA[4] = { 729 LOCAL_GL_RED, LOCAL_GL_RED, LOCAL_GL_RED, LOCAL_GL_GREEN}; 730 731 static bool AddLegacyFormats_LA8(FormatUsageAuthority* fua, gl::GLContext* gl) { 732 if (gl->IsCoreProfile()) { 733 if (!gl->IsSupported(gl::GLFeature::texture_swizzle)) return false; 734 735 PackingInfo pi; 736 DriverUnpackInfo dui; 737 738 const auto fnAdd = [fua, &pi, &dui](EffectiveFormat effFormat, 739 const GLint* swizzle) { 740 auto usage = fua->EditUsage(effFormat); 741 usage->isFilterable = true; 742 usage->textureSwizzleRGBA = swizzle; 743 744 fua->AddTexUnpack(usage, pi, dui); 745 746 fua->AllowUnsizedTexFormat(pi, usage); 747 }; 748 749 pi = {LOCAL_GL_LUMINANCE, LOCAL_GL_UNSIGNED_BYTE}; 750 dui = {LOCAL_GL_R8, LOCAL_GL_RED, LOCAL_GL_UNSIGNED_BYTE}; 751 fnAdd(EffectiveFormat::Luminance8, FormatUsageInfo::kLuminanceSwizzleRGBA); 752 753 pi = {LOCAL_GL_ALPHA, LOCAL_GL_UNSIGNED_BYTE}; 754 dui = {LOCAL_GL_R8, LOCAL_GL_RED, LOCAL_GL_UNSIGNED_BYTE}; 755 fnAdd(EffectiveFormat::Alpha8, FormatUsageInfo::kAlphaSwizzleRGBA); 756 757 pi = {LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_UNSIGNED_BYTE}; 758 dui = {LOCAL_GL_RG8, LOCAL_GL_RG, LOCAL_GL_UNSIGNED_BYTE}; 759 fnAdd(EffectiveFormat::Luminance8Alpha8, 760 FormatUsageInfo::kLumAlphaSwizzleRGBA); 761 } else { 762 // clang-format off 763 AddSimpleUnsized(fua, LOCAL_GL_LUMINANCE , LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Luminance8 ); 764 AddSimpleUnsized(fua, LOCAL_GL_ALPHA , LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Alpha8 ); 765 AddSimpleUnsized(fua, LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Luminance8Alpha8); 766 // clang-format on 767 } 768 769 return true; 770 } 771 772 static bool AddUnsizedFormats(FormatUsageAuthority* fua, gl::GLContext* gl) { 773 // clang-format off 774 775 // GLES 2.0.25, p63, Table 3.4 776 AddSimpleUnsized(fua, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::RGBA8 ); 777 AddSimpleUnsized(fua, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_4_4_4_4, EffectiveFormat::RGBA4 ); 778 AddSimpleUnsized(fua, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_5_5_5_1, EffectiveFormat::RGB5_A1); 779 AddSimpleUnsized(fua, LOCAL_GL_RGB , LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::RGB8 ); 780 AddSimpleUnsized(fua, LOCAL_GL_RGB , LOCAL_GL_UNSIGNED_SHORT_5_6_5 , EffectiveFormat::RGB565 ); 781 782 // L, A, LA 783 return AddLegacyFormats_LA8(fua, gl); 784 785 // clang-format on 786 } 787 788 void FormatUsageInfo::SetRenderable(const FormatRenderableState& state) { 789 if (!renderableState.IsExplicit()) { 790 renderableState = state; 791 } 792 793 #ifdef DEBUG 794 const auto format = this->format; 795 if (format->IsColorFormat()) { 796 const auto& map = format->copyDecayFormats; 797 const auto itr = map.find(format->unsizedFormat); 798 MOZ_ASSERT(itr != map.end(), 799 "Renderable formats must be in copyDecayFormats."); 800 MOZ_ASSERT(itr->second == format); 801 } 802 #endif 803 } 804 805 std::unique_ptr<FormatUsageAuthority> FormatUsageAuthority::CreateForWebGL1( 806 gl::GLContext* gl) { 807 std::unique_ptr<FormatUsageAuthority> ret(new FormatUsageAuthority); 808 const auto ptr = ret.get(); 809 810 //////////////////////////////////////////////////////////////////////////// 811 // Usages 812 813 const auto fnSet = [ptr](EffectiveFormat effFormat, bool isRenderable, 814 bool isFilterable) { 815 MOZ_ASSERT(!ptr->GetUsage(effFormat)); 816 817 auto usage = ptr->EditUsage(effFormat); 818 usage->isFilterable = isFilterable; 819 820 if (isRenderable) { 821 usage->SetRenderable(); 822 } 823 }; 824 825 // Largely from GLES 2.0.25, p117, Table 4.5, but also: 826 // * RGBA8: Made renderable in WebGL 1.0, "Framebuffer Object Attachments". 827 // * RGB8: Not guaranteed by ES2 to be renderable, but we should allow it for 828 // web-compat. Min-capability mode should mark this as non-renderable. 829 830 constexpr bool ALWAYS = true; // For better contrast with `false` in tables. 831 832 // clang-format off 833 // | format | renderable | filterable | 834 fnSet(EffectiveFormat::RGBA8 , ALWAYS , ALWAYS ); 835 fnSet(EffectiveFormat::RGBA4 , ALWAYS , ALWAYS ); 836 fnSet(EffectiveFormat::RGB5_A1 , ALWAYS , ALWAYS ); 837 fnSet(EffectiveFormat::RGB565 , ALWAYS , ALWAYS ); 838 fnSet(EffectiveFormat::RGB8 , ALWAYS , ALWAYS ); 839 // "Legacy" formats 840 fnSet(EffectiveFormat::Luminance8Alpha8 , false , ALWAYS ); 841 fnSet(EffectiveFormat::Luminance8 , false , ALWAYS ); 842 fnSet(EffectiveFormat::Alpha8 , false , ALWAYS ); 843 // Depth/stencil 844 fnSet(EffectiveFormat::DEPTH_COMPONENT16, ALWAYS , ALWAYS ); 845 fnSet(EffectiveFormat::DEPTH_COMPONENT24, ALWAYS , ALWAYS ); 846 fnSet(EffectiveFormat::STENCIL_INDEX8 , ALWAYS , false ); 847 // Added in WebGL 1.0 spec: 848 fnSet(EffectiveFormat::DEPTH24_STENCIL8 , ALWAYS , ALWAYS ); 849 // | format | renderable | filterable | 850 // clang-format on 851 852 //////////////////////////////////// 853 // RB formats 854 855 #define FOO(x) \ 856 ptr->AllowRBFormat(LOCAL_GL_##x, ptr->GetUsage(EffectiveFormat::x)) 857 858 FOO(RGBA4); 859 FOO(RGB5_A1); 860 FOO(RGB565); 861 FOO(DEPTH_COMPONENT16); 862 FOO(STENCIL_INDEX8); 863 // FOO(DEPTH24_STENCIL8 ); // WebGL 1 uses DEPTH_STENCIL instead of 864 // DEPTH24_STENCIL8. 865 866 #undef FOO 867 868 ptr->AllowRBFormat(LOCAL_GL_DEPTH_STENCIL, 869 ptr->GetUsage(EffectiveFormat::DEPTH24_STENCIL8)); 870 871 //////////////////////////////////////////////////////////////////////////// 872 873 if (!AddUnsizedFormats(ptr, gl)) return nullptr; 874 875 return ret; 876 } 877 878 std::unique_ptr<FormatUsageAuthority> FormatUsageAuthority::CreateForWebGL2( 879 gl::GLContext* gl) { 880 std::unique_ptr<FormatUsageAuthority> ret(new FormatUsageAuthority); 881 const auto ptr = ret.get(); 882 883 //////////////////////////////////////////////////////////////////////////// 884 // GLES 3.0.4 p111-113 885 886 const auto fnAddSizedUnpack = [ptr](EffectiveFormat effFormat, 887 GLenum internalFormat, 888 GLenum unpackFormat, GLenum unpackType) { 889 auto usage = ptr->EditUsage(effFormat); 890 891 const PackingInfo pi = {unpackFormat, unpackType}; 892 const DriverUnpackInfo dui = {internalFormat, unpackFormat, unpackType}; 893 ptr->AddTexUnpack(usage, pi, dui); 894 }; 895 896 // clang-format off 897 #define FOO(x) EffectiveFormat::x, LOCAL_GL_ ## x 898 899 // RGBA 900 fnAddSizedUnpack(FOO(RGBA8 ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE ); 901 fnAddSizedUnpack(FOO(RGBA4 ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ); 902 fnAddSizedUnpack(FOO(RGBA4 ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE ); 903 fnAddSizedUnpack(FOO(RGB5_A1 ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ); 904 fnAddSizedUnpack(FOO(RGB5_A1 ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE ); 905 fnAddSizedUnpack(FOO(RGB5_A1 ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV); 906 fnAddSizedUnpack(FOO(SRGB8_ALPHA8), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE ); 907 fnAddSizedUnpack(FOO(RGBA8_SNORM ), LOCAL_GL_RGBA, LOCAL_GL_BYTE ); 908 fnAddSizedUnpack(FOO(RGB10_A2 ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV); 909 fnAddSizedUnpack(FOO(RGBA16F ), LOCAL_GL_RGBA, LOCAL_GL_HALF_FLOAT ); 910 fnAddSizedUnpack(FOO(RGBA16F ), LOCAL_GL_RGBA, LOCAL_GL_FLOAT ); 911 fnAddSizedUnpack(FOO(RGBA32F ), LOCAL_GL_RGBA, LOCAL_GL_FLOAT ); 912 913 // RGBA_INTEGER 914 fnAddSizedUnpack(FOO(RGBA8UI ), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_UNSIGNED_BYTE ); 915 fnAddSizedUnpack(FOO(RGBA8I ), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_BYTE ); 916 fnAddSizedUnpack(FOO(RGBA16UI ), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_UNSIGNED_SHORT ); 917 fnAddSizedUnpack(FOO(RGBA16I ), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_SHORT ); 918 fnAddSizedUnpack(FOO(RGBA32UI ), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_UNSIGNED_INT ); 919 fnAddSizedUnpack(FOO(RGBA32I ), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_INT ); 920 fnAddSizedUnpack(FOO(RGB10_A2UI), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV); 921 922 // RGB 923 fnAddSizedUnpack(FOO(RGB8 ), LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_BYTE ); 924 fnAddSizedUnpack(FOO(SRGB8 ), LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_BYTE ); 925 fnAddSizedUnpack(FOO(RGB565 ), LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_SHORT_5_6_5 ); 926 fnAddSizedUnpack(FOO(RGB565 ), LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_BYTE ); 927 fnAddSizedUnpack(FOO(RGB8_SNORM ), LOCAL_GL_RGB, LOCAL_GL_BYTE ); 928 fnAddSizedUnpack(FOO(R11F_G11F_B10F), LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_INT_10F_11F_11F_REV); 929 fnAddSizedUnpack(FOO(R11F_G11F_B10F), LOCAL_GL_RGB, LOCAL_GL_HALF_FLOAT ); 930 fnAddSizedUnpack(FOO(R11F_G11F_B10F), LOCAL_GL_RGB, LOCAL_GL_FLOAT ); 931 fnAddSizedUnpack(FOO(RGB16F ), LOCAL_GL_RGB, LOCAL_GL_HALF_FLOAT ); 932 fnAddSizedUnpack(FOO(RGB16F ), LOCAL_GL_RGB, LOCAL_GL_FLOAT ); 933 fnAddSizedUnpack(FOO(RGB9_E5 ), LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_INT_5_9_9_9_REV ); 934 fnAddSizedUnpack(FOO(RGB9_E5 ), LOCAL_GL_RGB, LOCAL_GL_HALF_FLOAT ); 935 fnAddSizedUnpack(FOO(RGB9_E5 ), LOCAL_GL_RGB, LOCAL_GL_FLOAT ); 936 fnAddSizedUnpack(FOO(RGB32F ), LOCAL_GL_RGB, LOCAL_GL_FLOAT ); 937 938 // RGB_INTEGER 939 fnAddSizedUnpack(FOO(RGB8UI ), LOCAL_GL_RGB_INTEGER, LOCAL_GL_UNSIGNED_BYTE ); 940 fnAddSizedUnpack(FOO(RGB8I ), LOCAL_GL_RGB_INTEGER, LOCAL_GL_BYTE ); 941 fnAddSizedUnpack(FOO(RGB16UI), LOCAL_GL_RGB_INTEGER, LOCAL_GL_UNSIGNED_SHORT); 942 fnAddSizedUnpack(FOO(RGB16I ), LOCAL_GL_RGB_INTEGER, LOCAL_GL_SHORT ); 943 fnAddSizedUnpack(FOO(RGB32UI), LOCAL_GL_RGB_INTEGER, LOCAL_GL_UNSIGNED_INT ); 944 fnAddSizedUnpack(FOO(RGB32I ), LOCAL_GL_RGB_INTEGER, LOCAL_GL_INT ); 945 946 // RG 947 fnAddSizedUnpack(FOO(RG8 ), LOCAL_GL_RG, LOCAL_GL_UNSIGNED_BYTE); 948 fnAddSizedUnpack(FOO(RG8_SNORM), LOCAL_GL_RG, LOCAL_GL_BYTE ); 949 fnAddSizedUnpack(FOO(RG16F ), LOCAL_GL_RG, LOCAL_GL_HALF_FLOAT ); 950 fnAddSizedUnpack(FOO(RG16F ), LOCAL_GL_RG, LOCAL_GL_FLOAT ); 951 fnAddSizedUnpack(FOO(RG32F ), LOCAL_GL_RG, LOCAL_GL_FLOAT ); 952 953 // RG_INTEGER 954 fnAddSizedUnpack(FOO(RG8UI ), LOCAL_GL_RG_INTEGER, LOCAL_GL_UNSIGNED_BYTE ); 955 fnAddSizedUnpack(FOO(RG8I ), LOCAL_GL_RG_INTEGER, LOCAL_GL_BYTE ); 956 fnAddSizedUnpack(FOO(RG16UI), LOCAL_GL_RG_INTEGER, LOCAL_GL_UNSIGNED_SHORT); 957 fnAddSizedUnpack(FOO(RG16I ), LOCAL_GL_RG_INTEGER, LOCAL_GL_SHORT ); 958 fnAddSizedUnpack(FOO(RG32UI), LOCAL_GL_RG_INTEGER, LOCAL_GL_UNSIGNED_INT ); 959 fnAddSizedUnpack(FOO(RG32I ), LOCAL_GL_RG_INTEGER, LOCAL_GL_INT ); 960 961 // RED 962 fnAddSizedUnpack(FOO(R8 ), LOCAL_GL_RED, LOCAL_GL_UNSIGNED_BYTE); 963 fnAddSizedUnpack(FOO(R8_SNORM), LOCAL_GL_RED, LOCAL_GL_BYTE ); 964 fnAddSizedUnpack(FOO(R16F ), LOCAL_GL_RED, LOCAL_GL_HALF_FLOAT ); 965 fnAddSizedUnpack(FOO(R16F ), LOCAL_GL_RED, LOCAL_GL_FLOAT ); 966 fnAddSizedUnpack(FOO(R32F ), LOCAL_GL_RED, LOCAL_GL_FLOAT ); 967 968 // RED_INTEGER 969 fnAddSizedUnpack(FOO(R8UI ), LOCAL_GL_RED_INTEGER, LOCAL_GL_UNSIGNED_BYTE ); 970 fnAddSizedUnpack(FOO(R8I ), LOCAL_GL_RED_INTEGER, LOCAL_GL_BYTE ); 971 fnAddSizedUnpack(FOO(R16UI), LOCAL_GL_RED_INTEGER, LOCAL_GL_UNSIGNED_SHORT); 972 fnAddSizedUnpack(FOO(R16I ), LOCAL_GL_RED_INTEGER, LOCAL_GL_SHORT ); 973 fnAddSizedUnpack(FOO(R32UI), LOCAL_GL_RED_INTEGER, LOCAL_GL_UNSIGNED_INT ); 974 fnAddSizedUnpack(FOO(R32I ), LOCAL_GL_RED_INTEGER, LOCAL_GL_INT ); 975 976 // DEPTH_COMPONENT 977 fnAddSizedUnpack(FOO(DEPTH_COMPONENT16 ), LOCAL_GL_DEPTH_COMPONENT, LOCAL_GL_UNSIGNED_SHORT); 978 fnAddSizedUnpack(FOO(DEPTH_COMPONENT16 ), LOCAL_GL_DEPTH_COMPONENT, LOCAL_GL_UNSIGNED_INT ); 979 fnAddSizedUnpack(FOO(DEPTH_COMPONENT24 ), LOCAL_GL_DEPTH_COMPONENT, LOCAL_GL_UNSIGNED_INT ); 980 fnAddSizedUnpack(FOO(DEPTH_COMPONENT32F), LOCAL_GL_DEPTH_COMPONENT, LOCAL_GL_FLOAT ); 981 982 // DEPTH_STENCIL 983 fnAddSizedUnpack(FOO(DEPTH24_STENCIL8 ), LOCAL_GL_DEPTH_STENCIL, LOCAL_GL_UNSIGNED_INT_24_8 ); 984 fnAddSizedUnpack(FOO(DEPTH32F_STENCIL8), LOCAL_GL_DEPTH_STENCIL, LOCAL_GL_FLOAT_32_UNSIGNED_INT_24_8_REV); 985 986 #undef FOO 987 // clang-format on 988 989 //////////////////////////////////////////////////////////////////////////// 990 991 // For renderable, see GLES 3.0.4, p212 "Framebuffer Completeness" 992 // For filterable, see GLES 3.0.4, p161 "...a texture is complete unless..." 993 994 const auto fnAllowES3TexFormat = [ptr](GLenum sizedFormat, 995 EffectiveFormat effFormat, 996 bool isRenderable, bool isFilterable) { 997 auto usage = ptr->EditUsage(effFormat); 998 usage->isFilterable = isFilterable; 999 1000 if (isRenderable) { 1001 usage->SetRenderable(); 1002 } 1003 1004 ptr->AllowSizedTexFormat(sizedFormat, usage); 1005 1006 if (isRenderable) { 1007 ptr->AllowRBFormat(sizedFormat, usage); 1008 } 1009 }; 1010 1011 constexpr bool ALWAYS = true; // For better contrast with `false` in tables. 1012 1013 // clang-format off 1014 #define _(x) LOCAL_GL_##x, EffectiveFormat::x 1015 1016 // GLES 3.0.4, p128-129 "Required Texture Formats" 1017 // GLES 3.0.4, p130-132, table 3.13 1018 // | format | renderable | filterable | 1019 fnAllowES3TexFormat(_(R8) , ALWAYS , ALWAYS ); 1020 fnAllowES3TexFormat(_(R8_SNORM) , false , ALWAYS ); 1021 fnAllowES3TexFormat(_(RG8) , ALWAYS , ALWAYS ); 1022 fnAllowES3TexFormat(_(RG8_SNORM) , false , ALWAYS ); 1023 fnAllowES3TexFormat(_(RGB8) , ALWAYS , ALWAYS ); 1024 fnAllowES3TexFormat(_(RGB8_SNORM) , false , ALWAYS ); 1025 fnAllowES3TexFormat(_(RGB565) , ALWAYS , ALWAYS ); 1026 fnAllowES3TexFormat(_(RGBA4) , ALWAYS , ALWAYS ); 1027 fnAllowES3TexFormat(_(RGB5_A1) , ALWAYS , ALWAYS ); 1028 fnAllowES3TexFormat(_(RGBA8) , ALWAYS , ALWAYS ); 1029 fnAllowES3TexFormat(_(RGBA8_SNORM) , false , ALWAYS ); 1030 fnAllowES3TexFormat(_(RGB10_A2) , ALWAYS , ALWAYS ); 1031 fnAllowES3TexFormat(_(RGB10_A2UI) , ALWAYS , false ); 1032 1033 fnAllowES3TexFormat(_(SRGB8) , false , ALWAYS ); 1034 fnAllowES3TexFormat(_(SRGB8_ALPHA8) , ALWAYS , ALWAYS ); 1035 // | format | renderable | filterable | 1036 fnAllowES3TexFormat(_(R16F) , false , ALWAYS ); 1037 fnAllowES3TexFormat(_(RG16F) , false , ALWAYS ); 1038 fnAllowES3TexFormat(_(RGB16F) , false , ALWAYS ); 1039 fnAllowES3TexFormat(_(RGBA16F) , false , ALWAYS ); 1040 1041 fnAllowES3TexFormat(_(R32F) , false , false ); 1042 fnAllowES3TexFormat(_(RG32F) , false , false ); 1043 fnAllowES3TexFormat(_(RGB32F) , false , false ); 1044 fnAllowES3TexFormat(_(RGBA32F) , false , false ); 1045 1046 fnAllowES3TexFormat(_(R11F_G11F_B10F) , false , ALWAYS ); 1047 fnAllowES3TexFormat(_(RGB9_E5) , false , ALWAYS ); 1048 // | format | renderable | filterable | 1049 fnAllowES3TexFormat(_(R8I) , ALWAYS , false ); 1050 fnAllowES3TexFormat(_(R8UI) , ALWAYS , false ); 1051 fnAllowES3TexFormat(_(R16I) , ALWAYS , false ); 1052 fnAllowES3TexFormat(_(R16UI) , ALWAYS , false ); 1053 fnAllowES3TexFormat(_(R32I) , ALWAYS , false ); 1054 fnAllowES3TexFormat(_(R32UI) , ALWAYS , false ); 1055 1056 fnAllowES3TexFormat(_(RG8I) , ALWAYS , false ); 1057 fnAllowES3TexFormat(_(RG8UI) , ALWAYS , false ); 1058 fnAllowES3TexFormat(_(RG16I) , ALWAYS , false ); 1059 fnAllowES3TexFormat(_(RG16UI) , ALWAYS , false ); 1060 fnAllowES3TexFormat(_(RG32I) , ALWAYS , false ); 1061 fnAllowES3TexFormat(_(RG32UI) , ALWAYS , false ); 1062 // | format | renderable | filterable | 1063 fnAllowES3TexFormat(_(RGB8I) , false , false ); 1064 fnAllowES3TexFormat(_(RGB8UI) , false , false ); 1065 fnAllowES3TexFormat(_(RGB16I) , false , false ); 1066 fnAllowES3TexFormat(_(RGB16UI) , false , false ); 1067 fnAllowES3TexFormat(_(RGB32I) , false , false ); 1068 fnAllowES3TexFormat(_(RGB32UI) , false , false ); 1069 1070 fnAllowES3TexFormat(_(RGBA8I) , ALWAYS , false ); 1071 fnAllowES3TexFormat(_(RGBA8UI) , ALWAYS , false ); 1072 fnAllowES3TexFormat(_(RGBA16I) , ALWAYS , false ); 1073 fnAllowES3TexFormat(_(RGBA16UI) , ALWAYS , false ); 1074 fnAllowES3TexFormat(_(RGBA32I) , ALWAYS , false ); 1075 fnAllowES3TexFormat(_(RGBA32UI) , ALWAYS , false ); 1076 // | format | renderable | filterable | 1077 fnAllowES3TexFormat(_(DEPTH_COMPONENT16) , ALWAYS , false ); // [1] 1078 fnAllowES3TexFormat(_(DEPTH_COMPONENT24) , ALWAYS , false ); // [1] 1079 fnAllowES3TexFormat(_(DEPTH_COMPONENT32F), ALWAYS , false ); // [1] 1080 fnAllowES3TexFormat(_(DEPTH24_STENCIL8) , ALWAYS , false ); // [1] 1081 fnAllowES3TexFormat(_(DEPTH32F_STENCIL8) , ALWAYS , false ); // [1] 1082 1083 // [1]: Sized depth or depth-stencil formats are not filterable 1084 // per GLES 3.0.6 p161. 1085 // Specifically, they're texture-incomplete if depth-compare:none and 1086 // not NEAREST. 1087 1088 #undef _ 1089 // clang-format on 1090 1091 // GLES 3.0.4, p206, "Required Renderbuffer Formats": 1092 // "Implementations are also required to support STENCIL_INDEX8. Requesting 1093 // this internal format for a renderbuffer will allocate at least 8 stencil 1094 // bit planes." 1095 1096 auto usage = ptr->EditUsage(EffectiveFormat::STENCIL_INDEX8); 1097 usage->SetRenderable(); 1098 ptr->AllowRBFormat(LOCAL_GL_STENCIL_INDEX8, usage); 1099 1100 //////////////// 1101 // Legacy formats 1102 1103 if (!AddUnsizedFormats(ptr, gl)) return nullptr; 1104 1105 ptr->AllowRBFormat(LOCAL_GL_DEPTH_STENCIL, 1106 ptr->GetUsage(EffectiveFormat::DEPTH24_STENCIL8)); 1107 1108 //////////////////////////////////// 1109 1110 return ret; 1111 } 1112 1113 ////////////////////////////////////////////////////////////////////////////////////////// 1114 1115 void FormatUsageAuthority::AddTexUnpack(FormatUsageInfo* usage, 1116 const PackingInfo& pi, 1117 const DriverUnpackInfo& dui) { 1118 // Don't AlwaysInsert here, since we'll see duplicates from sized and unsized 1119 // formats. 1120 auto res = usage->validUnpacks.insert({pi, dui}); 1121 auto itr = res.first; 1122 1123 if (!usage->idealUnpack) { 1124 // First one! 1125 usage->idealUnpack = &(itr->second); 1126 } 1127 1128 mValidTexUnpackFormats.insert(pi.format); 1129 mValidTexUnpackTypes.insert(pi.type); 1130 } 1131 1132 static bool Contains(const std::set<GLenum>& set, GLenum key) { 1133 return set.find(key) != set.end(); 1134 } 1135 1136 bool FormatUsageAuthority::IsInternalFormatEnumValid( 1137 GLenum internalFormat) const { 1138 return Contains(mValidTexInternalFormats, internalFormat); 1139 } 1140 1141 bool FormatUsageAuthority::AreUnpackEnumsValid(GLenum unpackFormat, 1142 GLenum unpackType) const { 1143 return (Contains(mValidTexUnpackFormats, unpackFormat) && 1144 Contains(mValidTexUnpackTypes, unpackType)); 1145 } 1146 1147 //////////////////// 1148 1149 void FormatUsageAuthority::AllowRBFormat(GLenum sizedFormat, 1150 const FormatUsageInfo* usage, 1151 const bool expectRenderable) { 1152 MOZ_ASSERT(!usage->format->compression); 1153 MOZ_ASSERT(usage->format->sizedFormat); 1154 MOZ_ASSERT(usage->IsRenderable() || !expectRenderable); 1155 1156 const auto& found = mRBFormatMap.find(sizedFormat); 1157 if (found != mRBFormatMap.end()) { 1158 MOZ_ASSERT(found->second == usage); 1159 return; 1160 } 1161 AlwaysInsert(mRBFormatMap, sizedFormat, usage); 1162 } 1163 1164 void FormatUsageAuthority::AllowSizedTexFormat(GLenum sizedFormat, 1165 const FormatUsageInfo* usage) { 1166 if (usage->format->compression) { 1167 MOZ_ASSERT(usage->isFilterable, "Compressed formats should be filterable."); 1168 } else { 1169 MOZ_ASSERT(!usage->validUnpacks.empty() && usage->idealUnpack, 1170 "AddTexUnpack() first."); 1171 } 1172 1173 AlwaysInsert(mSizedTexFormatMap, sizedFormat, usage); 1174 1175 mValidTexInternalFormats.insert(sizedFormat); 1176 } 1177 1178 void FormatUsageAuthority::AllowUnsizedTexFormat(const PackingInfo& pi, 1179 const FormatUsageInfo* usage) { 1180 MOZ_ASSERT(!usage->format->compression); 1181 MOZ_ASSERT(!usage->validUnpacks.empty() && usage->idealUnpack, 1182 "AddTexUnpack() first."); 1183 1184 AlwaysInsert(mUnsizedTexFormatMap, pi, usage); 1185 1186 mValidTexInternalFormats.insert(pi.format); 1187 mValidTexUnpackFormats.insert(pi.format); 1188 mValidTexUnpackTypes.insert(pi.type); 1189 } 1190 1191 const FormatUsageInfo* FormatUsageAuthority::GetRBUsage( 1192 GLenum sizedFormat) const { 1193 return FindOrNull(mRBFormatMap, sizedFormat); 1194 } 1195 1196 const FormatUsageInfo* FormatUsageAuthority::GetSizedTexUsage( 1197 GLenum sizedFormat) const { 1198 return FindOrNull(mSizedTexFormatMap, sizedFormat); 1199 } 1200 1201 const FormatUsageInfo* FormatUsageAuthority::GetUnsizedTexUsage( 1202 const PackingInfo& pi) const { 1203 return FindOrNull(mUnsizedTexFormatMap, pi); 1204 } 1205 1206 FormatUsageInfo* FormatUsageAuthority::EditUsage(EffectiveFormat format) { 1207 auto itr = mUsageMap.find(format); 1208 1209 if (itr == mUsageMap.end()) { 1210 const FormatInfo* formatInfo = GetFormat(format); 1211 MOZ_RELEASE_ASSERT(formatInfo, "GFX: no format info set."); 1212 1213 FormatUsageInfo usage(formatInfo); 1214 1215 auto res = mUsageMap.insert({format, usage}); 1216 DebugOnly<bool> didInsert = res.second; 1217 MOZ_ASSERT(didInsert); 1218 1219 itr = res.first; 1220 } 1221 1222 return &(itr->second); 1223 } 1224 1225 const FormatUsageInfo* FormatUsageAuthority::GetUsage( 1226 EffectiveFormat format) const { 1227 auto itr = mUsageMap.find(format); 1228 if (itr == mUsageMap.end()) return nullptr; 1229 1230 return &(itr->second); 1231 } 1232 1233 //////////////////////////////////////////////////////////////////////////////// 1234 1235 } // namespace mozilla::webgl