1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin/Revolution gx demo
3   File:     perf-geo.c
4 
5   Copyright 1998 - 2006 Nintendo.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12   Immediate-mode performance test
13 
14  *---------------------------------------------------------------------------*/
15 
16 #include <demo.h>
17 #include <math.h>
18 
19 /*---------------------------------------------------------------------------*
20    Forward references
21  *---------------------------------------------------------------------------*/
22 
23 void        main             ( void );
24 static void CameraInit       ( void );
25 static void DrawInit         ( void );
26 static void DrawTick         ( void );
27 static void DumpStats        ( void );
28 static void PrintIntro       ( void );
29 static u32  checkForOverflow ( void );
30 static void DrawCubeIndx     ( void );
31 static void DrawCubeDirect   ( void );
32 static void DrawTexCubeIndx  ( void );
33 static void DrawTexCubeDirect( void );
34 
35 
36 /*---------------------------------------------------------------------------*
37    Defines
38  *---------------------------------------------------------------------------*/
39 #define BALL64_TEX_ID   8
40 #define N_TESTS         (sizeof(testData)/sizeof(TestData))
41 #define N_STATS         (sizeof(Stat)/sizeof(StatObj))
42 #define SIDE            50.0F
43 
44 typedef enum {
45     GP_PERF0,
46     GP_PERF1,
47     MEM_PERF,
48     PIX_PERF,
49     VC_PERF
50 } PerfType;
51 
52 /*---------------------------------------------------------------------------*
53    Global variables
54  *---------------------------------------------------------------------------*/
55 //
56 //  Cube data
57 //
58 f32 Vert[] ATTRIBUTE_ALIGN(32) =
59                      {
60                         -SIDE, SIDE, -SIDE, //0
61                         -SIDE, SIDE, SIDE,  //1
62                         -SIDE, -SIDE, SIDE, //2
63                         -SIDE, -SIDE, -SIDE,//3
64                         SIDE, SIDE, -SIDE,  //4
65                         SIDE, -SIDE, -SIDE, //5
66                         SIDE, -SIDE, SIDE,  //6
67                         SIDE, SIDE, SIDE    //7
68                     };
69 
70 f32 Norm[] ATTRIBUTE_ALIGN(32) =
71                      {
72                         -1.0F,  0.0F,  0.0F, //0
73                          0.0F, -1.0F,  0.0F, //1
74                          0.0F,  0.0F, -1.0F, //2
75                          1.0F,  0.0F,  0.0F, //3
76                          0.0F,  1.0F,  0.0F, //4
77                          0.0F,  0.0F,  1.0F  //5
78                     };
79 
80 f32 TexCoord[] ATTRIBUTE_ALIGN(32) =
81                      {
82                          0.0F,  0.0F, //0
83                          1.0F,  0.0F, //1
84                          1.0F,  1.0F, //2
85                          0.0F,  1.0F, //3
86                     };
87 
88 u32 MyColors[] ATTRIBUTE_ALIGN(32) =
89 {
90     0xff0000ff, // red
91     0x00ff00ff, // green
92     0x0000ffff, // blue
93     0xffff00ff, // yellow
94     0xff00ffff, // magenta
95     0x00ffffff  // cyan
96 };
97 
98 // index when lsb=1
99 typedef enum {
100     CUBE_DIR,     // lit and textured
101     CUBE_IDX,     // lit and textured
102     CUBE_TEX_DIR, // textured only
103     CUBE_TEX_IDX  // textured only
104 } CubeType;
105 
106 //
107 //  Test cases
108 //
109 typedef struct {
110     u32      nloops;  // number of loops (ncubes + nmtx)
111     u32      ncubes;  // number of cubes to draw, 24 verts each
112     u32      nmtx;    // number of matrix loads per ncubes
113     u32      fill;    // fill FIFO flag, if true fill FIFO before rendering
114     CubeType type;    // type of vertex data
115 } TestData;
116 
117 static TestData testData[] =
118 {  //  nloops, ncubes, nmtx, fill, type
119 
120 {       1,      0, 1000,    1,    CUBE_DIR }, // test matrix load speed
121 {       1,   1000,    1,    1,    CUBE_DIR }, // test a few large objects
122 {    1000,      1,    1,    1,    CUBE_DIR }, // test very small objects
123 {     500,      2,    1,    1,    CUBE_DIR }, //
124 {     333,      3,    1,    1,    CUBE_DIR }, //
125 {     250,      4,    1,    1,    CUBE_DIR }, //
126 {     200,      5,    1,    1,    CUBE_DIR }, //
127 {     100,     10,    1,    1,    CUBE_DIR }, // test many small objects
128 {     100,     10,    2,    1,    CUBE_DIR }, // how does n mtx effect?
129 {     100,     10,    3,    1,    CUBE_DIR },
130 {     100,     10,   10,    1,    CUBE_DIR },
131 
132 {       1,      0, 1000,    1,    CUBE_IDX }, // test matrix load speed
133 {       1,   1000,    1,    1,    CUBE_IDX }, // test a few large objects
134 {    1000,      1,    1,    1,    CUBE_IDX }, // test very small objects
135 {     500,      2,    1,    1,    CUBE_IDX }, //
136 {     333,      3,    1,    1,    CUBE_IDX }, //
137 {     250,      4,    1,    1,    CUBE_IDX }, //
138 {     200,      5,    1,    1,    CUBE_IDX }, //
139 {     100,     10,    1,    1,    CUBE_IDX }, // test many small objects
140 {     100,     10,    2,    1,    CUBE_IDX }, // how does n mtx effect?
141 {     100,     10,    3,    1,    CUBE_IDX },
142 {     100,     10,   10,    1,    CUBE_IDX },
143 
144 {       1,      0, 1000,    1,    CUBE_TEX_DIR }, // test matrix load speed
145 {       1,   1000,    1,    1,    CUBE_TEX_DIR }, // test a few large objects
146 {    1000,      1,    1,    1,    CUBE_TEX_DIR }, // test very small objects
147 {     500,      2,    1,    1,    CUBE_TEX_DIR }, //
148 {     333,      3,    1,    1,    CUBE_TEX_DIR }, //
149 {     250,      4,    1,    1,    CUBE_TEX_DIR }, //
150 {     200,      5,    1,    1,    CUBE_TEX_DIR }, //
151 {     100,     10,    1,    1,    CUBE_TEX_DIR }, // test many small objects
152 {     100,     10,    2,    1,    CUBE_TEX_DIR }, // how does n mtx effect?
153 {     100,     10,    3,    1,    CUBE_TEX_DIR },
154 {     100,     10,   10,    1,    CUBE_TEX_DIR },
155 
156 {       1,      0, 1000,    1,    CUBE_TEX_IDX }, // test matrix load speed
157 {       1,   1000,    1,    1,    CUBE_TEX_IDX }, // test a few large objects
158 {    1000,      1,    1,    1,    CUBE_TEX_IDX }, // test very small objects
159 {     500,      2,    1,    1,    CUBE_TEX_IDX }, //
160 {     333,      3,    1,    1,    CUBE_TEX_IDX }, //
161 {     250,      4,    1,    1,    CUBE_TEX_IDX }, //
162 {     200,      5,    1,    1,    CUBE_TEX_IDX }, //
163 {     100,     10,    1,    1,    CUBE_TEX_IDX }, // test many small objects
164 {     100,     10,    2,    1,    CUBE_TEX_IDX }, // how does n mtx effect?
165 {     100,     10,    3,    1,    CUBE_TEX_IDX },
166 {     100,     10,   10,    1,    CUBE_TEX_IDX }
167 };
168 
169 //
170 //  Statistics
171 //
172 typedef struct {
173     u32         cnt;
174     PerfType    stat_type;
175     u32         stat;
176     char        text[50];
177 } StatObj;
178 
179 StatObj Stat[] = { // stats to count
180     { 0, GP_PERF0, GX_PERF0_XF_WAIT_IN,       "xf waiting on input........" },
181     { 0, GP_PERF0, GX_PERF0_XF_WAIT_OUT,      "xf waiting on output......." },
182     { 0, GP_PERF0, GX_PERF0_XF_XFRM_CLKS,     "xf transform clocks........" },
183     { 0, GP_PERF0, GX_PERF0_XF_LIT_CLKS,      "xf lighting clocks........." },
184     { 0, GP_PERF0, GX_PERF0_XF_BOT_CLKS,      "xf bot of pipe clocks......" },
185     { 0, GP_PERF0, GX_PERF0_XF_REGLD_CLKS,    "xf register load clocks...." },
186     { 0, GP_PERF0, GX_PERF0_XF_REGRD_CLKS,    "xf register read clocks...." },
187     { 0, GP_PERF0, GX_PERF0_TRIANGLES,        "Triangles.................." },
188     { 0, GP_PERF0, GX_PERF0_CLOCKS,           "Perf0 clocks..............." },
189     { 0, GP_PERF1, GX_PERF1_VERTICES,         "vertices..................." },
190     { 0, GP_PERF1, GX_PERF1_VC_ELEMQ_FULL,    "Vtx$ elem queue full......." },
191     { 0, GP_PERF1, GX_PERF1_VC_MISSQ_FULL,    "Vtx$ miss queue full......." },
192     { 0, GP_PERF1, GX_PERF1_VC_MEMREQ_FULL,   "Vtx$ mem request full......" },
193     { 0, GP_PERF1, GX_PERF1_VC_STATUS7,       "Vtx$ status 7.............." },
194     { 0, GP_PERF1, GX_PERF1_VC_MISSREP_FULL,  "Vtx$ miss replace full....." },
195     { 0, GP_PERF1, GX_PERF1_VC_STREAMBUF_LOW, "Vtx$ stream buf low........" },
196     { 0, GP_PERF1, GX_PERF1_VC_ALL_STALLS,    "Vtx$ all stalls............" },
197     { 0, GP_PERF1, GX_PERF1_VERTICES,         "Perf1 vertices............." },
198     { 0, GP_PERF1, GX_PERF1_FIFO_REQ,         "CP fifo requests..........." },
199     { 0, GP_PERF1, GX_PERF1_CALL_REQ,         "CP call requests..........." },
200     { 0, GP_PERF1, GX_PERF1_VC_MISS_REQ,      "Vtx$ miss request.........." },
201     { 0, GP_PERF1, GX_PERF1_CP_ALL_REQ,       "CP all requests............" },
202     { 0, GP_PERF1, GX_PERF1_CLOCKS,           "Perf1 clocks..............." },
203     { 0, MEM_PERF, 0,                         "Memory requests............" }
204 };
205 
206 //
207 //  Global vars
208 //
209 static Mtx v, mv;
210 
211 static u32 Test    = 0;
212 static u32 curStat = 0;
213 static void (*testDraw)() = NULL; // function pointer for draw routine
214 
215 // pixel statistics counters
216 static u32 topPixIn;
217 static u32 topPixOut;
218 static u32 botPixIn;
219 static u32 botPixOut;
220 static u32 clrPixIn;
221 static u32 copyClks;
222 // vcache statistics counters
223 static u32 vcCheck;
224 static u32 vcMiss;
225 static u32 vcStall;
226 // clocks per verts
227 static u32 cpReq,
228            tcReq,
229            cpuRdReq,
230            cpuWrReq,
231            dspReq,
232            ioReq,
233            viReq,
234            peReq,
235            rfReq,
236            fiReq;
237 
238 static OSStopwatch myTotTime;
239 static OSStopwatch myCpuTime;
240 static OSStopwatch myGpTime;
241 static GXFifoObj newFifo;
242 
243 /*---------------------------------------------------------------------------*
244    Application main loop
245  *---------------------------------------------------------------------------*/
main(void)246 void main ( void )
247 {
248     u32 fillFifo = 0;
249     u32 i        = 0;
250     GXFifoObj waitFifo; // this is the default GX fifo
251     GXFifoObj tmpFifo;
252 
253 
254     DEMOInit(NULL);
255     DrawInit();
256     PrintIntro();
257 
258     OSInitStopwatch(&myTotTime, "myTotTime");
259     OSInitStopwatch(&myCpuTime, "myCpuTime");
260     OSInitStopwatch(&myGpTime, "myGpTime");
261 
262     // Allocate memory initialize the newFifo.  This fifo is used to hold
263     // a complete 'frame' to draw.  We don't really need a complete frame,
264     // just enough to see the performance difference.
265     GXInitFifoBase(&newFifo,
266                    MEMAllocFromAllocator(&DemoAllocator1, sizeof(u8)*1000*1500), sizeof(u8)*1000*1500);
267 
268     // get the default fifo, this will be emptied and then used
269     // to keep the GP from reading when we select fillFifo mode
270     GXFlush();
271     GXGetCPUFifo(&waitFifo);
272     Test = 0;
273 
274     while (Test != N_TESTS)
275     {
276         OSResetStopwatch(&myTotTime);
277         OSResetStopwatch(&myCpuTime);
278         OSResetStopwatch(&myGpTime);
279 
280         fillFifo = testData[Test].fill;
281         curStat = 0;
282         while (curStat != N_STATS)
283         {
284             DEMOBeforeRender();
285 
286             //
287             //  Enable various statistics
288             //  clear counters
289             //
290             if (Stat[curStat].stat_type == GP_PERF0)
291             {
292                 GXSetGP0Metric((GXPerf0)Stat[curStat].stat);
293                 GXClearGP0Metric();
294             }
295             else if (Stat[curStat].stat_type == GP_PERF1)
296             {
297                 GXSetGP1Metric((GXPerf1)Stat[curStat].stat);
298                 GXClearGP1Metric();
299             }
300             else if (Stat[curStat].stat_type == MEM_PERF)
301             {
302                 GXClearMemMetric();
303             }
304             else if (Stat[curStat].stat_type == PIX_PERF)
305             {
306                 GXClearPixMetric();
307             }
308             else // vcache stat
309             {
310                 GXSetVCacheMetric(GX_VC_ALL);
311                 GXClearVCacheMetric();
312             }
313 
314             // make sure all GX commands to here are flushed
315             GXFlush();
316             GXGetCPUFifo(&tmpFifo);
317 
318             // choose normal immediate mode or delayed immediate mode
319             if (fillFifo)
320             {
321                 // set new FIFO
322                 if (GXGetFifoBase(&tmpFifo) != GXGetFifoBase(&newFifo))
323                 {
324                     // reset read/write pointers
325                     GXInitFifoPtrs(&newFifo,
326                                     GXGetFifoBase(&newFifo),
327                                     GXGetFifoBase(&newFifo));
328                     GXSetCPUFifo(&newFifo);
329                 }
330                 OSStartStopwatch(&myCpuTime);
331             }
332             else
333             {
334                 // reset read write pointers
335                 if (GXGetFifoBase(&tmpFifo) != GXGetFifoBase(&waitFifo))
336                 {
337                     GXInitFifoPtrs(&waitFifo,
338                                    GXGetFifoBase(&waitFifo),
339                                    GXGetFifoBase(&waitFifo));
340                     // set new FIFO
341                     GXSetCPUFifo(&waitFifo);
342                 }
343             }
344 
345             OSStartStopwatch(&myTotTime);
346 
347 
348             DrawTick();
349 
350             // turn on FIFO reads after whole FIFO is filled
351             if (fillFifo)
352             {
353                 // push all data out
354                 GXFlush();
355                 OSStopStopwatch(&myCpuTime); // CPU is done here
356 
357                 // make sure we are in the newFifo limits
358                 if (checkForOverflow())
359                     OSHalt("Error, FIFO overflowed");
360 
361                 // switch to new fifo
362                 if ( !GXIsCPUGPFifoLinked() )
363                 {
364                 	GXFlush();
365                     GXGetCPUFifo(&tmpFifo);
366                     GXSetGPFifo(&tmpFifo);
367                 }
368 
369                 OSStartStopwatch(&myGpTime); // GP starts here
370             }
371 
372             GXDrawDone();   // wait for GP to be done
373                             // GXDrawDone does flush too
374 
375             //GXGetFifoPtrs(GXGetCPUFifo(), &readPtr1, &writePtr1);
376             //OSReport("Write pointer, after loop:  %08x\n", writePtr1);
377             //OSReport("Diff:  %8d (cache lines)\n",
378             //        ((u32)writePtr1 - (u32)writePtr0) / 32);
379 
380             OSStopStopwatch(&myTotTime);
381 
382             //
383             //  Read back various statistics
384             //
385             if (Stat[curStat].stat_type == GP_PERF0)
386             {
387                 Stat[curStat].cnt = GXReadGP0Metric();
388             }
389             else if (Stat[curStat].stat_type == GP_PERF1)
390             {
391                 Stat[curStat].cnt = GXReadGP1Metric();
392             }
393             else if (Stat[curStat].stat_type == MEM_PERF)
394             {
395                 GXReadMemMetric   ( &cpReq,
396                                     &tcReq,
397                                     &cpuRdReq,
398                                     &cpuWrReq,
399                                     &dspReq,
400                                     &ioReq,
401                                     &viReq,
402                                     &peReq,
403                                     &rfReq,
404                                     &fiReq );
405             }
406             else if (Stat[curStat].stat_type == PIX_PERF)
407             {
408                 GXReadPixMetric(&topPixIn, &topPixOut, &botPixIn, &botPixOut,
409                                 &clrPixIn, &copyClks);
410             }
411             else // vcache stats
412             {
413                 GXReadVCacheMetric(&vcCheck, &vcMiss, &vcStall);
414             }
415 
416             // turn off FIFO reads.
417             if (fillFifo)
418             {
419                 OSStopStopwatch(&myGpTime);
420                 // GP fifo is already empty, waitFifo is empty and no one
421                 // will write to it when fillFifo is true.  This is how
422                 // we keep the GP waiting until newFifo is ready.
423                 GXFlush();
424                 GXGetGPFifo(&tmpFifo);
425                 if ( GXGetFifoBase(&tmpFifo) != GXGetFifoBase(&waitFifo) )
426                     GXSetGPFifo(&waitFifo);
427 
428                 // make cpu fifo = wait fifo, so next time through we can
429                 // reset the pointer to the top.
430                 GXGetCPUFifo(&tmpFifo);
431                 if ( GXGetFifoBase(&tmpFifo) != GXGetFifoBase(&waitFifo))
432                     GXSetCPUFifo(&waitFifo);
433             }
434 
435             DEMODoneRender();
436             curStat++;
437         }
438 
439         DumpStats();
440         Test++;
441     }
442 
443     OSHalt("End of demo");
444 }
445 
446 /*---------------------------------------------------------------------------*
447    Functions
448  *---------------------------------------------------------------------------*/
449 
450 
451 /*---------------------------------------------------------------------------*
452     Name:           CameraInit
453 
454     Description:    Initialize the projection matrix and load into hardware.
455 
456     Arguments:      v   view matrix to be passed to ViewInit
457                     cameraLocScale  scale for the camera's distance from the
458                                     object - to be passed to ViewInit
459 
460     Returns:        none
461  *---------------------------------------------------------------------------*/
462 static
CameraInit(void)463 void CameraInit      ( void )
464 {
465     Mtx44 p;
466     Vec camPt  = {0.0F, 0.0F, 650.0F};
467     Vec up     = {0.0F, 1.0F, 0.0F};
468     Vec origin = {0.0F, 0.0F, -100.0F};
469 
470     MTXFrustum(p, 240, -240, -320, 320, 500, 2000);
471 
472     GXSetProjection(p, GX_PERSPECTIVE);
473 
474     MTXLookAt(v, &camPt, &up, &origin);
475 }
476 
477 /*---------------------------------------------------------------------------*
478     Name:           DrawInit
479 
480     Description:    Calls the correct initialization function for the current
481                     model.
482 
483     Arguments:      none
484 
485     Returns:        none
486  *---------------------------------------------------------------------------*/
487 static
DrawInit(void)488 void DrawInit( void )
489 {
490     GXLightObj MyLight;
491     GXColor color = {0, 255, 255, 255};
492     GXTexObj      texObj;  // texture object
493     TPLPalettePtr tpl = 0; // texture palette
494 
495     GXSetCullMode(GX_CULL_ALL);
496 
497     // constant matrix, just want to see load performance
498     CameraInit();   // Initialize the camera (v)
499     MTXTrans(mv, 0, 0, 0);
500     MTXConcat(v, mv, mv);
501 
502     GXSetCurrentMtx(0);
503 
504     GXInitLightPos(&MyLight, 0.0F, 0.0F, 0.0F);
505     GXInitLightColor(&MyLight, color);
506     GXLoadLightObjImm(&MyLight, GX_LIGHT0);
507 
508     GXSetChanMatColor(GX_COLOR0A0, color);
509     //  Load the texture palette
510     TPLGetPalette(&tpl, "gxTextrs.tpl");
511     //  Initialize a texture object to contain the correct texture
512     TPLGetGXTexObjFromPalette(tpl, &texObj, BALL64_TEX_ID);
513     //  Load the texture object; tex0 is used in stage 0
514     GXLoadTexObj(&texObj, GX_TEXMAP0);
515 
516     GXSetNumTevStages(1);
517 
518     GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
519     GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
520     GXSetTevOp(GX_TEVSTAGE0, GX_MODULATE);
521 
522     GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR);
523 
524     GXSetArray(GX_VA_POS,  Vert,     sizeof(f32)*3);
525     GXSetArray(GX_VA_NRM,  Norm,     sizeof(f32)*3);
526     GXSetArray(GX_VA_CLR0, MyColors, sizeof(u32));
527     GXSetArray(GX_VA_TEX0, TexCoord, sizeof(f32)*2);
528 
529     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
530     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
531     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
532     GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
533 
534     //GXDrawDone(); // make sure state is in GP
535 }
536 
537 
538 
539 /*---------------------------------------------------------------------------*
540     Name:           DrawTick
541 
542     Description:    Draws cubes
543 
544     Arguments:      none
545 
546     Returns:        none
547  *---------------------------------------------------------------------------*/
548 static
DrawTick(void)549 void DrawTick( void )
550 {
551     u32 i, j; // indices
552 
553     if (testData[Test].type == CUBE_IDX)
554     {
555         //OSReport("Using indexed data, tex and lit\n");
556         GXSetNumChans(1);
557         GXSetNumTexGens(1);
558 
559         GXSetChanCtrl(
560                 GX_COLOR0A0,
561                 GX_ENABLE,      // enable channel
562                 GX_SRC_REG,     // amb source
563                 GX_SRC_VTX,     // mat source
564                 GX_LIGHT0,      // light mask
565                 GX_DF_NONE,     // diffuse function
566                 GX_AF_NONE);
567 
568         GXClearVtxDesc();
569         GXSetVtxDesc(GX_VA_POS,  GX_INDEX16);
570         GXSetVtxDesc(GX_VA_NRM,  GX_INDEX8);
571         GXSetVtxDesc(GX_VA_CLR0, GX_INDEX8);
572         GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8);
573         testDraw = DrawCubeIndx;
574     }
575     else if (testData[Test].type == CUBE_DIR)
576     {
577         //OSReport("Using direct data, tex and lit\n");
578         GXSetNumChans(1);
579         GXSetNumTexGens(1);
580 
581         GXSetChanCtrl(
582                 GX_COLOR0A0,
583                 GX_ENABLE,      // enable channel
584                 GX_SRC_REG,     // amb source
585                 GX_SRC_VTX,     // mat source
586                 GX_LIGHT0,      // light mask
587                 GX_DF_NONE,     // diffuse function
588                 GX_AF_NONE);
589 
590         GXClearVtxDesc();
591         GXSetVtxDesc(GX_VA_POS,  GX_DIRECT);
592         GXSetVtxDesc(GX_VA_NRM,  GX_DIRECT);
593         GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
594         GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
595         testDraw = DrawCubeDirect;
596     }
597     else if (testData[Test].type == CUBE_TEX_IDX)
598     {
599         //OSReport("Using indexed data, tex-only\n");
600         GXSetNumChans(0);
601         GXSetNumTexGens(1);
602 
603         GXSetChanCtrl(
604                 GX_COLOR0A0,
605                 GX_DISABLE,     // enable channel
606                 GX_SRC_REG,     // amb source
607                 GX_SRC_REG,     // mat source
608                 GX_LIGHT0,      // light mask
609                 GX_DF_NONE,     // diffuse function
610                 GX_AF_NONE);
611 
612         GXClearVtxDesc();
613         GXSetVtxDesc(GX_VA_POS,  GX_INDEX16);
614         GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8);
615         testDraw = DrawTexCubeIndx;
616     }
617     else if (testData[Test].type == CUBE_TEX_DIR)
618     {
619         //OSReport("Using direct data, tex-only\n");
620         GXSetNumChans(0);
621         GXSetNumTexGens(1);
622 
623         GXSetChanCtrl(
624                 GX_COLOR0A0,
625                 GX_DISABLE,     // enable channel
626                 GX_SRC_REG,     // amb source
627                 GX_SRC_REG,     // mat source
628                 GX_LIGHT0,      // light mask
629                 GX_DF_NONE,     // diffuse function
630                 GX_AF_NONE);
631 
632         GXClearVtxDesc();
633         GXSetVtxDesc(GX_VA_POS,  GX_DIRECT);
634         GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
635         testDraw = DrawTexCubeDirect;
636     }
637 
638 
639     for (i = 0; i < testData[Test].nloops; i++)
640     {
641         for (j = 0; j < testData[Test].nmtx; j++)
642         {
643             GXLoadPosMtxImm(mv, 0);
644             GXLoadNrmMtxImm(mv, 0);
645         }
646         for (j = 0; j < testData[Test].ncubes; j++)
647         {
648             testDraw();
649         }
650     }
651 }
652 
653 /*---------------------------------------------------------------------------*
654     Name:           DumpStats
655 
656     Description:    Print current counters to stdout
657 
658     Arguments:      none
659 
660     Returns:        none
661  *---------------------------------------------------------------------------*/
662 static
DumpStats(void)663 void DumpStats( void )
664 {
665     u32 i;
666 
667         OSReport("******** Test %3d ********\n", Test);
668 
669         if (testData[Test].fill)
670             OSReport("Fill FIFO before rendering\n");
671         else
672             OSReport("Write to FIFO while rendering\n");
673 
674         switch (testData[Test].type)
675         {
676             case CUBE_DIR: OSReport("Direct data, tex and lit\n"); break;
677             case CUBE_IDX: OSReport("Indirect data, tex and lit\n"); break;
678             case CUBE_TEX_DIR: OSReport("Direct data, tex only\n"); break;
679             case CUBE_TEX_IDX: OSReport("Indirect data, tex only\n"); break;
680         }
681 
682         OSReport("Number of loops.......... %8d\n", testData[Test].nloops);
683         OSReport("Number of cubes.......... %8d\n", testData[Test].ncubes);
684         OSReport("Number of matrices/cube.. %8d\n", testData[Test].nmtx);
685 
686         for (i = 0; i < N_STATS; i++)
687         {
688             if (Stat[i].stat_type == PIX_PERF)
689             {
690                 OSReport("Top pixels in..............:   %8d\n", topPixIn);
691                 OSReport("Top pixels out.............:   %8d\n", topPixOut);
692                 OSReport("Bot pixels in..............:   %8d\n", botPixIn);
693                 OSReport("Bot pixels out.............:   %8d\n", botPixOut);
694                 OSReport("Clr pixels in..............:   %8d\n", clrPixIn);
695                 OSReport("Copy clocks................:   %8d\n", copyClks);
696             }
697             else if (Stat[i].stat_type == VC_PERF)
698             {
699                 OSReport("Vcache checks..............:   %8d\n", vcCheck);
700                 OSReport("Vcache misses..............:   %8d\n", vcMiss);
701                 OSReport("Vcache stalls..............:   %8d\n", vcStall);
702             }
703             else if (Stat[i].stat_type == MEM_PERF)
704             {
705                 OSReport("CP requests................:   %8d\n", cpReq);
706                 OSReport("TC requests................:   %8d\n", tcReq);
707                 OSReport("CPU Rd requests............:   %8d\n", cpuRdReq);
708                 OSReport("CPU Wr requests............:   %8d\n", cpuWrReq);
709                 OSReport("DSP requests...............:   %8d\n", dspReq);
710                 OSReport("IO requests................:   %8d\n", ioReq);
711                 OSReport("VI requests................:   %8d\n", viReq);
712                 OSReport("PE requests................:   %8d\n", peReq);
713                 OSReport("RF requests................:   %8d\n", rfReq);
714                 OSReport("FI requests................:   %8d\n", fiReq);
715             }
716             else
717                 OSReport("%s:   %8d\n", Stat[i].text, Stat[i].cnt);
718         }
719 
720 
721         if (testData[Test].fill)
722         {
723             OSDumpStopwatch(&myCpuTime);
724             OSDumpStopwatch(&myGpTime);
725         }
726         OSDumpStopwatch(&myTotTime);
727 }
728 
729 
730 /*---------------------------------------------------------------------------*
731     Name:           PrintIntro
732 
733     Description:    Print usage for test
734 
735     Arguments:      none
736 
737     Returns:        none
738  *---------------------------------------------------------------------------*/
739 static
PrintIntro(void)740 void PrintIntro( void )
741 {
742     OSReport("\n\n********************************\n");
743     OSReport(" Check immediate mode performance\n");
744     OSReport(" Check transform performance\n");
745     OSReport("\n");
746     OSReport(" This test outputs only text info\n");
747     OSReport("************************************\n");
748 }
749 
750 /*---------------------------------------------------------------------------*
751     Name:           checkForOverflow
752 
753     Description:    return overflow bit of newFifo
754 
755     Arguments:      none
756 
757     Returns:        none
758  *---------------------------------------------------------------------------*/
759 static u32
checkForOverflow(void)760 checkForOverflow( void )
761 {
762 #if 0
763     GXBool overhi, underlow;
764     GXBool cpu_write, gp_read, fifowrap;
765     u32    fifo_cnt;
766 
767     GXGetFifoStatus(&newFifo, &overhi, &underlow, &fifo_cnt, &cpu_write,
768                     &gp_read, &fifowrap);
769 
770     return ((u32)fifowrap);
771 #endif
772     return 0;
773 }
774 
775 /*---------------------------------------------------------------------------*
776     Name:           DrawCubeIndx
777 
778     Description:
779 
780     Arguments:      none
781 
782     Returns:        none
783  *---------------------------------------------------------------------------*/
784 static
DrawCubeIndx(void)785 void DrawCubeIndx( void )
786 {
787     GXBegin(GX_QUADS, GX_VTXFMT0, 4*6);
788         GXPosition1x16(4);
789         GXNormal1x8(0);
790         GXColor1x8(0);
791         GXTexCoord1x8(0); //
792         GXPosition1x16(5);
793         GXNormal1x8(0);
794         GXColor1x8(0);
795         GXTexCoord1x8(1); //
796         GXPosition1x16(6);
797         GXNormal1x8(0);
798         GXColor1x8(0);
799         GXTexCoord1x8(2); //
800         GXPosition1x16(7);
801         GXNormal1x8(0);
802         GXColor1x8(0);
803         GXTexCoord1x8(3); //
804 
805         GXPosition1x16(2);
806         GXNormal1x8(0);
807         GXColor1x8(1);
808         GXTexCoord1x8(0); //
809         GXPosition1x16(6);
810         GXNormal1x8(0);
811         GXColor1x8(1);
812         GXTexCoord1x8(1); //
813         GXPosition1x16(5);
814         GXNormal1x8(0);
815         GXColor1x8(1);
816         GXTexCoord1x8(2); //
817         GXPosition1x16(3);
818         GXNormal1x8(0);
819         GXColor1x8(1);
820         GXTexCoord1x8(3); //
821 
822         GXPosition1x16(1);
823         GXNormal1x8(0);
824         GXColor1x8(2);
825         GXTexCoord1x8(0); //
826         GXPosition1x16(0);
827         GXNormal1x8(0);
828         GXColor1x8(2);
829         GXTexCoord1x8(1); //
830         GXPosition1x16(4);
831         GXNormal1x8(0);
832         GXColor1x8(2);
833         GXTexCoord1x8(2); //
834         GXPosition1x16(7);
835         GXNormal1x8(0);
836         GXColor1x8(2);
837         GXTexCoord1x8(3); //
838 
839         GXPosition1x16(0);
840         GXNormal1x8(0);
841         GXColor1x8(3);
842         GXTexCoord1x8(0); //
843         GXPosition1x16(1);
844         GXNormal1x8(0);
845         GXColor1x8(3);
846         GXTexCoord1x8(1); //
847         GXPosition1x16(2);
848         GXNormal1x8(0);
849         GXColor1x8(3);
850         GXTexCoord1x8(2); //
851         GXPosition1x16(3);
852         GXNormal1x8(0);
853         GXColor1x8(3);
854         GXTexCoord1x8(3); //
855 
856         GXPosition1x16(5);
857         GXNormal1x8(0);
858         GXColor1x8(4);
859         GXTexCoord1x8(0); //
860         GXPosition1x16(4);
861         GXNormal1x8(0);
862         GXColor1x8(4);
863         GXTexCoord1x8(1); //
864         GXPosition1x16(0);
865         GXNormal1x8(0);
866         GXColor1x8(4);
867         GXTexCoord1x8(2); //
868         GXPosition1x16(3);
869         GXNormal1x8(0);
870         GXColor1x8(4);
871         GXTexCoord1x8(3); //
872 
873         GXPosition1x16(6);
874         GXNormal1x8(0);
875         GXColor1x8(5);
876         GXTexCoord1x8(0); //
877         GXPosition1x16(2);
878         GXNormal1x8(0);
879         GXColor1x8(5);
880         GXTexCoord1x8(1); //
881         GXPosition1x16(1);
882         GXNormal1x8(0);
883         GXColor1x8(5);
884         GXTexCoord1x8(2); //
885         GXPosition1x16(7);
886         GXNormal1x8(0);
887         GXColor1x8(5);
888         GXTexCoord1x8(3); //
889 
890     GXEnd();
891 }
892 
893 /*---------------------------------------------------------------------------*
894     Name:           DrawCubeDirect
895 
896     Description:
897 
898     Arguments:      none
899 
900     Returns:        none
901  *---------------------------------------------------------------------------*/
902 static
DrawCubeDirect(void)903 void DrawCubeDirect( void )
904 {
905     GXBegin(GX_QUADS, GX_VTXFMT0, 4*6);
906         GXPosition3f32( SIDE, SIDE, -SIDE); //4
907         GXNormal3f32( SIDE, SIDE, -SIDE); //4
908         GXColor1u32(0xff0000ff);// red
909         GXTexCoord2f32(0.0F, 0.0F);//
910         GXPosition3f32(SIDE, -SIDE, -SIDE);//5
911         GXNormal3f32( SIDE, SIDE, -SIDE); //4
912         GXColor1u32(0xff0000ff);// red
913         GXTexCoord2f32(1.0F, 0.0F);//
914         GXPosition3f32(SIDE, -SIDE, SIDE); //6
915         GXNormal3f32( SIDE, SIDE, -SIDE); //4
916         GXColor1u32(0xff0000ff);// red
917         GXTexCoord2f32(1.0F, 1.0F);//
918         GXPosition3f32(SIDE, SIDE, SIDE);  //7
919         GXNormal3f32( SIDE, SIDE, -SIDE); //4
920         GXColor1u32(0xff0000ff);// red
921         GXTexCoord2f32(0.0F, 1.0F);//
922 
923         GXPosition3f32(-SIDE, -SIDE, SIDE);//2
924         GXNormal3f32( SIDE, SIDE, -SIDE); //4
925         GXColor1u32(0x00ff00ff);// green
926         GXTexCoord2f32(0.0F, 0.0F);//
927         GXPosition3f32(SIDE, -SIDE, SIDE); //6
928         GXNormal3f32( SIDE, SIDE, -SIDE); //4
929         GXColor1u32(0x00ff00ff);// green
930         GXTexCoord2f32(1.0F, 0.0F);//
931         GXPosition3f32(SIDE, -SIDE, -SIDE);//5
932         GXNormal3f32( SIDE, SIDE, -SIDE); //4
933         GXColor1u32(0x00ff00ff);// green
934         GXTexCoord2f32(1.0F, 1.0F);//
935         GXPosition3f32(-SIDE, -SIDE, -SIDE);//3
936         GXNormal3f32( SIDE, SIDE, -SIDE); //4
937         GXColor1u32(0x00ff00ff);// green
938         GXTexCoord2f32(0.0F, 1.0F);//
939 
940         GXPosition3f32(-SIDE, SIDE, SIDE); //1
941         GXNormal3f32( SIDE, SIDE, -SIDE); //4
942         GXColor1u32(0x0000ffff);// blue
943         GXTexCoord2f32(0.0F, 0.0F);//
944         GXPosition3f32(-SIDE, SIDE, -SIDE);//0
945         GXNormal3f32( SIDE, SIDE, -SIDE); //4
946         GXColor1u32(0x0000ffff);// blue
947         GXTexCoord2f32(1.0F, 0.0F);//
948         GXPosition3f32( SIDE, SIDE, -SIDE); //4
949         GXNormal3f32( SIDE, SIDE, -SIDE); //4
950         GXColor1u32(0x0000ffff);// blue
951         GXTexCoord2f32(1.0F, 1.0F);//
952         GXPosition3f32(SIDE, SIDE, SIDE);  //7
953         GXNormal3f32( SIDE, SIDE, -SIDE); //4
954         GXColor1u32(0x0000ffff);// blue
955         GXTexCoord2f32(0.0F, 1.0F);//
956 
957         GXPosition3f32(-SIDE, SIDE, -SIDE);//0
958         GXNormal3f32( SIDE, SIDE, -SIDE); //4
959         GXColor1u32(0xffff00ff);// yellow
960         GXTexCoord2f32(0.0F, 0.0F);//
961         GXPosition3f32(-SIDE, SIDE, SIDE); //1
962         GXNormal3f32( SIDE, SIDE, -SIDE); //4
963         GXColor1u32(0xffff00ff);// yellow
964         GXTexCoord2f32(1.0F, 0.0F);//
965         GXPosition3f32(-SIDE, -SIDE, SIDE);//2
966         GXNormal3f32( SIDE, SIDE, -SIDE); //4
967         GXColor1u32(0xffff00ff);// yellow
968         GXTexCoord2f32(1.0F, 1.0F);//
969         GXPosition3f32(-SIDE, -SIDE, -SIDE);//3
970         GXNormal3f32( SIDE, SIDE, -SIDE); //4
971         GXColor1u32(0xffff00ff);// yellow
972         GXTexCoord2f32(0.0F, 1.0F);//
973 
974         GXPosition3f32(SIDE, -SIDE, -SIDE);//5
975         GXNormal3f32( SIDE, SIDE, -SIDE); //4
976         GXColor1u32(0xff00ffff);// magenta
977         GXTexCoord2f32(0.0F, 0.0F);//
978         GXPosition3f32( SIDE, SIDE, -SIDE); //4
979         GXNormal3f32( SIDE, SIDE, -SIDE); //4
980         GXColor1u32(0xff00ffff);// magenta
981         GXTexCoord2f32(1.0F, 0.0F);//
982         GXPosition3f32(-SIDE, SIDE, -SIDE);//0
983         GXNormal3f32( SIDE, SIDE, -SIDE); //4
984         GXColor1u32(0xff00ffff);// magenta
985         GXTexCoord2f32(1.0F, 1.0F);//
986         GXPosition3f32(-SIDE, -SIDE, -SIDE);//3
987         GXNormal3f32( SIDE, SIDE, -SIDE); //4
988         GXColor1u32(0xff00ffff);// magenta
989         GXTexCoord2f32(0.0F, 1.0F);//
990 
991         GXPosition3f32(SIDE, -SIDE, SIDE); //6
992         GXNormal3f32( SIDE, SIDE, -SIDE); //4
993         GXColor1u32(0x00ffffff);// cyan
994         GXTexCoord2f32(0.0F, 0.0F);//
995         GXPosition3f32(-SIDE, -SIDE, SIDE);//2
996         GXNormal3f32( SIDE, SIDE, -SIDE); //4
997         GXColor1u32(0x00ffffff);// cyan
998         GXTexCoord2f32(1.0F, 0.0F);//
999         GXPosition3f32(-SIDE, SIDE, SIDE); //1
1000         GXNormal3f32( SIDE, SIDE, -SIDE); //4
1001         GXColor1u32(0x00ffffff);// cyan
1002         GXTexCoord2f32(1.0F, 1.0F);//
1003         GXPosition3f32(SIDE, SIDE, SIDE);  //7
1004         GXNormal3f32( SIDE, SIDE, -SIDE); //4
1005         GXColor1u32(0x00ffffff);// cyan
1006         GXTexCoord2f32(0.0F, 1.0F);//
1007     GXEnd();
1008 }
1009 
1010 
1011 /*---------------------------------------------------------------------------*
1012     Name:           DrawTexCubeIndx
1013 
1014     Description:
1015 
1016     Arguments:      none
1017 
1018     Returns:        none
1019  *---------------------------------------------------------------------------*/
1020 static
DrawTexCubeIndx(void)1021 void DrawTexCubeIndx( void )
1022 {
1023     GXBegin(GX_QUADS, GX_VTXFMT0, 4*6);
1024         GXPosition1x16(4);
1025         GXTexCoord1x8(0); //
1026         GXPosition1x16(5);
1027         GXTexCoord1x8(1); //
1028         GXPosition1x16(6);
1029         GXTexCoord1x8(2); //
1030         GXPosition1x16(7);
1031         GXTexCoord1x8(3); //
1032 
1033         GXPosition1x16(2);
1034         GXTexCoord1x8(0); //
1035         GXPosition1x16(6);
1036         GXTexCoord1x8(1); //
1037         GXPosition1x16(5);
1038         GXTexCoord1x8(2); //
1039         GXPosition1x16(3);
1040         GXTexCoord1x8(3); //
1041 
1042         GXPosition1x16(1);
1043         GXTexCoord1x8(0); //
1044         GXPosition1x16(0);
1045         GXTexCoord1x8(1); //
1046         GXPosition1x16(4);
1047         GXTexCoord1x8(2); //
1048         GXPosition1x16(7);
1049         GXTexCoord1x8(3); //
1050 
1051         GXPosition1x16(0);
1052         GXTexCoord1x8(0); //
1053         GXPosition1x16(1);
1054         GXTexCoord1x8(1); //
1055         GXPosition1x16(2);
1056         GXTexCoord1x8(2); //
1057         GXPosition1x16(3);
1058         GXTexCoord1x8(3); //
1059 
1060         GXPosition1x16(5);
1061         GXTexCoord1x8(0); //
1062         GXPosition1x16(4);
1063         GXTexCoord1x8(1); //
1064         GXPosition1x16(0);
1065         GXTexCoord1x8(2); //
1066         GXPosition1x16(3);
1067         GXTexCoord1x8(3); //
1068 
1069         GXPosition1x16(6);
1070         GXTexCoord1x8(0); //
1071         GXPosition1x16(2);
1072         GXTexCoord1x8(1); //
1073         GXPosition1x16(1);
1074         GXTexCoord1x8(2); //
1075         GXPosition1x16(7);
1076         GXTexCoord1x8(3); //
1077 
1078     GXEnd();
1079 }
1080 
1081 /*---------------------------------------------------------------------------*
1082     Name:           DrawTexCubeDirect
1083 
1084     Description:
1085 
1086     Arguments:      none
1087 
1088     Returns:        none
1089  *---------------------------------------------------------------------------*/
1090 static
DrawTexCubeDirect(void)1091 void DrawTexCubeDirect( void )
1092 {
1093     GXBegin(GX_QUADS, GX_VTXFMT0, 4*6);
1094         GXPosition3f32( SIDE, SIDE, -SIDE); //4
1095         GXTexCoord2f32(0.0F, 0.0F);//
1096         GXPosition3f32(SIDE, -SIDE, -SIDE);//5
1097         GXTexCoord2f32(1.0F, 0.0F);//
1098         GXPosition3f32(SIDE, -SIDE, SIDE); //6
1099         GXTexCoord2f32(1.0F, 1.0F);//
1100         GXPosition3f32(SIDE, SIDE, SIDE);  //7
1101         GXTexCoord2f32(0.0F, 1.0F);//
1102 
1103         GXPosition3f32(-SIDE, -SIDE, SIDE);//2
1104         GXTexCoord2f32(0.0F, 0.0F);//
1105         GXPosition3f32(SIDE, -SIDE, SIDE); //6
1106         GXTexCoord2f32(1.0F, 0.0F);//
1107         GXPosition3f32(SIDE, -SIDE, -SIDE);//5
1108         GXTexCoord2f32(1.0F, 1.0F);//
1109         GXPosition3f32(-SIDE, -SIDE, -SIDE);//3
1110         GXTexCoord2f32(0.0F, 1.0F);//
1111 
1112         GXPosition3f32(-SIDE, SIDE, SIDE); //1
1113         GXTexCoord2f32(0.0F, 0.0F);//
1114         GXPosition3f32(-SIDE, SIDE, -SIDE);//0
1115         GXTexCoord2f32(1.0F, 0.0F);//
1116         GXPosition3f32( SIDE, SIDE, -SIDE); //4
1117         GXTexCoord2f32(1.0F, 1.0F);//
1118         GXPosition3f32(SIDE, SIDE, SIDE);  //7
1119         GXTexCoord2f32(0.0F, 1.0F);//
1120 
1121         GXPosition3f32(-SIDE, SIDE, -SIDE);//0
1122         GXTexCoord2f32(0.0F, 0.0F);//
1123         GXPosition3f32(-SIDE, SIDE, SIDE); //1
1124         GXTexCoord2f32(1.0F, 0.0F);//
1125         GXPosition3f32(-SIDE, -SIDE, SIDE);//2
1126         GXTexCoord2f32(1.0F, 1.0F);//
1127         GXPosition3f32(-SIDE, -SIDE, -SIDE);//3
1128         GXTexCoord2f32(0.0F, 1.0F);//
1129 
1130         GXPosition3f32(SIDE, -SIDE, -SIDE);//5
1131         GXTexCoord2f32(0.0F, 0.0F);//
1132         GXPosition3f32( SIDE, SIDE, -SIDE); //4
1133         GXTexCoord2f32(1.0F, 0.0F);//
1134         GXPosition3f32(-SIDE, SIDE, -SIDE);//0
1135         GXTexCoord2f32(1.0F, 1.0F);//
1136         GXPosition3f32(-SIDE, -SIDE, -SIDE);//3
1137         GXTexCoord2f32(0.0F, 1.0F);//
1138 
1139         GXPosition3f32(SIDE, -SIDE, SIDE); //6
1140         GXTexCoord2f32(0.0F, 0.0F);//
1141         GXPosition3f32(-SIDE, -SIDE, SIDE);//2
1142         GXTexCoord2f32(1.0F, 0.0F);//
1143         GXPosition3f32(-SIDE, SIDE, SIDE); //1
1144         GXTexCoord2f32(1.0F, 1.0F);//
1145         GXPosition3f32(SIDE, SIDE, SIDE);  //7
1146         GXTexCoord2f32(0.0F, 1.0F);//
1147     GXEnd();
1148 }
1149