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 ///  DEMOGfd.c
14 ///
15 ///     This is gfd file interface code for the DEMO library.
16 ///
17 ////===========================================================================
18 
19 #include <cafe/demo.h>
20 
21 // Read Vertex Shader from buffer
DEMOGFDReadVertexShader(GX2VertexShader ** ppShader,u32 index,const void * pData)22 BOOL DEMOGFDReadVertexShader(GX2VertexShader **ppShader, u32 index, const void *pData)
23 {
24     GX2VertexShader *pHeader;
25     void *pProgram;
26     u32 ret;
27     u32 headerSize;
28     u32 programSize;
29 
30     // Check inputs
31     if(pData == NULL || ppShader == NULL)
32     {
33         return FALSE;
34     }
35 
36     // Check index number of shaders
37     if(index >= GFDGetVertexShaderCount(pData))
38     {
39         return FALSE;
40     }
41 
42     // Get the size
43     headerSize = GFDGetVertexShaderHeaderSize(index, pData);
44     programSize = GFDGetVertexShaderProgramSize(index, pData);
45 
46     if(!headerSize || !programSize)
47         return FALSE;
48 
49     // Alloc header
50     pHeader = (GX2VertexShader *)DEMOAllocEx(headerSize, PPC_IO_BUFFER_ALIGN);
51 
52     GX2RBuffer shaderProgram;
53     GX2UTCreateShaderProgram(&shaderProgram, programSize);
54     pProgram = GX2RLockBuffer(&shaderProgram);
55 
56     // Get the shader structure and program
57     // from file buffer into user aligned buffer which created above
58     ret = GFDGetVertexShader(pHeader, pProgram, index, pData);
59 
60     if (ret)
61     {
62         GX2RUnlockBuffer(&shaderProgram);
63         pHeader->shaderPtr = NULL;
64         pHeader->shaderProgram = shaderProgram;
65         *ppShader = pHeader;
66     }
67     else
68     {
69         GX2RUnlockBufferEx(&shaderProgram, GX2R_OPTION_NO_INVALIDATE);
70         OSReport("Warning: Invalid Vertex Shader :%d", ret);
71         // Free if fail
72         if(pHeader)
73             DEMOFree(pHeader);
74 
75         GX2RDestroyBuffer(&shaderProgram);
76     }
77 
78     return ret;
79 }
80 
81 // Read Pixel Shader from buffer
DEMOGFDReadPixelShader(GX2PixelShader ** ppShader,u32 index,const void * pData)82 BOOL DEMOGFDReadPixelShader(GX2PixelShader **ppShader, u32 index, const void *pData)
83 {
84     GX2PixelShader *pHeader;
85     void *pProgram;
86     u32 ret;
87     u32 headerSize;
88     u32 programSize;
89 
90     // Check inputs
91     if(pData == NULL || ppShader == NULL)
92     {
93         OSReport("DEMOGFDReadPixelShader: NULL inputs\n");
94         return FALSE;
95     }
96 
97     // Check index number of shaders
98     if(index >= GFDGetPixelShaderCount(pData))
99     {
100         OSReport("DEMOGFDReadPixelShader: bad index\n");
101         return FALSE;
102     }
103     // Get the size
104     headerSize = GFDGetPixelShaderHeaderSize(index, pData);
105     programSize = GFDGetPixelShaderProgramSize(index, pData);
106 
107     if(!headerSize || !programSize)
108     {
109         OSReport("DEMOGFDReadPixelShader: header or program size is 0\n");
110         return FALSE;
111     }
112 
113     // Alloc header
114     pHeader = (GX2PixelShader *)DEMOAllocEx(headerSize, PPC_IO_BUFFER_ALIGN);
115 
116     // Alloc shader program
117     GX2RBuffer shaderProgram;
118     GX2UTCreateShaderProgram(&shaderProgram, programSize);
119     pProgram = GX2RLockBuffer(&shaderProgram);
120 
121     // Get the shader structure and program
122     // from file buffer into user aligned buffer which created above
123     ret = GFDGetPixelShader(pHeader, pProgram, index, pData);
124 
125     if (ret)
126     {
127         GX2RUnlockBuffer(&shaderProgram);
128         pHeader->shaderPtr = NULL;
129         pHeader->shaderProgram = shaderProgram;
130         *ppShader = pHeader;
131     }
132     else
133     {
134         GX2RUnlockBufferEx(&shaderProgram, GX2R_OPTION_NO_INVALIDATE);
135         OSReport("Warning: Invalid Pixel Shader :%d\n", ret);
136         // Free if fail
137         if(pHeader)
138             DEMOFree(pHeader);
139 
140         GX2RDestroyBuffer(&shaderProgram);
141     }
142 
143     return ret;
144 }
145 
146 // Read Geometry Shader from buffer
DEMOGFDReadGeometryShader(GX2GeometryShader ** ppShader,u32 index,const void * pData)147 BOOL DEMOGFDReadGeometryShader(GX2GeometryShader **ppShader, u32 index, const void *pData)
148 {
149     GX2GeometryShader *pHeader;
150     void *pProgram;
151     void *pCopyProgram;
152     u32 ret;
153     u32 headerSize;
154     u32 programSize;
155     u32 copyProgramSize;
156 
157     // Check inputs
158     if(pData == NULL || ppShader == NULL)
159     {
160         return FALSE;
161     }
162 
163     // Check index number of shaders
164     if(index >= GFDGetGeometryShaderCount(pData))
165     {
166         return FALSE;
167     }
168 
169     // Get the size
170     headerSize = GFDGetGeometryShaderHeaderSize(index, pData);
171     programSize = GFDGetGeometryShaderProgramSize(index, pData);
172     copyProgramSize = GFDGetGeometryShaderCopyProgramSize(index, pData);
173 
174     if(!headerSize || !programSize)
175         return FALSE;
176 
177     // Alloc header
178     pHeader = (GX2GeometryShader *)DEMOAllocEx(headerSize, PPC_IO_BUFFER_ALIGN);
179 
180     // Create shader program buffer
181     GX2RBuffer shaderProgram;
182     GX2UTCreateShaderProgram(&shaderProgram, programSize);
183 
184     // Alloc copy shader program (Must be aligned on 256 byte boundary.)
185     GX2RBuffer copyShaderProgram;
186     GX2UTCreateShaderProgram(&copyShaderProgram, copyProgramSize);
187 
188     pProgram = GX2RLockBuffer(&shaderProgram);
189     pCopyProgram = GX2RLockBuffer(&copyShaderProgram);
190 
191     // Get the shader structure and program
192     // from file buffer into user aligned buffer which created above
193     ret = GFDGetGeometryShader(pHeader, pProgram, pCopyProgram, index, pData);
194 
195     if(ret)
196     {
197         GX2RUnlockBuffer(&shaderProgram);
198         GX2RUnlockBuffer(&copyShaderProgram);
199 
200         pHeader->shaderPtr = NULL;
201         pHeader->shaderProgram = shaderProgram;
202         pHeader->copyShaderPtr = NULL;
203         pHeader->copyShaderProgram = copyShaderProgram;
204         *ppShader = pHeader;
205     }
206     else
207     {
208         OSReport("Warning: Invalid Geometry Shader :%d", ret);
209         // Free if fail
210         if(pHeader)
211             DEMOFree(pHeader);
212 
213         GX2RUnlockBufferEx(&shaderProgram, GX2R_OPTION_NO_INVALIDATE);
214         GX2RUnlockBufferEx(&copyShaderProgram, GX2R_OPTION_NO_INVALIDATE);
215 
216         GX2RDestroyBuffer(&shaderProgram);
217         GX2RDestroyBuffer(&copyShaderProgram);
218     }
219 
220     return ret;
221 }
222 
223 // Read Compute Shader from buffer
DEMOGFDReadComputeShader(GX2ComputeShader ** ppShader,u32 index,const void * pData)224 BOOL DEMOGFDReadComputeShader(GX2ComputeShader **ppShader, u32 index, const void *pData)
225 {
226     GX2ComputeShader *pHeader;
227     void *pProgram;
228     u32 ret;
229     u32 headerSize;
230     u32 programSize;
231 
232     // Check inputs
233     if(pData == NULL || ppShader == NULL)
234     {
235         return FALSE;
236     }
237 
238     // Check index number of shaders
239     if(index >= GFDGetComputeShaderCount(pData))
240     {
241         return FALSE;
242     }
243 
244     // Get the size
245     headerSize = GFDGetComputeShaderHeaderSize(index, pData);
246     programSize = GFDGetComputeShaderProgramSize(index, pData);
247 
248     if(!headerSize || !programSize)
249         return FALSE;
250 
251     // Alloc header
252     pHeader = (GX2ComputeShader *)DEMOAllocEx(headerSize, PPC_IO_BUFFER_ALIGN);
253 
254     GX2RBuffer shaderProgram;
255     GX2UTCreateShaderProgram(&shaderProgram, programSize);
256     pProgram = GX2RLockBuffer(&shaderProgram);
257 
258     // Get the shader structure and program
259     // from file buffer into user aligned buffer which created above
260     ret = GFDGetComputeShader(pHeader, pProgram, index, pData);
261 
262     if (ret)
263     {
264         GX2RUnlockBuffer(&shaderProgram);
265         pHeader->shaderPtr = NULL;
266         pHeader->shaderProgram = shaderProgram;
267         *ppShader = pHeader;
268     }
269     else
270     {
271         GX2RUnlockBufferEx(&shaderProgram, GX2R_OPTION_NO_INVALIDATE);
272         OSReport("Warning: Invalid Compute Shader :%d", ret);
273         // Free if fail
274         if(pHeader)
275             DEMOFree(pHeader);
276 
277         GX2RDestroyBuffer(&shaderProgram);
278     }
279 
280     return ret;
281 }
282 
283 // Read texture from buffer
DEMOGFDReadTexture(GX2Texture ** ppTexture,u32 index,const void * pData)284 BOOL DEMOGFDReadTexture(GX2Texture **ppTexture, u32 index, const void *pData)
285 {
286     GX2Texture *pHeader;
287     u32 ret;
288     u32 headerSize;
289     u32 imageSize;
290 
291     // Check inputs
292     if(pData == NULL || ppTexture == NULL)
293     {
294         return FALSE;
295     }
296 
297     // Check index number of shaders
298     if(index >= GFDGetTextureCount(pData))
299     {
300         return FALSE;
301     }
302 
303     // Get the size of texture header, image and align
304     headerSize = GFDGetTextureHeaderSize(index, pData);
305     imageSize  = GFDGetTextureImageSize(index, pData);
306 
307     if(!headerSize || !imageSize)
308         return FALSE;
309 
310     pHeader = (GX2Texture *)DEMOAllocEx(headerSize, PPC_IO_BUFFER_ALIGN);
311 
312     ret = GFDGetGX2RTexture(pHeader, index, pData);
313 
314     if(!ret)
315     {
316         OSReport("Warning: Invalid Texture :%d", ret);
317         // Free if fail
318         if(pHeader)
319             DEMOFree(pHeader);
320 
321         return ret;
322     }
323     else
324     {
325         // Set the return pointer to the texture header struct
326         *ppTexture = pHeader;
327     }
328 
329     return ret;
330 }
331 
332 // Free vertex shader
DEMOGFDFreeVertexShader(GX2VertexShader * pShader)333 void DEMOGFDFreeVertexShader(GX2VertexShader *pShader)
334 {
335     if(pShader)
336     {
337         if(pShader->shaderPtr)
338             DEMOGfxFreeMEM2(pShader->shaderPtr);
339         else
340             GX2RDestroyBuffer(&pShader->shaderProgram);
341 
342         DEMOFree(pShader);
343     }
344 }
345 
346 // Free pixel shader
DEMOGFDFreePixelShader(GX2PixelShader * pShader)347 void DEMOGFDFreePixelShader(GX2PixelShader *pShader)
348 {
349     if(pShader)
350     {
351         if(pShader->shaderPtr)
352             DEMOGfxFreeMEM2(pShader->shaderPtr);
353         else
354             GX2RDestroyBuffer(&pShader->shaderProgram);
355 
356         DEMOFree(pShader);
357     }
358 }
359 
360 // Free geometry shader
DEMOGFDFreeGeometryShader(GX2GeometryShader * pShader)361 void DEMOGFDFreeGeometryShader(GX2GeometryShader *pShader)
362 {
363     if(pShader)
364     {
365         if(pShader->shaderPtr)
366             DEMOGfxFreeMEM2(pShader->shaderPtr);
367         else
368             GX2RDestroyBuffer(&pShader->shaderProgram);
369 
370         if(pShader->copyShaderPtr)
371             DEMOGfxFreeMEM2(pShader->copyShaderPtr);
372         else
373             GX2RDestroyBuffer(&pShader->copyShaderProgram);
374 
375         DEMOFree(pShader);
376     }
377 }
378 
379 // Free compute shader
DEMOGFDFreeComputeShader(GX2ComputeShader * pShader)380 void DEMOGFDFreeComputeShader(GX2ComputeShader *pShader)
381 {
382     if(pShader)
383     {
384         if(pShader->shaderPtr)
385             DEMOGfxFreeMEM2(pShader->shaderPtr);
386         else
387             GX2RDestroyBuffer(&pShader->shaderProgram);
388 
389         DEMOFree(pShader);
390     }
391 }
392 
393 // Free texture
DEMOGFDFreeTexture(GX2Texture * pTexture)394 void DEMOGFDFreeTexture(GX2Texture *pTexture)
395 {
396     if(pTexture)
397     {
398         GX2RDestroySurface(&pTexture->surface);
399         DEMOFree(pTexture);
400     }
401 }
402 
403 
404 // Read Aligned Texture
DEMOGFDReadAlignedTexture(void ** pFileBuf,u32 index,u32 align,const char * fileName)405 GX2Texture* DEMOGFDReadAlignedTexture(void **pFileBuf, u32 index, u32 align, const char *fileName)
406 {
407     u32 len;
408     GX2Texture *pTexture;
409 
410     // Read the texture file into a buffer
411     *pFileBuf = DEMOGfxLoadAssetFileAlign(fileName, &len, align);
412 
413     // Check Align mode of the buffer
414     if(GFDGetAlignMode(*pFileBuf) != GFD_ALIGN_MODE_ENABLE)
415     {
416         DEMOGFDFreeAlignedTexture(*pFileBuf);
417         ASSERT(!"Input file isn't aligned. Please use \"-align\" option when it is created by tool.");
418         return NULL;
419     }
420 
421     pTexture = GFDGetGX2RTexturePointer(index, *pFileBuf);
422 
423     return pTexture;
424 }
425 
426 // Free Aligned Texture
DEMOGFDFreeAlignedTexture(void * pFileBuf)427 void DEMOGFDFreeAlignedTexture(void *pFileBuf)
428 {
429     if(pFileBuf)
430     {
431         DEMOFree(pFileBuf);
432 
433         // Destroy the GX2RSurface objects
434         u32 textureCount = GFDGetTextureCount(pFileBuf);
435         for (u32 i=0; i<textureCount; i++)
436         {
437             GX2Texture* pTexture = GFDGetTexturePointer(i, pFileBuf);
438             GX2RDestroySurface(&pTexture->surface);
439         }
440     }
441 }
442