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