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