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, ©Clks);
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