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