11 #include "video_types.h"
12 #include "lwp_watchdog.h"
14 #include "gx_regdef.h"
17 #define TEXCACHE_TESTING
23 #define LARGE_NUMBER (-1048576.0f)
25 #define LARGE_NUMBER (-1.0e+18f)
28 #define _SHIFTL(v, s, w) \
29 ((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s)))
30 #define _SHIFTR(v, s, w) \
31 ((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1)))
33 #define GX_LOAD_BP_REG(x) \
36 wgPipe->U32 = (u32)(x); \
39 #define GX_LOAD_CP_REG(x, y) \
42 wgPipe->U8 = (u8)(x); \
43 wgPipe->U32 = (u32)(y); \
46 #define GX_LOAD_XF_REG(x, y) \
49 wgPipe->U32 = (u32)((x)&0xffff); \
50 wgPipe->U32 = (u32)(y); \
53 #define GX_LOAD_XF_REGS(x, n) \
56 wgPipe->U32 = (u32)(((((n)&0xffff)-1)<<16)|((x)&0xffff)); \
59 #define XY(x, y) (((y) << 10) | (x))
61 #define GX_DEFAULT_BG {64,64,64,255}
62 #define BLACK {0,0,0,0}
63 #define WHITE {255,255,255,255}
65 WGPipe
* const wgPipe
= (WGPipe
*)0xCC008000;
67 static GXFifoObj _gpfifo
;
68 static GXFifoObj _cpufifo
;
69 static GXFifoObj _gxfifoobj
;
70 static GXFifoObj _gx_dl_fifoobj
;
71 static GXFifoObj _gx_old_cpufifo
;
72 static void *_gxcurrbp
= NULL
;
73 static lwp_t _gxcurrentlwp
= LWP_THREAD_NULL
;
75 static u32 _gxcpufifoready
= 0;
76 static u32 _gxgpfifoready
= 0;
77 static u32 _cpgplinked
= 0;
78 static u16 _gxgpstatus
= 0;
79 static vu32 _gxoverflowsuspend
= 0;
80 static vu32 _gxoverflowcount
= 0;
81 static vu32 _gxfinished
= 0;
82 static lwpq_t _gxwaitfinish
;
84 static GXBreakPtCallback breakPtCB
= NULL
;
85 static GXDrawDoneCallback drawDoneCB
= NULL
;
86 static GXDrawSyncCallback tokenCB
= NULL
;
88 static GXTexRegionCallback regionCB
= NULL
;
89 static GXTlutRegionCallback tlut_regionCB
= NULL
;
91 static vu32
* const _piReg
= (u32
*)0xCC003000;
92 static vu16
* const _cpReg
= (u16
*)0xCC000000;
93 static vu16
* const _peReg
= (u16
*)0xCC001000;
94 static vu16
* const _memReg
= (u16
*)0xCC004000;
96 static u8 _gxtevcolid
[9] = {0,1,0,1,0,1,7,5,6};
97 static u8 _gxtexmode0ids
[8] = {0x80,0x81,0x82,0x83,0xA0,0xA1,0xA2,0xA3};
98 static u8 _gxtexmode1ids
[8] = {0x84,0x85,0x86,0x87,0xA4,0xA5,0xA6,0xA7};
99 static u8 _gxteximg0ids
[8] = {0x88,0x89,0x8A,0x8B,0xA8,0xA9,0xAA,0xAB};
100 static u8 _gxteximg1ids
[8] = {0x8C,0x8D,0x8E,0x8F,0xAC,0xAD,0xAE,0xAF};
101 static u8 _gxteximg2ids
[8] = {0x90,0x91,0x92,0x93,0xB0,0xB1,0xB2,0xB3};
102 static u8 _gxteximg3ids
[8] = {0x94,0x95,0x96,0x97,0xB4,0xB5,0xB6,0xB7};
103 static u8 _gxtextlutids
[8] = {0x98,0x99,0x9A,0x9B,0xB8,0xB9,0xBA,0xBB};
106 static u32 _gxtexregionaddrtable
[48] =
108 0x00000000,0x00010000,0x00020000,0x00030000,
109 0x00040000,0x00050000,0x00060000,0x00070000,
110 0x00008000,0x00018000,0x00028000,0x00038000,
111 0x00048000,0x00058000,0x00068000,0x00078000,
112 0x00000000,0x00090000,0x00020000,0x000B0000,
113 0x00040000,0x00098000,0x00060000,0x000B8000,
114 0x00080000,0x00010000,0x000A0000,0x00030000,
115 0x00088000,0x00050000,0x000A8000,0x00070000,
116 0x00000000,0x00090000,0x00020000,0x000B0000,
117 0x00040000,0x00090000,0x00060000,0x000B0000,
118 0x00080000,0x00010000,0x000A0000,0x00030000,
119 0x00080000,0x00050000,0x000A0000,0x00070000
124 extern u8 __gxregs
[];
125 static struct __gx_regdef
*__gx
= (struct __gx_regdef
*)__gxregs
;
126 static u8 _gx_saved_data
[STRUCT_REGDEF_SIZE
] ATTRIBUTE_ALIGN(32);
128 static s32
__gx_onreset(s32 final
);
130 static sys_resetinfo __gx_resetinfo
= {
137 extern int printk(const char *fmt
,...);
140 static __inline__ BOOL
IsWriteGatherBufferEmpty()
142 return !(mfwpar()&1);
145 static __inline__
void DisableWriteGatherPipe()
147 mthid2((mfhid2()&~0x40000000));
150 static __inline__
void EnableWriteGatherPipe()
153 mthid2((mfhid2()|0x40000000));
156 static __inline__
void __GX_ResetWriteGatherPipe()
162 static __inline__
void __GX_FifoLink(u8 enable
)
164 __gx
->cpCRreg
= ((__gx
->cpCRreg
&~0x10)|(_SHIFTL(enable
,4,1)));
165 _cpReg
[1] = __gx
->cpCRreg
;
168 static __inline__
void __GX_WriteFifoIntReset(u8 inthi
,u8 intlo
)
170 __gx
->cpCLreg
= ((__gx
->cpCLreg
&~0x03)|(_SHIFTL(intlo
,1,1))|(inthi
&1));
171 _cpReg
[2] = __gx
->cpCLreg
;
174 static __inline__
void __GX_WriteFifoIntEnable(u8 inthi
, u8 intlo
)
176 __gx
->cpCRreg
= ((__gx
->cpCRreg
&~0x0C)|(_SHIFTL(intlo
,3,1))|(_SHIFTL(inthi
,2,1)));
177 _cpReg
[1] = __gx
->cpCRreg
;
180 static __inline__
void __GX_FifoReadEnable()
182 __gx
->cpCRreg
= ((__gx
->cpCRreg
&~0x01)|1);
183 _cpReg
[1] = __gx
->cpCRreg
;
186 static __inline__
void __GX_FifoReadDisable()
188 __gx
->cpCRreg
= ((__gx
->cpCRreg
&~0x01)|0);
189 _cpReg
[1] = __gx
->cpCRreg
;
192 static s32
__gx_onreset(s32 final
)
201 static u32
__GX_IsGPCPUFifoLinked()
206 static u32
__GX_IsGPFifoReady()
208 return _gxgpfifoready
;
211 static u32
__GX_IsCPUFifoReady()
213 return _gxcpufifoready
;
216 static u32
__GX_CPGPLinkCheck()
218 struct __gxfifo
*gpfifo
= (struct __gxfifo
*)&_gpfifo
;
219 struct __gxfifo
*cpufifo
= (struct __gxfifo
*)&_cpufifo
;
221 if(!_gxcpufifoready
|| !_gxgpfifoready
) return 0;
223 if((cpufifo
->buf_start
==gpfifo
->buf_start
)&&(cpufifo
->buf_end
==gpfifo
->buf_end
)) return 1;
228 static void __GX_InitRevBits()
234 __gx
->VAT0reg
[i
] = 0x40000000;
235 __gx
->VAT1reg
[i
] = 0x80000000;
236 GX_LOAD_CP_REG((0x0080|i
),__gx
->VAT1reg
[i
]);
240 GX_LOAD_XF_REG(0x1000,0x3f);
241 GX_LOAD_XF_REG(0x1012,0x01);
243 GX_LOAD_BP_REG(0x5800000f);
247 static void __GX_WaitAbort(u32 delay
)
254 if(diff_ticks(start
,end
)>=(u64
)delay
) break;
258 static u32
__GX_ReadMemCounterU32(u32 reg
)
265 lcnt
= _memReg
[reg
+1];
268 return (u32
)((ucnt
<<16)|lcnt
);
271 static void __GX_WaitAbortPixelEngine()
275 cnt
= __GX_ReadMemCounterU32(39);
279 cnt
= __GX_ReadMemCounterU32(39);
283 static void __GX_Abort()
285 if(__gx
->gxFifoInited
&& __GX_IsGPFifoReady())
286 __GX_WaitAbortPixelEngine();
295 static void __GX_SaveFifo()
299 struct __gxfifo
*cpufifo
= (struct __gxfifo
*)&_cpufifo
;
300 struct __gxfifo
*gpfifo
= (struct __gxfifo
*)&_gpfifo
;
302 _CPU_ISR_Disable(level
);
304 if(_gxcpufifoready
) {
306 cpufifo
->wt_ptr
= (u32
)MEM_PHYSICAL_TO_K0((val
&0x1FFFFFE0));
307 cpufifo
->fifo_wrap
= ((val
&0x20000000)==0x20000000);
311 gpfifo
->rd_ptr
= (u32
)MEM_PHYSICAL_TO_K0(_SHIFTL(_cpReg
[29],16,16)|(_cpReg
[28]&0xffff));
312 gpfifo
->rdwt_dst
= (_SHIFTL(_cpReg
[25],16,16)|(_cpReg
[24]&0xffff));
316 cpufifo
->rd_ptr
= gpfifo
->rd_ptr
;
317 cpufifo
->rdwt_dst
= gpfifo
->rdwt_dst
;
318 gpfifo
->wt_ptr
= cpufifo
->wt_ptr
;
319 } else if(_gxcpufifoready
) {
320 rdwt_dst
= (cpufifo
->wt_ptr
- cpufifo
->rd_ptr
);
321 if(rdwt_dst
<0) cpufifo
->rdwt_dst
= (cpufifo
->rdwt_dst
+ cpufifo
->size
);
322 else cpufifo
->rdwt_dst
= rdwt_dst
;
325 _CPU_ISR_Restore(level
);
328 static void __GX_CleanGPFifo()
331 struct __gxfifo
*gpfifo
= (struct __gxfifo
*)&_gpfifo
;
332 struct __gxfifo
*cpufifo
= (struct __gxfifo
*)&_cpufifo
;
334 if(!_gxgpfifoready
) return;
336 _CPU_ISR_Disable(level
);
337 __GX_FifoReadDisable();
338 __GX_WriteFifoIntEnable(FALSE
,FALSE
);
340 gpfifo
->rd_ptr
= gpfifo
->wt_ptr
;
341 gpfifo
->rdwt_dst
= 0;
343 /* setup rd<->wd dist */
344 _cpReg
[24] = _SHIFTL(gpfifo
->rdwt_dst
,0,16);
345 _cpReg
[25] = _SHIFTR(gpfifo
->rdwt_dst
,16,16);
348 _cpReg
[26] = _SHIFTL(MEM_VIRTUAL_TO_PHYSICAL(gpfifo
->wt_ptr
),0,16);
349 _cpReg
[27] = _SHIFTR(MEM_VIRTUAL_TO_PHYSICAL(gpfifo
->wt_ptr
),16,16);
352 _cpReg
[28] = _SHIFTL(MEM_VIRTUAL_TO_PHYSICAL(gpfifo
->rd_ptr
),0,16);
353 _cpReg
[29] = _SHIFTR(MEM_VIRTUAL_TO_PHYSICAL(gpfifo
->rd_ptr
),16,16);
357 cpufifo
->rd_ptr
= gpfifo
->rd_ptr
;
358 cpufifo
->wt_ptr
= gpfifo
->wt_ptr
;
359 cpufifo
->rdwt_dst
= gpfifo
->rdwt_dst
;
361 _piReg
[5] = (cpufifo
->wt_ptr
&0x1FFFFFE0);
362 __GX_WriteFifoIntEnable(TRUE
,FALSE
);
365 __gx
->cpCRreg
&= ~0x22;
366 _cpReg
[1] = __gx
->cpCRreg
;
369 __GX_WriteFifoIntReset(TRUE
,TRUE
);
370 __GX_FifoReadEnable();
371 _CPU_ISR_Restore(level
);
374 static void __GXOverflowHandler()
376 if(!_gxoverflowsuspend
) {
377 _gxoverflowsuspend
= 1;
379 __GX_WriteFifoIntEnable(GX_DISABLE
,GX_ENABLE
);
380 __GX_WriteFifoIntReset(GX_TRUE
,GX_FALSE
);
381 LWP_SuspendThread(_gxcurrentlwp
);
385 static void __GXUnderflowHandler()
387 if(_gxoverflowsuspend
) {
388 _gxoverflowsuspend
= 0;
389 LWP_ResumeThread(_gxcurrentlwp
);
390 __GX_WriteFifoIntReset(GX_TRUE
,GX_TRUE
);
391 __GX_WriteFifoIntEnable(GX_ENABLE
,GX_DISABLE
);
395 static void __GXCPInterruptHandler(u32 irq
,void *ctx
)
397 __gx
->cpSRreg
= _cpReg
[0];
399 if((__gx
->cpCRreg
&0x08) && (__gx
->cpSRreg
&0x02))
400 __GXUnderflowHandler();
402 if((__gx
->cpCRreg
&0x04) && (__gx
->cpSRreg
&0x01))
403 __GXOverflowHandler();
405 if((__gx
->cpCRreg
&0x20) && (__gx
->cpSRreg
&0x10)) {
406 __gx
->cpCRreg
&= ~0x20;
407 _cpReg
[1] = __gx
->cpCRreg
;
413 static void __GXTokenInterruptHandler(u32 irq
,void *ctx
)
415 u16 token
= _peReg
[7];
420 _peReg
[5] = (_peReg
[5]&~0x04)|0x04;
423 static void __GXFinishInterruptHandler(u32 irq
,void *ctx
)
426 printf("__GXFinishInterruptHandler()\n");
428 _peReg
[5] = (_peReg
[5]&~0x08)|0x08;
434 LWP_ThreadBroadcast(_gxwaitfinish
);
437 static void __GX_PEInit()
439 IRQ_Request(IRQ_PI_PETOKEN
,__GXTokenInterruptHandler
,NULL
);
440 __UnmaskIrq(IRQMASK(IRQ_PI_PETOKEN
));
442 IRQ_Request(IRQ_PI_PEFINISH
,__GXFinishInterruptHandler
,NULL
);
443 __UnmaskIrq(IRQMASK(IRQ_PI_PEFINISH
));
448 static void __GX_FifoInit()
450 IRQ_Request(IRQ_PI_CP
,__GXCPInterruptHandler
,NULL
);
451 __UnmaskIrq(IRQMASK(IRQ_PI_CP
));
453 memset(&_cpufifo
,0,sizeof(GXFifoObj
));
454 memset(&_gpfifo
,0,sizeof(GXFifoObj
));
459 _gxoverflowsuspend
= 0;
460 _gxcurrentlwp
= LWP_GetSelf();
463 static void __GX_SetTmemConfig(u8 nr
)
466 // Set_TextureImage0-3, GXTexMapID=0-3 tmem_offset=00000000, cache_width=32 kb, cache_height=32 kb, image_type=cached
467 GX_LOAD_BP_REG(0x8c0d8000);
468 GX_LOAD_BP_REG(0x900dc000);
469 GX_LOAD_BP_REG(0x8d0d8400);
470 GX_LOAD_BP_REG(0x910dc400);
471 GX_LOAD_BP_REG(0x8e0d8800);
472 GX_LOAD_BP_REG(0x920dc800);
473 GX_LOAD_BP_REG(0x8f0d8c00);
474 GX_LOAD_BP_REG(0x930dcc00);
476 // Set_TextureImage0-3, GXTexMapID=4-7 tmem_offset=00010000, cache_width=32 kb, cache_height=32 kb, image_type=cached
477 GX_LOAD_BP_REG(0xac0d9000);
478 GX_LOAD_BP_REG(0xb00dd000);
479 GX_LOAD_BP_REG(0xad0d9400);
480 GX_LOAD_BP_REG(0xb10dd400);
481 GX_LOAD_BP_REG(0xae0d9800);
482 GX_LOAD_BP_REG(0xb20dd800);
483 GX_LOAD_BP_REG(0xaf0d9c00);
484 GX_LOAD_BP_REG(0xb30ddc00);
490 // Set_TextureImage0-3, GXTexMapID=0-3 tmem_offset=00000000, cache_width=32 kb, cache_height=32 kb, image_type=cached
491 GX_LOAD_BP_REG(0x8c0d8000);
492 GX_LOAD_BP_REG(0x900dc000);
493 GX_LOAD_BP_REG(0x8d0d8800);
494 GX_LOAD_BP_REG(0x910dc800);
495 GX_LOAD_BP_REG(0x8e0d9000);
496 GX_LOAD_BP_REG(0x920dd000);
497 GX_LOAD_BP_REG(0x8f0d9800);
498 GX_LOAD_BP_REG(0x930dd800);
500 // Set_TextureImage0-3, GXTexMapID=4-7 tmem_offset=00010000, cache_width=32 kb, cache_height=32 kb, image_type=cached
501 GX_LOAD_BP_REG(0xac0da000);
502 GX_LOAD_BP_REG(0xb00de000);
503 GX_LOAD_BP_REG(0xad0da800);
504 GX_LOAD_BP_REG(0xb10de800);
505 GX_LOAD_BP_REG(0xae0db000);
506 GX_LOAD_BP_REG(0xb20df000);
507 GX_LOAD_BP_REG(0xaf0db800);
508 GX_LOAD_BP_REG(0xb30df800);
514 // Set_TextureImage0-3, GXTexMapID=0-3 tmem_offset=00000000, cache_width=32 kb, cache_height=32 kb, image_type=cached
515 GX_LOAD_BP_REG(0x8c0d8000);
516 GX_LOAD_BP_REG(0x900dc000);
517 GX_LOAD_BP_REG(0x8d0d8800);
518 GX_LOAD_BP_REG(0x910dc800);
519 GX_LOAD_BP_REG(0x8e0d9000);
520 GX_LOAD_BP_REG(0x920dd000);
521 GX_LOAD_BP_REG(0x8f0d9800);
522 GX_LOAD_BP_REG(0x930dd800);
524 // Set_TextureImage0-3, GXTexMapID=4-7 tmem_offset=00010000, cache_width=32 kb, cache_height=32 kb, image_type=cached
525 GX_LOAD_BP_REG(0xac0da000);
526 GX_LOAD_BP_REG(0xb00dc400);
527 GX_LOAD_BP_REG(0xad0da800);
528 GX_LOAD_BP_REG(0xb10dcc00);
529 GX_LOAD_BP_REG(0xae0db000);
530 GX_LOAD_BP_REG(0xb20dd400);
531 GX_LOAD_BP_REG(0xaf0db800);
532 GX_LOAD_BP_REG(0xb30ddc00);
539 static GXTexRegion
* __GXDefTexRegionCallback(GXTexObj
*obj
,u8 mapid
)
542 GXTexRegion
*ret
= NULL
;
544 fmt
= GX_GetTexObjFmt(obj
);
545 mipmap
= GX_GetTexObjMipMap(obj
);
546 if(fmt
>=GX_TF_CI4
&& fmt
<=GX_TF_CI14
)
547 return &__gx
->texRegion
[mapid
];
548 else if(fmt
==GX_TF_CMPR
)
549 ret
= &__gx
->texRegion
[mapid
];
551 ret
= &__gx
->texRegion
[mapid
+8];
553 if(mipmap
) ret
= &__gx
->texRegion
[mapid
+16];
558 static GXTexRegion
* __GXDefTexRegionCallback(GXTexObj
*obj
,u8 mapid
)
562 static u32 regionA
= 0;
563 static u32 regionB
= 0;
564 GXTexRegion
*ret
= NULL
;
566 fmt
= GX_GetTexObjFmt(obj
);
567 if(fmt
==0x0008 || fmt
==0x0009 || fmt
==0x000a) {
569 ret
= &__gx
->texRegion
[(idx
&3)+8];
572 ret
= &__gx
->texRegion
[(idx
&7)];
578 static GXTlutRegion
* __GXDefTlutRegionCallback(u32 tlut_name
)
580 return &__gx
->tlutRegion
[tlut_name
];
583 static void __GX_InitGX()
588 Mtx identity_matrix
=
595 rmode
= VIDEO_GetPreferredMode(NULL
);
597 GX_SetCopyClear((GXColor
)BLACK
,0xffffff);
598 GX_SetTexCoordGen(GX_TEXCOORD0
,GX_TG_MTX2x4
,GX_TG_TEX0
,GX_IDENTITY
);
599 GX_SetTexCoordGen(GX_TEXCOORD1
,GX_TG_MTX2x4
,GX_TG_TEX1
,GX_IDENTITY
);
600 GX_SetTexCoordGen(GX_TEXCOORD2
,GX_TG_MTX2x4
,GX_TG_TEX2
,GX_IDENTITY
);
601 GX_SetTexCoordGen(GX_TEXCOORD3
,GX_TG_MTX2x4
,GX_TG_TEX3
,GX_IDENTITY
);
602 GX_SetTexCoordGen(GX_TEXCOORD4
,GX_TG_MTX2x4
,GX_TG_TEX4
,GX_IDENTITY
);
603 GX_SetTexCoordGen(GX_TEXCOORD5
,GX_TG_MTX2x4
,GX_TG_TEX5
,GX_IDENTITY
);
604 GX_SetTexCoordGen(GX_TEXCOORD6
,GX_TG_MTX2x4
,GX_TG_TEX6
,GX_IDENTITY
);
605 GX_SetTexCoordGen(GX_TEXCOORD7
,GX_TG_MTX2x4
,GX_TG_TEX7
,GX_IDENTITY
);
610 GX_SetLineWidth(6,GX_TO_ZERO
);
611 GX_SetPointSize(6,GX_TO_ZERO
);
613 GX_EnableTexOffsets(GX_TEXCOORD0
,GX_DISABLE
,GX_DISABLE
);
614 GX_EnableTexOffsets(GX_TEXCOORD1
,GX_DISABLE
,GX_DISABLE
);
615 GX_EnableTexOffsets(GX_TEXCOORD2
,GX_DISABLE
,GX_DISABLE
);
616 GX_EnableTexOffsets(GX_TEXCOORD3
,GX_DISABLE
,GX_DISABLE
);
617 GX_EnableTexOffsets(GX_TEXCOORD4
,GX_DISABLE
,GX_DISABLE
);
618 GX_EnableTexOffsets(GX_TEXCOORD5
,GX_DISABLE
,GX_DISABLE
);
619 GX_EnableTexOffsets(GX_TEXCOORD6
,GX_DISABLE
,GX_DISABLE
);
620 GX_EnableTexOffsets(GX_TEXCOORD7
,GX_DISABLE
,GX_DISABLE
);
622 GX_LoadPosMtxImm(identity_matrix
,GX_PNMTX0
);
623 GX_LoadNrmMtxImm(identity_matrix
,GX_PNMTX0
);
624 GX_SetCurrentMtx(GX_PNMTX0
);
625 GX_LoadTexMtxImm(identity_matrix
,GX_IDENTITY
,GX_MTX3x4
);
626 GX_LoadTexMtxImm(identity_matrix
,GX_DTTIDENTITY
,GX_MTX3x4
);
628 GX_SetViewport(0,0,rmode
->fbWidth
,rmode
->efbHeight
,0,1);
629 GX_SetCoPlanar(GX_DISABLE
);
630 GX_SetCullMode(GX_CULL_BACK
);
631 GX_SetClipMode(GX_CLIP_ENABLE
);
633 GX_SetScissor(0,0,rmode
->fbWidth
,rmode
->efbHeight
);
634 GX_SetScissorBoxOffset(0,0);
638 GX_SetChanCtrl(GX_COLOR0A0
,GX_DISABLE
,GX_SRC_REG
,GX_SRC_VTX
,GX_LIGHTNULL
,GX_DF_NONE
,GX_AF_NONE
);
639 GX_SetChanAmbColor(GX_COLOR0A0
,(GXColor
)BLACK
);
640 GX_SetChanMatColor(GX_COLOR0A0
,(GXColor
)WHITE
);
642 GX_SetChanCtrl(GX_COLOR1A1
,GX_DISABLE
,GX_SRC_REG
,GX_SRC_VTX
,GX_LIGHTNULL
,GX_DF_NONE
,GX_AF_NONE
);
643 GX_SetChanAmbColor(GX_COLOR1A1
,(GXColor
)BLACK
);
644 GX_SetChanMatColor(GX_COLOR1A1
,(GXColor
)WHITE
);
646 GX_InvalidateTexAll();
647 GX_SetTexRegionCallback(__GXDefTexRegionCallback
);
648 GX_SetTlutRegionCallback(__GXDefTlutRegionCallback
);
650 GX_SetTevOrder(GX_TEVSTAGE0
,GX_TEXCOORD0
,GX_TEXMAP0
,GX_COLOR0A0
);
651 GX_SetTevOrder(GX_TEVSTAGE1
,GX_TEXCOORD1
,GX_TEXMAP1
,GX_COLOR0A0
);
652 GX_SetTevOrder(GX_TEVSTAGE2
,GX_TEXCOORD2
,GX_TEXMAP2
,GX_COLOR0A0
);
653 GX_SetTevOrder(GX_TEVSTAGE3
,GX_TEXCOORD3
,GX_TEXMAP3
,GX_COLOR0A0
);
654 GX_SetTevOrder(GX_TEVSTAGE4
,GX_TEXCOORD4
,GX_TEXMAP4
,GX_COLOR0A0
);
655 GX_SetTevOrder(GX_TEVSTAGE5
,GX_TEXCOORD5
,GX_TEXMAP5
,GX_COLOR0A0
);
656 GX_SetTevOrder(GX_TEVSTAGE6
,GX_TEXCOORD6
,GX_TEXMAP6
,GX_COLOR0A0
);
657 GX_SetTevOrder(GX_TEVSTAGE7
,GX_TEXCOORD7
,GX_TEXMAP7
,GX_COLOR0A0
);
658 GX_SetTevOrder(GX_TEVSTAGE8
,GX_TEXCOORDNULL
,GX_TEXMAP_NULL
,GX_COLORNULL
);
659 GX_SetTevOrder(GX_TEVSTAGE9
,GX_TEXCOORDNULL
,GX_TEXMAP_NULL
,GX_COLORNULL
);
660 GX_SetTevOrder(GX_TEVSTAGE10
,GX_TEXCOORDNULL
,GX_TEXMAP_NULL
,GX_COLORNULL
);
661 GX_SetTevOrder(GX_TEVSTAGE11
,GX_TEXCOORDNULL
,GX_TEXMAP_NULL
,GX_COLORNULL
);
662 GX_SetTevOrder(GX_TEVSTAGE12
,GX_TEXCOORDNULL
,GX_TEXMAP_NULL
,GX_COLORNULL
);
663 GX_SetTevOrder(GX_TEVSTAGE13
,GX_TEXCOORDNULL
,GX_TEXMAP_NULL
,GX_COLORNULL
);
664 GX_SetTevOrder(GX_TEVSTAGE14
,GX_TEXCOORDNULL
,GX_TEXMAP_NULL
,GX_COLORNULL
);
665 GX_SetTevOrder(GX_TEVSTAGE15
,GX_TEXCOORDNULL
,GX_TEXMAP_NULL
,GX_COLORNULL
);
666 GX_SetNumTevStages(1);
667 GX_SetTevOp(GX_TEVSTAGE0
,GX_REPLACE
);
668 GX_SetAlphaCompare(GX_ALWAYS
,0,GX_AOP_AND
,GX_ALWAYS
,0);
669 GX_SetZTexture(GX_ZT_DISABLE
,GX_TF_Z8
,0);
670 for(i
=0;i
<GX_MAX_TEVSTAGE
;i
++) {
671 GX_SetTevKColorSel(i
,GX_TEV_KCSEL_1_4
);
672 GX_SetTevKAlphaSel(i
,GX_TEV_KASEL_1
);
673 GX_SetTevSwapMode(i
,GX_TEV_SWAP0
,GX_TEV_SWAP0
);
676 GX_SetTevSwapModeTable(GX_TEV_SWAP0
,GX_CH_RED
,GX_CH_GREEN
,GX_CH_BLUE
,GX_CH_ALPHA
);
677 GX_SetTevSwapModeTable(GX_TEV_SWAP1
,GX_CH_RED
,GX_CH_RED
,GX_CH_RED
,GX_CH_ALPHA
);
678 GX_SetTevSwapModeTable(GX_TEV_SWAP2
,GX_CH_GREEN
,GX_CH_GREEN
,GX_CH_GREEN
,GX_CH_ALPHA
);
679 GX_SetTevSwapModeTable(GX_TEV_SWAP3
,GX_CH_BLUE
,GX_CH_BLUE
,GX_CH_BLUE
,GX_CH_ALPHA
);
680 for(i
=0;i
<GX_MAX_TEVSTAGE
;i
++) {
684 GX_SetNumIndStages(0);
685 GX_SetIndTexCoordScale(GX_INDTEXSTAGE0
,GX_ITS_1
,GX_ITS_1
);
686 GX_SetIndTexCoordScale(GX_INDTEXSTAGE1
,GX_ITS_1
,GX_ITS_1
);
687 GX_SetIndTexCoordScale(GX_INDTEXSTAGE2
,GX_ITS_1
,GX_ITS_1
);
688 GX_SetIndTexCoordScale(GX_INDTEXSTAGE3
,GX_ITS_1
,GX_ITS_1
);
690 GX_SetFog(GX_FOG_NONE
,0,1,0.1,1,(GXColor
)BLACK
);
691 GX_SetFogRangeAdj(GX_DISABLE
,0,NULL
);
693 GX_SetBlendMode(GX_BM_NONE
,GX_BL_SRCALPHA
,GX_BL_INVSRCALPHA
,GX_LO_CLEAR
);
694 GX_SetColorUpdate(GX_ENABLE
);
695 GX_SetAlphaUpdate(GX_ENABLE
);
696 GX_SetZMode(GX_ENABLE
,GX_LEQUAL
,GX_TRUE
);
697 GX_SetZCompLoc(GX_TRUE
);
698 GX_SetDither(GX_ENABLE
);
699 GX_SetDstAlpha(GX_DISABLE
,0);
700 GX_SetPixelFmt(GX_PF_RGB8_Z24
,GX_ZC_LINEAR
);
702 GX_SetFieldMask(GX_ENABLE
,GX_ENABLE
);
705 if(rmode
->viHeight
==(rmode
->xfbHeight
<<1)) flag
= 1;
706 GX_SetFieldMode(rmode
->field_rendering
,flag
);
708 GX_SetCopyClear((GXColor
)GX_DEFAULT_BG
,0x00ffffff);
709 GX_SetDispCopySrc(0,0,rmode
->fbWidth
,rmode
->efbHeight
);
710 GX_SetDispCopyDst(rmode
->fbWidth
,rmode
->efbHeight
);
711 GX_SetDispCopyYScale(1.0);
712 GX_SetCopyClamp(GX_CLAMP_TOP
|GX_CLAMP_BOTTOM
);
713 GX_SetCopyFilter(GX_FALSE
,NULL
,GX_FALSE
,NULL
);
714 GX_SetDispCopyGamma(GX_GM_1_0
);
715 GX_SetDispCopyFrame2Field(GX_COPY_PROGRESSIVE
);
716 GX_ClearBoundingBox();
718 GX_PokeColorUpdate(GX_TRUE
);
719 GX_PokeAlphaUpdate(GX_TRUE
);
720 GX_PokeDither(GX_FALSE
);
721 GX_PokeBlendMode(GX_BM_NONE
,GX_BL_ZERO
,GX_BL_ONE
,GX_LO_SET
);
722 GX_PokeAlphaMode(GX_ALWAYS
,0);
723 GX_PokeAlphaRead(GX_READ_FF
);
724 GX_PokeDstAlpha(GX_DISABLE
,0);
725 GX_PokeZMode(GX_TRUE
,GX_ALWAYS
,GX_TRUE
);
727 GX_SetGPMetric(GX_PERF0_NONE
,GX_PERF1_NONE
);
731 static void __GX_FlushTextureState()
733 GX_LOAD_BP_REG(__gx
->tevIndMask
);
736 static void __GX_XfVtxSpecs()
742 if(__gx
->vcdLo
&0x6000) cols
++;
743 if(__gx
->vcdLo
&0x18000) cols
++;
746 if(__gx
->vcdNrms
==1) nrms
= 1;
747 else if(__gx
->vcdNrms
==2) nrms
= 2;
750 if(__gx
->vcdHi
&0x3) texs
++;
751 if(__gx
->vcdHi
&0xc) texs
++;
752 if(__gx
->vcdHi
&0x30) texs
++;
753 if(__gx
->vcdHi
&0xc0) texs
++;
754 if(__gx
->vcdHi
&0x300) texs
++;
755 if(__gx
->vcdHi
&0xc00) texs
++;
756 if(__gx
->vcdHi
&0x3000) texs
++;
757 if(__gx
->vcdHi
&0xc000) texs
++;
759 xfvtxspecs
= (_SHIFTL(texs
,4,4))|(_SHIFTL(nrms
,2,2))|(cols
&0x3);
760 GX_LOAD_XF_REG(0x1008,xfvtxspecs
);
763 static void __GX_SetMatrixIndex(u32 mtx
)
766 GX_LOAD_CP_REG(0x30,__gx
->mtxIdxLo
);
767 GX_LOAD_XF_REG(0x1018,__gx
->mtxIdxLo
);
769 GX_LOAD_CP_REG(0x40,__gx
->mtxIdxHi
);
770 GX_LOAD_XF_REG(0x1019,__gx
->mtxIdxHi
);
774 static void __GX_SendFlushPrim()
778 tmp
= (__gx
->xfFlush
*__gx
->xfFlushExp
);
781 wgPipe
->U16
= __gx
->xfFlush
;
808 static void __GX_SetVCD()
810 GX_LOAD_CP_REG(0x50,__gx
->vcdLo
);
811 GX_LOAD_CP_REG(0x60,__gx
->vcdHi
);
815 static void __GX_SetVAT()
822 if(__gx
->VATTable
&setvtx
) {
823 GX_LOAD_CP_REG((0x70+(i
&7)),__gx
->VAT0reg
[i
]);
824 GX_LOAD_CP_REG((0x80+(i
&7)),__gx
->VAT1reg
[i
]);
825 GX_LOAD_CP_REG((0x90+(i
&7)),__gx
->VAT2reg
[i
]);
831 static void __SetSURegs(u8 texmap
,u8 texcoord
)
837 wd
= __gx
->texMapSize
[texmap
]&0x3ff;
838 ht
= _SHIFTR(__gx
->texMapSize
[texmap
],10,10);
839 wrap_s
= __gx
->texMapWrap
[texmap
]&3;
840 wrap_t
= _SHIFTR(__gx
->texMapWrap
[texmap
],2,2);
842 reg
= (texcoord
&0x7);
843 __gx
->suSsize
[reg
] = (__gx
->suSsize
[reg
]&~0x0000ffff)|wd
;
844 __gx
->suTsize
[reg
] = (__gx
->suTsize
[reg
]&~0x0000ffff)|ht
;
845 __gx
->suSsize
[reg
] = (__gx
->suSsize
[reg
]&~0x00010000)|(_SHIFTL(wrap_s
,16,1));
846 __gx
->suTsize
[reg
] = (__gx
->suTsize
[reg
]&~0x00010000)|(_SHIFTL(wrap_t
,16,1));
848 GX_LOAD_BP_REG(__gx
->suSsize
[reg
]);
849 GX_LOAD_BP_REG(__gx
->suTsize
[reg
]);
852 static void __GX_SetSUTexRegs()
857 u32 tevreg
,tevm
,texcm
;
859 dirtev
= (_SHIFTR(__gx
->genMode
,10,4))+1;
860 indtev
= _SHIFTR(__gx
->genMode
,16,3);
862 //indirect texture order
863 for(i
=0;i
<indtev
;i
++) {
865 case GX_INDTEXSTAGE0
:
866 texmap
= __gx
->tevRasOrder
[2]&7;
867 texcoord
= _SHIFTR(__gx
->tevRasOrder
[2],3,3);
869 case GX_INDTEXSTAGE1
:
870 texmap
= _SHIFTR(__gx
->tevRasOrder
[2],6,3);
871 texcoord
= _SHIFTR(__gx
->tevRasOrder
[2],9,3);
873 case GX_INDTEXSTAGE2
:
874 texmap
= _SHIFTR(__gx
->tevRasOrder
[2],12,3);
875 texcoord
= _SHIFTR(__gx
->tevRasOrder
[2],15,3);
877 case GX_INDTEXSTAGE3
:
878 texmap
= _SHIFTR(__gx
->tevRasOrder
[2],18,3);
879 texcoord
= _SHIFTR(__gx
->tevRasOrder
[2],21,3);
887 texcm
= _SHIFTL(1,texcoord
,1);
888 if(!(__gx
->texCoordManually
&texcm
))
889 __SetSURegs(texmap
,texcoord
);
892 //direct texture order
893 for(i
=0;i
<dirtev
;i
++) {
894 tevreg
= 3+(_SHIFTR(i
,1,3));
895 texmap
= (__gx
->tevTexMap
[i
]&0xff);
897 if(i
&1) texcoord
= _SHIFTR(__gx
->tevRasOrder
[tevreg
],15,3);
898 else texcoord
= _SHIFTR(__gx
->tevRasOrder
[tevreg
],3,3);
900 tevm
= _SHIFTL(1,i
,1);
901 texcm
= _SHIFTL(1,texcoord
,1);
902 if(texmap
!=0xff && (__gx
->tevTexCoordEnable
&tevm
) && !(__gx
->texCoordManually
&texcm
)) {
903 __SetSURegs(texmap
,texcoord
);
908 static void __GX_SetGenMode()
910 GX_LOAD_BP_REG(__gx
->genMode
);
914 static void __GX_UpdateBPMask()
921 nbmp
= _SHIFTR(__gx
->genMode
,16,3);
924 for(i
=0;i
<nbmp
;i
++) {
926 case GX_INDTEXSTAGE0
:
927 ntexmap
= __gx
->tevRasOrder
[2]&7;
929 case GX_INDTEXSTAGE1
:
930 ntexmap
= _SHIFTR(__gx
->tevRasOrder
[2],6,3);
932 case GX_INDTEXSTAGE2
:
933 ntexmap
= _SHIFTR(__gx
->tevRasOrder
[2],12,3);
935 case GX_INDTEXSTAGE3
:
936 ntexmap
= _SHIFTR(__gx
->tevRasOrder
[2],18,3);
942 nres
|= (1<<ntexmap
);
945 if((__gx
->tevIndMask
&0xff)!=nres
) {
946 __gx
->tevIndMask
= (__gx
->tevIndMask
&~0xff)|(nres
&0xff);
947 GX_LOAD_BP_REG(__gx
->tevIndMask
);
952 static void __GX_SetIndirectMask(u32 mask
)
954 __gx
->tevIndMask
= ((__gx
->tevIndMask
&~0xff)|(mask
&0xff));
955 GX_LOAD_BP_REG(__gx
->tevIndMask
);
958 static void __GX_SetTexCoordGen()
963 if(__gx
->dirtyState
&0x02000000) GX_LOAD_XF_REG(0x103f,(__gx
->genMode
&0xf));
967 mask
= _SHIFTR(__gx
->dirtyState
,16,8);
970 GX_LOAD_XF_REG(texcoord
,__gx
->texCoordGen
[i
]);
971 GX_LOAD_XF_REG((texcoord
+0x10),__gx
->texCoordGen2
[i
]);
979 static void __GX_SetChanColor()
981 if(__gx
->dirtyState
&0x0100)
982 GX_LOAD_XF_REG(0x100a,__gx
->chnAmbColor
[0]);
983 if(__gx
->dirtyState
&0x0200)
984 GX_LOAD_XF_REG(0x100b,__gx
->chnAmbColor
[1]);
985 if(__gx
->dirtyState
&0x0400)
986 GX_LOAD_XF_REG(0x100c,__gx
->chnMatColor
[0]);
987 if(__gx
->dirtyState
&0x0800)
988 GX_LOAD_XF_REG(0x100d,__gx
->chnMatColor
[1]);
991 static void __GX_SetChanCntrl()
995 if(__gx
->dirtyState
&0x01000000) GX_LOAD_XF_REG(0x1009,(_SHIFTR(__gx
->genMode
,4,3)));
999 mask
= _SHIFTR(__gx
->dirtyState
,12,4);
1001 if(mask
&0x0001) GX_LOAD_XF_REG(chan
,__gx
->chnCntrl
[i
]);
1009 static void __GX_SetDirtyState()
1011 if(__gx
->dirtyState
&0x0001) {
1012 __GX_SetSUTexRegs();
1014 if(__gx
->dirtyState
&0x0002) {
1015 __GX_UpdateBPMask();
1017 if(__gx
->dirtyState
&0x0004) {
1020 if(__gx
->dirtyState
&0x0008) {
1023 if(__gx
->dirtyState
&0x0010) {
1026 if(__gx
->dirtyState
&~0xff) {
1027 if(__gx
->dirtyState
&0x0f00) {
1028 __GX_SetChanColor();
1030 if(__gx
->dirtyState
&0x0100f000) {
1031 __GX_SetChanCntrl();
1033 if(__gx
->dirtyState
&0x02ff0000) {
1034 __GX_SetTexCoordGen();
1036 if(__gx
->dirtyState
&0x04000000) {
1037 __GX_SetMatrixIndex(0);
1038 __GX_SetMatrixIndex(5);
1041 __gx
->dirtyState
= 0;
1044 static u32
__GX_GetNumXfbLines(u16 efbHeight
,u32 yscale
)
1048 tmp
= (((efbHeight
-1)<<8)/yscale
)+1;
1049 if(yscale
>128 && yscale
<256) {
1050 while(yscale
&0x01) yscale
>>= 1;
1051 tmp1
= yscale
*(efbHeight
/yscale
);
1052 if(!(efbHeight
-tmp1
)) tmp
++;
1054 if(tmp
>1024) tmp
= 1024;
1059 GXFifoObj
* GX_Init(void *base
,u32 size
)
1065 u32 tmem_even
,tmem_odd
;
1068 u32 divid
= TB_BUS_CLOCK
;
1069 GXTexRegion
*region
= NULL
;
1070 GXTlutRegion
*tregion
= NULL
;
1072 LWP_InitQueue(&_gxwaitfinish
);
1073 SYS_RegisterResetFunc(&__gx_resetinfo
);
1075 memset(__gxregs
,0,STRUCT_REGDEF_SIZE
);
1078 GX_InitFifoBase(&_gxfifoobj
,base
,size
);
1079 GX_SetCPUFifo(&_gxfifoobj
);
1080 GX_SetGPFifo(&_gxfifoobj
);
1082 EnableWriteGatherPipe();
1084 __gx
->gxFifoInited
= 1;
1086 __gx
->tevIndMask
= 0xff;
1087 __gx
->tevIndMask
= (__gx
->tevIndMask
&~0xff000000)|(_SHIFTL(0x0f,24,8));
1093 __gx
->tevColorEnv
[i
] = (__gx
->tevColorEnv
[i
]&~0xff000000)|(_SHIFTL(re0
,24,8));
1094 __gx
->tevAlphaEnv
[i
] = (__gx
->tevAlphaEnv
[i
]&~0xff000000)|(_SHIFTL(re1
,24,8));
1095 re0
+= 2; re1
+= 2; i
++;
1098 __gx
->texCoordManually
= 0;
1099 __gx
->dirtyState
= 0;
1101 __gx
->saveDLctx
= 1;
1102 __gx
->gxFifoUnlinked
= 0;
1104 __gx
->sciTLcorner
= (__gx
->sciTLcorner
&~0xff000000)|(_SHIFTL(0x20,24,8));
1105 __gx
->sciBRcorner
= (__gx
->sciBRcorner
&~0xff000000)|(_SHIFTL(0x21,24,8));
1106 __gx
->lpWidth
= (__gx
->lpWidth
&~0xff000000)|(_SHIFTL(0x22,24,8));
1107 __gx
->genMode
= (__gx
->genMode
&~0xff000000)|(_SHIFTL(0x00,24,8));
1113 __gx
->suSsize
[i
] = (__gx
->suSsize
[i
]&~0xff000000)|(_SHIFTL(re0
,24,8));
1114 __gx
->suTsize
[i
] = (__gx
->suTsize
[i
]&~0xff000000)|(_SHIFTL(re1
,24,8));
1115 re0
+= 2; re1
+= 2; i
++;
1118 __gx
->peZMode
= (__gx
->peZMode
&~0xff000000)|(_SHIFTL(0x40,24,8));
1119 __gx
->peCMode0
= (__gx
->peCMode0
&~0xff000000)|(_SHIFTL(0x41,24,8));
1120 __gx
->peCMode1
= (__gx
->peCMode1
&~0xff000000)|(_SHIFTL(0x42,24,8));
1121 __gx
->peCntrl
= (__gx
->peCntrl
&~0xff000000)|(_SHIFTL(0x43,24,8));
1126 __gx
->tevRasOrder
[i
] = (__gx
->tevRasOrder
[i
]&~0xff000000)|(_SHIFTL(re0
,24,8));
1131 res
= (u32
)(divid
/divis
);
1132 __GX_FlushTextureState();
1133 GX_LOAD_BP_REG(0x69000000|((_SHIFTR(res
,11,24))|0x0400));
1136 res
= (u32
)(res
/divis
);
1137 __GX_FlushTextureState();
1138 GX_LOAD_BP_REG(0x46000000|(res
|0x0200));
1143 __gx
->tevSwapModeTable
[i
] = (__gx
->tevSwapModeTable
[i
]&~0xff000000)|(_SHIFTL(re0
,24,8));
1147 __gx
->tevTexCoordEnable
= 0;
1148 __gx
->perf0Mode
= GX_PERF0_NONE
;
1149 __gx
->perf1Mode
= GX_PERF1_NONE
;
1150 __gx
->cpPerfMode
= 0;
1156 __gx
->tevTexMap
[i
] = 0xff;
1163 region
= &__gx
->texRegion
[i
];
1164 GX_InitTexCacheRegion(region
,GX_FALSE
,_gxtexregionaddrtable
[i
+0],GX_TEXCACHE_32K
,_gxtexregionaddrtable
[i
+8],GX_TEXCACHE_32K
);
1166 region
= &__gx
->texRegion
[i
+8];
1167 GX_InitTexCacheRegion(region
,GX_FALSE
,_gxtexregionaddrtable
[i
+16],GX_TEXCACHE_32K
,_gxtexregionaddrtable
[i
+24],GX_TEXCACHE_32K
);
1169 region
= &__gx
->texRegion
[i
+16];
1170 GX_InitTexCacheRegion(region
,GX_TRUE
,_gxtexregionaddrtable
[i
+32],GX_TEXCACHE_32K
,_gxtexregionaddrtable
[i
+40],GX_TEXCACHE_32K
);
1177 tmem
= 0x000C0000+(i
<<13);
1178 tregion
= &__gx
->tlutRegion
[i
];
1179 GX_InitTlutRegion(tregion
,tmem
,GX_TLUT_256
);
1185 tmem
= 0x000E0000+(i
<<15);
1186 tregion
= &__gx
->tlutRegion
[i
+16];
1187 GX_InitTlutRegion(tregion
,tmem
,GX_TLUT_1K
);
1192 tmem_even
= tmem_odd
= (i
<<15);
1193 region
= &__gx
->texRegion
[i
];
1194 GX_InitTexCacheRegion(region
,GX_FALSE
,tmem_even
,GX_TEXCACHE_32K
,(tmem_odd
+0x00080000),GX_TEXCACHE_32K
);
1197 tmem_even
= ((0x08+(i
<<1))<<15);
1198 tmem_odd
= ((0x09+(i
<<1))<<15);
1199 region
= &__gx
->texRegion
[i
+8];
1200 GX_InitTexCacheRegion(region
,GX_FALSE
,tmem_even
,GX_TEXCACHE_32K
,tmem_odd
,GX_TEXCACHE_32K
);
1203 tmem_even
= (i
<<13)+0x000C0000;
1204 tregion
= &__gx
->tlutRegion
[i
];
1205 GX_InitTlutRegion(tregion
,tmem_even
,GX_TLUT_256
);
1208 tmem_even
= (i
<<15)+0x000E0000;
1209 tregion
= &__gx
->tlutRegion
[i
+16];
1210 GX_InitTlutRegion(tregion
,tmem_even
,GX_TLUT_1K
);
1214 GX_LOAD_CP_REG(0x20,0x00000000);
1215 GX_LOAD_XF_REG(0x1006,0x0);
1217 GX_LOAD_BP_REG(0x23000000);
1218 GX_LOAD_BP_REG(0x24000000);
1219 GX_LOAD_BP_REG(0x67000000);
1221 __GX_SetIndirectMask(0);
1223 __GX_SetTmemConfig(2);
1225 __GX_SetTmemConfig(0);
1232 void GX_InitFifoBase(GXFifoObj
*fifo
,void *base
,u32 size
)
1234 struct __gxfifo
*ptr
= (struct __gxfifo
*)fifo
;
1236 if(!ptr
|| size
<GX_FIFO_MINSIZE
) return;
1238 ptr
->buf_start
= (u32
)base
;
1239 ptr
->buf_end
= (u32
)base
+ size
- 4;
1243 GX_InitFifoLimits(fifo
,(size
-GX_FIFO_HIWATERMARK
),((size
>>1)&0x7fffffe0));
1244 GX_InitFifoPtrs(fifo
,base
,base
);
1247 void GX_InitFifoLimits(GXFifoObj
*fifo
,u32 hiwatermark
,u32 lowatermark
)
1249 struct __gxfifo
*ptr
= (struct __gxfifo
*)fifo
;
1251 ptr
->hi_mark
= hiwatermark
;
1252 ptr
->lo_mark
= lowatermark
;
1255 void GX_InitFifoPtrs(GXFifoObj
*fifo
,void *rd_ptr
,void *wt_ptr
)
1259 struct __gxfifo
*ptr
= (struct __gxfifo
*)fifo
;
1261 _CPU_ISR_Disable(level
);
1262 rdwt_dst
= wt_ptr
-rd_ptr
;
1263 ptr
->rd_ptr
= (u32
)rd_ptr
;
1264 ptr
->wt_ptr
= (u32
)wt_ptr
;
1265 ptr
->rdwt_dst
= rdwt_dst
;
1267 rdwt_dst
+= ptr
->size
;
1268 ptr
->rd_ptr
= rdwt_dst
;
1270 _CPU_ISR_Restore(level
);
1273 void GX_GetFifoPtrs(GXFifoObj
*fifo
,void **rd_ptr
,void **wt_ptr
)
1275 struct __gxfifo
*ptr
= (struct __gxfifo
*)fifo
;
1276 *rd_ptr
= (void*)ptr
->rd_ptr
;
1277 *wt_ptr
= (void*)ptr
->wt_ptr
;
1280 void GX_SetCPUFifo(GXFifoObj
*fifo
)
1283 struct __gxfifo
*ptr
= (struct __gxfifo
*)fifo
;
1284 struct __gxfifo
*cpufifo
= (struct __gxfifo
*)&_cpufifo
;
1286 _CPU_ISR_Disable(level
);
1288 _gxcpufifoready
= 0;
1290 cpufifo
->gpfifo_ready
= 0;
1291 cpufifo
->cpufifo_ready
= 0;
1292 _CPU_ISR_Restore(level
);
1296 cpufifo
->buf_start
= ptr
->buf_start
;
1297 cpufifo
->buf_end
= ptr
->buf_end
;
1298 cpufifo
->size
= ptr
->size
;
1299 cpufifo
->hi_mark
= ptr
->hi_mark
;
1300 cpufifo
->lo_mark
= ptr
->lo_mark
;
1301 cpufifo
->rd_ptr
= ptr
->rd_ptr
;
1302 cpufifo
->wt_ptr
= ptr
->wt_ptr
;
1303 cpufifo
->rdwt_dst
= ptr
->rdwt_dst
;
1304 cpufifo
->fifo_wrap
= ptr
->fifo_wrap
;
1305 cpufifo
->gpfifo_ready
= ptr
->gpfifo_ready
;
1306 cpufifo
->cpufifo_ready
= 1;
1308 _gxcpufifoready
= 1;
1309 if(__GX_CPGPLinkCheck()) {
1311 cpufifo
->gpfifo_ready
= 1;
1313 _piReg
[3] = MEM_VIRTUAL_TO_PHYSICAL(cpufifo
->buf_start
);
1314 _piReg
[4] = MEM_VIRTUAL_TO_PHYSICAL(cpufifo
->buf_end
);
1315 _piReg
[5] = (cpufifo
->wt_ptr
&0x1FFFFFE0);
1317 __GX_WriteFifoIntReset(GX_TRUE
,GX_TRUE
);
1318 __GX_WriteFifoIntEnable(GX_ENABLE
,GX_DISABLE
);
1319 __GX_FifoLink(GX_TRUE
);
1321 _CPU_ISR_Restore(level
);
1326 __GX_FifoLink(GX_FALSE
);
1330 __GX_WriteFifoIntEnable(GX_DISABLE
,GX_DISABLE
);
1332 _piReg
[3] = MEM_VIRTUAL_TO_PHYSICAL(cpufifo
->buf_start
);
1333 _piReg
[4] = MEM_VIRTUAL_TO_PHYSICAL(cpufifo
->buf_end
);
1334 _piReg
[5] = (cpufifo
->wt_ptr
&0x1FFFFFE0);
1337 _CPU_ISR_Restore(level
);
1340 void GX_GetCPUFifo(GXFifoObj
*fifo
)
1342 struct __gxfifo
* ptr
= (struct __gxfifo
*)fifo
;
1343 struct __gxfifo
* cpufifo
= (struct __gxfifo
*)&_cpufifo
;
1345 if(!_gxcpufifoready
) return;
1350 ptr
->buf_start
= cpufifo
->buf_start
;
1351 ptr
->buf_end
= cpufifo
->buf_end
;
1352 ptr
->size
= cpufifo
->size
;
1353 ptr
->rd_ptr
= cpufifo
->rd_ptr
;
1354 ptr
->wt_ptr
= cpufifo
->wt_ptr
;
1355 ptr
->rdwt_dst
= cpufifo
->rdwt_dst
;
1356 ptr
->hi_mark
= cpufifo
->hi_mark
;
1357 ptr
->lo_mark
= cpufifo
->lo_mark
;
1358 ptr
->fifo_wrap
= cpufifo
->fifo_wrap
;
1359 ptr
->cpufifo_ready
= cpufifo
->cpufifo_ready
;
1360 ptr
->gpfifo_ready
= cpufifo
->gpfifo_ready
;
1363 void GX_SetGPFifo(GXFifoObj
*fifo
)
1366 struct __gxfifo
*ptr
= (struct __gxfifo
*)fifo
;
1367 struct __gxfifo
*gpfifo
= (struct __gxfifo
*)&_gpfifo
;
1369 _CPU_ISR_Disable(level
);
1370 __GX_FifoReadDisable();
1371 __GX_WriteFifoIntEnable(GX_DISABLE
,GX_DISABLE
);
1376 gpfifo
->cpufifo_ready
= 0;
1377 gpfifo
->gpfifo_ready
= 0;
1378 __GX_FifoLink(GX_FALSE
);
1379 _CPU_ISR_Restore(level
);
1383 gpfifo
->buf_start
= ptr
->buf_start
;
1384 gpfifo
->buf_end
= ptr
->buf_end
;
1385 gpfifo
->size
= ptr
->size
;
1386 gpfifo
->hi_mark
= ptr
->hi_mark
;
1387 gpfifo
->lo_mark
= ptr
->lo_mark
;
1388 gpfifo
->rd_ptr
= ptr
->rd_ptr
;
1389 gpfifo
->wt_ptr
= ptr
->wt_ptr
;
1390 gpfifo
->rdwt_dst
= ptr
->rdwt_dst
;
1391 gpfifo
->fifo_wrap
= ptr
->fifo_wrap
;
1392 gpfifo
->cpufifo_ready
= ptr
->cpufifo_ready
;
1393 gpfifo
->gpfifo_ready
= 1;
1396 /* setup fifo base */
1397 _cpReg
[16] = _SHIFTL(MEM_VIRTUAL_TO_PHYSICAL(gpfifo
->buf_start
),0,16);
1398 _cpReg
[17] = _SHIFTR(MEM_VIRTUAL_TO_PHYSICAL(gpfifo
->buf_start
),16,16);
1400 /* setup fifo end */
1401 _cpReg
[18] = _SHIFTL(MEM_VIRTUAL_TO_PHYSICAL(gpfifo
->buf_end
),0,16);
1402 _cpReg
[19] = _SHIFTR(MEM_VIRTUAL_TO_PHYSICAL(gpfifo
->buf_end
),16,16);
1404 /* setup hiwater mark */
1405 _cpReg
[20] = _SHIFTL(gpfifo
->hi_mark
,0,16);
1406 _cpReg
[21] = _SHIFTR(gpfifo
->hi_mark
,16,16);
1408 /* setup lowater mark */
1409 _cpReg
[22] = _SHIFTL(gpfifo
->lo_mark
,0,16);
1410 _cpReg
[23] = _SHIFTR(gpfifo
->lo_mark
,16,16);
1412 /* setup rd<->wd dist */
1413 _cpReg
[24] = _SHIFTL(gpfifo
->rdwt_dst
,0,16);
1414 _cpReg
[25] = _SHIFTR(gpfifo
->rdwt_dst
,16,16);
1417 _cpReg
[26] = _SHIFTL(MEM_VIRTUAL_TO_PHYSICAL(gpfifo
->wt_ptr
),0,16);
1418 _cpReg
[27] = _SHIFTR(MEM_VIRTUAL_TO_PHYSICAL(gpfifo
->wt_ptr
),16,16);
1421 _cpReg
[28] = _SHIFTL(MEM_VIRTUAL_TO_PHYSICAL(gpfifo
->rd_ptr
),0,16);
1422 _cpReg
[29] = _SHIFTR(MEM_VIRTUAL_TO_PHYSICAL(gpfifo
->rd_ptr
),16,16);
1425 if(__GX_CPGPLinkCheck()) {
1427 gpfifo
->cpufifo_ready
= 1;
1428 __GX_WriteFifoIntEnable(GX_ENABLE
,GX_DISABLE
);
1429 __GX_FifoLink(GX_TRUE
);
1432 gpfifo
->cpufifo_ready
= 0;
1433 __GX_WriteFifoIntEnable(GX_DISABLE
,GX_DISABLE
);
1434 __GX_FifoLink(GX_FALSE
);
1437 __GX_WriteFifoIntReset(GX_TRUE
,GX_TRUE
);
1438 __GX_FifoReadEnable();
1439 _CPU_ISR_Restore(level
);
1442 void GX_GetGPFifo(GXFifoObj
*fifo
)
1444 struct __gxfifo
* ptr
= (struct __gxfifo
*)fifo
;
1445 struct __gxfifo
* gpfifo
= (struct __gxfifo
*)&_gpfifo
;
1447 if(!_gxgpfifoready
) return;
1451 ptr
->buf_start
= gpfifo
->buf_start
;
1452 ptr
->buf_end
= gpfifo
->buf_end
;
1453 ptr
->size
= gpfifo
->size
;
1454 ptr
->rd_ptr
= gpfifo
->rd_ptr
;
1455 ptr
->wt_ptr
= gpfifo
->wt_ptr
;
1456 ptr
->rdwt_dst
= gpfifo
->rdwt_dst
;
1457 ptr
->hi_mark
= gpfifo
->hi_mark
;
1458 ptr
->lo_mark
= gpfifo
->lo_mark
;
1459 ptr
->fifo_wrap
= gpfifo
->fifo_wrap
;
1460 ptr
->gpfifo_ready
= gpfifo
->gpfifo_ready
;
1461 ptr
->cpufifo_ready
= gpfifo
->cpufifo_ready
;
1464 void* GX_GetFifoBase(GXFifoObj
*fifo
)
1466 return (void*)((struct __gxfifo
*)fifo
)->buf_start
;
1469 u32
GX_GetFifoSize(GXFifoObj
*fifo
)
1471 return ((struct __gxfifo
*)fifo
)->size
;
1474 u32
GX_GetFifoCount(GXFifoObj
*fifo
)
1476 return ((struct __gxfifo
*)fifo
)->rdwt_dst
;
1479 u8
GX_GetFifoWrap(GXFifoObj
*fifo
)
1481 return ((struct __gxfifo
*)fifo
)->fifo_wrap
;
1484 u32
GX_GetOverflowCount()
1486 return _gxoverflowcount
;
1489 u32
GX_ResetOverflowCount()
1491 u32 ret
= _gxoverflowcount
;
1492 _gxoverflowcount
= 0;
1496 lwp_t
GX_GetCurrentGXThread()
1498 return _gxcurrentlwp
;
1501 lwp_t
GX_SetCurrentGXThread()
1505 _CPU_ISR_Disable(level
);
1506 lwp_t ret
= _gxcurrentlwp
;
1507 _gxcurrentlwp
= LWP_GetSelf();
1508 _CPU_ISR_Restore(level
);
1513 volatile void* GX_RedirectWriteGatherPipe(void *ptr
)
1516 struct __gxfifo
*cpufifo
= (struct __gxfifo
*)&_cpufifo
;
1518 _CPU_ISR_Disable(level
);
1520 while(!IsWriteGatherBufferEmpty());
1524 __GX_FifoLink(GX_FALSE
);
1525 __GX_WriteFifoIntEnable(GX_DISABLE
,GX_DISABLE
);
1527 cpufifo
->wt_ptr
= (u32
)MEM_PHYSICAL_TO_K0(_piReg
[5]&~0x04000000);
1530 _piReg
[4] = 0x04000000;
1531 _piReg
[5] = (((u32
)ptr
&0x3FFFFFE0)&~0x04000000);
1534 _CPU_ISR_Restore(level
);
1536 return (volatile void*)0x0C008000;
1539 void GX_RestoreWriteGatherPipe()
1542 struct __gxfifo
*cpufifo
= (struct __gxfifo
*)&_cpufifo
;
1544 _CPU_ISR_Disable(level
);
1556 while(!IsWriteGatherBufferEmpty());
1559 _piReg
[3] = MEM_VIRTUAL_TO_PHYSICAL(cpufifo
->buf_start
);
1560 _piReg
[4] = MEM_VIRTUAL_TO_PHYSICAL(cpufifo
->buf_end
);
1561 _piReg
[5] = (((u32
)cpufifo
->wt_ptr
&0x3FFFFFE0)&~0x04000000);
1563 __GX_WriteFifoIntReset(GX_TRUE
,GX_TRUE
);
1564 __GX_WriteFifoIntEnable(GX_ENABLE
,GX_DISABLE
);
1565 __GX_FifoLink(GX_TRUE
);
1567 _CPU_ISR_Restore(level
);
1572 if(__gx
->dirtyState
)
1573 __GX_SetDirtyState();
1587 void GX_EnableBreakPt(void *break_pt
)
1590 _CPU_ISR_Disable(level
);
1591 __GX_FifoReadDisable();
1592 _cpReg
[30] = _SHIFTL(MEM_VIRTUAL_TO_PHYSICAL(break_pt
),0,16);
1593 _cpReg
[31] = _SHIFTR(MEM_VIRTUAL_TO_PHYSICAL(break_pt
),16,16);
1594 __gx
->cpCRreg
= (__gx
->cpCRreg
&~0x22)|0x22;
1595 _cpReg
[1] = __gx
->cpCRreg
;
1596 _gxcurrbp
= break_pt
;
1597 __GX_FifoReadEnable();
1598 _CPU_ISR_Restore(level
);
1601 void GX_DisableBreakPt()
1604 _CPU_ISR_Disable(level
);
1605 __gx
->cpCRreg
= (__gx
->cpCRreg
&~0x22);
1606 _cpReg
[1] = __gx
->cpCRreg
;
1608 _CPU_ISR_Restore(level
);
1612 void GX_AbortFrame()
1619 if(__GX_IsGPFifoReady())
1622 #elif defined(HW_RVL)
1623 void GX_AbortFrame()
1626 if(__GX_IsGPFifoReady()) {
1630 __gx
->dirtyState
= 0;
1636 void GX_SetDrawSync(u16 token
)
1639 _CPU_ISR_Disable(level
);
1640 GX_LOAD_BP_REG(0x48000000 | token
);
1641 GX_LOAD_BP_REG(0x47000000 | token
);
1643 _CPU_ISR_Restore(level
);
1646 u16
GX_GetDrawSync()
1651 void GX_SetDrawDone()
1654 _CPU_ISR_Disable(level
);
1655 GX_LOAD_BP_REG(0x45000002); // set draw done!
1658 _CPU_ISR_Restore(level
);
1662 void GX_WaitDrawDone()
1666 printf("GX_WaitDrawDone()\n\n");
1668 _CPU_ISR_Disable(level
);
1670 LWP_ThreadSleep(_gxwaitfinish
);
1671 _CPU_ISR_Restore(level
);
1678 _CPU_ISR_Disable(level
);
1679 GX_LOAD_BP_REG(0x45000002); // set draw done!
1683 _CPU_ISR_Flash(level
);
1686 LWP_ThreadSleep(_gxwaitfinish
);
1687 _CPU_ISR_Restore(level
);
1690 GXDrawDoneCallback
GX_SetDrawDoneCallback(GXDrawDoneCallback cb
)
1694 _CPU_ISR_Disable(level
);
1695 GXDrawDoneCallback ret
= drawDoneCB
;
1697 _CPU_ISR_Restore(level
);
1701 GXDrawSyncCallback
GX_SetDrawSyncCallback(GXDrawSyncCallback cb
)
1705 _CPU_ISR_Disable(level
);
1706 GXDrawSyncCallback ret
= tokenCB
;
1708 _CPU_ISR_Restore(level
);
1712 GXBreakPtCallback
GX_SetBreakPtCallback(GXBreakPtCallback cb
)
1716 _CPU_ISR_Disable(level
);
1717 GXBreakPtCallback ret
= breakPtCB
;
1719 _CPU_ISR_Restore(level
);
1723 void GX_PixModeSync()
1725 GX_LOAD_BP_REG(__gx
->peCntrl
);
1728 void GX_TexModeSync()
1730 GX_LOAD_BP_REG(0x63000000);
1733 void GX_SetMisc(u32 token
,u32 value
)
1737 if(token
==GX_MT_XF_FLUSH
) {
1738 __gx
->xfFlushSafe
= value
;
1739 cnt
= cntlzw(__gx
->xfFlushSafe
);
1740 __gx
->xfFlushExp
= _SHIFTR(cnt
,5,16);
1743 if(!__gx
->xfFlushSafe
) return;
1745 __gx
->dirtyState
|= 0x0008;
1746 } else if(token
==GX_MT_DL_SAVE_CTX
) {
1747 __gx
->saveDLctx
= (value
&0xff);
1752 void GX_SetViewportJitter(f32 xOrig
,f32 yOrig
,f32 wd
,f32 ht
,f32 nearZ
,f32 farZ
,u32 field
)
1754 f32 x0
,y0
,x1
,y1
,n
,f
,z
;
1755 static f32 Xfactor
= 0.5;
1756 static f32 Yfactor
= 342.0;
1757 static f32 Zfactor
= 16777215.0;
1759 if(!field
) yOrig
-= Xfactor
;
1763 x1
= (xOrig
+(wd
*Xfactor
))+Yfactor
;
1764 y1
= (yOrig
+(ht
*Xfactor
))+Yfactor
;
1769 GX_LOAD_XF_REGS(0x101a,6);
1778 void GX_SetViewport(f32 xOrig
,f32 yOrig
,f32 wd
,f32 ht
,f32 nearZ
,f32 farZ
)
1780 GX_SetViewportJitter(xOrig
,yOrig
,wd
,ht
,nearZ
,farZ
,1);
1783 void GX_LoadProjectionMtx(Mtx44 mt
,u8 type
)
1787 ((u32
*)((void*)tmp
))[6] = (u32
)type
;
1794 case GX_PERSPECTIVE
:
1798 case GX_ORTHOGRAPHIC
:
1804 GX_LOAD_XF_REGS(0x1020,7);
1805 wgPipe
->F32
= tmp
[0];
1806 wgPipe
->F32
= tmp
[1];
1807 wgPipe
->F32
= tmp
[2];
1808 wgPipe
->F32
= tmp
[3];
1809 wgPipe
->F32
= tmp
[4];
1810 wgPipe
->F32
= tmp
[5];
1811 wgPipe
->F32
= tmp
[6];
1814 static void __GetImageTileCount(u32 fmt
,u16 wd
,u16 ht
,u32
*xtiles
,u32
*ytiles
,u32
*zplanes
)
1816 u32 xshift
,yshift
,tile
;
1857 if(!(wd
&0xffff)) wd
= 1;
1858 if(!(ht
&0xffff)) ht
= 1;
1861 tile
= (wd
+((1<<xshift
)-1))>>xshift
;
1865 tile
= (ht
+((1<<yshift
)-1))>>yshift
;
1869 if(fmt
==GX_TF_RGBA8
|| fmt
==GX_TF_Z24X8
) *zplanes
= 2;
1872 void GX_SetCopyClear(GXColor color
,u32 zvalue
)
1876 val
= (_SHIFTL(color
.a
,8,8))|(color
.r
&0xff);
1877 GX_LOAD_BP_REG(0x4f000000|val
);
1879 val
= (_SHIFTL(color
.g
,8,8))|(color
.b
&0xff);
1880 GX_LOAD_BP_REG(0x50000000|val
);
1882 val
= zvalue
&0x00ffffff;
1883 GX_LOAD_BP_REG(0x51000000|val
);
1886 void GX_SetCopyClamp(u8 clamp
)
1888 __gx
->dispCopyCntrl
= (__gx
->dispCopyCntrl
&~1)|(clamp
&1);
1889 __gx
->dispCopyCntrl
= (__gx
->dispCopyCntrl
&~2)|(clamp
&2);
1892 void GX_SetDispCopyGamma(u8 gamma
)
1894 __gx
->dispCopyCntrl
= (__gx
->dispCopyCntrl
&~0x180)|(_SHIFTL(gamma
,7,2));
1897 void GX_SetCopyFilter(u8 aa
,u8 sample_pattern
[12][2],u8 vf
,u8 vfilter
[7])
1899 u32 reg01
=0,reg02
=0,reg03
=0,reg04
=0,reg53
=0,reg54
=0;
1902 reg01
= sample_pattern
[0][0]&0xf;
1903 reg01
= (reg01
&~0xf0)|(_SHIFTL(sample_pattern
[0][1],4,4));
1904 reg01
= (reg01
&~0xf00)|(_SHIFTL(sample_pattern
[1][0],8,4));
1905 reg01
= (reg01
&~0xf000)|(_SHIFTL(sample_pattern
[1][1],12,4));
1906 reg01
= (reg01
&~0xf0000)|(_SHIFTL(sample_pattern
[2][0],16,4));
1907 reg01
= (reg01
&~0xf00000)|(_SHIFTL(sample_pattern
[2][1],20,4));
1908 reg01
= (reg01
&~0xff000000)|(_SHIFTL(0x01,24,8));
1910 reg02
= sample_pattern
[3][0]&0xf;
1911 reg02
= (reg02
&~0xf0)|(_SHIFTL(sample_pattern
[3][1],4,4));
1912 reg02
= (reg02
&~0xf00)|(_SHIFTL(sample_pattern
[4][0],8,4));
1913 reg02
= (reg02
&~0xf000)|(_SHIFTL(sample_pattern
[4][1],12,4));
1914 reg02
= (reg02
&~0xf0000)|(_SHIFTL(sample_pattern
[5][0],16,4));
1915 reg02
= (reg02
&~0xf00000)|(_SHIFTL(sample_pattern
[5][1],20,4));
1916 reg02
= (reg02
&~0xff000000)|(_SHIFTL(0x02,24,8));
1918 reg03
= sample_pattern
[6][0]&0xf;
1919 reg03
= (reg03
&~0xf0)|(_SHIFTL(sample_pattern
[6][1],4,4));
1920 reg03
= (reg03
&~0xf00)|(_SHIFTL(sample_pattern
[7][0],8,4));
1921 reg03
= (reg03
&~0xf000)|(_SHIFTL(sample_pattern
[7][1],12,4));
1922 reg03
= (reg03
&~0xf0000)|(_SHIFTL(sample_pattern
[8][0],16,4));
1923 reg03
= (reg03
&~0xf00000)|(_SHIFTL(sample_pattern
[8][1],20,4));
1924 reg03
= (reg03
&~0xff000000)|(_SHIFTL(0x03,24,8));
1926 reg04
= sample_pattern
[9][0]&0xf;
1927 reg04
= (reg04
&~0xf0)|(_SHIFTL(sample_pattern
[9][1],4,4));
1928 reg04
= (reg04
&~0xf00)|(_SHIFTL(sample_pattern
[10][0],8,4));
1929 reg04
= (reg04
&~0xf000)|(_SHIFTL(sample_pattern
[10][1],12,4));
1930 reg04
= (reg04
&~0xf0000)|(_SHIFTL(sample_pattern
[11][0],16,4));
1931 reg04
= (reg04
&~0xf00000)|(_SHIFTL(sample_pattern
[11][1],20,4));
1932 reg04
= (reg04
&~0xff000000)|(_SHIFTL(0x04,24,8));
1939 GX_LOAD_BP_REG(reg01
);
1940 GX_LOAD_BP_REG(reg02
);
1941 GX_LOAD_BP_REG(reg03
);
1942 GX_LOAD_BP_REG(reg04
);
1947 reg53
= 0x53000000|(vfilter
[0]&0x3f);
1948 reg53
= (reg53
&~0xfc0)|(_SHIFTL(vfilter
[1],6,6));
1949 reg53
= (reg53
&~0x3f000)|(_SHIFTL(vfilter
[2],12,6));
1950 reg53
= (reg53
&~0xfc0000)|(_SHIFTL(vfilter
[3],18,6));
1952 reg54
= 0x54000000|(vfilter
[4]&0x3f);
1953 reg54
= (reg54
&~0xfc0)|(_SHIFTL(vfilter
[5],6,6));
1954 reg54
= (reg54
&~0x3f000)|(_SHIFTL(vfilter
[6],12,6));
1956 GX_LOAD_BP_REG(reg53
);
1957 GX_LOAD_BP_REG(reg54
);
1960 void GX_SetDispCopyFrame2Field(u8 mode
)
1962 __gx
->dispCopyCntrl
= (__gx
->dispCopyCntrl
&~0x3000)|(_SHIFTL(mode
,12,2));
1965 u32
GX_SetDispCopyYScale(f32 yscale
)
1969 yScale
= ((u32
)(256.0f
/yscale
))&0x1ff;
1970 GX_LOAD_BP_REG(0x4e000000|yScale
);
1972 __gx
->dispCopyCntrl
= (__gx
->dispCopyCntrl
&~0x400)|(_SHIFTL(((256-yScale
)>0),10,1));
1973 ht
= _SHIFTR(__gx
->dispCopyWH
,12,10)+1;
1974 return __GX_GetNumXfbLines(ht
,yScale
);
1977 void GX_SetDispCopyDst(u16 wd
,u16 ht
)
1979 __gx
->dispCopyDst
= (__gx
->dispCopyDst
&~0x3ff)|(_SHIFTR(wd
,4,10));
1980 __gx
->dispCopyDst
= (__gx
->dispCopyDst
&~0xff000000)|(_SHIFTL(0x4d,24,8));
1983 void GX_SetDispCopySrc(u16 left
,u16 top
,u16 wd
,u16 ht
)
1985 __gx
->dispCopyTL
= (__gx
->dispCopyTL
&~0x00ffffff)|XY(left
,top
);
1986 __gx
->dispCopyTL
= (__gx
->dispCopyTL
&~0xff000000)|(_SHIFTL(0x49,24,8));
1987 __gx
->dispCopyWH
= (__gx
->dispCopyWH
&~0x00ffffff)|XY((wd
-1),(ht
-1));
1988 __gx
->dispCopyWH
= (__gx
->dispCopyWH
&~0xff000000)|(_SHIFTL(0x4a,24,8));
1991 void GX_CopyDisp(void *dest
,u8 clear
)
1997 val
= (__gx
->peZMode
&~0xf)|0xf;
1998 GX_LOAD_BP_REG(val
);
1999 val
= (__gx
->peCMode0
&~0x3);
2000 GX_LOAD_BP_REG(val
);
2004 if(clear
|| (__gx
->peCntrl
&0x7)==0x0003) {
2005 if(__gx
->peCntrl
&0x40) {
2007 val
= (__gx
->peCntrl
&~0x40);
2008 GX_LOAD_BP_REG(val
);
2012 GX_LOAD_BP_REG(__gx
->dispCopyTL
); // set source top
2013 GX_LOAD_BP_REG(__gx
->dispCopyWH
);
2015 GX_LOAD_BP_REG(__gx
->dispCopyDst
);
2017 val
= 0x4b000000|(_SHIFTR(MEM_VIRTUAL_TO_PHYSICAL(dest
),5,24));
2018 GX_LOAD_BP_REG(val
);
2020 __gx
->dispCopyCntrl
= (__gx
->dispCopyCntrl
&~0x800)|(_SHIFTL(clear
,11,1));
2021 __gx
->dispCopyCntrl
= (__gx
->dispCopyCntrl
&~0x4000)|0x4000;
2022 __gx
->dispCopyCntrl
= (__gx
->dispCopyCntrl
&~0xff000000)|(_SHIFTL(0x52,24,8));
2024 GX_LOAD_BP_REG(__gx
->dispCopyCntrl
);
2027 GX_LOAD_BP_REG(__gx
->peZMode
);
2028 GX_LOAD_BP_REG(__gx
->peCMode0
);
2030 if(clflag
) GX_LOAD_BP_REG(__gx
->peCntrl
);
2033 void GX_CopyTex(void *dest
,u8 clear
)
2039 val
= (__gx
->peZMode
&~0xf)|0xf;
2040 GX_LOAD_BP_REG(val
);
2041 val
= (__gx
->peCMode0
&~0x3);
2042 GX_LOAD_BP_REG(val
);
2046 val
= __gx
->peCntrl
;
2047 if(__gx
->texCopyZTex
&& (val
&0x7)!=0x0003) {
2049 val
= (val
&~0x7)|0x0003;
2051 if(clear
|| (val
&0x7)==0x0003) {
2057 if(clflag
) GX_LOAD_BP_REG(val
);
2059 val
= 0x4b000000|(_SHIFTR(MEM_VIRTUAL_TO_PHYSICAL(dest
),5,24));
2061 GX_LOAD_BP_REG(__gx
->texCopyTL
);
2062 GX_LOAD_BP_REG(__gx
->texCopyWH
);
2063 GX_LOAD_BP_REG(__gx
->texCopyDst
);
2064 GX_LOAD_BP_REG(val
);
2066 __gx
->texCopyCntrl
= (__gx
->texCopyCntrl
&~0x800)|(_SHIFTL(clear
,11,1));
2067 __gx
->texCopyCntrl
= (__gx
->texCopyCntrl
&~0x4000);
2068 __gx
->texCopyCntrl
= (__gx
->texCopyCntrl
&~0xff000000)|(_SHIFTL(0x52,24,8));
2069 GX_LOAD_BP_REG(__gx
->texCopyCntrl
);
2072 GX_LOAD_BP_REG(__gx
->peZMode
);
2073 GX_LOAD_BP_REG(__gx
->peCMode0
);
2075 if(clflag
) GX_LOAD_BP_REG(__gx
->peCntrl
);
2078 void GX_SetTexCopySrc(u16 left
,u16 top
,u16 wd
,u16 ht
)
2080 __gx
->texCopyTL
= (__gx
->texCopyTL
&~0x00ffffff)|XY(left
,top
);
2081 __gx
->texCopyTL
= (__gx
->texCopyTL
&~0xff000000)|(_SHIFTL(0x49,24,8));
2082 __gx
->texCopyWH
= (__gx
->texCopyWH
&~0x00ffffff)|XY((wd
-1),(ht
-1));
2083 __gx
->texCopyWH
= (__gx
->texCopyWH
&~0xff000000)|(_SHIFTL(0x4a,24,8));
2086 void GX_SetTexCopyDst(u16 wd
,u16 ht
,u32 fmt
,u8 mipmap
)
2089 u32 xtiles
,ytiles
,zplanes
;
2091 __GetImageTileCount(fmt
,wd
,ht
,&xtiles
,&ytiles
,&zplanes
);
2092 __gx
->texCopyDst
= (__gx
->texCopyDst
&~0x3ff)|((xtiles
*zplanes
)&0x3ff);
2094 if(fmt
==GX_TF_Z16
) lfmt
= 11;
2095 if(fmt
==GX_CTF_YUVA8
|| (fmt
>=GX_TF_I4
&& fmt
<GX_TF_RGB565
)) __gx
->texCopyCntrl
= (__gx
->texCopyCntrl
&~0x18000)|0x18000;
2096 else __gx
->texCopyCntrl
= (__gx
->texCopyCntrl
&~0x18000)|0x10000;
2098 __gx
->texCopyCntrl
= (__gx
->texCopyCntrl
&~0x8)|(lfmt
&0x8);
2099 __gx
->texCopyCntrl
= (__gx
->texCopyCntrl
&~0x200)|(_SHIFTL(mipmap
,9,1));
2100 __gx
->texCopyCntrl
= (__gx
->texCopyCntrl
&~0x70)|(_SHIFTL(lfmt
,4,3));
2102 __gx
->texCopyDst
= (__gx
->texCopyDst
&~0xff000000)|(_SHIFTL(0x4d,24,8));
2104 __gx
->texCopyZTex
= ((fmt
&_GX_TF_ZTF
)==_GX_TF_ZTF
);
2107 void GX_ClearBoundingBox()
2109 GX_LOAD_BP_REG(0x550003ff);
2110 GX_LOAD_BP_REG(0x560003ff);
2113 void GX_BeginDispList(void *list
,u32 size
)
2115 struct __gxfifo
*fifo
;
2117 if(__gx
->dirtyState
)
2118 __GX_SetDirtyState();
2121 memcpy(_gx_saved_data
,__gxregs
,STRUCT_REGDEF_SIZE
);
2123 fifo
= (struct __gxfifo
*)&_gx_dl_fifoobj
;
2124 fifo
->buf_start
= (u32
)list
;
2125 fifo
->buf_end
= (u32
)list
+ size
- 4;
2128 fifo
->rd_ptr
= (u32
)list
;
2129 fifo
->wt_ptr
= (u32
)list
;
2132 __gx
->gxFifoUnlinked
= 1;
2134 GX_GetCPUFifo(&_gx_old_cpufifo
);
2135 GX_SetCPUFifo(&_gx_dl_fifoobj
);
2136 __GX_ResetWriteGatherPipe();
2139 u32
GX_EndDispList()
2144 GX_GetCPUFifo(&_gx_dl_fifoobj
);
2145 GX_SetCPUFifo(&_gx_old_cpufifo
);
2147 if(__gx
->saveDLctx
) {
2148 _CPU_ISR_Disable(level
);
2149 memcpy(__gxregs
,_gx_saved_data
,STRUCT_REGDEF_SIZE
);
2150 _CPU_ISR_Restore(level
);
2153 __gx
->gxFifoUnlinked
= 0;
2155 wrap
= GX_GetFifoWrap(&_gx_dl_fifoobj
);
2158 return GX_GetFifoCount(&_gx_dl_fifoobj
);
2161 void GX_CallDispList(void *list
,u32 nbytes
)
2163 if(__gx
->dirtyState
)
2164 __GX_SetDirtyState();
2167 __GX_SendFlushPrim();
2169 wgPipe
->U8
= 0x40; //call displaylist
2170 wgPipe
->U32
= MEM_VIRTUAL_TO_PHYSICAL(list
);
2171 wgPipe
->U32
= nbytes
;
2174 void GX_SetChanCtrl(s32 channel
,u8 enable
,u8 ambsrc
,u8 matsrc
,u8 litmask
,u8 diff_fn
,u8 attn_fn
)
2176 u32 reg
,difffn
= (attn_fn
==GX_AF_SPEC
)?GX_DF_NONE
:diff_fn
;
2177 u32 val
= (matsrc
&1)|(_SHIFTL(enable
,1,1))|(_SHIFTL(litmask
,2,4))|(_SHIFTL(ambsrc
,6,1))|(_SHIFTL(difffn
,7,2))|(_SHIFTL(((GX_AF_NONE
-attn_fn
)>0),9,1))|(_SHIFTL((attn_fn
&1),10,1))|(_SHIFTL((_SHIFTR(litmask
,4,4)),11,4));
2179 reg
= (channel
&0x03);
2180 __gx
->chnCntrl
[reg
] = val
;
2181 __gx
->dirtyState
|= (0x1000<<reg
);
2183 if(channel
==GX_COLOR0A0
) {
2184 __gx
->chnCntrl
[2] = val
;
2185 __gx
->dirtyState
|= 0x5000;
2187 __gx
->chnCntrl
[3] = val
;
2188 __gx
->dirtyState
|= 0xa000;
2192 void GX_SetChanAmbColor(s32 channel
,GXColor color
)
2194 u32 reg
,val
= (_SHIFTL(color
.r
,24,8))|(_SHIFTL(color
.g
,16,8))|(_SHIFTL(color
.b
,8,8))|0x00;
2198 val
|= (__gx
->chnAmbColor
[0]&0xff);
2202 val
|= (__gx
->chnAmbColor
[1]&0xff);
2206 val
= ((__gx
->chnAmbColor
[0]&~0xff)|(color
.a
&0xff));
2210 val
= ((__gx
->chnAmbColor
[1]&~0xff)|(color
.a
&0xff));
2214 val
|= (color
.a
&0xFF);
2218 val
|= (color
.a
&0xFF);
2224 __gx
->chnAmbColor
[reg
] = val
;
2225 __gx
->dirtyState
|= (0x0100<<reg
);
2228 void GX_SetChanMatColor(s32 channel
,GXColor color
)
2230 u32 reg
,val
= (_SHIFTL(color
.r
,24,8))|(_SHIFTL(color
.g
,16,8))|(_SHIFTL(color
.b
,8,8))|0x00;
2234 val
|= (__gx
->chnMatColor
[0]&0xff);
2238 val
|= (__gx
->chnMatColor
[1]&0xff);
2242 val
= ((__gx
->chnMatColor
[0]&~0xff)|(color
.a
&0xff));
2246 val
= ((__gx
->chnMatColor
[1]&~0xff)|(color
.a
&0xff));
2250 val
|= (color
.a
&0xFF);
2254 val
|= (color
.a
&0xFF);
2260 __gx
->chnMatColor
[reg
] = val
;
2261 __gx
->dirtyState
|= (0x0400<<reg
);
2264 void GX_SetArray(u32 attr
,void *ptr
,u8 stride
)
2268 if(attr
==GX_VA_NBT
) attr
= GX_VA_NRM
;
2269 if(attr
>=GX_VA_POS
&& attr
<=GX_LIGHTARRAY
) {
2270 idx
= attr
-GX_VA_POS
;
2271 GX_LOAD_CP_REG((0xA0+idx
),(u32
)MEM_VIRTUAL_TO_PHYSICAL(ptr
));
2272 GX_LOAD_CP_REG((0xB0+idx
),(u32
)stride
);
2276 static __inline__
void __SETVCDATTR(u8 attr
,u8 type
)
2279 case GX_VA_PTNMTXIDX
:
2280 __gx
->vcdLo
= (__gx
->vcdLo
&~0x1)|(type
&0x1);
2282 case GX_VA_TEX0MTXIDX
:
2283 __gx
->vcdLo
= (__gx
->vcdLo
&~0x2)|(_SHIFTL(type
,1,1));
2285 case GX_VA_TEX1MTXIDX
:
2286 __gx
->vcdLo
= (__gx
->vcdLo
&~0x4)|(_SHIFTL(type
,2,1));
2288 case GX_VA_TEX2MTXIDX
:
2289 __gx
->vcdLo
= (__gx
->vcdLo
&~0x8)|(_SHIFTL(type
,3,1));
2291 case GX_VA_TEX3MTXIDX
:
2292 __gx
->vcdLo
= (__gx
->vcdLo
&~0x10)|(_SHIFTL(type
,4,1));
2294 case GX_VA_TEX4MTXIDX
:
2295 __gx
->vcdLo
= (__gx
->vcdLo
&~0x20)|(_SHIFTL(type
,5,1));
2297 case GX_VA_TEX5MTXIDX
:
2298 __gx
->vcdLo
= (__gx
->vcdLo
&~0x40)|(_SHIFTL(type
,6,1));
2300 case GX_VA_TEX6MTXIDX
:
2301 __gx
->vcdLo
= (__gx
->vcdLo
&~0x80)|(_SHIFTL(type
,7,1));
2303 case GX_VA_TEX7MTXIDX
:
2304 __gx
->vcdLo
= (__gx
->vcdLo
&~0x100)|(_SHIFTL(type
,8,1));
2307 __gx
->vcdLo
= (__gx
->vcdLo
&~0x600)|(_SHIFTL(type
,9,2));
2310 __gx
->vcdLo
= (__gx
->vcdLo
&~0x1800)|(_SHIFTL(type
,11,2));
2314 __gx
->vcdLo
= (__gx
->vcdLo
&~0x1800)|(_SHIFTL(type
,11,2));
2318 __gx
->vcdLo
= (__gx
->vcdLo
&~0x6000)|(_SHIFTL(type
,13,2));
2321 __gx
->vcdLo
= (__gx
->vcdLo
&~0x18000)|(_SHIFTL(type
,15,2));
2324 __gx
->vcdHi
= (__gx
->vcdHi
&~0x3)|(type
&0x3);
2327 __gx
->vcdHi
= (__gx
->vcdHi
&~0xc)|(_SHIFTL(type
,2,2));
2330 __gx
->vcdHi
= (__gx
->vcdHi
&~0x30)|(_SHIFTL(type
,4,2));
2333 __gx
->vcdHi
= (__gx
->vcdHi
&~0xc0)|(_SHIFTL(type
,6,2));
2336 __gx
->vcdHi
= (__gx
->vcdHi
&~0x300)|(_SHIFTL(type
,8,2));
2339 __gx
->vcdHi
= (__gx
->vcdHi
&~0xc00)|(_SHIFTL(type
,10,2));
2342 __gx
->vcdHi
= (__gx
->vcdHi
&~0x3000)|(_SHIFTL(type
,12,2));
2345 __gx
->vcdHi
= (__gx
->vcdHi
&~0xc000)|(_SHIFTL(type
,14,2));
2350 void GX_SetVtxDesc(u8 attr
,u8 type
)
2352 __SETVCDATTR(attr
,type
);
2353 __gx
->dirtyState
|= 0x0008;
2356 void GX_SetVtxDescv(GXVtxDesc
*attr_list
)
2360 if(!attr_list
) return;
2362 for(i
=0;i
<GX_MAX_VTXDESC_LISTSIZE
;i
++){
2363 if(attr_list
[i
].attr
==GX_VA_NULL
) break;
2365 __SETVCDATTR(attr_list
[i
].attr
,attr_list
[i
].type
);
2367 __gx
->dirtyState
|= 0x0008;
2370 void GX_GetVtxDescv(GXVtxDesc
*attr_list
)
2374 // Clear everything first
2375 for(count
=0;count
<GX_MAX_VTXDESC_LISTSIZE
;count
++) {
2376 attr_list
[count
].attr
= GX_VA_NULL
;
2377 attr_list
[count
].type
= 0;
2381 if(__gx
->vcdLo
&0x1) {
2382 attr_list
[count
].attr
= GX_VA_PTNMTXIDX
;
2383 attr_list
[count
].type
= __gx
->vcdLo
&0x1;
2387 if(__gx
->vcdLo
&0x2) {
2388 attr_list
[count
].attr
= GX_VA_TEX0MTXIDX
;
2389 attr_list
[count
].type
= _SHIFTR(__gx
->vcdLo
&0x2,1,1);
2393 if(__gx
->vcdLo
&0x4) {
2394 attr_list
[count
].attr
= GX_VA_TEX1MTXIDX
;
2395 attr_list
[count
].type
= _SHIFTR(__gx
->vcdLo
&0x4,2,1);
2399 if(__gx
->vcdLo
&0x8) {
2400 attr_list
[count
].attr
= GX_VA_TEX2MTXIDX
;
2401 attr_list
[count
].type
= _SHIFTR(__gx
->vcdLo
&0x8,3,1);
2405 if(__gx
->vcdLo
&0x10) {
2406 attr_list
[count
].attr
= GX_VA_TEX3MTXIDX
;
2407 attr_list
[count
].type
= _SHIFTR(__gx
->vcdLo
&0x10,4,1);
2411 if(__gx
->vcdLo
&0x20) {
2412 attr_list
[count
].attr
= GX_VA_TEX4MTXIDX
;
2413 attr_list
[count
].type
= _SHIFTR(__gx
->vcdLo
&0x20,5,1);
2417 if(__gx
->vcdLo
&0x40) {
2418 attr_list
[count
].attr
= GX_VA_TEX5MTXIDX
;
2419 attr_list
[count
].type
= _SHIFTR(__gx
->vcdLo
&0x40,6,1);
2423 if(__gx
->vcdLo
&0x80) {
2424 attr_list
[count
].attr
= GX_VA_TEX6MTXIDX
;
2425 attr_list
[count
].type
= _SHIFTR(__gx
->vcdLo
&0x80,7,1);
2429 if(__gx
->vcdLo
&0x100) {
2430 attr_list
[count
].attr
= GX_VA_TEX7MTXIDX
;
2431 attr_list
[count
].type
= _SHIFTR(__gx
->vcdLo
&0x100,8,1);
2435 if(__gx
->vcdLo
&0x600) {
2436 attr_list
[count
].attr
= GX_VA_POS
;
2437 attr_list
[count
].type
= _SHIFTR(__gx
->vcdLo
&0x600,9,2);
2441 if(__gx
->vcdLo
&0x1800) {
2442 if(__gx
->vcdNrms
==1) {
2443 attr_list
[count
].attr
= GX_VA_NRM
;
2444 attr_list
[count
].type
= _SHIFTR(__gx
->vcdLo
&0x1800,11,2);
2446 } else if(__gx
->vcdNrms
==2){
2447 attr_list
[count
].attr
= GX_VA_NBT
;
2448 attr_list
[count
].type
= _SHIFTR(__gx
->vcdLo
&0x1800,11,2);
2453 if(__gx
->vcdLo
&0x6000) {
2454 attr_list
[count
].attr
= GX_VA_CLR0
;
2455 attr_list
[count
].type
= _SHIFTR(__gx
->vcdLo
&0x6000,13,2);
2459 if(__gx
->vcdLo
&0x18000) {
2460 attr_list
[count
].attr
= GX_VA_CLR1
;
2461 attr_list
[count
].type
= _SHIFTR(__gx
->vcdLo
&0x18000,15,2);
2465 if(__gx
->vcdHi
&0x3) {
2466 attr_list
[count
].attr
= GX_VA_TEX0
;
2467 attr_list
[count
].type
= __gx
->vcdHi
&0x3;
2471 if(__gx
->vcdHi
&0xc) {
2472 attr_list
[count
].attr
= GX_VA_TEX1
;
2473 attr_list
[count
].type
= _SHIFTR(__gx
->vcdHi
&0xc,2,2);
2477 if(__gx
->vcdHi
&0x30) {
2478 attr_list
[count
].attr
= GX_VA_TEX2
;
2479 attr_list
[count
].type
= _SHIFTR(__gx
->vcdHi
&0x30,4,2);
2483 if(__gx
->vcdHi
&0xc0) {
2484 attr_list
[count
].attr
= GX_VA_TEX3
;
2485 attr_list
[count
].type
= _SHIFTR(__gx
->vcdHi
&0xc0,6,2);
2489 if(__gx
->vcdHi
&0x300) {
2490 attr_list
[count
].attr
= GX_VA_TEX4
;
2491 attr_list
[count
].type
= _SHIFTR(__gx
->vcdHi
&0x300,8,2);
2495 if(__gx
->vcdHi
&0xc00) {
2496 attr_list
[count
].attr
= GX_VA_TEX5
;
2497 attr_list
[count
].type
= _SHIFTR(__gx
->vcdHi
&0xc00,10,2);
2501 if(__gx
->vcdHi
&0x3000) {
2502 attr_list
[count
].attr
= GX_VA_TEX6
;
2503 attr_list
[count
].type
= _SHIFTR(__gx
->vcdHi
&0x3000,12,2);
2507 if(__gx
->vcdHi
&0xc000) {
2508 attr_list
[count
].attr
= GX_VA_TEX7
;
2509 attr_list
[count
].type
= _SHIFTR(__gx
->vcdHi
&0xc000,14,2);
2514 static __inline__
void __SETVCDFMT(u8 vtxfmt
,u32 vtxattr
,u32 comptype
,u32 compsize
,u32 frac
)
2516 u8 vat
= (vtxfmt
&7);
2518 if(vtxattr
==GX_VA_POS
&& (comptype
==GX_POS_XY
|| comptype
==GX_POS_XYZ
)
2519 && (compsize
>=GX_U8
&& compsize
<=GX_F32
)) {
2520 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x1)|(comptype
&1);
2521 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0xe)|(_SHIFTL(compsize
,1,3));
2522 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x1f0)|(_SHIFTL(frac
,4,5));
2524 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x40000000)|0x40000000;
2525 } else if(vtxattr
==GX_VA_NRM
&& comptype
==GX_NRM_XYZ
2526 && (compsize
==GX_S8
|| compsize
==GX_S16
|| compsize
==GX_F32
)) {
2527 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x200);
2528 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x1C00)|(_SHIFTL(compsize
,10,3));
2529 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x80000000);
2530 } else if(vtxattr
==GX_VA_NBT
&& (comptype
==GX_NRM_NBT
|| comptype
==GX_NRM_NBT3
)
2531 && (compsize
==GX_S8
|| compsize
==GX_S16
|| compsize
==GX_F32
)) {
2532 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x200)|0x200;
2533 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x1C00)|(_SHIFTL(compsize
,10,3));
2534 if(comptype
==GX_NRM_NBT3
)
2535 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x80000000)|0x80000000;
2536 } else if(vtxattr
==GX_VA_CLR0
&& (comptype
==GX_CLR_RGB
|| comptype
==GX_CLR_RGBA
)
2537 && (compsize
>=GX_RGB565
&& compsize
<=GX_RGBA8
)) {
2538 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x2000)|(_SHIFTL(comptype
,13,1));
2539 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x1C000)|(_SHIFTL(compsize
,14,3));
2540 } else if(vtxattr
==GX_VA_CLR1
&& (comptype
==GX_CLR_RGB
|| comptype
==GX_CLR_RGBA
)
2541 && (compsize
>=GX_RGB565
&& compsize
<=GX_RGBA8
)) {
2542 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x20000)|(_SHIFTL(comptype
,17,1));
2543 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x1C0000)|(_SHIFTL(compsize
,18,3));
2544 } else if(vtxattr
==GX_VA_TEX0
&& (comptype
==GX_TEX_S
|| comptype
==GX_TEX_ST
)
2545 && (compsize
>=GX_U8
&& compsize
<=GX_F32
)) {
2546 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x200000)|(_SHIFTL(comptype
,21,1));
2547 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x1C00000)|(_SHIFTL(compsize
,22,3));
2548 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x3E000000)|(_SHIFTL(frac
,25,5));
2550 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x40000000)|0x40000000;
2551 } else if(vtxattr
==GX_VA_TEX1
&& (comptype
==GX_TEX_S
|| comptype
==GX_TEX_ST
)
2552 && (compsize
>=GX_U8
&& compsize
<=GX_F32
)) {
2553 __gx
->VAT1reg
[vat
] = (__gx
->VAT1reg
[vat
]&~0x1)|(comptype
&1);
2554 __gx
->VAT1reg
[vat
] = (__gx
->VAT1reg
[vat
]&~0xe)|(_SHIFTL(compsize
,1,3));
2555 __gx
->VAT1reg
[vat
] = (__gx
->VAT1reg
[vat
]&~0x1F0)|(_SHIFTL(frac
,4,5));
2557 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x40000000)|0x40000000;
2558 } else if(vtxattr
==GX_VA_TEX2
&& (comptype
==GX_TEX_S
|| comptype
==GX_TEX_ST
)
2559 && (compsize
>=GX_U8
&& compsize
<=GX_F32
)) {
2560 __gx
->VAT1reg
[vat
] = (__gx
->VAT1reg
[vat
]&~0x200)|(_SHIFTL(comptype
,9,1));
2561 __gx
->VAT1reg
[vat
] = (__gx
->VAT1reg
[vat
]&~0x1C00)|(_SHIFTL(compsize
,10,3));
2562 __gx
->VAT1reg
[vat
] = (__gx
->VAT1reg
[vat
]&~0x3E000)|(_SHIFTL(frac
,13,5));
2564 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x40000000)|0x40000000;
2565 } else if(vtxattr
==GX_VA_TEX3
&& (comptype
==GX_TEX_S
|| comptype
==GX_TEX_ST
)
2566 && (compsize
>=GX_U8
&& compsize
<=GX_F32
)) {
2567 __gx
->VAT1reg
[vat
] = (__gx
->VAT1reg
[vat
]&~0x40000)|(_SHIFTL(comptype
,18,1));
2568 __gx
->VAT1reg
[vat
] = (__gx
->VAT1reg
[vat
]&~0x380000)|(_SHIFTL(compsize
,19,3));
2569 __gx
->VAT1reg
[vat
] = (__gx
->VAT1reg
[vat
]&~0x7C00000)|(_SHIFTL(frac
,22,5));
2571 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x40000000)|0x40000000;
2572 } else if(vtxattr
==GX_VA_TEX4
&& (comptype
==GX_TEX_S
|| comptype
==GX_TEX_ST
)
2573 && (compsize
>=GX_U8
&& compsize
<=GX_F32
)) {
2574 __gx
->VAT1reg
[vat
] = (__gx
->VAT1reg
[vat
]&~0x8000000)|(_SHIFTL(comptype
,27,1));
2575 __gx
->VAT1reg
[vat
] = (__gx
->VAT1reg
[vat
]&~0x70000000)|(_SHIFTL(compsize
,28,3));
2576 __gx
->VAT2reg
[vat
] = (__gx
->VAT2reg
[vat
]&~0x1f)|(frac
&0x1f);
2578 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x40000000)|0x40000000;
2579 } else if(vtxattr
==GX_VA_TEX5
&& (comptype
==GX_TEX_S
|| comptype
==GX_TEX_ST
)
2580 && (compsize
>=GX_U8
&& compsize
<=GX_F32
)) {
2581 __gx
->VAT2reg
[vat
] = (__gx
->VAT2reg
[vat
]&~0x20)|(_SHIFTL(comptype
,5,1));
2582 __gx
->VAT2reg
[vat
] = (__gx
->VAT2reg
[vat
]&~0x1C0)|(_SHIFTL(compsize
,6,3));
2583 __gx
->VAT2reg
[vat
] = (__gx
->VAT2reg
[vat
]&~0x3E00)|(_SHIFTL(frac
,9,5));
2585 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x40000000)|0x40000000;
2586 } else if(vtxattr
==GX_VA_TEX6
&& (comptype
==GX_TEX_S
|| comptype
==GX_TEX_ST
)
2587 && (compsize
>=GX_U8
&& compsize
<=GX_F32
)) {
2588 __gx
->VAT2reg
[vat
] = (__gx
->VAT2reg
[vat
]&~0x4000)|(_SHIFTL(comptype
,14,1));
2589 __gx
->VAT2reg
[vat
] = (__gx
->VAT2reg
[vat
]&~0x38000)|(_SHIFTL(compsize
,15,3));
2590 __gx
->VAT2reg
[vat
] = (__gx
->VAT2reg
[vat
]&~0x7C0000)|(_SHIFTL(frac
,18,5));
2592 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x40000000)|0x40000000;
2593 } else if(vtxattr
==GX_VA_TEX7
&& (comptype
==GX_TEX_S
|| comptype
==GX_TEX_ST
)
2594 && (compsize
>=GX_U8
&& compsize
<=GX_F32
)) {
2595 __gx
->VAT2reg
[vat
] = (__gx
->VAT2reg
[vat
]&~0x800000)|(_SHIFTL(comptype
,23,1));
2596 __gx
->VAT2reg
[vat
] = (__gx
->VAT2reg
[vat
]&~0x7000000)|(_SHIFTL(compsize
,24,3));
2597 __gx
->VAT2reg
[vat
] = (__gx
->VAT2reg
[vat
]&~0xF8000000)|(_SHIFTL(frac
,27,5));
2599 __gx
->VAT0reg
[vat
] = (__gx
->VAT0reg
[vat
]&~0x40000000)|0x40000000;
2603 void GX_SetVtxAttrFmt(u8 vtxfmt
,u32 vtxattr
,u32 comptype
,u32 compsize
,u32 frac
)
2605 __SETVCDFMT(vtxfmt
,vtxattr
,comptype
,compsize
,frac
);
2606 __gx
->VATTable
|= (1<<vtxfmt
);
2607 __gx
->dirtyState
|= 0x0010;
2610 void GX_SetVtxAttrFmtv(u8 vtxfmt
,GXVtxAttrFmt
*attr_list
)
2614 for(i
=0;i
<GX_MAX_VTXATTRFMT_LISTSIZE
;i
++) {
2615 if(attr_list
[i
].vtxattr
==GX_VA_NULL
) break;
2617 __SETVCDFMT(vtxfmt
,attr_list
[i
].vtxattr
,attr_list
[i
].comptype
,attr_list
[i
].compsize
,attr_list
[i
].frac
);
2619 __gx
->VATTable
|= (1<<vtxfmt
);
2620 __gx
->dirtyState
|= 0x0010;
2623 void GX_Begin(u8 primitve
,u8 vtxfmt
,u16 vtxcnt
)
2625 u8 reg
= primitve
|(vtxfmt
&7);
2627 if(__gx
->dirtyState
)
2628 __GX_SetDirtyState();
2631 wgPipe
->U16
= vtxcnt
;
2634 void GX_SetTexCoordGen(u16 texcoord
,u32 tgen_typ
,u32 tgen_src
,u32 mtxsrc
)
2636 GX_SetTexCoordGen2(texcoord
,tgen_typ
,tgen_src
,mtxsrc
,GX_FALSE
,GX_DTTIDENTITY
);
2639 void GX_SetTexCoordGen2(u16 texcoord
,u32 tgen_typ
,u32 tgen_src
,u32 mtxsrc
,u32 normalize
,u32 postmtx
)
2645 if(texcoord
>=GX_MAXCOORD
) return;
2702 if((tgen_typ
==GX_TG_MTX3x4
|| tgen_typ
==GX_TG_MTX2x4
))
2704 if(tgen_typ
==GX_TG_MTX3x4
) texcoords
= 0x02;
2706 texcoords
|= (_SHIFTL(stq
,2,1));
2707 texcoords
|= (_SHIFTL(vtxrow
,7,5));
2708 } else if((tgen_typ
>=GX_TG_BUMP0
&& tgen_typ
<=GX_TG_BUMP7
))
2710 tgen_src
-= GX_TG_TEXCOORD0
;
2711 tgen_typ
-= GX_TG_BUMP0
;
2714 texcoords
|= (_SHIFTL(stq
,2,1));
2715 texcoords
|= (_SHIFTL(vtxrow
,7,5));
2716 texcoords
|= (_SHIFTL(tgen_src
,12,3));
2717 texcoords
|= (_SHIFTL(tgen_typ
,15,3));
2718 } else if(tgen_typ
==GX_TG_SRTG
) {
2719 if(tgen_src
==GX_TG_COLOR0
) texcoords
= 0x20;
2720 else if(tgen_src
==GX_TG_COLOR1
) texcoords
= 0x30;
2721 texcoords
|= (_SHIFTL(stq
,2,1));
2722 texcoords
|= (_SHIFTL(2,7,5));
2725 postmtx
-= GX_DTTMTX0
;
2726 __gx
->texCoordGen
[txc
] = texcoords
;
2727 __gx
->texCoordGen2
[txc
] = ((_SHIFTL(normalize
,8,1))|(postmtx
&0x3f));
2731 __gx
->mtxIdxLo
= (__gx
->mtxIdxLo
&~0xfc0)|(_SHIFTL(mtxsrc
,6,6));
2734 __gx
->mtxIdxLo
= (__gx
->mtxIdxLo
&~0x3f000)|(_SHIFTL(mtxsrc
,12,6));
2737 __gx
->mtxIdxLo
= (__gx
->mtxIdxLo
&~0xfc0000)|(_SHIFTL(mtxsrc
,18,6));
2740 __gx
->mtxIdxLo
= (__gx
->mtxIdxLo
&~0x3f000000)|(_SHIFTL(mtxsrc
,24,6));
2743 __gx
->mtxIdxHi
= (__gx
->mtxIdxHi
&~0x3f)|(mtxsrc
&0x3f);
2746 __gx
->mtxIdxHi
= (__gx
->mtxIdxHi
&~0xfc0)|(_SHIFTL(mtxsrc
,6,6));
2749 __gx
->mtxIdxHi
= (__gx
->mtxIdxHi
&~0x3f000)|(_SHIFTL(mtxsrc
,12,6));
2752 __gx
->mtxIdxHi
= (__gx
->mtxIdxHi
&~0xfc0000)|(_SHIFTL(mtxsrc
,18,6));
2755 __gx
->dirtyState
|= (0x04000000|(0x00010000<<texcoord
));
2758 void GX_SetZTexture(u8 op
,u8 fmt
,u32 bias
)
2762 if(fmt
==GX_TF_Z8
) fmt
= 0;
2763 else if(fmt
==GX_TF_Z16
) fmt
= 1;
2766 val
= (u32
)(_SHIFTL(op
,2,2))|(fmt
&3);
2767 GX_LOAD_BP_REG(0xF4000000|(bias
&0x00FFFFFF));
2768 GX_LOAD_BP_REG(0xF5000000|(val
&0x00FFFFFF));
2771 static inline void WriteMtxPS4x3(register Mtx mt
,register void *wgpipe
)
2773 register f32 tmp0
,tmp1
,tmp2
,tmp3
,tmp4
,tmp5
;
2774 __asm__
__volatile__ (
2775 "psq_l %0,0(%6),0,0\n\
2776 psq_l %1,8(%6),0,0\n\
2777 psq_l %2,16(%6),0,0\n\
2778 psq_l %3,24(%6),0,0\n\
2779 psq_l %4,32(%6),0,0\n\
2780 psq_l %5,40(%6),0,0\n\
2781 psq_st %0,0(%7),0,0\n\
2782 psq_st %1,0(%7),0,0\n\
2783 psq_st %2,0(%7),0,0\n\
2784 psq_st %3,0(%7),0,0\n\
2785 psq_st %4,0(%7),0,0\n\
2786 psq_st %5,0(%7),0,0"
2787 : "=&f"(tmp0
),"=&f"(tmp1
),"=&f"(tmp2
),"=&f"(tmp3
),"=&f"(tmp4
),"=&f"(tmp5
)
2788 : "b"(mt
), "b"(wgpipe
)
2793 static inline void WriteMtxPS3x3from4x3(register Mtx mt
,register void *wgpipe
)
2795 register f32 tmp0
,tmp1
,tmp2
,tmp3
,tmp4
,tmp5
;
2796 __asm__ __volatile__
2797 ("psq_l %0,0(%6),0,0\n\
2799 psq_l %2,16(%6),0,0\n\
2801 psq_l %4,32(%6),0,0\n\
2803 psq_st %0,0(%7),0,0\n\
2805 psq_st %2,0(%7),0,0\n\
2807 psq_st %4,0(%7),0,0\n\
2809 : "=&f"(tmp0
),"=&f"(tmp1
),"=&f"(tmp2
),"=&f"(tmp3
),"=&f"(tmp4
),"=&f"(tmp5
)
2810 : "b"(mt
), "b"(wgpipe
)
2815 static inline void WriteMtxPS3x3(register Mtx33 mt
,register void *wgpipe
)
2817 register f32 tmp0
,tmp1
,tmp2
,tmp3
,tmp4
;
2818 __asm__ __volatile__
2819 ("psq_l %0,0(%5),0,0\n\
2820 psq_l %1,8(%5),0,0\n\
2821 psq_l %2,16(%5),0,0\n\
2822 psq_l %3,24(%5),0,0\n\
2824 psq_st %0,0(%6),0,0\n\
2825 psq_st %1,0(%6),0,0\n\
2826 psq_st %2,0(%6),0,0\n\
2827 psq_st %3,0(%6),0,0\n\
2829 : "=&f"(tmp0
),"=&f"(tmp1
),"=&f"(tmp2
),"=&f"(tmp3
),"=&f"(tmp4
)
2830 : "b"(mt
), "b"(wgpipe
)
2835 static inline void WriteMtxPS4x2(register Mtx mt
,register void *wgpipe
)
2837 register f32 tmp0
,tmp1
,tmp2
,tmp3
;
2838 __asm__ __volatile__
2839 ("psq_l %0,0(%4),0,0\n\
2840 psq_l %1,8(%4),0,0\n\
2841 psq_l %2,16(%4),0,0\n\
2842 psq_l %3,24(%4),0,0\n\
2843 psq_st %0,0(%5),0,0\n\
2844 psq_st %1,0(%5),0,0\n\
2845 psq_st %2,0(%5),0,0\n\
2846 psq_st %3,0(%5),0,0"
2847 : "=&f"(tmp0
),"=&f"(tmp1
),"=&f"(tmp2
),"=&f"(tmp3
)
2848 : "b"(mt
), "b"(wgpipe
)
2853 void GX_LoadPosMtxImm(Mtx mt
,u32 pnidx
)
2855 GX_LOAD_XF_REGS((0x0000|(_SHIFTL(pnidx
,2,8))),12);
2856 WriteMtxPS4x3(mt
,(void*)wgPipe
);
2859 void GX_LoadPosMtxIdx(u16 mtxidx
,u32 pnidx
)
2862 wgPipe
->U32
= ((_SHIFTL(mtxidx
,16,16))|0xb000|(_SHIFTL(pnidx
,2,8)));
2865 void GX_LoadNrmMtxImm(Mtx mt
,u32 pnidx
)
2867 GX_LOAD_XF_REGS((0x0400|(pnidx
*3)),9);
2868 WriteMtxPS3x3from4x3(mt
,(void*)wgPipe
);
2871 void GX_LoadNrmMtxImm3x3(Mtx33 mt
,u32 pnidx
)
2873 GX_LOAD_XF_REGS((0x0400|(pnidx
*3)),9);
2874 WriteMtxPS3x3(mt
,(void*)wgPipe
);
2877 void GX_LoadNrmMtxIdx3x3(u16 mtxidx
,u32 pnidx
)
2880 wgPipe
->U32
= ((_SHIFTL(mtxidx
,16,16))|0x8000|(0x0400|(pnidx
*3)));
2883 void GX_LoadTexMtxImm(Mtx mt
,u32 texidx
,u8 type
)
2886 u32 rows
= (type
==GX_MTX2x4
)?2:3;
2888 if(texidx
<GX_DTTMTX0
) addr
= (_SHIFTL(texidx
,2,8));
2890 texidx
-= GX_DTTMTX0
;
2891 addr
= 0x0500 + (_SHIFTL(texidx
,2,8));
2894 GX_LOAD_XF_REGS(addr
,(rows
*4));
2896 WriteMtxPS4x2(mt
,(void*)wgPipe
);
2898 WriteMtxPS4x3(mt
,(void*)wgPipe
);
2901 void GX_LoadTexMtxIdx(u16 mtxidx
,u32 texidx
,u8 type
)
2903 u32 addr
,size
= (type
==GX_MTX2x4
)?7:11;
2905 if(texidx
<GX_DTTMTX0
) addr
= 0x0000|(_SHIFTL(texidx
,2,8));
2906 else addr
= 0x0500|(_SHIFTL((texidx
-GX_DTTMTX0
),2,8));
2909 wgPipe
->U32
= ((_SHIFTL(mtxidx
,16,16))|(_SHIFTL(size
,12,4))|addr
);
2912 void GX_SetCurrentMtx(u32 mtx
)
2914 __gx
->mtxIdxLo
= (__gx
->mtxIdxLo
&~0x3f)|(mtx
&0x3f);
2915 __gx
->dirtyState
|= 0x04000000;
2918 void GX_SetNumTexGens(u32 nr
)
2920 __gx
->genMode
= (__gx
->genMode
&~0xf)|(nr
&0xf);
2921 __gx
->dirtyState
|= 0x02000004;
2924 void GX_InvVtxCache()
2926 wgPipe
->U8
= 0x48; // vertex cache weg
2929 void GX_SetZMode(u8 enable
,u8 func
,u8 update_enable
)
2931 __gx
->peZMode
= (__gx
->peZMode
&~0x1)|(enable
&1);
2932 __gx
->peZMode
= (__gx
->peZMode
&~0xe)|(_SHIFTL(func
,1,3));
2933 __gx
->peZMode
= (__gx
->peZMode
&~0x10)|(_SHIFTL(update_enable
,4,1));
2934 GX_LOAD_BP_REG(__gx
->peZMode
);
2937 static void __GetTexTileShift(u32 fmt
,u32
*xshift
,u32
*yshift
)
2979 u32
GX_GetTexObjFmt(GXTexObj
*obj
)
2981 return ((struct __gx_texobj
*)obj
)->tex_fmt
;
2984 u32
GX_GetTexObjMipMap(GXTexObj
*obj
)
2986 return (((struct __gx_texobj
*)obj
)->tex_flag
&0x01);
2989 u32
GX_GetTexBufferSize(u16 wd
,u16 ht
,u32 fmt
,u8 mipmap
,u8 maxlod
)
2991 u32 xshift
,yshift
,xtiles
,ytiles
,bitsize
,size
;
3034 if(fmt
==GX_TF_RGBA8
|| fmt
==GX_TF_Z24X8
) bitsize
= 64;
3038 u32 cnt
= (maxlod
&0xff);
3042 xtiles
= ((w
+(1<<xshift
))-1)>>xshift
;
3043 ytiles
= ((h
+(1<<yshift
))-1)>>yshift
;
3044 if(cnt
==0) return size
;
3046 size
+= ((xtiles
*ytiles
)*bitsize
);
3047 if(w
==0x0001 && h
==0x0001) return size
;
3048 if(wd
>0x0001) wd
= (w
>>1);
3050 if(ht
>0x0001) ht
= (h
>>1);
3059 xtiles
= (wd
+((1<<xshift
)-1))>>xshift
;
3062 ytiles
= (ht
+((1<<yshift
)-1))>>yshift
;
3064 size
= ((xtiles
*ytiles
)*bitsize
);
3069 void GX_InitTexCacheRegion(GXTexRegion
*region
,u8 is32bmipmap
,u32 tmem_even
,u8 size_even
,u32 tmem_odd
,u8 size_odd
)
3072 struct __gx_texregion
*ptr
= (struct __gx_texregion
*)region
;
3075 case GX_TEXCACHE_32K
:
3078 case GX_TEXCACHE_128K
:
3081 case GX_TEXCACHE_512K
:
3089 ptr
->tmem_even
= (ptr
->tmem_even
&~0x7fff)|(_SHIFTR(tmem_even
,5,15));
3090 ptr
->tmem_even
= (ptr
->tmem_even
&~0x38000)|(_SHIFTL(sze
,15,3));
3091 ptr
->tmem_even
= (ptr
->tmem_even
&~0x1C0000)|(_SHIFTL(sze
,18,3));
3094 case GX_TEXCACHE_32K
:
3097 case GX_TEXCACHE_128K
:
3100 case GX_TEXCACHE_512K
:
3108 ptr
->tmem_odd
= (ptr
->tmem_odd
&~0x7fff)|(_SHIFTR(tmem_odd
,5,15));
3109 ptr
->tmem_odd
= (ptr
->tmem_odd
&~0x38000)|(_SHIFTL(sze
,15,3));
3110 ptr
->tmem_odd
= (ptr
->tmem_odd
&~0x1C0000)|(_SHIFTL(sze
,18,3));
3112 ptr
->ismipmap
= is32bmipmap
;
3116 void GX_InitTexPreloadRegion(GXTexRegion
*region
,u32 tmem_even
,u32 size_even
,u32 tmem_odd
,u32 size_odd
)
3118 struct __gx_texregion
*ptr
= (struct __gx_texregion
*)region
;
3121 ptr
->tmem_even
= (ptr
->tmem_even
&~0x7FFF)|(_SHIFTR(tmem_even
,5,15));
3122 ptr
->tmem_even
= (ptr
->tmem_even
&~0x200000)|0x200000;
3125 ptr
->tmem_odd
= (ptr
->tmem_odd
&~0x7FFF)|(_SHIFTR(tmem_odd
,5,15));
3127 ptr
->size_even
= _SHIFTR(size_even
,5,16);
3128 ptr
->size_odd
= _SHIFTR(size_odd
,5,16);
3134 void GX_InitTlutRegion(GXTlutRegion
*region
,u32 tmem_addr
,u8 tlut_sz
)
3136 struct __gx_tlutregion
*ptr
= (struct __gx_tlutregion
*)region
;
3138 tmem_addr
-= 0x80000;
3140 ptr
->tmem_addr_conf
= 0;
3141 ptr
->tmem_addr_conf
= (ptr
->tmem_addr_conf
&~0x3ff)|(_SHIFTR(tmem_addr
,9,10));
3142 ptr
->tmem_addr_conf
= (ptr
->tmem_addr_conf
&~0x1FFC00)|(_SHIFTL(tlut_sz
,10,10));
3143 ptr
->tmem_addr_conf
= (ptr
->tmem_addr_conf
&~0xff000000)|(_SHIFTL(0x65,24,8));
3146 void GX_InitTexObj(GXTexObj
*obj
,void *img_ptr
,u16 wd
,u16 ht
,u8 fmt
,u8 wrap_s
,u8 wrap_t
,u8 mipmap
)
3150 struct __gx_texobj
*ptr
= (struct __gx_texobj
*)obj
;
3154 memset(obj
,0,sizeof(GXTexObj
));
3156 ptr
->tex_filt
= (ptr
->tex_filt
&~0x03)|(wrap_s
&3);
3157 ptr
->tex_filt
= (ptr
->tex_filt
&~0x0c)|(_SHIFTL(wrap_t
,2,2));
3158 ptr
->tex_filt
= (ptr
->tex_filt
&~0x10)|0x10;
3161 ptr
->tex_flag
|= 0x01;
3162 if(fmt
==GX_TF_CI4
|| fmt
==GX_TF_CI8
|| fmt
==GX_TF_CI14
)
3163 ptr
->tex_filt
= (ptr
->tex_filt
&~0xe0)|0x00a0;
3165 ptr
->tex_filt
= (ptr
->tex_filt
&~0xe0)|0x00c0;
3167 ptr
->tex_filt
= (ptr
->tex_filt
&~0xE0)|0x0080;
3170 ptr
->tex_size
= (ptr
->tex_size
&~0x3ff)|((wd
-1)&0x3ff);
3171 ptr
->tex_size
= (ptr
->tex_size
&~0xFFC00)|(_SHIFTL((ht
-1),10,10));
3172 ptr
->tex_size
= (ptr
->tex_size
&~0xF00000)|(_SHIFTL(fmt
,20,4));
3173 ptr
->tex_maddr
= (ptr
->tex_maddr
&~0x01ffffff)|(_SHIFTR(MEM_VIRTUAL_TO_PHYSICAL(img_ptr
),5,24));
3180 ptr
->tex_tile_type
= 1;
3187 ptr
->tex_tile_type
= 2;
3195 ptr
->tex_tile_type
= 2;
3200 ptr
->tex_tile_type
= 3;
3205 ptr
->tex_tile_type
= 0;
3210 ptr
->tex_tile_type
= 2;
3214 nwd
= ((wd
+(1<<xshift
))-1)>>xshift
;
3215 nht
= ((ht
+(1<<yshift
))-1)>>yshift
;
3216 ptr
->tex_tile_cnt
= (nwd
*nht
)&0x7fff;
3218 ptr
->tex_flag
|= 0x0002;
3221 void GX_InitTexObjCI(GXTexObj
*obj
,void *img_ptr
,u16 wd
,u16 ht
,u8 fmt
,u8 wrap_s
,u8 wrap_t
,u8 mipmap
,u32 tlut_name
)
3223 struct __gx_texobj
*ptr
= (struct __gx_texobj
*)obj
;
3225 GX_InitTexObj(obj
,img_ptr
,wd
,ht
,fmt
,wrap_s
,wrap_t
,mipmap
);
3226 ptr
->tex_flag
&= ~0x02;
3227 ptr
->tex_tlut
= tlut_name
;
3230 void GX_InitTexObjLOD(GXTexObj
*obj
,u8 minfilt
,u8 magfilt
,f32 minlod
,f32 maxlod
,f32 lodbias
,u8 biasclamp
,u8 edgelod
,u8 maxaniso
)
3232 struct __gx_texobj
*ptr
= (struct __gx_texobj
*)obj
;
3233 static u8 GX2HWFiltConv
[] = {0x00,0x04,0x01,0x05,0x02,0x06,0x00,0x00};
3234 //static u8 HW2GXFiltConv[] = {0x00,0x02,0x04,0x00,0x01,0x03,0x05,0x00};
3236 if(lodbias
<-4.0f
) lodbias
= -4.0f
;
3237 else if(lodbias
==4.0f
) lodbias
= 3.99f
;
3239 ptr
->tex_filt
= (ptr
->tex_filt
&~0x1fe00)|(_SHIFTL(((u32
)(32.0f
*lodbias
)),9,8));
3240 ptr
->tex_filt
= (ptr
->tex_filt
&~0x10)|(_SHIFTL((magfilt
==GX_LINEAR
?1:0),4,1));
3241 ptr
->tex_filt
= (ptr
->tex_filt
&~0xe0)|(_SHIFTL(GX2HWFiltConv
[minfilt
],5,3));
3242 ptr
->tex_filt
= (ptr
->tex_filt
&~0x100)|(_SHIFTL(!(edgelod
&0xff),8,1));
3243 ptr
->tex_filt
= (ptr
->tex_filt
&~0x180000)|(_SHIFTL(maxaniso
,19,2));
3244 ptr
->tex_filt
= (ptr
->tex_filt
&~0x200000)|(_SHIFTL(biasclamp
,21,1));
3246 if(minlod
<0.0f
) minlod
= 0.0f
;
3247 else if(minlod
>10.0f
) minlod
= 10.0f
;
3249 if(maxlod
<0.0f
) maxlod
= 0.0f
;
3250 else if(maxlod
>10.0f
) maxlod
= 10.0f
;
3252 ptr
->tex_lod
= (ptr
->tex_lod
&~0xff)|(((u32
)(16.0f
*minlod
))&0xff);
3253 ptr
->tex_lod
= (ptr
->tex_lod
&~0xff00)|(_SHIFTL(((u32
)(16.0f
*maxlod
)),8,8));
3256 void GX_InitTexObjData(GXTexObj
*obj
,void *img_ptr
)
3258 struct __gx_texobj
*ptr
= (struct __gx_texobj
*)obj
;
3259 ptr
->tex_maddr
= (ptr
->tex_maddr
&~0x01ffffff)|(_SHIFTR(MEM_VIRTUAL_TO_PHYSICAL(img_ptr
),5,24));
3262 void GX_InitTexObjTlut(GXTexObj
*obj
,u32 tlut_name
)
3264 ((struct __gx_texobj
*)obj
)->tex_tlut
= tlut_name
;
3267 void GX_InitTexObjWrapMode(GXTexObj
*obj
,u8 wrap_s
,u8 wrap_t
)
3269 struct __gx_texobj
*ptr
= (struct __gx_texobj
*)obj
;
3271 ptr
->tex_filt
= (ptr
->tex_filt
&~0x03)|(wrap_s
&3);
3272 ptr
->tex_filt
= (ptr
->tex_filt
&~0x0c)|(_SHIFTL(wrap_t
,2,2));
3275 void GX_InitTexObjFilterMode(GXTexObj
*obj
,u8 minfilt
,u8 magfilt
)
3277 struct __gx_texobj
*ptr
= (struct __gx_texobj
*)obj
;
3278 static u8 GX2HWFiltConv
[] = {0x00,0x04,0x01,0x05,0x02,0x06,0x00,0x00};
3280 ptr
->tex_filt
= (ptr
->tex_filt
&~0x10)|(_SHIFTL((magfilt
==GX_LINEAR
?1:0),4,1));
3281 ptr
->tex_filt
= (ptr
->tex_filt
&~0xe0)|(_SHIFTL(GX2HWFiltConv
[minfilt
],5,3));
3284 void GX_InitTexObjMinLOD(GXTexObj
*obj
,f32 minlod
)
3286 struct __gx_texobj
*ptr
= (struct __gx_texobj
*)obj
;
3288 if(minlod
<0.0f
) minlod
= 0.0f
;
3289 else if(minlod
>10.0f
) minlod
= 10.0f
;
3291 ptr
->tex_lod
= (ptr
->tex_lod
&~0xff)|(((u32
)(16.0f
*minlod
))&0xff);
3294 void GX_InitTexObjMaxLOD(GXTexObj
*obj
,f32 maxlod
)
3296 struct __gx_texobj
*ptr
= (struct __gx_texobj
*)obj
;
3298 if(maxlod
<0.0f
) maxlod
= 0.0f
;
3299 else if(maxlod
>10.0f
) maxlod
= 10.0f
;
3301 ptr
->tex_lod
= (ptr
->tex_lod
&~0xff00)|(_SHIFTL(((u32
)(16.0f
*maxlod
)),8,8));
3304 void GX_InitTexObjLODBias(GXTexObj
*obj
,f32 lodbias
)
3306 struct __gx_texobj
*ptr
= (struct __gx_texobj
*)obj
;
3308 if(lodbias
<-4.0f
) lodbias
= -4.0f
;
3309 else if(lodbias
==4.0f
) lodbias
= 3.99f
;
3311 ptr
->tex_filt
= (ptr
->tex_filt
&~0x1fe00)|(_SHIFTL(((u32
)(32.0f
*lodbias
)),9,8));
3314 void GX_InitTexObjBiasClamp(GXTexObj
*obj
,u8 biasclamp
)
3316 struct __gx_texobj
*ptr
= (struct __gx_texobj
*)obj
;
3317 ptr
->tex_filt
= (ptr
->tex_filt
&~0x200000)|(_SHIFTL(biasclamp
,21,1));
3320 void GX_InitTexObjEdgeLOD(GXTexObj
*obj
,u8 edgelod
)
3322 struct __gx_texobj
*ptr
= (struct __gx_texobj
*)obj
;
3323 ptr
->tex_filt
= (ptr
->tex_filt
&~0x100)|(_SHIFTL(!(edgelod
&0xff),8,1));
3326 void GX_InitTexObjMaxAniso(GXTexObj
*obj
,u8 maxaniso
)
3328 struct __gx_texobj
*ptr
= (struct __gx_texobj
*)obj
;
3329 ptr
->tex_filt
= (ptr
->tex_filt
&~0x180000)|(_SHIFTL(maxaniso
,19,2));
3332 void GX_InitTexObjUserData(GXTexObj
*obj
,void *userdata
)
3334 struct __gx_texobj
*ptr
= (struct __gx_texobj
*)obj
;
3335 ptr
->usr_data
= (u32
)userdata
;
3338 void* GX_GetTexObjUserData(GXTexObj
*obj
)
3340 struct __gx_texobj
*ptr
= (struct __gx_texobj
*)obj
;
3341 return (void*)ptr
->usr_data
;
3344 void GX_InitTlutObj(GXTlutObj
*obj
,void *lut
,u8 fmt
,u16 entries
)
3346 struct __gx_tlutobj
*ptr
= (struct __gx_tlutobj
*)obj
;
3348 memset(obj
,0,sizeof(GXTlutObj
));
3350 ptr
->tlut_fmt
= _SHIFTL(fmt
,10,2);
3351 ptr
->tlut_maddr
= (ptr
->tlut_maddr
&~0x00ffffff)|(_SHIFTR(MEM_VIRTUAL_TO_PHYSICAL(lut
),5,24));
3352 ptr
->tlut_maddr
= (ptr
->tlut_maddr
&~0xff000000)|(_SHIFTL(0x64,24,8));
3353 ptr
->tlut_nentries
= entries
;
3356 void GX_LoadTexObj(GXTexObj
*obj
,u8 mapid
)
3358 GXTexRegion
*region
= NULL
;
3361 region
= regionCB(obj
,mapid
);
3363 GX_LoadTexObjPreloaded(obj
,region
,mapid
);
3366 void GX_LoadTexObjPreloaded(GXTexObj
*obj
,GXTexRegion
*region
,u8 mapid
)
3369 struct __gx_tlutregion
*tlut
= NULL
;
3370 struct __gx_texobj
*ptr
= (struct __gx_texobj
*)obj
;
3371 struct __gx_texregion
*reg
= (struct __gx_texregion
*)region
;
3373 ptr
->tex_filt
= (ptr
->tex_filt
&~0xff000000)|(_SHIFTL(_gxtexmode0ids
[mapid
],24,8));
3374 ptr
->tex_lod
= (ptr
->tex_lod
&~0xff000000)|(_SHIFTL(_gxtexmode1ids
[mapid
],24,8));
3375 ptr
->tex_size
= (ptr
->tex_size
&~0xff000000)|(_SHIFTL(_gxteximg0ids
[mapid
],24,8));
3376 ptr
->tex_maddr
= (ptr
->tex_maddr
&~0xff000000)|(_SHIFTL(_gxteximg3ids
[mapid
],24,8));
3378 reg
->tmem_even
= (reg
->tmem_even
&~0xff000000)|(_SHIFTL(_gxteximg1ids
[mapid
],24,8));
3379 reg
->tmem_odd
= (reg
->tmem_odd
&~0xff000000)|(_SHIFTL(_gxteximg2ids
[mapid
],24,8));
3381 GX_LOAD_BP_REG(ptr
->tex_filt
);
3382 GX_LOAD_BP_REG(ptr
->tex_lod
);
3383 GX_LOAD_BP_REG(ptr
->tex_size
);
3385 GX_LOAD_BP_REG(reg
->tmem_even
);
3386 GX_LOAD_BP_REG(reg
->tmem_odd
);
3388 GX_LOAD_BP_REG(ptr
->tex_maddr
);
3390 type
= ptr
->tex_flag
;
3393 tlut
= (struct __gx_tlutregion
*)tlut_regionCB(ptr
->tex_tlut
);
3394 tlut
->tmem_addr_base
= (tlut
->tmem_addr_base
&~0xff000000)|(_SHIFTL(_gxtextlutids
[mapid
],24,8));
3395 GX_LOAD_BP_REG(tlut
->tmem_addr_base
);
3398 __gx
->texMapSize
[mapid
] = ptr
->tex_size
;
3399 __gx
->texMapWrap
[mapid
] = ptr
->tex_filt
;
3401 __gx
->dirtyState
|= 0x0001;
3404 void GX_PreloadEntireTexture(GXTexObj
*obj
,GXTexRegion
*region
)
3413 struct __gx_texobj
*ptr
= (struct __gx_texobj
*)obj
;
3414 struct __gx_texregion
*reg
= (struct __gx_texregion
*)region
;
3416 regA
= (regA
&~0xff000000)|(_SHIFTL(0x60,24,8));
3417 regA
= (regA
&~0x00ffffff)|(ptr
->tex_maddr
&~0xff000000);
3419 regB
= (regB
&~0xff000000)|(_SHIFTL(0x61,24,8));
3420 regB
= (regB
&~0x00007fff)|(reg
->tmem_even
&0x00007fff);
3422 regC
= (regC
&~0xff000000)|(_SHIFTL(0x62,24,8));
3423 regC
= (regC
&~0x00007fff)|(reg
->tmem_odd
&0x00007fff);
3425 regD
= (regD
&~0xff000000)|(_SHIFTL(0x63,24,8));
3426 regD
= (regD
&~0x00007fff)|(ptr
->tex_tile_cnt
&0x00007fff);
3427 regD
= (regD
&~0x00018000)|(_SHIFTL(ptr
->tex_tile_type
,15,2));
3429 fmt
= _SHIFTR(ptr
->tex_size
,20,4);
3431 __GX_FlushTextureState();
3432 GX_LOAD_BP_REG(regA
);
3433 GX_LOAD_BP_REG(regB
);
3434 GX_LOAD_BP_REG(regC
);
3435 GX_LOAD_BP_REG(regD
);
3437 if(ptr
->tex_flag
&0x01) {
3438 wd
= (ptr
->tex_size
&0x3ff)+1;
3439 ht
= _SHIFTR(ptr
->tex_size
,10,10)+1;
3441 cnt
= (31 - (cntlzw(wd
)));
3443 cnt
= (31 - (cntlzw(ht
)));
3447 u32 tmem_even
,tmem_odd
,maddr
;
3448 u32 tile_cnt
= ptr
->tex_tile_cnt
;
3450 tmem_even
= (reg
->tmem_even
&0xffff);
3451 tmem_odd
= (reg
->tmem_odd
&0xffff);
3452 maddr
= (ptr
->tex_maddr
&~0xff000000);
3460 if(fmt
==GX_TF_RGBA8
) {
3461 tmem_even
+= tile_cnt
;
3462 tmem_odd
+= tile_cnt
;
3463 maddr
+= (tile_cnt
<<1);
3466 if(i
&1) tmem_odd
+= tile_cnt
;
3467 else tmem_even
+= tile_cnt
;
3479 switch(ptr
->tex_fmt
) {
3508 regA
= ((regA
&~0x00ffffff)|(maddr
&0x00ffffff));
3509 GX_LOAD_BP_REG(regA
);
3511 regB
= ((regB
&~0x00007fff)|(te
&0x00007fff));
3512 GX_LOAD_BP_REG(regB
);
3514 regC
= ((regC
&~0x00007fff)|(to
&0x00007fff));
3515 GX_LOAD_BP_REG(regC
);
3517 tile_cnt
= (((w
+(1<<xshift
))-1)>>xshift
)*(((h
+(1<<yshift
))-1)>>yshift
);
3518 regD
= ((regD
&~0x00007fff)|(tile_cnt
&0x00007fff));
3519 GX_LOAD_BP_REG(regD
);
3525 __GX_FlushTextureState();
3528 void GX_InvalidateTexAll()
3530 __GX_FlushTextureState();
3531 GX_LOAD_BP_REG(0x66001000);
3532 GX_LOAD_BP_REG(0x66001100);
3533 __GX_FlushTextureState();
3536 void GX_InvalidateTexRegion(GXTexRegion
*region
)
3539 s32 cw_e
,ch_e
,cw_o
,ch_o
;
3540 u32 size
,tmp
,regvalA
= 0,regvalB
= 0;
3541 struct __gx_texregion
*ptr
= (struct __gx_texregion
*)region
;
3543 cw_e
= (_SHIFTR(ptr
->tmem_even
,15,3))-1;
3544 ch_e
= (_SHIFTR(ptr
->tmem_even
,18,3))-1;
3546 cw_o
= (_SHIFTR(ptr
->tmem_odd
,15,3))-1;
3547 ch_o
= (_SHIFTR(ptr
->tmem_odd
,18,3))-1;
3549 if(cw_e
<0) cw_e
= 0;
3550 if(ch_e
<0) ch_e
= 0;
3551 if(cw_o
<0) cw_o
= 0;
3552 if(ch_o
<0) ch_o
= 0;
3554 ismipmap
= ptr
->ismipmap
;
3556 tmp
= size
= cw_e
+ch_e
;
3557 if(ismipmap
) size
= (tmp
+cw_o
+ch_o
)-2;
3558 regvalA
= _SHIFTR((ptr
->tmem_even
&0x7fff),6,9)|(_SHIFTL(size
,9,4))|(_SHIFTL(0x66,24,8));
3562 if(ismipmap
) size
+= (tmp
-2);
3563 regvalB
= _SHIFTR((ptr
->tmem_odd
&0x7fff),6,9)|(_SHIFTL(size
,9,4))|(_SHIFTL(0x66,24,8));
3565 __GX_FlushTextureState();
3566 GX_LOAD_BP_REG(regvalA
);
3567 if(cw_o
!=0) GX_LOAD_BP_REG(regvalB
);
3568 __GX_FlushTextureState();
3571 void GX_LoadTlut(GXTlutObj
*obj
,u32 tlut_name
)
3573 struct __gx_tlutregion
*region
= NULL
;
3574 struct __gx_tlutobj
*ptr
= (struct __gx_tlutobj
*)obj
;
3577 region
= (struct __gx_tlutregion
*)tlut_regionCB(tlut_name
);
3579 __GX_FlushTextureState();
3580 GX_LOAD_BP_REG(ptr
->tlut_maddr
);
3581 GX_LOAD_BP_REG(region
->tmem_addr_conf
);
3582 __GX_FlushTextureState();
3584 region
->tmem_addr_base
= (ptr
->tlut_fmt
&~0x3ff)|(region
->tmem_addr_conf
&0x3ff);
3585 region
->tlut_maddr
= ptr
->tlut_maddr
;
3586 region
->tlut_nentries
= ptr
->tlut_nentries
;
3589 void GX_SetTexCoordScaleManually(u8 texcoord
,u8 enable
,u16 ss
,u16 ts
)
3593 __gx
->texCoordManually
= (__gx
->texCoordManually
&~(_SHIFTL(1,texcoord
,1)))|(_SHIFTL(enable
,texcoord
,1));
3596 reg
= (texcoord
&0x7);
3597 __gx
->suSsize
[reg
] = (__gx
->suSsize
[reg
]&~0xffff)|((ss
-1)&0xffff);
3598 __gx
->suTsize
[reg
] = (__gx
->suTsize
[reg
]&~0xffff)|((ts
-1)&0xffff);
3600 GX_LOAD_BP_REG(__gx
->suSsize
[reg
]);
3601 GX_LOAD_BP_REG(__gx
->suTsize
[reg
]);
3604 void GX_SetTexCoordCylWrap(u8 texcoord
,u8 s_enable
,u8 t_enable
)
3608 reg
= (texcoord
&0x7);
3609 __gx
->suSsize
[reg
] = (__gx
->suSsize
[reg
]&~0x20000)|(_SHIFTL(s_enable
,17,1));
3610 __gx
->suTsize
[reg
] = (__gx
->suTsize
[reg
]&~0x20000)|(_SHIFTL(t_enable
,17,1));
3612 if(!(__gx
->texCoordManually
&(_SHIFTL(1,texcoord
,1)))) return;
3614 GX_LOAD_BP_REG(__gx
->suSsize
[reg
]);
3615 GX_LOAD_BP_REG(__gx
->suTsize
[reg
]);
3618 void GX_SetTexCoordBias(u8 texcoord
,u8 s_enable
,u8 t_enable
)
3622 reg
= (texcoord
&0x7);
3623 __gx
->suSsize
[reg
] = (__gx
->suSsize
[reg
]&~0x10000)|(_SHIFTL(s_enable
,16,1));
3624 __gx
->suTsize
[reg
] = (__gx
->suTsize
[reg
]&~0x10000)|(_SHIFTL(t_enable
,16,1));
3626 if(!(__gx
->texCoordManually
&(_SHIFTL(1,texcoord
,1)))) return;
3628 GX_LOAD_BP_REG(__gx
->suSsize
[reg
]);
3629 GX_LOAD_BP_REG(__gx
->suTsize
[reg
]);
3632 GXTexRegionCallback
GX_SetTexRegionCallback(GXTexRegionCallback cb
)
3635 GXTexRegionCallback ret
;
3637 _CPU_ISR_Disable(level
);
3640 _CPU_ISR_Restore(level
);
3645 GXTlutRegionCallback
GX_SetTlutRegionCallback(GXTlutRegionCallback cb
)
3648 GXTlutRegionCallback ret
;
3650 _CPU_ISR_Disable(level
);
3651 ret
= tlut_regionCB
;
3653 _CPU_ISR_Restore(level
);
3658 void GX_SetBlendMode(u8 type
,u8 src_fact
,u8 dst_fact
,u8 op
)
3660 __gx
->peCMode0
= (__gx
->peCMode0
&~0x1);
3661 if(type
==GX_BM_BLEND
|| type
==GX_BM_SUBTRACT
) __gx
->peCMode0
|= 0x1;
3663 __gx
->peCMode0
= (__gx
->peCMode0
&~0x800);
3664 if(type
==GX_BM_SUBTRACT
) __gx
->peCMode0
|= 0x800;
3666 __gx
->peCMode0
= (__gx
->peCMode0
&~0x2);
3667 if(type
==GX_BM_LOGIC
) __gx
->peCMode0
|= 0x2;
3669 __gx
->peCMode0
= (__gx
->peCMode0
&~0xF000)|(_SHIFTL(op
,12,4));
3670 __gx
->peCMode0
= (__gx
->peCMode0
&~0xE0)|(_SHIFTL(dst_fact
,5,3));
3671 __gx
->peCMode0
= (__gx
->peCMode0
&~0x700)|(_SHIFTL(src_fact
,8,3));
3673 GX_LOAD_BP_REG(__gx
->peCMode0
);
3676 void GX_ClearVtxDesc()
3679 __gx
->vcdClear
= ((__gx
->vcdClear
&~0x0600)|0x0200);
3680 __gx
->vcdLo
= __gx
->vcdHi
= 0;
3681 __gx
->dirtyState
|= 0x0008;
3684 void GX_SetLineWidth(u8 width
,u8 fmt
)
3686 __gx
->lpWidth
= (__gx
->lpWidth
&~0xff)|(width
&0xff);
3687 __gx
->lpWidth
= (__gx
->lpWidth
&~0x70000)|(_SHIFTL(fmt
,16,3));
3688 GX_LOAD_BP_REG(__gx
->lpWidth
);
3691 void GX_SetPointSize(u8 width
,u8 fmt
)
3693 __gx
->lpWidth
= (__gx
->lpWidth
&~0xFF00)|(_SHIFTL(width
,8,8));
3694 __gx
->lpWidth
= (__gx
->lpWidth
&~0x380000)|(_SHIFTL(fmt
,19,3));
3695 GX_LOAD_BP_REG(__gx
->lpWidth
);
3698 void GX_SetTevColor(u8 tev_regid
,GXColor color
)
3702 reg
= (_SHIFTL((0xe0+(tev_regid
<<1)),24,8)|(_SHIFTL(color
.a
,12,8))|(color
.r
&0xff));
3703 GX_LOAD_BP_REG(reg
);
3705 reg
= (_SHIFTL((0xe1+(tev_regid
<<1)),24,8)|(_SHIFTL(color
.g
,12,8))|(color
.b
&0xff));
3706 GX_LOAD_BP_REG(reg
);
3708 //this two calls should obviously flush the Write Gather Pipe.
3709 GX_LOAD_BP_REG(reg
);
3710 GX_LOAD_BP_REG(reg
);
3713 void GX_SetTevColorS10(u8 tev_regid
,GXColorS10 color
)
3717 reg
= (_SHIFTL((0xe0+(tev_regid
<<1)),24,8)|(_SHIFTL(color
.a
,12,11))|(color
.r
&0x7ff));
3718 GX_LOAD_BP_REG(reg
);
3720 reg
= (_SHIFTL((0xe1+(tev_regid
<<1)),24,8)|(_SHIFTL(color
.g
,12,11))|(color
.b
&0x7ff));
3721 GX_LOAD_BP_REG(reg
);
3723 //this two calls should obviously flush the Write Gather Pipe.
3724 GX_LOAD_BP_REG(reg
);
3725 GX_LOAD_BP_REG(reg
);
3728 void GX_SetTevKColor(u8 tev_kregid
,GXColor color
)
3732 reg
= (_SHIFTL((0xe0+(tev_kregid
<<1)),24,8)|(_SHIFTL(1,23,1))|(_SHIFTL(color
.a
,12,8))|(color
.r
&0xff));
3733 GX_LOAD_BP_REG(reg
);
3735 reg
= (_SHIFTL((0xe1+(tev_kregid
<<1)),24,8)|(_SHIFTL(1,23,1))|(_SHIFTL(color
.g
,12,8))|(color
.b
&0xff));
3736 GX_LOAD_BP_REG(reg
);
3738 //this two calls should obviously flush the Write Gather Pipe.
3739 GX_LOAD_BP_REG(reg
);
3740 GX_LOAD_BP_REG(reg
);
3743 void GX_SetTevKColorS10(u8 tev_kregid
,GXColorS10 color
)
3747 reg
= (_SHIFTL((0xe0+(tev_kregid
<<1)),24,8)|(_SHIFTL(1,23,1))|(_SHIFTL(color
.a
,12,11))|(color
.r
&0x7ff));
3748 GX_LOAD_BP_REG(reg
);
3750 reg
= (_SHIFTL((0xe1+(tev_kregid
<<1)),24,8)|(_SHIFTL(1,23,1))|(_SHIFTL(color
.g
,12,11))|(color
.b
&0x7ff));
3751 GX_LOAD_BP_REG(reg
);
3753 //this two calls should obviously flush the Write Gather Pipe.
3754 GX_LOAD_BP_REG(reg
);
3755 GX_LOAD_BP_REG(reg
);
3758 void GX_SetTevOp(u8 tevstage
,u8 mode
)
3760 u8 defcolor
= GX_CC_RASC
;
3761 u8 defalpha
= GX_CA_RASA
;
3763 if(tevstage
!=GX_TEVSTAGE0
) {
3764 defcolor
= GX_CC_CPREV
;
3765 defalpha
= GX_CA_APREV
;
3770 GX_SetTevColorIn(tevstage
,GX_CC_ZERO
,GX_CC_TEXC
,defcolor
,GX_CC_ZERO
);
3771 GX_SetTevAlphaIn(tevstage
,GX_CA_ZERO
,GX_CA_TEXA
,defalpha
,GX_CA_ZERO
);
3774 GX_SetTevColorIn(tevstage
,defcolor
,GX_CC_TEXC
,GX_CC_TEXA
,GX_CC_ZERO
);
3775 GX_SetTevAlphaIn(tevstage
,GX_CA_ZERO
,GX_CA_ZERO
,GX_CA_ZERO
,defalpha
);
3778 GX_SetTevColorIn(tevstage
,defcolor
,GX_CC_ONE
,GX_CC_TEXC
,GX_CC_ZERO
);
3779 GX_SetTevAlphaIn(tevstage
,GX_CA_ZERO
,GX_CA_TEXA
,defalpha
,GX_CA_RASA
);
3782 GX_SetTevColorIn(tevstage
,GX_CC_ZERO
,GX_CC_ZERO
,GX_CC_ZERO
,GX_CC_TEXC
);
3783 GX_SetTevAlphaIn(tevstage
,GX_CA_ZERO
,GX_CA_ZERO
,GX_CA_ZERO
,GX_CA_TEXA
);
3786 GX_SetTevColorIn(tevstage
,GX_CC_ZERO
,GX_CC_ZERO
,GX_CC_ZERO
,defcolor
);
3787 GX_SetTevAlphaIn(tevstage
,GX_CC_A2
,GX_CC_A2
,GX_CC_A2
,defalpha
);
3790 GX_SetTevColorOp(tevstage
,GX_TEV_ADD
,GX_TB_ZERO
,GX_CS_SCALE_1
,GX_TRUE
,GX_TEVPREV
);
3791 GX_SetTevAlphaOp(tevstage
,GX_TEV_ADD
,GX_TB_ZERO
,GX_CS_SCALE_1
,GX_TRUE
,GX_TEVPREV
);
3794 void GX_SetTevColorIn(u8 tevstage
,u8 a
,u8 b
,u8 c
,u8 d
)
3796 u32 reg
= (tevstage
&0xf);
3797 __gx
->tevColorEnv
[reg
] = (__gx
->tevColorEnv
[reg
]&~0xF000)|(_SHIFTL(a
,12,4));
3798 __gx
->tevColorEnv
[reg
] = (__gx
->tevColorEnv
[reg
]&~0xF00)|(_SHIFTL(b
,8,4));
3799 __gx
->tevColorEnv
[reg
] = (__gx
->tevColorEnv
[reg
]&~0xF0)|(_SHIFTL(c
,4,4));
3800 __gx
->tevColorEnv
[reg
] = (__gx
->tevColorEnv
[reg
]&~0xf)|(d
&0xf);
3802 GX_LOAD_BP_REG(__gx
->tevColorEnv
[reg
]);
3805 void GX_SetTevAlphaIn(u8 tevstage
,u8 a
,u8 b
,u8 c
,u8 d
)
3807 u32 reg
= (tevstage
&0xf);
3808 __gx
->tevAlphaEnv
[reg
] = (__gx
->tevAlphaEnv
[reg
]&~0xE000)|(_SHIFTL(a
,13,3));
3809 __gx
->tevAlphaEnv
[reg
] = (__gx
->tevAlphaEnv
[reg
]&~0x1C00)|(_SHIFTL(b
,10,3));
3810 __gx
->tevAlphaEnv
[reg
] = (__gx
->tevAlphaEnv
[reg
]&~0x380)|(_SHIFTL(c
,7,3));
3811 __gx
->tevAlphaEnv
[reg
] = (__gx
->tevAlphaEnv
[reg
]&~0x70)|(_SHIFTL(d
,4,3));
3813 GX_LOAD_BP_REG(__gx
->tevAlphaEnv
[reg
]);
3816 void GX_SetTevColorOp(u8 tevstage
,u8 tevop
,u8 tevbias
,u8 tevscale
,u8 clamp
,u8 tevregid
)
3818 /* set tev op add/sub*/
3819 u32 reg
= (tevstage
&0xf);
3820 __gx
->tevColorEnv
[reg
] = (__gx
->tevColorEnv
[reg
]&~0x40000)|(_SHIFTL(tevop
,18,1));
3821 if(tevop
<=GX_TEV_SUB
) {
3822 __gx
->tevColorEnv
[reg
] = (__gx
->tevColorEnv
[reg
]&~0x300000)|(_SHIFTL(tevscale
,20,2));
3823 __gx
->tevColorEnv
[reg
] = (__gx
->tevColorEnv
[reg
]&~0x30000)|(_SHIFTL(tevbias
,16,2));
3825 __gx
->tevColorEnv
[reg
] = (__gx
->tevColorEnv
[reg
]&~0x300000)|((_SHIFTL(tevop
,19,4))&0x300000);
3826 __gx
->tevColorEnv
[reg
] = (__gx
->tevColorEnv
[reg
]&~0x30000)|0x30000;
3828 __gx
->tevColorEnv
[reg
] = (__gx
->tevColorEnv
[reg
]&~0x80000)|(_SHIFTL(clamp
,19,1));
3829 __gx
->tevColorEnv
[reg
] = (__gx
->tevColorEnv
[reg
]&~0xC00000)|(_SHIFTL(tevregid
,22,2));
3831 GX_LOAD_BP_REG(__gx
->tevColorEnv
[reg
]);
3834 void GX_SetTevAlphaOp(u8 tevstage
,u8 tevop
,u8 tevbias
,u8 tevscale
,u8 clamp
,u8 tevregid
)
3836 /* set tev op add/sub*/
3837 u32 reg
= (tevstage
&0xf);
3838 __gx
->tevAlphaEnv
[reg
] = (__gx
->tevAlphaEnv
[reg
]&~0x40000)|(_SHIFTL(tevop
,18,1));
3839 if(tevop
<=GX_TEV_SUB
) {
3840 __gx
->tevAlphaEnv
[reg
] = (__gx
->tevAlphaEnv
[reg
]&~0x300000)|(_SHIFTL(tevscale
,20,2));
3841 __gx
->tevAlphaEnv
[reg
] = (__gx
->tevAlphaEnv
[reg
]&~0x30000)|(_SHIFTL(tevbias
,16,2));
3843 __gx
->tevAlphaEnv
[reg
] = (__gx
->tevAlphaEnv
[reg
]&~0x300000)|((_SHIFTL(tevop
,19,4))&0x300000);
3844 __gx
->tevAlphaEnv
[reg
] = (__gx
->tevAlphaEnv
[reg
]&~0x30000)|0x30000;
3846 __gx
->tevAlphaEnv
[reg
] = (__gx
->tevAlphaEnv
[reg
]&~0x80000)|(_SHIFTL(clamp
,19,1));
3847 __gx
->tevAlphaEnv
[reg
] = (__gx
->tevAlphaEnv
[reg
]&~0xC00000)|(_SHIFTL(tevregid
,22,2));
3849 GX_LOAD_BP_REG(__gx
->tevAlphaEnv
[reg
]);
3852 void GX_SetCullMode(u8 mode
)
3854 static u8 cm2hw
[] = { 0, 2, 1, 3 };
3856 __gx
->genMode
= (__gx
->genMode
&~0xC000)|(_SHIFTL(cm2hw
[mode
],14,2));
3857 __gx
->dirtyState
|= 0x0004;
3860 void GX_SetCoPlanar(u8 enable
)
3862 __gx
->genMode
= (__gx
->genMode
&~0x80000)|(_SHIFTL(enable
,19,1));
3863 GX_LOAD_BP_REG(0xFE080000);
3864 GX_LOAD_BP_REG(__gx
->genMode
);
3867 void GX_EnableTexOffsets(u8 coord
,u8 line_enable
,u8 point_enable
)
3869 u32 reg
= (coord
&0x7);
3870 __gx
->suSsize
[reg
] = (__gx
->suSsize
[reg
]&~0x40000)|(_SHIFTL(line_enable
,18,1));
3871 __gx
->suSsize
[reg
] = (__gx
->suSsize
[reg
]&~0x80000)|(_SHIFTL(point_enable
,19,1));
3872 GX_LOAD_BP_REG(__gx
->suSsize
[reg
]);
3875 void GX_SetClipMode(u8 mode
)
3877 GX_LOAD_XF_REG(0x1005,(mode
&1));
3880 void GX_SetScissor(u32 xOrigin
,u32 yOrigin
,u32 wd
,u32 ht
)
3882 u32 xo
= xOrigin
+0x156;
3883 u32 yo
= yOrigin
+0x156;
3884 u32 nwd
= xo
+(wd
-1);
3885 u32 nht
= yo
+(ht
-1);
3887 __gx
->sciTLcorner
= (__gx
->sciTLcorner
&~0x7ff)|(yo
&0x7ff);
3888 __gx
->sciTLcorner
= (__gx
->sciTLcorner
&~0x7FF000)|(_SHIFTL(xo
,12,11));
3890 __gx
->sciBRcorner
= (__gx
->sciBRcorner
&~0x7ff)|(nht
&0xfff);
3891 __gx
->sciBRcorner
= (__gx
->sciBRcorner
&~0x7FF000)|(_SHIFTL(nwd
,12,11));
3893 GX_LOAD_BP_REG(__gx
->sciTLcorner
);
3894 GX_LOAD_BP_REG(__gx
->sciBRcorner
);
3897 void GX_SetScissorBoxOffset(s32 xoffset
,s32 yoffset
)
3899 s32 xoff
= _SHIFTR((xoffset
+0x156),1,24);
3900 s32 yoff
= _SHIFTR((yoffset
+0x156),1,24);
3902 GX_LOAD_BP_REG((0x59000000|(_SHIFTL(yoff
,10,10))|(xoff
&0x3ff)));
3905 void GX_SetNumChans(u8 num
)
3907 __gx
->genMode
= (__gx
->genMode
&~0x70)|(_SHIFTL(num
,4,3));
3908 __gx
->dirtyState
|= 0x01000004;
3911 void GX_SetTevOrder(u8 tevstage
,u8 texcoord
,u32 texmap
,u8 color
)
3915 u32 reg
= 3+(_SHIFTR(tevstage
,1,3));
3917 __gx
->tevTexMap
[(tevstage
&0xf)] = texmap
;
3919 texm
= (texmap
&~0x100);
3920 if(texm
>=GX_MAX_TEXMAP
) texm
= 0;
3921 if(texcoord
>=GX_MAXCOORD
) {
3923 __gx
->tevTexCoordEnable
&= ~(_SHIFTL(1,tevstage
,1));
3926 __gx
->tevTexCoordEnable
|= (_SHIFTL(1,tevstage
,1));
3930 __gx
->tevRasOrder
[reg
] = (__gx
->tevRasOrder
[reg
]&~0x7000)|(_SHIFTL(texm
,12,3));
3931 __gx
->tevRasOrder
[reg
] = (__gx
->tevRasOrder
[reg
]&~0x38000)|(_SHIFTL(texc
,15,3));
3933 colid
= GX_ALPHA_BUMP
;
3934 if(color
!=GX_COLORNULL
) colid
= _gxtevcolid
[color
];
3935 __gx
->tevRasOrder
[reg
] = (__gx
->tevRasOrder
[reg
]&~0x380000)|(_SHIFTL(colid
,19,3));
3938 if(texmap
==GX_TEXMAP_NULL
|| texmap
&0x100) tmp
= 0;
3939 __gx
->tevRasOrder
[reg
] = (__gx
->tevRasOrder
[reg
]&~0x40000)|(_SHIFTL(tmp
,18,1));
3941 __gx
->tevRasOrder
[reg
] = (__gx
->tevRasOrder
[reg
]&~0x7)|(texm
&0x7);
3942 __gx
->tevRasOrder
[reg
] = (__gx
->tevRasOrder
[reg
]&~0x38)|(_SHIFTL(texc
,3,3));
3944 colid
= GX_ALPHA_BUMP
;
3945 if(color
!=GX_COLORNULL
) colid
= _gxtevcolid
[color
];
3946 __gx
->tevRasOrder
[reg
] = (__gx
->tevRasOrder
[reg
]&~0x380)|(_SHIFTL(colid
,7,3));
3949 if(texmap
==GX_TEXMAP_NULL
|| texmap
&0x100) tmp
= 0;
3950 __gx
->tevRasOrder
[reg
] = (__gx
->tevRasOrder
[reg
]&~0x40)|(_SHIFTL(tmp
,6,1));
3952 GX_LOAD_BP_REG(__gx
->tevRasOrder
[reg
]);
3953 __gx
->dirtyState
|= 0x0001;
3956 void GX_SetNumTevStages(u8 num
)
3958 __gx
->genMode
= (__gx
->genMode
&~0x3C00)|(_SHIFTL((num
-1),10,4));
3959 __gx
->dirtyState
|= 0x0004;
3962 void GX_SetAlphaCompare(u8 comp0
,u8 ref0
,u8 aop
,u8 comp1
,u8 ref1
)
3965 val
= (_SHIFTL(aop
,22,2))|(_SHIFTL(comp1
,19,3))|(_SHIFTL(comp0
,16,3))|(_SHIFTL(ref1
,8,8))|(ref0
&0xff);
3966 GX_LOAD_BP_REG(0xf3000000|val
);
3969 void GX_SetTevKColorSel(u8 tevstage
,u8 sel
)
3971 u32 reg
= (_SHIFTR(tevstage
,1,3));
3974 __gx
->tevSwapModeTable
[reg
] = (__gx
->tevSwapModeTable
[reg
]&~0x7C000)|(_SHIFTL(sel
,14,5));
3976 __gx
->tevSwapModeTable
[reg
] = (__gx
->tevSwapModeTable
[reg
]&~0x1F0)|(_SHIFTL(sel
,4,5));
3977 GX_LOAD_BP_REG(__gx
->tevSwapModeTable
[reg
]);
3980 void GX_SetTevKAlphaSel(u8 tevstage
,u8 sel
)
3982 u32 reg
= (_SHIFTR(tevstage
,1,3));
3985 __gx
->tevSwapModeTable
[reg
] = (__gx
->tevSwapModeTable
[reg
]&~0xF80000)|(_SHIFTL(sel
,19,5));
3987 __gx
->tevSwapModeTable
[reg
] = (__gx
->tevSwapModeTable
[reg
]&~0x3E00)|(_SHIFTL(sel
,9,5));
3988 GX_LOAD_BP_REG(__gx
->tevSwapModeTable
[reg
]);
3991 void GX_SetTevSwapMode(u8 tevstage
,u8 ras_sel
,u8 tex_sel
)
3993 u32 reg
= (tevstage
&0xf);
3994 __gx
->tevAlphaEnv
[reg
] = (__gx
->tevAlphaEnv
[reg
]&~0x3)|(ras_sel
&0x3);
3995 __gx
->tevAlphaEnv
[reg
] = (__gx
->tevAlphaEnv
[reg
]&~0xC)|(_SHIFTL(tex_sel
,2,2));
3996 GX_LOAD_BP_REG(__gx
->tevAlphaEnv
[reg
]);
3999 void GX_SetTevSwapModeTable(u8 swapid
,u8 r
,u8 g
,u8 b
,u8 a
)
4001 u32 regA
= 0+(_SHIFTL(swapid
,1,3));
4002 u32 regB
= 1+(_SHIFTL(swapid
,1,3));
4004 __gx
->tevSwapModeTable
[regA
] = (__gx
->tevSwapModeTable
[regA
]&~0x3)|(r
&0x3);
4005 __gx
->tevSwapModeTable
[regA
] = (__gx
->tevSwapModeTable
[regA
]&~0xC)|(_SHIFTL(g
,2,2));
4006 GX_LOAD_BP_REG(__gx
->tevSwapModeTable
[regA
]);
4008 __gx
->tevSwapModeTable
[regB
] = (__gx
->tevSwapModeTable
[regB
]&~0x3)|(b
&0x3);
4009 __gx
->tevSwapModeTable
[regB
] = (__gx
->tevSwapModeTable
[regB
]&~0xC)|(_SHIFTL(a
,2,2));
4010 GX_LOAD_BP_REG(__gx
->tevSwapModeTable
[regB
]);
4013 void GX_SetTevIndirect(u8 tevstage
,u8 indtexid
,u8 format
,u8 bias
,u8 mtxid
,u8 wrap_s
,u8 wrap_t
,u8 addprev
,u8 utclod
,u8 a
)
4015 u32 val
= (0x10000000|(_SHIFTL(tevstage
,24,4)))|(indtexid
&3)|(_SHIFTL(format
,2,2))|(_SHIFTL(bias
,4,3))|(_SHIFTL(a
,7,2))|(_SHIFTL(mtxid
,9,4))|(_SHIFTL(wrap_s
,13,3))|(_SHIFTL(wrap_t
,16,3))|(_SHIFTL(utclod
,19,1))|(_SHIFTL(addprev
,20,1));
4016 GX_LOAD_BP_REG(val
);
4019 void GX_SetTevDirect(u8 tevstage
)
4021 GX_SetTevIndirect(tevstage
,GX_INDTEXSTAGE0
,GX_ITF_8
,GX_ITB_NONE
,GX_ITM_OFF
,GX_ITW_OFF
,GX_ITW_OFF
,GX_FALSE
,GX_FALSE
,GX_ITBA_OFF
);
4024 void GX_SetNumIndStages(u8 nstages
)
4026 __gx
->genMode
= (__gx
->genMode
&~0x70000)|(_SHIFTL(nstages
,16,3));
4027 __gx
->dirtyState
|= 0x0006;
4030 void GX_SetIndTexMatrix(u8 indtexmtx
,f32 offset_mtx
[2][3],s8 scale_exp
)
4035 if(indtexmtx
>0x00 && indtexmtx
<0x04) indtexmtx
-= 0x01;
4036 else if(indtexmtx
>0x04 && indtexmtx
<0x08) indtexmtx
-= 0x05;
4037 else if(indtexmtx
>0x08 && indtexmtx
<0x0C) indtexmtx
-= 0x09;
4038 else indtexmtx
= 0x00;
4041 idx
= ((indtexmtx
<<2)-indtexmtx
);
4043 ma
= (u32
)(offset_mtx
[0][0]*1024.0F
);
4044 mb
= (u32
)(offset_mtx
[1][0]*1024.0F
);
4045 val
= (_SHIFTL((0x06+idx
),24,8)|_SHIFTL(s
,22,2)|_SHIFTL(mb
,11,11)|_SHIFTL(ma
,0,11));
4046 GX_LOAD_BP_REG(val
);
4048 ma
= (u32
)(offset_mtx
[0][1]*1024.0F
);
4049 mb
= (u32
)(offset_mtx
[1][1]*1024.0F
);
4050 val
= (_SHIFTL((0x07+idx
),24,8)|_SHIFTL((s
>>2),22,2)|_SHIFTL(mb
,11,11)|_SHIFTL(ma
,0,11));
4051 GX_LOAD_BP_REG(val
);
4053 ma
= (u32
)(offset_mtx
[0][2]*1024.0F
);
4054 mb
= (u32
)(offset_mtx
[1][2]*1024.0F
);
4055 val
= (_SHIFTL((0x08+idx
),24,8)|_SHIFTL((s
>>4),22,2)|_SHIFTL(mb
,11,11)|_SHIFTL(ma
,0,11));
4056 GX_LOAD_BP_REG(val
);
4059 void GX_SetTevIndBumpST(u8 tevstage
,u8 indstage
,u8 mtx_sel
)
4082 GX_SetTevIndirect((tevstage
+0),indstage
,GX_ITF_8
,GX_ITB_ST
,sel_s
,GX_ITW_0
,GX_ITW_0
,GX_FALSE
,GX_FALSE
,GX_ITBA_OFF
);
4083 GX_SetTevIndirect((tevstage
+1),indstage
,GX_ITF_8
,GX_ITB_ST
,sel_t
,GX_ITW_0
,GX_ITW_0
,GX_TRUE
,GX_FALSE
,GX_ITBA_OFF
);
4084 GX_SetTevIndirect((tevstage
+2),indstage
,GX_ITF_8
,GX_ITB_NONE
,GX_ITM_OFF
,GX_ITW_OFF
,GX_ITW_OFF
,GX_TRUE
,GX_FALSE
,GX_ITBA_OFF
);
4087 void GX_SetTevIndBumpXYZ(u8 tevstage
,u8 indstage
,u8 mtx_sel
)
4089 GX_SetTevIndirect(tevstage
,indstage
,GX_ITF_8
,GX_ITB_STU
,mtx_sel
,GX_ITW_OFF
,GX_ITW_OFF
,GX_FALSE
,GX_FALSE
,GX_ITBA_OFF
);
4092 void GX_SetTevIndRepeat(u8 tevstage
)
4094 GX_SetTevIndirect(tevstage
,GX_INDTEXSTAGE0
,GX_ITF_8
,GX_ITB_NONE
,GX_ITM_OFF
,GX_ITW_0
,GX_ITW_0
,GX_TRUE
,GX_FALSE
,GX_ITBA_OFF
);
4097 void GX_SetIndTexCoordScale(u8 indtexid
,u8 scale_s
,u8 scale_t
)
4100 case GX_INDTEXSTAGE0
:
4101 __gx
->tevRasOrder
[0] = (__gx
->tevRasOrder
[0]&~0x0f)|(scale_s
&0x0f);
4102 __gx
->tevRasOrder
[0] = (__gx
->tevRasOrder
[0]&~0xF0)|(_SHIFTL(scale_t
,4,4));
4103 GX_LOAD_BP_REG(__gx
->tevRasOrder
[0]);
4105 case GX_INDTEXSTAGE1
:
4106 __gx
->tevRasOrder
[0] = (__gx
->tevRasOrder
[0]&~0xF00)|(_SHIFTL(scale_s
,8,4));
4107 __gx
->tevRasOrder
[0] = (__gx
->tevRasOrder
[0]&~0xF000)|(_SHIFTL(scale_t
,12,4));
4108 GX_LOAD_BP_REG(__gx
->tevRasOrder
[0]);
4110 case GX_INDTEXSTAGE2
:
4111 __gx
->tevRasOrder
[1] = (__gx
->tevRasOrder
[1]&~0x0f)|(scale_s
&0x0f);
4112 __gx
->tevRasOrder
[1] = (__gx
->tevRasOrder
[1]&~0xF0)|(_SHIFTL(scale_t
,4,4));
4113 GX_LOAD_BP_REG(__gx
->tevRasOrder
[1]);
4115 case GX_INDTEXSTAGE3
:
4116 __gx
->tevRasOrder
[1] = (__gx
->tevRasOrder
[1]&~0xF00)|(_SHIFTL(scale_s
,8,4));
4117 __gx
->tevRasOrder
[1] = (__gx
->tevRasOrder
[1]&~0xF000)|(_SHIFTL(scale_t
,12,4));
4118 GX_LOAD_BP_REG(__gx
->tevRasOrder
[1]);
4123 void GX_SetTevIndTile(u8 tevstage
,u8 indtexid
,u16 tilesize_x
,u16 tilesize_y
,u16 tilespacing_x
,u16 tilespacing_y
,u8 indtexfmt
,u8 indtexmtx
,u8 bias_sel
,u8 alpha_sel
)
4126 f32 offset_mtx
[2][3];
4127 f64 fdspace_x
,fdspace_y
;
4128 u32 fbuf_x
[2] = { 0x43300000,tilespacing_x
};
4129 u32 fbuf_y
[2] = { 0x43300000,tilespacing_y
};
4131 wrap_s
= GX_ITW_OFF
;
4132 if(tilesize_x
==0x0010) wrap_s
= GX_ITW_16
;
4133 else if(tilesize_x
==0x0020) wrap_s
= GX_ITW_32
;
4134 else if(tilesize_x
==0x0040) wrap_s
= GX_ITW_64
;
4135 else if(tilesize_x
==0x0080) wrap_s
= GX_ITW_128
;
4136 else if(tilesize_x
==0x0100) wrap_s
= GX_ITW_256
;
4138 wrap_t
= GX_ITW_OFF
;
4139 if(tilesize_y
==0x0010) wrap_t
= GX_ITW_16
;
4140 else if(tilesize_y
==0x0020) wrap_t
= GX_ITW_32
;
4141 else if(tilesize_y
==0x0040) wrap_t
= GX_ITW_64
;
4142 else if(tilesize_y
==0x0080) wrap_t
= GX_ITW_128
;
4143 else if(tilesize_y
==0x0100) wrap_t
= GX_ITW_256
;
4145 fdspace_x
= *(f64
*)((void*)fbuf_x
);
4146 fdspace_y
= *(f64
*)((void*)fbuf_y
);
4148 offset_mtx
[0][0] = (f32
)((fdspace_x
- 4503599627370496.0F
)*0.00097656250F
);
4149 offset_mtx
[0][1] = 0.0F
;
4150 offset_mtx
[0][2] = 0.0F
;
4151 offset_mtx
[1][0] = 0.0F
;
4152 offset_mtx
[1][1] = (f32
)((fdspace_y
- 4503599627370496.0F
)*0.00097656250F
);
4153 offset_mtx
[1][2] = 0.0F
;
4155 GX_SetIndTexMatrix(indtexmtx
,offset_mtx
,10);
4156 GX_SetTevIndirect(tevstage
,indtexid
,indtexfmt
,bias_sel
,indtexmtx
,wrap_s
,wrap_t
,GX_FALSE
,GX_TRUE
,alpha_sel
);
4159 void GX_SetFog(u8 type
,f32 startz
,f32 endz
,f32 nearz
,f32 farz
,GXColor col
)
4161 f32 A
, B
, B_mant
, C
, A_f
;
4162 u32 b_expn
, b_m
, a_hex
, c_hex
,val
,proj
= 0;
4163 union ieee32
{ f32 f
; u32 i
; } v
;
4165 proj
= _SHIFTR(type
,3,1);
4167 // Calculate constants a, b, and c (TEV HW requirements).
4168 if(proj
) { // Orthographic Fog Type
4169 if((farz
==nearz
) || (endz
==startz
)) {
4170 // take care of the odd-ball case.
4174 A
= 1.0f
/(endz
-startz
);
4175 A_f
= (farz
-nearz
) * A
;
4176 C
= (startz
-nearz
) * A
;
4181 } else { // Perspective Fog Type
4182 // Calculate constants a, b, and c (TEV HW requirements).
4183 if((farz
==nearz
) || (endz
==startz
)) {
4184 // take care of the odd-ball case.
4189 A
= (farz
*nearz
)/((farz
-nearz
)*(endz
-startz
));
4190 B
= farz
/(farz
-nearz
);
4191 C
= startz
/(endz
-startz
);
4196 while(B_mant
>1.0f
) {
4201 while((B_mant
>0.0f
) && (B_mant
<0.5f
)) {
4206 A_f
= A
/(1<<(b_expn
));
4207 b_m
= (u32
)(B_mant
* 8388638.0f
);
4215 val
= 0xee000000|(_SHIFTR(a_hex
,12,20));
4216 GX_LOAD_BP_REG(val
);
4218 val
= 0xef000000|(b_m
&0x00ffffff);
4219 GX_LOAD_BP_REG(val
);
4221 val
= 0xf0000000|(b_expn
&0x1f);
4222 GX_LOAD_BP_REG(val
);
4224 val
= 0xf1000000|(_SHIFTL(type
,21,3))|(_SHIFTL(proj
,20,1))|(_SHIFTR(c_hex
,12,20));
4225 GX_LOAD_BP_REG(val
);
4227 val
= 0xf2000000|(_SHIFTL(col
.r
,16,8))|(_SHIFTL(col
.g
,8,8))|(col
.b
&0xff);
4228 GX_LOAD_BP_REG(val
);
4231 void GX_InitFogAdjTable(GXFogAdjTbl
*table
,u16 width
,f32 projmtx
[4][4])
4234 f32 val0
,val1
,val2
,val4
,val5
,val6
;
4236 if(projmtx
[3][3]==0.0f
) {
4237 val0
= projmtx
[2][3]/(projmtx
[2][2] - 1.0f
);
4238 val1
= val0
/projmtx
[0][0];
4240 val1
= 1.0f
/projmtx
[0][0];
4241 val0
= val1
*1.7320499f
;
4245 val4
= 2.0f
/(f32
)width
;
4252 val6
= sqrtf(val5
+ 1.0f
);
4253 val7
= (u32
)(val6
*256.0f
);
4254 table
->r
[i
] = (val7
&0x0fff);
4258 void GX_SetFogRangeAdj(u8 enable
,u16 center
,GXFogAdjTbl
*table
)
4263 val
= 0xe9000000|(_SHIFTL(table
->r
[1],12,12))|(table
->r
[0]&0x0fff);
4264 GX_LOAD_BP_REG(val
);
4266 val
= 0xea000000|(_SHIFTL(table
->r
[3],12,12))|(table
->r
[2]&0x0fff);
4267 GX_LOAD_BP_REG(val
);
4269 val
= 0xeb000000|(_SHIFTL(table
->r
[5],12,12))|(table
->r
[4]&0x0fff);
4270 GX_LOAD_BP_REG(val
);
4272 val
= 0xec000000|(_SHIFTL(table
->r
[7],12,12))|(table
->r
[6]&0x0fff);
4273 GX_LOAD_BP_REG(val
);
4275 val
= 0xed000000|(_SHIFTL(table
->r
[9],12,12))|(table
->r
[8]&0x0fff);
4276 GX_LOAD_BP_REG(val
);
4278 val
= 0xe8000000|(_SHIFTL(enable
,10,1))|((center
+ 342)&0x03ff);
4279 GX_LOAD_BP_REG(val
);
4282 void GX_SetFogColor(GXColor color
)
4284 GX_LOAD_BP_REG(0xf2000000|(_SHIFTL(color
.r
,16,8)|_SHIFTL(color
.g
,8,8)|(color
.b
&0xff)));
4287 void GX_SetColorUpdate(u8 enable
)
4289 __gx
->peCMode0
= (__gx
->peCMode0
&~0x8)|(_SHIFTL(enable
,3,1));
4290 GX_LOAD_BP_REG(__gx
->peCMode0
);
4293 void GX_SetAlphaUpdate(u8 enable
)
4295 __gx
->peCMode0
= (__gx
->peCMode0
&~0x10)|(_SHIFTL(enable
,4,1));
4296 GX_LOAD_BP_REG(__gx
->peCMode0
);
4299 void GX_SetZCompLoc(u8 before_tex
)
4301 __gx
->peCntrl
= (__gx
->peCntrl
&~0x40)|(_SHIFTL(before_tex
,6,1));
4302 GX_LOAD_BP_REG(__gx
->peCntrl
);
4305 void GX_SetPixelFmt(u8 pix_fmt
,u8 z_fmt
)
4308 u32 realfmt
[8] = {0,1,2,3,4,4,4,5};
4310 __gx
->peCntrl
= (__gx
->peCntrl
&~0x7)|(realfmt
[pix_fmt
]&0x7);
4311 __gx
->peCntrl
= (__gx
->peCntrl
&~0x38)|(_SHIFTL(z_fmt
,3,3));
4312 GX_LOAD_BP_REG(__gx
->peCntrl
);
4313 __gx
->dirtyState
|= 0x0004;
4315 if(pix_fmt
==GX_PF_RGB565_Z16
) ms_en
= 1;
4316 __gx
->genMode
= (__gx
->genMode
&~0x200)|(_SHIFTL(ms_en
,9,1));
4318 if(realfmt
[pix_fmt
]==GX_PF_Y8
) {
4319 pix_fmt
-= GX_PF_Y8
;
4320 __gx
->peCMode1
= (__gx
->peCMode1
&~0xC00)|(_SHIFTL(pix_fmt
,10,2));
4321 GX_LOAD_BP_REG(__gx
->peCMode1
);
4325 void GX_SetDither(u8 dither
)
4327 __gx
->peCMode0
= (__gx
->peCMode0
&~0x4)|(_SHIFTL(dither
,2,1));
4328 GX_LOAD_BP_REG(__gx
->peCMode0
);
4331 void GX_SetDstAlpha(u8 enable
,u8 a
)
4333 __gx
->peCMode1
= (__gx
->peCMode1
&~0xff)|(a
&0xff);
4334 __gx
->peCMode1
= (__gx
->peCMode1
&~0x100)|(_SHIFTL(enable
,8,1));
4335 GX_LOAD_BP_REG(__gx
->peCMode1
);
4338 void GX_SetFieldMask(u8 even_mask
,u8 odd_mask
)
4342 val
= (_SHIFTL(even_mask
,1,1))|(odd_mask
&1);
4343 GX_LOAD_BP_REG(0x44000000|val
);
4346 void GX_SetFieldMode(u8 field_mode
,u8 half_aspect_ratio
)
4348 __gx
->lpWidth
= (__gx
->lpWidth
&~0x400000)|(_SHIFTL(half_aspect_ratio
,22,1));
4349 GX_LOAD_BP_REG(__gx
->lpWidth
);
4351 __GX_FlushTextureState();
4352 GX_LOAD_BP_REG(0x68000000|(field_mode
&1));
4353 __GX_FlushTextureState();
4356 void GX_PokeAlphaMode(u8 func
,u8 threshold
)
4358 _peReg
[3] = (_SHIFTL(func
,8,8))|(threshold
&0xFF);
4361 void GX_PokeAlphaRead(u8 mode
)
4363 _peReg
[4] = (mode
&~0x4)|0x4;
4366 void GX_PokeDstAlpha(u8 enable
,u8 a
)
4368 _peReg
[2] = (_SHIFTL(enable
,8,1))|(a
&0xff);
4371 void GX_PokeAlphaUpdate(u8 update_enable
)
4373 _peReg
[1] = (_peReg
[1]&~0x10)|(_SHIFTL(update_enable
,4,1));
4376 void GX_PokeColorUpdate(u8 update_enable
)
4378 _peReg
[1] = (_peReg
[1]&~0x8)|(_SHIFTL(update_enable
,3,1));
4381 void GX_PokeDither(u8 dither
)
4383 _peReg
[1] = (_peReg
[1]&~0x4)|(_SHIFTL(dither
,2,1));
4386 void GX_PokeBlendMode(u8 type
,u8 src_fact
,u8 dst_fact
,u8 op
)
4388 u32 regval
= _peReg
[1];
4390 regval
= (regval
&~0x1);
4391 if(type
==GX_BM_BLEND
|| type
==GX_BM_SUBTRACT
) regval
|= 0x1;
4393 regval
= (regval
&~0x800);
4394 if(type
==GX_BM_SUBTRACT
) regval
|= 0x800;
4396 regval
= (regval
&~0x2);
4397 if(type
==GX_BM_LOGIC
) regval
|= 0x2;
4399 regval
= (regval
&~0xF000)|(_SHIFTL(op
,12,4));
4400 regval
= (regval
&~0xE0)|(_SHIFTL(dst_fact
,5,3));
4401 regval
= (regval
&~0x700)|(_SHIFTL(src_fact
,8,3));
4403 regval
|= 0x41000000;
4404 _peReg
[1] = (u16
)regval
;
4407 void GX_PokeARGB(u16 x
,u16 y
,GXColor color
)
4411 regval
= 0xc8000000|(_SHIFTL(x
,2,10));
4412 regval
= (regval
&~0x3FF000)|(_SHIFTL(y
,12,10));
4413 *(u32
*)regval
= _SHIFTL(color
.a
,24,8)|_SHIFTL(color
.r
,16,8)|_SHIFTL(color
.g
,8,8)|(color
.b
&0xff);
4416 void GX_PeekARGB(u16 x
,u16 y
,GXColor
*color
)
4420 regval
= 0xc8000000|(_SHIFTL(x
,2,10));
4421 regval
= (regval
&~0x3FF000)|(_SHIFTL(y
,12,10));
4422 val
= *(u32
*)regval
;
4423 color
->a
= _SHIFTR(val
,24,8);
4424 color
->r
= _SHIFTR(val
,16,8);
4425 color
->g
= _SHIFTR(val
,8,8);
4426 color
->b
= val
&0xff;
4429 void GX_PokeZ(u16 x
,u16 y
,u32 z
)
4433 regval
= 0xc8000000|(_SHIFTL(x
,2,10));
4434 regval
= (regval
&~0x3FF000)|(_SHIFTL(y
,12,10));
4435 regval
= (regval
&~0xC00000)|0x400000;
4439 void GX_PeekZ(u16 x
,u16 y
,u32
*z
)
4443 regval
= 0xc8000000|(_SHIFTL(x
,2,10));
4444 regval
= (regval
&~0x3FF000)|(_SHIFTL(y
,12,10));
4445 regval
= (regval
&~0xC00000)|0x400000;
4449 void GX_PokeZMode(u8 comp_enable
,u8 func
,u8 update_enable
)
4452 regval
= comp_enable
&0x1;
4453 regval
= (regval
&~0xE)|(_SHIFTL(func
,1,3));
4454 regval
= (regval
&0x10)|(_SHIFTL(update_enable
,4,1));
4458 void GX_SetIndTexOrder(u8 indtexstage
,u8 texcoord
,u8 texmap
)
4460 switch(indtexstage
) {
4461 case GX_INDTEXSTAGE0
:
4462 __gx
->tevRasOrder
[2] = (__gx
->tevRasOrder
[2]&~0x7)|(texmap
&0x7);
4463 __gx
->tevRasOrder
[2] = (__gx
->tevRasOrder
[2]&~0x38)|(_SHIFTL(texcoord
,3,3));
4465 case GX_INDTEXSTAGE1
:
4466 __gx
->tevRasOrder
[2] = (__gx
->tevRasOrder
[2]&~0x1C0)|(_SHIFTL(texmap
,6,3));
4467 __gx
->tevRasOrder
[2] = (__gx
->tevRasOrder
[2]&~0xE00)|(_SHIFTL(texcoord
,9,3));
4469 case GX_INDTEXSTAGE2
:
4470 __gx
->tevRasOrder
[2] = (__gx
->tevRasOrder
[2]&~0x7000)|(_SHIFTL(texmap
,12,3));
4471 __gx
->tevRasOrder
[2] = (__gx
->tevRasOrder
[2]&~0x38000)|(_SHIFTL(texcoord
,15,3));
4473 case GX_INDTEXSTAGE3
:
4474 __gx
->tevRasOrder
[2] = (__gx
->tevRasOrder
[2]&~0x1C0000)|(_SHIFTL(texmap
,18,3));
4475 __gx
->tevRasOrder
[2] = (__gx
->tevRasOrder
[2]&~0xE00000)|(_SHIFTL(texcoord
,21,3));
4478 GX_LOAD_BP_REG(__gx
->tevRasOrder
[2]);
4479 __gx
->dirtyState
|= 0x0003;
4482 void GX_InitLightPos(GXLightObj
*lit_obj
,f32 x
,f32 y
,f32 z
)
4484 struct __gx_litobj
*lit
= (struct __gx_litobj
*)lit_obj
;
4491 void GX_InitLightColor(GXLightObj
*lit_obj
,GXColor col
)
4493 struct __gx_litobj
*lit
= (struct __gx_litobj
*)lit_obj
;
4494 lit
->col
= ((_SHIFTL(col
.r
,24,8))|(_SHIFTL(col
.g
,16,8))|(_SHIFTL(col
.b
,8,8))|(col
.a
&0xff));
4497 void GX_LoadLightObj(GXLightObj
*lit_obj
,u8 lit_id
)
4501 struct __gx_litobj
*lit
= (struct __gx_litobj
*)lit_obj
;
4533 reg
= 0x600|(_SHIFTL(id
,4,8));
4534 GX_LOAD_XF_REGS(reg
,16);
4538 wgPipe
->U32
= lit
->col
;
4539 wgPipe
->F32
= lit
->a0
;
4540 wgPipe
->F32
= lit
->a1
;
4541 wgPipe
->F32
= lit
->a2
;
4542 wgPipe
->F32
= lit
->k0
;
4543 wgPipe
->F32
= lit
->k1
;
4544 wgPipe
->F32
= lit
->k2
;
4545 wgPipe
->F32
= lit
->px
;
4546 wgPipe
->F32
= lit
->py
;
4547 wgPipe
->F32
= lit
->pz
;
4548 wgPipe
->F32
= lit
->nx
;
4549 wgPipe
->F32
= lit
->ny
;
4550 wgPipe
->F32
= lit
->nz
;
4553 void GX_LoadLightObjIdx(u32 litobjidx
,u8 litid
)
4589 reg
= 0xf600|(_SHIFTL(idx
,4,8));
4590 reg
= (reg
&~0xffff0000)|(_SHIFTL(litobjidx
,16,16));
4596 void GX_InitLightDir(GXLightObj
*lit_obj
,f32 nx
,f32 ny
,f32 nz
)
4598 struct __gx_litobj
*lit
= (struct __gx_litobj
*)lit_obj
;
4605 void GX_InitLightDistAttn(GXLightObj
*lit_obj
,f32 ref_dist
,f32 ref_brite
,u8 dist_fn
)
4608 struct __gx_litobj
*lit
= (struct __gx_litobj
*)lit_obj
;
4611 ref_brite
<0.0f
|| ref_brite
>=1.0f
) dist_fn
= GX_DA_OFF
;
4616 k1
= (1.0f
-ref_brite
)/(ref_brite
*ref_dist
);
4621 k1
= 0.5f
*(1.0f
-ref_brite
)/(ref_brite
*ref_dist
);
4622 k2
= 0.5f
*(1.0f
-ref_brite
)/(ref_brite
*ref_dist
*ref_dist
);
4627 k2
= (1.0f
-ref_brite
)/(ref_brite
*ref_dist
*ref_dist
);
4642 void GX_InitLightAttn(GXLightObj
*lit_obj
,f32 a0
,f32 a1
,f32 a2
,f32 k0
,f32 k1
,f32 k2
)
4644 struct __gx_litobj
*lit
= (struct __gx_litobj
*)lit_obj
;
4654 void GX_InitLightAttnA(GXLightObj
*lit_obj
,f32 a0
,f32 a1
,f32 a2
)
4656 struct __gx_litobj
*lit
= (struct __gx_litobj
*)lit_obj
;
4663 void GX_InitLightAttnK(GXLightObj
*lit_obj
,f32 k0
,f32 k1
,f32 k2
)
4665 struct __gx_litobj
*lit
= (struct __gx_litobj
*)lit_obj
;
4672 void GX_InitSpecularDirHA(GXLightObj
*lit_obj
,f32 nx
,f32 ny
,f32 nz
,f32 hx
,f32 hy
,f32 hz
)
4675 struct __gx_litobj
*lit
= (struct __gx_litobj
*)lit_obj
;
4677 px
= (nx
* LARGE_NUMBER
);
4678 py
= (ny
* LARGE_NUMBER
);
4679 pz
= (nz
* LARGE_NUMBER
);
4689 void GX_InitSpecularDir(GXLightObj
*lit_obj
,f32 nx
,f32 ny
,f32 nz
)
4692 f32 hx
, hy
, hz
, mag
;
4693 struct __gx_litobj
*lit
= (struct __gx_litobj
*)lit_obj
;
4695 // Compute half-angle vector
4699 mag
= ((hx
* hx
) + (hy
* hy
) + (hz
* hz
));
4700 if(mag
!=0.0f
) mag
= 1.0f
/ sqrtf(mag
);
4706 px
= (nx
* LARGE_NUMBER
);
4707 py
= (ny
* LARGE_NUMBER
);
4708 pz
= (nz
* LARGE_NUMBER
);
4718 void GX_InitLightSpot(GXLightObj
*lit_obj
,f32 cut_off
,u8 spotfn
)
4720 f32 r
,d
,cr
,a0
,a1
,a2
;
4721 struct __gx_litobj
*lit
= (struct __gx_litobj
*)lit_obj
;
4723 if(cut_off
<0.0f
|| cut_off
>90.0f
) spotfn
= GX_SP_OFF
;
4725 r
= (cut_off
*M_PI
)/180.0f
;
4736 a1
= 1.0f
/(1.0f
-cr
);
4742 a2
= 1.0f
/(1.0f
-cr
);
4745 d
= (1.0f
-cr
)*(1.0f
-cr
);
4751 d
= (1.0f
-cr
)*(1.0f
-cr
);
4753 a1
= 4.0f
*(1.0f
+cr
)/d
;
4757 d
= (1.0f
-cr
)*(1.0f
-cr
);
4758 a0
= 1.0f
-2.0f
*cr
*cr
/d
;
4775 void GX_SetGPMetric(u32 perf0
,u32 perf1
)
4777 // check last setted perf0 counters
4778 if(__gx
->perf0Mode
>=GX_PERF0_TRIANGLES
&& __gx
->perf0Mode
<GX_PERF0_QUAD_0CVG
)
4779 GX_LOAD_BP_REG(0x23000000);
4780 else if(__gx
->perf0Mode
>=GX_PERF0_QUAD_0CVG
&& __gx
->perf0Mode
<GX_PERF0_CLOCKS
)
4781 GX_LOAD_BP_REG(0x24000000);
4782 else if(__gx
->perf0Mode
>=GX_PERF0_VERTICES
&& __gx
->perf0Mode
<=GX_PERF0_CLOCKS
)
4783 GX_LOAD_XF_REG(0x1006,0);
4785 // check last setted perf1 counters
4786 if(__gx
->perf1Mode
>=GX_PERF1_VC_ELEMQ_FULL
&& __gx
->perf1Mode
<GX_PERF1_FIFO_REQ
) {
4787 __gx
->cpPerfMode
= (__gx
->cpPerfMode
&~0xf0);
4788 GX_LOAD_CP_REG(0x20,__gx
->cpPerfMode
);
4789 } else if(__gx
->perf1Mode
>=GX_PERF1_FIFO_REQ
&& __gx
->perf1Mode
<GX_PERF1_CLOCKS
) {
4791 } else if(__gx
->perf1Mode
>=GX_PERF1_TEXELS
&& __gx
->perf1Mode
<=GX_PERF1_CLOCKS
) {
4792 GX_LOAD_BP_REG(0x67000000);
4795 __gx
->perf0Mode
= perf0
;
4796 switch(__gx
->perf0Mode
) {
4797 case GX_PERF0_CLOCKS
:
4798 GX_LOAD_XF_REG(0x1006,0x00000273);
4800 case GX_PERF0_VERTICES
:
4801 GX_LOAD_XF_REG(0x1006,0x0000014a);
4803 case GX_PERF0_CLIP_VTX
:
4804 GX_LOAD_XF_REG(0x1006,0x0000016b);
4806 case GX_PERF0_CLIP_CLKS
:
4807 GX_LOAD_XF_REG(0x1006,0x00000084);
4809 case GX_PERF0_XF_WAIT_IN
:
4810 GX_LOAD_XF_REG(0x1006,0x000000c6);
4812 case GX_PERF0_XF_WAIT_OUT
:
4813 GX_LOAD_XF_REG(0x1006,0x00000210);
4815 case GX_PERF0_XF_XFRM_CLKS
:
4816 GX_LOAD_XF_REG(0x1006,0x00000252);
4818 case GX_PERF0_XF_LIT_CLKS
:
4819 GX_LOAD_XF_REG(0x1006,0x00000231);
4821 case GX_PERF0_XF_BOT_CLKS
:
4822 GX_LOAD_XF_REG(0x1006,0x000001ad);
4824 case GX_PERF0_XF_REGLD_CLKS
:
4825 GX_LOAD_XF_REG(0x1006,0x000001ce);
4827 case GX_PERF0_XF_REGRD_CLKS
:
4828 GX_LOAD_XF_REG(0x1006,0x00000021);
4830 case GX_PERF0_CLIP_RATIO
:
4831 GX_LOAD_XF_REG(0x1006,0x00000153);
4833 case GX_PERF0_TRIANGLES
:
4834 GX_LOAD_BP_REG(0x2300AE7F);
4836 case GX_PERF0_TRIANGLES_CULLED
:
4837 GX_LOAD_BP_REG(0x23008E7F);
4839 case GX_PERF0_TRIANGLES_PASSED
:
4840 GX_LOAD_BP_REG(0x23009E7F);
4842 case GX_PERF0_TRIANGLES_SCISSORED
:
4843 GX_LOAD_BP_REG(0x23001E7F);
4845 case GX_PERF0_TRIANGLES_0TEX
:
4846 GX_LOAD_BP_REG(0x2300AC3F);
4848 case GX_PERF0_TRIANGLES_1TEX
:
4849 GX_LOAD_BP_REG(0x2300AC7F);
4851 case GX_PERF0_TRIANGLES_2TEX
:
4852 GX_LOAD_BP_REG(0x2300ACBF);
4854 case GX_PERF0_TRIANGLES_3TEX
:
4855 GX_LOAD_BP_REG(0x2300ACFF);
4857 case GX_PERF0_TRIANGLES_4TEX
:
4858 GX_LOAD_BP_REG(0x2300AD3F);
4860 case GX_PERF0_TRIANGLES_5TEX
:
4861 GX_LOAD_BP_REG(0x2300AD7F);
4863 case GX_PERF0_TRIANGLES_6TEX
:
4864 GX_LOAD_BP_REG(0x2300ADBF);
4866 case GX_PERF0_TRIANGLES_7TEX
:
4867 GX_LOAD_BP_REG(0x2300ADFF);
4869 case GX_PERF0_TRIANGLES_8TEX
:
4870 GX_LOAD_BP_REG(0x2300AE3F);
4872 case GX_PERF0_TRIANGLES_0CLR
:
4873 GX_LOAD_BP_REG(0x2300A27F);
4875 case GX_PERF0_TRIANGLES_1CLR
:
4876 GX_LOAD_BP_REG(0x2300A67F);
4878 case GX_PERF0_TRIANGLES_2CLR
:
4879 GX_LOAD_BP_REG(0x2300AA7F);
4881 case GX_PERF0_QUAD_0CVG
:
4882 GX_LOAD_BP_REG(0x2402C0C6);
4884 case GX_PERF0_QUAD_NON0CVG
:
4885 GX_LOAD_BP_REG(0x2402C16B);
4887 case GX_PERF0_QUAD_1CVG
:
4888 GX_LOAD_BP_REG(0x2402C0E7);
4890 case GX_PERF0_QUAD_2CVG
:
4891 GX_LOAD_BP_REG(0x2402C108);
4893 case GX_PERF0_QUAD_3CVG
:
4894 GX_LOAD_BP_REG(0x2402C129);
4896 case GX_PERF0_QUAD_4CVG
:
4897 GX_LOAD_BP_REG(0x2402C14A);
4899 case GX_PERF0_AVG_QUAD_CNT
:
4900 GX_LOAD_BP_REG(0x2402C1AD);
4906 __gx
->perf1Mode
= perf1
;
4907 switch(__gx
->perf1Mode
) {
4908 case GX_PERF1_CLOCKS
:
4909 GX_LOAD_BP_REG(0x67000042);
4911 case GX_PERF1_TEXELS
:
4912 GX_LOAD_BP_REG(0x67000084);
4914 case GX_PERF1_TX_IDLE
:
4915 GX_LOAD_BP_REG(0x67000063);
4917 case GX_PERF1_TX_REGS
:
4918 GX_LOAD_BP_REG(0x67000129);
4920 case GX_PERF1_TX_MEMSTALL
:
4921 GX_LOAD_BP_REG(0x67000252);
4923 case GX_PERF1_TC_CHECK1_2
:
4924 GX_LOAD_BP_REG(0x67000021);
4926 case GX_PERF1_TC_CHECK3_4
:
4927 GX_LOAD_BP_REG(0x6700014b);
4929 case GX_PERF1_TC_CHECK5_6
:
4930 GX_LOAD_BP_REG(0x6700018d);
4932 case GX_PERF1_TC_CHECK7_8
:
4933 GX_LOAD_BP_REG(0x670001cf);
4935 case GX_PERF1_TC_MISS
:
4936 GX_LOAD_BP_REG(0x67000211);
4938 case GX_PERF1_VC_ELEMQ_FULL
:
4939 __gx
->cpPerfMode
= (__gx
->cpPerfMode
&~0xf0)|0x20;
4940 GX_LOAD_CP_REG(0x20,__gx
->cpPerfMode
);
4942 case GX_PERF1_VC_MISSQ_FULL
:
4943 __gx
->cpPerfMode
= (__gx
->cpPerfMode
&~0xf0)|0x30;
4944 GX_LOAD_CP_REG(0x20,__gx
->cpPerfMode
);
4946 case GX_PERF1_VC_MEMREQ_FULL
:
4947 __gx
->cpPerfMode
= (__gx
->cpPerfMode
&~0xf0)|0x40;
4948 GX_LOAD_CP_REG(0x20,__gx
->cpPerfMode
);
4950 case GX_PERF1_VC_STATUS7
:
4951 __gx
->cpPerfMode
= (__gx
->cpPerfMode
&~0xf0)|0x50;
4952 GX_LOAD_CP_REG(0x20,__gx
->cpPerfMode
);
4954 case GX_PERF1_VC_MISSREP_FULL
:
4955 __gx
->cpPerfMode
= (__gx
->cpPerfMode
&~0xf0)|0x60;
4956 GX_LOAD_CP_REG(0x20,__gx
->cpPerfMode
);
4958 case GX_PERF1_VC_STREAMBUF_LOW
:
4959 __gx
->cpPerfMode
= (__gx
->cpPerfMode
&~0xf0)|0x70;
4960 GX_LOAD_CP_REG(0x20,__gx
->cpPerfMode
);
4962 case GX_PERF1_VC_ALL_STALLS
:
4963 __gx
->cpPerfMode
= (__gx
->cpPerfMode
&~0xf0)|0x90;
4964 GX_LOAD_CP_REG(0x20,__gx
->cpPerfMode
);
4966 case GX_PERF1_VERTICES
:
4967 __gx
->cpPerfMode
= (__gx
->cpPerfMode
&~0xf0)|0x80;
4968 GX_LOAD_CP_REG(0x20,__gx
->cpPerfMode
);
4970 case GX_PERF1_FIFO_REQ
:
4973 case GX_PERF1_CALL_REQ
:
4976 case GX_PERF1_VC_MISS_REQ
:
4979 case GX_PERF1_CP_ALL_REQ
:
4988 void GX_ClearGPMetric()
4993 void GX_InitXfRasMetric()
4995 GX_LOAD_BP_REG(0x2402C022);
4996 GX_LOAD_XF_REG(0x1006,0x31000);
4999 void GX_ReadXfRasMetric(u32
*xfwaitin
,u32
*xfwaitout
,u32
*rasbusy
,u32
*clks
)
5001 *rasbusy
= _SHIFTL(_cpReg
[33],16,16)|(_cpReg
[32]&0xffff);
5002 *clks
= _SHIFTL(_cpReg
[35],16,16)|(_cpReg
[34]&0xffff);
5003 *xfwaitin
= _SHIFTL(_cpReg
[37],16,16)|(_cpReg
[36]&0xffff);
5004 *xfwaitout
= _SHIFTL(_cpReg
[39],16,16)|(_cpReg
[38]&0xffff);
5007 u32
GX_ReadClksPerVtx()
5010 _cpReg
[49] = 0x1007;
5011 _cpReg
[48] = 0x1007;
5012 return (_cpReg
[50]<<8);
5015 void GX_ClearVCacheMetric()
5017 GX_LOAD_CP_REG(0,0);
5020 void GX_ReadVCacheMetric(u32
*check
,u32
*miss
,u32
*stall
)
5022 *check
= _SHIFTL(_cpReg
[41],16,16)|(_cpReg
[40]&0xffff);
5023 *miss
= _SHIFTL(_cpReg
[43],16,16)|(_cpReg
[42]&0xffff);
5024 *stall
= _SHIFTL(_cpReg
[45],16,16)|(_cpReg
[44]&0xffff);
5027 void GX_SetVCacheMetric(u32 attr
)
5031 void GX_GetGPStatus(u8
*overhi
,u8
*underlow
,u8
*readIdle
,u8
*cmdIdle
,u8
*brkpt
)
5033 _gxgpstatus
= _cpReg
[0];
5034 *overhi
= !!(_gxgpstatus
&1);
5035 *underlow
= !!(_gxgpstatus
&2);
5036 *readIdle
= !!(_gxgpstatus
&4);
5037 *cmdIdle
= !!(_gxgpstatus
&8);
5038 *brkpt
= !!(_gxgpstatus
&16);
5041 void GX_ReadGPMetric(u32
*cnt0
,u32
*cnt1
)
5043 u32 tmp
,reg1
,reg2
,reg3
,reg4
;
5045 reg1
= (_SHIFTL(_cpReg
[33],16,16))|(_cpReg
[32]&0xffff);
5046 reg2
= (_SHIFTL(_cpReg
[35],16,16))|(_cpReg
[34]&0xffff);
5047 reg3
= (_SHIFTL(_cpReg
[37],16,16))|(_cpReg
[36]&0xffff);
5048 reg4
= (_SHIFTL(_cpReg
[39],16,16))|(_cpReg
[38]&0xffff);
5051 if(__gx
->perf0Mode
==GX_PERF0_CLIP_RATIO
) {
5054 } else if(__gx
->perf0Mode
>=GX_PERF0_VERTICES
&& __gx
->perf0Mode
<GX_PERF0_NONE
) *cnt0
= reg1
;
5056 //further implementation needed.....
5060 void GX_AdjustForOverscan(GXRModeObj
*rmin
,GXRModeObj
*rmout
,u16 hor
,u16 ver
)
5062 if(rmin
!=rmout
) memcpy(rmout
,rmin
,sizeof(GXRModeObj
));
5064 rmout
->fbWidth
= rmin
->fbWidth
-(hor
<<1);
5065 rmout
->efbHeight
= rmin
->efbHeight
-((rmin
->efbHeight
*(ver
<<1))/rmin
->xfbHeight
);
5066 if(rmin
->xfbMode
==VI_XFBMODE_SF
&& !(rmin
->viTVMode
&VI_PROGRESSIVE
)) rmout
->xfbHeight
= rmin
->xfbHeight
-ver
;
5067 else rmout
->xfbHeight
= rmin
->xfbHeight
-(ver
<<1);
5069 rmout
->viWidth
= rmin
->viWidth
-(hor
<<1);
5070 if(rmin
->viTVMode
&VI_PROGRESSIVE
) rmout
->viHeight
= rmin
->viHeight
-(ver
<<2);
5071 else rmout
->viHeight
= rmin
->viHeight
-(ver
<<1);
5073 rmout
->viXOrigin
+= hor
;
5074 rmout
->viYOrigin
+= ver
;
5077 f32
GX_GetYScaleFactor(u16 efbHeight
,u16 xfbHeight
)
5079 u32 yScale
,xfblines
,cnt
;
5082 yscale
= (f32
)efbHeight
/(f32
)xfbHeight
;
5083 yScale
= (u32
)((f32
)256.0/yscale
)&0x1ff;
5086 xfblines
= __GX_GetNumXfbLines(efbHeight
,yScale
);
5087 while(xfblines
>=xfbHeight
) {
5088 yscale
= (f32
)(cnt
--)/(f32
)efbHeight
;
5089 yScale
= (u32
)((f32
)256.0/yscale
)&0x1ff;
5090 xfblines
= __GX_GetNumXfbLines(efbHeight
,yScale
);
5093 while(xfblines
<xfbHeight
) {
5094 yscale
= (f32
)(cnt
++)/(f32
)efbHeight
;
5095 yScale
= (u32
)((f32
)256.0/yscale
)&0x1ff;
5096 xfblines
= __GX_GetNumXfbLines(efbHeight
,yScale
);
5101 void GX_ReadBoundingBox(u16
*top
,u16
*bottom
,u16
*left
,u16
*right
)
5106 *bottom
= _peReg
[11];