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: 29329 $ 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 /*! 36 @brief 3x4行列をwHzyxの順に逆転してコピーします。(ヘッダーあり) 37 38 @param[in] dst 結果を書き込む先のポインタです。 39 @param[in] src 34行列です。 40 @param[in] header ヘッダです。 41 */ 42 void CopyMtx34WithHeader( 43 f32* dst, 44 const nn::math::MTX34* src, 45 bit32 header ); 46 47 /*! 48 @brief 4x4行列をwHzyxの順に逆転してコピーします。(ヘッダーあり) 49 50 @param[in] dst 結果を書き込む先のポインタです。 51 @param[in] src 44行列です。 52 @param[in] header ヘッダです。 53 */ 54 void CopyMtx44WithHeader( 55 f32* dst, 56 const nn::math::MTX44* src, 57 bit32 header ); 58 59 //------------------------------------------------------------------------------------ 60 61 /*! 62 @brief 34行列を頂点シェーダのユニフォームにセットするコマンドを生成します。 63 64 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 65 @param[in] location レジスタの場所です。 66 @param[in] mtx34 34行列です。 67 68 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 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( (f32*)command, &mtx34, PICA_CMD_HEADER_VS_F32( 3 ) ); 75 return command + 14; 76 } 77 78 //------------------------------------------------------------------------------------ 79 80 /*! 81 @brief 44行列を頂点シェーダのユニフォームにセットするコマンドを生成します。 82 83 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 84 @param[in] location レジスタの場所です。 85 @param[in] mtx44 44行列です。 86 87 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 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( (f32*)command, &mtx44, PICA_CMD_HEADER_VS_F32( 4 ) ); 94 return command + 18; 95 } 96 97 //------------------------------------------------------------------------------------ 98 99 /*! 100 @brief ベクトルを頂点シェーダのユニフォームにセットするコマンドを生成します。 101 102 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 103 @param[in] location レジスタの場所です。 104 @param[in] vec4 4次元のベクトルです。 105 106 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 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 /*! 123 @brief ベクトルの配列を頂点シェーダのユニフォームにセットするコマンドを生成します。 124 125 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 126 @param[in] location レジスタの場所です。 127 @param[in] vec4 4次元のベクトルの配列です。 128 @param[in] num 配列のサイズです。 129 130 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 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 /*! 158 @brief 整数を頂点シェーダのユニフォームにセットするコマンドを生成します。 159 160 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 161 @param[in] location レジスタの場所です。 162 @param[in] x x 座標の値です。 163 @param[in] y y 座標の値です。 164 @param[in] z z 座標の値です。 165 166 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 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 /*! 178 @brief 34行列をジオメトリシェーダのユニフォームにセットするコマンドを生成します。 179 180 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 181 @param[in] location レジスタの場所です。 182 @param[in] mtx34 34行列です。 183 184 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 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( (f32*)command, &mtx34, PICA_CMD_HEADER_GS_F32( 3 ) ); 191 return command + 14; 192 } 193 194 //------------------------------------------------------------------------------------ 195 196 /*! 197 @brief 44行列をジオメトリシェーダのユニフォームにセットするコマンドを生成します。 198 199 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 200 @param[in] location レジスタの場所です。 201 @param[in] mtx44 44行列です。 202 203 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 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( (f32*)command, &mtx44, PICA_CMD_HEADER_GS_F32( 4 ) ); 210 return command + 18; 211 } 212 213 //------------------------------------------------------------------------------------ 214 215 /*! 216 @brief ベクトルをジオメトリシェーダのユニフォームにセットするコマンドを生成します. 217 218 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 219 @param[in] location レジスタの場所です。 220 @param[in] vec4 4次元のベクトルです。 221 222 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 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 /*! 238 @brief ベクトルの配列をジオメトリシェーダのユニフォームにセットするコマンドを生成します。 239 240 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 241 @param[in] location レジスタの場所です。 242 @param[in] vec4 4次元のベクトルの配列です。 243 @param[in] num 配列のサイズです。 244 245 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 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 /*! 273 @brief 整数をジオメトリシェーダのユニフォームにセットするコマンドを生成します。 274 275 @param[in] command 描画コマンドの書き込み先の先頭アドレスです。 276 @param[in] location レジスタの場所です。 277 @param[in] x x 座標の値です。 278 @param[in] y y 座標の値です。 279 @param[in] z z 座標の値です。 280 281 @return 書き込まれた描画コマンドの終端の次のアドレスを返します。 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 /*! 293 @brief float32 を u8 に変換します。 294 295 @param[in] val 変換前の値です。 296 297 @return 変換後の値です。 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 /*! 309 @brief float32 を クランプせずに u8 に変換します。 310 311 @param[in] val 変換前の値です。 312 313 @return 変換後の値です 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 /*! 325 @brief float32 から float16 に変換します。 326 327 @param[in] val 変換前の値です。 328 329 @return 変換後の値です 330 */ Float32ToFloat16(f32 val)331 inline u16 Float32ToFloat16( f32 val ) 332 { 333 static const int bias_ = 128 - (1 << (5 - 1)); 334 335 u32 uval_ = *(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 /*! 347 @brief float32 から float24 に変換します。 348 349 @param[in] val 変換前の値です。 350 351 @return 変換後の値です 352 */ Float32ToFloat24(f32 val)353 inline u32 Float32ToFloat24( f32 val ) 354 { 355 static const int bias_ = 128 - (1 << (7 - 1)); 356 u32 uval_ = *(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 /*! 365 @brief float32 から float20 に変換します。 366 367 @param[in] val 変換前の値です。 368 369 @return 変換後の値です 370 */ Float32ToFloat20(f32 val)371 inline u32 Float32ToFloat20( f32 val ) 372 { 373 static const int bias_ = 128 - (1 << (7 - 1)); 374 u32 uval_ = *(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 /*! 383 @brief float32 から float31 に変換します。 384 385 @param[in] val 変換前の値です。 386 387 @return 変換後の値です 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_ = *(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 /*! 403 @brief float32 から 符号なし fixed24 に変換します。 404 405 @param[in] val 変換前の値です。 406 407 @return 変換後の値です 408 */ Float32ToUnsignedFix24(f32 val)409 inline u32 Float32ToUnsignedFix24( f32 val ) 410 { 411 unsigned v_ = *(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 /*! 434 @brief float32 から 符号なし fixed16 に変換します。 435 436 @param[in] val 変換前の値です。 437 438 @return 変換後の値です 439 */ Float32ToUnsignedFix16(f32 val)440 inline u32 Float32ToUnsignedFix16( f32 val ) 441 { 442 unsigned v_ = *(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 /*! 464 @brief float32 から 符号あり fixed16 に変換します。 465 466 @param[in] val 変換前の値です。 467 468 @return 変換後の値です 469 */ Float32ToFix16(f32 val)470 inline u16 Float32ToFix16( f32 val ) 471 { 472 unsigned v_ = *(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 /*! 505 @brief float32 から 符号なし fixed12 に変換します。 506 507 @param[in] val 変換前の値です。 508 509 @return 変換後の値です 510 */ Float32ToUnsignedFix12(f32 val)511 inline u32 Float32ToUnsignedFix12( f32 val ) 512 { 513 unsigned v_ = *(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 /*! 539 @brief float32 から 符号あり fixed12 に変換します。 540 541 @param[in] val 変換前の値です。 542 543 @return 変換後の値です 544 */ Float32ToFix12(f32 val)545 inline u32 Float32ToFix12( f32 val ) 546 { 547 unsigned v_ = *(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 /*! 571 @brief float32 から fixed12 ( fraction 11) に変換します。 572 573 @param[in] val 変換前の値です。 574 575 @return 変換後の値です 576 */ Float32ToFix12Fraction11(f32 val)577 inline u32 Float32ToFix12Fraction11( f32 val ) 578 { 579 unsigned v_ = *(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 /*! 613 @brief float32 から fixed13 ( fraction 8) に変換します。 614 615 @param[in] val 変換前の値です。 616 617 @return 変換後の値です 618 */ Float32ToFix13Fraction8(f32 val)619 inline u32 Float32ToFix13Fraction8( f32 val ) 620 { 621 unsigned v_ = *(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 /*! 645 @brief float32 から fixed11 ( fraction 8) に変換します。 646 647 @param[in] val 変換前の値です。 648 649 @return 変換後の値です 650 */ Float32ToFix13Fraction11(f32 val)651 inline u32 Float32ToFix13Fraction11( f32 val ) 652 { 653 unsigned v_ = *(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 /*! 670 @brief float32 から 符号無し fixed11 に変換します。 671 672 @param[in] val 変換前の値です。 673 674 @return 変換後の値です 675 */ Float32ToUnsignedFix11(f32 val)676 inline u32 Float32ToUnsignedFix11( f32 val ) 677 { 678 unsigned v_ = *(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 /*! 696 @brief float32 から fixed8 ( 7bits fraction ) に変換します。 697 698 @param[in] val 変換前の値です。 699 700 @return 変換後の値です 701 */ Float32ToFix8Fraction7(f32 val)702 inline u8 Float32ToFix8Fraction7( f32 val ) 703 { 704 unsigned v_ = *(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 /*! 738 @brief 頂点配列の型から、バイトサイズを求めます。 739 740 @param[in] type 頂点配列の型です。 741 742 @return バイトサイズです。 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 } // namespace CTR 769 } // namespace gr 770 } // namespace nn 771 772 #endif // NN_GR_UTILITY_H_ 773