/*---------------------------------------------------------------------------* Project: Horizon File: gr_Utility.h Copyright (C)2010 Nintendo Co., Ltd. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Rev: 38755 $ *---------------------------------------------------------------------------*/ #ifndef NN_GR_UTILITY_H_ #define NN_GR_UTILITY_H_ #include #include #include #include #include namespace nn { namespace gr { namespace CTR { //------------------------------------------------------------------------------ /* Please see man pages for details */ void CopyMtx34WithHeader( f32* dst, const nn::math::MTX34* src, bit32 header ); /* Please see man pages for details */ void CopyMtx44WithHeader( f32* dst, const nn::math::MTX44* src, bit32 header ); //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline bit32* MakeUniformCommandVS( bit32* command, u8 location, const nn::math::MTX34& mtx34 ) { *command++ = 0x80000000 | location; *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_VS_FLOAT_ADDR ); CopyMtx34WithHeader( reinterpret_cast( command ), &mtx34, PICA_CMD_HEADER_VS_F32( 3 ) ); return command + 14; } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline bit32* MakeUniformCommandVS( bit32* command, u8 location, const nn::math::MTX44& mtx44 ) { *command++ = 0x80000000 | location; *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_VS_FLOAT_ADDR ); CopyMtx44WithHeader( reinterpret_cast( command ), &mtx44, PICA_CMD_HEADER_VS_F32( 4 ) ); return command + 18; } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline bit32* MakeUniformCommandVS( bit32* command, u8 location, const nn::math::VEC4& vec4 ) { // 0x2c0 *command++ = 0x80000000 | location; *command++ = PICA_CMD_HEADER_BURSTSEQ( PICA_REG_VS_FLOAT_ADDR, 5 ); // 0x2c1-0x2c4 *command++ = nn::math::F32AsU32( vec4.w ); *command++ = nn::math::F32AsU32( vec4.z ); *command++ = nn::math::F32AsU32( vec4.y ); *command++ = nn::math::F32AsU32( vec4.x ); return command; } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline bit32* MakeUniformCommandVS( bit32* command, u8 location, const nn::math::VEC4 vec4[], const int num ) { const u32 MAX_VS_F32_VEC4_NUM = 24; NN_GR_ASSERT( num <= MAX_VS_F32_VEC4_NUM ); NN_UNUSED_VAR( MAX_VS_F32_VEC4_NUM ); // 0x2c0 *command++ = 0x80000000 | location; *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_VS_FLOAT_ADDR ); // 0x2c1 *command++ = nn::math::F32AsU32( vec4[0].w ); *command++ = PICA_CMD_HEADER_VS_F32( num ); *command++ = nn::math::F32AsU32( vec4[0].z ); *command++ = nn::math::F32AsU32( vec4[0].y ); *command++ = nn::math::F32AsU32( vec4[0].x ); for ( int i = 1; i < num; ++i ) { *command++ = nn::math::F32AsU32( vec4[i].w ); *command++ = nn::math::F32AsU32( vec4[i].z ); *command++ = nn::math::F32AsU32( vec4[i].y ); *command++ = nn::math::F32AsU32( vec4[i].x ); } *command++ = 0; // Padding return command; } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline bit32* MakeUniformCommandVS( bit32* command, u8 location, u8 x, u8 y, u8 z ) { *command++ = PICA_CMD_DATA_VS_INT( x, y, z ); *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_VS_INT0 + location ); return command; } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline bit32* MakeUniformCommandGS( bit32* command, u8 location, const nn::math::MTX34& mtx34 ) { *command++ = 0x80000000 | location; *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_GS_FLOAT_ADDR ); CopyMtx34WithHeader( reinterpret_cast( command ), &mtx34, PICA_CMD_HEADER_GS_F32( 3 ) ); return command + 14; } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline bit32* MakeUniformCommandGS( bit32* command, u8 location, const nn::math::MTX44& mtx44 ) { *command++ = 0x80000000 | location; *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_GS_FLOAT_ADDR ); CopyMtx44WithHeader( reinterpret_cast( command ), &mtx44, PICA_CMD_HEADER_GS_F32( 4 ) ); return command + 18; } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline bit32* MakeUniformCommandGS( bit32* command, u8 location, const nn::math::VEC4& vec4 ) { *command++ = 0x80000000 | location; *command++ = PICA_CMD_HEADER_BURSTSEQ( PICA_REG_GS_FLOAT_ADDR, 5 ); *command++ = nn::math::F32AsU32( vec4.w ); // a *command++ = nn::math::F32AsU32( vec4.z ); // b *command++ = nn::math::F32AsU32( vec4.y ); // g *command++ = nn::math::F32AsU32( vec4.x ); // r return command; } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline bit32* MakeUniformCommandGS( bit32* command, u8 location, const nn::math::VEC4 vec4[], const int num ) { const u32 MAX_GS_F32_VEC4_NUM = 24; NN_GR_ASSERT( num <= MAX_GS_F32_VEC4_NUM ); NN_UNUSED_VAR( MAX_GS_F32_VEC4_NUM ); *command++ = 0x80000000 | location; *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_GS_FLOAT_ADDR ); *command++ = nn::math::F32AsU32( vec4[0].w ); *command++ = PICA_CMD_HEADER_GS_F32( num ); *command++ = nn::math::F32AsU32( vec4[0].z ); *command++ = nn::math::F32AsU32( vec4[0].y ); *command++ = nn::math::F32AsU32( vec4[0].x ); for ( int i = 1; i < num; ++i ) { *command++ = nn::math::F32AsU32( vec4[i].w ); *command++ = nn::math::F32AsU32( vec4[i].z ); *command++ = nn::math::F32AsU32( vec4[i].y ); *command++ = nn::math::F32AsU32( vec4[i].x ); } *command++ = 0; // Padding return command; } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline bit32* MakeUniformCommandGS( bit32* command, u8 location, u8 x, u8 y, u8 z ) { *command++ = PICA_CMD_DATA_GS_INT( x, y, z ); *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_GS_INT0 + location ); return command; } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline u8 FloatToUnsignedByte( f32 val ) { return ( u8 )( 0.5f + ( val < 0.f ? 0.f : ( 1.f < val ? 1.f : val ) ) * ( 0xff ) ); } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline u8 FloatToUnsignedByteNoClamp( f32 val ) { return ( u8 )( 0.5f + val * 0xff ); } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline u16 Float32ToFloat16( f32 val ) { static const int bias_ = 128 - (1 << (5 - 1)); u32 uval_ = *( reinterpret_cast( &val ) ); int e_ = (uval_ & 0x7fffffff) ? (((uval_ >> 23) & 0xff) - bias_) : 0; if (e_ >= 0) { return ( u16 )( ((uval_ & 0x7fffff) >> (23 - 10)) | (e_ << 10) | ((uval_ >> 31) << (10 + 5)) ); } return ( u16 )((uval_ >> 31) << (10 + 5)); } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline u32 Float32ToFloat24( f32 val ) { static const int bias_ = 128 - (1 << (7 - 1)); u32 uval_ = *( reinterpret_cast( &val ) ); s32 e_ = (uval_ & 0x7fffffff) ? (((uval_ >> 23) & 0xff) - bias_) : 0; return e_ >= 0 ? ((uval_ & 0x7fffff) >> (23 - 16)) | (e_ << 16) | ((uval_ >> 31) << (16 + 7)) : ((uval_ >> 31) << (16 + 7)); } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline u32 Float32ToFloat20( f32 val ) { static const int bias_ = 128 - (1 << (7 - 1)); u32 uval_ = *( reinterpret_cast( &val ) ); s32 e_ = (uval_ & 0x7fffffff) ? (((uval_ >> 23) & 0xff) - bias_) : 0; return e_ >= 0 ? ((uval_ & 0x7fffff) >> (23 - 12)) | (e_ << 12) | ((uval_ >> 31) << (12 + 7)) : ((uval_ >> 31) << (12 + 7)); } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline u32 Float32ToFloat31( f32 val ) { unsigned uval_, m_; int e_; float f_ = val; static const int bias_ = 128 - (1 << (7 - 1)); uval_ = *( reinterpret_cast( &f_ ) ); e_ = (uval_ & 0x7fffffff) ? (((uval_ >> 23) & 0xff) - bias_) : 0; m_ = (uval_ & 0x7fffff) >> (23 - 23); return e_ >= 0 ? m_ | (e_ << 23) | ((uval_ >> 31) << (23 + 7)) : ((uval_ >> 31) << (23 + 7)); } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline u32 Float32ToUnsignedFix24( f32 val ) { unsigned v_ = *( reinterpret_cast( &val ) ); if (val <= 0 || (v_ & 0x7f800000) == 0x7f800000) { return 0; } else { val *= 1 << (24 - 0); if ( val >= (1 << 24) ) { return (1 << 24) - 1; } else { return (unsigned)(val); } } } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline u32 Float32ToUnsignedFix16( f32 val ) { unsigned v_ = *( reinterpret_cast( &val) ); if (val <= 0 || (v_ & 0x7f800000) == 0x7f800000) { return 0; } else { val *= 1 << (16 - 0); if ( val >= (1 << 16) ) { return (1 << 16) - 1; } else { return (unsigned)( val ); } } } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline u16 Float32ToFix16( f32 val ) { unsigned v_ = *( reinterpret_cast( &val ) ); if ( (val == 0.f) || ( (v_ & 0x7f800000) == 0x7f800000 ) ) { return 0; } else { val += 0.5f * (1 << 4); val *= 1 << (16 - 4); if (val < 0) { val = 0; } else if (val >= (1 << 16)) { val = (1 << 16) - 1; } if (val >= (1 << (16 - 1))) { return (unsigned)(val - (1 << (16 - 1))); } else { return (unsigned)(val + (1 << (16 - 1))); } } } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline u32 Float32ToUnsignedFix12( f32 val ) { unsigned v_ = *( reinterpret_cast( &val ) ); if( val <= 0 || (v_ & 0x7f800000) == 0x7f800000 ) { return 0; } else { unsigned uval_; val *= 1 << (12 - 0); if (val >= (1 << 12)) { uval_ = (1 << 12) - 1; } else { uval_ = (unsigned)(val); } return uval_; } } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline u32 Float32ToFix12( f32 val ) { unsigned v_ = *( reinterpret_cast( &val ) ); if( val == 0.f || (v_ & 0x7f800000) == 0x7f800000 ) return 0; int ret; val *= (1 << (12 - 1)); if( val < 0 ) { ret = 1 << (12 - 1); val = -val; } else ret = 0; if( val >= (1 << (12 - 1)) ) val = (1 << (12 - 1)) - 1; ret |= (unsigned)(val); return ret; } /* Please see man pages for details */ inline u32 Float32ToFix12Fraction11( f32 val ) { unsigned v_ = *( reinterpret_cast( &val ) ); if (val == 0.f || (v_ & 0x7f800000) == 0x7f800000) { return 0; } else { val += 0.5f * (1 << 1); val *= 1 << (12 - 1); if (val < 0) { val = 0; } else if (val >= (1 << 12)) { val = (1 << 12) - 1; } if (val >= (1 << (12 - 1))) { return (unsigned)(val - (1 << (12 - 1))); } else { return (unsigned)(val + (1 << (12 - 1))); } } } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline u32 Float32ToFix13Fraction8( f32 val ) { unsigned v_ = *( reinterpret_cast( &val ) ); if ( ( val == 0.0f ) || ( (v_ & 0x7f800000) == 0x7f800000 ) ) { return 0; } val += 0.5f * (1 << 5); val *= 1 << (13 - 5); if (val < 0) { val = 0; } else if (val >= (1 << 13)) { val = (1 << 13) - 1; } return (val >= (1 << (13 - 1))) ? (unsigned)(val - (1 << (13 - 1))) : (unsigned)(val + (1 << (13 - 1))); } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline u32 Float32ToFix13Fraction11( f32 val ) { unsigned v_ = *( reinterpret_cast( &val ) ); if( val == 0.f || (v_ & 0x7f800000) == 0x7f800000 ) return 0; val += 0.5f * (1 << 2); val *= 1 << (13 - 2); if (val < 0) val = 0; else if (val >= (1 << 13)) val = (1 << 13) - 1; return (val >= (1 << (13 - 1))) ? (unsigned)(val - (1 << (13 - 1))) : (unsigned)(val + (1 << (13 - 1))); } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline u32 Float32ToUnsignedFix11( f32 val ) { unsigned v_ = *( reinterpret_cast( &val ) ); if( val <= 0 || (v_ & 0x7f800000) == 0x7f800000 ) return 0; unsigned uval_; val *= 1 << (11 - 0); if (val >= (1 << 11)) uval_ = (1 << 11) - 1; else uval_ = (unsigned)(val); return uval_; } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline u8 Float32ToFix8Fraction7( f32 val ) { unsigned v_ = *( reinterpret_cast( &val ) ); if (val == 0.f || (v_ & 0x7f800000) == 0x7f800000) { return 0; } else { val += 0.5f * (1 << 1); val *= 1 << (8 - 1); if (val < 0) { val = 0; } else if (val >= (1 << 8)) { val = (1 << 8) - 1; } if (val >= (1 << (8 - 1))) { return (unsigned)(val - (1 << (8 - 1))); } else { return (unsigned)(val + (1 << (8 - 1))); } } } //------------------------------------------------------------------------------------ /* Please see man pages for details */ inline u32 PicaDataVertexAttrTypeToByteSize( const PicaDataVertexAttrType type ) { switch ( type ) { case PICA_DATA_SIZE_1_BYTE : return 1 * sizeof( s8 ); case PICA_DATA_SIZE_1_UNSIGNED_BYTE : return 1 * sizeof( u8 ); case PICA_DATA_SIZE_1_SHORT : return 1 * sizeof( s16 ); case PICA_DATA_SIZE_1_FLOAT : return 1 * sizeof( f32 ); case PICA_DATA_SIZE_2_BYTE : return 2 * sizeof( s8 ); case PICA_DATA_SIZE_2_UNSIGNED_BYTE : return 2 * sizeof( u8 ); case PICA_DATA_SIZE_2_SHORT : return 2 * sizeof( s16 ); case PICA_DATA_SIZE_2_FLOAT : return 2 * sizeof( f32 ); case PICA_DATA_SIZE_3_BYTE : return 3 * sizeof( s8 ); case PICA_DATA_SIZE_3_UNSIGNED_BYTE : return 3 * sizeof( u8 ); case PICA_DATA_SIZE_3_SHORT : return 3 * sizeof( s16 ); case PICA_DATA_SIZE_3_FLOAT : return 3 * sizeof( f32 ); case PICA_DATA_SIZE_4_BYTE : return 4 * sizeof( s8 ); case PICA_DATA_SIZE_4_UNSIGNED_BYTE : return 4 * sizeof( u8 ); case PICA_DATA_SIZE_4_SHORT : return 4 * sizeof( s16 ); case PICA_DATA_SIZE_4_FLOAT : return 4 * sizeof( f32 ); } return 0; } //------------------------------------------------------------------------------------ /* Please see man pages for details */ bit32* MakeDisableAllCommand( bit32* command ); } // namespace CTR } // namespace gr } // namespace nn #endif // NN_GR_UTILITY_H_