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 GXGetCPUFifo(&waitFifo);
271 Test = 0;
272
273 while (Test != N_TESTS)
274 {
275 OSResetStopwatch(&myTotTime);
276 OSResetStopwatch(&myCpuTime);
277 OSResetStopwatch(&myGpTime);
278
279 fillFifo = testData[Test].fill;
280 curStat = 0;
281 while (curStat != N_STATS)
282 {
283 DEMOBeforeRender();
284
285 //
286 // Enable various statistics
287 // clear counters
288 //
289 if (Stat[curStat].stat_type == GP_PERF0)
290 {
291 GXSetGP0Metric((GXPerf0)Stat[curStat].stat);
292 GXClearGP0Metric();
293 }
294 else if (Stat[curStat].stat_type == GP_PERF1)
295 {
296 GXSetGP1Metric((GXPerf1)Stat[curStat].stat);
297 GXClearGP1Metric();
298 }
299 else if (Stat[curStat].stat_type == MEM_PERF)
300 {
301 GXClearMemMetric();
302 }
303 else if (Stat[curStat].stat_type == PIX_PERF)
304 {
305 GXClearPixMetric();
306 }
307 else // vcache stat
308 {
309 GXSetVCacheMetric(GX_VC_ALL);
310 GXClearVCacheMetric();
311 }
312
313 // make sure all GX commands to here are flushed
314 GXGetCPUFifo(&tmpFifo);
315
316 // choose normal immediate mode or delayed immediate mode
317 if (fillFifo)
318 {
319 // set new FIFO
320 if (GXGetFifoBase(&tmpFifo) != GXGetFifoBase(&newFifo))
321 {
322 // reset read/write pointers
323 GXInitFifoPtrs(&newFifo,
324 GXGetFifoBase(&newFifo),
325 GXGetFifoBase(&newFifo));
326 GXSetCPUFifo(&newFifo);
327 }
328 OSStartStopwatch(&myCpuTime);
329 }
330 else
331 {
332 // reset read write pointers
333 if (GXGetFifoBase(&tmpFifo) != GXGetFifoBase(&waitFifo))
334 {
335 GXInitFifoPtrs(&waitFifo,
336 GXGetFifoBase(&waitFifo),
337 GXGetFifoBase(&waitFifo));
338 // set new FIFO
339 GXSetCPUFifo(&waitFifo);
340 }
341 }
342
343 OSStartStopwatch(&myTotTime);
344
345
346 DrawTick();
347
348 // turn on FIFO reads after whole FIFO is filled
349 if (fillFifo)
350 {
351 // push all data out
352 GXFlush();
353 OSStopStopwatch(&myCpuTime); // CPU is done here
354
355 // make sure we are in the newFifo limits
356 if (checkForOverflow())
357 OSHalt("Error, FIFO overflowed");
358
359 // switch to new fifo
360 if ( !GXIsCPUGPFifoLinked() )
361 {
362 GXGetCPUFifo(&tmpFifo);
363 GXSetGPFifo(&tmpFifo);
364 }
365
366 OSStartStopwatch(&myGpTime); // GP starts here
367 }
368
369 GXDrawDone(); // wait for GP to be done
370 // GXDrawDone does flush too
371
372 //GXGetFifoPtrs(GXGetCPUFifo(), &readPtr1, &writePtr1);
373 //OSReport("Write pointer, after loop: %08x\n", writePtr1);
374 //OSReport("Diff: %8d (cache lines)\n",
375 // ((u32)writePtr1 - (u32)writePtr0) / 32);
376
377 OSStopStopwatch(&myTotTime);
378
379 //
380 // Read back various statistics
381 //
382 if (Stat[curStat].stat_type == GP_PERF0)
383 {
384 Stat[curStat].cnt = GXReadGP0Metric();
385 }
386 else if (Stat[curStat].stat_type == GP_PERF1)
387 {
388 Stat[curStat].cnt = GXReadGP1Metric();
389 }
390 else if (Stat[curStat].stat_type == MEM_PERF)
391 {
392 GXReadMemMetric ( &cpReq,
393 &tcReq,
394 &cpuRdReq,
395 &cpuWrReq,
396 &dspReq,
397 &ioReq,
398 &viReq,
399 &peReq,
400 &rfReq,
401 &fiReq );
402 }
403 else if (Stat[curStat].stat_type == PIX_PERF)
404 {
405 GXReadPixMetric(&topPixIn, &topPixOut, &botPixIn, &botPixOut,
406 &clrPixIn, ©Clks);
407 }
408 else // vcache stats
409 {
410 GXReadVCacheMetric(&vcCheck, &vcMiss, &vcStall);
411 }
412
413 // turn off FIFO reads.
414 if (fillFifo)
415 {
416 OSStopStopwatch(&myGpTime);
417 // GP fifo is already empty, waitFifo is empty and no one
418 // will write to it when fillFifo is true. This is how
419 // we keep the GP waiting until newFifo is ready.
420 GXGetGPFifo(&tmpFifo);
421 if ( GXGetFifoBase(&tmpFifo) != GXGetFifoBase(&waitFifo) )
422 GXSetGPFifo(&waitFifo);
423
424 // make cpu fifo = wait fifo, so next time through we can
425 // reset the pointer to the top.
426 GXGetCPUFifo(&tmpFifo);
427 if ( GXGetFifoBase(&tmpFifo) != GXGetFifoBase(&waitFifo))
428 GXSetCPUFifo(&waitFifo);
429 }
430
431 DEMODoneRender();
432 curStat++;
433 }
434
435 DumpStats();
436 Test++;
437 }
438
439 OSHalt("End of demo");
440 }
441
442 /*---------------------------------------------------------------------------*
443 Functions
444 *---------------------------------------------------------------------------*/
445
446
447 /*---------------------------------------------------------------------------*
448 Name: CameraInit
449
450 Description: Initialize the projection matrix and load into hardware.
451
452 Arguments: v view matrix to be passed to ViewInit
453 cameraLocScale scale for the camera's distance from the
454 object - to be passed to ViewInit
455
456 Returns: none
457 *---------------------------------------------------------------------------*/
458 static
CameraInit(void)459 void CameraInit ( void )
460 {
461 Mtx44 p;
462 Vec camPt = {0.0F, 0.0F, 650.0F};
463 Vec up = {0.0F, 1.0F, 0.0F};
464 Vec origin = {0.0F, 0.0F, -100.0F};
465
466 MTXFrustum(p, 240, -240, -320, 320, 500, 2000);
467
468 GXSetProjection(p, GX_PERSPECTIVE);
469
470 MTXLookAt(v, &camPt, &up, &origin);
471 }
472
473 /*---------------------------------------------------------------------------*
474 Name: DrawInit
475
476 Description: Calls the correct initialization function for the current
477 model.
478
479 Arguments: none
480
481 Returns: none
482 *---------------------------------------------------------------------------*/
483 static
DrawInit(void)484 void DrawInit( void )
485 {
486 GXLightObj MyLight;
487 GXColor color = {0, 255, 255, 255};
488 GXTexObj texObj; // texture object
489 TPLPalettePtr tpl = 0; // texture palette
490
491 GXSetCullMode(GX_CULL_ALL);
492
493 // constant matrix, just want to see load performance
494 CameraInit(); // Initialize the camera (v)
495 MTXTrans(mv, 0, 0, 0);
496 MTXConcat(v, mv, mv);
497
498 GXSetCurrentMtx(0);
499
500 GXInitLightPos(&MyLight, 0.0F, 0.0F, 0.0F);
501 GXInitLightColor(&MyLight, color);
502 GXLoadLightObjImm(&MyLight, GX_LIGHT0);
503
504 GXSetChanMatColor(GX_COLOR0A0, color);
505 // Load the texture palette
506 TPLGetPalette(&tpl, "gxTextrs.tpl");
507 // Initialize a texture object to contain the correct texture
508 TPLGetGXTexObjFromPalette(tpl, &texObj, BALL64_TEX_ID);
509 // Load the texture object; tex0 is used in stage 0
510 GXLoadTexObj(&texObj, GX_TEXMAP0);
511
512 GXSetNumTevStages(1);
513
514 GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
515 GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
516 GXSetTevOp(GX_TEVSTAGE0, GX_MODULATE);
517
518 GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR);
519
520 GXSetArray(GX_VA_POS, Vert, sizeof(f32)*3);
521 GXSetArray(GX_VA_NRM, Norm, sizeof(f32)*3);
522 GXSetArray(GX_VA_CLR0, MyColors, sizeof(u32));
523 GXSetArray(GX_VA_TEX0, TexCoord, sizeof(f32)*2);
524
525 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
526 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
527 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
528 GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
529
530 //GXDrawDone(); // make sure state is in GP
531 }
532
533
534
535 /*---------------------------------------------------------------------------*
536 Name: DrawTick
537
538 Description: Draws cubes
539
540 Arguments: none
541
542 Returns: none
543 *---------------------------------------------------------------------------*/
544 static
DrawTick(void)545 void DrawTick( void )
546 {
547 u32 i, j; // indices
548
549 if (testData[Test].type == CUBE_IDX)
550 {
551 //OSReport("Using indexed data, tex and lit\n");
552 GXSetNumChans(1);
553 GXSetNumTexGens(1);
554
555 GXSetChanCtrl(
556 GX_COLOR0A0,
557 GX_ENABLE, // enable channel
558 GX_SRC_REG, // amb source
559 GX_SRC_VTX, // mat source
560 GX_LIGHT0, // light mask
561 GX_DF_NONE, // diffuse function
562 GX_AF_NONE);
563
564 GXClearVtxDesc();
565 GXSetVtxDesc(GX_VA_POS, GX_INDEX16);
566 GXSetVtxDesc(GX_VA_NRM, GX_INDEX8);
567 GXSetVtxDesc(GX_VA_CLR0, GX_INDEX8);
568 GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8);
569 testDraw = DrawCubeIndx;
570 }
571 else if (testData[Test].type == CUBE_DIR)
572 {
573 //OSReport("Using direct data, tex and lit\n");
574 GXSetNumChans(1);
575 GXSetNumTexGens(1);
576
577 GXSetChanCtrl(
578 GX_COLOR0A0,
579 GX_ENABLE, // enable channel
580 GX_SRC_REG, // amb source
581 GX_SRC_VTX, // mat source
582 GX_LIGHT0, // light mask
583 GX_DF_NONE, // diffuse function
584 GX_AF_NONE);
585
586 GXClearVtxDesc();
587 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
588 GXSetVtxDesc(GX_VA_NRM, GX_DIRECT);
589 GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
590 GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
591 testDraw = DrawCubeDirect;
592 }
593 else if (testData[Test].type == CUBE_TEX_IDX)
594 {
595 //OSReport("Using indexed data, tex-only\n");
596 GXSetNumChans(0);
597 GXSetNumTexGens(1);
598
599 GXSetChanCtrl(
600 GX_COLOR0A0,
601 GX_DISABLE, // enable channel
602 GX_SRC_REG, // amb source
603 GX_SRC_REG, // mat source
604 GX_LIGHT0, // light mask
605 GX_DF_NONE, // diffuse function
606 GX_AF_NONE);
607
608 GXClearVtxDesc();
609 GXSetVtxDesc(GX_VA_POS, GX_INDEX16);
610 GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8);
611 testDraw = DrawTexCubeIndx;
612 }
613 else if (testData[Test].type == CUBE_TEX_DIR)
614 {
615 //OSReport("Using direct data, tex-only\n");
616 GXSetNumChans(0);
617 GXSetNumTexGens(1);
618
619 GXSetChanCtrl(
620 GX_COLOR0A0,
621 GX_DISABLE, // enable channel
622 GX_SRC_REG, // amb source
623 GX_SRC_REG, // mat source
624 GX_LIGHT0, // light mask
625 GX_DF_NONE, // diffuse function
626 GX_AF_NONE);
627
628 GXClearVtxDesc();
629 GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
630 GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
631 testDraw = DrawTexCubeDirect;
632 }
633
634
635 for (i = 0; i < testData[Test].nloops; i++)
636 {
637 for (j = 0; j < testData[Test].nmtx; j++)
638 {
639 GXLoadPosMtxImm(mv, 0);
640 GXLoadNrmMtxImm(mv, 0);
641 }
642 for (j = 0; j < testData[Test].ncubes; j++)
643 {
644 testDraw();
645 }
646 }
647 }
648
649 /*---------------------------------------------------------------------------*
650 Name: DumpStats
651
652 Description: Print current counters to stdout
653
654 Arguments: none
655
656 Returns: none
657 *---------------------------------------------------------------------------*/
658 static
DumpStats(void)659 void DumpStats( void )
660 {
661 u32 i;
662
663 OSReport("******** Test %3d ********\n", Test);
664
665 if (testData[Test].fill)
666 OSReport("Fill FIFO before rendering\n");
667 else
668 OSReport("Write to FIFO while rendering\n");
669
670 switch (testData[Test].type)
671 {
672 case CUBE_DIR: OSReport("Direct data, tex and lit\n"); break;
673 case CUBE_IDX: OSReport("Indirect data, tex and lit\n"); break;
674 case CUBE_TEX_DIR: OSReport("Direct data, tex only\n"); break;
675 case CUBE_TEX_IDX: OSReport("Indirect data, tex only\n"); break;
676 }
677
678 OSReport("Number of loops.......... %8d\n", testData[Test].nloops);
679 OSReport("Number of cubes.......... %8d\n", testData[Test].ncubes);
680 OSReport("Number of matrices/cube.. %8d\n", testData[Test].nmtx);
681
682 for (i = 0; i < N_STATS; i++)
683 {
684 if (Stat[i].stat_type == PIX_PERF)
685 {
686 OSReport("Top pixels in..............: %8d\n", topPixIn);
687 OSReport("Top pixels out.............: %8d\n", topPixOut);
688 OSReport("Bot pixels in..............: %8d\n", botPixIn);
689 OSReport("Bot pixels out.............: %8d\n", botPixOut);
690 OSReport("Clr pixels in..............: %8d\n", clrPixIn);
691 OSReport("Copy clocks................: %8d\n", copyClks);
692 }
693 else if (Stat[i].stat_type == VC_PERF)
694 {
695 OSReport("Vcache checks..............: %8d\n", vcCheck);
696 OSReport("Vcache misses..............: %8d\n", vcMiss);
697 OSReport("Vcache stalls..............: %8d\n", vcStall);
698 }
699 else if (Stat[i].stat_type == MEM_PERF)
700 {
701 OSReport("CP requests................: %8d\n", cpReq);
702 OSReport("TC requests................: %8d\n", tcReq);
703 OSReport("CPU Rd requests............: %8d\n", cpuRdReq);
704 OSReport("CPU Wr requests............: %8d\n", cpuWrReq);
705 OSReport("DSP requests...............: %8d\n", dspReq);
706 OSReport("IO requests................: %8d\n", ioReq);
707 OSReport("VI requests................: %8d\n", viReq);
708 OSReport("PE requests................: %8d\n", peReq);
709 OSReport("RF requests................: %8d\n", rfReq);
710 OSReport("FI requests................: %8d\n", fiReq);
711 }
712 else
713 OSReport("%s: %8d\n", Stat[i].text, Stat[i].cnt);
714 }
715
716
717 if (testData[Test].fill)
718 {
719 OSDumpStopwatch(&myCpuTime);
720 OSDumpStopwatch(&myGpTime);
721 }
722 OSDumpStopwatch(&myTotTime);
723 }
724
725
726 /*---------------------------------------------------------------------------*
727 Name: PrintIntro
728
729 Description: Print usage for test
730
731 Arguments: none
732
733 Returns: none
734 *---------------------------------------------------------------------------*/
735 static
PrintIntro(void)736 void PrintIntro( void )
737 {
738 OSReport("\n\n********************************\n");
739 OSReport(" Check immediate mode performance\n");
740 OSReport(" Check transform performance\n");
741 OSReport("\n");
742 OSReport(" This test outputs only text info\n");
743 OSReport("************************************\n");
744 }
745
746 /*---------------------------------------------------------------------------*
747 Name: checkForOverflow
748
749 Description: return overflow bit of newFifo
750
751 Arguments: none
752
753 Returns: none
754 *---------------------------------------------------------------------------*/
755 static u32
checkForOverflow(void)756 checkForOverflow( void )
757 {
758 #if 0
759 GXBool overhi, underlow;
760 GXBool cpu_write, gp_read, fifowrap;
761 u32 fifo_cnt;
762
763 GXGetFifoStatus(&newFifo, &overhi, &underlow, &fifo_cnt, &cpu_write,
764 &gp_read, &fifowrap);
765
766 return ((u32)fifowrap);
767 #endif
768 return 0;
769 }
770
771 /*---------------------------------------------------------------------------*
772 Name: DrawCubeIndx
773
774 Description:
775
776 Arguments: none
777
778 Returns: none
779 *---------------------------------------------------------------------------*/
780 static
DrawCubeIndx(void)781 void DrawCubeIndx( void )
782 {
783 GXBegin(GX_QUADS, GX_VTXFMT0, 4*6);
784 GXPosition1x16(4);
785 GXNormal1x8(0);
786 GXColor1x8(0);
787 GXTexCoord1x8(0); //
788 GXPosition1x16(5);
789 GXNormal1x8(0);
790 GXColor1x8(0);
791 GXTexCoord1x8(1); //
792 GXPosition1x16(6);
793 GXNormal1x8(0);
794 GXColor1x8(0);
795 GXTexCoord1x8(2); //
796 GXPosition1x16(7);
797 GXNormal1x8(0);
798 GXColor1x8(0);
799 GXTexCoord1x8(3); //
800
801 GXPosition1x16(2);
802 GXNormal1x8(0);
803 GXColor1x8(1);
804 GXTexCoord1x8(0); //
805 GXPosition1x16(6);
806 GXNormal1x8(0);
807 GXColor1x8(1);
808 GXTexCoord1x8(1); //
809 GXPosition1x16(5);
810 GXNormal1x8(0);
811 GXColor1x8(1);
812 GXTexCoord1x8(2); //
813 GXPosition1x16(3);
814 GXNormal1x8(0);
815 GXColor1x8(1);
816 GXTexCoord1x8(3); //
817
818 GXPosition1x16(1);
819 GXNormal1x8(0);
820 GXColor1x8(2);
821 GXTexCoord1x8(0); //
822 GXPosition1x16(0);
823 GXNormal1x8(0);
824 GXColor1x8(2);
825 GXTexCoord1x8(1); //
826 GXPosition1x16(4);
827 GXNormal1x8(0);
828 GXColor1x8(2);
829 GXTexCoord1x8(2); //
830 GXPosition1x16(7);
831 GXNormal1x8(0);
832 GXColor1x8(2);
833 GXTexCoord1x8(3); //
834
835 GXPosition1x16(0);
836 GXNormal1x8(0);
837 GXColor1x8(3);
838 GXTexCoord1x8(0); //
839 GXPosition1x16(1);
840 GXNormal1x8(0);
841 GXColor1x8(3);
842 GXTexCoord1x8(1); //
843 GXPosition1x16(2);
844 GXNormal1x8(0);
845 GXColor1x8(3);
846 GXTexCoord1x8(2); //
847 GXPosition1x16(3);
848 GXNormal1x8(0);
849 GXColor1x8(3);
850 GXTexCoord1x8(3); //
851
852 GXPosition1x16(5);
853 GXNormal1x8(0);
854 GXColor1x8(4);
855 GXTexCoord1x8(0); //
856 GXPosition1x16(4);
857 GXNormal1x8(0);
858 GXColor1x8(4);
859 GXTexCoord1x8(1); //
860 GXPosition1x16(0);
861 GXNormal1x8(0);
862 GXColor1x8(4);
863 GXTexCoord1x8(2); //
864 GXPosition1x16(3);
865 GXNormal1x8(0);
866 GXColor1x8(4);
867 GXTexCoord1x8(3); //
868
869 GXPosition1x16(6);
870 GXNormal1x8(0);
871 GXColor1x8(5);
872 GXTexCoord1x8(0); //
873 GXPosition1x16(2);
874 GXNormal1x8(0);
875 GXColor1x8(5);
876 GXTexCoord1x8(1); //
877 GXPosition1x16(1);
878 GXNormal1x8(0);
879 GXColor1x8(5);
880 GXTexCoord1x8(2); //
881 GXPosition1x16(7);
882 GXNormal1x8(0);
883 GXColor1x8(5);
884 GXTexCoord1x8(3); //
885
886 GXEnd();
887 }
888
889 /*---------------------------------------------------------------------------*
890 Name: DrawCubeDirect
891
892 Description:
893
894 Arguments: none
895
896 Returns: none
897 *---------------------------------------------------------------------------*/
898 static
DrawCubeDirect(void)899 void DrawCubeDirect( void )
900 {
901 GXBegin(GX_QUADS, GX_VTXFMT0, 4*6);
902 GXPosition3f32( SIDE, SIDE, -SIDE); //4
903 GXNormal3f32( SIDE, SIDE, -SIDE); //4
904 GXColor1u32(0xff0000ff);// red
905 GXTexCoord2f32(0.0F, 0.0F);//
906 GXPosition3f32(SIDE, -SIDE, -SIDE);//5
907 GXNormal3f32( SIDE, SIDE, -SIDE); //4
908 GXColor1u32(0xff0000ff);// red
909 GXTexCoord2f32(1.0F, 0.0F);//
910 GXPosition3f32(SIDE, -SIDE, SIDE); //6
911 GXNormal3f32( SIDE, SIDE, -SIDE); //4
912 GXColor1u32(0xff0000ff);// red
913 GXTexCoord2f32(1.0F, 1.0F);//
914 GXPosition3f32(SIDE, SIDE, SIDE); //7
915 GXNormal3f32( SIDE, SIDE, -SIDE); //4
916 GXColor1u32(0xff0000ff);// red
917 GXTexCoord2f32(0.0F, 1.0F);//
918
919 GXPosition3f32(-SIDE, -SIDE, SIDE);//2
920 GXNormal3f32( SIDE, SIDE, -SIDE); //4
921 GXColor1u32(0x00ff00ff);// green
922 GXTexCoord2f32(0.0F, 0.0F);//
923 GXPosition3f32(SIDE, -SIDE, SIDE); //6
924 GXNormal3f32( SIDE, SIDE, -SIDE); //4
925 GXColor1u32(0x00ff00ff);// green
926 GXTexCoord2f32(1.0F, 0.0F);//
927 GXPosition3f32(SIDE, -SIDE, -SIDE);//5
928 GXNormal3f32( SIDE, SIDE, -SIDE); //4
929 GXColor1u32(0x00ff00ff);// green
930 GXTexCoord2f32(1.0F, 1.0F);//
931 GXPosition3f32(-SIDE, -SIDE, -SIDE);//3
932 GXNormal3f32( SIDE, SIDE, -SIDE); //4
933 GXColor1u32(0x00ff00ff);// green
934 GXTexCoord2f32(0.0F, 1.0F);//
935
936 GXPosition3f32(-SIDE, SIDE, SIDE); //1
937 GXNormal3f32( SIDE, SIDE, -SIDE); //4
938 GXColor1u32(0x0000ffff);// blue
939 GXTexCoord2f32(0.0F, 0.0F);//
940 GXPosition3f32(-SIDE, SIDE, -SIDE);//0
941 GXNormal3f32( SIDE, SIDE, -SIDE); //4
942 GXColor1u32(0x0000ffff);// blue
943 GXTexCoord2f32(1.0F, 0.0F);//
944 GXPosition3f32( SIDE, SIDE, -SIDE); //4
945 GXNormal3f32( SIDE, SIDE, -SIDE); //4
946 GXColor1u32(0x0000ffff);// blue
947 GXTexCoord2f32(1.0F, 1.0F);//
948 GXPosition3f32(SIDE, SIDE, SIDE); //7
949 GXNormal3f32( SIDE, SIDE, -SIDE); //4
950 GXColor1u32(0x0000ffff);// blue
951 GXTexCoord2f32(0.0F, 1.0F);//
952
953 GXPosition3f32(-SIDE, SIDE, -SIDE);//0
954 GXNormal3f32( SIDE, SIDE, -SIDE); //4
955 GXColor1u32(0xffff00ff);// yellow
956 GXTexCoord2f32(0.0F, 0.0F);//
957 GXPosition3f32(-SIDE, SIDE, SIDE); //1
958 GXNormal3f32( SIDE, SIDE, -SIDE); //4
959 GXColor1u32(0xffff00ff);// yellow
960 GXTexCoord2f32(1.0F, 0.0F);//
961 GXPosition3f32(-SIDE, -SIDE, SIDE);//2
962 GXNormal3f32( SIDE, SIDE, -SIDE); //4
963 GXColor1u32(0xffff00ff);// yellow
964 GXTexCoord2f32(1.0F, 1.0F);//
965 GXPosition3f32(-SIDE, -SIDE, -SIDE);//3
966 GXNormal3f32( SIDE, SIDE, -SIDE); //4
967 GXColor1u32(0xffff00ff);// yellow
968 GXTexCoord2f32(0.0F, 1.0F);//
969
970 GXPosition3f32(SIDE, -SIDE, -SIDE);//5
971 GXNormal3f32( SIDE, SIDE, -SIDE); //4
972 GXColor1u32(0xff00ffff);// magenta
973 GXTexCoord2f32(0.0F, 0.0F);//
974 GXPosition3f32( SIDE, SIDE, -SIDE); //4
975 GXNormal3f32( SIDE, SIDE, -SIDE); //4
976 GXColor1u32(0xff00ffff);// magenta
977 GXTexCoord2f32(1.0F, 0.0F);//
978 GXPosition3f32(-SIDE, SIDE, -SIDE);//0
979 GXNormal3f32( SIDE, SIDE, -SIDE); //4
980 GXColor1u32(0xff00ffff);// magenta
981 GXTexCoord2f32(1.0F, 1.0F);//
982 GXPosition3f32(-SIDE, -SIDE, -SIDE);//3
983 GXNormal3f32( SIDE, SIDE, -SIDE); //4
984 GXColor1u32(0xff00ffff);// magenta
985 GXTexCoord2f32(0.0F, 1.0F);//
986
987 GXPosition3f32(SIDE, -SIDE, SIDE); //6
988 GXNormal3f32( SIDE, SIDE, -SIDE); //4
989 GXColor1u32(0x00ffffff);// cyan
990 GXTexCoord2f32(0.0F, 0.0F);//
991 GXPosition3f32(-SIDE, -SIDE, SIDE);//2
992 GXNormal3f32( SIDE, SIDE, -SIDE); //4
993 GXColor1u32(0x00ffffff);// cyan
994 GXTexCoord2f32(1.0F, 0.0F);//
995 GXPosition3f32(-SIDE, SIDE, SIDE); //1
996 GXNormal3f32( SIDE, SIDE, -SIDE); //4
997 GXColor1u32(0x00ffffff);// cyan
998 GXTexCoord2f32(1.0F, 1.0F);//
999 GXPosition3f32(SIDE, SIDE, SIDE); //7
1000 GXNormal3f32( SIDE, SIDE, -SIDE); //4
1001 GXColor1u32(0x00ffffff);// cyan
1002 GXTexCoord2f32(0.0F, 1.0F);//
1003 GXEnd();
1004 }
1005
1006
1007 /*---------------------------------------------------------------------------*
1008 Name: DrawTexCubeIndx
1009
1010 Description:
1011
1012 Arguments: none
1013
1014 Returns: none
1015 *---------------------------------------------------------------------------*/
1016 static
DrawTexCubeIndx(void)1017 void DrawTexCubeIndx( void )
1018 {
1019 GXBegin(GX_QUADS, GX_VTXFMT0, 4*6);
1020 GXPosition1x16(4);
1021 GXTexCoord1x8(0); //
1022 GXPosition1x16(5);
1023 GXTexCoord1x8(1); //
1024 GXPosition1x16(6);
1025 GXTexCoord1x8(2); //
1026 GXPosition1x16(7);
1027 GXTexCoord1x8(3); //
1028
1029 GXPosition1x16(2);
1030 GXTexCoord1x8(0); //
1031 GXPosition1x16(6);
1032 GXTexCoord1x8(1); //
1033 GXPosition1x16(5);
1034 GXTexCoord1x8(2); //
1035 GXPosition1x16(3);
1036 GXTexCoord1x8(3); //
1037
1038 GXPosition1x16(1);
1039 GXTexCoord1x8(0); //
1040 GXPosition1x16(0);
1041 GXTexCoord1x8(1); //
1042 GXPosition1x16(4);
1043 GXTexCoord1x8(2); //
1044 GXPosition1x16(7);
1045 GXTexCoord1x8(3); //
1046
1047 GXPosition1x16(0);
1048 GXTexCoord1x8(0); //
1049 GXPosition1x16(1);
1050 GXTexCoord1x8(1); //
1051 GXPosition1x16(2);
1052 GXTexCoord1x8(2); //
1053 GXPosition1x16(3);
1054 GXTexCoord1x8(3); //
1055
1056 GXPosition1x16(5);
1057 GXTexCoord1x8(0); //
1058 GXPosition1x16(4);
1059 GXTexCoord1x8(1); //
1060 GXPosition1x16(0);
1061 GXTexCoord1x8(2); //
1062 GXPosition1x16(3);
1063 GXTexCoord1x8(3); //
1064
1065 GXPosition1x16(6);
1066 GXTexCoord1x8(0); //
1067 GXPosition1x16(2);
1068 GXTexCoord1x8(1); //
1069 GXPosition1x16(1);
1070 GXTexCoord1x8(2); //
1071 GXPosition1x16(7);
1072 GXTexCoord1x8(3); //
1073
1074 GXEnd();
1075 }
1076
1077 /*---------------------------------------------------------------------------*
1078 Name: DrawTexCubeDirect
1079
1080 Description:
1081
1082 Arguments: none
1083
1084 Returns: none
1085 *---------------------------------------------------------------------------*/
1086 static
DrawTexCubeDirect(void)1087 void DrawTexCubeDirect( void )
1088 {
1089 GXBegin(GX_QUADS, GX_VTXFMT0, 4*6);
1090 GXPosition3f32( SIDE, SIDE, -SIDE); //4
1091 GXTexCoord2f32(0.0F, 0.0F);//
1092 GXPosition3f32(SIDE, -SIDE, -SIDE);//5
1093 GXTexCoord2f32(1.0F, 0.0F);//
1094 GXPosition3f32(SIDE, -SIDE, SIDE); //6
1095 GXTexCoord2f32(1.0F, 1.0F);//
1096 GXPosition3f32(SIDE, SIDE, SIDE); //7
1097 GXTexCoord2f32(0.0F, 1.0F);//
1098
1099 GXPosition3f32(-SIDE, -SIDE, SIDE);//2
1100 GXTexCoord2f32(0.0F, 0.0F);//
1101 GXPosition3f32(SIDE, -SIDE, SIDE); //6
1102 GXTexCoord2f32(1.0F, 0.0F);//
1103 GXPosition3f32(SIDE, -SIDE, -SIDE);//5
1104 GXTexCoord2f32(1.0F, 1.0F);//
1105 GXPosition3f32(-SIDE, -SIDE, -SIDE);//3
1106 GXTexCoord2f32(0.0F, 1.0F);//
1107
1108 GXPosition3f32(-SIDE, SIDE, SIDE); //1
1109 GXTexCoord2f32(0.0F, 0.0F);//
1110 GXPosition3f32(-SIDE, SIDE, -SIDE);//0
1111 GXTexCoord2f32(1.0F, 0.0F);//
1112 GXPosition3f32( SIDE, SIDE, -SIDE); //4
1113 GXTexCoord2f32(1.0F, 1.0F);//
1114 GXPosition3f32(SIDE, SIDE, SIDE); //7
1115 GXTexCoord2f32(0.0F, 1.0F);//
1116
1117 GXPosition3f32(-SIDE, SIDE, -SIDE);//0
1118 GXTexCoord2f32(0.0F, 0.0F);//
1119 GXPosition3f32(-SIDE, SIDE, SIDE); //1
1120 GXTexCoord2f32(1.0F, 0.0F);//
1121 GXPosition3f32(-SIDE, -SIDE, SIDE);//2
1122 GXTexCoord2f32(1.0F, 1.0F);//
1123 GXPosition3f32(-SIDE, -SIDE, -SIDE);//3
1124 GXTexCoord2f32(0.0F, 1.0F);//
1125
1126 GXPosition3f32(SIDE, -SIDE, -SIDE);//5
1127 GXTexCoord2f32(0.0F, 0.0F);//
1128 GXPosition3f32( SIDE, SIDE, -SIDE); //4
1129 GXTexCoord2f32(1.0F, 0.0F);//
1130 GXPosition3f32(-SIDE, SIDE, -SIDE);//0
1131 GXTexCoord2f32(1.0F, 1.0F);//
1132 GXPosition3f32(-SIDE, -SIDE, -SIDE);//3
1133 GXTexCoord2f32(0.0F, 1.0F);//
1134
1135 GXPosition3f32(SIDE, -SIDE, SIDE); //6
1136 GXTexCoord2f32(0.0F, 0.0F);//
1137 GXPosition3f32(-SIDE, -SIDE, SIDE);//2
1138 GXTexCoord2f32(1.0F, 0.0F);//
1139 GXPosition3f32(-SIDE, SIDE, SIDE); //1
1140 GXTexCoord2f32(1.0F, 1.0F);//
1141 GXPosition3f32(SIDE, SIDE, SIDE); //7
1142 GXTexCoord2f32(0.0F, 1.0F);//
1143 GXEnd();
1144 }
1145