1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: gr_Texture.cpp 4 5 Copyright (C)2009-2012 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: 46395 $ 14 *---------------------------------------------------------------------------*/ 15 16 #include <nn/gr/CTR/gr_Texture.h> 17 18 namespace nn 19 { 20 namespace gr 21 { 22 namespace CTR 23 { 24 MakeCommand(bit32 * command,bool is_update_texture_func) const25 bit32* Texture::Unit0::MakeCommand( bit32* command, bool is_update_texture_func ) const 26 { 27 if ( is_update_texture_func ) 28 { 29 command = m_Texture.MakeFuncCommand( command ); 30 } 31 32 // 0x081 33 *command++ = borderColorR | borderColorG << 8 | borderColorB << 16 | borderColorA << 24; 34 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_BORDER_COLOR ); 35 36 // 0x082 37 *command++ = PICA_CMD_DATA_TEXTURE_SIZE( width, height ); 38 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_SIZE ); 39 40 // 0x083 41 u8 useShadow = 0; 42 if ( ( texType == PICA_DATA_TEXTURE0_SAMPLER_TYPE_TEXTURE_SHADOW_2D_DMP ) || 43 ( texType == PICA_DATA_TEXTURE0_SAMPLER_TYPE_TEXTURE_SHADOW_CUBE_DMP ) ) 44 { 45 useShadow = 1; 46 } 47 *command++ = PICA_CMD_DATA_TEXTURE_WRAP_FILTER( magFilter, minFilter, format, wrapT, wrapS, useShadow, texType ); 48 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_WRAP_FILTER ); 49 50 if ( IsEnableMipMap() ) 51 { 52 NN_ASSERT( -16.f <= lodBias && lodBias <= 16.f ); 53 54 // 0x084 55 *command++ = PICA_CMD_DATA_TEXTURE_LOD_LEVEL( Float32ToFix13Fraction8( lodBias ), maxLodLevel, minLodLevel ); 56 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_LOD ); 57 } 58 else 59 { 60 *command++ = 0; 61 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_LOD ); 62 } 63 64 if ( ( texType == PICA_DATA_TEXTURE0_SAMPLER_TYPE_TEXTURE_2D ) || 65 ( texType == PICA_DATA_TEXTURE0_SAMPLER_TYPE_TEXTURE_PROJECTION_DMP ) || 66 ( texType == PICA_DATA_TEXTURE0_SAMPLER_TYPE_TEXTURE_SHADOW_2D_DMP ) ) 67 { 68 // 0x085 69 *command++ = PICA_CMD_DATA_TEXTURE_ADDR( physicalAddr ); 70 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_ADDR1 ); 71 } 72 else if ( ( texType == PICA_DATA_TEXTURE0_SAMPLER_TYPE_TEXTURE_CUBE_MAP ) || 73 ( texType == PICA_DATA_TEXTURE0_SAMPLER_TYPE_TEXTURE_SHADOW_CUBE_DMP ) ) 74 { 75 // 0x085 76 *command++ = PICA_CMD_DATA_TEXTURE_ADDR( cubeMapAddrPosX ); 77 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_ADDR1 ); 78 79 // 0x086 80 *command++ = PICA_CMD_DATA_TEXTURE_CUBE_MAP_ADDR( PICA_CMD_DATA_TEXTURE_ADDR( cubeMapAddrNegX ) ); 81 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_ADDR2 ); 82 83 // 0x087 84 *command++ = PICA_CMD_DATA_TEXTURE_CUBE_MAP_ADDR( PICA_CMD_DATA_TEXTURE_ADDR( cubeMapAddrPosY ) ); 85 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_ADDR3 ); 86 87 // 0x088 88 *command++ = PICA_CMD_DATA_TEXTURE_CUBE_MAP_ADDR( PICA_CMD_DATA_TEXTURE_ADDR( cubeMapAddrNegY ) ); 89 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_ADDR4 ); 90 91 // 0x089 92 *command++ = PICA_CMD_DATA_TEXTURE_CUBE_MAP_ADDR( PICA_CMD_DATA_TEXTURE_ADDR( cubeMapAddrPosZ ) ); 93 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_ADDR5 ); 94 95 // 0x08a 96 *command++ = PICA_CMD_DATA_TEXTURE_CUBE_MAP_ADDR( PICA_CMD_DATA_TEXTURE_ADDR( cubeMapAddrNegZ ) ); 97 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_ADDR6 ); 98 } 99 100 // 0x08e 101 *command++ = PICA_CMD_DATA_TEXTURE_FORMAT_TYPE( format ); 102 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_FORMAT ); 103 104 return command; 105 } 106 107 //------------------------------------------------------------------------------ MakeCommand(bit32 * command,bool is_update_texture_func) const108 bit32* Texture::Unit1::MakeCommand( bit32* command, bool is_update_texture_func ) const 109 { 110 if ( is_update_texture_func ) 111 { 112 command = m_Texture.MakeFuncCommand( command ); 113 } 114 115 // 0x091 116 *command++ = borderColorR | borderColorG << 8 | borderColorB << 16 | borderColorA << 24; 117 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE1_BORDER_COLOR ); 118 119 // 0x092 120 *command++ = PICA_CMD_DATA_TEXTURE_SIZE( width, height ); 121 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE1_SIZE ); 122 123 // 0x093 124 *command++ = PICA_CMD_DATA_TEXTURE1_WRAP_FILTER( magFilter, minFilter, format, wrapT, wrapS ); 125 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE1_WRAP_FILTER ); 126 127 128 if ( IsEnableMipMap() ) 129 { 130 NN_ASSERT( -16.f <= lodBias && lodBias <= 16.f ); 131 // 0x094 132 *command++ = PICA_CMD_DATA_TEXTURE_LOD_LEVEL( Float32ToFix13Fraction8( lodBias ), maxLodLevel, minLodLevel ); 133 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE1_LOD ); 134 } 135 else 136 { 137 *command++ = 0; 138 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE1_LOD ); 139 } 140 141 // 0x095 142 *command++ = PICA_CMD_DATA_TEXTURE_ADDR( physicalAddr ); 143 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE1_ADDR ); 144 145 // 0x096 146 *command++ = PICA_CMD_DATA_TEXTURE_FORMAT_TYPE( format ); 147 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE1_FORMAT ); 148 149 return command; 150 } 151 152 //------------------------------------------------------------------------------ MakeCommand(bit32 * command,bool is_update_texture_func) const153 bit32* Texture::Unit2::MakeCommand( bit32* command, bool is_update_texture_func ) const 154 { 155 if ( is_update_texture_func ) 156 { 157 command = m_Texture.MakeFuncCommand( command ); 158 } 159 160 // 0x099 161 *command++ = borderColorR | borderColorG << 8 | borderColorB << 16 | borderColorA << 24; 162 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE2_BORDER_COLOR ); 163 164 // 0x09a 165 *command++ = PICA_CMD_DATA_TEXTURE_SIZE( width, height ); 166 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE2_SIZE ); 167 168 // 0x09b 169 *command++ = PICA_CMD_DATA_TEXTURE2_WRAP_FILTER( magFilter, minFilter, format, wrapT, wrapS ); 170 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE2_WRAP_FILTER ); 171 172 if ( IsEnableMipMap() ) 173 { 174 NN_ASSERT( -16.f <= lodBias && lodBias <= 16.f ); 175 // 0x09c 176 *command++ = PICA_CMD_DATA_TEXTURE_LOD_LEVEL( Float32ToFix13Fraction8( lodBias ), maxLodLevel, minLodLevel ); 177 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE2_LOD ); 178 } 179 else 180 { 181 *command++ = 0; 182 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE2_LOD ); 183 } 184 185 // 0x09d 186 *command++ = PICA_CMD_DATA_TEXTURE_ADDR( physicalAddr ); 187 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE2_ADDR ); 188 189 // 0x09e 190 *command++ = PICA_CMD_DATA_TEXTURE_FORMAT_TYPE( format ); 191 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE2_FORMAT ); 192 193 return command; 194 } 195 196 //------------------------------------------------------------------------------ MakeCommand(bit32 * command,bool is_update_texture_func) const197 bit32* Texture::Unit3::MakeCommand( bit32* command, bool is_update_texture_func ) const 198 { 199 if ( is_update_texture_func ) 200 { 201 command = m_Texture.MakeFuncCommand( command ); 202 } 203 204 return command; 205 } 206 207 //------------------------------------------------------------------------------ 208 MakeCommand(bit32 * command,bool isAddDummyCommand) const209 bit32* Texture::MakeCommand( bit32* command, bool isAddDummyCommand ) const 210 { 211 command = MakeFuncCommand( command, isAddDummyCommand ); 212 command = unit0.MakeCommand( command, false ); 213 command = unit1.MakeCommand( command, false ); 214 command = unit2.MakeCommand( command, false ); 215 command = unit3.MakeCommand( command, false ); 216 217 return command; 218 } 219 220 //------------------------------------------------------------------------------ 221 MakeFuncCommand(bit32 * command,bool isAddDummyCommand) const222 bit32* Texture::MakeFuncCommand( bit32* command, bool isAddDummyCommand ) const 223 { 224 if ( isAddDummyCommand ) 225 { 226 command = MakeDummyCommand_( command ); 227 } 228 229 // 0x080 230 *command++ = PICA_CMD_DATA_TEXTURE_FUNC( unit0.texType, unit1.texType, unit2.texType, 231 unit3.texCoord, unit3.texType, unit2.texCoord, 0x1 ); 232 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE_FUNC ); 233 234 return command; 235 } 236 237 //------------------------------------------------------------------------------ 238 MakeDisableCommand(bit32 * command,bool isAddDummyCommand)239 bit32* Texture::MakeDisableCommand( bit32* command, bool isAddDummyCommand ) 240 { 241 if ( isAddDummyCommand ) 242 { 243 command = MakeDummyCommand_( command ); 244 } 245 246 const PicaDataTexture0SamplerType texture0SamplerType = PICA_DATA_TEXTURE0_SAMPLER_TYPE_FALSE; 247 const PicaDataTexture1SamplerType texture1SamplerType = PICA_DATA_TEXTURE1_SAMPLER_TYPE_FALSE; 248 const PicaDataTexture2SamplerType texture2SamplerType = PICA_DATA_TEXTURE2_SAMPLER_TYPE_FALSE; 249 const PicaDataTexture2TexCoord texture2TexCoord = PICA_DATA_TEXTURE2_TEXCOORD_TEXTURE1; 250 const PicaDataTexture3SamplerType texture3SamplerType = PICA_DATA_TEXTURE3_SAMPLER_TYPE_FALSE; 251 const PicaDataTexture3TexCoord texture3TexCoord = PICA_DATA_TEXTURE3_TEXCOORD_TEXTURE0; 252 const bit32 clearTextureCache = 1; 253 254 // 0x080 255 *command++ = PICA_CMD_DATA_TEXTURE_FUNC( texture0SamplerType, 256 texture1SamplerType, 257 texture2SamplerType, 258 texture3TexCoord, 259 texture3SamplerType, 260 texture2TexCoord, 261 clearTextureCache ); 262 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE_FUNC ); 263 264 return command; 265 } 266 267 //------------------------------------------------------------------------------ 268 MakeDummyCommand_(bit32 * command)269 bit32* Texture::MakeDummyCommand_( bit32* command ) 270 { 271 // Send the dummy command to 0x080 three times 272 *command++ = 0x0; 273 *command++ = PICA_CMD_HEADER_BURST_BE( PICA_REG_TEXTURE_FUNC, 0x3, 0x0 ); 274 275 *command++ = 0x0; 276 *command++ = 0x0; 277 278 return command; 279 } 280 281 //------------------------------------------------------------------------------ 282 UnitBase()283 Texture::UnitBase::UnitBase() 284 : physicalAddr( 0 ), 285 width( 0 ), 286 height( 0 ), 287 format( PICA_DATA_TEXTURE_FORMAT_ETC1_RGB8_NATIVE_DMP ), 288 wrapT( PICA_DATA_TEXTURE_WRAP_REPEAT ), 289 wrapS( PICA_DATA_TEXTURE_WRAP_REPEAT ), 290 magFilter( PICA_DATA_TEXTURE_MAG_FILTER_NEAREST ), 291 minFilter( PICA_DATA_TEXTURE_MIN_FILTER_NEAREST ), 292 lodBias( 0.f ), 293 minLodLevel( 0 ), 294 maxLodLevel( 0 ), 295 borderColorR( 0 ), 296 borderColorG( 0 ), 297 borderColorB( 0 ), 298 borderColorA( 0 ) 299 { 300 } 301 302 //------------------------------------------------------------------------------ 303 Unit0(const Texture & texture_)304 Texture::Unit0::Unit0( const Texture& texture_ ) 305 : texType( PICA_DATA_TEXTURE0_SAMPLER_TYPE_TEXTURE_FALSE ), 306 cubeMapAddrPosX( 0 ), 307 cubeMapAddrNegX( 0 ), 308 cubeMapAddrPosY( 0 ), 309 cubeMapAddrNegY( 0 ), 310 cubeMapAddrPosZ( 0 ), 311 cubeMapAddrNegZ( 0 ), 312 m_Texture( texture_ ) 313 { 314 } 315 316 //------------------------------------------------------------------------------ 317 Unit1(const Texture & texture_)318 Texture::Unit1::Unit1( const Texture& texture_ ) 319 : texType( PICA_DATA_TEXTURE1_SAMPLER_TYPE_FALSE ), 320 m_Texture( texture_ ) 321 { 322 } 323 324 //------------------------------------------------------------------------------ 325 Unit2(const Texture & texture_)326 Texture::Unit2::Unit2( const Texture& texture_ ) 327 : texType( PICA_DATA_TEXTURE2_SAMPLER_TYPE_FALSE ), 328 texCoord( PICA_DATA_TEXTURE2_TEXCOORD_TEXTURE2 ), 329 m_Texture( texture_ ) 330 { 331 } 332 333 //------------------------------------------------------------------------------ 334 Unit3(const Texture & texture_)335 Texture::Unit3::Unit3( const Texture& texture_ ) 336 : texType( PICA_DATA_TEXTURE3_SAMPLER_TYPE_FALSE ), 337 texCoord( PICA_DATA_TEXTURE3_TEXCOORD_TEXTURE0 ), 338 m_Texture( texture_ ) 339 { 340 } 341 342 //------------------------------------------------------------------------------ 343 Texture()344 Texture::Texture() 345 : unit0( *this ), 346 unit1( *this ), 347 unit2( *this ), 348 unit3( *this ) 349 { 350 } 351 352 } // namespace CTR 353 } // namespace gr 354 } // namespace nn 355