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 26namespace gl 27{ 28 unsigned int UniformComponentCount(GLenum type) 29 { 30 switch(type) 31 { 32 case GL_BOOL: 33 case GL_FLOAT: 34 case GL_INT: 35 case GL_SAMPLER_2D: 36 case GL_SAMPLER_CUBE: 37 return 1; 38 case GL_BOOL_VEC2: 39 case GL_FLOAT_VEC2: 40 case GL_INT_VEC2: 41 return 2; 42 case GL_INT_VEC3: 43 case GL_FLOAT_VEC3: 44 case GL_BOOL_VEC3: 45 return 3; 46 case GL_BOOL_VEC4: 47 case GL_FLOAT_VEC4: 48 case GL_INT_VEC4: 49 case GL_FLOAT_MAT2: 50 return 4; 51 case GL_FLOAT_MAT3: 52 return 9; 53 case GL_FLOAT_MAT4: 54 return 16; 55 default: 56 UNREACHABLE(type); 57 } 58 59 return 0; 60 } 61 62 GLenum UniformComponentType(GLenum type) 63 { 64 switch(type) 65 { 66 case GL_BOOL: 67 case GL_BOOL_VEC2: 68 case GL_BOOL_VEC3: 69 case GL_BOOL_VEC4: 70 return GL_BOOL; 71 case GL_FLOAT: 72 case GL_FLOAT_VEC2: 73 case GL_FLOAT_VEC3: 74 case GL_FLOAT_VEC4: 75 case GL_FLOAT_MAT2: 76 case GL_FLOAT_MAT3: 77 case GL_FLOAT_MAT4: 78 return GL_FLOAT; 79 case GL_INT: 80 case GL_SAMPLER_2D: 81 case GL_SAMPLER_CUBE: 82 case GL_INT_VEC2: 83 case GL_INT_VEC3: 84 case GL_INT_VEC4: 85 return GL_INT; 86 default: 87 UNREACHABLE(type); 88 } 89 90 return GL_NONE; 91 } 92 93 size_t UniformTypeSize(GLenum type) 94 { 95 switch(type) 96 { 97 case GL_BOOL: return sizeof(GLboolean); 98 case GL_FLOAT: return sizeof(GLfloat); 99 case GL_INT: return sizeof(GLint); 100 } 101 102 return UniformTypeSize(UniformComponentType(type)) * UniformComponentCount(type); 103 } 104 105 int VariableRowCount(GLenum type) 106 { 107 switch(type) 108 { 109 case GL_NONE: 110 return 0; 111 case GL_BOOL: 112 case GL_FLOAT: 113 case GL_INT: 114 case GL_BOOL_VEC2: 115 case GL_FLOAT_VEC2: 116 case GL_INT_VEC2: 117 case GL_INT_VEC3: 118 case GL_FLOAT_VEC3: 119 case GL_BOOL_VEC3: 120 case GL_BOOL_VEC4: 121 case GL_FLOAT_VEC4: 122 case GL_INT_VEC4: 123 case GL_SAMPLER_2D: 124 case GL_SAMPLER_CUBE: 125 return 1; 126 case GL_FLOAT_MAT2: 127 return 2; 128 case GL_FLOAT_MAT3: 129 return 3; 130 case GL_FLOAT_MAT4: 131 return 4; 132 default: 133 UNREACHABLE(type); 134 } 135 136 return 0; 137 } 138 139 int VariableColumnCount(GLenum type) 140 { 141 switch(type) 142 { 143 case GL_NONE: 144 return 0; 145 case GL_BOOL: 146 case GL_FLOAT: 147 case GL_INT: 148 return 1; 149 case GL_BOOL_VEC2: 150 case GL_FLOAT_VEC2: 151 case GL_INT_VEC2: 152 case GL_FLOAT_MAT2: 153 return 2; 154 case GL_INT_VEC3: 155 case GL_FLOAT_VEC3: 156 case GL_BOOL_VEC3: 157 case GL_FLOAT_MAT3: 158 return 3; 159 case GL_BOOL_VEC4: 160 case GL_FLOAT_VEC4: 161 case GL_INT_VEC4: 162 case GL_FLOAT_MAT4: 163 return 4; 164 default: 165 UNREACHABLE(type); 166 } 167 168 return 0; 169 } 170 171 int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize) 172 { 173 ASSERT(allocationSize <= bitsSize); 174 175 unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize); 176 177 for(unsigned int i = 0; i < bitsSize - allocationSize + 1; i++) 178 { 179 if((*bits & mask) == 0) 180 { 181 *bits |= mask; 182 return i; 183 } 184 185 mask <<= 1; 186 } 187 188 return -1; 189 } 190 191 GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment) 192 { 193 ASSERT(alignment > 0 && isPow2(alignment)); 194 195 GLsizei rawPitch = ComputePixelSize(format, type) * width; 196 return (rawPitch + alignment - 1) & ~(alignment - 1); 197 } 198 199 GLsizei ComputeCompressedPitch(GLsizei width, GLenum format) 200 { 201 return ComputeCompressedSize(width, 1, format); 202 } 203 204 GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format) 205 { 206 switch(format) 207 { 208 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 209 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 210 return 8 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f); 211 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 212 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: 213 return 16 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f); 214 default: 215 return 0; 216 } 217 } 218 219 bool IsCompressed(GLenum format) 220 { 221 return format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || 222 format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || 223 format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT || 224 format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; 225 } 226 227 bool IsDepthTexture(GLenum format) 228 { 229 return format == GL_DEPTH_COMPONENT || 230 format == GL_DEPTH_STENCIL_EXT; 231 } 232 233 bool IsStencilTexture(GLenum format) 234 { 235 return format == GL_STENCIL_INDEX || 236 format == GL_DEPTH_STENCIL_EXT; 237 } 238 239 // Returns the size, in bytes, of a single texel in an Image 240 int ComputePixelSize(GLenum format, GLenum type) 241 { 242 switch(type) 243 { 244 case GL_UNSIGNED_BYTE: 245 switch(format) 246 { 247 case GL_ALPHA: return sizeof(unsigned char); 248 case GL_LUMINANCE: return sizeof(unsigned char); 249 case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2; 250 case GL_RGB: return sizeof(unsigned char) * 3; 251 case GL_RGBA: return sizeof(unsigned char) * 4; 252 case GL_BGRA_EXT: return sizeof(unsigned char) * 4; 253 default: UNREACHABLE(format); 254 } 255 break; 256 case GL_UNSIGNED_SHORT_4_4_4_4: 257 case GL_UNSIGNED_SHORT_5_5_5_1: 258 case GL_UNSIGNED_SHORT_5_6_5: 259 case GL_UNSIGNED_SHORT: 260 return sizeof(unsigned short); 261 case GL_UNSIGNED_INT: 262 case GL_UNSIGNED_INT_24_8_EXT: 263 case GL_UNSIGNED_INT_8_8_8_8_REV: 264 return sizeof(unsigned int); 265 case GL_FLOAT: 266 switch(format) 267 { 268 case GL_ALPHA: return sizeof(float); 269 case GL_LUMINANCE: return sizeof(float); 270 case GL_DEPTH_COMPONENT: return sizeof(float); 271 case GL_LUMINANCE_ALPHA: return sizeof(float) * 2; 272 case GL_RGB: return sizeof(float) * 3; 273 case GL_RGBA: return sizeof(float) * 4; 274 default: UNREACHABLE(format); 275 } 276 break; 277 case GL_HALF_FLOAT: 278 switch(format) 279 { 280 case GL_ALPHA: return sizeof(unsigned short); 281 case GL_LUMINANCE: return sizeof(unsigned short); 282 case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2; 283 case GL_RGB: return sizeof(unsigned short) * 3; 284 case GL_RGBA: return sizeof(unsigned short) * 4; 285 default: UNREACHABLE(format); 286 } 287 break; 288 default: UNREACHABLE(type); 289 } 290 291 return 0; 292 } 293 294 bool IsCubemapTextureTarget(GLenum target) 295 { 296 return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z); 297 } 298 299 int CubeFaceIndex(GLenum cubeFace) 300 { 301 switch(cubeFace) 302 { 303 case GL_TEXTURE_CUBE_MAP: 304 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: return 0; 305 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: return 1; 306 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: return 2; 307 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: return 3; 308 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: return 4; 309 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: return 5; 310 default: UNREACHABLE(cubeFace); return 0; 311 } 312 } 313 314 bool IsTextureTarget(GLenum target) 315 { 316 return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target); 317 } 318 319 // Verify that format/type are one of the combinations from table 3.4. 320 bool CheckTextureFormatType(GLenum format, GLenum type) 321 { 322 switch(type) 323 { 324 case GL_UNSIGNED_BYTE: 325 switch(format) 326 { 327 case GL_RGBA: 328 case GL_BGRA_EXT: 329 case GL_RGB: 330 case GL_ALPHA: 331 case GL_LUMINANCE: 332 case GL_LUMINANCE_ALPHA: 333 return true; 334 default: 335 return false; 336 } 337 case GL_FLOAT: 338 case GL_HALF_FLOAT: 339 switch(format) 340 { 341 case GL_RGBA: 342 case GL_RGB: 343 case GL_ALPHA: 344 case GL_LUMINANCE: 345 case GL_LUMINANCE_ALPHA: 346 return true; 347 default: 348 return false; 349 } 350 case GL_UNSIGNED_SHORT_4_4_4_4: 351 case GL_UNSIGNED_SHORT_5_5_5_1: 352 return (format == GL_RGBA); 353 case GL_UNSIGNED_SHORT_5_6_5: 354 return (format == GL_RGB); 355 case GL_UNSIGNED_INT: 356 return (format == GL_DEPTH_COMPONENT); 357 case GL_UNSIGNED_INT_24_8_EXT: 358 return (format == GL_DEPTH_STENCIL_EXT); 359 case GL_UNSIGNED_INT_8_8_8_8_REV: 360 return (format == GL_BGRA); 361 default: 362 return false; 363 } 364 } 365 366 bool IsColorRenderable(GLenum internalformat) 367 { 368 switch(internalformat) 369 { 370 case GL_RGBA4: 371 case GL_RGB5_A1: 372 case GL_RGB565: 373 case GL_RGB8_EXT: 374 case GL_RGBA8_EXT: 375 return true; 376 case GL_DEPTH_COMPONENT16: 377 case GL_DEPTH_COMPONENT24: 378 case GL_STENCIL_INDEX8: 379 case GL_DEPTH24_STENCIL8_EXT: 380 return false; 381 default: 382 UNIMPLEMENTED(); 383 } 384 385 return false; 386 } 387 388 bool IsDepthRenderable(GLenum internalformat) 389 { 390 switch(internalformat) 391 { 392 case GL_DEPTH_COMPONENT16: 393 case GL_DEPTH_COMPONENT24: 394 case GL_DEPTH24_STENCIL8_EXT: 395 return true; 396 case GL_STENCIL_INDEX8: 397 case GL_RGBA4: 398 case GL_RGB5_A1: 399 case GL_RGB565: 400 case GL_RGB8_EXT: 401 case GL_RGBA8_EXT: 402 return false; 403 default: 404 UNIMPLEMENTED(); 405 } 406 407 return false; 408 } 409 410 bool IsStencilRenderable(GLenum internalformat) 411 { 412 switch(internalformat) 413 { 414 case GL_STENCIL_INDEX8: 415 case GL_DEPTH24_STENCIL8_EXT: 416 return true; 417 case GL_RGBA4: 418 case GL_RGB5_A1: 419 case GL_RGB565: 420 case GL_RGB8_EXT: 421 case GL_RGBA8_EXT: 422 case GL_DEPTH_COMPONENT16: 423 case GL_DEPTH_COMPONENT24: 424 return false; 425 default: 426 UNIMPLEMENTED(); 427 } 428 429 return false; 430 } 431} 432 433namespace es2sw 434{ 435 sw::DepthCompareMode ConvertDepthComparison(GLenum comparison) 436 { 437 switch(comparison) 438 { 439 case GL_NEVER: return sw::DEPTH_NEVER; 440 case GL_ALWAYS: return sw::DEPTH_ALWAYS; 441 case GL_LESS: return sw::DEPTH_LESS; 442 case GL_LEQUAL: return sw::DEPTH_LESSEQUAL; 443 case GL_EQUAL: return sw::DEPTH_EQUAL; 444 case GL_GREATER: return sw::DEPTH_GREATER; 445 case GL_GEQUAL: return sw::DEPTH_GREATEREQUAL; 446 case GL_NOTEQUAL: return sw::DEPTH_NOTEQUAL; 447 default: UNREACHABLE(comparison); 448 } 449 450 return sw::DEPTH_ALWAYS; 451 } 452 453 sw::StencilCompareMode ConvertStencilComparison(GLenum comparison) 454 { 455 switch(comparison) 456 { 457 case GL_NEVER: return sw::STENCIL_NEVER; 458 case GL_ALWAYS: return sw::STENCIL_ALWAYS; 459 case GL_LESS: return sw::STENCIL_LESS; 460 case GL_LEQUAL: return sw::STENCIL_LESSEQUAL; 461 case GL_EQUAL: return sw::STENCIL_EQUAL; 462 case GL_GREATER: return sw::STENCIL_GREATER; 463 case GL_GEQUAL: return sw::STENCIL_GREATEREQUAL; 464 case GL_NOTEQUAL: return sw::STENCIL_NOTEQUAL; 465 default: UNREACHABLE(comparison); 466 } 467 468 return sw::STENCIL_ALWAYS; 469 } 470 471 sw::Color<float> ConvertColor(gl::Color color) 472 { 473 return sw::Color<float>(color.red, color.green, color.blue, color.alpha); 474 } 475 476 sw::BlendFactor ConvertBlendFunc(GLenum blend) 477 { 478 switch(blend) 479 { 480 case GL_ZERO: return sw::BLEND_ZERO; 481 case GL_ONE: return sw::BLEND_ONE; 482 case GL_SRC_COLOR: return sw::BLEND_SOURCE; 483 case GL_ONE_MINUS_SRC_COLOR: return sw::BLEND_INVSOURCE; 484 case GL_DST_COLOR: return sw::BLEND_DEST; 485 case GL_ONE_MINUS_DST_COLOR: return sw::BLEND_INVDEST; 486 case GL_SRC_ALPHA: return sw::BLEND_SOURCEALPHA; 487 case GL_ONE_MINUS_SRC_ALPHA: return sw::BLEND_INVSOURCEALPHA; 488 case GL_DST_ALPHA: return sw::BLEND_DESTALPHA; 489 case GL_ONE_MINUS_DST_ALPHA: return sw::BLEND_INVDESTALPHA; 490 case GL_CONSTANT_COLOR: return sw::BLEND_CONSTANT; 491 case GL_ONE_MINUS_CONSTANT_COLOR: return sw::BLEND_INVCONSTANT; 492 case GL_CONSTANT_ALPHA: return sw::BLEND_CONSTANTALPHA; 493 case GL_ONE_MINUS_CONSTANT_ALPHA: return sw::BLEND_INVCONSTANTALPHA; 494 case GL_SRC_ALPHA_SATURATE: return sw::BLEND_SRCALPHASAT; 495 default: UNREACHABLE(blend); 496 } 497 498 return sw::BLEND_ZERO; 499 } 500 501 sw::BlendOperation ConvertBlendOp(GLenum blendOp) 502 { 503 switch(blendOp) 504 { 505 case GL_FUNC_ADD: return sw::BLENDOP_ADD; 506 case GL_FUNC_SUBTRACT: return sw::BLENDOP_SUB; 507 case GL_FUNC_REVERSE_SUBTRACT: return sw::BLENDOP_INVSUB; 508 case GL_MIN_EXT: return sw::BLENDOP_MIN; 509 case GL_MAX_EXT: return sw::BLENDOP_MAX; 510 default: UNREACHABLE(blendOp); 511 } 512 513 return sw::BLENDOP_ADD; 514 } 515 516 sw::LogicalOperation ConvertLogicalOperation(GLenum logicalOperation) 517 { 518 switch(logicalOperation) 519 { 520 case GL_CLEAR: return sw::LOGICALOP_CLEAR; 521 case GL_SET: return sw::LOGICALOP_SET; 522 case GL_COPY: return sw::LOGICALOP_COPY; 523 case GL_COPY_INVERTED: return sw::LOGICALOP_COPY_INVERTED; 524 case GL_NOOP: return sw::LOGICALOP_NOOP; 525 case GL_INVERT: return sw::LOGICALOP_INVERT; 526 case GL_AND: return sw::LOGICALOP_AND; 527 case GL_NAND: return sw::LOGICALOP_NAND; 528 case GL_OR: return sw::LOGICALOP_OR; 529 case GL_NOR: return sw::LOGICALOP_NOR; 530 case GL_XOR: return sw::LOGICALOP_XOR; 531 case GL_EQUIV: return sw::LOGICALOP_EQUIV; 532 case GL_AND_REVERSE: return sw::LOGICALOP_AND_REVERSE; 533 case GL_AND_INVERTED: return sw::LOGICALOP_AND_INVERTED; 534 case GL_OR_REVERSE: return sw::LOGICALOP_OR_REVERSE; 535 case GL_OR_INVERTED: return sw::LOGICALOP_OR_INVERTED; 536 default: UNREACHABLE(logicalOperation); 537 } 538 539 return sw::LOGICALOP_COPY; 540 } 541 542 sw::StencilOperation ConvertStencilOp(GLenum stencilOp) 543 { 544 switch(stencilOp) 545 { 546 case GL_ZERO: return sw::OPERATION_ZERO; 547 case GL_KEEP: return sw::OPERATION_KEEP; 548 case GL_REPLACE: return sw::OPERATION_REPLACE; 549 case GL_INCR: return sw::OPERATION_INCRSAT; 550 case GL_DECR: return sw::OPERATION_DECRSAT; 551 case GL_INVERT: return sw::OPERATION_INVERT; 552 case GL_INCR_WRAP: return sw::OPERATION_INCR; 553 case GL_DECR_WRAP: return sw::OPERATION_DECR; 554 default: UNREACHABLE(stencilOp); 555 } 556 557 return sw::OPERATION_KEEP; 558 } 559 560 sw::AddressingMode ConvertTextureWrap(GLenum wrap) 561 { 562 switch(wrap) 563 { 564 case GL_CLAMP: return sw::ADDRESSING_CLAMP; 565 case GL_REPEAT: return sw::ADDRESSING_WRAP; 566 case GL_CLAMP_TO_EDGE: return sw::ADDRESSING_CLAMP; 567 case GL_MIRRORED_REPEAT: return sw::ADDRESSING_MIRROR; 568 default: UNREACHABLE(wrap); 569 } 570 571 return sw::ADDRESSING_WRAP; 572 } 573 574 sw::CullMode ConvertCullMode(GLenum cullFace, GLenum frontFace) 575 { 576 switch(cullFace) 577 { 578 case GL_FRONT: 579 return (frontFace == GL_CCW ? sw::CULL_CLOCKWISE : sw::CULL_COUNTERCLOCKWISE); 580 case GL_BACK: 581 return (frontFace == GL_CCW ? sw::CULL_COUNTERCLOCKWISE : sw::CULL_CLOCKWISE); 582 case GL_FRONT_AND_BACK: 583 return sw::CULL_NONE; // culling will be handled during draw 584 default: UNREACHABLE(cullFace); 585 } 586 587 return sw::CULL_COUNTERCLOCKWISE; 588 } 589 590 unsigned int ConvertColorMask(bool red, bool green, bool blue, bool alpha) 591 { 592 return (red ? 0x00000001 : 0) | 593 (green ? 0x00000002 : 0) | 594 (blue ? 0x00000004 : 0) | 595 (alpha ? 0x00000008 : 0); 596 } 597 598 sw::MipmapType ConvertMipMapFilter(GLenum minFilter) 599 { 600 switch(minFilter) 601 { 602 case GL_NEAREST: 603 case GL_LINEAR: 604 return sw::MIPMAP_NONE; 605 break; 606 case GL_NEAREST_MIPMAP_NEAREST: 607 case GL_LINEAR_MIPMAP_NEAREST: 608 return sw::MIPMAP_POINT; 609 break; 610 case GL_NEAREST_MIPMAP_LINEAR: 611 case GL_LINEAR_MIPMAP_LINEAR: 612 return sw::MIPMAP_LINEAR; 613 break; 614 default: 615 UNREACHABLE(minFilter); 616 return sw::MIPMAP_NONE; 617 } 618 } 619 620 sw::FilterType ConvertTextureFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy) 621 { 622 if(maxAnisotropy > 1.0f) 623 { 624 return sw::FILTER_ANISOTROPIC; 625 } 626 627 switch(minFilter) 628 { 629 case GL_NEAREST: 630 case GL_NEAREST_MIPMAP_NEAREST: 631 case GL_NEAREST_MIPMAP_LINEAR: 632 return (magFilter == GL_NEAREST) ? sw::FILTER_POINT : sw::FILTER_MIN_POINT_MAG_LINEAR; 633 case GL_LINEAR: 634 case GL_LINEAR_MIPMAP_NEAREST: 635 case GL_LINEAR_MIPMAP_LINEAR: 636 return (magFilter == GL_NEAREST) ? sw::FILTER_MIN_LINEAR_MAG_POINT : sw::FILTER_LINEAR; 637 default: 638 UNREACHABLE(minFilter); 639 return sw::FILTER_LINEAR; 640 } 641 } 642 643 bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, gl::PrimitiveType &swPrimitiveType, int &primitiveCount) 644 { 645 switch(primitiveType) 646 { 647 case GL_POINTS: 648 swPrimitiveType = gl::DRAW_POINTLIST; 649 primitiveCount = elementCount; 650 break; 651 case GL_LINES: 652 swPrimitiveType = gl::DRAW_LINELIST; 653 primitiveCount = elementCount / 2; 654 break; 655 case GL_LINE_LOOP: 656 swPrimitiveType = gl::DRAW_LINELOOP; 657 primitiveCount = elementCount; 658 break; 659 case GL_LINE_STRIP: 660 swPrimitiveType = gl::DRAW_LINESTRIP; 661 primitiveCount = elementCount - 1; 662 break; 663 case GL_TRIANGLES: 664 swPrimitiveType = gl::DRAW_TRIANGLELIST; 665 primitiveCount = elementCount / 3; 666 break; 667 case GL_TRIANGLE_STRIP: 668 swPrimitiveType = gl::DRAW_TRIANGLESTRIP; 669 primitiveCount = elementCount - 2; 670 break; 671 case GL_TRIANGLE_FAN: 672 swPrimitiveType = gl::DRAW_TRIANGLEFAN; 673 primitiveCount = elementCount - 2; 674 break; 675 case GL_QUADS: 676 swPrimitiveType = gl::DRAW_QUADLIST; 677 primitiveCount = (elementCount / 4) * 2; 678 break; 679 default: 680 return false; 681 } 682 683 return true; 684 } 685 686 sw::Format ConvertRenderbufferFormat(GLenum format) 687 { 688 switch(format) 689 { 690 case GL_RGBA4: 691 case GL_RGB5_A1: 692 case GL_RGBA8_EXT: return sw::FORMAT_A8R8G8B8; 693 case GL_RGB565: return sw::FORMAT_R5G6B5; 694 case GL_RGB8_EXT: return sw::FORMAT_X8R8G8B8; 695 case GL_DEPTH_COMPONENT16: 696 case GL_DEPTH_COMPONENT24: 697 case GL_STENCIL_INDEX8: 698 case GL_DEPTH24_STENCIL8_EXT: return sw::FORMAT_D24S8; 699 default: UNREACHABLE(format); return sw::FORMAT_A8R8G8B8; 700 } 701 } 702} 703 704namespace sw2es 705{ 706 unsigned int GetStencilSize(sw::Format stencilFormat) 707 { 708 switch(stencilFormat) 709 { 710 case sw::FORMAT_D24FS8: 711 case sw::FORMAT_D24S8: 712 case sw::FORMAT_D32FS8_TEXTURE: 713 return 8; 714 // case sw::FORMAT_D24X4S4: 715 // return 4; 716 // case sw::FORMAT_D15S1: 717 // return 1; 718 // case sw::FORMAT_D16_LOCKABLE: 719 case sw::FORMAT_D32: 720 case sw::FORMAT_D24X8: 721 case sw::FORMAT_D32F_LOCKABLE: 722 case sw::FORMAT_D16: 723 return 0; 724 // case sw::FORMAT_D32_LOCKABLE: return 0; 725 // case sw::FORMAT_S8_LOCKABLE: return 8; 726 default: 727 return 0; 728 } 729 } 730 731 unsigned int GetAlphaSize(sw::Format colorFormat) 732 { 733 switch(colorFormat) 734 { 735 case sw::FORMAT_A16B16G16R16F: 736 return 16; 737 case sw::FORMAT_A32B32G32R32F: 738 return 32; 739 case sw::FORMAT_A2R10G10B10: 740 return 2; 741 case sw::FORMAT_A8R8G8B8: 742 return 8; 743 case sw::FORMAT_A1R5G5B5: 744 return 1; 745 case sw::FORMAT_X8R8G8B8: 746 case sw::FORMAT_R5G6B5: 747 return 0; 748 default: 749 return 0; 750 } 751 } 752 753 unsigned int GetRedSize(sw::Format colorFormat) 754 { 755 switch(colorFormat) 756 { 757 case sw::FORMAT_A16B16G16R16F: 758 return 16; 759 case sw::FORMAT_A32B32G32R32F: 760 return 32; 761 case sw::FORMAT_A2R10G10B10: 762 return 10; 763 case sw::FORMAT_A8R8G8B8: 764 case sw::FORMAT_X8R8G8B8: 765 return 8; 766 case sw::FORMAT_A1R5G5B5: 767 case sw::FORMAT_R5G6B5: 768 return 5; 769 default: 770 return 0; 771 } 772 } 773 774 unsigned int GetGreenSize(sw::Format colorFormat) 775 { 776 switch(colorFormat) 777 { 778 case sw::FORMAT_A16B16G16R16F: 779 return 16; 780 case sw::FORMAT_A32B32G32R32F: 781 return 32; 782 case sw::FORMAT_A2R10G10B10: 783 return 10; 784 case sw::FORMAT_A8R8G8B8: 785 case sw::FORMAT_X8R8G8B8: 786 return 8; 787 case sw::FORMAT_A1R5G5B5: 788 return 5; 789 case sw::FORMAT_R5G6B5: 790 return 6; 791 default: 792 return 0; 793 } 794 } 795 796 unsigned int GetBlueSize(sw::Format colorFormat) 797 { 798 switch(colorFormat) 799 { 800 case sw::FORMAT_A16B16G16R16F: 801 return 16; 802 case sw::FORMAT_A32B32G32R32F: 803 return 32; 804 case sw::FORMAT_A2R10G10B10: 805 return 10; 806 case sw::FORMAT_A8R8G8B8: 807 case sw::FORMAT_X8R8G8B8: 808 return 8; 809 case sw::FORMAT_A1R5G5B5: 810 case sw::FORMAT_R5G6B5: 811 return 5; 812 default: 813 return 0; 814 } 815 } 816 817 unsigned int GetDepthSize(sw::Format depthFormat) 818 { 819 switch(depthFormat) 820 { 821 // case sw::FORMAT_D16_LOCKABLE: return 16; 822 case sw::FORMAT_D32: return 32; 823 // case sw::FORMAT_D15S1: return 15; 824 case sw::FORMAT_D24S8: return 24; 825 case sw::FORMAT_D24X8: return 24; 826 // case sw::FORMAT_D24X4S4: return 24; 827 case sw::FORMAT_D16: return 16; 828 case sw::FORMAT_D32F_LOCKABLE: return 32; 829 case sw::FORMAT_D24FS8: return 24; 830 // case sw::FORMAT_D32_LOCKABLE: return 32; 831 // case sw::FORMAT_S8_LOCKABLE: return 0; 832 case sw::FORMAT_D32FS8_TEXTURE: return 32; 833 default: return 0; 834 } 835 } 836 837 GLenum ConvertBackBufferFormat(sw::Format format) 838 { 839 switch(format) 840 { 841 case sw::FORMAT_A4R4G4B4: return GL_RGBA4; 842 case sw::FORMAT_A8R8G8B8: return GL_RGBA8_EXT; 843 case sw::FORMAT_A1R5G5B5: return GL_RGB5_A1; 844 case sw::FORMAT_R5G6B5: return GL_RGB565; 845 case sw::FORMAT_X8R8G8B8: return GL_RGB8_EXT; 846 default: 847 UNREACHABLE(format); 848 } 849 850 return GL_RGBA4; 851 } 852 853 GLenum ConvertDepthStencilFormat(sw::Format format) 854 { 855 switch(format) 856 { 857 case sw::FORMAT_D16: 858 return GL_DEPTH_COMPONENT16; 859 case sw::FORMAT_D32: 860 return GL_DEPTH_COMPONENT32; 861 case sw::FORMAT_D24X8: 862 return GL_DEPTH_COMPONENT24; 863 case sw::FORMAT_D24S8: 864 return GL_DEPTH24_STENCIL8_EXT; 865 default: 866 UNREACHABLE(format); 867 } 868 869 return GL_DEPTH24_STENCIL8_EXT; 870 } 871} 872