1 /*---------------------------------------------------------------------------*
2
3 Copyright (C) Nintendo. All rights reserved.
4
5 These coded instructions, statements, and computer programs contain
6 proprietary information of Nintendo of America Inc. and/or Nintendo
7 Company Ltd., and are protected by Federal copyright law. They may
8 not be disclosed to third parties or copied or duplicated in any form,
9 in whole or in part, without the prior written consent of Nintendo.
10
11 *---------------------------------------------------------------------------*/
12
13 #include <stdio.h>
14 #include <string.h>
15 #include <math.h>
16
17 #include <cafe/demo.h>
18 #include <cafe/gx2.h>
19
20 #define PI 3.14159f
21
22 // ----- Surface Information
23
24 #define RENDERTARGET_WIDTH 1280
25 #define RENDERTARGET_HEIGHT 720
26
27 #define SURFACE_WIDTH 1280
28 #define SURFACE_HEIGHT 720
29
30 ////////////////////////////////////////////////////
31 //
32 // Assets Data
33 //
34 ////////////////////////////////////////////////////
35
36 // ----- Attribute Layout
37
38 struct AttributeLayout
39 {
40 const char* shaderVarName;
41 GX2AttribFormat attribFormat;
42 u32 elementSize;
43 };
44
45 // ----- Model files
46
47 #define NUM_MODEL 4
48 static char* MODEL_FILES[NUM_MODEL][3] =
49 {
50 {"assets/geometries/elephantPosition.dat",
51 "assets/geometries/elephantNormal.dat",
52 "assets/geometries/elephantIdx.dat"},
53 {"assets/geometries/teapotPosition.dat",
54 "assets/geometries/teapotNormal.dat",
55 "assets/geometries/teapotIdx.dat"},
56 {"assets/geometries/torusPosition.dat",
57 "assets/geometries/torusNormal.dat",
58 "assets/geometries/torusIdx.dat"},
59 {"assets/geometries/spherePosition.dat",
60 "assets/geometries/sphereNormal.dat",
61 "assets/geometries/sphereIdx.dat"}
62 };
63
64 // ----- Shader files
65
66 static const char * const GSH_SHADER_FILE_DEFERRED_GEOMETRY = "assets/shaders/test_gx2/cafe/shading/deferredRenderingSetup.gsh";
67 static const char * const GSH_SHADER_FILE_DEFERRED_LIGHTING = "assets/shaders/test_gx2/cafe/shading/deferredRenderingLighting.gsh";
68 static const char * const GSH_SHADER_FILE_TEXTURE2D = "assets/shaders/test_gx2/cafe/simple/texture2D.gsh";
69
70 // ----- Struct for geometry stage attribute buffers
71
72 static AttributeLayout s_modelAttributeLayout[] =
73 {
74 { "a_position", GX2_ATTRIB_FORMAT_32_32_32_FLOAT, sizeof(DEMO_F32x3) },
75 { "a_normal", GX2_ATTRIB_FORMAT_32_32_32_FLOAT, sizeof(DEMO_F32x3) },
76 };
77 static const u32 MODEL_NUM_ATTRIBUTES=sizeof(s_modelAttributeLayout)/sizeof(s_modelAttributeLayout[0]);
78
79 typedef struct _ModelAttribBuffer
80 {
81 GX2RBuffer attributeBuffer[MODEL_NUM_ATTRIBUTES];
82 GX2RBuffer indexBuffer;
83 } ModelAttribBuffer;
84
85 // ----- Struct for lighting stage attribute buffers
86
87 static AttributeLayout s_LightingAttributeLayout[] =
88 {
89 { "a_position", GX2_ATTRIB_FORMAT_32_32_32_FLOAT, sizeof(DEMO_F32x3) },
90 { "a_texCoord", GX2_ATTRIB_FORMAT_32_32_FLOAT, sizeof(DEMO_F32x2) },
91 };
92 static const u32 LIGHTING_NUM_ATTRIBUTES=sizeof(s_LightingAttributeLayout)/sizeof(s_LightingAttributeLayout[0]);
93
94 typedef struct _LightingAttribBuffer
95 {
96 GX2RBuffer attributeBuffer[LIGHTING_NUM_ATTRIBUTES];
97 GX2RBuffer indexBuffer;
98 } LightingAttribBuffer;
99
100 // ----- Struct for gbuffer stage attribute buffers
101
102 static AttributeLayout s_gBufferAttributeLayout[] =
103 {
104 { "a_position", GX2_ATTRIB_FORMAT_32_32_32_FLOAT, sizeof(DEMO_F32x3) },
105 { "a_texCoord", GX2_ATTRIB_FORMAT_32_32_FLOAT, sizeof(DEMO_F32x2) },
106 };
107 static const u32 G_BUFFER_NUM_ATTRIBUTES=sizeof(s_gBufferAttributeLayout)/sizeof(s_gBufferAttributeLayout[0]);
108
109 typedef struct _GBufferAttribBuffer
110 {
111 GX2RBuffer attributeBuffer[G_BUFFER_NUM_ATTRIBUTES];
112 GX2RBuffer indexBuffer;
113 } GBufferAttribBuffer;
114
115 static struct _GeometryPass
116 {
117 // -- Shaders -- //
118 DEMOGfxShader shaders;
119
120 // -- Constant Buffers -- //
121 Mtx44 modelMtx44;
122 Mtx44 viewprojMtx44;
123 Qtrn color;
124
125 // -- Attribute Buffers -- //
126 ModelAttribBuffer attribs[NUM_MODEL];
127
128 // -- Texture Setting -- //
129 GX2ColorBuffer myColorBuffer[3];
130 void * myColorBufferData[3];
131 void * myScanBufferPtr;
132 } GeometryPass;
133
134 static struct _LightingPass
135 {
136 // -- Shaders -- //
137 DEMOGfxShader shaders;
138
139 // -- Constant Buffers -- //
140 Qtrn ambientColor;
141 Qtrn lightColor;
142 Qtrn lightPosition;
143 Qtrn cameraPosition;
144
145 // -- Attribute Buffers -- //
146 LightingAttribBuffer attribs;
147
148 // -- Texture Setting -- //
149 GX2Texture myTextureBuffer[3];
150 GX2Sampler mySampler;
151 } LightingPass;
152
153 static struct _BuffersPass
154 {
155 // -- Shaders -- //
156 DEMOGfxShader shaders;
157
158 // -- Attribute Buffers -- //
159 GBufferAttribBuffer attribs;
160
161 // -- Texture Setting -- //
162 GX2Texture myTextureBuffer[3];
163 GX2Sampler mySampler;
164 } BuffersPass;
165
166 // Globals
167 static float s_rotateY;
168 static BOOL s_drawBuffers;
169 static u32 s_modelIdx;
170 static u32 s_avgNoSwizzleTime;
171 static u32 s_avgSwizzleTime;
172 static u32 s_noSwizzleTime;
173 static u32 s_swizzleTime;
174 static u64* s_timerData;
175 static u32 s_ticks;
176
177 // Prototype
178 static void CameraInit(Mtx44 resultViewProjMtx44);
179 static void SceneInit(void);
180 static void SceneUpdate(void);
181 static void GeometryPassInit(void);
182 static void LightingPassInit(void);
183 static void BuffersPassInit(void);
184 static void SceneFree(void);
185 static void GeometryPassDraw(void);
186 static void LightingPassDraw(void);
187 static void BuffersPassDraw(void);
188 static void SceneDraw(void);
189
190 // Init function for setting projection matrix
CameraInit(Mtx44 resultViewProjMtx44)191 static void CameraInit(Mtx44 resultViewProjMtx44)
192 {
193 // row major matricies
194 Mtx lookAtMtx34;
195 Mtx44 projMtx44;
196 Mtx44 viewMtx44;
197
198 Vec up = {0.0f, 1.0f, 0.0f};
199 Vec objPt = {0.0f, 0.0f, 0.0f};
200 Vec camLoc = {0.0f, 0.0f, 300.0f};
201
202 f32 pers = 30.0f;
203 f32 aspect = (f32)SURFACE_WIDTH / (f32)SURFACE_HEIGHT;
204 f32 znear = 50.0f;
205 f32 zfar = 2000.0f;
206
207 // Set light position
208 LightingPass.cameraPosition.x = camLoc.x;
209 LightingPass.cameraPosition.y = camLoc.y;
210 LightingPass.cameraPosition.z = camLoc.z;
211 LightingPass.cameraPosition.w = 1.0f;
212
213 // Compute perspective matrix
214 MTXPerspective(projMtx44, pers, aspect, znear, zfar);
215
216 // Compute lookAt matrix
217 MTXLookAt(lookAtMtx34, &camLoc, &up, &objPt);
218 MTX34To44(lookAtMtx34, viewMtx44);
219
220 // return view+proj
221 MTX44Concat(projMtx44, viewMtx44, resultViewProjMtx44);
222 }
223
224 // The init function for the rendering portions of this app
SceneInit(void)225 static void SceneInit(void)
226 {
227 // Initialize globals
228 s_rotateY = 0.0f;
229 s_drawBuffers = TRUE;
230 s_modelIdx = 0;
231 s_noSwizzleTime = 0;
232 s_swizzleTime = 0;
233 s_avgNoSwizzleTime = 0;
234 s_avgSwizzleTime = 0;
235 s_timerData = (u64*)DEMOGfxAllocMEM2(sizeof(u64)*2, GX2_DEFAULT_BUFFER_ALIGNMENT);
236 s_ticks = 0;
237
238 // Initialize passes
239 GeometryPassInit();
240 LightingPassInit();
241 BuffersPassInit();
242 }
243
244 // rotate the model
SceneUpdate(void)245 static void SceneUpdate(void)
246 {
247 Mtx modelWorldMtx;
248
249 MTXRotRad(modelWorldMtx, 'y', s_rotateY / 4.0f);
250 MTX34To44(modelWorldMtx, GeometryPass.modelMtx44);
251
252 s_rotateY += 0.06f;
253 if(s_rotateY > PI*8)
254 {
255 s_rotateY -= PI*8;
256 s_drawBuffers = !s_drawBuffers;
257 if(s_drawBuffers)
258 s_modelIdx = (s_modelIdx + 1) % NUM_MODEL;
259 }
260 ++s_ticks;
261 }
262
LoadModelBuffer(const char * modelFileName,GX2RResourceFlags resourceFlags,u32 elementSize)263 static GX2RBuffer LoadModelBuffer(const char* modelFileName, GX2RResourceFlags resourceFlags, u32 elementSize)
264 {
265 // This version does it's own file reading to eliminate the extra malloc/memcpy/free
266 // and just load straight into the buffer memory.
267 DEMOFSFileInfo file;
268 u32 fileLen;
269 s32 fileRet;
270
271 fileRet = DEMOFSOpenFile(modelFileName, &file);
272 DEMOAssert(fileRet == DEMO_FS_RESULT_OK && "couldn't open file");
273
274 fileRet = DEMOFSGetLength(&file, &fileLen);
275 DEMOAssert(fileRet == DEMO_FS_RESULT_OK && "couldn't get file length");
276
277 u32 elementCount = fileLen/elementSize;
278
279 GX2RBuffer gx2Buffer;
280 GX2UTCreateBuffer(&gx2Buffer, resourceFlags | GX2R_USAGE_CPU_WRITE | GX2R_USAGE_GPU_READ, elementSize, elementCount);
281 GX2RSetBufferName(&gx2Buffer, modelFileName);
282
283 // Lock the buffer and read straight into the memory with no copying
284 void* pMem=GX2RLockBuffer(&gx2Buffer);
285
286 fileRet = DEMOFSRead(&file, pMem, (s32)fileLen, 0);
287 DEMOAssert(fileRet == DEMO_FS_RESULT_OK && "couldn't read file");
288
289 GX2RUnlockBuffer(&gx2Buffer);
290
291 fileRet = DEMOFSCloseFile(&file);
292 if (fileRet != DEMO_FS_RESULT_OK)
293 {
294 DEMOAssert(!"couldn't close file");
295 }
296
297 return gx2Buffer;
298 }
299 // Initialized the Geometry pass
GeometryPassInit(void)300 static void GeometryPassInit(void)
301 {
302 u32 i;
303 u32 gshLen;
304 void *gshBuf;
305
306 // initialize uniforms
307 CameraInit(GeometryPass.viewprojMtx44);
308 SceneUpdate();
309 GeometryPass.color.x = 1.0f;
310 GeometryPass.color.y = 0.0f;
311 GeometryPass.color.z = 0.0f;
312 GeometryPass.color.w = 80.0f / 255.0f; // shininess / 255.0f
313
314 // DEMOFSSimpleRead sets PPC_IO_BUFFER_ALIGN alignment.
315 // This number must fit to vertex and index buffer alignment.
316 ASSERT(PPC_IO_BUFFER_ALIGN % GX2_VERTEX_BUFFER_ALIGNMENT == 0);
317 ASSERT(PPC_IO_BUFFER_ALIGN % GX2_INDEX_BUFFER_ALIGNMENT == 0);
318
319 // load models
320 for(i = 0; i < NUM_MODEL; ++i)
321 {
322 // Load attribute buffers
323 for (u32 attribSlot=0; attribSlot<MODEL_NUM_ATTRIBUTES; attribSlot++)
324 {
325 GeometryPass.attribs[i].attributeBuffer[attribSlot] = LoadModelBuffer(MODEL_FILES[i][attribSlot],
326 GX2R_BIND_VERTEX_BUFFER,
327 s_modelAttributeLayout[attribSlot].elementSize);
328 }
329 // Load index buffer
330 GeometryPass.attribs[i].indexBuffer = LoadModelBuffer(MODEL_FILES[i][MODEL_NUM_ATTRIBUTES],
331 GX2R_BIND_INDEX_BUFFER,
332 GX2UTGetIndexSize(GX2_INDEX_FORMAT_U32));
333 };
334
335 // Load shader binary to memory
336 gshBuf = DEMOFSSimpleRead(GSH_SHADER_FILE_DEFERRED_GEOMETRY, &gshLen);
337
338 // Load shaders from memory.
339 DEMOGfxLoadShaders(&GeometryPass.shaders, 0, gshBuf);
340
341 // Free memory used to load the shader file
342 DEMOFree(gshBuf);
343
344 // Init attribs
345 for (u32 attribSlot=0; attribSlot<MODEL_NUM_ATTRIBUTES; attribSlot++)
346 {
347 DEMOGfxInitShaderAttribute(&GeometryPass.shaders,
348 s_modelAttributeLayout[attribSlot].shaderVarName,
349 attribSlot,
350 0,
351 s_modelAttributeLayout[attribSlot].attribFormat);
352 }
353
354 // Get uniform location
355 DEMOGfxGetVertexShaderUniformLocation(&GeometryPass.shaders, "u_modelMtx");
356 DEMOGfxGetVertexShaderUniformLocation(&GeometryPass.shaders, "u_viewprojMtx");
357
358 // Get uniform location
359 DEMOGfxGetPixelShaderUniformLocation(&GeometryPass.shaders, "u_color");
360
361 // Initialize fetch Shader
362 DEMOGfxInitFetchShader(&GeometryPass.shaders);
363
364
365 // Initialize render color buffers
366 GX2InitColorBuffer(&GeometryPass.myColorBuffer[0],
367 RENDERTARGET_WIDTH,
368 RENDERTARGET_HEIGHT,
369 GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM,
370 GX2_AA_MODE_1X);
371 GeometryPass.myColorBufferData[0] = DEMOGfxAllocMEM1(GeometryPass.myColorBuffer[0].surface.imageSize,
372 GeometryPass.myColorBuffer[0].surface.alignment);
373 GX2InitColorBufferPtr(&GeometryPass.myColorBuffer[0], GeometryPass.myColorBufferData[0]);
374 GX2SetSurfaceSwizzle(&GeometryPass.myColorBuffer[0].surface, 0);
375
376 GX2InitColorBuffer(&GeometryPass.myColorBuffer[1],
377 RENDERTARGET_WIDTH,
378 RENDERTARGET_HEIGHT,
379 GX2_SURFACE_FORMAT_TC_R10_G10_B10_A2_SNORM,
380 GX2_AA_MODE_1X);
381 GeometryPass.myColorBufferData[1] = DEMOGfxAllocMEM1(GeometryPass.myColorBuffer[1].surface.imageSize,
382 GeometryPass.myColorBuffer[1].surface.alignment);
383 GX2InitColorBufferPtr(&GeometryPass.myColorBuffer[1], GeometryPass.myColorBufferData[1]);
384 GX2SetSurfaceSwizzle(&GeometryPass.myColorBuffer[1].surface, 2);
385
386 GX2InitColorBuffer(&GeometryPass.myColorBuffer[2],
387 RENDERTARGET_WIDTH,
388 RENDERTARGET_HEIGHT,
389 GX2_SURFACE_FORMAT_TC_R11_G11_B10_FLOAT,
390 GX2_AA_MODE_1X);
391 GeometryPass.myColorBufferData[2] = DEMOGfxAllocMEM1(GeometryPass.myColorBuffer[2].surface.imageSize,
392 GeometryPass.myColorBuffer[2].surface.alignment);
393 GX2InitColorBufferPtr(&GeometryPass.myColorBuffer[2], GeometryPass.myColorBufferData[2]);
394 GX2SetSurfaceSwizzle(&GeometryPass.myColorBuffer[2].surface, 7);
395 }
396
397 // Initializes the Lighting pass
LightingPassInit(void)398 static void LightingPassInit(void)
399 {
400 u32 gshLen;
401 void *gshBuf;
402
403 // initialize uniforms
404 LightingPass.ambientColor.x = 0.3f;
405 LightingPass.ambientColor.y = 0.3f;
406 LightingPass.ambientColor.z = 0.3f;
407 LightingPass.ambientColor.w = 1.0f;
408
409 LightingPass.lightColor.x = 1.0f;
410 LightingPass.lightColor.y = 1.0f;
411 LightingPass.lightColor.z = 1.0f;
412 LightingPass.lightColor.w = 10.0f / 255.0f; // attenuation / 255.0f
413
414 LightingPass.lightPosition.x = 40.0f;
415 LightingPass.lightPosition.y = 30.0f;
416 LightingPass.lightPosition.z = 40.0f;
417 LightingPass.lightPosition.w = 1.0f;
418
419 // Initialize texture buffers
420 GX2InitTexture(&LightingPass.myTextureBuffer[0],
421 RENDERTARGET_WIDTH, // width
422 RENDERTARGET_HEIGHT, // height
423 1, // depth
424 0, // num mips
425 GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM,
426 GX2_SURFACE_DIM_2D);
427 GX2SetSurfaceSwizzle(&LightingPass.myTextureBuffer[0].surface, 1);
428 GX2InitTexture(&LightingPass.myTextureBuffer[1],
429 RENDERTARGET_WIDTH, // width
430 RENDERTARGET_HEIGHT, // height
431 1, // depth
432 0, // num mips
433 GX2_SURFACE_FORMAT_TC_R10_G10_B10_A2_SNORM,
434 GX2_SURFACE_DIM_2D);
435 GX2SetSurfaceSwizzle(&LightingPass.myTextureBuffer[1].surface, 2);
436 GX2InitTexture(&LightingPass.myTextureBuffer[2],
437 RENDERTARGET_WIDTH, // width
438 RENDERTARGET_HEIGHT, // height
439 1, // depth
440 0, // num mips
441 GX2_SURFACE_FORMAT_TC_R11_G11_B10_FLOAT,
442 GX2_SURFACE_DIM_2D);
443 GX2SetSurfaceSwizzle(&LightingPass.myTextureBuffer[2].surface, 4);
444
445 // Set up the sampler object
446 GX2InitSampler(&LightingPass.mySampler,
447 GX2_TEX_CLAMP_CLAMP,
448 GX2_TEX_XY_FILTER_POINT);
449
450 // geometry data
451 DEMO_F32x3 posInitData[] = {{-1.0f,-1.0f, 0.0f},
452 { 1.0f,-1.0f, 0.0f},
453 { 1.0f, 1.0f, 0.0f},
454 {-1.0f, 1.0f, 0.0f}
455 };
456 DEMO_F32x2 texInitData[] = {{ 0.0f, 1.0f},
457 { 1.0f, 1.0f},
458 { 1.0f, 0.0f},
459 { 0.0f, 0.0f}
460 };
461 DEMO_U32 idxInitData[] = {0, 1, 2, 3};
462
463 // Create Vertex Buffer
464 GX2UTCreateVertexBuffer(&LightingPass.attribs.attributeBuffer[0],
465 sizeof(DEMO_F32x3),
466 sizeof(posInitData) / sizeof(DEMO_F32x3));
467
468 // Create Texture Buffer
469 GX2UTCreateVertexBuffer(&LightingPass.attribs.attributeBuffer[1],
470 sizeof(DEMO_F32x2),
471 sizeof(texInitData) / sizeof(DEMO_F32x2));
472
473 // Create Index Buffer
474 GX2UTCreateIndexBuffer(&LightingPass.attribs.indexBuffer,
475 sizeof(DEMO_U32),
476 sizeof(idxInitData) / sizeof(DEMO_U32));
477
478 // Set attributes data
479 GX2UTFillBuffer(&LightingPass.attribs.attributeBuffer[0], posInitData);
480 GX2UTFillBuffer(&LightingPass.attribs.attributeBuffer[1], texInitData);
481 GX2UTFillBuffer(&LightingPass.attribs.indexBuffer, idxInitData);
482
483 // Load shader binary to memory
484 gshBuf = DEMOFSSimpleRead(GSH_SHADER_FILE_DEFERRED_LIGHTING, &gshLen);
485
486 // Load shaders from memory.
487 DEMOGfxLoadShaders(&LightingPass.shaders, 0, gshBuf);
488
489 // Free memory used to load the shader file
490 DEMOFree(gshBuf);
491
492 // Init attribs
493 for (u32 attribSlot=0; attribSlot<G_BUFFER_NUM_ATTRIBUTES; attribSlot++)
494 {
495 DEMOGfxInitShaderAttribute(&LightingPass.shaders,
496 s_LightingAttributeLayout[attribSlot].shaderVarName,
497 attribSlot,
498 0,
499 s_LightingAttributeLayout[attribSlot].attribFormat);
500 }
501
502 // Get sampler location
503 DEMOGfxGetPixelShaderSamplerLocation(&LightingPass.shaders, "s_diffuse");
504 DEMOGfxGetPixelShaderSamplerLocation(&LightingPass.shaders, "s_normal");
505 DEMOGfxGetPixelShaderSamplerLocation(&LightingPass.shaders, "s_position");
506
507 // Get uniform location
508 DEMOGfxGetPixelShaderUniformLocation(&LightingPass.shaders, "u_ambientColor");
509 DEMOGfxGetPixelShaderUniformLocation(&LightingPass.shaders, "u_lightColor");
510 DEMOGfxGetPixelShaderUniformLocation(&LightingPass.shaders, "u_lightPosition");
511 DEMOGfxGetPixelShaderUniformLocation(&LightingPass.shaders, "u_cameraPosition");
512
513 // Initialize fetch Shader
514 DEMOGfxInitFetchShader(&LightingPass.shaders);
515
516 }
517
518 // Initializes the Buffers pass
BuffersPassInit(void)519 static void BuffersPassInit(void)
520 {
521 u32 gshLen;
522 void *gshBuf;
523
524 // Initialize texture buffers
525 GX2InitTexture(&BuffersPass.myTextureBuffer[0],
526 RENDERTARGET_WIDTH, // width
527 RENDERTARGET_HEIGHT, // height
528 1, // depth
529 0, // num mips
530 GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM,
531 GX2_SURFACE_DIM_2D);
532 GX2SetSurfaceSwizzle(&BuffersPass.myTextureBuffer[0].surface, 1);
533 GX2InitTexture(&BuffersPass.myTextureBuffer[1],
534 RENDERTARGET_WIDTH, // width
535 RENDERTARGET_HEIGHT, // height
536 1, // depth
537 0, // num mips
538 GX2_SURFACE_FORMAT_TC_R10_G10_B10_A2_SNORM,
539 GX2_SURFACE_DIM_2D);
540 GX2SetSurfaceSwizzle(&BuffersPass.myTextureBuffer[1].surface, 2);
541 GX2InitTexture(&BuffersPass.myTextureBuffer[2],
542 RENDERTARGET_WIDTH, // width
543 RENDERTARGET_HEIGHT, // height
544 1, // depth
545 0, // num mips
546 GX2_SURFACE_FORMAT_TC_R11_G11_B10_FLOAT,
547 GX2_SURFACE_DIM_2D);
548 GX2SetSurfaceSwizzle(&BuffersPass.myTextureBuffer[2].surface, 4);
549
550 // Set up the sampler object
551 GX2InitSampler(&BuffersPass.mySampler,
552 GX2_TEX_CLAMP_CLAMP,
553 GX2_TEX_XY_FILTER_POINT);
554
555 // geometry data
556 const f32 divs = 2.0f;
557 DEMO_F32x3 posInitData[] = {{-1.0f/divs,-1.0f/divs, 0.0f},
558 { 1.0f/divs,-1.0f/divs, 0.0f},
559 { 1.0f/divs, 1.0f/divs, 0.0f},
560 {-1.0f/divs, 1.0f/divs, 0.0f}
561 };
562 DEMO_F32x2 texInitData[] = {{ 0.0f, 1.0f},
563 { 1.0f, 1.0f},
564 { 1.0f, 0.0f},
565 { 0.0f, 0.0f}
566 };
567 DEMO_U32 idxInitData[] = {0, 1, 2, 3};
568
569 // Create Vertex Buffer
570 GX2UTCreateVertexBuffer(&BuffersPass.attribs.attributeBuffer[0],
571 sizeof(DEMO_F32x3),
572 sizeof(posInitData) / sizeof(DEMO_F32x3));
573
574 // Create Texture Buffer
575 GX2UTCreateVertexBuffer(&BuffersPass.attribs.attributeBuffer[1],
576 sizeof(DEMO_F32x2),
577 sizeof(texInitData) / sizeof(DEMO_F32x2));
578
579 // Create Index Buffer
580 GX2UTCreateIndexBuffer(&BuffersPass.attribs.indexBuffer,
581 sizeof(DEMO_U32),
582 sizeof(idxInitData) / sizeof(DEMO_U32));
583
584 // Set attributes data
585 GX2UTFillBuffer(&BuffersPass.attribs.attributeBuffer[0], posInitData);
586 GX2UTFillBuffer(&BuffersPass.attribs.attributeBuffer[1], texInitData);
587 GX2UTFillBuffer(&BuffersPass.attribs.indexBuffer, idxInitData);
588
589 // Load shader binary to memory
590 gshBuf = DEMOFSSimpleRead(GSH_SHADER_FILE_TEXTURE2D, &gshLen);
591
592 // Load shaders from memory.
593 DEMOGfxLoadShaders(&BuffersPass.shaders, 0, gshBuf);
594
595 // Free memory used to load the shader file
596 DEMOFree(gshBuf);
597
598 // Init attribs
599 for (u32 attribSlot=0; attribSlot<G_BUFFER_NUM_ATTRIBUTES; attribSlot++)
600 {
601 DEMOGfxInitShaderAttribute(&BuffersPass.shaders,
602 s_gBufferAttributeLayout[attribSlot].shaderVarName,
603 attribSlot,
604 0,
605 s_gBufferAttributeLayout[attribSlot].attribFormat);
606 }
607
608 // Get sampler location
609 DEMOGfxGetPixelShaderSamplerLocation(&BuffersPass.shaders, "s_texture");
610
611 // Get uniform location
612 DEMOGfxGetVertexShaderUniformLocation(&BuffersPass.shaders, "u_offset");
613
614 // Initialize fetch Shader
615 DEMOGfxInitFetchShader(&BuffersPass.shaders);
616
617 }
618
619 // Deallocates all resources
SceneFree(void)620 static void SceneFree(void)
621 {
622 u32 i;
623
624 // Geometry pass free
625 DEMOGfxFreeShaders(&GeometryPass.shaders);
626
627 for(i = 0; i < NUM_MODEL; ++i)
628 {
629 for (u32 attribSlot=0; attribSlot<MODEL_NUM_ATTRIBUTES; attribSlot++)
630 {
631 GX2RDestroyBuffer(&GeometryPass.attribs[i].attributeBuffer[attribSlot]);
632 }
633
634 GX2RDestroyBuffer(&GeometryPass.attribs[i].indexBuffer);
635 }
636
637 DEMOGfxFreeMEM1(GeometryPass.myColorBufferData[0]);
638 DEMOGfxFreeMEM1(GeometryPass.myColorBufferData[1]);
639 DEMOGfxFreeMEM1(GeometryPass.myColorBufferData[2]);
640
641 // Lighting pass free
642 DEMOGfxFreeShaders(&LightingPass.shaders);
643
644 for (u32 attribSlot=0; attribSlot<G_BUFFER_NUM_ATTRIBUTES; attribSlot++)
645 {
646 GX2RDestroyBuffer(&LightingPass.attribs.attributeBuffer[attribSlot]);
647 }
648
649 GX2RDestroyBuffer(&LightingPass.attribs.indexBuffer);
650
651 // Buffers pass free
652 DEMOGfxFreeShaders(&BuffersPass.shaders);
653
654 for (u32 attribSlot=0; attribSlot<G_BUFFER_NUM_ATTRIBUTES; attribSlot++)
655 {
656 GX2RDestroyBuffer(&BuffersPass.attribs.attributeBuffer[attribSlot]);
657 }
658
659 GX2RDestroyBuffer(&BuffersPass.attribs.indexBuffer);
660
661 // Free the timer
662 DEMOGfxFreeMEM2(s_timerData);
663 }
664
665 // The draw function for the rendering portions of this app
SceneDraw(void)666 static void SceneDraw(void)
667 {
668 u32 sceneDraws;
669 u32 swizzleValues[2][3] =
670 {
671 {0,0,0}, // all the same (no swizzle)
672 {0,2,7} // all different (swizzle)
673 }; // 0-7 are valid values
674
675 DEMOGfxBeforeRender();
676
677 for(sceneDraws = 0; sceneDraws < 2; ++sceneDraws)
678 {
679 // Compare time with and without swizzle (normally swizzle is just set during init)
680 u32 i, time;
681 for(i = 0; i < 3; ++i)
682 {
683 GX2SetSurfaceSwizzle(&GeometryPass.myColorBuffer[i].surface, swizzleValues[sceneDraws][i]);
684 GX2SetSurfaceSwizzle(&LightingPass.myTextureBuffer[i].surface, swizzleValues[sceneDraws][i]);
685 GX2SetSurfaceSwizzle(&BuffersPass.myTextureBuffer[i].surface, swizzleValues[sceneDraws][i]);
686 }
687
688 // start timing
689 GX2DrawDone();
690 GX2SampleTopGPUCycle(&s_timerData[0]);
691 GX2Flush();
692
693 // 1ST PASS (SETUP)
694 GeometryPassDraw();
695
696 // 2ND PASS (LIGHTING)
697 LightingPassDraw();
698
699 // record time taken
700 GX2SampleBottomGPUCycle(&s_timerData[1]);
701 GX2DrawDone();
702 DCInvalidateRange((void*)s_timerData, sizeof(u64)*2);
703 time = (u32)((s_timerData[1] - s_timerData[0]) * 0.0370370);
704
705 // average time over 15 frames
706 if(sceneDraws == 0)
707 {
708 s_noSwizzleTime += time;
709 if(s_ticks % 15 == 14)
710 {
711 s_avgNoSwizzleTime = s_noSwizzleTime / 15;
712 s_noSwizzleTime = 0;
713 }
714 }
715 else
716 {
717 s_swizzleTime += time;
718 if(s_ticks % 15 == 14)
719 {
720 s_avgSwizzleTime = s_swizzleTime / 15;
721 s_swizzleTime = 0;
722 }
723 }
724 }
725
726 // DRAW G-BUFFERS
727 BuffersPassDraw();
728
729 // Set Demo Font state
730 DEMOFontSetContextState();
731
732 if(s_drawBuffers == TRUE)
733 {
734 // label g-buffers
735 DEMOFontPrintf(3, 1, "DIFFUSE G-BUFFER");
736 DEMOFontPrintf(3, 2, "R8G8B8A8_UNORM");
737 DEMOFontPrintf(43, 1, "NORMAL G-BUFFER");
738 DEMOFontPrintf(43, 2, "R10G10B10A2_SNORM");
739 DEMOFontPrintf(3, 21, "POSITION G-BUFFER");
740 DEMOFontPrintf(3, 22, "R11G11B10_FLOAT");
741 }
742
743 // display times
744 DEMOFontPrintf(32, 21, "Render Time w/o swizzle: %d", s_avgNoSwizzleTime);
745 DEMOFontPrintf(32, 22, "Render Time w/ swizzle: %d (%d%%)", s_avgSwizzleTime, (u32)(100 * (f32)s_avgSwizzleTime / (f32)s_avgNoSwizzleTime));
746
747 DEMOGfxDoneRender();
748 }
749
750
751 // Render Geometry Info to G-Buffers
GeometryPassDraw(void)752 static void GeometryPassDraw(void)
753 {
754 u32 uniformVSCount = 0;
755 u32 uniformPSCount = 0;
756
757 GX2SetColorBuffer(&GeometryPass.myColorBuffer[0], GX2_RENDER_TARGET_0);
758 GX2SetColorBuffer(&GeometryPass.myColorBuffer[1], GX2_RENDER_TARGET_1);
759 GX2SetColorBuffer(&GeometryPass.myColorBuffer[2], GX2_RENDER_TARGET_2);
760
761 GX2SetViewport(0.0f, 0.0f, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT, 0.0f, 1.0f);
762 GX2SetScissor(0, 0, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT);
763
764 GX2ClearColor(&GeometryPass.myColorBuffer[0], 0.4f, 0.4f, 0.4f, 0.0f);
765 GX2ClearColor(&GeometryPass.myColorBuffer[1], 0.0f, 0.0f, 0.0f, 0.0f);
766 GX2ClearColor(&GeometryPass.myColorBuffer[2], 0.0f, 0.0f, 0.0f, 0.0f);
767 GX2ClearDepthStencil(&DEMODepthBuffer, GX2_CLEAR_BOTH);
768
769 DEMOGfxSetContextState();
770
771 // Set Depth Stencil Control Register
772 GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_LESS);
773
774 GX2SetShaders(&GeometryPass.shaders.fetchShader,
775 GeometryPass.shaders.pVertexShader,
776 GeometryPass.shaders.pPixelShader);
777
778 // Bind attribute buffers
779 for (u32 attribSlot=0; attribSlot<MODEL_NUM_ATTRIBUTES; attribSlot++)
780 {
781 GX2UTSetAttributeBuffer(&GeometryPass.attribs[s_modelIdx].attributeBuffer[attribSlot], attribSlot, 0);
782 }
783
784 // Uniform Location Lookup
785 GX2SetVertexUniformReg(GeometryPass.shaders.uniformsVS.location[uniformVSCount++], 4*4, GeometryPass.modelMtx44);
786 GX2SetVertexUniformReg(GeometryPass.shaders.uniformsVS.location[uniformVSCount++], 4*4, GeometryPass.viewprojMtx44);
787
788 GX2SetPixelUniformReg(GeometryPass.shaders.uniformsPS.location[uniformPSCount], 4, &GeometryPass.color);
789
790 // Draw Model
791 GX2UTDrawIndexed(GX2_PRIMITIVE_TRIANGLES, &GeometryPass.attribs[s_modelIdx].indexBuffer);
792
793 GX2Invalidate(GX2_INVALIDATE_COLOR_BUFFER,
794 GeometryPass.myColorBuffer[0].surface.imagePtr,
795 GeometryPass.myColorBuffer[0].surface.imageSize );
796 GX2Invalidate(GX2_INVALIDATE_COLOR_BUFFER,
797 GeometryPass.myColorBuffer[1].surface.imagePtr,
798 GeometryPass.myColorBuffer[1].surface.imageSize );
799 GX2Invalidate(GX2_INVALIDATE_COLOR_BUFFER,
800 GeometryPass.myColorBuffer[2].surface.imagePtr,
801 GeometryPass.myColorBuffer[2].surface.imageSize );
802 GX2Invalidate(GX2_INVALIDATE_TEXTURE,
803 LightingPass.myTextureBuffer[0].surface.imagePtr,
804 LightingPass.myTextureBuffer[0].surface.imageSize );
805 GX2Invalidate(GX2_INVALIDATE_TEXTURE,
806 LightingPass.myTextureBuffer[1].surface.imagePtr,
807 LightingPass.myTextureBuffer[1].surface.imageSize );
808 GX2Invalidate(GX2_INVALIDATE_TEXTURE,
809 LightingPass.myTextureBuffer[2].surface.imagePtr,
810 LightingPass.myTextureBuffer[2].surface.imageSize );
811
812 if(s_drawBuffers == TRUE)
813 {
814 GX2Invalidate(GX2_INVALIDATE_TEXTURE,
815 BuffersPass.myTextureBuffer[0].surface.imagePtr,
816 BuffersPass.myTextureBuffer[0].surface.imageSize );
817 GX2Invalidate(GX2_INVALIDATE_TEXTURE,
818 BuffersPass.myTextureBuffer[1].surface.imagePtr,
819 BuffersPass.myTextureBuffer[1].surface.imageSize );
820 GX2Invalidate(GX2_INVALIDATE_TEXTURE,
821 BuffersPass.myTextureBuffer[2].surface.imagePtr,
822 BuffersPass.myTextureBuffer[2].surface.imageSize );
823 }
824 }
825
826 // Draw Lit Models using G-Buffers
LightingPassDraw(void)827 static void LightingPassDraw(void)
828 {
829 u32 samplerPSCount = 0;
830 u32 uniformPSCount = 0;
831
832 // Render lit scene in bottom-right if drawing g-buffers or fullscreen otherwise
833 if(s_drawBuffers == TRUE)
834 {
835 GX2SetViewport(SURFACE_WIDTH/2, SURFACE_HEIGHT/2, SURFACE_WIDTH/2, SURFACE_HEIGHT/2, 0.0f, 1.0f);
836 GX2SetScissor(SURFACE_WIDTH/2, SURFACE_HEIGHT/2, SURFACE_WIDTH/2, SURFACE_HEIGHT/2);
837 }
838 else
839 {
840 GX2SetViewport(0.0f, 0.0f, SURFACE_WIDTH, SURFACE_HEIGHT, 0.0f, 1.0f);
841 GX2SetScissor(0, 0, SURFACE_WIDTH, SURFACE_HEIGHT);
842 }
843
844 GX2SetColorBuffer(&DEMOColorBuffer, GX2_RENDER_TARGET_0);
845
846 GX2ClearColor(&DEMOColorBuffer, 0.4f, 0.4f, 0.4f, 0.0f);
847
848 // Set Depth Stencil Control Register
849 GX2SetDepthOnlyControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_NEVER);
850
851 DEMOGfxSetContextState();
852
853 GX2SetShaders(&LightingPass.shaders.fetchShader,
854 LightingPass.shaders.pVertexShader,
855 LightingPass.shaders.pPixelShader);
856
857 // Bind attribute buffers
858 for (u32 attribSlot=0; attribSlot<G_BUFFER_NUM_ATTRIBUTES; attribSlot++)
859 {
860 GX2UTSetAttributeBuffer(&LightingPass.attribs.attributeBuffer[attribSlot], attribSlot, 0);
861 }
862
863 // ------------------------------------------------------------
864
865 GX2InitTexturePtrs(&LightingPass.myTextureBuffer[0], GeometryPass.myColorBuffer[0].surface.imagePtr, 0);
866 GX2InitTexturePtrs(&LightingPass.myTextureBuffer[1], GeometryPass.myColorBuffer[1].surface.imagePtr, 0);
867 GX2InitTexturePtrs(&LightingPass.myTextureBuffer[2], GeometryPass.myColorBuffer[2].surface.imagePtr, 0);
868
869 GX2SetPixelTexture(&LightingPass.myTextureBuffer[0], LightingPass.shaders.samplersPS.location[samplerPSCount]);
870 GX2SetPixelSampler(&LightingPass.mySampler, LightingPass.shaders.samplersPS.location[samplerPSCount]);
871 samplerPSCount += 1;
872 GX2SetPixelTexture(&LightingPass.myTextureBuffer[1], LightingPass.shaders.samplersPS.location[samplerPSCount]);
873 GX2SetPixelSampler(&LightingPass.mySampler, LightingPass.shaders.samplersPS.location[samplerPSCount]);
874 samplerPSCount += 1;
875 GX2SetPixelTexture(&LightingPass.myTextureBuffer[2], LightingPass.shaders.samplersPS.location[samplerPSCount]);
876 GX2SetPixelSampler(&LightingPass.mySampler, LightingPass.shaders.samplersPS.location[samplerPSCount]);
877
878 // Uniform Location Lookup
879 GX2SetPixelUniformReg(LightingPass.shaders.uniformsPS.location[uniformPSCount], 4, &LightingPass.ambientColor);
880 uniformPSCount += 1;
881 GX2SetPixelUniformReg(LightingPass.shaders.uniformsPS.location[uniformPSCount], 4, &LightingPass.lightColor);
882 uniformPSCount += 1;
883 GX2SetPixelUniformReg(LightingPass.shaders.uniformsPS.location[uniformPSCount], 4, &LightingPass.lightPosition);
884 uniformPSCount += 1;
885 GX2SetPixelUniformReg(LightingPass.shaders.uniformsPS.location[uniformPSCount], 4, &LightingPass.cameraPosition);
886
887 // -----------------------
888 // Draw quad
889 GX2UTDrawIndexed(GX2_PRIMITIVE_QUADS, &LightingPass.attribs.indexBuffer);
890
891 }
892
893 // Draw G-Buffers used for Lighting
BuffersPassDraw(void)894 static void BuffersPassDraw(void)
895 {
896 u32 samplerPSCount = 0;
897 u32 uniformVSCount = 0;
898
899 f32 mOffset[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
900
901 if(s_drawBuffers == FALSE)
902 return;
903
904 GX2SetColorBuffer(&DEMOColorBuffer, GX2_RENDER_TARGET_0);
905
906 GX2SetViewport(0.0f, 0.0f, SURFACE_WIDTH, SURFACE_HEIGHT, 0.0f, 1.0f);
907 GX2SetScissor(0, 0, SURFACE_WIDTH, SURFACE_HEIGHT);
908
909 DEMOGfxSetContextState();
910
911 GX2SetShaders(&BuffersPass.shaders.fetchShader,
912 BuffersPass.shaders.pVertexShader,
913 BuffersPass.shaders.pPixelShader);
914
915 // Bind attribute buffers
916 for (u32 attribSlot=0; attribSlot<G_BUFFER_NUM_ATTRIBUTES; attribSlot++)
917 {
918 GX2UTSetAttributeBuffer(&BuffersPass.attribs.attributeBuffer[attribSlot], attribSlot, 0);
919 }
920
921 // ------------------------------------------------------------
922
923 mOffset[0] = -0.5f;
924 mOffset[1] = 0.5f;
925
926 // Uniform Location Lookup
927 GX2SetVertexUniformReg(BuffersPass.shaders.uniformsVS.location[uniformVSCount], 4, mOffset);
928
929 GX2InitTexturePtrs(&BuffersPass.myTextureBuffer[0],
930 GeometryPass.myColorBuffer[0].surface.imagePtr, 0);
931
932 GX2SetPixelTexture(&BuffersPass.myTextureBuffer[0], BuffersPass.shaders.samplersPS.location[samplerPSCount]);
933 GX2SetPixelSampler(&BuffersPass.mySampler, BuffersPass.shaders.samplersPS.location[samplerPSCount]);
934 // -----------------------
935 // Draw quad
936 GX2UTDrawIndexed(GX2_PRIMITIVE_QUADS, &BuffersPass.attribs.indexBuffer);
937
938 // ------------------------------------------------------------
939
940 mOffset[0] = 0.5f;
941 mOffset[1] = 0.5f;
942
943 // Uniform Location Lookup
944 GX2SetVertexUniformReg(BuffersPass.shaders.uniformsVS.location[uniformVSCount], 4, mOffset);
945
946 GX2InitTexturePtrs(&BuffersPass.myTextureBuffer[1],
947 GeometryPass.myColorBuffer[1].surface.imagePtr, 0);
948
949 GX2SetPixelTexture(&BuffersPass.myTextureBuffer[1], BuffersPass.shaders.samplersPS.location[samplerPSCount]);
950 GX2SetPixelSampler(&BuffersPass.mySampler, BuffersPass.shaders.samplersPS.location[samplerPSCount]);
951 // -----------------------
952 // Draw quad
953 GX2UTDrawIndexed(GX2_PRIMITIVE_QUADS, &BuffersPass.attribs.indexBuffer);
954
955 // ------------------------------------------------------------
956
957 mOffset[0] = -0.5f;
958 mOffset[1] = -0.5f;
959
960 // Uniform Location Lookup
961 GX2SetVertexUniformReg(BuffersPass.shaders.uniformsVS.location[uniformVSCount], 4, mOffset);
962
963 GX2InitTexturePtrs(&BuffersPass.myTextureBuffer[2],
964 GeometryPass.myColorBuffer[2].surface.imagePtr, 0);
965
966 GX2SetPixelTexture(&BuffersPass.myTextureBuffer[2], BuffersPass.shaders.samplersPS.location[samplerPSCount]);
967 GX2SetPixelSampler(&BuffersPass.mySampler, BuffersPass.shaders.samplersPS.location[samplerPSCount]);
968 // -----------------------
969 // Draw quad
970 GX2UTDrawIndexed(GX2_PRIMITIVE_QUADS, &BuffersPass.attribs.indexBuffer);
971 }
972
973 #ifndef TEST_MAIN
974 #define TEST_MAIN main
975 #endif
976
TEST_MAIN(int argc,char ** argv)977 int TEST_MAIN(int argc, char **argv)
978 {
979 DEMOInit();
980 DEMOTestInit(argc, argv);
981 DEMOGfxInit(argc, argv);
982 DEMOFontInit();
983
984 SceneInit();
985 while(DEMOIsRunning())
986 {
987 SceneDraw();
988 SceneUpdate();
989 }
990 GX2DrawDone();
991 SceneFree();
992
993 DEMOFontShutdown();
994 DEMOGfxShutdown();
995 DEMOShutdown();
996 return DEMOTestResult();
997 }
998