1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     gr_Combiner.cpp
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: 25760 $
14  *---------------------------------------------------------------------------*/
15 
16 #include <nn/gr/CTR/gr_Combiner.h>
17 
18 namespace nn
19 {
20     namespace gr
21     {
22         namespace CTR
23         {
24 
MakeCommand(u32 * command) const25             u32* Combiner::MakeCommand( u32* command ) const
26             {
27                 for ( int stage_index = 0; stage_index < COMBINER_STAGE_MAX; ++ stage_index )
28                 {
29                     command = stage[ stage_index ].MakeCommand( command );
30                 }
31 
32                 return MakeCombinerBufferCommand( command );
33             }
34 
35             //------------------------------------------------------------------------------
36 
MakeCombinerBufferCommand(u32 * command) const37             u32* Combiner::MakeCombinerBufferCommand( u32* command ) const
38             {
39                 // 0x0e0
40                 *command++ =PICA_CMD_SET_TEX_ENV_BUFFER_INPUT(
41                     stage[ 1 ].rgb.bufferInput, stage[ 1 ].alpha.bufferInput,
42                     stage[ 2 ].rgb.bufferInput, stage[ 2 ].alpha.bufferInput,
43                     stage[ 3 ].rgb.bufferInput, stage[ 3 ].alpha.bufferInput,
44                     stage[ 4 ].rgb.bufferInput, stage[ 4 ].alpha.bufferInput );
45                 *command++ = PICA_CMD_HEADER_SINGLE_BE( PICA_REG_TEX_ENV_BUFFER_INPUT, 0x2 );
46 
47                 // 0x0fd
48 
49                 *command++ = bufferColorR | bufferColorG << 8 | bufferColorB << 16 | bufferColorA << 24;
50                 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV_BUFFER_COLOR );
51                 return command;
52             }
53 
54             //------------------------------------------------------------------------------
55 
MakeCommand(u32 * command) const56             u32* Combiner::Stage::MakeCommand( u32* command ) const
57             {
58                 NN_GR_ASSERT( PICA_REG_TEX_ENV0 <= headRegister &&
59                               PICA_REG_TEX_ENV5 >= headRegister );
60 
61                 *command++ = PICA_CMD_DATA_TEX_ENV_SRC(
62                     rgb.source[0],   rgb.source[1],   rgb.source[2],
63                     alpha.source[0], alpha.source[1], alpha.source[2] );
64 
65                 *command++ = PICA_CMD_HEADER_BURSTSEQ(
66                     headRegister,
67                     5 );
68 
69                 *command++ = PICA_CMD_DATA_TEX_ENV_OPERAND(
70                     rgb.operand[0],   rgb.operand[1],   rgb.operand[2],
71                     alpha.operand[0], alpha.operand[1], alpha.operand[2] );
72 
73                 *command++ = PICA_CMD_DATA_TEX_ENV_COMBINE(
74                     rgb.combine,
75                     alpha.combine );
76 
77                 *command++ = PICA_CMD_DATA_TEX_ENV_CONST(
78                     constColorR, constColorG, constColorB,
79                     constColorA );
80 
81                 *command++ = PICA_CMD_DATA_TEX_ENV_SCALE(
82                     rgb.scale,
83                     alpha.scale );
84 
85                 return command;
86             }
87 
88             //------------------------------------------------------------------------------
89 
SetupPrimary()90             void Combiner::Stage::SetupPrimary()
91             {
92                 rgb.combine       = PICA_DATA_TEX_ENV_COMBINE_REPLACE;
93                 rgb.operand[0]    = PICA_DATA_OPE_RGB_SRC_COLOR;
94                 rgb.operand[1]    = PICA_DATA_OPE_RGB_SRC_COLOR;
95                 rgb.operand[2]    = PICA_DATA_OPE_RGB_SRC_COLOR;
96                 rgb.source[0]     = PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR;
97                 rgb.source[1]     = PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR;
98                 rgb.source[2]     = PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR;
99                 rgb.scale         = PICA_DATA_TEX_ENV_SCALE_1;
100                 rgb.bufferInput   = PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS_BUFFER_DMP;
101 
102                 alpha.combine     = PICA_DATA_TEX_ENV_COMBINE_REPLACE;
103                 alpha.operand[0]  = PICA_DATA_OPE_ALPHA_SRC_ALPHA;
104                 alpha.operand[1]  = PICA_DATA_OPE_ALPHA_SRC_ALPHA;
105                 alpha.operand[2]  = PICA_DATA_OPE_ALPHA_SRC_ALPHA;
106                 alpha.source[0]   = PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR;
107                 alpha.source[1]   = PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR;
108                 alpha.source[2]   = PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR;
109                 alpha.scale       = PICA_DATA_TEX_ENV_SCALE_1;
110                 alpha.bufferInput = PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS_BUFFER_DMP;
111             }
112 
113             //------------------------------------------------------------------------------
114 
SetupFragmentPrimary()115             void Combiner::Stage::SetupFragmentPrimary()
116             {
117                 rgb.combine       = PICA_DATA_TEX_ENV_COMBINE_REPLACE;
118                 rgb.operand[0]    = PICA_DATA_OPE_RGB_SRC_COLOR;
119                 rgb.operand[1]    = PICA_DATA_OPE_RGB_SRC_COLOR;
120                 rgb.operand[2]    = PICA_DATA_OPE_RGB_SRC_COLOR;
121                 rgb.source[0]     = PICA_DATA_TEX_ENV_SRC_RGBA_FRAGMENT_PRIMARY_COLOR_DMP;
122                 rgb.source[1]     = PICA_DATA_TEX_ENV_SRC_RGBA_FRAGMENT_PRIMARY_COLOR_DMP;
123                 rgb.source[2]     = PICA_DATA_TEX_ENV_SRC_RGBA_FRAGMENT_PRIMARY_COLOR_DMP;
124                 rgb.scale         = PICA_DATA_TEX_ENV_SCALE_1;
125                 rgb.bufferInput   = PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS_BUFFER_DMP;
126 
127                 alpha.combine     = PICA_DATA_TEX_ENV_COMBINE_REPLACE;
128                 alpha.operand[0]  = PICA_DATA_OPE_ALPHA_SRC_ALPHA;
129                 alpha.operand[1]  = PICA_DATA_OPE_ALPHA_SRC_ALPHA;
130                 alpha.operand[2]  = PICA_DATA_OPE_ALPHA_SRC_ALPHA;
131                 alpha.source[0]   = PICA_DATA_TEX_ENV_SRC_RGBA_FRAGMENT_PRIMARY_COLOR_DMP;
132                 alpha.source[1]   = PICA_DATA_TEX_ENV_SRC_RGBA_FRAGMENT_PRIMARY_COLOR_DMP;
133                 alpha.source[2]   = PICA_DATA_TEX_ENV_SRC_RGBA_FRAGMENT_PRIMARY_COLOR_DMP;
134                 alpha.scale       = PICA_DATA_TEX_ENV_SCALE_1;
135                 alpha.bufferInput = PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS_BUFFER_DMP;
136             }
137 
SetupTexture0()138             void Combiner::Stage::SetupTexture0()
139             {
140                 rgb.combine       = PICA_DATA_TEX_ENV_COMBINE_REPLACE;
141                 rgb.operand[0]    = PICA_DATA_OPE_RGB_SRC_COLOR;
142                 rgb.operand[1]    = PICA_DATA_OPE_RGB_SRC_COLOR;
143                 rgb.operand[2]    = PICA_DATA_OPE_RGB_SRC_COLOR;
144                 rgb.source[0]     = PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0;
145                 rgb.source[1]     = PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0;
146                 rgb.source[2]     = PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0;
147                 rgb.scale         = PICA_DATA_TEX_ENV_SCALE_1;
148                 rgb.bufferInput   = PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS_BUFFER_DMP;
149 
150                 alpha.combine     = PICA_DATA_TEX_ENV_COMBINE_REPLACE;
151                 alpha.operand[0]  = PICA_DATA_OPE_ALPHA_SRC_ALPHA;
152                 alpha.operand[1]  = PICA_DATA_OPE_ALPHA_SRC_ALPHA;
153                 alpha.operand[2]  = PICA_DATA_OPE_ALPHA_SRC_ALPHA;
154                 alpha.source[0]   = PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0;
155                 alpha.source[1]   = PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0;
156                 alpha.source[2]   = PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0;
157                 alpha.scale       = PICA_DATA_TEX_ENV_SCALE_1;
158                 alpha.bufferInput = PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS_BUFFER_DMP;
159             }
160 
161             //------------------------------------------------------------------------------
162 
SetupPrevious()163             void Combiner::Stage::SetupPrevious()
164             {
165                 rgb.combine       = PICA_DATA_TEX_ENV_COMBINE_REPLACE;
166                 rgb.operand[0]    = PICA_DATA_OPE_RGB_SRC_COLOR;
167                 rgb.operand[1]    = PICA_DATA_OPE_RGB_SRC_COLOR;
168                 rgb.operand[2]    = PICA_DATA_OPE_RGB_SRC_COLOR;
169                 rgb.source[0]     = PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS;
170                 rgb.source[1]     = PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS;
171                 rgb.source[2]     = PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS;
172                 rgb.scale         = PICA_DATA_TEX_ENV_SCALE_1;
173                 rgb.bufferInput   = PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS_BUFFER_DMP;
174 
175                 alpha.combine     = PICA_DATA_TEX_ENV_COMBINE_REPLACE;
176                 alpha.operand[0]  = PICA_DATA_OPE_ALPHA_SRC_ALPHA;
177                 alpha.operand[1]  = PICA_DATA_OPE_ALPHA_SRC_ALPHA;
178                 alpha.operand[2]  = PICA_DATA_OPE_ALPHA_SRC_ALPHA;
179                 alpha.source[0]   = PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS;
180                 alpha.source[1]   = PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS;
181                 alpha.source[2]   = PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS;
182                 alpha.scale       = PICA_DATA_TEX_ENV_SCALE_1;
183                 alpha.bufferInput = PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS_BUFFER_DMP;
184             }
185 
186             //------------------------------------------------------------------------------
187 
SetupPrimaryModulateTexture0()188             void Combiner::Stage::SetupPrimaryModulateTexture0()
189             {
190                 rgb.combine       = PICA_DATA_TEX_ENV_COMBINE_MODULATE;
191                 rgb.operand[0]    = PICA_DATA_OPE_RGB_SRC_COLOR;
192                 rgb.operand[1]    = PICA_DATA_OPE_RGB_SRC_COLOR;
193                 rgb.operand[2]    = PICA_DATA_OPE_RGB_SRC_COLOR;
194                 rgb.source[0]     = PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR;
195                 rgb.source[1]     = PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0;
196                 rgb.source[2]     = PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS;
197                 rgb.scale         = PICA_DATA_TEX_ENV_SCALE_1;
198                 rgb.bufferInput   = PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS_BUFFER_DMP;
199 
200                 alpha.combine     = PICA_DATA_TEX_ENV_COMBINE_MODULATE;
201                 alpha.operand[0]  = PICA_DATA_OPE_ALPHA_SRC_ALPHA;
202                 alpha.operand[1]  = PICA_DATA_OPE_ALPHA_SRC_ALPHA;
203                 alpha.operand[2]  = PICA_DATA_OPE_ALPHA_SRC_ALPHA;
204                 alpha.source[0]   = PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR;
205                 alpha.source[1]   = PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0;
206                 alpha.source[2]   = PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS;
207                 alpha.scale       = PICA_DATA_TEX_ENV_SCALE_1;
208                 alpha.bufferInput = PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS_BUFFER_DMP;
209             }
210 
211             //------------------------------------------------------------------------------
212 
SetupFragmentPrimaryModulateTexture0()213             void Combiner::Stage::SetupFragmentPrimaryModulateTexture0()
214             {
215                 rgb.combine       = PICA_DATA_TEX_ENV_COMBINE_MODULATE;
216                 rgb.operand[0]    = PICA_DATA_OPE_RGB_SRC_COLOR;
217                 rgb.operand[1]    = PICA_DATA_OPE_RGB_SRC_COLOR;
218                 rgb.operand[2]    = PICA_DATA_OPE_RGB_SRC_COLOR;
219                 rgb.source[0]     = PICA_DATA_TEX_ENV_SRC_RGBA_FRAGMENT_PRIMARY_COLOR_DMP;
220                 rgb.source[1]     = PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0;
221                 rgb.source[2]     = PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS;
222                 rgb.scale         = PICA_DATA_TEX_ENV_SCALE_1;
223                 rgb.bufferInput   = PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS_BUFFER_DMP;
224 
225                 alpha.combine     = PICA_DATA_TEX_ENV_COMBINE_MODULATE;
226                 alpha.operand[0]  = PICA_DATA_OPE_ALPHA_SRC_ALPHA;
227                 alpha.operand[1]  = PICA_DATA_OPE_ALPHA_SRC_ALPHA;
228                 alpha.operand[2]  = PICA_DATA_OPE_ALPHA_SRC_ALPHA;
229                 alpha.source[0]   = PICA_DATA_TEX_ENV_SRC_RGBA_FRAGMENT_PRIMARY_COLOR_DMP;
230                 alpha.source[1]   = PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0;
231                 alpha.source[2]   = PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS;
232                 alpha.scale       = PICA_DATA_TEX_ENV_SCALE_1;
233                 alpha.bufferInput = PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS_BUFFER_DMP;
234             }
235 
236             //------------------------------------------------------------------------------
237 
Combiner()238             Combiner::Combiner()
239                 : bufferColorR( 0 ),
240                   bufferColorG( 0 ),
241                   bufferColorB( 0 ),
242                   bufferColorA( 0 )
243             {
244                 for ( int stage_index = 0; stage_index < COMBINER_STAGE_MAX; ++stage_index )
245                 {
246                     stage[ stage_index ] = Stage( stage_index );
247                 }
248             }
249 
250             //------------------------------------------------------------------------------
251 
Stage(const int stage_index)252             Combiner::Stage::Stage( const int stage_index )
253                 : rgb  ( stage_index, true ),
254                   alpha( stage_index, false ),
255                   constColorR( 0 ),
256                   constColorG( 0 ),
257                   constColorB( 0 ),
258                   constColorA( 0 )
259             {
260                 switch( stage_index )
261                 {
262                 case 0 : headRegister = PICA_REG_TEX_ENV0; break;
263                 case 1 : headRegister = PICA_REG_TEX_ENV1; break;
264                 case 2 : headRegister = PICA_REG_TEX_ENV2; break;
265                 case 3 : headRegister = PICA_REG_TEX_ENV3; break;
266                 case 4 : headRegister = PICA_REG_TEX_ENV4; break;
267                 case 5 : headRegister = PICA_REG_TEX_ENV5; break;
268                 }
269             }
270             //------------------------------------------------------------------------------
271 
CombineFunction(const u8 stage_index,bool is_rgb)272             Combiner::Stage::CombineFunction::CombineFunction( const u8 stage_index, bool is_rgb )
273                 : combine( PICA_DATA_TEX_ENV_COMBINE_REPLACE ),
274                   scale( PICA_DATA_TEX_ENV_SCALE_1 ),
275                   bufferInput( PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS_BUFFER_DMP )
276             {
277                 operand[ 0 ] = operand[ 1 ] = operand[ 2 ] =
278                     ( is_rgb )
279                         ? PICA_DATA_OPE_RGB_SRC_COLOR
280                         : PICA_DATA_OPE_ALPHA_SRC_ALPHA;
281 
282                 source[ 0 ] = source[ 1 ] = source[ 2 ] =
283                     ( stage_index == 0 )
284                         ? PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT
285                         : PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS;
286             }
287 
288         } // namespace CTR
289     } // namespace gr
290 } // namespace nn
291