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