1 /*---------------------------------------------------------------------------*
2 Project: Dolphin GD library
3 File: GDIndirect.c
4
5 Copyright 2001- 2003 Nintendo. 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 $Log: GDIndirect.c,v $
14 Revision 1.2 2006/02/20 04:24:39 mitu
15 Changed include path from dolphin/ to revolution/.
16
17 Revision 1.1.1.1 2005/05/12 02:15:49 yasuh-to
18 Ported from dolphin source tree.
19
20
21 2 2003/02/19 17:37 Hirose
22
23 1 2003/02/03 14:03 Hirose
24 Initial check in.
25
26 $NoKeywords: $
27 *---------------------------------------------------------------------------*/
28
29 #include <revolution/gd.h>
30 #include <revolution/os.h>
31
32 /*---------------------------------------------------------------------------*/
33
34 /*---------------------------------------------------------------------------*
35 Macros
36 *---------------------------------------------------------------------------*/
37 #define IND_TEX_MTX_EXP 10
38 #define IND_TEX_MTX_SCALE (f32)(1 << IND_TEX_MTX_EXP)
39 #define IND_TEX_MTX_MASK 0x7ff
40 #define IND_TEX_SCALE_BIAS 0x11
41
42
43 /*---------------------------------------------------------------------------*/
44 // Name: GDSetTevIndirect
45 //
46 // Desc: Compile the state of an Indirect texture object in to HW
47 // dependent values.
48 //
49 // Arguments: tev_stage: TEV stage name.
50 // ind_stage: Index of the Indirect texture being bound
51 // format: format of indirect texture offsets.
52 // bias_sel: Bias added to the texture offsets.
53 // matrix_sel: Selects texture offset matrix.
54 // wrap_s: Wrap value of Direct S coordinate.
55 // wrap_t: Wrap value of Direct T coordinate
56 // add_prev: Add output from previous stage to texture coords.
57 // utc_lod: Use the unmodified texture coordinates for LOD.
58 // alpha_sel: Selects indirect texture alpha output.
59 //
60 // Returns: none
61 //
62 /*---------------------------------------------------------------------------*/
GDSetTevIndirect(GXTevStageID tev_stage,GXIndTexStageID ind_stage,GXIndTexFormat format,GXIndTexBiasSel bias_sel,GXIndTexMtxID matrix_sel,GXIndTexWrap wrap_s,GXIndTexWrap wrap_t,GXBool add_prev,GXBool utc_lod,GXIndTexAlphaSel alpha_sel)63 void GDSetTevIndirect (
64 GXTevStageID tev_stage,
65 GXIndTexStageID ind_stage,
66 GXIndTexFormat format,
67 GXIndTexBiasSel bias_sel,
68 GXIndTexMtxID matrix_sel,
69 GXIndTexWrap wrap_s,
70 GXIndTexWrap wrap_t,
71 GXBool add_prev,
72 GXBool utc_lod,
73 GXIndTexAlphaSel alpha_sel )
74 {
75 GDWriteBPCmd( IND_CMD(
76 (ind_stage & 3),
77 (format & 3),
78 (bias_sel & 7),
79 (alpha_sel & 3),
80 (matrix_sel & 0x0F),
81 (wrap_s & 7),
82 (wrap_t & 7),
83 (utc_lod & 1),
84 (add_prev & 1),
85 (IND_CMD0_ID + (tev_stage & 0x0F)) ));
86 }
87
88 /*---------------------------------------------------------------------------*/
89 //
90 // Name: GDSetIndTexMtx
91 //
92 // Desc: Sets transformation matrix for indirect texture coordinates.
93 //
94 // Arguments: MtxId: Matrix Name.
95 // OffsetMatrix[3][2]: Matrix for the texture offsets.
96 // ScaleExp: Exponent value for scale ( scale = 2ScaleExp)
97 //
98 // Returns: none
99 //
100 /*---------------------------------------------------------------------------*/
GDSetIndTexMtx(GXIndTexMtxID mtx_id,const f32 offset[2][3],s8 scale_exp)101 void GDSetIndTexMtx ( GXIndTexMtxID mtx_id, const f32 offset[2][3], s8 scale_exp )
102 {
103 u32 id_offset;
104
105 switch ( mtx_id )
106 {
107 case GX_ITM_0:
108 id_offset = 0;
109 break;
110 case GX_ITM_1:
111 id_offset = 3;
112 break;
113 case GX_ITM_2:
114 id_offset = 6;
115 break;
116 default:
117 ASSERTMSG(0, "GDSetIndTexMtx: Invalid matrix id");
118 break;
119 }
120
121 scale_exp += IND_TEX_SCALE_BIAS;
122
123 GDWriteBPCmd( IND_MTXA(
124 (((s32)(offset[0][0] * IND_TEX_MTX_SCALE)) & IND_TEX_MTX_MASK),
125 (((s32)(offset[1][0] * IND_TEX_MTX_SCALE)) & IND_TEX_MTX_MASK),
126 (scale_exp & 0x03),
127 (IND_MTXA0_ID + id_offset) ));
128
129 GDWriteBPCmd( IND_MTXB(
130 (((s32)(offset[0][1] * IND_TEX_MTX_SCALE)) & IND_TEX_MTX_MASK),
131 (((s32)(offset[1][1] * IND_TEX_MTX_SCALE)) & IND_TEX_MTX_MASK),
132 ((scale_exp >> 2) & 0x03),
133 (IND_MTXB0_ID + id_offset) ));
134
135 GDWriteBPCmd( IND_MTXC(
136 (((s32)(offset[0][2] * IND_TEX_MTX_SCALE)) & IND_TEX_MTX_MASK),
137 (((s32)(offset[1][2] * IND_TEX_MTX_SCALE)) & IND_TEX_MTX_MASK),
138 ((scale_exp >> 4) & 0x03),
139 (IND_MTXC0_ID + id_offset) ));
140 }
141
142 /*---------------------------------------------------------------------------*/
143 //
144 // Name: GDSetIndTexScale
145 //
146 // Desc: Sets scale value for indirect textures.
147 //
148 // Args: indStageEven: Indirect stage id (must be even).
149 // scaleS0: Scale value for S (even stage).
150 // scaleT0: Scale value for T (even stage).
151 // scaleS1: Scale value for S (odd stage).
152 // scaleT1: Scale value for T (odd stage).
153 //
154 /*---------------------------------------------------------------------------*/
GDSetIndTexCoordScale(GXIndTexStageID indStageEven,GXIndTexScale scaleS0,GXIndTexScale scaleT0,GXIndTexScale scaleS1,GXIndTexScale scaleT1)155 void GDSetIndTexCoordScale (
156 GXIndTexStageID indStageEven,
157 GXIndTexScale scaleS0,
158 GXIndTexScale scaleT0,
159 GXIndTexScale scaleS1,
160 GXIndTexScale scaleT1 )
161 {
162 GDWriteBPCmd( RAS1_SS(
163 (scaleS0 & 0x0F),
164 (scaleT0 & 0x0F),
165 (scaleS1 & 0x0F),
166 (scaleT1 & 0x0F),
167 (RAS1_SS0_ID + ((indStageEven >> 1) & 0x01)) ));
168 }
169
170 /*---------------------------------------------------------------------------*/
171 //
172 // Name: GDSetIndTexOrder
173 //
174 // Desc: Associates direct texture maps and coordinate names
175 // with indirect texture maps.
176 //
177 // Arguments: texCoord0: Associated texcoord for indirect texture 0.
178 // texMap0: Associated texture map for indirect texture 0.
179 // texCoord1: Associated texcoord for indirect texture 1.
180 // texMap1: Associated texture map for indirect texture 1.
181 // texCoord2: Associated texcoord for indirect texture 2.
182 // texMap2: Associated texture map for indirect texture 2.
183 // texCoord3: Associated texcoord for indirect texture 3.
184 // texMap3: Associated texture map for indirect texture 3.
185 //
186 /*---------------------------------------------------------------------------*/
GDSetIndTexOrder(GXTexCoordID texCoord0,GXTexMapID texMap0,GXTexCoordID texCoord1,GXTexMapID texMap1,GXTexCoordID texCoord2,GXTexMapID texMap2,GXTexCoordID texCoord3,GXTexMapID texMap3)187 void GDSetIndTexOrder (
188 GXTexCoordID texCoord0,
189 GXTexMapID texMap0,
190 GXTexCoordID texCoord1,
191 GXTexMapID texMap1,
192 GXTexCoordID texCoord2,
193 GXTexMapID texMap2,
194 GXTexCoordID texCoord3,
195 GXTexMapID texMap3 )
196 {
197 GDWriteBPCmd( RAS1_IREF(
198 (texMap0 & 7),
199 (texCoord0 & 7),
200 (texMap1 & 7),
201 (texCoord1 & 7),
202 (texMap2 & 7),
203 (texCoord2 & 7),
204 (texMap3 & 7),
205 (texCoord3 & 7),
206 RAS1_IREF_ID) );
207 }
208
209 /*---------------------------------------------------------------------------*/
210 //
211 // Name: GDSetTevDirect
212 //
213 // Desc: Sets a TEV stage back to a normal, direct lookup.
214 //
215 // Arguments: tev_stage: TEV stage number.
216 //
217 /*---------------------------------------------------------------------------*/
GDSetTevDirect(GXTevStageID tev_stage)218 void GDSetTevDirect ( GXTevStageID tev_stage )
219 {
220 GDSetTevIndirect(tev_stage, GX_INDTEXSTAGE0, GX_ITF_8,
221 GX_ITB_NONE, GX_ITM_OFF, GX_ITW_OFF, GX_ITW_OFF,
222 GX_FALSE, GX_FALSE, GX_ITBA_OFF);
223 }
224
225 /*---------------------------------------------------------------------------*/
226 //
227 // Name: GDSetTevIndWarp
228 //
229 // Desc: Used for simple indirect texture warping.
230 //
231 /*---------------------------------------------------------------------------*/
GDSetTevIndWarp(GXTevStageID tev_stage,GXIndTexStageID ind_stage,GXBool signed_offset,GXBool replace_mode,GXIndTexMtxID matrix_sel)232 void GDSetTevIndWarp ( GXTevStageID tev_stage, GXIndTexStageID ind_stage,
233 GXBool signed_offset, GXBool replace_mode,
234 GXIndTexMtxID matrix_sel)
235 {
236 GXIndTexWrap wrap = (replace_mode) ? GX_ITW_0 : GX_ITW_OFF;
237
238 GDSetTevIndirect(tev_stage, // tev stage
239 ind_stage, // indirect stage
240 GX_ITF_8, // format
241 (signed_offset) ? GX_ITB_STU : GX_ITB_NONE, // bias
242 matrix_sel, // matrix select
243 wrap, // wrap direct S
244 wrap, // wrap direct T
245 GX_FALSE, // add prev stage output?
246 GX_FALSE, // use unmodified TC for LOD?
247 GX_ITBA_OFF ); // bump alpha select
248 }
249
250 /*---------------------------------------------------------------------------*/
251 //
252 // Name: GXSetTevIndTile
253 //
254 // Desc: Used for indirect texture tiling and pseudo-3D texturing.
255 //
256 /*---------------------------------------------------------------------------*/
GDSetTevIndTile(GXTevStageID tev_stage,GXIndTexStageID ind_stage,u16 tilesize_s,u16 tilesize_t,u16 tilespacing_s,u16 tilespacing_t,GXIndTexFormat format,GXIndTexMtxID matrix_sel,GXIndTexBiasSel bias_sel,GXIndTexAlphaSel alpha_sel)257 void GDSetTevIndTile ( GXTevStageID tev_stage, GXIndTexStageID ind_stage,
258 u16 tilesize_s, u16 tilesize_t,
259 u16 tilespacing_s, u16 tilespacing_t,
260 GXIndTexFormat format, GXIndTexMtxID matrix_sel,
261 GXIndTexBiasSel bias_sel, GXIndTexAlphaSel alpha_sel)
262 {
263 GXIndTexWrap wrap_s, wrap_t;
264 f32 mtx[2][3];
265
266 // Compute wrap parameters from tilesize
267 switch (tilesize_s) {
268 case 256: wrap_s = GX_ITW_256; break;
269 case 128: wrap_s = GX_ITW_128; break;
270 case 64: wrap_s = GX_ITW_64; break;
271 case 32: wrap_s = GX_ITW_32; break;
272 case 16: wrap_s = GX_ITW_16; break;
273 default:
274 ASSERTMSG(0, "GDSetTevIndTile: Invalid tilesize for S coordinate");
275 wrap_s = GX_ITW_OFF;
276 break;
277 }
278
279 switch (tilesize_t) {
280 case 256: wrap_t = GX_ITW_256; break;
281 case 128: wrap_t = GX_ITW_128; break;
282 case 64: wrap_t = GX_ITW_64; break;
283 case 32: wrap_t = GX_ITW_32; break;
284 case 16: wrap_t = GX_ITW_16; break;
285 default:
286 ASSERTMSG(0, "GDSetTevIndTile: Invalid tilesize for T coordinate");
287 wrap_t = GX_ITW_OFF;
288 break;
289 }
290
291 // compute the matrix using tilespacing values.
292 mtx[0][0] = ((f32) tilespacing_s / IND_TEX_MTX_SCALE);
293 mtx[0][1] = mtx[0][2] = 0.0f;
294 mtx[1][1] = ((f32) tilespacing_t / IND_TEX_MTX_SCALE);
295 mtx[1][0] = mtx[1][2] = 0.0f;
296 GDSetIndTexMtx(matrix_sel, mtx, IND_TEX_MTX_EXP);
297
298 GDSetTevIndirect(tev_stage, // tev stage
299 ind_stage, // indirect stage
300 format, // format
301 bias_sel, // bias select
302 matrix_sel, // matrix select
303 wrap_s, // wrap direct S
304 wrap_t, // wrap direct T
305 GX_FALSE, // add prev stage output?
306 GX_TRUE, // use unmodified TC for LOD?
307 alpha_sel); // bump alpha select
308 }
309
310 /*---------------------------------------------------------------------------*/
311 //
312 // Name: GDSetTevIndBumpST
313 //
314 // Desc: Set up TEV stages for environment-mapped bump-mapped texture
315 // lookup. The bump map is in ST space.
316 //
317 /*---------------------------------------------------------------------------*/
GDSetTevIndBumpST(GXTevStageID tev_stage,GXIndTexStageID ind_stage,GXIndTexMtxID matrix_sel)318 void GDSetTevIndBumpST ( GXTevStageID tev_stage, GXIndTexStageID ind_stage,
319 GXIndTexMtxID matrix_sel )
320 {
321 GXIndTexMtxID sm, tm;
322
323 switch(matrix_sel)
324 {
325 case GX_ITM_0:
326 sm = GX_ITM_S0;
327 tm = GX_ITM_T0;
328 break;
329 case GX_ITM_1:
330 sm = GX_ITM_S1;
331 tm = GX_ITM_T1;
332 break;
333 case GX_ITM_2:
334 sm = GX_ITM_S2;
335 tm = GX_ITM_T2;
336 break;
337 default:
338 ASSERTMSG(0, "GDSetTevIndBumpST: Invalid matrix selection");
339 }
340
341 GDSetTevIndirect(tev_stage, // tev stage
342 ind_stage, // indirect stage
343 GX_ITF_8, // format
344 GX_ITB_ST, // bias
345 sm, // matrix select
346 GX_ITW_0, // wrap direct S
347 GX_ITW_0, // wrap direct T
348 GX_FALSE, // add prev stage output?
349 GX_FALSE, // use unmodified TC for LOD?
350 GX_ITBA_OFF); // bump alpha select
351
352 GDSetTevIndirect((GXTevStageID) (tev_stage+1), // tev stage
353 ind_stage, // indirect stage
354 GX_ITF_8, // format
355 GX_ITB_ST, // bias
356 tm, // matrix select
357 GX_ITW_0, // wrap direct S
358 GX_ITW_0, // wrap direct T
359 GX_TRUE, // add prev stage output?
360 GX_FALSE, // use unmodified TC for LOD?
361 GX_ITBA_OFF); // bump alpha select
362
363 GDSetTevIndirect((GXTevStageID) (tev_stage+2), // tev stage
364 ind_stage, // indirect stage
365 GX_ITF_8, // format
366 GX_ITB_NONE, // bias
367 GX_ITM_OFF, // matrix select
368 GX_ITW_OFF, // wrap direct S
369 GX_ITW_OFF, // wrap direct T
370 GX_TRUE, // add prev stage output?
371 GX_FALSE, // use unmodified TC for LOD?
372 GX_ITBA_OFF); // bump alpha select
373 }
374
375 /*---------------------------------------------------------------------------*/
376 //
377 // Name: GDSetTevIndBumpXYZ
378 //
379 // Desc: Set up TEV stages for environment-mapped bump-mapped texture
380 // lookup. The bump map is in 3D object space.
381 //
382 /*---------------------------------------------------------------------------*/
GDSetTevIndBumpXYZ(GXTevStageID tev_stage,GXIndTexStageID ind_stage,GXIndTexMtxID matrix_sel)383 void GDSetTevIndBumpXYZ ( GXTevStageID tev_stage, GXIndTexStageID ind_stage,
384 GXIndTexMtxID matrix_sel )
385 {
386 GDSetTevIndirect(tev_stage, // tev stage
387 ind_stage, // indirect stage
388 GX_ITF_8, // format
389 GX_ITB_STU, // bias
390 matrix_sel, // matrix select
391 GX_ITW_OFF, // wrap direct S
392 GX_ITW_OFF, // wrap direct T
393 GX_FALSE, // add prev stage output?
394 GX_FALSE, // use unmodified TC for LOD?
395 GX_ITBA_OFF); // bump alpha select
396 }
397
398 /*---------------------------------------------------------------------------*/
399 //
400 // Name: GDSetTevIndRepeat
401 //
402 // Desc: Provides a texture coordinate that is the repeat of the
403 // TC computation from the previous stage. Intended only to
404 // be used with GDSetTevIndBumpST().
405 //
406 /*---------------------------------------------------------------------------*/
GDSetTevIndRepeat(GXTevStageID tev_stage)407 void GDSetTevIndRepeat ( GXTevStageID tev_stage )
408 {
409 GDSetTevIndirect(tev_stage, // tev stage
410 GX_INDTEXSTAGE0, // indirect stage
411 GX_ITF_8, // format
412 GX_ITB_NONE, // bias
413 GX_ITM_OFF, // matrix select
414 GX_ITW_0, // wrap direct S
415 GX_ITW_0, // wrap direct T
416 GX_TRUE, // add prev stage output?
417 GX_FALSE, // use unmodified TC for LOD?
418 GX_ITBA_OFF); // bump alpha select
419 }
420
421 /*---------------------------------------------------------------------------*/
422 //
423 // Name: __GDSetIndTexMask
424 //
425 // Desc: Sets new value of imask register.
426 // (Probably not necessary to do, though)
427 //
428 // Arguments: mask: Mask parameter.
429 //
430 /*---------------------------------------------------------------------------*/
__GDSetIndTexMask(u32 mask)431 void __GDSetIndTexMask ( u32 mask )
432 {
433 GDWriteBPCmd( IND_IMASK(
434 (mask & 0x0FF),
435 IND_IMASK_ID) );
436 }
437
438 /*---------------------------------------------------------------------------*/
439