1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // utilities.cpp: Conversion functions and other utility routines. 16 17 #include "utilities.h" 18 19 #include "Framebuffer.h" 20 #include "main.h" 21 #include "mathutil.h" 22 #include "Context.h" 23 #include "Shader.h" 24 #include "common/debug.h" 25 26 #include <limits> 27 #include <stdio.h> 28 #include <stdlib.h> 29 30 namespace es2 31 { 32 UniformComponentCount(GLenum type)33 unsigned int UniformComponentCount(GLenum type) 34 { 35 switch(type) 36 { 37 case GL_BOOL: 38 case GL_FLOAT: 39 case GL_INT: 40 case GL_UNSIGNED_INT: 41 case GL_SAMPLER_2D: 42 case GL_SAMPLER_CUBE: 43 case GL_SAMPLER_2D_RECT_ARB: 44 case GL_SAMPLER_EXTERNAL_OES: 45 case GL_SAMPLER_3D_OES: 46 case GL_SAMPLER_2D_ARRAY: 47 case GL_SAMPLER_2D_SHADOW: 48 case GL_SAMPLER_CUBE_SHADOW: 49 case GL_SAMPLER_2D_ARRAY_SHADOW: 50 case GL_INT_SAMPLER_2D: 51 case GL_UNSIGNED_INT_SAMPLER_2D: 52 case GL_INT_SAMPLER_CUBE: 53 case GL_UNSIGNED_INT_SAMPLER_CUBE: 54 case GL_INT_SAMPLER_3D: 55 case GL_UNSIGNED_INT_SAMPLER_3D: 56 case GL_INT_SAMPLER_2D_ARRAY: 57 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: 58 return 1; 59 case GL_BOOL_VEC2: 60 case GL_FLOAT_VEC2: 61 case GL_INT_VEC2: 62 case GL_UNSIGNED_INT_VEC2: 63 return 2; 64 case GL_INT_VEC3: 65 case GL_UNSIGNED_INT_VEC3: 66 case GL_FLOAT_VEC3: 67 case GL_BOOL_VEC3: 68 return 3; 69 case GL_BOOL_VEC4: 70 case GL_FLOAT_VEC4: 71 case GL_INT_VEC4: 72 case GL_UNSIGNED_INT_VEC4: 73 case GL_FLOAT_MAT2: 74 return 4; 75 case GL_FLOAT_MAT2x3: 76 case GL_FLOAT_MAT3x2: 77 return 6; 78 case GL_FLOAT_MAT2x4: 79 case GL_FLOAT_MAT4x2: 80 return 8; 81 case GL_FLOAT_MAT3: 82 return 9; 83 case GL_FLOAT_MAT3x4: 84 case GL_FLOAT_MAT4x3: 85 return 12; 86 case GL_FLOAT_MAT4: 87 return 16; 88 default: 89 UNREACHABLE(type); 90 } 91 92 return 0; 93 } 94 UniformComponentType(GLenum type)95 GLenum UniformComponentType(GLenum type) 96 { 97 switch(type) 98 { 99 case GL_BOOL: 100 case GL_BOOL_VEC2: 101 case GL_BOOL_VEC3: 102 case GL_BOOL_VEC4: 103 return GL_BOOL; 104 case GL_FLOAT: 105 case GL_FLOAT_VEC2: 106 case GL_FLOAT_VEC3: 107 case GL_FLOAT_VEC4: 108 case GL_FLOAT_MAT2: 109 case GL_FLOAT_MAT2x3: 110 case GL_FLOAT_MAT2x4: 111 case GL_FLOAT_MAT3: 112 case GL_FLOAT_MAT3x2: 113 case GL_FLOAT_MAT3x4: 114 case GL_FLOAT_MAT4: 115 case GL_FLOAT_MAT4x2: 116 case GL_FLOAT_MAT4x3: 117 return GL_FLOAT; 118 case GL_INT: 119 case GL_SAMPLER_2D: 120 case GL_SAMPLER_CUBE: 121 case GL_SAMPLER_2D_RECT_ARB: 122 case GL_SAMPLER_EXTERNAL_OES: 123 case GL_SAMPLER_3D_OES: 124 case GL_SAMPLER_2D_ARRAY: 125 case GL_SAMPLER_2D_SHADOW: 126 case GL_SAMPLER_CUBE_SHADOW: 127 case GL_SAMPLER_2D_ARRAY_SHADOW: 128 case GL_INT_SAMPLER_2D: 129 case GL_UNSIGNED_INT_SAMPLER_2D: 130 case GL_INT_SAMPLER_CUBE: 131 case GL_UNSIGNED_INT_SAMPLER_CUBE: 132 case GL_INT_SAMPLER_3D: 133 case GL_UNSIGNED_INT_SAMPLER_3D: 134 case GL_INT_SAMPLER_2D_ARRAY: 135 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: 136 case GL_INT_VEC2: 137 case GL_INT_VEC3: 138 case GL_INT_VEC4: 139 return GL_INT; 140 case GL_UNSIGNED_INT: 141 case GL_UNSIGNED_INT_VEC2: 142 case GL_UNSIGNED_INT_VEC3: 143 case GL_UNSIGNED_INT_VEC4: 144 return GL_UNSIGNED_INT; 145 default: 146 UNREACHABLE(type); 147 } 148 149 return GL_NONE; 150 } 151 UniformTypeSize(GLenum type)152 size_t UniformTypeSize(GLenum type) 153 { 154 switch(type) 155 { 156 case GL_BOOL: return sizeof(GLboolean); 157 case GL_FLOAT: return sizeof(GLfloat); 158 case GL_INT: return sizeof(GLint); 159 case GL_UNSIGNED_INT: return sizeof(GLuint); 160 } 161 162 return UniformTypeSize(UniformComponentType(type)) * UniformComponentCount(type); 163 } 164 IsSamplerUniform(GLenum type)165 bool IsSamplerUniform(GLenum type) 166 { 167 switch(type) 168 { 169 case GL_SAMPLER_2D: 170 case GL_SAMPLER_CUBE: 171 case GL_SAMPLER_2D_RECT_ARB: 172 case GL_SAMPLER_EXTERNAL_OES: 173 case GL_SAMPLER_3D_OES: 174 case GL_SAMPLER_2D_ARRAY: 175 case GL_SAMPLER_2D_SHADOW: 176 case GL_SAMPLER_CUBE_SHADOW: 177 case GL_SAMPLER_2D_ARRAY_SHADOW: 178 case GL_INT_SAMPLER_2D: 179 case GL_UNSIGNED_INT_SAMPLER_2D: 180 case GL_INT_SAMPLER_CUBE: 181 case GL_UNSIGNED_INT_SAMPLER_CUBE: 182 case GL_INT_SAMPLER_3D: 183 case GL_UNSIGNED_INT_SAMPLER_3D: 184 case GL_INT_SAMPLER_2D_ARRAY: 185 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: 186 return true; 187 default: 188 return false; 189 } 190 } 191 VariableRowCount(GLenum type)192 int VariableRowCount(GLenum type) 193 { 194 switch(type) 195 { 196 case GL_NONE: 197 return 0; 198 case GL_BOOL: 199 case GL_FLOAT: 200 case GL_INT: 201 case GL_UNSIGNED_INT: 202 case GL_BOOL_VEC2: 203 case GL_FLOAT_VEC2: 204 case GL_INT_VEC2: 205 case GL_UNSIGNED_INT_VEC2: 206 case GL_INT_VEC3: 207 case GL_UNSIGNED_INT_VEC3: 208 case GL_FLOAT_VEC3: 209 case GL_BOOL_VEC3: 210 case GL_BOOL_VEC4: 211 case GL_FLOAT_VEC4: 212 case GL_INT_VEC4: 213 case GL_UNSIGNED_INT_VEC4: 214 case GL_SAMPLER_2D: 215 case GL_SAMPLER_CUBE: 216 case GL_SAMPLER_2D_RECT_ARB: 217 case GL_SAMPLER_EXTERNAL_OES: 218 case GL_SAMPLER_3D_OES: 219 case GL_SAMPLER_2D_ARRAY: 220 case GL_SAMPLER_2D_SHADOW: 221 case GL_SAMPLER_CUBE_SHADOW: 222 case GL_SAMPLER_2D_ARRAY_SHADOW: 223 case GL_INT_SAMPLER_2D: 224 case GL_UNSIGNED_INT_SAMPLER_2D: 225 case GL_INT_SAMPLER_CUBE: 226 case GL_UNSIGNED_INT_SAMPLER_CUBE: 227 case GL_INT_SAMPLER_3D: 228 case GL_UNSIGNED_INT_SAMPLER_3D: 229 case GL_INT_SAMPLER_2D_ARRAY: 230 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: 231 return 1; 232 case GL_FLOAT_MAT2: 233 case GL_FLOAT_MAT3x2: 234 case GL_FLOAT_MAT4x2: 235 return 2; 236 case GL_FLOAT_MAT3: 237 case GL_FLOAT_MAT2x3: 238 case GL_FLOAT_MAT4x3: 239 return 3; 240 case GL_FLOAT_MAT4: 241 case GL_FLOAT_MAT2x4: 242 case GL_FLOAT_MAT3x4: 243 return 4; 244 default: 245 UNREACHABLE(type); 246 } 247 248 return 0; 249 } 250 VariableColumnCount(GLenum type)251 int VariableColumnCount(GLenum type) 252 { 253 switch(type) 254 { 255 case GL_NONE: 256 return 0; 257 case GL_BOOL: 258 case GL_FLOAT: 259 case GL_INT: 260 case GL_UNSIGNED_INT: 261 return 1; 262 case GL_BOOL_VEC2: 263 case GL_FLOAT_VEC2: 264 case GL_INT_VEC2: 265 case GL_UNSIGNED_INT_VEC2: 266 case GL_FLOAT_MAT2: 267 case GL_FLOAT_MAT2x3: 268 case GL_FLOAT_MAT2x4: 269 return 2; 270 case GL_INT_VEC3: 271 case GL_UNSIGNED_INT_VEC3: 272 case GL_FLOAT_VEC3: 273 case GL_BOOL_VEC3: 274 case GL_FLOAT_MAT3: 275 case GL_FLOAT_MAT3x2: 276 case GL_FLOAT_MAT3x4: 277 return 3; 278 case GL_BOOL_VEC4: 279 case GL_FLOAT_VEC4: 280 case GL_INT_VEC4: 281 case GL_UNSIGNED_INT_VEC4: 282 case GL_FLOAT_MAT4: 283 case GL_FLOAT_MAT4x2: 284 case GL_FLOAT_MAT4x3: 285 return 4; 286 default: 287 UNREACHABLE(type); 288 } 289 290 return 0; 291 } 292 VariableRegisterCount(GLenum type)293 int VariableRegisterCount(GLenum type) 294 { 295 // Number of registers used is the number of columns for matrices or 1 for scalars and vectors 296 return (VariableRowCount(type) > 1) ? VariableColumnCount(type) : 1; 297 } 298 VariableRegisterSize(GLenum type)299 int VariableRegisterSize(GLenum type) 300 { 301 // Number of components per register is the number of rows for matrices or columns for scalars and vectors 302 int nbRows = VariableRowCount(type); 303 return (nbRows > 1) ? nbRows : VariableColumnCount(type); 304 } 305 AllocateFirstFreeBits(unsigned int * bits,unsigned int allocationSize,unsigned int bitsSize)306 int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize) 307 { 308 ASSERT(allocationSize <= bitsSize); 309 310 unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize); 311 312 for(unsigned int i = 0; i < bitsSize - allocationSize + 1; i++) 313 { 314 if((*bits & mask) == 0) 315 { 316 *bits |= mask; 317 return i; 318 } 319 320 mask <<= 1; 321 } 322 323 return -1; 324 } 325 IsCompressed(GLint internalformat)326 bool IsCompressed(GLint internalformat) 327 { 328 switch(internalformat) 329 { 330 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 331 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 332 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: 333 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: 334 case GL_ETC1_RGB8_OES: 335 case GL_COMPRESSED_R11_EAC: 336 case GL_COMPRESSED_SIGNED_R11_EAC: 337 case GL_COMPRESSED_RG11_EAC: 338 case GL_COMPRESSED_SIGNED_RG11_EAC: 339 case GL_COMPRESSED_RGB8_ETC2: 340 case GL_COMPRESSED_SRGB8_ETC2: 341 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: 342 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: 343 case GL_COMPRESSED_RGBA8_ETC2_EAC: 344 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: 345 return true; 346 default: 347 return false; 348 } 349 } 350 IsSizedInternalFormat(GLint internalformat)351 bool IsSizedInternalFormat(GLint internalformat) 352 { 353 switch(internalformat) 354 { 355 case GL_ALPHA8_EXT: 356 case GL_LUMINANCE8_EXT: 357 case GL_LUMINANCE8_ALPHA8_EXT: 358 case GL_ALPHA32F_EXT: 359 case GL_LUMINANCE32F_EXT: 360 case GL_LUMINANCE_ALPHA32F_EXT: 361 case GL_ALPHA16F_EXT: 362 case GL_LUMINANCE16F_EXT: 363 case GL_LUMINANCE_ALPHA16F_EXT: 364 case GL_R8: 365 case GL_R8UI: 366 case GL_R8I: 367 case GL_R16UI: 368 case GL_R16I: 369 case GL_R32UI: 370 case GL_R32I: 371 case GL_RG8: 372 case GL_RG8UI: 373 case GL_RG8I: 374 case GL_RG16UI: 375 case GL_RG16I: 376 case GL_RG32UI: 377 case GL_RG32I: 378 case GL_SRGB8_ALPHA8: 379 case GL_RGB8UI: 380 case GL_RGB8I: 381 case GL_RGB16UI: 382 case GL_RGB16I: 383 case GL_RGB32UI: 384 case GL_RGB32I: 385 case GL_RG8_SNORM: 386 case GL_R8_SNORM: 387 case GL_RGB10_A2: 388 case GL_RGBA8UI: 389 case GL_RGBA8I: 390 case GL_RGB10_A2UI: 391 case GL_RGBA16UI: 392 case GL_RGBA16I: 393 case GL_RGBA32I: 394 case GL_RGBA32UI: 395 case GL_RGBA4: 396 case GL_RGB5_A1: 397 case GL_RGB565: 398 case GL_RGB8: 399 case GL_RGBA8: 400 case GL_BGRA8_EXT: // GL_APPLE_texture_format_BGRA8888 401 case GL_R16F: 402 case GL_RG16F: 403 case GL_R11F_G11F_B10F: 404 case GL_RGB16F: 405 case GL_RGBA16F: 406 case GL_R32F: 407 case GL_RG32F: 408 case GL_RGB32F: 409 case GL_RGBA32F: 410 case GL_DEPTH_COMPONENT24: 411 case GL_DEPTH_COMPONENT32_OES: 412 case GL_DEPTH_COMPONENT32F: 413 case GL_DEPTH32F_STENCIL8: 414 case GL_DEPTH_COMPONENT16: 415 case GL_STENCIL_INDEX8: 416 case GL_DEPTH24_STENCIL8_OES: 417 case GL_RGBA8_SNORM: 418 case GL_SRGB8: 419 case GL_RGB8_SNORM: 420 case GL_RGB9_E5: 421 return true; 422 default: 423 return false; 424 } 425 } 426 ValidateSubImageParams(bool compressed,bool copy,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,Texture * texture)427 GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset, 428 GLsizei width, GLsizei height, GLenum format, GLenum type, Texture *texture) 429 { 430 if(!texture) 431 { 432 return GL_INVALID_OPERATION; 433 } 434 435 GLenum sizedInternalFormat = texture->getFormat(target, level); 436 437 if(compressed) 438 { 439 if(format != sizedInternalFormat) 440 { 441 return GL_INVALID_OPERATION; 442 } 443 } 444 else if(!copy) // CopyTexSubImage doesn't have format/type parameters. 445 { 446 GLenum validationError = ValidateTextureFormatType(format, type, sizedInternalFormat, target); 447 if(validationError != GL_NO_ERROR) 448 { 449 return validationError; 450 } 451 } 452 453 if(compressed) 454 { 455 if((width % 4 != 0 && width != texture->getWidth(target, 0)) || 456 (height % 4 != 0 && height != texture->getHeight(target, 0))) 457 { 458 return GL_INVALID_OPERATION; 459 } 460 } 461 462 if(xoffset + width > texture->getWidth(target, level) || 463 yoffset + height > texture->getHeight(target, level)) 464 { 465 return GL_INVALID_VALUE; 466 } 467 468 return GL_NO_ERROR; 469 } 470 ValidateSubImageParams(bool compressed,bool copy,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,Texture * texture)471 GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, 472 GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, Texture *texture) 473 { 474 if(!texture) 475 { 476 return GL_INVALID_OPERATION; 477 } 478 479 if(compressed != texture->isCompressed(target, level)) 480 { 481 return GL_INVALID_OPERATION; 482 } 483 484 if(!copy) 485 { 486 GLenum sizedInternalFormat = texture->getFormat(target, level); 487 488 GLenum validationError = ValidateTextureFormatType(format, type, sizedInternalFormat, target); 489 if(validationError != GL_NO_ERROR) 490 { 491 return validationError; 492 } 493 } 494 495 if(compressed) 496 { 497 if((width % 4 != 0 && width != texture->getWidth(target, 0)) || 498 (height % 4 != 0 && height != texture->getHeight(target, 0)) || 499 (depth % 4 != 0 && depth != texture->getDepth(target, 0))) 500 { 501 return GL_INVALID_OPERATION; 502 } 503 } 504 505 if(xoffset + width > texture->getWidth(target, level) || 506 yoffset + height > texture->getHeight(target, level) || 507 zoffset + depth > texture->getDepth(target, level)) 508 { 509 return GL_INVALID_VALUE; 510 } 511 512 return GL_NO_ERROR; 513 } 514 ValidateCopyFormats(GLenum textureFormat,GLenum colorbufferFormat)515 bool ValidateCopyFormats(GLenum textureFormat, GLenum colorbufferFormat) 516 { 517 ASSERT(!gl::IsUnsizedInternalFormat(textureFormat)); 518 ASSERT(!gl::IsUnsizedInternalFormat(colorbufferFormat)); 519 520 if(GetColorComponentType(textureFormat) == GL_NONE) 521 { 522 return error(GL_INVALID_ENUM, false); 523 } 524 525 if(GetColorComponentType(colorbufferFormat) != GetColorComponentType(textureFormat)) 526 { 527 return error(GL_INVALID_OPERATION, false); 528 } 529 530 if(GetColorEncoding(colorbufferFormat) != GetColorEncoding(textureFormat)) 531 { 532 return error(GL_INVALID_OPERATION, false); 533 } 534 535 GLenum baseTexureFormat = gl::GetBaseInternalFormat(textureFormat); 536 GLenum baseColorbufferFormat = gl::GetBaseInternalFormat(colorbufferFormat); 537 538 // [OpenGL ES 2.0.24] table 3.9 539 // [OpenGL ES 3.0.5] table 3.16 540 switch(baseTexureFormat) 541 { 542 case GL_ALPHA: 543 if(baseColorbufferFormat != GL_ALPHA && 544 baseColorbufferFormat != GL_RGBA && 545 baseColorbufferFormat != GL_BGRA_EXT) // GL_EXT_texture_format_BGRA8888 / GL_APPLE_texture_format_BGRA8888 546 { 547 return error(GL_INVALID_OPERATION, false); 548 } 549 break; 550 case GL_LUMINANCE_ALPHA: 551 case GL_RGBA: 552 if(baseColorbufferFormat != GL_RGBA && 553 baseColorbufferFormat != GL_BGRA_EXT) // GL_EXT_texture_format_BGRA8888 / GL_APPLE_texture_format_BGRA8888 554 { 555 return error(GL_INVALID_OPERATION, false); 556 } 557 break; 558 case GL_LUMINANCE: 559 case GL_RED: 560 if(baseColorbufferFormat != GL_RED && 561 baseColorbufferFormat != GL_RG && 562 baseColorbufferFormat != GL_RGB && 563 baseColorbufferFormat != GL_RGBA && 564 baseColorbufferFormat != GL_BGRA_EXT) // GL_EXT_texture_format_BGRA8888 / GL_APPLE_texture_format_BGRA8888 565 { 566 return error(GL_INVALID_OPERATION, false); 567 } 568 break; 569 case GL_RG: 570 if(baseColorbufferFormat != GL_RG && 571 baseColorbufferFormat != GL_RGB && 572 baseColorbufferFormat != GL_RGBA && 573 baseColorbufferFormat != GL_BGRA_EXT) // GL_EXT_texture_format_BGRA8888 / GL_APPLE_texture_format_BGRA8888 574 { 575 return error(GL_INVALID_OPERATION, false); 576 } 577 break; 578 case GL_RGB: 579 if(baseColorbufferFormat != GL_RGB && 580 baseColorbufferFormat != GL_RGBA && 581 baseColorbufferFormat != GL_BGRA_EXT) // GL_EXT_texture_format_BGRA8888 / GL_APPLE_texture_format_BGRA8888 582 { 583 return error(GL_INVALID_OPERATION, false); 584 } 585 break; 586 case GL_DEPTH_COMPONENT: 587 case GL_DEPTH_STENCIL_OES: 588 return error(GL_INVALID_OPERATION, false); 589 case GL_BGRA_EXT: // GL_EXT_texture_format_BGRA8888 nor GL_APPLE_texture_format_BGRA8888 mention the format to be accepted by glCopyTexImage2D. 590 default: 591 return error(GL_INVALID_ENUM, false); 592 } 593 594 return true; 595 } 596 ValidateReadPixelsFormatType(const Framebuffer * framebuffer,GLenum format,GLenum type)597 bool ValidateReadPixelsFormatType(const Framebuffer *framebuffer, GLenum format, GLenum type) 598 { 599 // GL_NV_read_depth 600 if(format == GL_DEPTH_COMPONENT) 601 { 602 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); 603 604 if(!depthbuffer) 605 { 606 return error(GL_INVALID_OPERATION, false); 607 } 608 609 GLint internalformat = depthbuffer->getFormat(); 610 611 switch(type) 612 { 613 case GL_UNSIGNED_SHORT: 614 case GL_UNSIGNED_INT_24_8_OES: 615 switch(internalformat) 616 { 617 case GL_DEPTH_COMPONENT16: 618 case GL_DEPTH_COMPONENT24: 619 case GL_DEPTH_COMPONENT32_OES: 620 case GL_DEPTH24_STENCIL8: 621 break; 622 case GL_DEPTH_COMPONENT32F: 623 case GL_DEPTH32F_STENCIL8: 624 return error(GL_INVALID_OPERATION, false); 625 default: 626 UNREACHABLE(internalformat); 627 return error(GL_INVALID_OPERATION, false); 628 } 629 break; 630 case GL_FLOAT: 631 switch(internalformat) 632 { 633 case GL_DEPTH_COMPONENT32F: 634 case GL_DEPTH32F_STENCIL8: 635 break; 636 case GL_DEPTH_COMPONENT16: 637 case GL_DEPTH_COMPONENT24: 638 case GL_DEPTH_COMPONENT32_OES: 639 case GL_DEPTH24_STENCIL8: 640 return error(GL_INVALID_OPERATION, false); 641 default: 642 UNREACHABLE(internalformat); 643 return error(GL_INVALID_OPERATION, false); 644 } 645 break; 646 default: 647 return error(GL_INVALID_ENUM, false); 648 } 649 650 return true; 651 } 652 653 // GL_NV_read_stencil 654 if(format == GL_STENCIL_INDEX_OES) 655 { 656 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer(); 657 658 if(!stencilbuffer) 659 { 660 return error(GL_INVALID_OPERATION, false); 661 } 662 663 switch(type) 664 { 665 case GL_UNSIGNED_BYTE: 666 break; 667 default: 668 return error(GL_INVALID_ENUM, false); 669 } 670 671 return true; 672 } 673 674 Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer(); 675 676 if(!colorbuffer) 677 { 678 return error(GL_INVALID_OPERATION, false); 679 } 680 681 GLint internalformat = colorbuffer->getFormat(); 682 683 if(IsNormalizedInteger(internalformat)) 684 { 685 // Combination always supported by normalized fixed-point rendering surfaces. 686 if(format == GL_RGBA && type == GL_UNSIGNED_BYTE) 687 { 688 return true; 689 } 690 691 // GL_EXT_read_format_bgra combinations. 692 if(format == GL_BGRA_EXT) 693 { 694 if(type == GL_UNSIGNED_BYTE || 695 type == GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT || 696 type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT) 697 { 698 return true; 699 } 700 } 701 } 702 else if(IsFloatFormat(internalformat)) 703 { 704 // Combination always supported by floating-point rendering surfaces. 705 // Supported in OpenGL ES 2.0 due to GL_EXT_color_buffer_half_float. 706 if(format == GL_RGBA && type == GL_FLOAT) 707 { 708 return true; 709 } 710 } 711 else if(IsSignedNonNormalizedInteger(internalformat)) 712 { 713 if(format == GL_RGBA_INTEGER && type == GL_INT) 714 { 715 return true; 716 } 717 } 718 else if(IsUnsignedNonNormalizedInteger(internalformat)) 719 { 720 if(format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT) 721 { 722 return true; 723 } 724 } 725 else UNREACHABLE(internalformat); 726 727 // GL_IMPLEMENTATION_COLOR_READ_FORMAT / GL_IMPLEMENTATION_COLOR_READ_TYPE 728 GLenum implementationReadFormat = GL_NONE; 729 GLenum implementationReadType = GL_NONE; 730 switch(format) 731 { 732 default: 733 implementationReadFormat = framebuffer->getImplementationColorReadFormat(); 734 implementationReadType = framebuffer->getImplementationColorReadType(); 735 break; 736 case GL_DEPTH_COMPONENT: 737 implementationReadFormat = framebuffer->getDepthReadFormat(); 738 implementationReadType = framebuffer->getDepthReadType(); 739 break; 740 } 741 742 GLenum coreType = (type == GL_HALF_FLOAT_OES) ? GL_HALF_FLOAT : type; 743 744 if(format == implementationReadFormat && coreType == implementationReadType) 745 { 746 return true; 747 } 748 749 // Additional third combination accepted by OpenGL ES 3.0. 750 if(internalformat == GL_RGB10_A2) 751 { 752 if(format == GL_RGBA && type == GL_UNSIGNED_INT_2_10_10_10_REV) 753 { 754 return true; 755 } 756 } 757 758 return error(GL_INVALID_OPERATION, false); 759 } 760 IsDepthTexture(GLint format)761 bool IsDepthTexture(GLint format) 762 { 763 return format == GL_DEPTH_COMPONENT16 || 764 format == GL_DEPTH_COMPONENT24 || 765 format == GL_DEPTH_COMPONENT32_OES || 766 format == GL_DEPTH_COMPONENT32F || 767 format == GL_DEPTH24_STENCIL8 || 768 format == GL_DEPTH32F_STENCIL8; 769 } 770 IsStencilTexture(GLint format)771 bool IsStencilTexture(GLint format) 772 { 773 return format == GL_DEPTH24_STENCIL8 || 774 format == GL_DEPTH32F_STENCIL8 || 775 format == GL_STENCIL_INDEX8; 776 } 777 IsCubemapTextureTarget(GLenum target)778 bool IsCubemapTextureTarget(GLenum target) 779 { 780 return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z); 781 } 782 CubeFaceIndex(GLenum cubeFace)783 int CubeFaceIndex(GLenum cubeFace) 784 { 785 switch(cubeFace) 786 { 787 case GL_TEXTURE_CUBE_MAP: 788 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: return 0; 789 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: return 1; 790 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: return 2; 791 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: return 3; 792 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: return 4; 793 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: return 5; 794 default: UNREACHABLE(cubeFace); return 0; 795 } 796 } 797 IsTexImageTarget(GLenum target)798 bool IsTexImageTarget(GLenum target) 799 { 800 return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target) || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_RECTANGLE_ARB; 801 } 802 IsTextureTarget(GLenum target)803 bool IsTextureTarget(GLenum target) 804 { 805 return IsTexImageTarget(target) || target == GL_TEXTURE_3D; 806 } 807 ValidateTextureFormatType(GLenum format,GLenum type,GLint internalformat,GLenum target)808 GLenum ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLenum target) 809 { 810 switch(type) 811 { 812 case GL_UNSIGNED_BYTE: 813 case GL_UNSIGNED_SHORT_4_4_4_4: 814 case GL_UNSIGNED_SHORT_5_5_5_1: 815 case GL_UNSIGNED_SHORT_5_6_5: 816 case GL_FLOAT: // GL_OES_texture_float 817 case GL_HALF_FLOAT_OES: // GL_OES_texture_half_float 818 case GL_HALF_FLOAT: 819 case GL_UNSIGNED_INT_24_8: // GL_OES_packed_depth_stencil (GL_UNSIGNED_INT_24_8_EXT) 820 case GL_UNSIGNED_SHORT: // GL_OES_depth_texture 821 case GL_UNSIGNED_INT: // GL_OES_depth_texture 822 break; 823 case GL_BYTE: 824 case GL_SHORT: 825 case GL_INT: 826 case GL_UNSIGNED_INT_2_10_10_10_REV: 827 case GL_UNSIGNED_INT_10F_11F_11F_REV: 828 case GL_UNSIGNED_INT_5_9_9_9_REV: 829 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 830 break; 831 default: 832 return GL_INVALID_ENUM; 833 } 834 835 switch(format) 836 { 837 case GL_ALPHA: 838 case GL_RGB: 839 case GL_RGBA: 840 case GL_LUMINANCE: 841 case GL_LUMINANCE_ALPHA: 842 case GL_BGRA_EXT: // GL_EXT_texture_format_BGRA8888 843 case GL_RED_EXT: // GL_EXT_texture_rg 844 case GL_RG_EXT: // GL_EXT_texture_rg 845 break; 846 case GL_DEPTH_STENCIL: // GL_OES_packed_depth_stencil (GL_DEPTH_STENCIL_OES) 847 case GL_DEPTH_COMPONENT: // GL_OES_depth_texture 848 switch(target) 849 { 850 case GL_TEXTURE_2D: 851 case GL_TEXTURE_2D_ARRAY: 852 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: // GL_OES_depth_texture_cube_map 853 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 854 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 855 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 856 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 857 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 858 break; 859 default: 860 return GL_INVALID_OPERATION; 861 } 862 break; 863 case GL_RED_INTEGER: 864 case GL_RG_INTEGER: 865 case GL_RGB_INTEGER: 866 case GL_RGBA_INTEGER: 867 break; 868 default: 869 return GL_INVALID_ENUM; 870 } 871 872 if((GLenum)internalformat != format) 873 { 874 if(gl::IsUnsizedInternalFormat(internalformat)) 875 { 876 return GL_INVALID_OPERATION; 877 } 878 879 if(!IsSizedInternalFormat(internalformat)) 880 { 881 return GL_INVALID_VALUE; 882 } 883 } 884 885 if((GLenum)internalformat == format) 886 { 887 // Validate format, type, and unsized internalformat combinations [OpenGL ES 3.0 Table 3.3] 888 switch(format) 889 { 890 case GL_RGBA: 891 switch(type) 892 { 893 case GL_UNSIGNED_BYTE: 894 case GL_UNSIGNED_SHORT_4_4_4_4: 895 case GL_UNSIGNED_SHORT_5_5_5_1: 896 case GL_FLOAT: // GL_OES_texture_float 897 case GL_HALF_FLOAT_OES: // GL_OES_texture_half_float 898 break; 899 default: 900 return GL_INVALID_OPERATION; 901 } 902 break; 903 case GL_RGB: 904 switch(type) 905 { 906 case GL_UNSIGNED_BYTE: 907 case GL_UNSIGNED_SHORT_5_6_5: 908 case GL_FLOAT: // GL_OES_texture_float 909 case GL_HALF_FLOAT_OES: // GL_OES_texture_half_float 910 break; 911 default: 912 return GL_INVALID_OPERATION; 913 } 914 break; 915 case GL_LUMINANCE_ALPHA: 916 case GL_LUMINANCE: 917 case GL_ALPHA: 918 switch(type) 919 { 920 case GL_UNSIGNED_BYTE: 921 case GL_FLOAT: // GL_OES_texture_float 922 case GL_HALF_FLOAT_OES: // GL_OES_texture_half_float 923 break; 924 default: 925 return GL_INVALID_OPERATION; 926 } 927 break; 928 case GL_DEPTH_COMPONENT: 929 switch(type) 930 { 931 case GL_UNSIGNED_SHORT: // GL_OES_depth_texture 932 case GL_UNSIGNED_INT: // GL_OES_depth_texture 933 break; 934 default: 935 return GL_INVALID_OPERATION; 936 } 937 break; 938 case GL_DEPTH_STENCIL_OES: 939 switch(type) 940 { 941 case GL_UNSIGNED_INT_24_8_OES: // GL_OES_packed_depth_stencil 942 break; 943 default: 944 return GL_INVALID_OPERATION; 945 } 946 break; 947 case GL_RED_EXT: 948 case GL_RG_EXT: 949 switch(type) 950 { 951 case GL_UNSIGNED_BYTE: // GL_EXT_texture_rg 952 case GL_FLOAT: // GL_EXT_texture_rg + GL_OES_texture_float 953 case GL_HALF_FLOAT_OES: // GL_EXT_texture_rg + GL_OES_texture_half_float 954 break; 955 default: 956 return GL_INVALID_OPERATION; 957 } 958 break; 959 case GL_BGRA_EXT: 960 if(type != GL_UNSIGNED_BYTE) // GL_APPLE_texture_format_BGRA8888 / GL_EXT_texture_format_BGRA8888 961 { 962 return GL_INVALID_OPERATION; 963 } 964 break; 965 default: 966 UNREACHABLE(format); 967 return GL_INVALID_ENUM; 968 } 969 970 return GL_NO_ERROR; 971 } 972 973 // Validate format, type, and sized internalformat combinations [OpenGL ES 3.0 Table 3.2] 974 bool validSizedInternalformat = false; 975 #define VALIDATE_INTERNALFORMAT(...) { GLint validInternalformats[] = {__VA_ARGS__}; for(GLint v : validInternalformats) {if(internalformat == v) validSizedInternalformat = true;} } break; 976 977 switch(format) 978 { 979 case GL_RGBA: 980 switch(type) 981 { 982 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8, GL_RGB5_A1, GL_RGBA4, GL_SRGB8_ALPHA8) 983 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8_SNORM) 984 case GL_UNSIGNED_SHORT_4_4_4_4: VALIDATE_INTERNALFORMAT(GL_RGBA4) 985 case GL_UNSIGNED_SHORT_5_5_5_1: VALIDATE_INTERNALFORMAT(GL_RGB5_A1) 986 case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2, GL_RGB5_A1) 987 case GL_HALF_FLOAT_OES: 988 case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGBA16F) 989 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGBA32F, GL_RGBA16F) 990 default: return GL_INVALID_OPERATION; 991 } 992 break; 993 case GL_RGBA_INTEGER: 994 switch(type) 995 { 996 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8UI) 997 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8I) 998 case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RGBA16UI) 999 case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RGBA16I) 1000 case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RGBA32UI) 1001 case GL_INT: VALIDATE_INTERNALFORMAT(GL_RGBA32I) 1002 case GL_UNSIGNED_INT_2_10_10_10_REV: VALIDATE_INTERNALFORMAT(GL_RGB10_A2UI) 1003 default: return GL_INVALID_OPERATION; 1004 } 1005 break; 1006 case GL_RGB: 1007 switch(type) 1008 { 1009 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8, GL_RGB565, GL_SRGB8) 1010 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8_SNORM) 1011 case GL_UNSIGNED_SHORT_5_6_5: VALIDATE_INTERNALFORMAT(GL_RGB565) 1012 case GL_UNSIGNED_INT_10F_11F_11F_REV: VALIDATE_INTERNALFORMAT(GL_R11F_G11F_B10F) 1013 case GL_UNSIGNED_INT_5_9_9_9_REV: VALIDATE_INTERNALFORMAT(GL_RGB9_E5) 1014 case GL_HALF_FLOAT_OES: 1015 case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5) 1016 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RGB32F, GL_RGB16F, GL_R11F_G11F_B10F, GL_RGB9_E5) 1017 default: return GL_INVALID_OPERATION; 1018 } 1019 break; 1020 case GL_RGB_INTEGER: 1021 switch(type) 1022 { 1023 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8UI) 1024 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8I) 1025 case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RGB16UI) 1026 case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RGB16I) 1027 case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RGB32UI) 1028 case GL_INT: VALIDATE_INTERNALFORMAT(GL_RGB32I) 1029 default: return GL_INVALID_OPERATION; 1030 } 1031 break; 1032 case GL_RG: 1033 switch(type) 1034 { 1035 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8) 1036 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8_SNORM) 1037 case GL_HALF_FLOAT_OES: 1038 case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_RG16F) 1039 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_RG32F, GL_RG16F) 1040 default: return GL_INVALID_OPERATION; 1041 } 1042 break; 1043 case GL_RG_INTEGER: 1044 switch(type) 1045 { 1046 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8UI) 1047 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_RG8I) 1048 case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_RG16UI) 1049 case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_RG16I) 1050 case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_RG32UI) 1051 case GL_INT: VALIDATE_INTERNALFORMAT(GL_RG32I) 1052 default: return GL_INVALID_OPERATION; 1053 } 1054 break; 1055 case GL_RED: 1056 switch(type) 1057 { 1058 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_R8) 1059 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_R8_SNORM) 1060 case GL_HALF_FLOAT_OES: 1061 case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_R16F) 1062 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_R32F, GL_R16F) 1063 default: return GL_INVALID_OPERATION; 1064 } 1065 break; 1066 case GL_RED_INTEGER: 1067 switch(type) 1068 { 1069 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_R8UI) 1070 case GL_BYTE: VALIDATE_INTERNALFORMAT(GL_R8I) 1071 case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_R16UI) 1072 case GL_SHORT: VALIDATE_INTERNALFORMAT(GL_R16I) 1073 case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_R32UI) 1074 case GL_INT: VALIDATE_INTERNALFORMAT(GL_R32I) 1075 default: return GL_INVALID_OPERATION; 1076 } 1077 break; 1078 case GL_DEPTH_COMPONENT: 1079 switch(type) 1080 { 1081 case GL_UNSIGNED_SHORT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT16) 1082 case GL_UNSIGNED_INT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16) 1083 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_DEPTH_COMPONENT32F) 1084 default: return GL_INVALID_OPERATION; 1085 } 1086 break; 1087 case GL_DEPTH_STENCIL: 1088 switch(type) 1089 { 1090 case GL_UNSIGNED_INT_24_8: VALIDATE_INTERNALFORMAT(GL_DEPTH24_STENCIL8) 1091 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: VALIDATE_INTERNALFORMAT(GL_DEPTH32F_STENCIL8) 1092 default: return GL_INVALID_OPERATION; 1093 } 1094 break; 1095 case GL_LUMINANCE_ALPHA: 1096 switch(type) 1097 { 1098 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_LUMINANCE8_ALPHA8_EXT) 1099 case GL_HALF_FLOAT_OES: 1100 case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_LUMINANCE_ALPHA16F_EXT) 1101 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA16F_EXT) 1102 default: 1103 return GL_INVALID_OPERATION; 1104 } 1105 break; 1106 case GL_LUMINANCE: 1107 switch(type) 1108 { 1109 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_LUMINANCE8_EXT) 1110 case GL_HALF_FLOAT_OES: 1111 case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_LUMINANCE16F_EXT) 1112 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_LUMINANCE32F_EXT, GL_LUMINANCE16F_EXT) 1113 default: 1114 return GL_INVALID_OPERATION; 1115 } 1116 break; 1117 case GL_ALPHA: 1118 switch(type) 1119 { 1120 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_ALPHA8_EXT) 1121 case GL_HALF_FLOAT_OES: 1122 case GL_HALF_FLOAT: VALIDATE_INTERNALFORMAT(GL_ALPHA16F_EXT) 1123 case GL_FLOAT: VALIDATE_INTERNALFORMAT(GL_ALPHA32F_EXT, GL_ALPHA16F_EXT) 1124 default: 1125 return GL_INVALID_OPERATION; 1126 } 1127 break; 1128 case GL_BGRA_EXT: // GL_APPLE_texture_format_BGRA8888 1129 switch(type) 1130 { 1131 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_BGRA8_EXT) 1132 default: return GL_INVALID_OPERATION; 1133 } 1134 break; 1135 default: 1136 UNREACHABLE(format); 1137 return GL_INVALID_ENUM; 1138 } 1139 1140 #undef VALIDATE_INTERNALFORMAT 1141 1142 if(!validSizedInternalformat) 1143 { 1144 return GL_INVALID_OPERATION; 1145 } 1146 1147 return GL_NO_ERROR; 1148 } 1149 GetTypeSize(GLenum type)1150 size_t GetTypeSize(GLenum type) 1151 { 1152 switch(type) 1153 { 1154 case GL_BYTE: 1155 case GL_UNSIGNED_BYTE: 1156 return 1; 1157 case GL_UNSIGNED_SHORT_4_4_4_4: 1158 case GL_UNSIGNED_SHORT_5_5_5_1: 1159 case GL_UNSIGNED_SHORT_5_6_5: 1160 case GL_UNSIGNED_SHORT: 1161 case GL_SHORT: 1162 case GL_HALF_FLOAT: 1163 case GL_HALF_FLOAT_OES: 1164 return 2; 1165 case GL_FLOAT: 1166 case GL_UNSIGNED_INT_24_8: 1167 case GL_UNSIGNED_INT: 1168 case GL_INT: 1169 case GL_UNSIGNED_INT_2_10_10_10_REV: 1170 case GL_UNSIGNED_INT_10F_11F_11F_REV: 1171 case GL_UNSIGNED_INT_5_9_9_9_REV: 1172 return 4; 1173 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 1174 return 8; 1175 default: 1176 UNREACHABLE(type); 1177 break; 1178 } 1179 1180 return 1; 1181 } 1182 ConvertReadFormatType(GLenum format,GLenum type)1183 sw::Format ConvertReadFormatType(GLenum format, GLenum type) 1184 { 1185 switch(format) 1186 { 1187 case GL_LUMINANCE: 1188 switch(type) 1189 { 1190 case GL_UNSIGNED_BYTE: return sw::FORMAT_L8; 1191 case GL_HALF_FLOAT: return sw::FORMAT_L16F; 1192 case GL_HALF_FLOAT_OES: return sw::FORMAT_L16F; 1193 case GL_FLOAT: return sw::FORMAT_L32F; 1194 default: UNREACHABLE(type); 1195 } 1196 break; 1197 case GL_LUMINANCE_ALPHA: 1198 switch(type) 1199 { 1200 case GL_UNSIGNED_BYTE: return sw::FORMAT_A8L8; 1201 case GL_HALF_FLOAT: return sw::FORMAT_A16L16F; 1202 case GL_HALF_FLOAT_OES: return sw::FORMAT_A16L16F; 1203 case GL_FLOAT: return sw::FORMAT_A32L32F; 1204 default: UNREACHABLE(type); 1205 } 1206 break; 1207 case GL_RGBA: 1208 switch(type) 1209 { 1210 case GL_UNSIGNED_BYTE: return sw::FORMAT_A8B8G8R8; 1211 case GL_UNSIGNED_SHORT_4_4_4_4: return sw::FORMAT_R4G4B4A4; 1212 case GL_UNSIGNED_SHORT_5_5_5_1: return sw::FORMAT_R5G5B5A1; 1213 case GL_HALF_FLOAT: return sw::FORMAT_A16B16G16R16F; 1214 case GL_HALF_FLOAT_OES: return sw::FORMAT_A16B16G16R16F; 1215 case GL_FLOAT: return sw::FORMAT_A32B32G32R32F; 1216 case GL_UNSIGNED_INT_2_10_10_10_REV_EXT: return sw::FORMAT_A2B10G10R10; 1217 default: UNREACHABLE(type); 1218 } 1219 break; 1220 case GL_BGRA_EXT: 1221 switch(type) 1222 { 1223 case GL_UNSIGNED_BYTE: return sw::FORMAT_A8R8G8B8; 1224 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: return sw::FORMAT_A4R4G4B4; 1225 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: return sw::FORMAT_A1R5G5B5; 1226 default: UNREACHABLE(type); 1227 } 1228 break; 1229 case GL_RGB: 1230 switch(type) 1231 { 1232 case GL_UNSIGNED_BYTE: return sw::FORMAT_B8G8R8; 1233 case GL_UNSIGNED_SHORT_5_6_5: return sw::FORMAT_R5G6B5; 1234 case GL_HALF_FLOAT: return sw::FORMAT_B16G16R16F; 1235 case GL_HALF_FLOAT_OES: return sw::FORMAT_B16G16R16F; 1236 case GL_FLOAT: return sw::FORMAT_B32G32R32F; 1237 default: UNREACHABLE(type); 1238 } 1239 break; 1240 case GL_RG: 1241 switch(type) 1242 { 1243 case GL_UNSIGNED_BYTE: return sw::FORMAT_G8R8; 1244 case GL_HALF_FLOAT: return sw::FORMAT_G16R16F; 1245 case GL_HALF_FLOAT_OES: return sw::FORMAT_G16R16F; 1246 case GL_FLOAT: return sw::FORMAT_G32R32F; 1247 default: UNREACHABLE(type); 1248 } 1249 break; 1250 case GL_RED: 1251 switch(type) 1252 { 1253 case GL_UNSIGNED_BYTE: return sw::FORMAT_R8; 1254 case GL_HALF_FLOAT: return sw::FORMAT_R16F; 1255 case GL_HALF_FLOAT_OES: return sw::FORMAT_R16F; 1256 case GL_FLOAT: return sw::FORMAT_R32F; 1257 default: UNREACHABLE(type); 1258 } 1259 break; 1260 case GL_ALPHA: 1261 switch(type) 1262 { 1263 case GL_UNSIGNED_BYTE: return sw::FORMAT_A8; 1264 case GL_HALF_FLOAT: return sw::FORMAT_A16F; 1265 case GL_HALF_FLOAT_OES: return sw::FORMAT_A16F; 1266 case GL_FLOAT: return sw::FORMAT_A32F; 1267 default: UNREACHABLE(type); 1268 } 1269 break; 1270 case GL_RED_INTEGER: 1271 switch(type) 1272 { 1273 case GL_INT: return sw::FORMAT_R32I; 1274 case GL_UNSIGNED_INT: return sw::FORMAT_R32UI; 1275 default: UNREACHABLE(type); 1276 } 1277 break; 1278 case GL_RG_INTEGER: 1279 switch(type) 1280 { 1281 case GL_INT: return sw::FORMAT_G32R32I; 1282 case GL_UNSIGNED_INT: return sw::FORMAT_G32R32UI; 1283 default: UNREACHABLE(type); 1284 } 1285 break; 1286 case GL_RGB_INTEGER: 1287 switch(type) 1288 { 1289 case GL_INT: return sw::FORMAT_X32B32G32R32I; 1290 case GL_UNSIGNED_INT: return sw::FORMAT_X32B32G32R32UI; 1291 default: UNREACHABLE(type); 1292 } 1293 break; 1294 case GL_RGBA_INTEGER: 1295 switch(type) 1296 { 1297 case GL_INT: return sw::FORMAT_A32B32G32R32I; 1298 case GL_UNSIGNED_INT: return sw::FORMAT_A32B32G32R32UI; 1299 case GL_UNSIGNED_INT_2_10_10_10_REV: return sw::FORMAT_A2B10G10R10UI; 1300 default: UNREACHABLE(type); 1301 } 1302 break; 1303 case GL_DEPTH_COMPONENT: 1304 switch(type) 1305 { 1306 case GL_UNSIGNED_SHORT: return sw::FORMAT_D16; 1307 case GL_UNSIGNED_INT_24_8_OES: return sw::FORMAT_D24X8; 1308 case GL_FLOAT: return sw::FORMAT_D32F_LOCKABLE; 1309 default: UNREACHABLE(type); 1310 } 1311 break; 1312 case GL_STENCIL_INDEX_OES: 1313 switch(type) 1314 { 1315 case GL_UNSIGNED_BYTE: return sw::FORMAT_S8; 1316 default: UNREACHABLE(type); 1317 } 1318 break; 1319 case GL_DEPTH_STENCIL_OES: // Cannot be read as one format. Handled separately. 1320 default: 1321 UNREACHABLE(format); 1322 break; 1323 } 1324 1325 return sw::FORMAT_NULL; 1326 } 1327 IsColorRenderable(GLint internalformat)1328 bool IsColorRenderable(GLint internalformat) 1329 { 1330 if(IsCompressed(internalformat)) 1331 { 1332 return false; 1333 } 1334 1335 switch(internalformat) 1336 { 1337 case GL_RGBA4: 1338 case GL_RGB5_A1: 1339 case GL_RGB565: 1340 case GL_R8: 1341 case GL_RG8: 1342 case GL_RGB8: 1343 case GL_RGBA8: 1344 case GL_R16F: 1345 case GL_RG16F: 1346 case GL_RGB16F: 1347 case GL_RGBA16F: 1348 case GL_R32F: 1349 case GL_RG32F: 1350 case GL_RGB32F: 1351 case GL_RGBA32F: // GL_EXT_color_buffer_float, OpenGL ES 3.0+ only. 1352 case GL_BGRA8_EXT: // GL_EXT_texture_format_BGRA8888 1353 case GL_R8UI: 1354 case GL_R8I: 1355 case GL_R16UI: 1356 case GL_R16I: 1357 case GL_R32UI: 1358 case GL_R32I: 1359 case GL_RG8UI: 1360 case GL_RG8I: 1361 case GL_RG16UI: 1362 case GL_RG16I: 1363 case GL_RG32UI: 1364 case GL_RG32I: 1365 case GL_SRGB8_ALPHA8: 1366 case GL_RGB10_A2: 1367 case GL_RGBA8UI: 1368 case GL_RGBA8I: 1369 case GL_RGB10_A2UI: 1370 case GL_RGBA16UI: 1371 case GL_RGBA16I: 1372 case GL_RGBA32I: 1373 case GL_RGBA32UI: 1374 case GL_R11F_G11F_B10F: 1375 return true; 1376 case GL_R8_SNORM: 1377 case GL_RG8_SNORM: 1378 case GL_RGB8_SNORM: 1379 case GL_RGBA8_SNORM: 1380 case GL_ALPHA8_EXT: 1381 case GL_LUMINANCE8_EXT: 1382 case GL_LUMINANCE8_ALPHA8_EXT: 1383 case GL_ALPHA32F_EXT: 1384 case GL_LUMINANCE32F_EXT: 1385 case GL_LUMINANCE_ALPHA32F_EXT: 1386 case GL_ALPHA16F_EXT: 1387 case GL_LUMINANCE16F_EXT: 1388 case GL_LUMINANCE_ALPHA16F_EXT: 1389 case GL_DEPTH_COMPONENT24: 1390 case GL_DEPTH_COMPONENT32_OES: 1391 case GL_DEPTH_COMPONENT32F: 1392 case GL_DEPTH32F_STENCIL8: 1393 case GL_DEPTH_COMPONENT16: 1394 case GL_STENCIL_INDEX8: 1395 case GL_DEPTH24_STENCIL8_OES: 1396 return false; 1397 default: 1398 UNIMPLEMENTED(); 1399 } 1400 1401 return false; 1402 } 1403 IsDepthRenderable(GLint internalformat)1404 bool IsDepthRenderable(GLint internalformat) 1405 { 1406 if(IsCompressed(internalformat)) 1407 { 1408 return false; 1409 } 1410 1411 switch(internalformat) 1412 { 1413 case GL_DEPTH_COMPONENT24: 1414 case GL_DEPTH_COMPONENT16: 1415 case GL_DEPTH24_STENCIL8_OES: // GL_OES_packed_depth_stencil 1416 case GL_DEPTH_COMPONENT32_OES: // GL_OES_depth32 1417 case GL_DEPTH32F_STENCIL8: 1418 case GL_DEPTH_COMPONENT32F: 1419 return true; 1420 case GL_STENCIL_INDEX8: 1421 case GL_R8: 1422 case GL_R8UI: 1423 case GL_R8I: 1424 case GL_R16UI: 1425 case GL_R16I: 1426 case GL_R32UI: 1427 case GL_R32I: 1428 case GL_RG8: 1429 case GL_RG8UI: 1430 case GL_RG8I: 1431 case GL_RG16UI: 1432 case GL_RG16I: 1433 case GL_RG32UI: 1434 case GL_RG32I: 1435 case GL_SRGB8_ALPHA8: 1436 case GL_RGB10_A2: 1437 case GL_RGBA8UI: 1438 case GL_RGBA8I: 1439 case GL_RGB10_A2UI: 1440 case GL_RGBA16UI: 1441 case GL_RGBA16I: 1442 case GL_RGBA32I: 1443 case GL_RGBA32UI: 1444 case GL_RGBA4: 1445 case GL_RGB5_A1: 1446 case GL_RGB565: 1447 case GL_RGB8: 1448 case GL_RGBA8: 1449 case GL_RED: 1450 case GL_RG: 1451 case GL_RGB: 1452 case GL_RGBA: 1453 case GL_R16F: 1454 case GL_RG16F: 1455 case GL_R11F_G11F_B10F: 1456 case GL_RGB16F: 1457 case GL_RGBA16F: 1458 case GL_R32F: 1459 case GL_RG32F: 1460 case GL_RGB32F: 1461 case GL_RGBA32F: 1462 case GL_R8_SNORM: 1463 case GL_RG8_SNORM: 1464 case GL_RGB8_SNORM: 1465 case GL_RGBA8_SNORM: 1466 return false; 1467 default: 1468 UNIMPLEMENTED(); 1469 } 1470 1471 return false; 1472 } 1473 IsStencilRenderable(GLint internalformat)1474 bool IsStencilRenderable(GLint internalformat) 1475 { 1476 if(IsCompressed(internalformat)) 1477 { 1478 return false; 1479 } 1480 1481 switch(internalformat) 1482 { 1483 case GL_STENCIL_INDEX8: 1484 case GL_DEPTH24_STENCIL8_OES: 1485 case GL_DEPTH32F_STENCIL8: 1486 return true; 1487 case GL_R8: 1488 case GL_R8UI: 1489 case GL_R8I: 1490 case GL_R16UI: 1491 case GL_R16I: 1492 case GL_R32UI: 1493 case GL_R32I: 1494 case GL_RG8: 1495 case GL_RG8UI: 1496 case GL_RG8I: 1497 case GL_RG16UI: 1498 case GL_RG16I: 1499 case GL_RG32UI: 1500 case GL_RG32I: 1501 case GL_SRGB8_ALPHA8: 1502 case GL_RGB10_A2: 1503 case GL_RGBA8UI: 1504 case GL_RGBA8I: 1505 case GL_RGB10_A2UI: 1506 case GL_RGBA16UI: 1507 case GL_RGBA16I: 1508 case GL_RGBA32I: 1509 case GL_RGBA32UI: 1510 case GL_RGBA4: 1511 case GL_RGB5_A1: 1512 case GL_RGB565: 1513 case GL_RGB8: 1514 case GL_RGBA8: 1515 case GL_RED: 1516 case GL_RG: 1517 case GL_RGB: 1518 case GL_RGBA: 1519 case GL_R16F: 1520 case GL_RG16F: 1521 case GL_R11F_G11F_B10F: 1522 case GL_RGB16F: 1523 case GL_RGBA16F: 1524 case GL_R32F: 1525 case GL_RG32F: 1526 case GL_RGB32F: 1527 case GL_RGBA32F: 1528 case GL_DEPTH_COMPONENT16: 1529 case GL_DEPTH_COMPONENT24: 1530 case GL_DEPTH_COMPONENT32_OES: 1531 case GL_DEPTH_COMPONENT32F: 1532 case GL_R8_SNORM: 1533 case GL_RG8_SNORM: 1534 case GL_RGB8_SNORM: 1535 case GL_RGBA8_SNORM: 1536 return false; 1537 default: 1538 UNIMPLEMENTED(); 1539 } 1540 1541 return false; 1542 } 1543 IsMipmappable(GLint internalformat)1544 bool IsMipmappable(GLint internalformat) 1545 { 1546 if(internalformat == GL_NONE) 1547 { 1548 return true; // Image unspecified. Not an error. 1549 } 1550 1551 if(IsNonNormalizedInteger(internalformat)) 1552 { 1553 return false; 1554 } 1555 1556 switch(internalformat) 1557 { 1558 case GL_ALPHA8_EXT: 1559 case GL_LUMINANCE8_EXT: 1560 case GL_LUMINANCE8_ALPHA8_EXT: 1561 case GL_ALPHA32F_EXT: 1562 case GL_LUMINANCE32F_EXT: 1563 case GL_LUMINANCE_ALPHA32F_EXT: 1564 case GL_ALPHA16F_EXT: 1565 case GL_LUMINANCE16F_EXT: 1566 case GL_LUMINANCE_ALPHA16F_EXT: 1567 return true; 1568 default: 1569 return IsColorRenderable(internalformat); 1570 } 1571 } 1572 GetAlphaSize(GLint internalformat)1573 GLuint GetAlphaSize(GLint internalformat) 1574 { 1575 switch(internalformat) 1576 { 1577 case GL_NONE: return 0; 1578 case GL_RGBA4: return 4; 1579 case GL_RGB5_A1: return 1; 1580 case GL_RGB565: return 0; 1581 case GL_R8: return 0; 1582 case GL_RG8: return 0; 1583 case GL_RGB8: return 0; 1584 case GL_RGBA8: return 8; 1585 case GL_R16F: return 0; 1586 case GL_RG16F: return 0; 1587 case GL_RGB16F: return 0; 1588 case GL_RGBA16F: return 16; 1589 case GL_R32F: return 0; 1590 case GL_RG32F: return 0; 1591 case GL_RGB32F: return 0; 1592 case GL_RGBA32F: return 32; 1593 case GL_BGRA8_EXT: return 8; 1594 case GL_R8UI: return 0; 1595 case GL_R8I: return 0; 1596 case GL_R16UI: return 0; 1597 case GL_R16I: return 0; 1598 case GL_R32UI: return 0; 1599 case GL_R32I: return 0; 1600 case GL_RG8UI: return 0; 1601 case GL_RG8I: return 0; 1602 case GL_RG16UI: return 0; 1603 case GL_RG16I: return 0; 1604 case GL_RG32UI: return 0; 1605 case GL_RG32I: return 0; 1606 case GL_SRGB8_ALPHA8: return 8; 1607 case GL_RGB10_A2: return 2; 1608 case GL_RGBA8UI: return 8; 1609 case GL_RGBA8I: return 8; 1610 case GL_RGB10_A2UI: return 2; 1611 case GL_RGBA16UI: return 16; 1612 case GL_RGBA16I: return 16; 1613 case GL_RGBA32I: return 32; 1614 case GL_RGBA32UI: return 32; 1615 case GL_R11F_G11F_B10F: return 0; 1616 default: 1617 // UNREACHABLE(internalformat); 1618 return 0; 1619 } 1620 } 1621 GetRedSize(GLint internalformat)1622 GLuint GetRedSize(GLint internalformat) 1623 { 1624 switch(internalformat) 1625 { 1626 case GL_NONE: return 0; 1627 case GL_RGBA4: return 4; 1628 case GL_RGB5_A1: return 5; 1629 case GL_RGB565: return 5; 1630 case GL_R8: return 8; 1631 case GL_RG8: return 8; 1632 case GL_RGB8: return 8; 1633 case GL_RGBA8: return 8; 1634 case GL_R16F: return 16; 1635 case GL_RG16F: return 16; 1636 case GL_RGB16F: return 16; 1637 case GL_RGBA16F: return 16; 1638 case GL_R32F: return 32; 1639 case GL_RG32F: return 32; 1640 case GL_RGB32F: return 32; 1641 case GL_RGBA32F: return 32; 1642 case GL_BGRA8_EXT: return 8; 1643 case GL_R8UI: return 8; 1644 case GL_R8I: return 8; 1645 case GL_R16UI: return 16; 1646 case GL_R16I: return 16; 1647 case GL_R32UI: return 32; 1648 case GL_R32I: return 32; 1649 case GL_RG8UI: return 8; 1650 case GL_RG8I: return 8; 1651 case GL_RG16UI: return 16; 1652 case GL_RG16I: return 16; 1653 case GL_RG32UI: return 32; 1654 case GL_RG32I: return 32; 1655 case GL_SRGB8_ALPHA8: return 8; 1656 case GL_RGB10_A2: return 10; 1657 case GL_RGBA8UI: return 8; 1658 case GL_RGBA8I: return 8; 1659 case GL_RGB10_A2UI: return 10; 1660 case GL_RGBA16UI: return 16; 1661 case GL_RGBA16I: return 16; 1662 case GL_RGBA32I: return 32; 1663 case GL_RGBA32UI: return 32; 1664 case GL_R11F_G11F_B10F: return 11; 1665 default: 1666 // UNREACHABLE(internalformat); 1667 return 0; 1668 } 1669 } 1670 GetGreenSize(GLint internalformat)1671 GLuint GetGreenSize(GLint internalformat) 1672 { 1673 switch(internalformat) 1674 { 1675 case GL_NONE: return 0; 1676 case GL_RGBA4: return 4; 1677 case GL_RGB5_A1: return 5; 1678 case GL_RGB565: return 6; 1679 case GL_R8: return 0; 1680 case GL_RG8: return 8; 1681 case GL_RGB8: return 8; 1682 case GL_RGBA8: return 8; 1683 case GL_R16F: return 0; 1684 case GL_RG16F: return 16; 1685 case GL_RGB16F: return 16; 1686 case GL_RGBA16F: return 16; 1687 case GL_R32F: return 0; 1688 case GL_RG32F: return 32; 1689 case GL_RGB32F: return 32; 1690 case GL_RGBA32F: return 32; 1691 case GL_BGRA8_EXT: return 8; 1692 case GL_R8UI: return 0; 1693 case GL_R8I: return 0; 1694 case GL_R16UI: return 0; 1695 case GL_R16I: return 0; 1696 case GL_R32UI: return 0; 1697 case GL_R32I: return 0; 1698 case GL_RG8UI: return 8; 1699 case GL_RG8I: return 8; 1700 case GL_RG16UI: return 16; 1701 case GL_RG16I: return 16; 1702 case GL_RG32UI: return 32; 1703 case GL_RG32I: return 32; 1704 case GL_SRGB8_ALPHA8: return 8; 1705 case GL_RGB10_A2: return 10; 1706 case GL_RGBA8UI: return 8; 1707 case GL_RGBA8I: return 8; 1708 case GL_RGB10_A2UI: return 10; 1709 case GL_RGBA16UI: return 16; 1710 case GL_RGBA16I: return 16; 1711 case GL_RGBA32I: return 32; 1712 case GL_RGBA32UI: return 32; 1713 case GL_R11F_G11F_B10F: return 11; 1714 default: 1715 // UNREACHABLE(internalformat); 1716 return 0; 1717 } 1718 } 1719 GetBlueSize(GLint internalformat)1720 GLuint GetBlueSize(GLint internalformat) 1721 { 1722 switch(internalformat) 1723 { 1724 case GL_NONE: return 0; 1725 case GL_RGBA4: return 4; 1726 case GL_RGB5_A1: return 5; 1727 case GL_RGB565: return 5; 1728 case GL_R8: return 0; 1729 case GL_RG8: return 0; 1730 case GL_RGB8: return 8; 1731 case GL_RGBA8: return 8; 1732 case GL_R16F: return 0; 1733 case GL_RG16F: return 0; 1734 case GL_RGB16F: return 16; 1735 case GL_RGBA16F: return 16; 1736 case GL_R32F: return 0; 1737 case GL_RG32F: return 0; 1738 case GL_RGB32F: return 32; 1739 case GL_RGBA32F: return 32; 1740 case GL_BGRA8_EXT: return 8; 1741 case GL_R8UI: return 0; 1742 case GL_R8I: return 0; 1743 case GL_R16UI: return 0; 1744 case GL_R16I: return 0; 1745 case GL_R32UI: return 0; 1746 case GL_R32I: return 0; 1747 case GL_RG8UI: return 0; 1748 case GL_RG8I: return 0; 1749 case GL_RG16UI: return 0; 1750 case GL_RG16I: return 0; 1751 case GL_RG32UI: return 0; 1752 case GL_RG32I: return 0; 1753 case GL_SRGB8_ALPHA8: return 8; 1754 case GL_RGB10_A2: return 10; 1755 case GL_RGBA8UI: return 8; 1756 case GL_RGBA8I: return 8; 1757 case GL_RGB10_A2UI: return 10; 1758 case GL_RGBA16UI: return 16; 1759 case GL_RGBA16I: return 16; 1760 case GL_RGBA32I: return 32; 1761 case GL_RGBA32UI: return 32; 1762 case GL_R11F_G11F_B10F: return 10; 1763 default: 1764 // UNREACHABLE(internalformat); 1765 return 0; 1766 } 1767 } 1768 GetDepthSize(GLint internalformat)1769 GLuint GetDepthSize(GLint internalformat) 1770 { 1771 switch(internalformat) 1772 { 1773 case GL_STENCIL_INDEX8: return 0; 1774 case GL_DEPTH_COMPONENT16: return 16; 1775 case GL_DEPTH_COMPONENT24: return 24; 1776 case GL_DEPTH_COMPONENT32_OES: return 32; 1777 case GL_DEPTH_COMPONENT32F: return 32; 1778 case GL_DEPTH24_STENCIL8: return 24; 1779 case GL_DEPTH32F_STENCIL8: return 32; 1780 default: 1781 // UNREACHABLE(internalformat); 1782 return 0; 1783 } 1784 } 1785 GetStencilSize(GLint internalformat)1786 GLuint GetStencilSize(GLint internalformat) 1787 { 1788 switch(internalformat) 1789 { 1790 case GL_STENCIL_INDEX8: return 8; 1791 case GL_DEPTH_COMPONENT16: return 0; 1792 case GL_DEPTH_COMPONENT24: return 0; 1793 case GL_DEPTH_COMPONENT32_OES: return 0; 1794 case GL_DEPTH_COMPONENT32F: return 0; 1795 case GL_DEPTH24_STENCIL8: return 8; 1796 case GL_DEPTH32F_STENCIL8: return 8; 1797 default: 1798 // UNREACHABLE(internalformat); 1799 return 0; 1800 } 1801 } 1802 GetColorComponentType(GLint internalformat)1803 GLenum GetColorComponentType(GLint internalformat) 1804 { 1805 switch(internalformat) 1806 { 1807 case GL_ALPHA8_EXT: 1808 case GL_LUMINANCE8_ALPHA8_EXT: 1809 case GL_LUMINANCE8_EXT: 1810 case GL_R8: 1811 case GL_RG8: 1812 case GL_SRGB8_ALPHA8: 1813 case GL_RGB10_A2: 1814 case GL_RGBA4: 1815 case GL_RGB5_A1: 1816 case GL_RGB565: 1817 case GL_RGB8: 1818 case GL_RGBA8: 1819 case GL_SRGB8: 1820 case GL_BGRA8_EXT: 1821 return GL_UNSIGNED_NORMALIZED; 1822 case GL_R8_SNORM: 1823 case GL_RG8_SNORM: 1824 case GL_RGB8_SNORM: 1825 case GL_RGBA8_SNORM: 1826 return GL_SIGNED_NORMALIZED; 1827 case GL_R8UI: 1828 case GL_R16UI: 1829 case GL_R32UI: 1830 case GL_RG8UI: 1831 case GL_RG16UI: 1832 case GL_RG32UI: 1833 case GL_RGB8UI: 1834 case GL_RGB16UI: 1835 case GL_RGB32UI: 1836 case GL_RGB10_A2UI: 1837 case GL_RGBA16UI: 1838 case GL_RGBA32UI: 1839 case GL_RGBA8UI: 1840 return GL_UNSIGNED_INT; 1841 case GL_R8I: 1842 case GL_R16I: 1843 case GL_R32I: 1844 case GL_RG8I: 1845 case GL_RG16I: 1846 case GL_RG32I: 1847 case GL_RGB8I: 1848 case GL_RGB16I: 1849 case GL_RGB32I: 1850 case GL_RGBA8I: 1851 case GL_RGBA16I: 1852 case GL_RGBA32I: 1853 return GL_INT; 1854 case GL_ALPHA32F_EXT: 1855 case GL_LUMINANCE32F_EXT: 1856 case GL_LUMINANCE_ALPHA32F_EXT: 1857 case GL_ALPHA16F_EXT: 1858 case GL_LUMINANCE16F_EXT: 1859 case GL_LUMINANCE_ALPHA16F_EXT: 1860 case GL_R16F: 1861 case GL_RG16F: 1862 case GL_R11F_G11F_B10F: 1863 case GL_RGB16F: 1864 case GL_RGBA16F: 1865 case GL_R32F: 1866 case GL_RG32F: 1867 case GL_RGB32F: 1868 case GL_RGBA32F: 1869 case GL_RGB9_E5: 1870 return GL_FLOAT; 1871 default: 1872 // UNREACHABLE(internalformat); 1873 return GL_NONE; 1874 } 1875 } 1876 GetComponentType(GLint internalformat,GLenum attachment)1877 GLenum GetComponentType(GLint internalformat, GLenum attachment) 1878 { 1879 // Can be one of GL_FLOAT, GL_INT, GL_UNSIGNED_INT, GL_SIGNED_NORMALIZED, or GL_UNSIGNED_NORMALIZED 1880 switch(attachment) 1881 { 1882 case GL_COLOR_ATTACHMENT0: 1883 case GL_COLOR_ATTACHMENT1: 1884 case GL_COLOR_ATTACHMENT2: 1885 case GL_COLOR_ATTACHMENT3: 1886 case GL_COLOR_ATTACHMENT4: 1887 case GL_COLOR_ATTACHMENT5: 1888 case GL_COLOR_ATTACHMENT6: 1889 case GL_COLOR_ATTACHMENT7: 1890 case GL_COLOR_ATTACHMENT8: 1891 case GL_COLOR_ATTACHMENT9: 1892 case GL_COLOR_ATTACHMENT10: 1893 case GL_COLOR_ATTACHMENT11: 1894 case GL_COLOR_ATTACHMENT12: 1895 case GL_COLOR_ATTACHMENT13: 1896 case GL_COLOR_ATTACHMENT14: 1897 case GL_COLOR_ATTACHMENT15: 1898 case GL_COLOR_ATTACHMENT16: 1899 case GL_COLOR_ATTACHMENT17: 1900 case GL_COLOR_ATTACHMENT18: 1901 case GL_COLOR_ATTACHMENT19: 1902 case GL_COLOR_ATTACHMENT20: 1903 case GL_COLOR_ATTACHMENT21: 1904 case GL_COLOR_ATTACHMENT22: 1905 case GL_COLOR_ATTACHMENT23: 1906 case GL_COLOR_ATTACHMENT24: 1907 case GL_COLOR_ATTACHMENT25: 1908 case GL_COLOR_ATTACHMENT26: 1909 case GL_COLOR_ATTACHMENT27: 1910 case GL_COLOR_ATTACHMENT28: 1911 case GL_COLOR_ATTACHMENT29: 1912 case GL_COLOR_ATTACHMENT30: 1913 case GL_COLOR_ATTACHMENT31: 1914 return GetColorComponentType(internalformat); 1915 case GL_DEPTH_ATTACHMENT: 1916 case GL_STENCIL_ATTACHMENT: 1917 // Only color buffers may have integer components. 1918 return GL_FLOAT; 1919 default: 1920 UNREACHABLE(attachment); 1921 return GL_NONE; 1922 } 1923 } 1924 IsNormalizedInteger(GLint internalformat)1925 bool IsNormalizedInteger(GLint internalformat) 1926 { 1927 GLenum type = GetColorComponentType(internalformat); 1928 1929 return type == GL_UNSIGNED_NORMALIZED || type == GL_SIGNED_NORMALIZED; 1930 } 1931 IsNonNormalizedInteger(GLint internalformat)1932 bool IsNonNormalizedInteger(GLint internalformat) 1933 { 1934 GLenum type = GetColorComponentType(internalformat); 1935 1936 return type == GL_UNSIGNED_INT || type == GL_INT; 1937 } 1938 IsFloatFormat(GLint internalformat)1939 bool IsFloatFormat(GLint internalformat) 1940 { 1941 return GetColorComponentType(internalformat) == GL_FLOAT; 1942 } 1943 IsSignedNonNormalizedInteger(GLint internalformat)1944 bool IsSignedNonNormalizedInteger(GLint internalformat) 1945 { 1946 return GetColorComponentType(internalformat) == GL_INT; 1947 } 1948 IsUnsignedNonNormalizedInteger(GLint internalformat)1949 bool IsUnsignedNonNormalizedInteger(GLint internalformat) 1950 { 1951 return GetColorComponentType(internalformat) == GL_UNSIGNED_INT; 1952 } 1953 GetColorEncoding(GLint internalformat)1954 GLenum GetColorEncoding(GLint internalformat) 1955 { 1956 switch(internalformat) 1957 { 1958 case GL_SRGB8: 1959 case GL_SRGB8_ALPHA8: 1960 return GL_SRGB; 1961 default: 1962 // [OpenGL ES 3.0.5] section 6.1.13 page 242: 1963 // If attachment is not a color attachment, or no data storage or texture image 1964 // has been specified for the attachment, params will contain the value LINEAR. 1965 return GL_LINEAR; 1966 } 1967 } 1968 ParseUniformName(const std::string & name,unsigned int * outSubscript)1969 std::string ParseUniformName(const std::string &name, unsigned int *outSubscript) 1970 { 1971 // Strip any trailing array operator and retrieve the subscript 1972 size_t open = name.find_last_of('['); 1973 size_t close = name.find_last_of(']'); 1974 bool hasIndex = (open != std::string::npos) && (close == name.length() - 1); 1975 if(!hasIndex) 1976 { 1977 if(outSubscript) 1978 { 1979 *outSubscript = GL_INVALID_INDEX; 1980 } 1981 return name; 1982 } 1983 1984 if(outSubscript) 1985 { 1986 int index = atoi(name.substr(open + 1).c_str()); 1987 if(index >= 0) 1988 { 1989 *outSubscript = index; 1990 } 1991 else 1992 { 1993 *outSubscript = GL_INVALID_INDEX; 1994 } 1995 } 1996 1997 return name.substr(0, open); 1998 } 1999 FloatFitsInInt(float f)2000 bool FloatFitsInInt(float f) 2001 { 2002 // We can't just do a raw comparison of "f > (float) INT32_MAX", 2003 // because "(float) INT32_MAX" is unrepresentable as an integer. 2004 // 2005 // So instead I subtracted an ULP from "(float) INT32_MAX", cast that 2006 // to an int, and do the comparison with that value. That value is 2007 // 2147483520, and can be found with the following code: 2008 // float f_max = static_cast<float>(INT32_MAX); 2009 // int32_t f_bits = *static_cast<int32_t *>((void *)&f_max); 2010 // f_bits -= 1; 2011 // float f_next = *static_cast<float *>((void *)&f_bits); 2012 // int32_t out = static_cast<int32_t>(f_next); 2013 return std::isfinite(f) && (-2147483520.f < f) && (f < 2147483520.f); 2014 } 2015 } 2016 2017 namespace es2sw 2018 { ConvertDepthComparison(GLenum comparison)2019 sw::DepthCompareMode ConvertDepthComparison(GLenum comparison) 2020 { 2021 switch(comparison) 2022 { 2023 case GL_NEVER: return sw::DEPTH_NEVER; 2024 case GL_ALWAYS: return sw::DEPTH_ALWAYS; 2025 case GL_LESS: return sw::DEPTH_LESS; 2026 case GL_LEQUAL: return sw::DEPTH_LESSEQUAL; 2027 case GL_EQUAL: return sw::DEPTH_EQUAL; 2028 case GL_GREATER: return sw::DEPTH_GREATER; 2029 case GL_GEQUAL: return sw::DEPTH_GREATEREQUAL; 2030 case GL_NOTEQUAL: return sw::DEPTH_NOTEQUAL; 2031 default: UNREACHABLE(comparison); 2032 } 2033 2034 return sw::DEPTH_ALWAYS; 2035 } 2036 ConvertStencilComparison(GLenum comparison)2037 sw::StencilCompareMode ConvertStencilComparison(GLenum comparison) 2038 { 2039 switch(comparison) 2040 { 2041 case GL_NEVER: return sw::STENCIL_NEVER; 2042 case GL_ALWAYS: return sw::STENCIL_ALWAYS; 2043 case GL_LESS: return sw::STENCIL_LESS; 2044 case GL_LEQUAL: return sw::STENCIL_LESSEQUAL; 2045 case GL_EQUAL: return sw::STENCIL_EQUAL; 2046 case GL_GREATER: return sw::STENCIL_GREATER; 2047 case GL_GEQUAL: return sw::STENCIL_GREATEREQUAL; 2048 case GL_NOTEQUAL: return sw::STENCIL_NOTEQUAL; 2049 default: UNREACHABLE(comparison); 2050 } 2051 2052 return sw::STENCIL_ALWAYS; 2053 } 2054 ConvertColor(es2::Color color)2055 sw::Color<float> ConvertColor(es2::Color color) 2056 { 2057 return sw::Color<float>(color.red, color.green, color.blue, color.alpha); 2058 } 2059 ConvertBlendFunc(GLenum blend)2060 sw::BlendFactor ConvertBlendFunc(GLenum blend) 2061 { 2062 switch(blend) 2063 { 2064 case GL_ZERO: return sw::BLEND_ZERO; 2065 case GL_ONE: return sw::BLEND_ONE; 2066 case GL_SRC_COLOR: return sw::BLEND_SOURCE; 2067 case GL_ONE_MINUS_SRC_COLOR: return sw::BLEND_INVSOURCE; 2068 case GL_DST_COLOR: return sw::BLEND_DEST; 2069 case GL_ONE_MINUS_DST_COLOR: return sw::BLEND_INVDEST; 2070 case GL_SRC_ALPHA: return sw::BLEND_SOURCEALPHA; 2071 case GL_ONE_MINUS_SRC_ALPHA: return sw::BLEND_INVSOURCEALPHA; 2072 case GL_DST_ALPHA: return sw::BLEND_DESTALPHA; 2073 case GL_ONE_MINUS_DST_ALPHA: return sw::BLEND_INVDESTALPHA; 2074 case GL_CONSTANT_COLOR: return sw::BLEND_CONSTANT; 2075 case GL_ONE_MINUS_CONSTANT_COLOR: return sw::BLEND_INVCONSTANT; 2076 case GL_CONSTANT_ALPHA: return sw::BLEND_CONSTANTALPHA; 2077 case GL_ONE_MINUS_CONSTANT_ALPHA: return sw::BLEND_INVCONSTANTALPHA; 2078 case GL_SRC_ALPHA_SATURATE: return sw::BLEND_SRCALPHASAT; 2079 default: UNREACHABLE(blend); 2080 } 2081 2082 return sw::BLEND_ZERO; 2083 } 2084 ConvertBlendOp(GLenum blendOp)2085 sw::BlendOperation ConvertBlendOp(GLenum blendOp) 2086 { 2087 switch(blendOp) 2088 { 2089 case GL_FUNC_ADD: return sw::BLENDOP_ADD; 2090 case GL_FUNC_SUBTRACT: return sw::BLENDOP_SUB; 2091 case GL_FUNC_REVERSE_SUBTRACT: return sw::BLENDOP_INVSUB; 2092 case GL_MIN_EXT: return sw::BLENDOP_MIN; 2093 case GL_MAX_EXT: return sw::BLENDOP_MAX; 2094 default: UNREACHABLE(blendOp); 2095 } 2096 2097 return sw::BLENDOP_ADD; 2098 } 2099 ConvertStencilOp(GLenum stencilOp)2100 sw::StencilOperation ConvertStencilOp(GLenum stencilOp) 2101 { 2102 switch(stencilOp) 2103 { 2104 case GL_ZERO: return sw::OPERATION_ZERO; 2105 case GL_KEEP: return sw::OPERATION_KEEP; 2106 case GL_REPLACE: return sw::OPERATION_REPLACE; 2107 case GL_INCR: return sw::OPERATION_INCRSAT; 2108 case GL_DECR: return sw::OPERATION_DECRSAT; 2109 case GL_INVERT: return sw::OPERATION_INVERT; 2110 case GL_INCR_WRAP: return sw::OPERATION_INCR; 2111 case GL_DECR_WRAP: return sw::OPERATION_DECR; 2112 default: UNREACHABLE(stencilOp); 2113 } 2114 2115 return sw::OPERATION_KEEP; 2116 } 2117 ConvertTextureWrap(GLenum wrap)2118 sw::AddressingMode ConvertTextureWrap(GLenum wrap) 2119 { 2120 switch(wrap) 2121 { 2122 case GL_REPEAT: return sw::ADDRESSING_WRAP; 2123 case GL_CLAMP_TO_EDGE: return sw::ADDRESSING_CLAMP; 2124 case GL_MIRRORED_REPEAT: return sw::ADDRESSING_MIRROR; 2125 default: UNREACHABLE(wrap); 2126 } 2127 2128 return sw::ADDRESSING_WRAP; 2129 } 2130 ConvertCompareFunc(GLenum compareFunc,GLenum compareMode)2131 sw::CompareFunc ConvertCompareFunc(GLenum compareFunc, GLenum compareMode) 2132 { 2133 if(compareMode == GL_COMPARE_REF_TO_TEXTURE) 2134 { 2135 switch(compareFunc) 2136 { 2137 case GL_LEQUAL: return sw::COMPARE_LESSEQUAL; 2138 case GL_GEQUAL: return sw::COMPARE_GREATEREQUAL; 2139 case GL_LESS: return sw::COMPARE_LESS; 2140 case GL_GREATER: return sw::COMPARE_GREATER; 2141 case GL_EQUAL: return sw::COMPARE_EQUAL; 2142 case GL_NOTEQUAL: return sw::COMPARE_NOTEQUAL; 2143 case GL_ALWAYS: return sw::COMPARE_ALWAYS; 2144 case GL_NEVER: return sw::COMPARE_NEVER; 2145 default: UNREACHABLE(compareFunc); 2146 } 2147 } 2148 else if(compareMode == GL_NONE) 2149 { 2150 return sw::COMPARE_BYPASS; 2151 } 2152 else UNREACHABLE(compareMode); 2153 2154 return sw::COMPARE_BYPASS; 2155 } 2156 ConvertSwizzleType(GLenum swizzleType)2157 sw::SwizzleType ConvertSwizzleType(GLenum swizzleType) 2158 { 2159 switch(swizzleType) 2160 { 2161 case GL_RED: return sw::SWIZZLE_RED; 2162 case GL_GREEN: return sw::SWIZZLE_GREEN; 2163 case GL_BLUE: return sw::SWIZZLE_BLUE; 2164 case GL_ALPHA: return sw::SWIZZLE_ALPHA; 2165 case GL_ZERO: return sw::SWIZZLE_ZERO; 2166 case GL_ONE: return sw::SWIZZLE_ONE; 2167 default: UNREACHABLE(swizzleType); 2168 } 2169 2170 return sw::SWIZZLE_RED; 2171 } 2172 ConvertCullMode(GLenum cullFace,GLenum frontFace)2173 sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace) 2174 { 2175 switch(cullFace) 2176 { 2177 case GL_FRONT: 2178 return (frontFace == GL_CCW ? sw::CULL_CLOCKWISE : sw::CULL_COUNTERCLOCKWISE); 2179 case GL_BACK: 2180 return (frontFace == GL_CCW ? sw::CULL_COUNTERCLOCKWISE : sw::CULL_CLOCKWISE); 2181 case GL_FRONT_AND_BACK: 2182 return sw::CULL_NONE; // culling will be handled during draw 2183 default: UNREACHABLE(cullFace); 2184 } 2185 2186 return sw::CULL_COUNTERCLOCKWISE; 2187 } 2188 ConvertColorMask(bool red,bool green,bool blue,bool alpha)2189 unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha) 2190 { 2191 return (red ? 0x00000001 : 0) | 2192 (green ? 0x00000002 : 0) | 2193 (blue ? 0x00000004 : 0) | 2194 (alpha ? 0x00000008 : 0); 2195 } 2196 ConvertMipMapFilter(GLenum minFilter)2197 sw::MipmapType ConvertMipMapFilter(GLenum minFilter) 2198 { 2199 switch(minFilter) 2200 { 2201 case GL_NEAREST: 2202 case GL_LINEAR: 2203 return sw::MIPMAP_NONE; 2204 case GL_NEAREST_MIPMAP_NEAREST: 2205 case GL_LINEAR_MIPMAP_NEAREST: 2206 return sw::MIPMAP_POINT; 2207 case GL_NEAREST_MIPMAP_LINEAR: 2208 case GL_LINEAR_MIPMAP_LINEAR: 2209 return sw::MIPMAP_LINEAR; 2210 default: 2211 UNREACHABLE(minFilter); 2212 return sw::MIPMAP_NONE; 2213 } 2214 } 2215 ConvertTextureFilter(GLenum minFilter,GLenum magFilter,float maxAnisotropy)2216 sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy) 2217 { 2218 if(maxAnisotropy > 1.0f) 2219 { 2220 return sw::FILTER_ANISOTROPIC; 2221 } 2222 2223 switch(magFilter) 2224 { 2225 case GL_NEAREST: 2226 case GL_LINEAR: 2227 break; 2228 default: 2229 UNREACHABLE(magFilter); 2230 } 2231 2232 switch(minFilter) 2233 { 2234 case GL_NEAREST: 2235 case GL_NEAREST_MIPMAP_NEAREST: 2236 case GL_NEAREST_MIPMAP_LINEAR: 2237 return (magFilter == GL_NEAREST) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR; 2238 case GL_LINEAR: 2239 case GL_LINEAR_MIPMAP_NEAREST: 2240 case GL_LINEAR_MIPMAP_LINEAR: 2241 return (magFilter == GL_NEAREST) ? sw::FILTER_MIN_LINEAR_MAG_POINT : sw::FILTER_LINEAR; 2242 default: 2243 UNREACHABLE(minFilter); 2244 return sw::FILTER_POINT; 2245 } 2246 } 2247 ConvertPrimitiveType(GLenum primitiveType,GLsizei elementCount,GLenum elementType,sw::DrawType & drawType,int & primitiveCount,int & verticesPerPrimitive)2248 bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, GLenum elementType, sw::DrawType &drawType, int &primitiveCount, int &verticesPerPrimitive) 2249 { 2250 switch(primitiveType) 2251 { 2252 case GL_POINTS: 2253 drawType = sw::DRAW_POINTLIST; 2254 primitiveCount = elementCount; 2255 verticesPerPrimitive = 1; 2256 break; 2257 case GL_LINES: 2258 drawType = sw::DRAW_LINELIST; 2259 primitiveCount = elementCount / 2; 2260 verticesPerPrimitive = 2; 2261 break; 2262 case GL_LINE_LOOP: 2263 drawType = sw::DRAW_LINELOOP; 2264 primitiveCount = elementCount; 2265 verticesPerPrimitive = 2; 2266 break; 2267 case GL_LINE_STRIP: 2268 drawType = sw::DRAW_LINESTRIP; 2269 primitiveCount = elementCount - 1; 2270 verticesPerPrimitive = 2; 2271 break; 2272 case GL_TRIANGLES: 2273 drawType = sw::DRAW_TRIANGLELIST; 2274 primitiveCount = elementCount / 3; 2275 verticesPerPrimitive = 3; 2276 break; 2277 case GL_TRIANGLE_STRIP: 2278 drawType = sw::DRAW_TRIANGLESTRIP; 2279 primitiveCount = elementCount - 2; 2280 verticesPerPrimitive = 3; 2281 break; 2282 case GL_TRIANGLE_FAN: 2283 drawType = sw::DRAW_TRIANGLEFAN; 2284 primitiveCount = elementCount - 2; 2285 verticesPerPrimitive = 3; 2286 break; 2287 default: 2288 return false; 2289 } 2290 2291 sw::DrawType elementSize; 2292 switch(elementType) 2293 { 2294 case GL_NONE: elementSize = sw::DRAW_NONINDEXED; break; 2295 case GL_UNSIGNED_BYTE: elementSize = sw::DRAW_INDEXED8; break; 2296 case GL_UNSIGNED_SHORT: elementSize = sw::DRAW_INDEXED16; break; 2297 case GL_UNSIGNED_INT: elementSize = sw::DRAW_INDEXED32; break; 2298 default: return false; 2299 } 2300 2301 drawType = sw::DrawType(drawType | elementSize); 2302 2303 return true; 2304 } 2305 } 2306 2307 namespace sw2es 2308 { ConvertBackBufferFormat(sw::Format format)2309 GLenum ConvertBackBufferFormat(sw::Format format) 2310 { 2311 switch(format) 2312 { 2313 case sw::FORMAT_A4R4G4B4: return GL_RGBA4; 2314 case sw::FORMAT_A8R8G8B8: return GL_RGBA8; 2315 case sw::FORMAT_A8B8G8R8: return GL_RGBA8; 2316 case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1; 2317 case sw::FORMAT_R5G6B5: return GL_RGB565; 2318 case sw::FORMAT_X8R8G8B8: return GL_RGB8; 2319 case sw::FORMAT_X8B8G8R8: return GL_RGB8; 2320 case sw::FORMAT_SRGB8_A8: return GL_RGBA8; 2321 case sw::FORMAT_SRGB8_X8: return GL_RGB8; 2322 default: 2323 UNREACHABLE(format); 2324 } 2325 2326 return GL_RGBA4; 2327 } 2328 ConvertDepthStencilFormat(sw::Format format)2329 GLenum ConvertDepthStencilFormat(sw::Format format) 2330 { 2331 switch(format) 2332 { 2333 case sw::FORMAT_D16: return GL_DEPTH_COMPONENT16; 2334 case sw::FORMAT_D24X8: return GL_DEPTH_COMPONENT24; 2335 case sw::FORMAT_D32: return GL_DEPTH_COMPONENT32_OES; 2336 case sw::FORMAT_D24S8: return GL_DEPTH24_STENCIL8_OES; 2337 case sw::FORMAT_D32F: return GL_DEPTH_COMPONENT32F; 2338 case sw::FORMAT_D32FS8: return GL_DEPTH32F_STENCIL8; 2339 case sw::FORMAT_S8: return GL_STENCIL_INDEX8; 2340 default: 2341 UNREACHABLE(format); 2342 } 2343 2344 return GL_DEPTH24_STENCIL8_OES; 2345 } 2346 } 2347