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