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(©ShaderProgram, copyProgramSize);
187
188 pProgram = GX2RLockBuffer(&shaderProgram);
189 pCopyProgram = GX2RLockBuffer(©ShaderProgram);
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(©ShaderProgram);
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(©ShaderProgram, GX2R_OPTION_NO_INVALIDATE);
215
216 GX2RDestroyBuffer(&shaderProgram);
217 GX2RDestroyBuffer(©ShaderProgram);
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