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 "mathutil.h" 20 #include "Context.h" 21 #include "common/debug.h" 22 23 #include <limits> 24 #include <stdio.h> 25 26 namespace es1 27 { IsCompressed(GLenum format)28 bool IsCompressed(GLenum format) 29 { 30 return format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || 31 format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || 32 format == GL_ETC1_RGB8_OES; 33 } 34 IsSizedInternalFormat(GLint internalformat)35 bool IsSizedInternalFormat(GLint internalformat) 36 { 37 switch(internalformat) 38 { 39 case GL_ALPHA8_EXT: 40 case GL_LUMINANCE8_ALPHA8_EXT: 41 case GL_LUMINANCE8_EXT: 42 case GL_RGBA4_OES: 43 case GL_RGB5_A1_OES: 44 case GL_RGB565_OES: 45 case GL_RGB8_OES: 46 case GL_RGBA8_OES: 47 case GL_BGRA8_EXT: // GL_APPLE_texture_format_BGRA8888 48 case GL_DEPTH_COMPONENT16_OES: 49 case GL_STENCIL_INDEX8_OES: 50 case GL_DEPTH24_STENCIL8_OES: 51 return true; 52 default: 53 return false; 54 } 55 } 56 ValidateSubImageParams(bool compressed,bool copy,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,Texture * texture)57 GLenum ValidateSubImageParams(bool compressed, bool copy, GLenum target, GLint level, GLint xoffset, GLint yoffset, 58 GLsizei width, GLsizei height, GLenum format, GLenum type, Texture *texture) 59 { 60 if(!texture) 61 { 62 return GL_INVALID_OPERATION; 63 } 64 65 GLenum sizedInternalFormat = texture->getFormat(target, level); 66 67 if(compressed) 68 { 69 if(format != sizedInternalFormat) 70 { 71 return GL_INVALID_OPERATION; 72 } 73 } 74 else if(!copy) // CopyTexSubImage doesn't have format/type parameters. 75 { 76 GLenum validationError = ValidateTextureFormatType(format, type, sizedInternalFormat, target); 77 if(validationError != GL_NO_ERROR) 78 { 79 return validationError; 80 } 81 } 82 83 if(compressed) 84 { 85 if((width % 4 != 0 && width != texture->getWidth(target, 0)) || 86 (height % 4 != 0 && height != texture->getHeight(target, 0))) 87 { 88 return GL_INVALID_OPERATION; 89 } 90 } 91 92 if(xoffset + width > texture->getWidth(target, level) || 93 yoffset + height > texture->getHeight(target, level)) 94 { 95 return GL_INVALID_VALUE; 96 } 97 98 return GL_NO_ERROR; 99 } 100 IsDepthTexture(GLenum format)101 bool IsDepthTexture(GLenum format) 102 { 103 return format == GL_DEPTH_STENCIL_OES; 104 } 105 IsStencilTexture(GLenum format)106 bool IsStencilTexture(GLenum format) 107 { 108 return format == GL_DEPTH_STENCIL_OES; 109 } 110 IsCubemapTextureTarget(GLenum target)111 bool IsCubemapTextureTarget(GLenum target) 112 { 113 return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES); 114 } 115 CubeFaceIndex(GLenum cubeFace)116 int CubeFaceIndex(GLenum cubeFace) 117 { 118 switch(cubeFace) 119 { 120 case GL_TEXTURE_CUBE_MAP_OES: 121 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES: return 0; 122 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES: return 1; 123 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES: return 2; 124 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES: return 3; 125 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES: return 4; 126 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES: return 5; 127 default: UNREACHABLE(cubeFace); return 0; 128 } 129 } 130 IsTextureTarget(GLenum target)131 bool IsTextureTarget(GLenum target) 132 { 133 return target == GL_TEXTURE_2D; 134 } 135 136 // Verify that format/type are one of the combinations from table 3.4. ValidateTextureFormatType(GLenum format,GLenum type,GLint internalformat,GLenum target)137 GLenum ValidateTextureFormatType(GLenum format, GLenum type, GLint internalformat, GLenum target) 138 { 139 switch(type) 140 { 141 case GL_UNSIGNED_BYTE: 142 case GL_UNSIGNED_SHORT_4_4_4_4: 143 case GL_UNSIGNED_SHORT_5_5_5_1: 144 case GL_UNSIGNED_SHORT_5_6_5: 145 case GL_UNSIGNED_INT_24_8_OES: // GL_OES_packed_depth_stencil 146 break; 147 default: 148 return GL_INVALID_ENUM; 149 } 150 151 switch(format) 152 { 153 case GL_ALPHA: 154 case GL_RGB: 155 case GL_RGBA: 156 case GL_LUMINANCE: 157 case GL_LUMINANCE_ALPHA: 158 case GL_BGRA_EXT: // GL_EXT_texture_format_BGRA8888 159 break; 160 case GL_DEPTH_STENCIL_OES: // GL_OES_packed_depth_stencil (GL_DEPTH_STENCIL_OES) 161 switch(target) 162 { 163 case GL_TEXTURE_2D: 164 break; 165 default: 166 return GL_INVALID_OPERATION; 167 } 168 break; 169 default: 170 return GL_INVALID_ENUM; 171 } 172 173 if((GLenum)internalformat != format) 174 { 175 if(gl::IsUnsizedInternalFormat(internalformat)) 176 { 177 return GL_INVALID_OPERATION; 178 } 179 180 if(!IsSizedInternalFormat(internalformat)) 181 { 182 return GL_INVALID_VALUE; 183 } 184 } 185 186 if((GLenum)internalformat == format) 187 { 188 // Validate format, type, and unsized internalformat combinations [OpenGL ES 1.1 Table 3.3] 189 switch(format) 190 { 191 case GL_RGBA: 192 switch(type) 193 { 194 case GL_UNSIGNED_BYTE: 195 case GL_UNSIGNED_SHORT_4_4_4_4: 196 case GL_UNSIGNED_SHORT_5_5_5_1: 197 break; 198 default: 199 return GL_INVALID_OPERATION; 200 } 201 break; 202 case GL_RGB: 203 switch(type) 204 { 205 case GL_UNSIGNED_BYTE: 206 case GL_UNSIGNED_SHORT_5_6_5: 207 break; 208 default: 209 return GL_INVALID_OPERATION; 210 } 211 break; 212 case GL_LUMINANCE_ALPHA: 213 case GL_LUMINANCE: 214 case GL_ALPHA: 215 switch(type) 216 { 217 case GL_UNSIGNED_BYTE: 218 break; 219 default: 220 return GL_INVALID_OPERATION; 221 } 222 break; 223 case GL_DEPTH_STENCIL_OES: 224 switch(type) 225 { 226 case GL_UNSIGNED_INT_24_8_OES: // GL_OES_packed_depth_stencil 227 break; 228 default: 229 return GL_INVALID_OPERATION; 230 } 231 break; 232 case GL_BGRA_EXT: 233 if(type != GL_UNSIGNED_BYTE) // GL_APPLE_texture_format_BGRA8888 / GL_EXT_texture_format_BGRA8888 234 { 235 return GL_INVALID_OPERATION; 236 } 237 break; 238 default: 239 UNREACHABLE(format); 240 return GL_INVALID_ENUM; 241 } 242 243 return GL_NO_ERROR; 244 } 245 246 // Validate format, type, and sized internalformat combinations [OpenGL ES 3.0 Table 3.2] 247 bool validSizedInternalformat = false; 248 #define VALIDATE_INTERNALFORMAT(...) { GLint validInternalformats[] = {__VA_ARGS__}; for(GLint v : validInternalformats) {if(internalformat == v) validSizedInternalformat = true;} } break; 249 250 switch(format) 251 { 252 case GL_RGBA: 253 switch(type) 254 { 255 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGBA8_OES, GL_RGB5_A1_OES, GL_RGBA4_OES) 256 case GL_UNSIGNED_SHORT_4_4_4_4: VALIDATE_INTERNALFORMAT(GL_RGBA4_OES) 257 case GL_UNSIGNED_SHORT_5_5_5_1: VALIDATE_INTERNALFORMAT(GL_RGB5_A1_OES) 258 default: return GL_INVALID_OPERATION; 259 } 260 break; 261 case GL_RGB: 262 switch(type) 263 { 264 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_RGB8_OES, GL_RGB565_OES) 265 case GL_UNSIGNED_SHORT_5_6_5: VALIDATE_INTERNALFORMAT(GL_RGB565_OES) 266 default: return GL_INVALID_OPERATION; 267 } 268 break; 269 case GL_DEPTH_STENCIL_OES: 270 switch(type) 271 { 272 case GL_UNSIGNED_INT_24_8_OES: VALIDATE_INTERNALFORMAT(GL_DEPTH24_STENCIL8_OES) 273 default: return GL_INVALID_OPERATION; 274 } 275 break; 276 case GL_LUMINANCE_ALPHA: 277 switch(type) 278 { 279 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_LUMINANCE8_ALPHA8_EXT) 280 default: 281 return GL_INVALID_OPERATION; 282 } 283 break; 284 case GL_LUMINANCE: 285 switch(type) 286 { 287 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_LUMINANCE8_EXT) 288 default: 289 return GL_INVALID_OPERATION; 290 } 291 break; 292 case GL_ALPHA: 293 switch(type) 294 { 295 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_ALPHA8_EXT) 296 default: 297 return GL_INVALID_OPERATION; 298 } 299 break; 300 case GL_BGRA_EXT: // GL_APPLE_texture_format_BGRA8888 301 switch(type) 302 { 303 case GL_UNSIGNED_BYTE: VALIDATE_INTERNALFORMAT(GL_BGRA8_EXT) 304 default: return GL_INVALID_OPERATION; 305 } 306 break; 307 default: 308 UNREACHABLE(format); 309 return GL_INVALID_ENUM; 310 } 311 312 #undef VALIDATE_INTERNALFORMAT 313 314 if(!validSizedInternalformat) 315 { 316 return GL_INVALID_OPERATION; 317 } 318 319 return GL_NO_ERROR; 320 } 321 IsColorRenderable(GLint internalformat)322 bool IsColorRenderable(GLint internalformat) 323 { 324 switch(internalformat) 325 { 326 case GL_RGBA4_OES: 327 case GL_RGB5_A1_OES: 328 case GL_RGB565_OES: 329 case GL_RGB8_OES: 330 case GL_RGBA8_OES: 331 return true; 332 case GL_DEPTH_COMPONENT16_OES: 333 case GL_STENCIL_INDEX8_OES: 334 case GL_DEPTH24_STENCIL8_OES: 335 return false; 336 default: 337 UNIMPLEMENTED(); 338 } 339 340 return false; 341 } 342 IsDepthRenderable(GLint internalformat)343 bool IsDepthRenderable(GLint internalformat) 344 { 345 switch(internalformat) 346 { 347 case GL_DEPTH_COMPONENT16_OES: 348 case GL_DEPTH24_STENCIL8_OES: 349 return true; 350 case GL_STENCIL_INDEX8_OES: 351 case GL_RGBA4_OES: 352 case GL_RGB5_A1_OES: 353 case GL_RGB565_OES: 354 case GL_RGB8_OES: 355 case GL_RGBA8_OES: 356 return false; 357 default: 358 UNIMPLEMENTED(); 359 } 360 361 return false; 362 } 363 IsStencilRenderable(GLint internalformat)364 bool IsStencilRenderable(GLint internalformat) 365 { 366 switch(internalformat) 367 { 368 case GL_STENCIL_INDEX8_OES: 369 case GL_DEPTH24_STENCIL8_OES: 370 return true; 371 case GL_RGBA4_OES: 372 case GL_RGB5_A1_OES: 373 case GL_RGB565_OES: 374 case GL_RGB8_OES: 375 case GL_RGBA8_OES: 376 case GL_DEPTH_COMPONENT16_OES: 377 return false; 378 default: 379 UNIMPLEMENTED(); 380 } 381 382 return false; 383 } 384 GetAlphaSize(GLint internalformat)385 GLuint GetAlphaSize(GLint internalformat) 386 { 387 switch(internalformat) 388 { 389 case GL_NONE_OES: return 0; 390 case GL_RGBA4_OES: return 4; 391 case GL_RGB5_A1_OES: return 1; 392 case GL_RGB565_OES: return 0; 393 case GL_RGB8_OES: return 0; 394 case GL_RGBA8_OES: return 8; 395 case GL_BGRA8_EXT: return 8; 396 default: 397 // UNREACHABLE(internalformat); 398 return 0; 399 } 400 } 401 GetRedSize(GLint internalformat)402 GLuint GetRedSize(GLint internalformat) 403 { 404 switch(internalformat) 405 { 406 case GL_NONE_OES: return 0; 407 case GL_RGBA4_OES: return 4; 408 case GL_RGB5_A1_OES: return 5; 409 case GL_RGB565_OES: return 5; 410 case GL_RGB8_OES: return 8; 411 case GL_RGBA8_OES: return 8; 412 case GL_BGRA8_EXT: return 8; 413 default: 414 // UNREACHABLE(internalformat); 415 return 0; 416 } 417 } 418 GetGreenSize(GLint internalformat)419 GLuint GetGreenSize(GLint internalformat) 420 { 421 switch(internalformat) 422 { 423 case GL_NONE_OES: return 0; 424 case GL_RGBA4_OES: return 4; 425 case GL_RGB5_A1_OES: return 5; 426 case GL_RGB565_OES: return 6; 427 case GL_RGB8_OES: return 8; 428 case GL_RGBA8_OES: return 8; 429 case GL_BGRA8_EXT: return 8; 430 default: 431 // UNREACHABLE(internalformat); 432 return 0; 433 } 434 } 435 GetBlueSize(GLint internalformat)436 GLuint GetBlueSize(GLint internalformat) 437 { 438 switch(internalformat) 439 { 440 case GL_NONE_OES: return 0; 441 case GL_RGBA4_OES: return 4; 442 case GL_RGB5_A1_OES: return 5; 443 case GL_RGB565_OES: return 5; 444 case GL_RGB8_OES: return 8; 445 case GL_RGBA8_OES: return 8; 446 case GL_BGRA8_EXT: return 8; 447 default: 448 // UNREACHABLE(internalformat); 449 return 0; 450 } 451 } 452 GetDepthSize(GLint internalformat)453 GLuint GetDepthSize(GLint internalformat) 454 { 455 switch(internalformat) 456 { 457 case GL_STENCIL_INDEX8_OES: return 0; 458 case GL_DEPTH_COMPONENT16_OES: return 16; 459 case GL_DEPTH24_STENCIL8_OES: return 24; 460 default: 461 // UNREACHABLE(internalformat); 462 return 0; 463 } 464 } 465 GetStencilSize(GLint internalformat)466 GLuint GetStencilSize(GLint internalformat) 467 { 468 switch(internalformat) 469 { 470 case GL_STENCIL_INDEX8_OES: return 8; 471 case GL_DEPTH_COMPONENT16_OES: return 0; 472 case GL_DEPTH24_STENCIL8_OES: return 8; 473 default: 474 // UNREACHABLE(internalformat); 475 return 0; 476 } 477 } 478 IsAlpha(GLint internalformat)479 bool IsAlpha(GLint internalformat) 480 { 481 switch(internalformat) 482 { 483 case GL_ALPHA8_EXT: 484 return true; 485 default: 486 return false; 487 } 488 } 489 IsRGB(GLint internalformat)490 bool IsRGB(GLint internalformat) 491 { 492 switch(internalformat) 493 { 494 case GL_LUMINANCE8_EXT: 495 case GL_RGB565_OES: 496 case GL_RGB8_OES: 497 case SW_YV12_BT601: 498 case SW_YV12_BT709: 499 case SW_YV12_JFIF: 500 return true; 501 default: 502 return false; 503 } 504 } 505 IsRGBA(GLint internalformat)506 bool IsRGBA(GLint internalformat) 507 { 508 switch(internalformat) 509 { 510 case GL_LUMINANCE8_ALPHA8_EXT: 511 case GL_RGBA: 512 case GL_BGRA8_EXT: // GL_EXT_texture_format_BGRA8888 513 case GL_RGBA4_OES: 514 case GL_RGB5_A1_OES: 515 case GL_RGBA8_OES: 516 return true; 517 default: 518 return false; 519 } 520 } 521 } 522 523 namespace es2sw 524 { ConvertDepthComparison(GLenum comparison)525 sw::DepthCompareMode ConvertDepthComparison(GLenum comparison) 526 { 527 switch(comparison) 528 { 529 case GL_NEVER: return sw::DEPTH_NEVER; 530 case GL_ALWAYS: return sw::DEPTH_ALWAYS; 531 case GL_LESS: return sw::DEPTH_LESS; 532 case GL_LEQUAL: return sw::DEPTH_LESSEQUAL; 533 case GL_EQUAL: return sw::DEPTH_EQUAL; 534 case GL_GREATER: return sw::DEPTH_GREATER; 535 case GL_GEQUAL: return sw::DEPTH_GREATEREQUAL; 536 case GL_NOTEQUAL: return sw::DEPTH_NOTEQUAL; 537 default: UNREACHABLE(comparison); 538 } 539 540 return sw::DEPTH_ALWAYS; 541 } 542 ConvertStencilComparison(GLenum comparison)543 sw::StencilCompareMode ConvertStencilComparison(GLenum comparison) 544 { 545 switch(comparison) 546 { 547 case GL_NEVER: return sw::STENCIL_NEVER; 548 case GL_ALWAYS: return sw::STENCIL_ALWAYS; 549 case GL_LESS: return sw::STENCIL_LESS; 550 case GL_LEQUAL: return sw::STENCIL_LESSEQUAL; 551 case GL_EQUAL: return sw::STENCIL_EQUAL; 552 case GL_GREATER: return sw::STENCIL_GREATER; 553 case GL_GEQUAL: return sw::STENCIL_GREATEREQUAL; 554 case GL_NOTEQUAL: return sw::STENCIL_NOTEQUAL; 555 default: UNREACHABLE(comparison); 556 } 557 558 return sw::STENCIL_ALWAYS; 559 } 560 ConvertAlphaComparison(GLenum comparison)561 sw::AlphaCompareMode ConvertAlphaComparison(GLenum comparison) 562 { 563 switch(comparison) 564 { 565 case GL_NEVER: return sw::ALPHA_NEVER; 566 case GL_ALWAYS: return sw::ALPHA_ALWAYS; 567 case GL_LESS: return sw::ALPHA_LESS; 568 case GL_LEQUAL: return sw::ALPHA_LESSEQUAL; 569 case GL_EQUAL: return sw::ALPHA_EQUAL; 570 case GL_GREATER: return sw::ALPHA_GREATER; 571 case GL_GEQUAL: return sw::ALPHA_GREATEREQUAL; 572 case GL_NOTEQUAL: return sw::ALPHA_NOTEQUAL; 573 default: UNREACHABLE(comparison); 574 } 575 576 return sw::ALPHA_ALWAYS; 577 } 578 ConvertColor(es1::Color color)579 sw::Color<float> ConvertColor(es1::Color color) 580 { 581 return sw::Color<float>(color.red, color.green, color.blue, color.alpha); 582 } 583 ConvertBlendFunc(GLenum blend)584 sw::BlendFactor ConvertBlendFunc(GLenum blend) 585 { 586 switch(blend) 587 { 588 case GL_ZERO: return sw::BLEND_ZERO; 589 case GL_ONE: return sw::BLEND_ONE; 590 case GL_SRC_COLOR: return sw::BLEND_SOURCE; 591 case GL_ONE_MINUS_SRC_COLOR: return sw::BLEND_INVSOURCE; 592 case GL_DST_COLOR: return sw::BLEND_DEST; 593 case GL_ONE_MINUS_DST_COLOR: return sw::BLEND_INVDEST; 594 case GL_SRC_ALPHA: return sw::BLEND_SOURCEALPHA; 595 case GL_ONE_MINUS_SRC_ALPHA: return sw::BLEND_INVSOURCEALPHA; 596 case GL_DST_ALPHA: return sw::BLEND_DESTALPHA; 597 case GL_ONE_MINUS_DST_ALPHA: return sw::BLEND_INVDESTALPHA; 598 case GL_SRC_ALPHA_SATURATE: return sw::BLEND_SRCALPHASAT; 599 default: UNREACHABLE(blend); 600 } 601 602 return sw::BLEND_ZERO; 603 } 604 ConvertBlendOp(GLenum blendOp)605 sw::BlendOperation ConvertBlendOp(GLenum blendOp) 606 { 607 switch(blendOp) 608 { 609 case GL_FUNC_ADD_OES: return sw::BLENDOP_ADD; 610 case GL_FUNC_SUBTRACT_OES: return sw::BLENDOP_SUB; 611 case GL_FUNC_REVERSE_SUBTRACT_OES: return sw::BLENDOP_INVSUB; 612 case GL_MIN_EXT: return sw::BLENDOP_MIN; 613 case GL_MAX_EXT: return sw::BLENDOP_MAX; 614 default: UNREACHABLE(blendOp); 615 } 616 617 return sw::BLENDOP_ADD; 618 } 619 ConvertLogicalOperation(GLenum logicalOperation)620 sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation) 621 { 622 switch(logicalOperation) 623 { 624 case GL_CLEAR: return sw::LOGICALOP_CLEAR; 625 case GL_SET: return sw::LOGICALOP_SET; 626 case GL_COPY: return sw::LOGICALOP_COPY; 627 case GL_COPY_INVERTED: return sw::LOGICALOP_COPY_INVERTED; 628 case GL_NOOP: return sw::LOGICALOP_NOOP; 629 case GL_INVERT: return sw::LOGICALOP_INVERT; 630 case GL_AND: return sw::LOGICALOP_AND; 631 case GL_NAND: return sw::LOGICALOP_NAND; 632 case GL_OR: return sw::LOGICALOP_OR; 633 case GL_NOR: return sw::LOGICALOP_NOR; 634 case GL_XOR: return sw::LOGICALOP_XOR; 635 case GL_EQUIV: return sw::LOGICALOP_EQUIV; 636 case GL_AND_REVERSE: return sw::LOGICALOP_AND_REVERSE; 637 case GL_AND_INVERTED: return sw::LOGICALOP_AND_INVERTED; 638 case GL_OR_REVERSE: return sw::LOGICALOP_OR_REVERSE; 639 case GL_OR_INVERTED: return sw::LOGICALOP_OR_INVERTED; 640 default: UNREACHABLE(logicalOperation); 641 } 642 643 return sw::LOGICALOP_COPY; 644 } 645 ConvertStencilOp(GLenum stencilOp)646 sw::StencilOperation ConvertStencilOp(GLenum stencilOp) 647 { 648 switch(stencilOp) 649 { 650 case GL_ZERO: return sw::OPERATION_ZERO; 651 case GL_KEEP: return sw::OPERATION_KEEP; 652 case GL_REPLACE: return sw::OPERATION_REPLACE; 653 case GL_INCR: return sw::OPERATION_INCRSAT; 654 case GL_DECR: return sw::OPERATION_DECRSAT; 655 case GL_INVERT: return sw::OPERATION_INVERT; 656 case GL_INCR_WRAP_OES: return sw::OPERATION_INCR; 657 case GL_DECR_WRAP_OES: return sw::OPERATION_DECR; 658 default: UNREACHABLE(stencilOp); 659 } 660 661 return sw::OPERATION_KEEP; 662 } 663 ConvertTextureWrap(GLenum wrap)664 sw::AddressingMode ConvertTextureWrap(GLenum wrap) 665 { 666 switch(wrap) 667 { 668 case GL_REPEAT: return sw::ADDRESSING_WRAP; 669 case GL_CLAMP_TO_EDGE: return sw::ADDRESSING_CLAMP; 670 case GL_MIRRORED_REPEAT_OES: return sw::ADDRESSING_MIRROR; 671 default: UNREACHABLE(wrap); 672 } 673 674 return sw::ADDRESSING_WRAP; 675 } 676 ConvertCullMode(GLenum cullFace,GLenum frontFace)677 sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace) 678 { 679 switch(cullFace) 680 { 681 case GL_FRONT: 682 return (frontFace == GL_CCW ? sw::CULL_CLOCKWISE : sw::CULL_COUNTERCLOCKWISE); 683 case GL_BACK: 684 return (frontFace == GL_CCW ? sw::CULL_COUNTERCLOCKWISE : sw::CULL_CLOCKWISE); 685 case GL_FRONT_AND_BACK: 686 return sw::CULL_NONE; // culling will be handled during draw 687 default: UNREACHABLE(cullFace); 688 } 689 690 return sw::CULL_COUNTERCLOCKWISE; 691 } 692 ConvertColorMask(bool red,bool green,bool blue,bool alpha)693 unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha) 694 { 695 return (red ? 0x00000001 : 0) | 696 (green ? 0x00000002 : 0) | 697 (blue ? 0x00000004 : 0) | 698 (alpha ? 0x00000008 : 0); 699 } 700 ConvertMipMapFilter(GLenum minFilter)701 sw::MipmapType ConvertMipMapFilter(GLenum minFilter) 702 { 703 switch(minFilter) 704 { 705 case GL_NEAREST: 706 case GL_LINEAR: 707 return sw::MIPMAP_NONE; 708 break; 709 case GL_NEAREST_MIPMAP_NEAREST: 710 case GL_LINEAR_MIPMAP_NEAREST: 711 return sw::MIPMAP_POINT; 712 break; 713 case GL_NEAREST_MIPMAP_LINEAR: 714 case GL_LINEAR_MIPMAP_LINEAR: 715 return sw::MIPMAP_LINEAR; 716 break; 717 default: 718 UNREACHABLE(minFilter); 719 return sw::MIPMAP_NONE; 720 } 721 } 722 ConvertTextureFilter(GLenum minFilter,GLenum magFilter,float maxAnisotropy)723 sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy) 724 { 725 if(maxAnisotropy > 1.0f) 726 { 727 return sw::FILTER_ANISOTROPIC; 728 } 729 730 sw::FilterType magFilterType = sw::FILTER_POINT; 731 switch(magFilter) 732 { 733 case GL_NEAREST: magFilterType = sw::FILTER_POINT; break; 734 case GL_LINEAR: magFilterType = sw::FILTER_LINEAR; break; 735 default: UNREACHABLE(magFilter); 736 } 737 738 switch(minFilter) 739 { 740 case GL_NEAREST: 741 case GL_NEAREST_MIPMAP_NEAREST: 742 case GL_NEAREST_MIPMAP_LINEAR: 743 return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR; 744 case GL_LINEAR: 745 case GL_LINEAR_MIPMAP_NEAREST: 746 case GL_LINEAR_MIPMAP_LINEAR: 747 return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_MIN_LINEAR_MAG_POINT : sw::FILTER_LINEAR; 748 default: 749 UNREACHABLE(minFilter); 750 return (magFilterType == sw::FILTER_POINT) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR; 751 } 752 } 753 ConvertPrimitiveType(GLenum primitiveType,GLsizei elementCount,GLenum elementType,sw::DrawType & drawType,int & primitiveCount)754 bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, GLenum elementType, sw::DrawType &drawType, int &primitiveCount) 755 { 756 switch(primitiveType) 757 { 758 case GL_POINTS: 759 drawType = sw::DRAW_POINTLIST; 760 primitiveCount = elementCount; 761 break; 762 case GL_LINES: 763 drawType = sw::DRAW_LINELIST; 764 primitiveCount = elementCount / 2; 765 break; 766 case GL_LINE_LOOP: 767 drawType = sw::DRAW_LINELOOP; 768 primitiveCount = elementCount; 769 break; 770 case GL_LINE_STRIP: 771 drawType = sw::DRAW_LINESTRIP; 772 primitiveCount = elementCount - 1; 773 break; 774 case GL_TRIANGLES: 775 drawType = sw::DRAW_TRIANGLELIST; 776 primitiveCount = elementCount / 3; 777 break; 778 case GL_TRIANGLE_STRIP: 779 drawType = sw::DRAW_TRIANGLESTRIP; 780 primitiveCount = elementCount - 2; 781 break; 782 case GL_TRIANGLE_FAN: 783 drawType = sw::DRAW_TRIANGLEFAN; 784 primitiveCount = elementCount - 2; 785 break; 786 default: 787 return false; 788 } 789 790 sw::DrawType elementSize; 791 switch(elementType) 792 { 793 case GL_NONE_OES: elementSize = sw::DRAW_NONINDEXED; break; 794 case GL_UNSIGNED_BYTE: elementSize = sw::DRAW_INDEXED8; break; 795 case GL_UNSIGNED_SHORT: elementSize = sw::DRAW_INDEXED16; break; 796 case GL_UNSIGNED_INT: elementSize = sw::DRAW_INDEXED32; break; 797 default: return false; 798 } 799 800 drawType = sw::DrawType(drawType | elementSize); 801 802 return true; 803 } 804 ConvertCombineOperation(GLenum operation)805 sw::TextureStage::StageOperation ConvertCombineOperation(GLenum operation) 806 { 807 switch(operation) 808 { 809 case GL_REPLACE: return sw::TextureStage::STAGE_SELECTARG1; 810 case GL_MODULATE: return sw::TextureStage::STAGE_MODULATE; 811 case GL_ADD: return sw::TextureStage::STAGE_ADD; 812 case GL_ADD_SIGNED: return sw::TextureStage::STAGE_ADDSIGNED; 813 case GL_INTERPOLATE: return sw::TextureStage::STAGE_LERP; 814 case GL_SUBTRACT: return sw::TextureStage::STAGE_SUBTRACT; 815 case GL_DOT3_RGB: return sw::TextureStage::STAGE_DOT3; 816 case GL_DOT3_RGBA: return sw::TextureStage::STAGE_DOT3; 817 default: UNREACHABLE(operation); return sw::TextureStage::STAGE_SELECTARG1; 818 } 819 } 820 ConvertSourceArgument(GLenum argument)821 sw::TextureStage::SourceArgument ConvertSourceArgument(GLenum argument) 822 { 823 switch(argument) 824 { 825 case GL_TEXTURE: return sw::TextureStage::SOURCE_TEXTURE; 826 case GL_CONSTANT: return sw::TextureStage::SOURCE_CONSTANT; 827 case GL_PRIMARY_COLOR: return sw::TextureStage::SOURCE_DIFFUSE; 828 case GL_PREVIOUS: return sw::TextureStage::SOURCE_CURRENT; 829 default: UNREACHABLE(argument); return sw::TextureStage::SOURCE_CURRENT; 830 } 831 } 832 ConvertSourceOperand(GLenum operand)833 sw::TextureStage::ArgumentModifier ConvertSourceOperand(GLenum operand) 834 { 835 switch(operand) 836 { 837 case GL_SRC_COLOR: return sw::TextureStage::MODIFIER_COLOR; 838 case GL_ONE_MINUS_SRC_COLOR: return sw::TextureStage::MODIFIER_INVCOLOR; 839 case GL_SRC_ALPHA: return sw::TextureStage::MODIFIER_ALPHA; 840 case GL_ONE_MINUS_SRC_ALPHA: return sw::TextureStage::MODIFIER_INVALPHA; 841 default: UNREACHABLE(operand); return sw::TextureStage::MODIFIER_COLOR; 842 } 843 } 844 } 845 846 namespace sw2es 847 { ConvertBackBufferFormat(sw::Format format)848 GLenum ConvertBackBufferFormat(sw::Format format) 849 { 850 switch(format) 851 { 852 case sw::FORMAT_A4R4G4B4: return GL_RGBA4_OES; 853 case sw::FORMAT_A8R8G8B8: return GL_RGBA8_OES; 854 case sw::FORMAT_A8B8G8R8: return GL_RGBA8_OES; 855 case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1_OES; 856 case sw::FORMAT_R5G6B5: return GL_RGB565_OES; 857 case sw::FORMAT_X8R8G8B8: return GL_RGB8_OES; 858 case sw::FORMAT_X8B8G8R8: return GL_RGB8_OES; 859 default: 860 UNREACHABLE(format); 861 } 862 863 return GL_RGBA4_OES; 864 } 865 ConvertDepthStencilFormat(sw::Format format)866 GLenum ConvertDepthStencilFormat(sw::Format format) 867 { 868 switch(format) 869 { 870 case sw::FORMAT_D16: 871 case sw::FORMAT_D24X8: 872 case sw::FORMAT_D32: 873 return GL_DEPTH_COMPONENT16_OES; 874 case sw::FORMAT_D24S8: 875 return GL_DEPTH24_STENCIL8_OES; 876 default: 877 UNREACHABLE(format); 878 } 879 880 return GL_DEPTH24_STENCIL8_OES; 881 } 882 } 883