1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: gr_Utility.h 4 5 Copyright (C)2010 Nintendo Co., Ltd. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Rev: 33660 $ 14 *---------------------------------------------------------------------------*/ 15 16 #ifndef NN_GR_UTILITY_H_ 17 #define NN_GR_UTILITY_H_ 18 19 #include <nn.h> 20 #include <nn/types.h> 21 #include <nn/gx.h> 22 #include <nn/gx/CTR/gx_CommandAccess.h> 23 24 #include <nn/gr/CTR/gr_Prefix.h> 25 26 namespace nn 27 { 28 namespace gr 29 { 30 namespace CTR 31 { 32 33 //------------------------------------------------------------------------------ 34 35 /* Please see man pages for details 36 37 38 39 40 41 */ 42 void CopyMtx34WithHeader( 43 f32* dst, 44 const nn::math::MTX34* src, 45 bit32 header ); 46 47 /* Please see man pages for details 48 49 50 51 52 53 */ 54 void CopyMtx44WithHeader( 55 f32* dst, 56 const nn::math::MTX44* src, 57 bit32 header ); 58 59 //------------------------------------------------------------------------------------ 60 61 /* Please see man pages for details 62 63 64 65 66 67 68 69 */ MakeUniformCommandVS(bit32 * command,u8 location,const nn::math::MTX34 & mtx34)70 inline bit32* MakeUniformCommandVS( bit32* command, u8 location, const nn::math::MTX34& mtx34 ) 71 { 72 *command++ = 0x80000000 | location; 73 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_VS_FLOAT_ADDR ); 74 CopyMtx34WithHeader( reinterpret_cast<f32*>( command ), &mtx34, PICA_CMD_HEADER_VS_F32( 3 ) ); 75 return command + 14; 76 } 77 78 //------------------------------------------------------------------------------------ 79 80 /* Please see man pages for details 81 82 83 84 85 86 87 88 */ MakeUniformCommandVS(bit32 * command,u8 location,const nn::math::MTX44 & mtx44)89 inline bit32* MakeUniformCommandVS( bit32* command, u8 location, const nn::math::MTX44& mtx44 ) 90 { 91 *command++ = 0x80000000 | location; 92 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_VS_FLOAT_ADDR ); 93 CopyMtx44WithHeader( reinterpret_cast<f32*>( command ), &mtx44, PICA_CMD_HEADER_VS_F32( 4 ) ); 94 return command + 18; 95 } 96 97 //------------------------------------------------------------------------------------ 98 99 /* Please see man pages for details 100 101 102 103 104 105 106 107 */ MakeUniformCommandVS(bit32 * command,u8 location,const nn::math::VEC4 & vec4)108 inline bit32* MakeUniformCommandVS( bit32* command, u8 location, const nn::math::VEC4& vec4 ) 109 { 110 *command++ = 0x80000000 | location; 111 *command++ = PICA_CMD_HEADER_BURSTSEQ( PICA_REG_VS_FLOAT_ADDR, 5 ); 112 *command++ = nn::math::F32AsU32( vec4.w ); 113 *command++ = nn::math::F32AsU32( vec4.z ); 114 *command++ = nn::math::F32AsU32( vec4.y ); 115 *command++ = nn::math::F32AsU32( vec4.x ); 116 return command; 117 } 118 119 120 //------------------------------------------------------------------------------------ 121 122 /* Please see man pages for details 123 124 125 126 127 128 129 130 131 */ MakeUniformCommandVS(bit32 * command,u8 location,const nn::math::VEC4 vec4[],const int num)132 inline bit32* MakeUniformCommandVS( bit32* command, u8 location, const nn::math::VEC4 vec4[], const int num ) 133 { 134 *command++ = 0x80000000 | location; 135 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_VS_FLOAT_ADDR ); 136 *command++ = nn::math::F32AsU32( vec4[0].w ); 137 *command++ = PICA_CMD_HEADER_VS_F32( num ); 138 *command++ = nn::math::F32AsU32( vec4[0].z ); 139 *command++ = nn::math::F32AsU32( vec4[0].y ); 140 *command++ = nn::math::F32AsU32( vec4[0].x ); 141 142 for ( int i = 1; i < num; ++i ) 143 { 144 *command++ = nn::math::F32AsU32( vec4[i].w ); 145 *command++ = nn::math::F32AsU32( vec4[i].z ); 146 *command++ = nn::math::F32AsU32( vec4[i].y ); 147 *command++ = nn::math::F32AsU32( vec4[i].x ); 148 } 149 150 *command++ = 0; // Padding 151 152 return command; 153 } 154 155 //------------------------------------------------------------------------------------ 156 157 /* Please see man pages for details 158 159 160 161 162 163 164 165 166 167 */ MakeUniformCommandVS(bit32 * command,u8 location,u8 x,u8 y,u8 z)168 inline bit32* MakeUniformCommandVS( bit32* command, u8 location, u8 x, u8 y, u8 z ) 169 { 170 *command++ = PICA_CMD_DATA_VS_INT( x, y, z ); 171 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_VS_INT0 + location ); 172 return command; 173 } 174 175 //------------------------------------------------------------------------------------ 176 177 /* Please see man pages for details 178 179 180 181 182 183 184 185 */ MakeUniformCommandGS(bit32 * command,u8 location,const nn::math::MTX34 & mtx34)186 inline bit32* MakeUniformCommandGS( bit32* command, u8 location, const nn::math::MTX34& mtx34 ) 187 { 188 *command++ = 0x80000000 | location; 189 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_GS_FLOAT_ADDR ); 190 CopyMtx34WithHeader( reinterpret_cast<f32*>( command ), &mtx34, PICA_CMD_HEADER_GS_F32( 3 ) ); 191 return command + 14; 192 } 193 194 //------------------------------------------------------------------------------------ 195 196 /* Please see man pages for details 197 198 199 200 201 202 203 204 */ MakeUniformCommandGS(bit32 * command,u8 location,const nn::math::MTX44 & mtx44)205 inline bit32* MakeUniformCommandGS( bit32* command, u8 location, const nn::math::MTX44& mtx44 ) 206 { 207 *command++ = 0x80000000 | location; 208 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_GS_FLOAT_ADDR ); 209 CopyMtx44WithHeader( reinterpret_cast<f32*>( command ), &mtx44, PICA_CMD_HEADER_GS_F32( 4 ) ); 210 return command + 18; 211 } 212 213 //------------------------------------------------------------------------------------ 214 215 /* Please see man pages for details 216 217 218 219 220 221 222 223 */ MakeUniformCommandGS(bit32 * command,u8 location,const nn::math::VEC4 & vec4)224 inline bit32* MakeUniformCommandGS( bit32* command, u8 location, const nn::math::VEC4& vec4 ) 225 { 226 *command++ = 0x80000000 | location; 227 *command++ = PICA_CMD_HEADER_BURSTSEQ( PICA_REG_GS_FLOAT_ADDR, 5 ); 228 *command++ = nn::math::F32AsU32( vec4.w ); // a 229 *command++ = nn::math::F32AsU32( vec4.z ); // b 230 *command++ = nn::math::F32AsU32( vec4.y ); // g 231 *command++ = nn::math::F32AsU32( vec4.x ); // r 232 return command; 233 } 234 235 //------------------------------------------------------------------------------------ 236 237 /* Please see man pages for details 238 239 240 241 242 243 244 245 246 */ MakeUniformCommandGS(bit32 * command,u8 location,const nn::math::VEC4 vec4[],const int num)247 inline bit32* MakeUniformCommandGS( bit32* command, u8 location, const nn::math::VEC4 vec4[], const int num ) 248 { 249 *command++ = 0x80000000 | location; 250 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_GS_FLOAT_ADDR ); 251 *command++ = nn::math::F32AsU32( vec4[0].w ); 252 *command++ = PICA_CMD_HEADER_GS_F32( num ); 253 *command++ = nn::math::F32AsU32( vec4[0].z ); 254 *command++ = nn::math::F32AsU32( vec4[0].y ); 255 *command++ = nn::math::F32AsU32( vec4[0].x ); 256 257 for ( int i = 1; i < num; ++i ) 258 { 259 *command++ = nn::math::F32AsU32( vec4[i].w ); 260 *command++ = nn::math::F32AsU32( vec4[i].z ); 261 *command++ = nn::math::F32AsU32( vec4[i].y ); 262 *command++ = nn::math::F32AsU32( vec4[i].x ); 263 } 264 265 *command++ = 0; // Padding 266 267 return command; 268 } 269 270 //------------------------------------------------------------------------------------ 271 272 /* Please see man pages for details 273 274 275 276 277 278 279 280 281 282 */ MakeUniformCommandGS(bit32 * command,u8 location,u8 x,u8 y,u8 z)283 inline bit32* MakeUniformCommandGS( bit32* command, u8 location, u8 x, u8 y, u8 z ) 284 { 285 *command++ = PICA_CMD_DATA_GS_INT( x, y, z ); 286 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_GS_INT0 + location ); 287 return command; 288 } 289 290 //------------------------------------------------------------------------------------ 291 292 /* Please see man pages for details 293 294 295 296 297 298 */ FloatToUnsignedByte(f32 val)299 inline u8 FloatToUnsignedByte( 300 f32 val 301 ) 302 { 303 return ( u8 )( 0.5f + ( val < 0.f ? 0.f : ( 1.f < val ? 1.f : val ) ) * ( 0xff ) ); 304 } 305 306 //------------------------------------------------------------------------------------ 307 308 /* Please see man pages for details 309 310 311 312 313 314 */ FloatToUnsignedByteNoClamp(f32 val)315 inline u8 FloatToUnsignedByteNoClamp( 316 f32 val 317 ) 318 { 319 return ( u8 )( 0.5f + val * 0xff ); 320 } 321 322 //------------------------------------------------------------------------------------ 323 324 /* Please see man pages for details 325 326 327 328 329 330 */ Float32ToFloat16(f32 val)331 inline u16 Float32ToFloat16( f32 val ) 332 { 333 static const int bias_ = 128 - (1 << (5 - 1)); 334 335 u32 uval_ = *( reinterpret_cast<u32*>( &val ) ); 336 int e_ = (uval_ & 0x7fffffff) ? (((uval_ >> 23) & 0xff) - bias_) : 0; 337 if (e_ >= 0) 338 { 339 return ( u16 )( ((uval_ & 0x7fffff) >> (23 - 10)) | (e_ << 10) | ((uval_ >> 31) << (10 + 5)) ); 340 } 341 return ( u16 )((uval_ >> 31) << (10 + 5)); 342 } 343 344 //------------------------------------------------------------------------------------ 345 346 /* Please see man pages for details 347 348 349 350 351 352 */ Float32ToFloat24(f32 val)353 inline u32 Float32ToFloat24( f32 val ) 354 { 355 static const int bias_ = 128 - (1 << (7 - 1)); 356 u32 uval_ = *( reinterpret_cast<unsigned*>( &val ) ); 357 s32 e_ = (uval_ & 0x7fffffff) ? (((uval_ >> 23) & 0xff) - bias_) : 0; 358 359 return e_ >= 0 ? ((uval_ & 0x7fffff) >> (23 - 16)) | (e_ << 16) | ((uval_ >> 31) << (16 + 7)) : ((uval_ >> 31) << (16 + 7)); 360 } 361 362 //------------------------------------------------------------------------------------ 363 364 /* Please see man pages for details 365 366 367 368 369 370 */ Float32ToFloat20(f32 val)371 inline u32 Float32ToFloat20( f32 val ) 372 { 373 static const int bias_ = 128 - (1 << (7 - 1)); 374 u32 uval_ = *( reinterpret_cast<unsigned*>( &val ) ); 375 s32 e_ = (uval_ & 0x7fffffff) ? (((uval_ >> 23) & 0xff) - bias_) : 0; 376 377 return e_ >= 0 ? ((uval_ & 0x7fffff) >> (23 - 12)) | (e_ << 12) | ((uval_ >> 31) << (12 + 7)) : ((uval_ >> 31) << (12 + 7)); 378 } 379 380 //------------------------------------------------------------------------------------ 381 382 /* Please see man pages for details 383 384 385 386 387 388 */ Float32ToFloat31(f32 val)389 inline u32 Float32ToFloat31( f32 val ) 390 { 391 unsigned uval_, m_; 392 int e_; 393 float f_ = val; 394 static const int bias_ = 128 - (1 << (7 - 1)); 395 uval_ = *( reinterpret_cast<unsigned*>( &f_ ) ); 396 e_ = (uval_ & 0x7fffffff) ? (((uval_ >> 23) & 0xff) - bias_) : 0; 397 m_ = (uval_ & 0x7fffff) >> (23 - 23); 398 return e_ >= 0 ? m_ | (e_ << 23) | ((uval_ >> 31) << (23 + 7)) : ((uval_ >> 31) << (23 + 7)); 399 } 400 401 //------------------------------------------------------------------------------------ 402 /* Please see man pages for details 403 404 405 406 407 408 */ Float32ToUnsignedFix24(f32 val)409 inline u32 Float32ToUnsignedFix24( f32 val ) 410 { 411 unsigned v_ = *( reinterpret_cast<unsigned*>( &val ) ); 412 413 if (val <= 0 || (v_ & 0x7f800000) == 0x7f800000) 414 { 415 return 0; 416 } 417 else 418 { 419 val *= 1 << (24 - 0); 420 421 if ( val >= (1 << 24) ) 422 { 423 return (1 << 24) - 1; 424 } 425 else 426 { 427 return (unsigned)(val); 428 } 429 } 430 } 431 432 //------------------------------------------------------------------------------------ 433 /* Please see man pages for details 434 435 436 437 438 439 */ Float32ToUnsignedFix16(f32 val)440 inline u32 Float32ToUnsignedFix16( f32 val ) 441 { 442 unsigned v_ = *( reinterpret_cast<unsigned*>( &val) ); 443 444 if (val <= 0 || (v_ & 0x7f800000) == 0x7f800000) 445 { 446 return 0; 447 } 448 else 449 { 450 val *= 1 << (16 - 0); 451 if ( val >= (1 << 16) ) 452 { 453 return (1 << 16) - 1; 454 } 455 else 456 { 457 return (unsigned)( val ); 458 } 459 } 460 } 461 462 //------------------------------------------------------------------------------------ 463 /* Please see man pages for details 464 465 466 467 468 469 */ Float32ToFix16(f32 val)470 inline u16 Float32ToFix16( f32 val ) 471 { 472 unsigned v_ = *( reinterpret_cast<unsigned*>( &val ) ); 473 474 if ( (val == 0.f) || ( (v_ & 0x7f800000) == 0x7f800000 ) ) 475 { 476 return 0; 477 } 478 else 479 { 480 val += 0.5f * (1 << 4); 481 val *= 1 << (16 - 4); 482 if (val < 0) 483 { 484 val = 0; 485 } 486 else if (val >= (1 << 16)) 487 { 488 val = (1 << 16) - 1; 489 } 490 491 if (val >= (1 << (16 - 1))) 492 { 493 return (unsigned)(val - (1 << (16 - 1))); 494 } 495 else 496 { 497 return (unsigned)(val + (1 << (16 - 1))); 498 } 499 } 500 } 501 502 //------------------------------------------------------------------------------------ 503 504 /* Please see man pages for details 505 506 507 508 509 510 */ Float32ToUnsignedFix12(f32 val)511 inline u32 Float32ToUnsignedFix12( f32 val ) 512 { 513 unsigned v_ = *( reinterpret_cast<unsigned*>( &val ) ); 514 if( val <= 0 || (v_ & 0x7f800000) == 0x7f800000 ) 515 { 516 return 0; 517 } 518 else 519 { 520 unsigned uval_; 521 522 val *= 1 << (12 - 0); 523 if (val >= (1 << 12)) 524 { 525 uval_ = (1 << 12) - 1; 526 } 527 else 528 { 529 uval_ = (unsigned)(val); 530 } 531 532 return uval_; 533 } 534 } 535 536 //------------------------------------------------------------------------------------ 537 538 /* Please see man pages for details 539 540 541 542 543 544 */ Float32ToFix12(f32 val)545 inline u32 Float32ToFix12( f32 val ) 546 { 547 unsigned v_ = *( reinterpret_cast<unsigned*>( &val ) ); 548 if( val == 0.f || (v_ & 0x7f800000) == 0x7f800000 ) 549 return 0; 550 551 int ret; 552 553 val *= (1 << (12 - 1)); 554 555 if( val < 0 ) 556 { 557 ret = 1 << (12 - 1); 558 val = -val; 559 } 560 else 561 ret = 0; 562 563 if( val >= (1 << (12 - 1)) ) 564 val = (1 << (12 - 1)) - 1; 565 566 ret |= (unsigned)(val); 567 return ret; 568 } 569 570 /* Please see man pages for details 571 572 573 574 575 576 */ Float32ToFix12Fraction11(f32 val)577 inline u32 Float32ToFix12Fraction11( f32 val ) 578 { 579 unsigned v_ = *( reinterpret_cast<unsigned*>( &val ) ); 580 581 if (val == 0.f || (v_ & 0x7f800000) == 0x7f800000) 582 { 583 return 0; 584 } 585 else 586 { 587 val += 0.5f * (1 << 1); 588 val *= 1 << (12 - 1); 589 590 if (val < 0) 591 { 592 val = 0; 593 } 594 else if (val >= (1 << 12)) 595 { 596 val = (1 << 12) - 1; 597 } 598 599 if (val >= (1 << (12 - 1))) 600 { 601 return (unsigned)(val - (1 << (12 - 1))); 602 } 603 else 604 { 605 return (unsigned)(val + (1 << (12 - 1))); 606 } 607 } 608 } 609 610 //------------------------------------------------------------------------------------ 611 612 /* Please see man pages for details 613 614 615 616 617 618 */ Float32ToFix13Fraction8(f32 val)619 inline u32 Float32ToFix13Fraction8( f32 val ) 620 { 621 unsigned v_ = *( reinterpret_cast<unsigned*>( &val ) ); 622 if ( ( val == 0.0f ) || 623 ( (v_ & 0x7f800000) == 0x7f800000 ) ) 624 { 625 return 0; 626 } 627 628 val += 0.5f * (1 << 5); 629 val *= 1 << (13 - 5); 630 if (val < 0) 631 { 632 val = 0; 633 } 634 else if (val >= (1 << 13)) 635 { 636 val = (1 << 13) - 1; 637 } 638 639 return (val >= (1 << (13 - 1))) ? (unsigned)(val - (1 << (13 - 1))) : (unsigned)(val + (1 << (13 - 1))); 640 } 641 642 //------------------------------------------------------------------------------------ 643 644 /* Please see man pages for details 645 646 647 648 649 650 */ Float32ToFix13Fraction11(f32 val)651 inline u32 Float32ToFix13Fraction11( f32 val ) 652 { 653 unsigned v_ = *( reinterpret_cast<unsigned*>( &val ) ); 654 if( val == 0.f || (v_ & 0x7f800000) == 0x7f800000 ) 655 return 0; 656 657 val += 0.5f * (1 << 2); 658 val *= 1 << (13 - 2); 659 if (val < 0) 660 val = 0; 661 else if (val >= (1 << 13)) 662 val = (1 << 13) - 1; 663 664 return (val >= (1 << (13 - 1))) ? (unsigned)(val - (1 << (13 - 1))) : (unsigned)(val + (1 << (13 - 1))); 665 } 666 667 //------------------------------------------------------------------------------------ 668 669 /* Please see man pages for details 670 671 672 673 674 675 */ Float32ToUnsignedFix11(f32 val)676 inline u32 Float32ToUnsignedFix11( f32 val ) 677 { 678 unsigned v_ = *( reinterpret_cast<unsigned*>( &val ) ); 679 if( val <= 0 || (v_ & 0x7f800000) == 0x7f800000 ) 680 return 0; 681 682 unsigned uval_; 683 684 val *= 1 << (11 - 0); 685 if (val >= (1 << 11)) 686 uval_ = (1 << 11) - 1; 687 else 688 uval_ = (unsigned)(val); 689 690 return uval_; 691 } 692 693 //------------------------------------------------------------------------------------ 694 695 /* Please see man pages for details 696 697 698 699 700 701 */ Float32ToFix8Fraction7(f32 val)702 inline u8 Float32ToFix8Fraction7( f32 val ) 703 { 704 unsigned v_ = *( reinterpret_cast<unsigned*>( &val ) ); 705 706 if (val == 0.f || (v_ & 0x7f800000) == 0x7f800000) 707 { 708 return 0; 709 } 710 else 711 { 712 val += 0.5f * (1 << 1); 713 val *= 1 << (8 - 1); 714 715 if (val < 0) 716 { 717 val = 0; 718 } 719 else if (val >= (1 << 8)) 720 { 721 val = (1 << 8) - 1; 722 } 723 724 if (val >= (1 << (8 - 1))) 725 { 726 return (unsigned)(val - (1 << (8 - 1))); 727 } 728 else 729 { 730 return (unsigned)(val + (1 << (8 - 1))); 731 } 732 } 733 } 734 735 //------------------------------------------------------------------------------------ 736 737 /* Please see man pages for details 738 739 740 741 742 743 */ PicaDataVertexAttrTypeToByteSize(const PicaDataVertexAttrType type)744 inline u32 PicaDataVertexAttrTypeToByteSize( const PicaDataVertexAttrType type ) 745 { 746 switch ( type ) 747 { 748 case PICA_DATA_SIZE_1_BYTE : return 1 * sizeof( s8 ); 749 case PICA_DATA_SIZE_1_UNSIGNED_BYTE : return 1 * sizeof( u8 ); 750 case PICA_DATA_SIZE_1_SHORT : return 1 * sizeof( s16 ); 751 case PICA_DATA_SIZE_1_FLOAT : return 1 * sizeof( f32 ); 752 case PICA_DATA_SIZE_2_BYTE : return 2 * sizeof( s8 ); 753 case PICA_DATA_SIZE_2_UNSIGNED_BYTE : return 2 * sizeof( u8 ); 754 case PICA_DATA_SIZE_2_SHORT : return 2 * sizeof( s16 ); 755 case PICA_DATA_SIZE_2_FLOAT : return 2 * sizeof( f32 ); 756 case PICA_DATA_SIZE_3_BYTE : return 3 * sizeof( s8 ); 757 case PICA_DATA_SIZE_3_UNSIGNED_BYTE : return 3 * sizeof( u8 ); 758 case PICA_DATA_SIZE_3_SHORT : return 3 * sizeof( s16 ); 759 case PICA_DATA_SIZE_3_FLOAT : return 3 * sizeof( f32 ); 760 case PICA_DATA_SIZE_4_BYTE : return 4 * sizeof( s8 ); 761 case PICA_DATA_SIZE_4_UNSIGNED_BYTE : return 4 * sizeof( u8 ); 762 case PICA_DATA_SIZE_4_SHORT : return 4 * sizeof( s16 ); 763 case PICA_DATA_SIZE_4_FLOAT : return 4 * sizeof( f32 ); 764 } 765 return 0; 766 } 767 768 769 //------------------------------------------------------------------------------------ 770 771 /* Please see man pages for details 772 773 774 775 776 777 */ 778 bit32* MakeDisableAllCommand( bit32* command ); 779 780 } // namespace CTR 781 } // namespace gr 782 } // namespace nn 783 784 #endif // NN_GR_UTILITY_H_ 785