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 ///  demoGfxShader.c
14 ///
15 ///     This is graphics shader system code for the DEMO library.
16 ///
17 ////===========================================================================
18 
19 #include <cafe/demo.h>
20 #include <cafe/gx2.h>
21 #include <cafe/gfd.h>
22 
DEMOGfxLoadShaders(DEMOGfxShader * pShader,u32 index,const void * pData)23 BOOL DEMOGfxLoadShaders(DEMOGfxShader *pShader, u32 index, const void *pData)
24 {
25     memset(pShader, 0, sizeof(DEMOGfxShader));
26 
27     // Load shaders from memory.
28     if(!DEMOGFDReadVertexShader(&pShader->pVertexShader, index, pData))
29     {
30         OSReport("Warning : The file did not contain a vertex shader\n");
31         return FALSE;
32     }
33     if(!DEMOGFDReadPixelShader(&pShader->pPixelShader, index, pData))
34     {
35         OSReport("Warning : The file did not contain a pixel shader\n");
36         return FALSE;
37     }
38 
39     if(!DEMOGFDReadGeometryShader(&pShader->pGeometryShader, index, pData))
40     {
41         //OSReport("Warning : The file did not contain a geometry shader\n");
42         //return FALSE;
43     }
44 
45     return TRUE;
46 }
47 
DEMOGfxInitShaderAttribute(DEMOGfxShader * pShader,const char * name,u32 bufferIndex,u32 offset,GX2AttribFormat format)48 BOOL DEMOGfxInitShaderAttribute(DEMOGfxShader *pShader, const char *name,
49                                 u32 bufferIndex, u32 offset, GX2AttribFormat format)
50 {
51     if(!pShader)
52     {
53         OSReport("Error : Null pointer.\n");
54         return FALSE;
55     }
56     if(bufferIndex > GX2_MAX_ATTRIB_BUFFERS )
57     {
58         OSReport("Warning : The attribute buffer index (%d) is over %d\n", bufferIndex, GX2_MAX_ATTRIB_BUFFERS);
59         return FALSE;
60     }
61     // Get location
62 
63     u32 location = (u32)GX2GetVertexAttribVarLocation(pShader->pVertexShader, name);
64     ASSERT(DEMOGfxCheckShaderLocation(location));
65 
66     // Initialize the vertex attribute structure for the fetch shader.
67     GX2InitAttribStream(&pShader->attribs[pShader->attribCount],
68                         location, bufferIndex, offset, format);
69 
70     // Increase count
71     pShader->attribCount++;
72     return TRUE;
73 }
74 
DEMOGfxGetVertexShaderSamplerLocation(DEMOGfxShader * pShader,const char * name)75 BOOL DEMOGfxGetVertexShaderSamplerLocation(DEMOGfxShader *pShader, const char *name)
76 {
77     if(!pShader)
78     {
79         OSReport("Error : Null pointer.\n");
80         return FALSE;
81     }
82     if(pShader->samplersVS.count > GX2_MAX_SAMPLERS )
83     {
84         OSReport("Warning : The sampler count (%d) in VS is over %d\n", pShader->samplersVS.count, GX2_MAX_SAMPLERS);
85         return FALSE;
86     }
87 
88     // Set sampler data
89     pShader->samplersVS.location[pShader->samplersVS.count] =
90     (u32)GX2GetVertexSamplerVarLocation(pShader->pVertexShader, name);
91     ASSERT(DEMOGfxCheckShaderLocation(pShader->samplersVS.location[pShader->samplersVS.count]));
92 
93     // Increase count
94     pShader->samplersVS.count++;
95     return TRUE;
96 }
97 
DEMOGfxGetPixelShaderSamplerLocation(DEMOGfxShader * pShader,const char * name)98 BOOL DEMOGfxGetPixelShaderSamplerLocation(DEMOGfxShader *pShader, const char *name)
99 {
100     if(!pShader)
101     {
102         OSReport("Error : Null pointer.\n");
103         return FALSE;
104     }
105     if(pShader->samplersPS.count > GX2_MAX_SAMPLERS )
106     {
107         OSReport("Warning : The sampler count (%d) in PS is over %d\n", pShader->samplersPS.count, GX2_MAX_SAMPLERS);
108         return FALSE;
109     }
110 
111     // Get sampler location
112     pShader->samplersPS.location[pShader->samplersPS.count] =
113     (u32)GX2GetPixelSamplerVarLocation(pShader->pPixelShader, name);
114     ASSERT(DEMOGfxCheckShaderLocation(pShader->samplersPS.location[pShader->samplersPS.count]));
115 
116     // Increase count
117     pShader->samplersPS.count++;
118     return TRUE;
119 }
120 
DEMOGfxGetGeometryShaderSamplerLocation(DEMOGfxShader * pShader,const char * name)121 BOOL DEMOGfxGetGeometryShaderSamplerLocation(DEMOGfxShader *pShader, const char *name)
122 {
123     if(!pShader)
124     {
125         OSReport("Error : Null pointer.\n");
126         return FALSE;
127     }
128     if(pShader->samplersGS.count > GX2_MAX_SAMPLERS )
129     {
130         OSReport("Warning : The sampler count (%d) in GS is over %d\n", pShader->samplersGS.count, GX2_MAX_SAMPLERS);
131         return FALSE;
132     }
133 
134     // Get sampler location
135     pShader->samplersGS.location[pShader->samplersGS.count] =
136     (u32)GX2GetGeometrySamplerVarLocation(pShader->pGeometryShader, name);
137     ASSERT(DEMOGfxCheckShaderLocation(pShader->samplersGS.location[pShader->samplersGS.count]));
138 
139     // Increase count
140     pShader->samplersGS.count++;
141     return TRUE;
142 }
143 
DEMOGfxGetVertexShaderUniformLocation(DEMOGfxShader * pShader,const char * name)144 BOOL DEMOGfxGetVertexShaderUniformLocation(DEMOGfxShader *pShader, const char *name)
145 {
146     if(!pShader)
147     {
148         OSReport("Error : Null pointer.\n");
149         return FALSE;
150     }
151     if(pShader->uniformsVS.count > GX2_MAX_VS_UNIFORM_VARS )
152     {
153         OSReport("Warning : The uniform count (%d) in VS is over %d\n", pShader->uniformsVS.count, GX2_MAX_VS_UNIFORM_VARS);
154         return FALSE;
155     }
156 
157     // Get uniform location
158     pShader->uniformsVS.location[pShader->uniformsVS.count] =
159     (u32)GX2GetVertexUniformVarOffset(pShader->pVertexShader, name);
160     ASSERT(DEMOGfxCheckShaderLocation(pShader->uniformsVS.location[pShader->uniformsVS.count]));
161 
162     // Increase count
163     pShader->uniformsVS.count++;
164     return TRUE;
165 }
166 
DEMOGfxGetPixelShaderUniformLocation(DEMOGfxShader * pShader,const char * name)167 BOOL DEMOGfxGetPixelShaderUniformLocation(DEMOGfxShader *pShader, const char *name)
168 {
169     if(!pShader)
170     {
171         OSReport("Error : Null pointer.\n");
172         return FALSE;
173     }
174     if(pShader->uniformsPS.count > GX2_MAX_PS_UNIFORM_VARS )
175     {
176         OSReport("Warning : The uniform count (%d) in PS is over %d\n", pShader->uniformsPS.count, GX2_MAX_PS_UNIFORM_VARS);
177         return FALSE;
178     }
179     // Get uniform location
180     pShader->uniformsPS.location[pShader->uniformsPS.count] =
181     (u32)GX2GetPixelUniformVarOffset(pShader->pPixelShader, name);
182     ASSERT(DEMOGfxCheckShaderLocation(pShader->uniformsPS.location[pShader->uniformsPS.count]));
183 
184     // Increase count
185     pShader->uniformsPS.count++;
186     return TRUE;
187 }
188 
DEMOGfxGetVertexShaderUniformBlockLocation(DEMOGfxShader * pShader,const char * name)189 BOOL DEMOGfxGetVertexShaderUniformBlockLocation(DEMOGfxShader *pShader, const char *name)
190 {
191     if(!pShader)
192     {
193         OSReport("Error : Null pointer.\n");
194         return FALSE;
195     }
196     if(pShader->uniformBlocksVS.count > GX2_MAX_UNIFORM_BLOCKS )
197     {
198         OSReport("Warning : The uniform block count (%d) in VS is over %d\n", pShader->uniformBlocksVS.count, GX2_MAX_UNIFORM_BLOCKS);
199         return FALSE;
200     }
201     GX2UniformBlock *block = GX2GetVertexUniformBlock(pShader->pVertexShader, name);
202 
203     // Get uniform block location and size
204     pShader->uniformBlocksVS.location[pShader->uniformBlocksVS.count] = block->location;
205     pShader->uniformBlocksVS.size[pShader->uniformBlocksVS.count] = block->size;
206     ASSERT(DEMOGfxCheckShaderLocation(pShader->uniformBlocksVS.location[pShader->uniformBlocksVS.count]));
207 
208     // Increase count
209     pShader->uniformBlocksVS.count++;
210     return TRUE;
211 }
212 
DEMOGfxGetPixelShaderUniformBlockLocation(DEMOGfxShader * pShader,const char * name)213 BOOL DEMOGfxGetPixelShaderUniformBlockLocation(DEMOGfxShader *pShader, const char *name)
214 {
215     if(!pShader)
216     {
217         OSReport("Error : Null pointer.\n");
218         return FALSE;
219     }
220     if(pShader->uniformBlocksPS.count > GX2_MAX_UNIFORM_BLOCKS )
221     {
222         OSReport("Warning : The uniform block count (%d) in PS is over %d\n", pShader->uniformBlocksPS.count, GX2_MAX_UNIFORM_BLOCKS);
223         return FALSE;
224     }
225     GX2UniformBlock *block = GX2GetPixelUniformBlock(pShader->pPixelShader, name);
226 
227     // Get uniform block location and size
228     pShader->uniformBlocksPS.location[pShader->uniformBlocksPS.count] = block->location;
229     pShader->uniformBlocksPS.size[pShader->uniformBlocksPS.count] = block->size;
230     ASSERT(DEMOGfxCheckShaderLocation(pShader->uniformBlocksPS.location[pShader->uniformBlocksPS.count]));
231 
232     // Increase count
233     pShader->uniformBlocksPS.count++;
234     return TRUE;
235 }
236 
DEMOGfxGetGeometryShaderUniformBlockLocation(DEMOGfxShader * pShader,const char * name)237 BOOL DEMOGfxGetGeometryShaderUniformBlockLocation(DEMOGfxShader *pShader, const char *name)
238 {
239     if(!pShader)
240     {
241         OSReport("Error : Null pointer.\n");
242         return FALSE;
243     }
244     if(pShader->uniformBlocksGS.count > GX2_MAX_UNIFORM_BLOCKS )
245     {
246         OSReport("Warning : The uniform block count (%d) in GS is over %d\n", pShader->uniformBlocksGS.count, GX2_MAX_UNIFORM_BLOCKS);
247         return FALSE;
248     }
249     GX2UniformBlock *block = GX2GetGeometryUniformBlock(pShader->pGeometryShader, name);
250 
251     // Get uniform block location and size
252     pShader->uniformBlocksGS.location[pShader->uniformBlocksGS.count] = block->location;
253     pShader->uniformBlocksGS.size[pShader->uniformBlocksGS.count] = block->size;
254     ASSERT(DEMOGfxCheckShaderLocation(pShader->uniformBlocksGS.location[pShader->uniformBlocksGS.count]));
255 
256     // Increase count
257     pShader->uniformBlocksGS.count++;
258     return TRUE;
259 }
260 
DEMOGfxInitFetchShader(DEMOGfxShader * pShader)261 BOOL DEMOGfxInitFetchShader(DEMOGfxShader *pShader)
262 {
263     if(!pShader)
264     {
265         OSReport("Error : Null pointer.\n");
266         return FALSE;
267     }
268     // Allocate memory for the fetch shader based on the number of attributes
269     // for the vertex shader.
270     u32 shaderSize = GX2CalcFetchShaderSize(pShader->attribCount); // size in bytes
271     pShader->pFetchShaderBuffer = DEMOGfxAllocMEM2(shaderSize, GX2_SHADER_ALIGNMENT);
272 
273     // Initialize the fetch shader. This will construct the fetch shader to
274     // use later in a call to GX2SetShaders.
275     GX2InitFetchShader(&pShader->fetchShader,
276                        pShader->pFetchShaderBuffer,
277                        pShader->attribCount,
278                        pShader->attribs);
279 
280     ASSERT(pShader->fetchShader.shaderSize == shaderSize);
281 
282     GX2Invalidate(GX2_INVALIDATE_CPU_SHADER, pShader->pFetchShaderBuffer, shaderSize);
283     return TRUE;
284 }
285 
DEMOGfxFreeShaders(DEMOGfxShader * pShader)286 BOOL DEMOGfxFreeShaders(DEMOGfxShader *pShader)
287 {
288     if(!pShader)
289     {
290         OSReport("Error : Null pointer.\n");
291         return FALSE;
292     }
293     // Free memory for the fetch shader
294     if(pShader->pFetchShaderBuffer)
295         DEMOGfxFreeMEM2(pShader->pFetchShaderBuffer);
296     if(pShader->pVertexShader)
297         DEMOGFDFreeVertexShader(pShader->pVertexShader);
298     if(pShader->pPixelShader)
299         DEMOGFDFreePixelShader(pShader->pPixelShader);
300     if(pShader->pGeometryShader)
301         DEMOGFDFreeGeometryShader(pShader->pGeometryShader);
302 
303     return TRUE;
304 }
305