1 
2 /*---------------------------------------------------------------------------*
3 
4   Copyright (C) 2010-2011 Nintendo.  All rights reserved.
5 
6   These coded instructions, statements, and computer programs contain
7   proprietary information of Nintendo of America Inc. and/or Nintendo
8   Company Ltd., and are protected by Federal copyright law.  They may
9   not be disclosed to third parties or copied or duplicated in any form,
10   in whole or in part, without the prior written consent of Nintendo.
11 
12  *---------------------------------------------------------------------------*/
13 // -------------------------------------------------------
14 //   gx2Shaders.h       (Shared between PC:gshConvert and Gx2)
15 //
16 //
17 //   Declares shader-related types & functions for gx2 library.
18 //
19 //   Note.  Many of the structures in this file exist in serialized
20 //   format in Gfx2 shader files.  Modifying any of the structures
21 //   hence runs huge risk of invalidating any or all shader files.
22 //
23 //   Because these structures are also used on the PC,
24 //   do not add non-32-bit element fields to these data structures.
25 //   They will not serialize correctly.
26 // --------------------------------------------------------
27 
28 #ifndef _CAFE_GX2_SHADERS_H_
29 #define _CAFE_GX2_SHADERS_H_
30 
31 #include <string.h>
32 #include <cafe/gx2/gx2rResource.h>
33 
34 #ifdef __cplusplus
35 extern "C"
36 {
37 #endif // __cplusplus
38 
39 /// @addtogroup GX2ShaderGroup
40 /// @{
41 
42 /// @addtogroup GX2ShaderAllGroup
43 /// @{
44 
45 //----------------------------------------------------------------------
46 // Defines
47 
48 /// \brief The number of registers used to describe vertex shaders
49 #define GX2_NUM_VERTEX_SHADER_REGISTERS      52
50 
51 /// \brief The number of registers used to describe geometry shaders
52 #define GX2_NUM_GEOMETRY_SHADER_REGISTERS      19
53 
54 /// \brief The number of registers used to describe pixel shaders
55 #define GX2_NUM_PIXEL_SHADER_REGISTERS      41
56 
57 /// \brief The number of registers used to describe fetch shaders
58 #define GX2_NUM_FETCH_SHADER_REGISTERS      1
59 
60 /// \brief The number of registers used to describe compute shaders
61 #define GX2_NUM_COMPUTE_SHADER_REGISTERS      12
62 
63 /// \brief The number of u32 values used to describe loop vars
64 #define GX2_NUM_LOOP_VAR_U32_WORDS      2
65 
66 // ---------------------------------------
67 // Shader data structures
68 
69 /// \brief Shader Uniform Block Structure
70 ///
71 /// A Uniform Block is a container for one or more Uniform Block Variables stored sequentially
72 ///
73 typedef struct _GX2UniformBlock
74 {
75     /// Name of uniform block
76     const char * name;
77     /// Hardware location of uniform block, determined by the shader compiler
78     u32          location;
79     /// Size of the overall block, in bytes
80     u32          size;
81 } GX2UniformBlock;
82 
83 /// \brief Uniform Initial Value Structure
84 ///
85 /// Contains initial uniform value along with corresponding offset
86 ///
87 typedef struct _GX2UniformInitialValue
88 {
89     /// Initial uniform value
90     f32 value[4];
91     /// Register offset
92     u32 offset;
93 } GX2UniformInitialValue;
94 
95 /// \brief Shader Uniform Variable Structure
96 ///
97 /// \note This applies to both Uniform Registers and Uniform Blocks (as specified)
98 ///
99 typedef struct _GX2UniformVar
100 {
101     /// Name of uniform (imported from shader)
102     const char *     name;
103     /// Variable data type. Use \ref GX2VarTypeToCount to convert to a count.
104     GX2VarType       type;
105     /// Number of elements in an array. Set to one for non-arrays.
106     u32              arrayCount;
107     /// Usually an offset into uniform block or register file, in number of u32's; for loop limits have a special encoding with flag bits set in the upper 16 bits
108     u32              offset;
109     /// Which uniform block this uniform belongs to.
110     ///
111     /// For Uniform Blocks, this is the index into the GX2*Shader.uniformBlocks array.
112     /// Range is 0 to (GX2*Shader.numUniformBlocks - 1)
113     ///
114     /// For Uniforms Registers, this is always GX2_UNIFORM_BLOCK_INDEX_INVALID.
115     ///
116     /// This should not be confused with GX2UniformBlock.location.
117     u32              blockIndex;
118 } GX2UniformVar;
119 
120 /// \brief Vertex Attribute Variable (as seen by the Vertex Shader)
121 ///
122 typedef struct _GX2AttribVar
123 {
124     /// Name of attribute
125     const char * name;
126     /// Variable type
127     GX2VarType   type;
128     /// Number of elements in an array. Set to one for non-arrays.
129     u32          arrayCount;
130     /// Attribute location in hardware semantic table
131     u32          location;
132 } GX2AttribVar;
133 
134 /// \brief Vertex Attribute Stream (as seen by the Fetch Shader)
135 ///
136 typedef struct _GX2AttribStream
137 {
138     /// Attribute location (destination) on hardware. See \ref GX2AttribVar (location)
139     u32 location;
140     /// Vertex Buffer index (source) to read from. Should match index in \ref GX2SetAttribBuffer.
141     u32 buffer;
142     /// Byte offset from start of vertex buffer to this element
143     u32 offset;
144     /// Vertex stream data is in this format
145     GX2AttribFormat format;
146     /// Vertex stream data fetch element index type
147     /// (vertex Id or instance Id)
148     GX2AttribIndexType indexType;
149     /// This only applies when indexType == GX2_ATTRIB_INDEX_INSTANCE_ID.
150     /// If greater than 1, the element index is further integer divided by
151     /// aluDivisor. You may have up to 2 unique divisors that are > 1 in a
152     /// a given fetch shader. More than 2 such divisors might be supported
153     /// in a future SDK; this requires additional fetch shader instructions.
154     /// Note: Divisors > 1 are not compatible with tessellation.
155     u32 aluDivisor;
156     /// Per-component destination selects for writing into destination GPR
157     GX2CompSel destSel;
158 
159     /// Endian swap mode to use when reading the data
160     GX2EndianSwapMode endianSwap;
161 } GX2AttribStream;
162 
163 /// \brief Texture Sampler as seen by pixel and vertex shaders.
164 ///
165 /// \note The location value applies to both the texture number and the sampler number.
166 ///
167 typedef struct _GX2SamplerVar
168 {
169     /// Name of texture sampler
170     const char       * name;
171     /// Sampler type
172     GX2SamplerType     type;
173     /// Hardware location of texture and sampler
174     u32                location;
175 } GX2SamplerVar;
176 
177 /// @}
178 /// @addtogroup GX2ShaderVertexGroup
179 /// @{
180 
181 // !!!Note!!! - The GX2VertexShader structure is burned into a .gsh file.
182 // Altering parameters or changing their order may invalidate all existing content.
183 
184 /// \brief Contains all information (user and private) for a vertex shader
185 ///
186 typedef struct _GX2VertexShader
187 {
188     /// All register information needed to setup GPU7 (private)
189     u32 _regs[GX2_NUM_VERTEX_SHADER_REGISTERS];
190 
191     /// size of shader program, in bytes
192     u32                 shaderSize;
193     /// pointer to shader program.  Must be aligned on 256 byte boundary.
194     void              * shaderPtr;
195 
196     /// Shader mode for uniforms \ref GX2SetShaderMode
197     GX2ShaderMode       shaderMode;
198 
199     /// Number of Uniform Blocks (only for \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_GEOMETRY_SHADER)
200     u32                 numUniformBlocks;
201     /// Uniform Blocks (only for \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_GEOMETRY_SHADER)
202     GX2UniformBlock   * uniformBlocks;
203 
204     /// Number of Vertex Shader Uniforms
205     u32                 numUniforms;
206     /// Vertex Shader Uniforms
207     GX2UniformVar     * uniformVars;
208 
209     /// Number of initial values for Uniforms. Count is in Vec4s
210     /// (Matrix data types may have 2-4 rows).
211     u32                         numInitialValues;
212     /// Initial values for Uniforms
213     GX2UniformInitialValue    * initialValues;
214 
215     /// Number of loop variables (private)
216     u32                 _numLoops;
217     /// Loops variables (private)
218     void              * _loopVars;
219 
220     /// Number of Sampler variables
221     u32                 numSamplers;
222     /// Samplers variables
223     GX2SamplerVar     * samplerVars;
224 
225     /// Number of Attribute variables
226     u32                 numAttribs;
227     /// Attribute variables
228     GX2AttribVar      * attribVars;
229 
230     // Space allocated to a single vertex in the GS Input ring buffer (in u32's).
231     // The number of 32-bit values written by the shader per vertex.
232     u32 ringItemsize;
233 
234     /// The shader contains stream out write instructions.
235     GX2Boolean hasStreamOut;
236 
237     /// stride (in bytes) between each vertex for each stream out target
238     u32 streamOutVertexStride[GX2_MAX_STREAMOUT_BUFFERS];
239 
240     /// use a GX2RBuffer for the shader program instead of shaderPtr and shaderSize. shaderPtr must be NULL.
241     GX2RBuffer          shaderProgram;
242 } GX2VertexShader;
243 
244 /// @}
245 /// @addtogroup GX2ShaderGeometryGroup
246 /// @{
247 
248 // !!!Note!!! - The GX2GeometryShader structure is burned into a .gsh file.
249 // Altering parameters or changing their order may invalidate all existing content.
250 
251 /// \brief Contains all information (user and private) for a geometry shader
252 ///
253 typedef struct _GX2GeometryShader
254 {
255     /// All register information needed to setup GPU7 (private)
256     u32 _regs[GX2_NUM_GEOMETRY_SHADER_REGISTERS];
257 
258     /// size of the GS shader program, in bytes
259     u32 shaderSize;
260     /// pointer to GS shader program. Must be aligned on a 256 byte boundary.
261     void * shaderPtr;
262 
263     /// size of the copy shader program, in bytes
264     u32 copyShaderSize;
265     /// pointer to copy shader program. Must be aligned on a 256 byte boundary.
266     void * copyShaderPtr;
267 
268 
269     /// Shader mode for uniforms \ref GX2SetShaderMode
270     /// At the moment, must always be GX2_SHADER_MODE_GEOMETRY_SHADER.
271     GX2ShaderMode       shaderMode;
272 
273     /// Number of Uniform Blocks
274     u32                 numUniformBlocks;
275     /// Uniform Blocks
276     GX2UniformBlock   * uniformBlocks;
277 
278     /// Number of Vertex Shader Uniforms
279     u32                 numUniforms;
280     /// Vertex Shader Uniforms
281     GX2UniformVar     * uniformVars;
282 
283     /// Number of initial values for Uniforms. Count is in Vec4s
284     /// (Matrix data types may have 2-4 rows).
285     u32                         numInitialValues;
286     /// Initial values for Uniforms
287     GX2UniformInitialValue    * initialValues;
288 
289     /// Number of loop variables (private)
290     u32                 _numLoops;
291     /// Loops variables (private)
292     void              * _loopVars;
293 
294     /// Number of Sampler variables
295     u32                 numSamplers;
296     /// Samplers variables
297     GX2SamplerVar     * samplerVars;
298 
299     // Space allocated to a single primitive in the GS output ring buffer (in u32's).
300     // The number of 32-bit values written by the shader is the number
301     // of vertices output * the amount of data per vertex.
302     u32 ringItemsize;
303 
304     /// The shader contains stream out write instructions.
305     GX2Boolean hasStreamOut;
306 
307     /// stride (in bytes) between each vertex for each stream out target
308     u32 streamOutVertexStride[GX2_MAX_STREAMOUT_BUFFERS];
309 
310     /// use a GX2RBuffer for the shader program instead of shaderPtr and shaderSize. shaderPtr must be NULL.
311     GX2RBuffer          shaderProgram;
312 
313     /// use a GX2RBuffer for the shader program instead of shaderPtr and shaderSize. shaderPtr must be NULL.
314     GX2RBuffer          copyShaderProgram;
315 
316 } GX2GeometryShader;
317 
318 // !!!Note!!! - The GX2PixelShader structure is burned into a .gsh file.
319 // Altering parameters or changing their order may invalidate all existing content.
320 
321 /// @}
322 /// @addtogroup GX2ShaderPixelGroup
323 /// @{
324 
325 /// \brief Contains all information (user and private) for a pixel shader
326 ///
327 typedef struct _GX2PixelShader
328 {
329     /// All register information needed to setup GPU7 (private)
330     u32  _regs[GX2_NUM_PIXEL_SHADER_REGISTERS];
331 
332     /// size of shader program, in bytes
333     u32                 shaderSize;
334     /// pointer to shader program.  Must be aligned on 256 byte boundary.
335     void              * shaderPtr;
336 
337     /// Shader mode for uniforms \ref GX2SetShaderMode
338     GX2ShaderMode       shaderMode;
339 
340     /// Number of Uniform Blocks (only for \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_GEOMETRY_SHADER)
341     u32                 numUniformBlocks;
342     /// Uniform Blocks (only for \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_GEOMETRY_SHADER)
343     GX2UniformBlock   * uniformBlocks;
344 
345     /// Number of Pixel Shader Uniforms
346     u32                 numUniforms;
347     /// Pixel Shader Uniforms
348     GX2UniformVar     * uniformVars;
349 
350     /// Number of initial values for Uniforms. Count is in Vec4s
351     /// (Matrix data types may have 2-4 rows).
352     u32                         numInitialValues;
353     /// Initial values for Uniforms
354     GX2UniformInitialValue    * initialValues;
355 
356     /// Number of loop variables (private)
357     u32                 _numLoops;
358     /// Loops variables (private)
359     void              * _loopVars;
360 
361     /// Number of Sampler variables
362     u32                 numSamplers;
363     /// Samplers variables
364     GX2SamplerVar     * samplerVars;
365 
366     /// use a GX2RBuffer for the shader program instead of shaderPtr and shaderSize. shaderPtr must be NULL.
367     GX2RBuffer          shaderProgram;
368 
369 } GX2PixelShader;
370 
371 /// @}
372 /// @addtogroup GX2ShaderFetchGroup
373 /// @{
374 
375 /// \brief Contains all information (user and private) for a Fetch Shader
376 ///
377 typedef struct _GX2FetchShader
378 {
379     // Fetch shader type
380     GX2FetchShaderType type;
381 
382     /// All register information needed to setup GPU7 (private)
383     u32 _regs[GX2_NUM_FETCH_SHADER_REGISTERS];
384 
385     /// size of shader program, in bytes
386     u32                 shaderSize;
387 
388     /// pointer to shader program.  Must be aligned on 256 byte boundary.
389     void              * shaderPtr;
390 
391     /// Number of Attributes specified by Fetch Shader
392     u32 numAttribs;
393 
394     // prototype for instancing (private)
395     u32 _num_divisors;
396     u32 _divisors[2];
397 
398 } GX2FetchShader;
399 
400 /// @}
401 /// @addtogroup GX2ShaderComputeGroup
402 /// @{
403 
404 /// \brief Compute shader dispatch parameters.
405 ///
406 /// This structure contains the necessary data used by \ref GX2DispatchCompute
407 /// for running a compute shader on a set of work-groups.
408 ///
409 /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders"
410 ///
411 typedef struct _GX2DispatchParams {
412     u32 num_groups_x; ///< Number of work-groups in x dimension. Must be at least 1.
413     u32 num_groups_y; ///< Number of work-groups in y dimension. Must be at least 1.
414     u32 num_groups_z; ///< Number of work-groups in z dimension. Must be at least 1.
415     u32 padding; ///< Alignment padding
416 } GX2DispatchParams;
417 
418 /// \brief Contains all information (user and private) for a Compute Shader
419 ///
420 /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders"
421 ///
422 typedef struct _GX2ComputeShader
423 {
424     /// All register information needed to setup GPU7 (private)
425     u32 _regs[GX2_NUM_COMPUTE_SHADER_REGISTERS];
426 
427     /// size of shader program, in bytes
428     u32                 shaderSize;
429 
430     /// pointer to shader program.  Must be aligned on 256 byte boundary.
431     void              * shaderPtr;
432 
433     /// Number of Uniform Blocks
434     u32                 numUniformBlocks;
435     /// Uniform Blocks
436     GX2UniformBlock   * uniformBlocks;
437 
438     /// Number of Compute Shader Uniforms
439     u32                 numUniforms;
440     /// Compute Shader Uniforms
441     GX2UniformVar     * uniformVars;
442 
443     /// Number of initial values for Uniforms. Count is in Vec4s
444     /// (Matrix data types may have 2-4 rows).
445     u32                         numInitialValues;
446     /// Initial values for Uniforms
447     GX2UniformInitialValue    * initialValues;
448 
449     /// Number of loop variables (private)
450     u32                 _numLoops;
451     /// Loops variables (private)
452     void              * _loopVars;
453 
454     /// Number of Sampler variables
455     u32                 numSamplers;
456     /// Samplers variables
457     GX2SamplerVar     * samplerVars;
458 
459     // Layout of shader
460     u32  layout_size_x; ///< Number of work-items per work-group in the x dimension.
461     u32  layout_size_y; ///< Number of work-items per work-group in the y dimension.
462     u32  layout_size_z; ///< Number of work-items per work-group in the z dimension.
463 
464     /// The shader exceeds the 64 limit on group size
465     GX2Boolean          Over64Mode;
466 
467     /// Maximum allowed wavefronts to run on a given SIMD. Zero-means unrestricted.
468     u32 numWavesPerSIMD;
469 
470     /// use a GX2RBuffer for the shader program instead of shaderPtr and shaderSize. shaderPtr must be NULL.
471     GX2RBuffer          shaderProgram;
472 
473 } GX2ComputeShader;
474 
475 // ---------------------------------------
476 // Shader Program Resources
477 
478 /// @}
479 /// @addtogroup GX2ShaderVertexGroup
480 /// @{
481 
482 /// \brief Function to return the number of GPRs used by the Vertex Shader program
483 ///
484 /// \param pShader Pointer to Vertex Shader
485 /// \return number of GPRs used by the vertex shader program
486 ///
487 /// \donotcall \threadsafe \enddonotcall
488 ///
489 u32 GX2API GX2GetVertexShaderGPRs(const GX2VertexShader * pShader);
490 
491 /// \brief Function to return the number of stack entries used by the Vertex Shader program
492 ///
493 /// \param pShader Pointer to Vertex Shader
494 /// \return number of stack entries used by the vertex shader program
495 ///
496 /// \donotcall \threadsafe \enddonotcall
497 ///
498 u32 GX2API GX2GetVertexShaderStackEntries(const GX2VertexShader * pShader);
499 
500 
501 /// @}
502 /// @addtogroup GX2ShaderGeometryGroup
503 /// @{
504 
505 /// \brief Function to return the number of GPRs used by the Geometry Shader program
506 ///
507 /// \param pShader Pointer to Geometry Shader
508 /// \return number of GPRs used by the geometry shader program
509 ///
510 /// \donotcall \threadsafe \enddonotcall
511 ///
512 u32 GX2API GX2GetGeometryShaderGPRs(const GX2GeometryShader * pShader);
513 
514 /// \brief Function to return the number of stack entries used by the Geometry Shader program
515 ///
516 /// \param pShader Pointer to Geometry Shader
517 /// \return number of stack entries used by the geometry shader program
518 ///
519 /// \donotcall \threadsafe \enddonotcall
520 ///
521 u32 GX2API GX2GetGeometryShaderStackEntries(const GX2GeometryShader * pShader);
522 
523 /// @}
524 /// @addtogroup GX2ShaderPixelGroup
525 /// @{
526 
527 /// \brief Function to return the number of GPRs used by the Pixel Shader program
528 ///
529 /// \param  pShader shader Pointer to Pixel Shader
530 /// \return number of GPRs used by the pixel shader program
531 ///
532 /// \donotcall \threadsafe \enddonotcall
533 ///
534 u32 GX2API GX2GetPixelShaderGPRs(const GX2PixelShader * pShader);
535 
536 /// \brief Function to return the number of stack entries used by the Pixel Shader program
537 ///
538 /// \param  pShader Pointer to Pixel Shader
539 /// \return number of stack entries used by the pixel shader program
540 ///
541 /// \donotcall \threadsafe \enddonotcall
542 ///
543 u32 GX2API GX2GetPixelShaderStackEntries(const GX2PixelShader * pShader);
544 
545 /// @}
546 /// @addtogroup GX2ShaderVertexGroup
547 /// @{
548 
549 // ---------------------------------------
550 // Uniforms
551 
552 /// \brief Convenience function to return a Vertex Shader Uniform Variable (given its name)
553 ///
554 /// \note Will return NULL if the variable is not found.
555 ///
556 /// \param shader Pointer to Vertex Shader
557 /// \param name String name specified in shader code
558 /// \return Pointer to Uniform structure within the shader structure
559 ///
560 /// \donotcall \threadsafe \devonly \enddonotcall
561 ///
GX2GetVertexUniformVar(const GX2VertexShader * shader,const char * name)562 GX2_INLINE GX2UniformVar * GX2GetVertexUniformVar(const GX2VertexShader * shader, const char * name)
563 {
564     u32 i;
565     ASSERT(shader && "NULL Shader");
566     ASSERT(name && "NULL name");
567     for (i = 0; i < shader->numUniforms; i++)
568     {
569        if (strcmp(shader->uniformVars[i].name, name) == 0)
570            return &(shader->uniformVars[i]);
571     }
572     return NULL;
573 }
574 
575 /// @}
576 /// @addtogroup GX2ShaderGeometryGroup
577 /// @{
578 
579 /// \brief Convenience function to return a Geometry Shader Uniform Variable (given its name)
580 ///
581 /// \note Will return NULL if the variable is not found.
582 ///
583 /// \param shader Pointer to Geometry Shader
584 /// \param name String name specified in shader code
585 /// \return Pointer to Uniform structure within the shader structure
586 ///
587 /// \donotcall \threadsafe \devonly \enddonotcall
588 ///
GX2GetGeometryUniformVar(const GX2GeometryShader * shader,const char * name)589 GX2_INLINE GX2UniformVar * GX2GetGeometryUniformVar(const GX2GeometryShader * shader, const char * name)
590 {
591     u32 i;
592     ASSERT(shader && "NULL Shader");
593     ASSERT(name && "NULL name");
594     for (i = 0; i < shader->numUniforms; i++)
595     {
596        if (strcmp(shader->uniformVars[i].name, name) == 0)
597            return &(shader->uniformVars[i]);
598     }
599     return NULL;
600 }
601 
602 /// @}
603 /// @addtogroup GX2ShaderPixelGroup
604 /// @{
605 
606 /// \brief Convenience function to return a Pixel Shader Uniform Variable (given its name)
607 ///
608 /// \note Will return NULL if the variable is not found.
609 ///
610 /// \param shader Pointer to Pixel Shader
611 /// \param name String name specified in shader code
612 /// \return Pointer to Uniform structure within the shader structure
613 ///
614 /// \donotcall \threadsafe \devonly \enddonotcall
615 ///
GX2GetPixelUniformVar(const GX2PixelShader * shader,const char * name)616 GX2_INLINE GX2UniformVar * GX2GetPixelUniformVar(const GX2PixelShader * shader, const char * name)
617 {
618     u32 i;
619     ASSERT(shader && "NULL Shader");
620     ASSERT(name && "NULL name");
621     for (i = 0; i < shader->numUniforms; i++)
622     {
623        if (strcmp(shader->uniformVars[i].name, name) == 0)
624            return &(shader->uniformVars[i]);
625     }
626     return NULL;
627 }
628 
629 /// @}
630 /// @addtogroup GX2ShaderComputeGroup
631 /// @{
632 
633 /// \brief Convenience function to return a Compute Shader Uniform Variable (given its name)
634 ///
635 /// \note Will return NULL if the variable is not found.
636 ///
637 /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders"
638 ///
639 /// \param shader Pointer to Compute Shader
640 /// \param name String name specified in shader code
641 /// \return Pointer to Uniform structure within the shader structure
642 ///
643 /// \donotcall \threadsafe \devonly \enddonotcall
644 ///
GX2GetComputeUniformVar(const GX2ComputeShader * shader,const char * name)645 GX2_INLINE GX2UniformVar * GX2GetComputeUniformVar(const GX2ComputeShader * shader, const char * name)
646 {
647     u32 i;
648     ASSERT(shader && "NULL Shader");
649     ASSERT(name && "NULL name");
650     for (i = 0; i < shader->numUniforms; i++)
651     {
652        if (strcmp(shader->uniformVars[i].name, name) == 0)
653            return &(shader->uniformVars[i]);
654     }
655     return NULL;
656 }
657 
658 /// @}
659 /// @addtogroup GX2ShaderVertexGroup
660 /// @{
661 
662 /// \brief Convenience function to return a Vertex Shader Uniform's Offset (given its name)
663 ///
664 /// \note Will return GX2_UNIFORM_VAR_INVALID_OFFSET if the uniform is not found.
665 ///
666 /// \note Also note that if the uniform variable is used as the limit of a for loop, then some special flags to be used by the hardware are placed in the upper 16 bits of the offset.
667 /// In this case, the full 32 bit offset (including flags) may still be passed to GX2SetVertexUniformReg.
668 ///
669 ///
670 /// \param shader Pointer to Vertex Shader
671 /// \param name String name specified in shader code
672 /// \return Offset value provided in number of u32's
673 ///
674 /// \donotcall \threadsafe \devonly \enddonotcall
675 ///
GX2GetVertexUniformVarOffset(const GX2VertexShader * shader,const char * name)676 GX2_INLINE s32 GX2GetVertexUniformVarOffset(const GX2VertexShader * shader, const char * name)
677 {
678     GX2UniformVar * uniform;
679     ASSERT(shader && "NULL Shader");
680     ASSERT(name && "NULL name");
681     uniform = GX2GetVertexUniformVar(shader, name);
682     if (!uniform) return GX2_UNIFORM_VAR_INVALID_OFFSET;
683     return (s32) uniform->offset;
684 }
685 
686 /// @}
687 /// @addtogroup GX2ShaderGeometryGroup
688 /// @{
689 
690 /// \brief Convenience function to return a Geometry Shader Uniform's Offset (given its name)
691 ///
692 /// \note Will return GX2_UNIFORM_VAR_INVALID_OFFSET if the uniform is not found.
693 ///
694 /// \param shader Pointer to Geometry Shader
695 /// \param name String name specified in shader code
696 /// \return Offset value provided in number of u32's
697 ///
698 /// \donotcall \threadsafe \devonly \enddonotcall
699 ///
GX2GetGeometryUniformVarOffset(const GX2GeometryShader * shader,const char * name)700 GX2_INLINE s32 GX2GetGeometryUniformVarOffset(const GX2GeometryShader * shader, const char * name)
701 {
702     GX2UniformVar * uniform;
703     ASSERT(shader && "NULL Shader");
704     ASSERT(name && "NULL name");
705     uniform = GX2GetGeometryUniformVar(shader, name);
706     if (!uniform) return GX2_UNIFORM_VAR_INVALID_OFFSET;
707     return (s32) uniform->offset;
708 }
709 
710 /// @}
711 /// @addtogroup GX2ShaderPixelGroup
712 /// @{
713 
714 /// \brief Convenience function to return a Pixel Shader Uniform's Offset (given its name)
715 ///
716 /// \note Will return GX2_UNIFORM_VAR_INVALID_OFFSET if the uniform is not found.
717 ///
718 /// \note Also note that if the uniform variable is used as the limit of a for loop, then some special flags to be used by the hardware are placed in the upper 16 bits of the offset.
719 /// In this case, the full 32 bit offset (including flags) may still be passed to GX2SetPixelUniformReg.
720 ///
721 /// \param shader Pointer to Pixel Shader
722 /// \param name String name specified in shader code
723 /// \return Offset value provided in number of u32's
724 ///
725 /// \donotcall \threadsafe \devonly \enddonotcall
726 ///
GX2GetPixelUniformVarOffset(const GX2PixelShader * shader,const char * name)727 GX2_INLINE s32 GX2GetPixelUniformVarOffset(const GX2PixelShader * shader, const char * name)
728 {
729     GX2UniformVar * uniform;
730     ASSERT(shader && "NULL Shader");
731     ASSERT(name && "NULL name");
732     uniform = GX2GetPixelUniformVar(shader, name);
733     if (!uniform) return GX2_UNIFORM_VAR_INVALID_OFFSET;
734     return (s32) uniform->offset;
735 }
736 
737 /// @}
738 /// @addtogroup GX2ShaderComputeGroup
739 /// @{
740 
741 /// \brief Convenience function to return a Compute Shader Uniform's Offset (given its name)
742 ///
743 /// \note Will return GX2_UNIFORM_VAR_INVALID_OFFSET if the uniform is not found.
744 ///
745 /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders"
746 ///
747 /// \param shader Pointer to Compute Shader
748 /// \param name String name specified in shader code
749 /// \return Offset value provided in number of u32's
750 ///
751 /// \donotcall \threadsafe \devonly \enddonotcall
752 ///
GX2GetComputeUniformVarOffset(const GX2ComputeShader * shader,const char * name)753 GX2_INLINE s32 GX2GetComputeUniformVarOffset(const GX2ComputeShader * shader, const char * name)
754 {
755     GX2UniformVar * uniform;
756     ASSERT(shader && "NULL Shader");
757     ASSERT(name && "NULL name");
758     uniform = GX2GetComputeUniformVar(shader, name);
759     if (!uniform) return GX2_UNIFORM_VAR_INVALID_OFFSET;
760     return (s32) uniform->offset;
761 }
762 
763 /// @}
764 /// @addtogroup GX2ShaderAllGroup
765 /// @{
766 
767 // ---------------------------------------
768 // Uniform Registers
769 
770 /// \brief Convenience function to convert Uniform Type into its component count
771 ///
772 /// \note the component count is rounded up to multiples of 4, due to the HW
773 //// requirement that uniform registers always contain 4 u32-sized components.
774 ///
775 /// \param type Uniform type
776 /// \return Count of how many u32-sized components are used by that type
777 ///
778 /// \donotcall \threadsafe \devonly \enddonotcall
779 ///
GX2VarTypeToCount(GX2VarType type)780 GX2_INLINE u32 GX2VarTypeToCount(GX2VarType type)
781 {
782     switch (type)
783     {
784     case GX2_VAR_TYPE_VOID:
785         return 0;
786     case GX2_VAR_TYPE_FLOAT:
787     case GX2_VAR_TYPE_BOOL:
788     case GX2_VAR_TYPE_INT:
789     case GX2_VAR_TYPE_UINT:
790         return 4;
791     case GX2_VAR_TYPE_VEC2:
792     case GX2_VAR_TYPE_BVEC2:
793     case GX2_VAR_TYPE_IVEC2:
794     case GX2_VAR_TYPE_UVEC2:
795         return 4;
796     case GX2_VAR_TYPE_VEC3:
797     case GX2_VAR_TYPE_BVEC3:
798     case GX2_VAR_TYPE_IVEC3:
799     case GX2_VAR_TYPE_UVEC3:
800         return 4;
801     case GX2_VAR_TYPE_VEC4:
802     case GX2_VAR_TYPE_BVEC4:
803     case GX2_VAR_TYPE_IVEC4:
804     case GX2_VAR_TYPE_UVEC4:
805         return 4;
806     case GX2_VAR_TYPE_MAT2:
807     case GX2_VAR_TYPE_MAT2X3:
808     case GX2_VAR_TYPE_MAT2X4:
809         return 8;
810     case GX2_VAR_TYPE_MAT3X2:
811     case GX2_VAR_TYPE_MAT3:
812     case GX2_VAR_TYPE_MAT3X4:
813         return 12;
814     case GX2_VAR_TYPE_MAT4X2:
815     case GX2_VAR_TYPE_MAT4X3:
816     case GX2_VAR_TYPE_MAT4:
817         return 16;
818     case GX2_VAR_TYPE_DOUBLE:
819     case GX2_VAR_TYPE_DVEC2:
820     case GX2_VAR_TYPE_DVEC3:
821     case GX2_VAR_TYPE_DVEC4:
822     case GX2_VAR_TYPE_DMAT2:
823     case GX2_VAR_TYPE_DMAT2X3:
824     case GX2_VAR_TYPE_DMAT2X4:
825     case GX2_VAR_TYPE_DMAT3X2:
826     case GX2_VAR_TYPE_DMAT3:
827     case GX2_VAR_TYPE_DMAT3X4:
828     case GX2_VAR_TYPE_DMAT4X2:
829     case GX2_VAR_TYPE_DMAT4X3:
830     case GX2_VAR_TYPE_DMAT4:
831     default:
832         ASSERT(!"var type not supported\n");
833         return 0;
834     }
835     // no fall through
836 }
837 
838 /// @}
839 /// @addtogroup GX2ShaderVertexGroup
840 /// @{
841 
842 /// \brief Set vertex shader uniform values (for \ref GX2_SHADER_MODE_UNIFORM_REGISTER only)
843 ///
844 /// This API can set individual uniforms or many uniforms.
845 /// \note This API is used for f32, u32, and bool formats.
846 /// \note This API can only be used for GX2_SHADER_MODE_UNIFORM_REGISTER. See \ref GX2SetShaderMode
847 ///
848 /// \param offset   Offset of the uniform (in number of u32's); MUST BE A MULTIPLE of 4 (unless this was returned by GX2GetVertexUniformVarOffset)
849 /// \param count    Number of components (in number of u32's); MUST BE A MULTIPLE of 4!
850 /// \param values   Pointer to buffer containing values (byte size should be count * sizeof(u32))
851 ///
852 /// \donotcall \gx2_typical \enddonotcall
853 ///
854 /// \writesgpu
855 /// \alwayswritesgpu
856 ///
857 void GX2API GX2SetVertexUniformReg(u32 offset, u32 count, const void *values);
858 
859 /// @}
860 /// @addtogroup GX2ShaderPixelGroup
861 /// @{
862 
863 /// \brief Set pixel shader uniform values (for \ref GX2_SHADER_MODE_UNIFORM_REGISTER only)
864 ///
865 /// This API can set individual uniforms or many uniforms.
866 /// \note This API is used for f32, u32, and bool formats.
867 /// \note This API can only be used for GX2_SHADER_MODE_UNIFORM_REGISTER. See \ref GX2SetShaderMode
868 ///
869 /// \param offset   Offset of the uniform (in number of u32's); MUST BE A MULTIPLE of 4 (unless returned from GX2GetPixelUniformVarOffset)
870 /// \param count    Number of components (in number of u32's); MUST BE A MULTIPLE of 4!
871 /// \param values   Pointer to buffer containing values (byte size should be count * sizeof(u32))
872 ///
873 /// \donotcall \gx2_typical \enddonotcall
874 ///
875 /// \writesgpu
876 /// \alwayswritesgpu
877 ///
878 void GX2API GX2SetPixelUniformReg(u32 offset, u32 count, const void *values);
879 
880 /// @}
881 /// @addtogroup GX2ShaderVertexGroup
882 /// @{
883 
884 /// \brief Set default (initial) VS uniform values (for \ref GX2_SHADER_MODE_UNIFORM_REGISTER only)
885 ///
886 /// \param shader Pointer to Vertex Shader containing uniforms to initialize
887 ///
888 /// \donotcall \gx2_typical \enddonotcall
889 ///
890 /// \writesgpu
891 /// \alwayswritesgpu
892 ///
GX2SetVertexUniformRegDefaults(const GX2VertexShader * shader)893 GX2_INLINE void GX2SetVertexUniformRegDefaults(const GX2VertexShader* shader)
894 {
895     u32 i;
896     ASSERT(shader && "NULL Shader");
897     for (i = 0; i < shader->numInitialValues; i++) {
898         GX2SetVertexUniformReg(shader->initialValues[i].offset * 4,
899                                4,
900                                shader->initialValues[i].value);
901     }
902 }
903 
904 /// @}
905 /// @addtogroup GX2ShaderPixelGroup
906 /// @{
907 
908 /// \brief Set default (initial) PS uniform values (for \ref GX2_SHADER_MODE_UNIFORM_REGISTER only)
909 ///
910 /// \param shader Pointer to Pixel Shader containing uniforms to initialize
911 ///
912 /// \donotcall \gx2_typical \enddonotcall
913 ///
914 /// \writesgpu
915 /// \alwayswritesgpu
916 ///
GX2SetPixelUniformRegDefaults(const GX2PixelShader * shader)917 GX2_INLINE void GX2SetPixelUniformRegDefaults(const GX2PixelShader* shader)
918 {
919     u32 i;
920     ASSERT(shader && "NULL Shader");
921     for (i = 0; i < shader->numInitialValues; i++) {
922         GX2SetPixelUniformReg(shader->initialValues[i].offset * 4,
923                               4,
924                               shader->initialValues[i].value);
925     }
926 }
927 
928 /// @}
929 /// @addtogroup GX2ShaderVertexGroup
930 /// @{
931 
932 // ---------------------------------------
933 // Uniform Blocks
934 
935 /// \brief Convenience function to return a vertex shader Uniform Block (given its name)
936 ///
937 /// Use in \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_GEOMETRY_SHADER only.
938 ///
939 /// \note Will return NULL if uniform block is not found.
940 ///
941 /// \param shader Pointer to Vertex Shader
942 /// \param name String name specified in shader code
943 /// \return Pointer to Uniform Block structure within the shader structure
944 ///
945 /// \donotcall \threadsafe \devonly \enddonotcall
946 ///
GX2GetVertexUniformBlock(const GX2VertexShader * shader,const char * name)947 GX2_INLINE GX2UniformBlock* GX2GetVertexUniformBlock(const GX2VertexShader* shader,
948                                                  const char * name)
949 {
950     u32 i;
951     ASSERT(shader && "NULL Shader");
952     ASSERT(name && "NULL name");
953     for (i = 0; i < shader->numUniformBlocks; i++)
954     {
955        if (strcmp(shader->uniformBlocks[i].name, name) == 0)
956            return &(shader->uniformBlocks[i]);
957     }
958     return NULL;
959 }
960 
961 /// @}
962 /// @addtogroup GX2ShaderGeometryGroup
963 /// @{
964 
965 /// \brief Convenience function to return a geometry shader Uniform Block (given its name)
966 ///
967 /// \note Will return NULL if uniform block is not found.
968 ///
969 /// \param shader Pointer to Geometry Shader
970 /// \param name String name specified in shader code
971 /// \return Pointer to Uniform Block structure within the shader structure
972 ///
973 /// \donotcall \threadsafe \devonly \enddonotcall
974 ///
GX2GetGeometryUniformBlock(const GX2GeometryShader * shader,const char * name)975 GX2_INLINE GX2UniformBlock* GX2GetGeometryUniformBlock(const GX2GeometryShader* shader,
976                                                  const char * name)
977 {
978     u32 i;
979     ASSERT(shader && "NULL Shader");
980     ASSERT(name && "NULL name");
981     for (i = 0; i < shader->numUniformBlocks; i++)
982     {
983        if (strcmp(shader->uniformBlocks[i].name, name) == 0)
984            return &(shader->uniformBlocks[i]);
985     }
986     return NULL;
987 }
988 
989 /// @}
990 /// @addtogroup GX2ShaderPixelGroup
991 /// @{
992 
993 /// \brief Convenience function to return a pixel shader Uniform Block (given its name)
994 ///
995 /// Use in \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_GEOMETRY_SHADER only.
996 ///
997 /// \note Will return NULL if uniform block is not found.
998 ///
999 /// \param shader Pointer to Pixel Shader
1000 /// \param name String name specified in shader code
1001 /// \return Pointer to Uniform Block structure within the shader structure
1002 ///
1003 /// \donotcall \threadsafe \devonly \enddonotcall
1004 ///
GX2GetPixelUniformBlock(const GX2PixelShader * shader,const char * name)1005 GX2_INLINE GX2UniformBlock* GX2GetPixelUniformBlock(const GX2PixelShader* shader,
1006                                                 const char * name)
1007 {
1008     u32 i;
1009     ASSERT(shader && "NULL Shader");
1010     ASSERT(name && "NULL name");
1011     for (i = 0; i < shader->numUniformBlocks; i++)
1012     {
1013        if (strcmp(shader->uniformBlocks[i].name, name) == 0)
1014            return &(shader->uniformBlocks[i]);
1015     }
1016     return NULL;
1017 }
1018 
1019 /// @}
1020 /// @addtogroup GX2ShaderComputeGroup
1021 /// @{
1022 
1023 // ---------------------------------------
1024 // Uniform Blocks
1025 
1026 /// \brief Convenience function to return a compute shader Uniform Block (given its name)
1027 ///
1028 /// \note Will return NULL if uniform block is not found.
1029 ///
1030 /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders"
1031 ///
1032 /// \param shader Pointer to Compute Shader
1033 /// \param name String name specified in shader code
1034 /// \return Pointer to Uniform Block structure within the shader structure
1035 ///
1036 /// \donotcall \threadsafe \devonly \enddonotcall
1037 ///
GX2GetComputeUniformBlock(const GX2ComputeShader * shader,const char * name)1038 GX2_INLINE GX2UniformBlock* GX2GetComputeUniformBlock(const GX2ComputeShader* shader,
1039                                                  const char * name)
1040 {
1041     u32 i;
1042     ASSERT(shader && "NULL Shader");
1043     ASSERT(name && "NULL name");
1044     for (i = 0; i < shader->numUniformBlocks; i++)
1045     {
1046        if (strcmp(shader->uniformBlocks[i].name, name) == 0)
1047            return &(shader->uniformBlocks[i]);
1048     }
1049     return NULL;
1050 }
1051 
1052 /// @}
1053 /// @addtogroup GX2ShaderVertexGroup
1054 /// @{
1055 
1056 /// \brief Set a Uniform Block for the Vertex Shader
1057 ///
1058 /// Use in \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_GEOMETRY_SHADER only.
1059 ///
1060 /// \b Warning: User must keep the buffer valid (with expected values)
1061 /// until the GPU has completed the draws using this Uniform Block.
1062 ///
1063 /// \param location Hardware location of uniform block (\ref GX2UniformBlock)
1064 /// \param size Size of Uniform Block (in bytes) (\ref GX2UniformBlock)
1065 /// \param addr User-allocated buffer (of size "size") containing all values for block
1066 ///
1067 /// \donotcall \gx2_typical \enddonotcall
1068 ///
1069 /// \writesgpu
1070 /// \alwayswritesgpu
1071 ///
1072 void GX2API GX2SetVertexUniformBlock(u32 location, u32 size, const void* addr);
1073 
1074 /// @}
1075 /// @addtogroup GX2ShaderGeometryGroup
1076 /// @{
1077 
1078 /// \brief Set a Uniform Block for the Geometry Shader
1079 ///
1080 /// \b Warning: User must keep the buffer valid (with expected values)
1081 /// until GPU has completed the draws using this Uniform Block.
1082 ///
1083 /// \param location Hardware location of uniform block (\ref GX2UniformBlock)
1084 /// \param size Size of Uniform Block (in bytes) (\ref GX2UniformBlock)
1085 /// \param addr User-allocated buffer (of size "size") containing all values for block
1086 ///
1087 /// \donotcall \gx2_typical \enddonotcall
1088 ///
1089 /// \writesgpu
1090 /// \alwayswritesgpu
1091 ///
1092 void GX2API GX2SetGeometryUniformBlock(u32 location, u32 size, const void* addr);
1093 
1094 /// @}
1095 /// @addtogroup GX2ShaderPixelGroup
1096 /// @{
1097 
1098 /// \brief Set a Uniform Block for the Pixel Shader
1099 ///
1100 /// Use in  \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_GEOMETRY_SHADER only.
1101 ///
1102 /// \b Warning: User must keep the buffer valid (with expected values)
1103 /// until GPU has completed the draws using this Uniform Block.
1104 ///
1105 /// \param location Hardware location of uniform block (\ref GX2UniformBlock)
1106 /// \param size Size of Uniform Block (in bytes) (\ref GX2UniformBlock)
1107 /// \param addr User-allocated buffer (of size "size") containing all values for block
1108 ///
1109 /// \donotcall \gx2_typical \enddonotcall
1110 ///
1111 /// \writesgpu
1112 /// \alwayswritesgpu
1113 ///
1114 void GX2API GX2SetPixelUniformBlock(u32 location, u32 size, const void* addr);
1115 
1116 /// @}
1117 /// @addtogroup GX2ShaderComputeGroup
1118 /// @{
1119 
1120 /// \brief Set a Uniform Block for the Compute Shader
1121 ///
1122 /// Use in  \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_COMPUTE_SHADER only.
1123 ///
1124 /// \b Warning: User must keep the buffer valid (with expected values)
1125 /// until GPU has completed the draws using this Uniform Block.
1126 ///
1127 /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders"
1128 ///
1129 /// \param location Hardware location of uniform block (\ref GX2UniformBlock)
1130 /// \param size Size of Uniform Block (in bytes) (\ref GX2UniformBlock)
1131 /// \param addr User-allocated buffer (of size "size") containing all values for block
1132 ///
1133 /// \donotcall \gx2_typical \enddonotcall
1134 ///
1135 /// \writesgpu
1136 /// \alwayswritesgpu
1137 ///
1138 void GX2API GX2SetComputeUniformBlock(u32 location, u32 size, const void* addr);
1139 
1140 /// @}
1141 /// @addtogroup GX2ShaderVertexGroup
1142 /// @{
1143 
1144 // ---------------------------------------
1145 // Samplers
1146 
1147 /// \brief Convenience function to return a Vertex Shader Sampler Variable (given its name)
1148 ///
1149 /// \note Will return NULL if sampler is not found.
1150 ///
1151 /// \param shader Pointer to Vertex Shader
1152 /// \param name String name specified in shader code
1153 /// \return Pointer to Sampler structure within the shader structure
1154 ///
1155 /// \donotcall \threadsafe \devonly \enddonotcall
1156 ///
GX2GetVertexSamplerVar(const GX2VertexShader * shader,const char * name)1157 GX2_INLINE GX2SamplerVar* GX2GetVertexSamplerVar(const GX2VertexShader* shader,
1158                                              const char* name)
1159 {
1160     u32 i;
1161     ASSERT(shader && "NULL Shader");
1162     ASSERT(name && "NULL name");
1163     for (i = 0; i < shader->numSamplers; i++)
1164     {
1165        if (strcmp(shader->samplerVars[i].name, name) == 0)
1166            return &(shader->samplerVars[i]);
1167     }
1168     return NULL;
1169 }
1170 
1171 /// @}
1172 /// @addtogroup GX2ShaderGeometryGroup
1173 /// @{
1174 
1175 /// \brief Convenience function to return a Geometry Shader Sampler Variable (given its name)
1176 ///
1177 /// \note Will return NULL if sampler is not found.
1178 ///
1179 /// \param shader Pointer to Geometry Shader
1180 /// \param name String name specified in shader code
1181 /// \return Pointer to Sampler structure within the shader structure
1182 ///
1183 /// \donotcall \threadsafe \devonly \enddonotcall
1184 ///
GX2GetGeometrySamplerVar(const GX2GeometryShader * shader,const char * name)1185 GX2_INLINE GX2SamplerVar* GX2GetGeometrySamplerVar(const GX2GeometryShader* shader,
1186                                                const char* name)
1187 {
1188     u32 i;
1189     ASSERT(shader && "NULL Shader");
1190     ASSERT(name && "NULL name");
1191     for (i = 0; i < shader->numSamplers; i++)
1192     {
1193        if (strcmp(shader->samplerVars[i].name, name) == 0)
1194            return &(shader->samplerVars[i]);
1195     }
1196     return NULL;
1197 }
1198 
1199 /// @}
1200 /// @addtogroup GX2ShaderPixelGroup
1201 /// @{
1202 
1203 /// \brief Convenience function to return a Pixel Shader Sampler Variable (given its name)
1204 ///
1205 /// \note Will return NULL if sampler is not found.
1206 ///
1207 /// \param shader Pointer to Pixel Shader
1208 /// \param name String name specified in shader code
1209 /// \return Pointer to Sampler structure within the shader structure
1210 ///
1211 /// \donotcall \threadsafe \devonly \enddonotcall
1212 ///
GX2GetPixelSamplerVar(const GX2PixelShader * shader,const char * name)1213 GX2_INLINE GX2SamplerVar* GX2GetPixelSamplerVar(const GX2PixelShader* shader,
1214                                             const char* name)
1215 {
1216     u32 i;
1217     ASSERT(shader && "NULL Shader");
1218     ASSERT(name && "NULL name");
1219     for (i = 0; i < shader->numSamplers; i++)
1220     {
1221        if (strcmp(shader->samplerVars[i].name, name) == 0)
1222            return &(shader->samplerVars[i]);
1223     }
1224     return NULL;
1225 }
1226 
1227 /// @}
1228 /// @addtogroup GX2ShaderComputeGroup
1229 /// @{
1230 
1231 // ---------------------------------------
1232 // Samplers
1233 
1234 /// \brief Convenience function to return a Compute Shader Sampler Variable (given its name)
1235 ///
1236 /// \note Will return NULL if sampler is not found.
1237 ///
1238 /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders"
1239 ///
1240 /// \param shader Pointer to Compute Shader
1241 /// \param name String name specified in shader code
1242 /// \return Pointer to Sampler structure within the shader structure
1243 ///
1244 /// \donotcall \threadsafe \devonly \enddonotcall
1245 ///
GX2GetComputeSamplerVar(const GX2ComputeShader * shader,const char * name)1246 GX2_INLINE GX2SamplerVar* GX2GetComputeSamplerVar(const GX2ComputeShader* shader,
1247                                              const char* name)
1248 {
1249     u32 i;
1250     ASSERT(shader && "NULL Shader");
1251     ASSERT(name && "NULL name");
1252     for (i = 0; i < shader->numSamplers; i++)
1253     {
1254        if (strcmp(shader->samplerVars[i].name, name) == 0)
1255            return &(shader->samplerVars[i]);
1256     }
1257     return NULL;
1258 }
1259 
1260 /// @}
1261 /// @addtogroup GX2ShaderVertexGroup
1262 /// @{
1263 
1264 /// \brief Convenience function to return a Vertex Shader Sampler's hardware location (given its name)
1265 ///
1266 /// \note Will return (-1) if the sampler is not found.
1267 ///
1268 /// \param shader Pointer to Vertex Shader
1269 /// \param name String name specified in shader code
1270 /// \return Hardware location determined by compiler
1271 ///
1272 /// \donotcall \threadsafe \devonly \enddonotcall
1273 ///
GX2GetVertexSamplerVarLocation(const GX2VertexShader * shader,const char * name)1274 GX2_INLINE s32 GX2GetVertexSamplerVarLocation(const GX2VertexShader* shader,
1275                                           const char* name)
1276 {
1277     GX2SamplerVar * sampler;
1278     ASSERT(shader && "NULL Shader");
1279     ASSERT(name && "NULL name");
1280     sampler = GX2GetVertexSamplerVar(shader, name);
1281     if (!sampler) return -1;
1282     return (s32) sampler->location;
1283 }
1284 
1285 /// @}
1286 /// @addtogroup GX2ShaderGeometryGroup
1287 /// @{
1288 
1289 /// \brief Convenience function to return a Geometry Shader Sampler's hardware location (given its name)
1290 ///
1291 /// \note Will return (-1) if the sampler is not found.
1292 ///
1293 /// \param shader Pointer to Geometry Shader
1294 /// \param name String name specified in shader code
1295 /// \return Hardware location determined by compiler
1296 ///
1297 /// \donotcall \threadsafe \devonly \enddonotcall
1298 ///
GX2GetGeometrySamplerVarLocation(const GX2GeometryShader * shader,const char * name)1299 GX2_INLINE s32 GX2GetGeometrySamplerVarLocation(const GX2GeometryShader* shader,
1300                                             const char* name)
1301 {
1302     GX2SamplerVar * sampler;
1303     ASSERT(shader && "NULL Shader");
1304     ASSERT(name && "NULL name");
1305     sampler = GX2GetGeometrySamplerVar(shader, name);
1306     if (!sampler) return -1;
1307     return (s32) sampler->location;
1308 }
1309 
1310 /// @}
1311 /// @addtogroup GX2ShaderPixelGroup
1312 /// @{
1313 
1314 /// \brief Convenience function to return a Pixel Shader Sampler's hardware location (given its name)
1315 ///
1316 /// \note Will return (-1) if the sampler is not found.
1317 ///
1318 /// \param shader Pointer to Pixel Shader
1319 /// \param name String name specified in shader code
1320 /// \return Hardware location determined by compiler
1321 ///
1322 /// \donotcall \threadsafe \devonly \enddonotcall
1323 ///
GX2GetPixelSamplerVarLocation(const GX2PixelShader * shader,const char * name)1324 GX2_INLINE s32 GX2GetPixelSamplerVarLocation(const GX2PixelShader* shader,
1325                                          const char* name)
1326 {
1327     GX2SamplerVar * sampler;
1328     ASSERT(shader && "NULL Shader");
1329     ASSERT(name && "NULL name");
1330     sampler = GX2GetPixelSamplerVar(shader, name);
1331     if (!sampler) return -1;
1332     return (s32) sampler->location;
1333 }
1334 
1335 /// @}
1336 /// @addtogroup GX2ShaderComputeGroup
1337 /// @{
1338 
1339 /// \brief Convenience function to return a Compute Shader Sampler's hardware location (given its name)
1340 ///
1341 /// \note Will return (-1) if the sampler is not found.
1342 ///
1343 /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders"
1344 ///
1345 /// \param shader Pointer to Compute Shader
1346 /// \param name String name specified in shader code
1347 /// \return Hardware location determined by compiler
1348 ///
1349 /// \donotcall \threadsafe \devonly \enddonotcall
1350 ///
GX2GetComputeSamplerVarLocation(const GX2ComputeShader * shader,const char * name)1351 GX2_INLINE s32 GX2GetComputeSamplerVarLocation(const GX2ComputeShader* shader,
1352                                           const char* name)
1353 {
1354     GX2SamplerVar * sampler;
1355     ASSERT(shader && "NULL Shader");
1356     ASSERT(name && "NULL name");
1357     sampler = GX2GetComputeSamplerVar(shader, name);
1358     if (!sampler) return -1;
1359     return (s32) sampler->location;
1360 }
1361 
1362 /// @}
1363 /// @addtogroup GX2ShaderVertexGroup
1364 /// @{
1365 
1366 /// \brief Convenience function to return a shader Attribute Variable (given its name)
1367 ///
1368 /// \note Will return NULL if the attribute is not found.
1369 ///
1370 /// \param shader Pointer to Vertex Shader
1371 /// \param name String name specified in shader code
1372 /// \return Pointer to Attribute structure within the shader structure
1373 ///
1374 /// \donotcall \threadsafe \devonly \enddonotcall
1375 ///
GX2GetVertexAttribVar(const GX2VertexShader * shader,const char * name)1376 GX2_INLINE GX2AttribVar* GX2GetVertexAttribVar(const GX2VertexShader* shader,
1377                                            const char* name)
1378 {
1379     u32 i;
1380     ASSERT(shader && "NULL Shader");
1381     ASSERT(name && "NULL name");
1382     for (i = 0; i < shader->numAttribs; i++)
1383     {
1384        if (strcmp(shader->attribVars[i].name, name) == 0)
1385            return &(shader->attribVars[i]);
1386     }
1387     return NULL;
1388 }
1389 
1390 /// \brief Convenience function to return a shader Attribute's hardware location (given its name)
1391 ///
1392 /// \note Will return (-1) if the attribute is not found.
1393 ///
1394 /// \param shader Pointer to Vertex Shader
1395 /// \param name String name specified in shader code
1396 /// \return Hardware location determined by compiler
1397 ///
1398 /// \donotcall \threadsafe \devonly \enddonotcall
1399 ///
GX2GetVertexAttribVarLocation(const GX2VertexShader * shader,const char * name)1400 GX2_INLINE s32 GX2GetVertexAttribVarLocation(const GX2VertexShader* shader,
1401                                          const char* name)
1402 {
1403     GX2AttribVar * attribVar;
1404     ASSERT(shader && "NULL Shader");
1405     ASSERT(name && "NULL name");
1406     attribVar = GX2GetVertexAttribVar(shader, name);
1407     if (!attribVar) return -1;
1408     return (s32) attribVar->location;
1409 }
1410 
1411 /// @}
1412 /// @addtogroup GX2ShaderFetchGroup
1413 /// @{
1414 
1415 // ---------------------------------------
1416 // Fetch Shader Initialization
1417 
1418 
1419 /// \brief Calculate the size of a fetch shader.
1420 ///
1421 /// \param num_attrib number of attribute
1422 /// \param fsType     The type of fetch shader to generate
1423 /// \param tessMode   Tesselation mode, only valid if type is not GX2_FETCH_SHADER_TESSELATION_NONE
1424 ///
1425 /// \donotcall \threadsafe \devonly \enddonotcall
1426 ///
1427 u32 GX2API GX2CalcFetchShaderSizeEx(u32 num_attrib,
1428                              GX2FetchShaderType fsType,
1429                              GX2TessellationMode tessMode);
1430 
1431 /// \brief Calculate the size of a fetch shader.
1432 ///
1433 /// \param num_attrib number of attribute
1434 ///
1435 /// \donotcall \threadsafe \devonly \enddonotcall
1436 ///
GX2CalcFetchShaderSize(u32 num_attrib)1437 GX2_INLINE u32 GX2CalcFetchShaderSize(u32 num_attrib)
1438 {
1439     return GX2CalcFetchShaderSizeEx(num_attrib,
1440                                     GX2_FETCH_SHADER_TESSELATION_NONE,
1441                                     GX2_TESSELLATION_MODE_DISCRETE); // Not used
1442 }
1443 
1444 /// \brief Create a fetch shader based on the given attribute stream list.
1445 ///
1446 /// \param fs        User-allocated instance of \ref GX2FetchShader structure
1447 /// \param fs_buffer User-allocated aligned buffer for the fetch shader binary code
1448 /// \param count     Number of attribute streams
1449 /// \param attribs   User-allocated array of \ref GX2AttribStream structures containing information
1450 ///                  about all attribute streams
1451 /// \param type      The type of fetch shader to generate
1452 /// \param tessMode  Tesselation mode, only valid if type is not GX2_FETCH_SHADER_TESSELATION_NONE
1453 ///
1454 /// \donotcall \threadsafe \devonly \enddonotcall
1455 ///
1456 void GX2API GX2InitFetchShaderEx(
1457     GX2FetchShader* fs,
1458     void* fs_buffer,
1459     u32 count,
1460     const GX2AttribStream* attribs,
1461     GX2FetchShaderType type,
1462     GX2TessellationMode tessMode);
1463 
1464 /// \brief Create a fetch shader based on the given attribute stream list.
1465 ///
1466 /// \param fs        User-allocated instance of \ref GX2FetchShader structure
1467 /// \param fs_buffer User-allocated aligned buffer for the fetch shader binary code
1468 /// \param count     Number of attribute streams
1469 /// \param attribs   User-allocated array of \ref GX2AttribStream structures containing information
1470 ///                  about all attribute streams
1471 ///
1472 /// \donotcall \threadsafe \devonly \enddonotcall
1473 ///
GX2InitFetchShader(GX2FetchShader * fs,void * fs_buffer,u32 count,const GX2AttribStream * attribs)1474 GX2_INLINE void GX2InitFetchShader(
1475     GX2FetchShader* fs,
1476     void* fs_buffer,
1477     u32 count,
1478     const GX2AttribStream* attribs)
1479 {
1480     GX2InitFetchShaderEx(fs,
1481                          fs_buffer,
1482                          count,
1483                          attribs,
1484                          GX2_FETCH_SHADER_TESSELATION_NONE,
1485                          GX2_TESSELLATION_MODE_DISCRETE); // Not used
1486 
1487 }
1488 
1489 /// \brief Helper function to set up a Vertex Attribute Stream. See \ref GX2AttribStream.
1490 ///
1491 /// \note Common defaults (based on the format) are assumed for the destination selects.
1492 ///       All attributes are assumed to be indexed by vertex ID.
1493 ///
1494 /// \donotcall \threadsafe \devonly \enddonotcall
1495 ///
GX2InitAttribStream(GX2AttribStream * attribStream,u32 location,u32 buffer,u32 offset,GX2AttribFormat format)1496 GX2_INLINE void GX2InitAttribStream(
1497     GX2AttribStream* attribStream,
1498     u32 location,
1499     u32 buffer,
1500     u32 offset,
1501     GX2AttribFormat format)
1502 {
1503     const GX2CompSel dstSel[20] = { GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01,
1504                                     GX2_COMP_SEL_X001, GX2_COMP_SEL_X001,
1505                                     GX2_COMP_SEL_XY01, GX2_COMP_SEL_X001,
1506                                     GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01,
1507                                     GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZ1,
1508                                     GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW,
1509                                     GX2_COMP_SEL_XY01, GX2_COMP_SEL_XY01,
1510                                     GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW,
1511                                     GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZ1,
1512                                     GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW};
1513 
1514     GX2_CHECK_ENUM_RANGE(format, GX2_ATTRIB_FORMAT);
1515     ASSERT(attribStream && "NULL Attrib");
1516 
1517     attribStream->buffer      = buffer;
1518     attribStream->offset      = offset;
1519     attribStream->location    = location;
1520     attribStream->format      = format;
1521     attribStream->destSel     = dstSel[format & 0xff];
1522     attribStream->indexType   = GX2_ATTRIB_INDEX_VERTEX_ID;
1523     attribStream->aluDivisor  = 0;
1524     attribStream->endianSwap  = GX2_ENDIANSWAP_DEFAULT;
1525 }
1526 
1527 /// \brief Returns the size in bits per attribute for a given attribute format.
1528 ///
1529 /// \donotcall \threadsafe \devonly \enddonotcall
1530 ///
1531 u32 GX2API GX2GetAttribFormatBits(GX2AttribFormat format);
1532 
1533 /// @}
1534 /// @addtogroup GX2ShaderGeometryGroup
1535 /// @{
1536 
1537 /// \brief Calculates the necessary ring buffer size for geometry shader input (VS output)
1538 ///
1539 /// \param maxVSItemSize item size from vertex shader being used
1540 ///
1541 /// \donotcall \threadsafe \devonly \enddonotcall
1542 ///
1543 u32 GX2API GX2CalcGeometryShaderInputRingBufferSize(u32 maxVSItemSize);
1544 
1545 /// \brief Calculate necessary ring buffer size for geometry shader output (PS input)
1546 ///
1547 /// \param maxGSItemSize item size of geometry shader being used
1548 ///
1549 /// \donotcall \threadsafe \devonly \enddonotcall
1550 ///
1551 u32 GX2API GX2CalcGeometryShaderOutputRingBufferSize(u32 maxGSItemSize);
1552 
1553 /// \brief Setup ring buffer for geometry shader input (VS output)
1554 ///
1555 /// \note The ring buffer must be 256-byte aligned.
1556 /// \note This function invokes a full pipeline flush (approx. 8 usecs).
1557 ///
1558 /// \param pRingBuffer address of ring buffer
1559 /// \param size size of ring buffer
1560 ///
1561 /// \donotcall \gx2_typical \enddonotcall
1562 ///
1563 /// \writesgpu
1564 /// \alwayswritesgpu
1565 ///
1566 void GX2API GX2SetGeometryShaderInputRingBuffer(void* pRingBuffer, u32 size);
1567 
1568 /// \brief Setup ring buffer for geometry shader output (PS input)
1569 ///
1570 /// \note The ring buffer must be 256-byte aligned.
1571 /// \note This function invokes a full pipeline flush (approx. 8 usecs).
1572 ///
1573 /// \param pRingBuffer address of ring buffer
1574 /// \param size size of ring buffer
1575 ///
1576 /// \donotcall \gx2_typical \enddonotcall
1577 ///
1578 /// \writesgpu
1579 /// \alwayswritesgpu
1580 ///
1581 void GX2API GX2SetGeometryShaderOutputRingBuffer(void* pRingBuffer, u32 size);
1582 
1583 /// @}
1584 /// @addtogroup GX2ShaderAllGroup
1585 /// @{
1586 
1587 /// \brief Select the shader mode and setup the shader resources
1588 ///
1589 /// \param mode shader mode
1590 /// \param vsGprs number of GPRs allocated to the vertex shader pipe
1591 /// \param vsStackSize number of stack entries allocated to the vertex shader pipe
1592 /// \param gsGprs number of GPRs allocated to the geometry shader pipe
1593 /// \param gsStackSize number of stack entries allocated to the geometry shader pipe
1594 /// \param psGprs number of GPRs allocated to the pixel shader pipe
1595 /// \param psStackSize number of stack entries allocated to the pixel shader pipe
1596 ///
1597 /// \note This function invokes a full pipeline flush (approx. 8 usecs).
1598 ///
1599 /// \note You must always reset the shaders in use after calling this.
1600 ///
1601 /// \note gsGprs and gsStackSize are only valid when the shader mode is set to
1602 ///       \ref GX2_SHADER_MODE_GEOMETRY_SHADER.  These values are ignored and should be set to 0 for
1603 ///       all other modes.
1604 ///
1605 /// \note vsGprs+gsGprs+psGprs should not exceed \ref GX2_TOTAL_GPRS_GS_ENABLED when the shader mode is
1606 ///       \ref GX2_SHADER_MODE_GEOMETRY_SHADER.
1607 ///
1608 /// \note vsGprs+psGprs should not exceed \ref GX2_TOTAL_GPRS_GS_DISABLED when the shader mode is
1609 ///       not \ref GX2_SHADER_MODE_GEOMETRY_SHADER.
1610 ///
1611 /// \note vsStackSize+gsStackSize+psStackSize should not exceed \ref GX2_TOTAL_STACK_ENTRIES
1612 ///
1613 /// \note \ref GX2_SHADER_MODE_COMPUTE_SHADER ignores all Gpr and Stack parameters.
1614 ///
1615 /// \note \ref GX2_SHADER_MODE_COMPUTE_SHADER clobbers the state set by
1616 /// \ref GX2SetGeometryShaderInputRingBuffer and \ref GX2SetGeometryShaderOutputRingBuffer.
1617 /// State set by those API's must be reissued after resetting to \ref GX2_SHADER_MODE_GEOMETRY_SHADER.
1618 ///
1619 /// \donotcall \gx2_typical \enddonotcall
1620 ///
1621 /// \writesgpu
1622 /// \alwayswritesgpu
1623 ///
1624 void GX2API GX2SetShaderModeEx(
1625     GX2ShaderMode mode,
1626     u32 vsGprs,
1627     u32 vsStackSize,
1628     u32 gsGprs,
1629     u32 gsStackSize,
1630     u32 psGprs,
1631     u32 psStackSize);
1632 
1633 /// \brief Select the shader mode
1634 ///
1635 /// \param mode shader mode
1636 /// \note This function invokes a full pipeline flush (approx. 8 usecs).
1637 ///
1638 /// \note You must always reset the shaders in use after calling this.
1639 ///
1640 /// \note \ref GX2_SHADER_MODE_COMPUTE_SHADER clobbers the state set by
1641 /// \ref GX2SetGeometryShaderInputRingBuffer and \ref GX2SetGeometryShaderOutputRingBuffer.
1642 /// State set by those API's must be reissued after resetting to \ref GX2_SHADER_MODE_GEOMETRY_SHADER.
1643 ///
1644 /// \donotcall \gx2_typical \enddonotcall
1645 ///
1646 /// \writesgpu
1647 /// \alwayswritesgpu
1648 ///
GX2SetShaderMode(GX2ShaderMode mode)1649 GX2_INLINE void GX2SetShaderMode(GX2ShaderMode mode)
1650 {
1651     u32 vsGprs;
1652     u32 vsStackSize;
1653     u32 gsGprs;
1654     u32 gsStackSize;
1655     u32 psGprs;
1656     u32 psStackSize;
1657 
1658     if (mode == GX2_SHADER_MODE_GEOMETRY_SHADER)
1659     {
1660         // Geometry shader is enabled
1661         vsGprs = 44;
1662         gsGprs = 64;
1663         psGprs = 76;
1664 
1665         vsStackSize = 32;
1666         gsStackSize = 48;
1667         psStackSize = 176;
1668     }
1669     else
1670     {
1671         // Geometry shader is disabled
1672         vsGprs = 48;
1673         gsGprs = 0;
1674         psGprs = 200;
1675 
1676         vsStackSize = 64;
1677         gsStackSize = 0;
1678         psStackSize = 192;
1679     }
1680 
1681     GX2SetShaderModeEx(mode, vsGprs, vsStackSize, gsGprs, gsStackSize, psGprs, psStackSize);
1682 }
1683 
1684 /// @}
1685 /// @addtogroup GX2ShaderFetchGroup
1686 /// @{
1687 
1688 /// \brief Sets up the given fetch shader to be used
1689 ///
1690 /// \param fs Pointer to fetch shader structure to be used in rendering
1691 ///
1692 /// \donotcall \gx2_typical \enddonotcall
1693 ///
1694 /// \writesgpu
1695 /// \alwayswritesgpu
1696 ///
1697 void GX2API GX2SetFetchShader(GX2CTXPRM const GX2FetchShader* fs);
1698 
1699 /// @}
1700 /// @addtogroup GX2ShaderVertexGroup
1701 /// @{
1702 
1703 /// \brief Sets up the given vertex shader to be used
1704 ///
1705 /// \param vs Pointer to vertex shader structure to be used in rendering
1706 ///
1707 /// \donotcall \gx2_typical \enddonotcall
1708 ///
1709 /// \writesgpu
1710 /// \alwayswritesgpu
1711 ///
1712 void GX2API GX2SetVertexShader(GX2CTXPRM const GX2VertexShader* vs);
1713 
1714 /// @}
1715 /// @addtogroup GX2ShaderGeometryGroup
1716 /// @{
1717 
1718 /// \brief Sets up the given geometry shader to be used
1719 ///
1720 /// \param gs Pointer to geometry shader structure to be used in rendering
1721 ///
1722 /// \donotcall \gx2_typical \enddonotcall
1723 ///
1724 /// \writesgpu
1725 /// \alwayswritesgpu
1726 ///
1727 void GX2API GX2SetGeometryShader(GX2CTXPRM const GX2GeometryShader * gs);
1728 
1729 /// @}
1730 /// @addtogroup GX2ShaderPixelGroup
1731 /// @{
1732 
1733 /// \brief Sets up the given pixel shader to be used
1734 ///
1735 /// \param ps Pointer to pixel shader structure to be used in rendering
1736 ///
1737 /// \donotcall \gx2_typical \enddonotcall
1738 ///
1739 /// \writesgpu
1740 /// \alwayswritesgpu
1741 ///
1742 void GX2API GX2SetPixelShader(GX2CTXPRM const GX2PixelShader* ps);
1743 
1744 /// @}
1745 /// @addtogroup GX2ShaderComputeGroup
1746 /// @{
1747 
1748 /// \brief Sets up the given compute shader to be used
1749 ///
1750 /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders"
1751 ///
1752 /// \param cs Pointer to compute shader structure to be used in rendering
1753 ///
1754 /// \donotcall \gx2_typical \enddonotcall
1755 ///
1756 /// \writesgpu
1757 /// \alwayswritesgpu
1758 ///
1759 void GX2API GX2SetComputeShader(GX2CTXPRM const GX2ComputeShader* cs);
1760 
1761 /// @}
1762 /// @addtogroup GX2ShaderAllGroup
1763 /// @{
1764 
1765 #ifndef GX2_OFFLINE_COMPILE
1766 /// \brief Helper function to set up Fetch, Vertex, and Pixel shaders at once.
1767 ///
1768 /// \param fs Pointer to fetch shader structure to be used in rendering
1769 /// \param vs Pointer to vertex shader structure to be used in rendering
1770 /// \param ps Pointer to pixel shader structure to be used in rendering
1771 ///
1772 /// \donotcall \gx2_typical \enddonotcall
1773 ///
1774 /// \writesgpu
1775 /// \alwayswritesgpu
1776 ///
GX2SetShaders(const GX2FetchShader * fs,const GX2VertexShader * vs,const GX2PixelShader * ps)1777 GX2_INLINE void GX2SetShaders(const GX2FetchShader* fs,
1778                           const GX2VertexShader* vs,
1779                           const GX2PixelShader* ps)
1780 {
1781     ASSERT(fs && "NULL Shader");
1782     ASSERT(vs && "NULL Shader");
1783     ASSERT(ps && "NULL Shader");
1784     GX2SetFetchShader(fs);
1785     GX2SetVertexShader(vs);
1786     GX2SetPixelShader(ps);
1787 }
1788 #endif // GX2_OFFLINE_COMPILE
1789 
1790 /// @}
1791 /// @addtogroup GX2ShaderAllGroup
1792 /// @{
1793 
1794 #ifndef GX2_OFFLINE_COMPILE
1795 /// \brief Helper function to set up Fetch, Vertex, Geometry, and Pixel shaders at once.
1796 ///
1797 /// \param fs Pointer to fetch shader structure to be used in rendering
1798 /// \param vs Pointer to vertex shader structure to be used in rendering
1799 /// \param gs Pointer to geometry shader structure to be used in rendering
1800 /// \param ps Pointer to pixel shader structure to be used in rendering
1801 ///
1802 /// \donotcall \gx2_typical \enddonotcall
1803 ///
1804 /// \writesgpu
1805 /// \alwayswritesgpu
1806 ///
GX2SetShadersEx(const GX2FetchShader * fs,const GX2VertexShader * vs,const GX2GeometryShader * gs,const GX2PixelShader * ps)1807 GX2_INLINE void GX2SetShadersEx(const GX2FetchShader* fs,
1808                             const GX2VertexShader* vs,
1809                             const GX2GeometryShader* gs,
1810                             const GX2PixelShader* ps)
1811 {
1812     ASSERT(fs && "NULL Shader");
1813     ASSERT(vs && "NULL Shader");
1814     ASSERT(gs && "NULL Shader");
1815     ASSERT(ps && "NULL Shader");
1816     ASSERT(gs->shaderMode == GX2_SHADER_MODE_GEOMETRY_SHADER);
1817 
1818     GX2SetFetchShader(fs);
1819     GX2SetVertexShader(vs);
1820     GX2SetGeometryShader(gs);
1821     GX2SetPixelShader(ps);
1822 }
1823 #endif // GX2_OFFLINE_COMPILE
1824 
1825 /// @}
1826 /// @}
1827 
1828 /// @addtogroup GX2StreamOutGroup
1829 /// @{
1830 
1831 /// \brief Stream Out Context Data
1832 ///
1833 /// \note Used by the HW to store information for a stream out buffer
1834 ///
1835 typedef struct _GX2StreamOutContext
1836 {
1837     u32 data[GX2_STREAMOUT_BUFFER_CONTEXT_SIZE/sizeof(u32)];
1838 } GX2StreamOutContext;
1839 
1840 /// \brief Describes a stream out buffer
1841 ///
1842 /// \note Stream output follows the same rules as DX10 stream output where the max stride in a single buffer is 2048 bytes,
1843 ///       defined to be the spacing between the beginning of each vertex.  If streaming into multiple buffers,
1844 ///       the stride must equal the element width in each buffer.  Each buffer can only contain a single varying output
1845 ///       corresponding to the stream out varings file.  Writing stops as as soon as any one of the
1846 ///       buffers is full.
1847 ///
1848 typedef struct _GX2StreamOutBuffer
1849 {
1850     u32    size;         ///< the size (in bytes) of the stream out buffer
1851     void*  dataPtr;      ///< pointer to the stream out buffer
1852     u32    vertexStride; ///< Stride (in bytes) between each vertex in the stream out buffer
1853 
1854     GX2RBuffer streamOutData; ///< use a GX2RBuffer in preference to size, dataPtr and vertexStride (dataPtr must be NULL in this case)
1855 
1856     GX2StreamOutContext* ctxPtr;  ///< pointer to HW context data for the stream out buffer
1857 } GX2StreamOutBuffer;
1858 
1859 /// \brief Set the stream out buffer to be used as the given stream out target
1860 ///
1861 /// \note soTarget should be less than \ref GX2_MAX_STREAMOUT_BUFFERS
1862 /// \note soTarget corresponds to the zero-based stream out varings file index
1863 ///
1864 /// \param soTarget      The stream out target to setup
1865 /// \param pStreamOutBuf Pointer to stream out buffer structure to use
1866 ///
1867 /// \donotcall \gx2_typical \enddonotcall
1868 ///
1869 /// \writesgpu
1870 /// \alwayswritesgpu
1871 ///
1872 void GX2API GX2SetStreamOutBuffer(u32 soTarget, const GX2StreamOutBuffer* pStreamOutBuf);
1873 
1874 /// \brief Save the stream out buffer context to memory
1875 ///
1876 /// \note soTarget should be less than \ref GX2_MAX_STREAMOUT_BUFFERS
1877 /// \note soTarget corresponds to the zero-based stream out varings file index
1878 ///
1879 /// \note This function should be called to save the current stream out buffer context for each
1880 ///       target before a context switch or before \ref GX2SetStreamOutBuffer() is called to set a
1881 ///       new stream out buffer to the soTarget.
1882 ///
1883 /// \param soTarget      The stream out target the buffer is currently set to
1884 /// \param pStreamOutBuf Pointer to stream out buffer structure
1885 ///
1886 /// \donotcall \gx2_typical \enddonotcall
1887 ///
1888 /// \writesgpu
1889 /// \alwayswritesgpu
1890 ///
1891 void GX2API GX2SaveStreamOutContext(u32 soTarget, const GX2StreamOutBuffer* pStreamOutBuf);
1892 
1893 /// \brief Initialize the stream out buffer context for the stream out target
1894 ///
1895 /// \note soTarget should be less than \ref GX2_MAX_STREAMOUT_BUFFERS
1896 /// \note soTarget corresponds to the zero-based stream out varings file index
1897 ///
1898 /// \note If the reset flag is set to GX2_TRUE writes will start at the beginning of the stream
1899 ///       out buffer.  Otherwise, writes will start at the current location in the stream out
1900 ///       buffer (append to the buffer).
1901 ///
1902 /// \note This function should be called (for each stream out target used) after a context switch
1903 ///       (before a draw operation with stream out enabled) or after calling
1904 ///       \ref GX2SetStreamOutBuffer()
1905 ///
1906 /// \param soTarget      The stream out target to initialize
1907 /// \param pStreamOutBuf Pointer to stream out buffer structure
1908 /// \param reset         Stream out context reset flag
1909 ///
1910 /// \donotcall \gx2_typical \enddonotcall
1911 ///
1912 /// \writesgpu
1913 /// \alwayswritesgpu
1914 ///
1915 void GX2API GX2SetStreamOutContext(u32 soTarget,
1916                                    const GX2StreamOutBuffer* pStreamOutBuf,
1917                                    GX2Boolean reset);
1918 
1919 
1920 /// \brief Set an explicit offset for a stream out target
1921 ///
1922 /// Instead of starting to write a stream-out buffer at the beginning or after the place
1923 /// that was last written, this function allows you to write starting at an explicit offset.
1924 /// This function is used in place of GX2SetStreamOutContext.
1925 ///
1926 /// \note soTarget should be less than \ref GX2_MAX_STREAMOUT_BUFFERS
1927 /// \note soTarget corresponds to the zero-based stream out varings file index
1928 ///
1929 /// \param soTarget      The stream out target to initialize
1930 /// \param offset        The offset value desired
1931 ///
1932 /// \donotcall \gx2_typical \enddonotcall
1933 ///
1934 /// \writesgpu
1935 /// \alwayswritesgpu
1936 ///
GX2SetStreamOutExplicitOffset(u32 soTarget,u32 offset)1937 GX2_INLINE void GX2SetStreamOutExplicitOffset(u32 soTarget, u32 offset)
1938 {
1939     GX2SetStreamOutContext(soTarget, (GX2StreamOutBuffer *) offset, (GX2Boolean) GX2_STREAMOUT_OFFSET_EXPLICIT);
1940 }
1941 
1942 /// \brief Enable/disable stream out writes from the vertex shader or geometry shader
1943 ///
1944 /// \note If stream out is disabled and the shader contains instructions to write to a stream
1945 ///       out buffer the writes will be killed just as they would be if the stream out buffer is
1946 ///       full (i.e. the amount of data written exceeds the size of the stream out buffer).
1947 ///
1948 /// \param enable  Enable flag for stream out
1949 ///
1950 /// \donotcall \gx2_typical \enddonotcall
1951 ///
1952 /// \writesgpu
1953 /// \alwayswritesgpu
1954 ///
1955 void GX2API GX2SetStreamOutEnable(GX2Boolean enable);
1956 
1957 /// @}
1958 /// @addtogroup GX2ShaderAllGroup
1959 /// @{
1960 
1961 /// \brief Sets up the global shader export buffer.
1962 ///
1963 /// This maps a user buffer to the global SSBO that is shared by all shader
1964 /// types.
1965 ///
1966 /// \note Setting the buffer size to 0 disables the global SSBO.
1967 /// \note For more information see \ref GX2GLSLSSBOSect.
1968 ///
1969 /// \warning Changing shader export buffers results in a GPU flush because it
1970 /// is not context specific. Changing the shader export buffer frequently
1971 /// may cause a reduction in performance.
1972 ///
1973 /// \param buffer Pointer to the buffer where export data should be written. Alignment must be in multiples of \ref GX2_EXPORT_BUFFER_ALIGNMENT.
1974 /// \param size Size in bytes of the buffer where export data is to be written. Must be a multiple of \ref GX2_EXPORT_BUFFER_ALIGNMENT bytes.
1975 ///
1976 /// \donotcall \gx2_typical \enddonotcall
1977 ///
1978 /// \writesgpu
1979 /// \alwayswritesgpu
1980 ///
1981 void GX2API GX2SetShaderExportBuffer(void *buffer, u32 size);
1982 
1983 /// @}
1984 
1985 
1986 #ifdef __cplusplus
1987 }
1988 #endif // __cplusplus
1989 
1990 #endif // _CAFE_GX2_SHADERS_H_
1991