/*---------------------------------------------------------------------------* Copyright (C) Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. *---------------------------------------------------------------------------*/ // ------------------------------------------------------- // gx2Shaders.h (Shared between PC:gshConvert and Gx2) // // // Declares shader-related types & functions for gx2 library. // // Note. Many of the structures in this file exist in serialized // format in Gfx2 shader files. Modifying any of the structures // hence runs huge risk of invalidating any or all shader files. // // Because these structures are also used on the PC, // please do not add non 32-bit/element fields into these data structures, // as they will not serialize correctly. // -------------------------------------------------------- #ifndef _CAFE_GX2_SHADERS_H_ #define _CAFE_GX2_SHADERS_H_ #include #include #ifdef __cplusplus extern "C" { #endif // __cplusplus /// @addtogroup GX2ShaderGroup /// @{ /// @addtogroup GX2ShaderAllGroup /// @{ //---------------------------------------------------------------------- // Defines /// \brief The number of registers used to describe vertex shaders #define GX2_NUM_VERTEX_SHADER_REGISTERS 52 /// \brief The number of registers used to describe geometry shaders #define GX2_NUM_GEOMETRY_SHADER_REGISTERS 19 /// \brief The number of registers used to describe pixel shaders #define GX2_NUM_PIXEL_SHADER_REGISTERS 41 /// \brief The number of registers used to describe fetch shaders #define GX2_NUM_FETCH_SHADER_REGISTERS 1 /// \brief The number of registers used to describe compute shaders #define GX2_NUM_COMPUTE_SHADER_REGISTERS 12 /// \brief The number of u32 values used to describe loop vars #define GX2_NUM_LOOP_VAR_U32_WORDS 2 // --------------------------------------- // Shader data structures /// \brief Shader Uniform Block Structure /// /// A Uniform Block is a container for one or more Uniform Block Variables stored sequentially /// typedef struct _GX2UniformBlock { /// Name of uniform block const char * name; /// Hardware location of uniform block, determined by the shader compiler u32 location; /// Size of the overall block, in bytes u32 size; } GX2UniformBlock; /// \brief Uniform Initial Value Structure /// /// Contains initial uniform value along with corresponding offset /// typedef struct _GX2UniformInitialValue { /// Initial uniform value f32 value[4]; /// Register offset u32 offset; } GX2UniformInitialValue; /// \brief Shader Uniform Variable Structure /// /// \note This applies to both Uniform Registers and Uniform Blocks (as specified) /// typedef struct _GX2UniformVar { /// Name of uniform (imported from shader) const char * name; /// Variable data type. Use \ref GX2VarTypeToCount to convert to a count. GX2VarType type; /// Number of elements in an array. Set to one for non-arrays. u32 arrayCount; /// 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 u32 offset; /// Which uniform block this uniform belongs to. /// /// For Uniform Blocks, this is the index into the GX2*Shader.uniformBlocks array. /// Range is 0 to (GX2*Shader.numUniformBlocks - 1) /// /// For Uniforms Registers, this is always GX2_UNIFORM_BLOCK_INDEX_INVALID. /// /// This should not be confused with GX2UniformBlock.location. u32 blockIndex; } GX2UniformVar; /// \brief Vertex Attribute Variable (as seen by the Vertex Shader) /// typedef struct _GX2AttribVar { /// Name of attribute const char * name; /// Variable type GX2VarType type; /// Number of elements in an array. Set to one for non-arrays. u32 arrayCount; /// Attribute location in hardware semantic table u32 location; } GX2AttribVar; /// \brief Vertex Attribute Stream (as seen by the Fetch Shader) /// typedef struct _GX2AttribStream { /// Attribute location (destination) on hardware. See \ref GX2AttribVar (location) u32 location; /// Vertex Buffer index (source) to read from. Should match index in \ref GX2SetAttribBuffer. u32 buffer; /// Byte offset from start of vertex buffer to this element u32 offset; /// Vertex stream data is in this format GX2AttribFormat format; /// Vertex stream data fetch element index type /// (vertex Id or instance Id) GX2AttribIndexType indexType; /// This only applies when indexType == GX2_ATTRIB_INDEX_INSTANCE_ID. /// If greater than 1, the element index is further integer divided by /// aluDivisor. You may have up to 2 unique divisors that are > 1 in a /// a given fetch shader. More than 2 such divisors might be supported /// in a future SDK; this requires additional fetch shader instructions. /// Note: Divisors > 1 are not compatible with tessellation. u32 aluDivisor; /// Per-component destination selects for writing into destination GPR GX2CompSel destSel; /// Endian swap mode to use when reading the data GX2EndianSwapMode endianSwap; } GX2AttribStream; /// \brief Texture Sampler as seen by pixel and vertex shaders. /// /// \note The location value applies to both the texture number and the sampler number. /// typedef struct _GX2SamplerVar { /// Name of texture sampler const char * name; /// Sampler type GX2SamplerType type; /// Hardware location of texture and sampler u32 location; } GX2SamplerVar; /// @} /// @addtogroup GX2ShaderVertexGroup /// @{ // !!!Note!!! - The GX2VertexShader structure is burned into a .gsh file. // Altering parameters or changing their order may invalidate all existing content. /// \brief Contains all information (user and private) for a vertex shader /// typedef struct _GX2VertexShader { /// All register information needed to setup GPU7 (private) u32 _regs[GX2_NUM_VERTEX_SHADER_REGISTERS]; /// size of shader program, in bytes u32 shaderSize; /// pointer to shader program. Must be aligned on 256 byte boundary. void * shaderPtr; /// Shader mode for uniforms \ref GX2SetShaderMode GX2ShaderMode shaderMode; /// Number of Uniform Blocks (only for \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_GEOMETRY_SHADER) u32 numUniformBlocks; /// Uniform Blocks (only for \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_GEOMETRY_SHADER) GX2UniformBlock * uniformBlocks; /// Number of Vertex Shader Uniforms u32 numUniforms; /// Vertex Shader Uniforms GX2UniformVar * uniformVars; /// Number of initial values for Uniforms. Count is in Vec4s /// (Matrix data types may have 2-4 rows). u32 numInitialValues; /// Initial values for Uniforms GX2UniformInitialValue * initialValues; /// Number of loop variables (private) u32 _numLoops; /// Loops variables (private) void * _loopVars; /// Number of Sampler variables u32 numSamplers; /// Samplers variables GX2SamplerVar * samplerVars; /// Number of Attribute variables u32 numAttribs; /// Attribute variables GX2AttribVar * attribVars; // Space allocated to a single vertex in the GS Input ring buffer (in u32's). // The number of 32-bit values written by the shader per vertex. u32 ringItemsize; /// The shader contains stream out write instructions. GX2Boolean hasStreamOut; /// stride (in bytes) between each vertex for each stream out target u32 streamOutVertexStride[GX2_MAX_STREAMOUT_BUFFERS]; /// use a GX2RBuffer for the shader program instead of shaderPtr and shaderSize. shaderPtr must be NULL. GX2RBuffer shaderProgram; } GX2VertexShader; /// @} /// @addtogroup GX2ShaderGeometryGroup /// @{ // !!!Note!!! - The GX2GeometryShader structure is burned into a .gsh file. // Altering parameters or changing their order may invalidate all existing content. /// \brief Contains all information (user and private) for a geometry shader /// typedef struct _GX2GeometryShader { /// All register information needed to setup GPU7 (private) u32 _regs[GX2_NUM_GEOMETRY_SHADER_REGISTERS]; /// size of the GS shader program, in bytes u32 shaderSize; /// pointer to GS shader program. Must be aligned on a 256 byte boundary. void * shaderPtr; /// size of the copy shader program, in bytes u32 copyShaderSize; /// pointer to copy shader program. Must be aligned on a 256 byte boundary. void * copyShaderPtr; /// Shader mode for uniforms \ref GX2SetShaderMode /// At the moment, must always be GX2_SHADER_MODE_GEOMETRY_SHADER. GX2ShaderMode shaderMode; /// Number of Uniform Blocks u32 numUniformBlocks; /// Uniform Blocks GX2UniformBlock * uniformBlocks; /// Number of Vertex Shader Uniforms u32 numUniforms; /// Vertex Shader Uniforms GX2UniformVar * uniformVars; /// Number of initial values for Uniforms. Count is in Vec4s /// (Matrix data types may have 2-4 rows). u32 numInitialValues; /// Initial values for Uniforms GX2UniformInitialValue * initialValues; /// Number of loop variables (private) u32 _numLoops; /// Loops variables (private) void * _loopVars; /// Number of Sampler variables u32 numSamplers; /// Samplers variables GX2SamplerVar * samplerVars; // Space allocated to a single primitive in the GS output ring buffer (in u32's). // The number of 32-bit values written by the shader is the number // of vertices output * the amount of data per vertex. u32 ringItemsize; /// The shader contains stream out write instructions. GX2Boolean hasStreamOut; /// stride (in bytes) between each vertex for each stream out target u32 streamOutVertexStride[GX2_MAX_STREAMOUT_BUFFERS]; /// use a GX2RBuffer for the shader program instead of shaderPtr and shaderSize. shaderPtr must be NULL. GX2RBuffer shaderProgram; /// use a GX2RBuffer for the shader program instead of shaderPtr and shaderSize. shaderPtr must be NULL. GX2RBuffer copyShaderProgram; } GX2GeometryShader; // !!!Note!!! - The GX2PixelShader structure is burned into a .gsh file. // Altering parameters or changing their order may invalidate all existing content. /// @} /// @addtogroup GX2ShaderPixelGroup /// @{ /// \brief Contains all information (user and private) for a pixel shader /// typedef struct _GX2PixelShader { /// All register information needed to setup GPU7 (private) u32 _regs[GX2_NUM_PIXEL_SHADER_REGISTERS]; /// size of shader program, in bytes u32 shaderSize; /// pointer to shader program. Must be aligned on 256 byte boundary. void * shaderPtr; /// Shader mode for uniforms \ref GX2SetShaderMode GX2ShaderMode shaderMode; /// Number of Uniform Blocks (only for \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_GEOMETRY_SHADER) u32 numUniformBlocks; /// Uniform Blocks (only for \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_GEOMETRY_SHADER) GX2UniformBlock * uniformBlocks; /// Number of Pixel Shader Uniforms u32 numUniforms; /// Pixel Shader Uniforms GX2UniformVar * uniformVars; /// Number of initial values for Uniforms. Count is in Vec4s /// (Matrix data types may have 2-4 rows). u32 numInitialValues; /// Initial values for Uniforms GX2UniformInitialValue * initialValues; /// Number of loop variables (private) u32 _numLoops; /// Loops variables (private) void * _loopVars; /// Number of Sampler variables u32 numSamplers; /// Samplers variables GX2SamplerVar * samplerVars; /// use a GX2RBuffer for the shader program instead of shaderPtr and shaderSize. shaderPtr must be NULL. GX2RBuffer shaderProgram; } GX2PixelShader; /// @} /// @addtogroup GX2ShaderFetchGroup /// @{ /// \brief Contains all information (user and private) for a Fetch Shader /// typedef struct _GX2FetchShader { // Fetch shader type GX2FetchShaderType type; /// All register information needed to setup GPU7 (private) u32 _regs[GX2_NUM_FETCH_SHADER_REGISTERS]; /// size of shader program, in bytes u32 shaderSize; /// pointer to shader program. Must be aligned on 256 byte boundary. void * shaderPtr; /// Number of Attributes specified by Fetch Shader u32 numAttribs; // prototype for instancing (private) u32 _num_divisors; u32 _divisors[2]; } GX2FetchShader; /// @} /// @addtogroup GX2ShaderComputeGroup /// @{ /// \brief Compute shader dispatch parameters. /// /// This structure contains the necessary data used by \ref GX2DispatchCompute /// for running a compute shader on a set of work-groups. /// /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders" /// typedef struct _GX2DispatchParams { u32 num_groups_x; ///< Number of work-groups in x dimension. Must be at least 1. u32 num_groups_y; ///< Number of work-groups in y dimension. Must be at least 1. u32 num_groups_z; ///< Number of work-groups in z dimension. Must be at least 1. u32 padding; ///< Alignment padding } GX2DispatchParams; /// \brief Contains all information (user and private) for a Compute Shader /// /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders" /// typedef struct _GX2ComputeShader { /// All register information needed to setup GPU7 (private) u32 _regs[GX2_NUM_COMPUTE_SHADER_REGISTERS]; /// size of shader program, in bytes u32 shaderSize; /// pointer to shader program. Must be aligned on 256 byte boundary. void * shaderPtr; /// Number of Uniform Blocks u32 numUniformBlocks; /// Uniform Blocks GX2UniformBlock * uniformBlocks; /// Number of Compute Shader Uniforms u32 numUniforms; /// Compute Shader Uniforms GX2UniformVar * uniformVars; /// Number of initial values for Uniforms. Count is in Vec4s /// (Matrix data types may have 2-4 rows). u32 numInitialValues; /// Initial values for Uniforms GX2UniformInitialValue * initialValues; /// Number of loop variables (private) u32 _numLoops; /// Loops variables (private) void * _loopVars; /// Number of Sampler variables u32 numSamplers; /// Samplers variables GX2SamplerVar * samplerVars; // Layout of shader u32 layout_size_x; ///< Number of work-items per work-group in the x dimension. u32 layout_size_y; ///< Number of work-items per work-group in the y dimension. u32 layout_size_z; ///< Number of work-items per work-group in the z dimension. /// The shader exceeds the 64 limit on group size GX2Boolean Over64Mode; /// Maximum allowed wavefronts to run on a given SIMD. Zero-means unrestricted. u32 numWavesPerSIMD; /// use a GX2RBuffer for the shader program instead of shaderPtr and shaderSize. shaderPtr must be NULL. GX2RBuffer shaderProgram; } GX2ComputeShader; // --------------------------------------- // Shader Program Resources /// @} /// @addtogroup GX2ShaderVertexGroup /// @{ /// \brief Function to return the number of GPRs used by the Vertex Shader program /// /// \param pShader Pointer to Vertex Shader /// \return number of GPRs used by the vertex shader program /// /// \donotcall \threadsafe \enddonotcall /// u32 GX2API GX2GetVertexShaderGPRs(const GX2VertexShader * pShader); /// \brief Function to return the number of stack entries used by the Vertex Shader program /// /// \param pShader Pointer to Vertex Shader /// \return number of stack entries used by the vertex shader program /// /// \donotcall \threadsafe \enddonotcall /// u32 GX2API GX2GetVertexShaderStackEntries(const GX2VertexShader * pShader); /// @} /// @addtogroup GX2ShaderGeometryGroup /// @{ /// \brief Function to return the number of GPRs used by the Geometry Shader program /// /// \param pShader Pointer to Geometry Shader /// \return number of GPRs used by the geometry shader program /// /// \donotcall \threadsafe \enddonotcall /// u32 GX2API GX2GetGeometryShaderGPRs(const GX2GeometryShader * pShader); /// \brief Function to return the number of stack entries used by the Geometry Shader program /// /// \param pShader Pointer to Geometry Shader /// \return number of stack entries used by the geometry shader program /// /// \donotcall \threadsafe \enddonotcall /// u32 GX2API GX2GetGeometryShaderStackEntries(const GX2GeometryShader * pShader); /// @} /// @addtogroup GX2ShaderPixelGroup /// @{ /// \brief Function to return the number of GPRs used by the Pixel Shader program /// /// \param pShader shader Pointer to Pixel Shader /// \return number of GPRs used by the pixel shader program /// /// \donotcall \threadsafe \enddonotcall /// u32 GX2API GX2GetPixelShaderGPRs(const GX2PixelShader * pShader); /// \brief Function to return the number of stack entries used by the Pixel Shader program /// /// \param pShader Pointer to Pixel Shader /// \return number of stack entries used by the pixel shader program /// /// \donotcall \threadsafe \enddonotcall /// u32 GX2API GX2GetPixelShaderStackEntries(const GX2PixelShader * pShader); /// @} /// @addtogroup GX2ShaderVertexGroup /// @{ // --------------------------------------- // Uniforms /// \brief Convenience function to return a Vertex Shader Uniform Variable (given its name) /// /// \note Will return NULL if the variable is not found. /// /// \param shader Pointer to Vertex Shader /// \param name String name specified in shader code /// \return Pointer to Uniform structure within the shader structure /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE GX2UniformVar * GX2GetVertexUniformVar(const GX2VertexShader * shader, const char * name) { u32 i; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); for (i = 0; i < shader->numUniforms; i++) { if (strcmp(shader->uniformVars[i].name, name) == 0) return &(shader->uniformVars[i]); } return NULL; } /// @} /// @addtogroup GX2ShaderGeometryGroup /// @{ /// \brief Convenience function to return a Geometry Shader Uniform Variable (given its name) /// /// \note Will return NULL if the variable is not found. /// /// \param shader Pointer to Geometry Shader /// \param name String name specified in shader code /// \return Pointer to Uniform structure within the shader structure /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE GX2UniformVar * GX2GetGeometryUniformVar(const GX2GeometryShader * shader, const char * name) { u32 i; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); for (i = 0; i < shader->numUniforms; i++) { if (strcmp(shader->uniformVars[i].name, name) == 0) return &(shader->uniformVars[i]); } return NULL; } /// @} /// @addtogroup GX2ShaderPixelGroup /// @{ /// \brief Convenience function to return a Pixel Shader Uniform Variable (given its name) /// /// \note Will return NULL if the variable is not found. /// /// \param shader Pointer to Pixel Shader /// \param name String name specified in shader code /// \return Pointer to Uniform structure within the shader structure /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE GX2UniformVar * GX2GetPixelUniformVar(const GX2PixelShader * shader, const char * name) { u32 i; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); for (i = 0; i < shader->numUniforms; i++) { if (strcmp(shader->uniformVars[i].name, name) == 0) return &(shader->uniformVars[i]); } return NULL; } /// @} /// @addtogroup GX2ShaderComputeGroup /// @{ /// \brief Convenience function to return a Compute Shader Uniform Variable (given its name) /// /// \note Will return NULL if the variable is not found. /// /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders" /// /// \param shader Pointer to Compute Shader /// \param name String name specified in shader code /// \return Pointer to Uniform structure within the shader structure /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE GX2UniformVar * GX2GetComputeUniformVar(const GX2ComputeShader * shader, const char * name) { u32 i; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); for (i = 0; i < shader->numUniforms; i++) { if (strcmp(shader->uniformVars[i].name, name) == 0) return &(shader->uniformVars[i]); } return NULL; } /// @} /// @addtogroup GX2ShaderVertexGroup /// @{ /// \brief Convenience function to return a Vertex Shader Uniform's Offset (given its name) /// /// \note Will return GX2_UNIFORM_VAR_INVALID_OFFSET if the uniform is not found. /// /// \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. /// In this case, the full 32 bit offset (including flags) may still be passed to GX2SetVertexUniformReg. /// /// /// \param shader Pointer to Vertex Shader /// \param name String name specified in shader code /// \return Offset value provided in number of u32's /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE s32 GX2GetVertexUniformVarOffset(const GX2VertexShader * shader, const char * name) { GX2UniformVar * uniform; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); uniform = GX2GetVertexUniformVar(shader, name); if (!uniform) return GX2_UNIFORM_VAR_INVALID_OFFSET; return (s32) uniform->offset; } /// @} /// @addtogroup GX2ShaderGeometryGroup /// @{ /// \brief Convenience function to return a Geometry Shader Uniform's Offset (given its name) /// /// \note Will return GX2_UNIFORM_VAR_INVALID_OFFSET if the uniform is not found. /// /// \param shader Pointer to Geometry Shader /// \param name String name specified in shader code /// \return Offset value provided in number of u32's /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE s32 GX2GetGeometryUniformVarOffset(const GX2GeometryShader * shader, const char * name) { GX2UniformVar * uniform; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); uniform = GX2GetGeometryUniformVar(shader, name); if (!uniform) return GX2_UNIFORM_VAR_INVALID_OFFSET; return (s32) uniform->offset; } /// @} /// @addtogroup GX2ShaderPixelGroup /// @{ /// \brief Convenience function to return a Pixel Shader Uniform's Offset (given its name) /// /// \note Will return GX2_UNIFORM_VAR_INVALID_OFFSET if the uniform is not found. /// /// \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. /// In this case, the full 32 bit offset (including flags) may still be passed to GX2SetPixelUniformReg. /// /// \param shader Pointer to Pixel Shader /// \param name String name specified in shader code /// \return Offset value provided in number of u32's /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE s32 GX2GetPixelUniformVarOffset(const GX2PixelShader * shader, const char * name) { GX2UniformVar * uniform; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); uniform = GX2GetPixelUniformVar(shader, name); if (!uniform) return GX2_UNIFORM_VAR_INVALID_OFFSET; return (s32) uniform->offset; } /// @} /// @addtogroup GX2ShaderComputeGroup /// @{ /// \brief Convenience function to return a Compute Shader Uniform's Offset (given its name) /// /// \note Will return GX2_UNIFORM_VAR_INVALID_OFFSET if the uniform is not found. /// /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders" /// /// \param shader Pointer to Compute Shader /// \param name String name specified in shader code /// \return Offset value provided in number of u32's /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE s32 GX2GetComputeUniformVarOffset(const GX2ComputeShader * shader, const char * name) { GX2UniformVar * uniform; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); uniform = GX2GetComputeUniformVar(shader, name); if (!uniform) return GX2_UNIFORM_VAR_INVALID_OFFSET; return (s32) uniform->offset; } /// @} /// @addtogroup GX2ShaderAllGroup /// @{ // --------------------------------------- // Uniform Registers /// \brief Convenience function to convert Uniform Type into its component count /// /// \note the component count is rounded up to multiples of 4, due to the HW //// requirement that uniform registers always contain 4 u32-sized components. /// /// \param type Uniform type /// \return Count of how many u32-sized components are used by that type /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE u32 GX2VarTypeToCount(GX2VarType type) { switch (type) { case GX2_VAR_TYPE_VOID: return 0; case GX2_VAR_TYPE_FLOAT: case GX2_VAR_TYPE_BOOL: case GX2_VAR_TYPE_INT: case GX2_VAR_TYPE_UINT: return 4; case GX2_VAR_TYPE_VEC2: case GX2_VAR_TYPE_BVEC2: case GX2_VAR_TYPE_IVEC2: case GX2_VAR_TYPE_UVEC2: return 4; case GX2_VAR_TYPE_VEC3: case GX2_VAR_TYPE_BVEC3: case GX2_VAR_TYPE_IVEC3: case GX2_VAR_TYPE_UVEC3: return 4; case GX2_VAR_TYPE_VEC4: case GX2_VAR_TYPE_BVEC4: case GX2_VAR_TYPE_IVEC4: case GX2_VAR_TYPE_UVEC4: return 4; case GX2_VAR_TYPE_MAT2: case GX2_VAR_TYPE_MAT2X3: case GX2_VAR_TYPE_MAT2X4: return 8; case GX2_VAR_TYPE_MAT3X2: case GX2_VAR_TYPE_MAT3: case GX2_VAR_TYPE_MAT3X4: return 12; case GX2_VAR_TYPE_MAT4X2: case GX2_VAR_TYPE_MAT4X3: case GX2_VAR_TYPE_MAT4: return 16; case GX2_VAR_TYPE_DOUBLE: case GX2_VAR_TYPE_DVEC2: case GX2_VAR_TYPE_DVEC3: case GX2_VAR_TYPE_DVEC4: case GX2_VAR_TYPE_DMAT2: case GX2_VAR_TYPE_DMAT2X3: case GX2_VAR_TYPE_DMAT2X4: case GX2_VAR_TYPE_DMAT3X2: case GX2_VAR_TYPE_DMAT3: case GX2_VAR_TYPE_DMAT3X4: case GX2_VAR_TYPE_DMAT4X2: case GX2_VAR_TYPE_DMAT4X3: case GX2_VAR_TYPE_DMAT4: default: ASSERT(!"var type not supported\n"); return 0; } // no fall through } /// @} /// @addtogroup GX2ShaderVertexGroup /// @{ /// \brief Set vertex shader uniform values (for \ref GX2_SHADER_MODE_UNIFORM_REGISTER only) /// /// This API can set individual uniforms or many uniforms. /// \note This API is used for f32, u32, and bool formats. /// \note This API can only be used for GX2_SHADER_MODE_UNIFORM_REGISTER. See \ref GX2SetShaderMode /// /// \param offset Offset of the uniform (in number of u32's); MUST BE A MULTIPLE of 4 (unless this was returned by GX2GetVertexUniformVarOffset) /// \param count Number of components (in number of u32's); MUST BE A MULTIPLE of 4! /// \param values Pointer to buffer containing values (byte size should be count * sizeof(u32)) /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetVertexUniformReg(u32 offset, u32 count, const void *values); /// @} /// @addtogroup GX2ShaderPixelGroup /// @{ /// \brief Set pixel shader uniform values (for \ref GX2_SHADER_MODE_UNIFORM_REGISTER only) /// /// This API can set individual uniforms or many uniforms. /// \note This API is used for f32, u32, and bool formats. /// \note This API can only be used for GX2_SHADER_MODE_UNIFORM_REGISTER. See \ref GX2SetShaderMode /// /// \param offset Offset of the uniform (in number of u32's); MUST BE A MULTIPLE of 4 (unless returned from GX2GetPixelUniformVarOffset) /// \param count Number of components (in number of u32's); MUST BE A MULTIPLE of 4! /// \param values Pointer to buffer containing values (byte size should be count * sizeof(u32)) /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetPixelUniformReg(u32 offset, u32 count, const void *values); /// @} /// @addtogroup GX2ShaderVertexGroup /// @{ /// \brief Set default (initial) VS uniform values (for \ref GX2_SHADER_MODE_UNIFORM_REGISTER only) /// /// \param shader Pointer to Vertex Shader containing uniforms to initialize /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// GX2_INLINE void GX2SetVertexUniformRegDefaults(const GX2VertexShader* shader) { u32 i; ASSERT(shader && "NULL Shader"); for (i = 0; i < shader->numInitialValues; i++) { GX2SetVertexUniformReg(shader->initialValues[i].offset * 4, 4, shader->initialValues[i].value); } } /// @} /// @addtogroup GX2ShaderPixelGroup /// @{ /// \brief Set default (initial) PS uniform values (for \ref GX2_SHADER_MODE_UNIFORM_REGISTER only) /// /// \param shader Pointer to Pixel Shader containing uniforms to initialize /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// GX2_INLINE void GX2SetPixelUniformRegDefaults(const GX2PixelShader* shader) { u32 i; ASSERT(shader && "NULL Shader"); for (i = 0; i < shader->numInitialValues; i++) { GX2SetPixelUniformReg(shader->initialValues[i].offset * 4, 4, shader->initialValues[i].value); } } /// @} /// @addtogroup GX2ShaderVertexGroup /// @{ // --------------------------------------- // Uniform Blocks /// \brief Convenience function to return a vertex shader Uniform Block (given its name) /// /// Use in \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_GEOMETRY_SHADER only. /// /// \note Will return NULL if uniform block is not found. /// /// \param shader Pointer to Vertex Shader /// \param name String name specified in shader code /// \return Pointer to Uniform Block structure within the shader structure /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE GX2UniformBlock* GX2GetVertexUniformBlock(const GX2VertexShader* shader, const char * name) { u32 i; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); for (i = 0; i < shader->numUniformBlocks; i++) { if (strcmp(shader->uniformBlocks[i].name, name) == 0) return &(shader->uniformBlocks[i]); } return NULL; } /// @} /// @addtogroup GX2ShaderGeometryGroup /// @{ /// \brief Convenience function to return a geometry shader Uniform Block (given its name) /// /// \note Will return NULL if uniform block is not found. /// /// \param shader Pointer to Geometry Shader /// \param name String name specified in shader code /// \return Pointer to Uniform Block structure within the shader structure /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE GX2UniformBlock* GX2GetGeometryUniformBlock(const GX2GeometryShader* shader, const char * name) { u32 i; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); for (i = 0; i < shader->numUniformBlocks; i++) { if (strcmp(shader->uniformBlocks[i].name, name) == 0) return &(shader->uniformBlocks[i]); } return NULL; } /// @} /// @addtogroup GX2ShaderPixelGroup /// @{ /// \brief Convenience function to return a pixel shader Uniform Block (given its name) /// /// Use in \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_GEOMETRY_SHADER only. /// /// \note Will return NULL if uniform block is not found. /// /// \param shader Pointer to Pixel Shader /// \param name String name specified in shader code /// \return Pointer to Uniform Block structure within the shader structure /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE GX2UniformBlock* GX2GetPixelUniformBlock(const GX2PixelShader* shader, const char * name) { u32 i; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); for (i = 0; i < shader->numUniformBlocks; i++) { if (strcmp(shader->uniformBlocks[i].name, name) == 0) return &(shader->uniformBlocks[i]); } return NULL; } /// @} /// @addtogroup GX2ShaderComputeGroup /// @{ // --------------------------------------- // Uniform Blocks /// \brief Convenience function to return a compute shader Uniform Block (given its name) /// /// \note Will return NULL if uniform block is not found. /// /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders" /// /// \param shader Pointer to Compute Shader /// \param name String name specified in shader code /// \return Pointer to Uniform Block structure within the shader structure /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE GX2UniformBlock* GX2GetComputeUniformBlock(const GX2ComputeShader* shader, const char * name) { u32 i; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); for (i = 0; i < shader->numUniformBlocks; i++) { if (strcmp(shader->uniformBlocks[i].name, name) == 0) return &(shader->uniformBlocks[i]); } return NULL; } /// @} /// @addtogroup GX2ShaderVertexGroup /// @{ /// \brief Set a Uniform Block for the Vertex Shader /// /// Use in \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_GEOMETRY_SHADER only. /// /// \b Warning: User must keep the buffer valid (with expected values) /// until the GPU has completed the draws using this Uniform Block. /// /// \param location Hardware location of uniform block (\ref GX2UniformBlock) /// \param size Size of Uniform Block (in bytes) (\ref GX2UniformBlock) /// \param addr User-allocated buffer (of size "size") containing all values for block /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetVertexUniformBlock(u32 location, u32 size, const void* addr); /// @} /// @addtogroup GX2ShaderGeometryGroup /// @{ /// \brief Set a Uniform Block for the Geometry Shader /// /// \b Warning: User must keep the buffer valid (with expected values) /// until GPU has completed the draws using this Uniform Block. /// /// \param location Hardware location of uniform block (\ref GX2UniformBlock) /// \param size Size of Uniform Block (in bytes) (\ref GX2UniformBlock) /// \param addr User-allocated buffer (of size "size") containing all values for block /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetGeometryUniformBlock(u32 location, u32 size, const void* addr); /// @} /// @addtogroup GX2ShaderPixelGroup /// @{ /// \brief Set a Uniform Block for the Pixel Shader /// /// Use in \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_GEOMETRY_SHADER only. /// /// \b Warning: User must keep the buffer valid (with expected values) /// until GPU has completed the draws using this Uniform Block. /// /// \param location Hardware location of uniform block (\ref GX2UniformBlock) /// \param size Size of Uniform Block (in bytes) (\ref GX2UniformBlock) /// \param addr User-allocated buffer (of size "size") containing all values for block /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetPixelUniformBlock(u32 location, u32 size, const void* addr); /// @} /// @addtogroup GX2ShaderComputeGroup /// @{ /// \brief Set a Uniform Block for the Compute Shader /// /// Use in \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_COMPUTE_SHADER only. /// /// \b Warning: User must keep the buffer valid (with expected values) /// until GPU has completed the draws using this Uniform Block. /// /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders" /// /// \param location Hardware location of uniform block (\ref GX2UniformBlock) /// \param size Size of Uniform Block (in bytes) (\ref GX2UniformBlock) /// \param addr User-allocated buffer (of size "size") containing all values for block /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetComputeUniformBlock(u32 location, u32 size, const void* addr); /// @} /// @addtogroup GX2ShaderVertexGroup /// @{ // --------------------------------------- // Samplers /// \brief Convenience function to return a Vertex Shader Sampler Variable (given its name) /// /// \note Will return NULL if sampler is not found. /// /// \param shader Pointer to Vertex Shader /// \param name String name specified in shader code /// \return Pointer to Sampler structure within the shader structure /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE GX2SamplerVar* GX2GetVertexSamplerVar(const GX2VertexShader* shader, const char* name) { u32 i; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); for (i = 0; i < shader->numSamplers; i++) { if (strcmp(shader->samplerVars[i].name, name) == 0) return &(shader->samplerVars[i]); } return NULL; } /// @} /// @addtogroup GX2ShaderGeometryGroup /// @{ /// \brief Convenience function to return a Geometry Shader Sampler Variable (given its name) /// /// \note Will return NULL if sampler is not found. /// /// \param shader Pointer to Geometry Shader /// \param name String name specified in shader code /// \return Pointer to Sampler structure within the shader structure /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE GX2SamplerVar* GX2GetGeometrySamplerVar(const GX2GeometryShader* shader, const char* name) { u32 i; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); for (i = 0; i < shader->numSamplers; i++) { if (strcmp(shader->samplerVars[i].name, name) == 0) return &(shader->samplerVars[i]); } return NULL; } /// @} /// @addtogroup GX2ShaderPixelGroup /// @{ /// \brief Convenience function to return a Pixel Shader Sampler Variable (given its name) /// /// \note Will return NULL if sampler is not found. /// /// \param shader Pointer to Pixel Shader /// \param name String name specified in shader code /// \return Pointer to Sampler structure within the shader structure /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE GX2SamplerVar* GX2GetPixelSamplerVar(const GX2PixelShader* shader, const char* name) { u32 i; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); for (i = 0; i < shader->numSamplers; i++) { if (strcmp(shader->samplerVars[i].name, name) == 0) return &(shader->samplerVars[i]); } return NULL; } /// @} /// @addtogroup GX2ShaderComputeGroup /// @{ // --------------------------------------- // Samplers /// \brief Convenience function to return a Compute Shader Sampler Variable (given its name) /// /// \note Will return NULL if sampler is not found. /// /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders" /// /// \param shader Pointer to Compute Shader /// \param name String name specified in shader code /// \return Pointer to Sampler structure within the shader structure /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE GX2SamplerVar* GX2GetComputeSamplerVar(const GX2ComputeShader* shader, const char* name) { u32 i; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); for (i = 0; i < shader->numSamplers; i++) { if (strcmp(shader->samplerVars[i].name, name) == 0) return &(shader->samplerVars[i]); } return NULL; } /// @} /// @addtogroup GX2ShaderVertexGroup /// @{ /// \brief Convenience function to return a Vertex Shader Sampler's hardware location (given its name) /// /// \note Will return (-1) if the sampler is not found. /// /// \param shader Pointer to Vertex Shader /// \param name String name specified in shader code /// \return Hardware location determined by compiler /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE s32 GX2GetVertexSamplerVarLocation(const GX2VertexShader* shader, const char* name) { GX2SamplerVar * sampler; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); sampler = GX2GetVertexSamplerVar(shader, name); if (!sampler) return -1; return (s32) sampler->location; } /// @} /// @addtogroup GX2ShaderGeometryGroup /// @{ /// \brief Convenience function to return a Geometry Shader Sampler's hardware location (given its name) /// /// \note Will return (-1) if the sampler is not found. /// /// \param shader Pointer to Geometry Shader /// \param name String name specified in shader code /// \return Hardware location determined by compiler /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE s32 GX2GetGeometrySamplerVarLocation(const GX2GeometryShader* shader, const char* name) { GX2SamplerVar * sampler; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); sampler = GX2GetGeometrySamplerVar(shader, name); if (!sampler) return -1; return (s32) sampler->location; } /// @} /// @addtogroup GX2ShaderPixelGroup /// @{ /// \brief Convenience function to return a Pixel Shader Sampler's hardware location (given its name) /// /// \note Will return (-1) if the sampler is not found. /// /// \param shader Pointer to Pixel Shader /// \param name String name specified in shader code /// \return Hardware location determined by compiler /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE s32 GX2GetPixelSamplerVarLocation(const GX2PixelShader* shader, const char* name) { GX2SamplerVar * sampler; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); sampler = GX2GetPixelSamplerVar(shader, name); if (!sampler) return -1; return (s32) sampler->location; } /// @} /// @addtogroup GX2ShaderComputeGroup /// @{ /// \brief Convenience function to return a Compute Shader Sampler's hardware location (given its name) /// /// \note Will return (-1) if the sampler is not found. /// /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders" /// /// \param shader Pointer to Compute Shader /// \param name String name specified in shader code /// \return Hardware location determined by compiler /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE s32 GX2GetComputeSamplerVarLocation(const GX2ComputeShader* shader, const char* name) { GX2SamplerVar * sampler; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); sampler = GX2GetComputeSamplerVar(shader, name); if (!sampler) return -1; return (s32) sampler->location; } /// @} /// @addtogroup GX2ShaderVertexGroup /// @{ /// \brief Convenience function to return a shader Attribute Variable (given its name) /// /// \note Will return NULL if the attribute is not found. /// /// \param shader Pointer to Vertex Shader /// \param name String name specified in shader code /// \return Pointer to Attribute structure within the shader structure /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE GX2AttribVar* GX2GetVertexAttribVar(const GX2VertexShader* shader, const char* name) { u32 i; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); for (i = 0; i < shader->numAttribs; i++) { if (strcmp(shader->attribVars[i].name, name) == 0) return &(shader->attribVars[i]); } return NULL; } /// \brief Convenience function to return a shader Attribute's hardware location (given its name) /// /// \note Will return (-1) if the attribute is not found. /// /// \param shader Pointer to Vertex Shader /// \param name String name specified in shader code /// \return Hardware location determined by compiler /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE s32 GX2GetVertexAttribVarLocation(const GX2VertexShader* shader, const char* name) { GX2AttribVar * attribVar; ASSERT(shader && "NULL Shader"); ASSERT(name && "NULL name"); attribVar = GX2GetVertexAttribVar(shader, name); if (!attribVar) return -1; return (s32) attribVar->location; } /// @} /// @addtogroup GX2ShaderFetchGroup /// @{ // --------------------------------------- // Fetch Shader Initialization /// \brief Calculate the size of a fetch shader. /// /// \param num_attrib number of attribute /// \param fsType The type of fetch shader to generate /// \param tessMode Tessellation mode, only valid if type is not \ref GX2_FETCH_SHADER_TESSELATION_NONE /// /// \donotcall \threadsafe \devonly \enddonotcall /// u32 GX2API GX2CalcFetchShaderSizeEx(u32 num_attrib, GX2FetchShaderType fsType, GX2TessellationMode tessMode); /// \brief Calculate the size of a fetch shader. /// /// \param num_attrib number of attribute /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE u32 GX2CalcFetchShaderSize(u32 num_attrib) { return GX2CalcFetchShaderSizeEx(num_attrib, GX2_FETCH_SHADER_TESSELATION_NONE, GX2_TESSELLATION_MODE_DISCRETE); // Not used } /// \brief Create a fetch shader based on the given attribute stream list. /// /// \param fs User-allocated instance of \ref GX2FetchShader structure /// \param fs_buffer User-allocated aligned buffer for the fetch shader binary code /// \param count Number of attribute streams /// \param attribs User-allocated array of \ref GX2AttribStream structures containing information /// about all attribute streams /// \param type The type of fetch shader to generate /// \param tessMode Tesselation mode, only valid if type is not \ref GX2_FETCH_SHADER_TESSELATION_NONE /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2InitFetchShaderEx( GX2FetchShader* fs, void* fs_buffer, u32 count, const GX2AttribStream* attribs, GX2FetchShaderType type, GX2TessellationMode tessMode); /// \brief Create a fetch shader based on the given attribute stream list. /// /// \param fs User-allocated instance of \ref GX2FetchShader structure /// \param fs_buffer User-allocated aligned buffer for the fetch shader binary code /// \param count Number of attribute streams /// \param attribs User-allocated array of \ref GX2AttribStream structures containing information /// about all attribute streams /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE void GX2InitFetchShader( GX2FetchShader* fs, void* fs_buffer, u32 count, const GX2AttribStream* attribs) { GX2InitFetchShaderEx(fs, fs_buffer, count, attribs, GX2_FETCH_SHADER_TESSELATION_NONE, GX2_TESSELLATION_MODE_DISCRETE); // Not used } /// \brief Helper function to set up a Vertex Attribute Stream. See \ref GX2AttribStream. /// /// \note Common defaults (based on the format) are assumed for the destination selects. /// All attributes are assumed to be indexed by vertex ID. /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE void GX2InitAttribStream( GX2AttribStream* attribStream, u32 location, u32 buffer, u32 offset, GX2AttribFormat format) { const GX2CompSel dstSel[20] = { GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_X001, GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_X001, GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW}; GX2_CHECK_ENUM_RANGE(format, GX2_ATTRIB_FORMAT); ASSERT(attribStream && "NULL Attrib"); attribStream->buffer = buffer; attribStream->offset = offset; attribStream->location = location; attribStream->format = format; attribStream->destSel = dstSel[format & 0xff]; attribStream->indexType = GX2_ATTRIB_INDEX_VERTEX_ID; attribStream->aluDivisor = 0; attribStream->endianSwap = GX2_ENDIANSWAP_DEFAULT; } /// \brief Returns the size in bits per attribute for a given attribute format. /// /// \donotcall \threadsafe \devonly \enddonotcall /// u32 GX2API GX2GetAttribFormatBits(GX2AttribFormat format); /// @} /// @addtogroup GX2ShaderGeometryGroup /// @{ /// \brief Calculates the necessary ring buffer size for geometry shader input (VS output) /// /// \param maxVSItemSize item size from vertex shader being used /// /// \donotcall \threadsafe \devonly \enddonotcall /// u32 GX2API GX2CalcGeometryShaderInputRingBufferSize(u32 maxVSItemSize); /// \brief Calculate necessary ring buffer size for geometry shader output (PS input) /// /// \param maxGSItemSize item size of geometry shader being used /// /// \donotcall \threadsafe \devonly \enddonotcall /// u32 GX2API GX2CalcGeometryShaderOutputRingBufferSize(u32 maxGSItemSize); /// \brief Setup ring buffer for geometry shader input (VS output) /// /// \note The ring buffer must be 256-byte aligned. /// \note This function invokes a full pipeline flush (approx. 8 microseconds). /// /// \param pRingBuffer Address of ring buffer /// \param size Size of ring buffer /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetGeometryShaderInputRingBuffer(void* pRingBuffer, u32 size); /// \brief Setup ring buffer for geometry shader output (PS input) /// /// \note The ring buffer must be 256-byte aligned. /// \note This function invokes a full pipeline flush (approx. 8 microseconds). /// /// \param pRingBuffer Address of ring buffer /// \param size Size of ring buffer /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetGeometryShaderOutputRingBuffer(void* pRingBuffer, u32 size); /// @} /// @addtogroup GX2ShaderAllGroup /// @{ /// \brief Select the shader mode and setup the shader resources /// /// \param mode shader mode /// \param vsGprs number of GPRs allocated to the vertex shader pipe /// \param vsStackSize number of stack entries allocated to the vertex shader pipe /// \param gsGprs number of GPRs allocated to the geometry shader pipe /// \param gsStackSize number of stack entries allocated to the geometry shader pipe /// \param psGprs number of GPRs allocated to the pixel shader pipe /// \param psStackSize number of stack entries allocated to the pixel shader pipe /// /// \note This function invokes a full pipeline flush (approx. 8 usecs). /// /// \note You must always reset the shaders in use after calling this. /// /// \note gsGprs and gsStackSize are only valid when the shader mode is set to /// \ref GX2_SHADER_MODE_GEOMETRY_SHADER. These values are ignored and should be set to 0 for /// all other modes. /// /// \note vsGprs+gsGprs+psGprs should not exceed \ref GX2_TOTAL_GPRS_GS_ENABLED when the shader mode is /// \ref GX2_SHADER_MODE_GEOMETRY_SHADER. /// /// \note vsGprs+psGprs should not exceed \ref GX2_TOTAL_GPRS_GS_DISABLED when the shader mode is /// not \ref GX2_SHADER_MODE_GEOMETRY_SHADER. /// /// \note vsStackSize+gsStackSize+psStackSize should not exceed \ref GX2_TOTAL_STACK_ENTRIES /// /// \note \ref GX2_SHADER_MODE_COMPUTE_SHADER ignores all Gpr and Stack parameters. /// /// \note \ref GX2_SHADER_MODE_COMPUTE_SHADER clobbers the state set by /// \ref GX2SetGeometryShaderInputRingBuffer and \ref GX2SetGeometryShaderOutputRingBuffer. /// State set by those API's must be reissued after resetting to \ref GX2_SHADER_MODE_GEOMETRY_SHADER. /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetShaderModeEx( GX2ShaderMode mode, u32 vsGprs, u32 vsStackSize, u32 gsGprs, u32 gsStackSize, u32 psGprs, u32 psStackSize); /// \brief Select the shader mode /// /// \param mode shader mode /// \note This function invokes a full pipeline flush (approx. 8 usecs). /// /// \note You must always reset the shaders in use after calling this. /// /// \note \ref GX2_SHADER_MODE_COMPUTE_SHADER clobbers the state set by /// \ref GX2SetGeometryShaderInputRingBuffer and \ref GX2SetGeometryShaderOutputRingBuffer. /// State set by those API's must be reissued after resetting to \ref GX2_SHADER_MODE_GEOMETRY_SHADER. /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// GX2_INLINE void GX2SetShaderMode(GX2ShaderMode mode) { u32 vsGprs; u32 vsStackSize; u32 gsGprs; u32 gsStackSize; u32 psGprs; u32 psStackSize; if (mode == GX2_SHADER_MODE_GEOMETRY_SHADER) { // Geometry shader is enabled vsGprs = 44; gsGprs = 64; psGprs = 76; vsStackSize = 32; gsStackSize = 48; psStackSize = 176; } else { // Geometry shader is disabled vsGprs = 48; gsGprs = 0; psGprs = 200; vsStackSize = 64; gsStackSize = 0; psStackSize = 192; } GX2SetShaderModeEx(mode, vsGprs, vsStackSize, gsGprs, gsStackSize, psGprs, psStackSize); } /// @} /// @addtogroup GX2ShaderFetchGroup /// @{ /// \brief Sets up the given fetch shader to be used /// /// \param fs Pointer to fetch shader structure to be used in rendering /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetFetchShader(GX2CTXPRM const GX2FetchShader* fs); /// @} /// @addtogroup GX2ShaderVertexGroup /// @{ /// \brief Sets up the given vertex shader to be used /// /// \param vs Pointer to vertex shader structure to be used in rendering /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetVertexShader(GX2CTXPRM const GX2VertexShader* vs); /// @} /// @addtogroup GX2ShaderGeometryGroup /// @{ /// \brief Sets up the given geometry shader to be used /// /// \param gs Pointer to geometry shader structure to be used in rendering /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetGeometryShader(GX2CTXPRM const GX2GeometryShader * gs); /// @} /// @addtogroup GX2ShaderPixelGroup /// @{ /// \brief Sets up the given pixel shader to be used /// /// \param ps Pointer to pixel shader structure to be used in rendering /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetPixelShader(GX2CTXPRM const GX2PixelShader* ps); /// @} /// @addtogroup GX2ShaderComputeGroup /// @{ /// \brief Sets up the given compute shader to be used /// /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders" /// /// \param cs Pointer to compute shader structure to be used in rendering /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetComputeShader(GX2CTXPRM const GX2ComputeShader* cs); /// @} /// @addtogroup GX2ShaderAllGroup /// @{ #ifndef GX2_OFFLINE_COMPILE /// \brief Helper function to set up Fetch, Vertex, and Pixel shaders at once. /// /// \param fs Pointer to fetch shader structure to be used in rendering /// \param vs Pointer to vertex shader structure to be used in rendering /// \param ps Pointer to pixel shader structure to be used in rendering /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// GX2_INLINE void GX2SetShaders(const GX2FetchShader* fs, const GX2VertexShader* vs, const GX2PixelShader* ps) { ASSERT(fs && "NULL Shader"); ASSERT(vs && "NULL Shader"); ASSERT(ps && "NULL Shader"); GX2SetFetchShader(fs); GX2SetVertexShader(vs); GX2SetPixelShader(ps); } #endif // GX2_OFFLINE_COMPILE /// @} /// @addtogroup GX2ShaderAllGroup /// @{ #ifndef GX2_OFFLINE_COMPILE /// \brief Helper function to set up Fetch, Vertex, Geometry, and Pixel shaders at once. /// /// \param fs Pointer to fetch shader structure to be used in rendering /// \param vs Pointer to vertex shader structure to be used in rendering /// \param gs Pointer to geometry shader structure to be used in rendering /// \param ps Pointer to pixel shader structure to be used in rendering /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// GX2_INLINE void GX2SetShadersEx(const GX2FetchShader* fs, const GX2VertexShader* vs, const GX2GeometryShader* gs, const GX2PixelShader* ps) { ASSERT(fs && "NULL Shader"); ASSERT(vs && "NULL Shader"); ASSERT(gs && "NULL Shader"); ASSERT(ps && "NULL Shader"); ASSERT(gs->shaderMode == GX2_SHADER_MODE_GEOMETRY_SHADER); GX2SetFetchShader(fs); GX2SetVertexShader(vs); GX2SetGeometryShader(gs); GX2SetPixelShader(ps); } #endif // GX2_OFFLINE_COMPILE /// @} /// @} /// @addtogroup GX2StreamOutGroup /// @{ /// \brief Stream Out Context Data /// /// \note Used by the HW to store information for a stream out buffer /// typedef struct _GX2StreamOutContext { u32 data[GX2_STREAMOUT_BUFFER_CONTEXT_SIZE/sizeof(u32)]; } GX2StreamOutContext; /// \brief Describes a stream out buffer /// /// \note Stream output follows the same rules as DX10 stream output where the max stride in a single buffer is 2048 bytes, /// defined to be the spacing between the beginning of each vertex. If streaming into multiple buffers, /// the stride must equal the element width in each buffer. Each buffer can only contain a single varying output /// corresponding to the stream out varings file. Writing stops as soon as any one of the /// buffers is full. /// typedef struct _GX2StreamOutBuffer { u32 size; ///< the size (in bytes) of the stream out buffer void* dataPtr; ///< pointer to the stream out buffer u32 vertexStride; ///< Stride (in bytes) between each vertex in the stream out buffer GX2RBuffer streamOutData; ///< use a GX2RBuffer in preference to size, dataPtr and vertexStride (dataPtr must be NULL in this case) GX2StreamOutContext* ctxPtr; ///< pointer to HW context data for the stream out buffer } GX2StreamOutBuffer; /// \brief Set the stream out buffer to be used as the given stream out target /// /// \note soTarget should be less than \ref GX2_MAX_STREAMOUT_BUFFERS /// \note soTarget corresponds to the zero-based stream out varings file index /// /// \param soTarget The stream out target to setup /// \param pStreamOutBuf Pointer to stream out buffer structure to use /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetStreamOutBuffer(u32 soTarget, const GX2StreamOutBuffer* pStreamOutBuf); /// \brief Save the stream out buffer context to memory /// /// \note soTarget should be less than \ref GX2_MAX_STREAMOUT_BUFFERS /// \note soTarget corresponds to the zero-based stream out varings file index /// /// \note This function should be called to save the current stream out buffer context for each /// target before a context switch or before \ref GX2SetStreamOutBuffer() is called to set a /// new stream out buffer to the soTarget. /// /// \param soTarget The stream out target the buffer is currently set to /// \param pStreamOutBuf Pointer to stream out buffer structure /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SaveStreamOutContext(u32 soTarget, const GX2StreamOutBuffer* pStreamOutBuf); /// \brief Initialize the stream out buffer context for the stream out target /// /// \note soTarget should be less than \ref GX2_MAX_STREAMOUT_BUFFERS /// \note soTarget corresponds to the zero-based stream out varings file index /// /// \note If the reset flag is set to GX2_TRUE writes will start at the beginning of the stream /// out buffer. Otherwise, writes will start at the current location in the stream out /// buffer (append to the buffer). /// /// \note This function should be called (for each stream out target used) after a context switch /// (before a draw operation with stream out enabled) or after calling /// \ref GX2SetStreamOutBuffer() /// /// \param soTarget The stream out target to initialize /// \param pStreamOutBuf Pointer to stream out buffer structure /// \param reset Stream out context reset flag /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetStreamOutContext(u32 soTarget, const GX2StreamOutBuffer* pStreamOutBuf, GX2Boolean reset); /// \brief Set an explicit offset for a stream out target /// /// Instead of starting to write a stream-out buffer at the beginning or after the place /// that was last written, this function allows you to write starting at an explicit offset. /// This function is used in place of GX2SetStreamOutContext. /// /// \note soTarget should be less than \ref GX2_MAX_STREAMOUT_BUFFERS /// \note soTarget corresponds to the zero-based stream out varings file index /// /// \param soTarget The stream out target to initialize /// \param offset The offset value desired /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// GX2_INLINE void GX2SetStreamOutExplicitOffset(u32 soTarget, u32 offset) { GX2SetStreamOutContext(soTarget, (GX2StreamOutBuffer *) offset, (GX2Boolean) GX2_STREAMOUT_OFFSET_EXPLICIT); } /// \brief Enable/disable stream out writes from the vertex shader or geometry shader /// /// \note If stream out is disabled and the shader contains instructions to write to a stream /// out buffer the writes will be killed just as they would be if the stream out buffer is /// full (i.e. the amount of data written exceeds the size of the stream out buffer). /// /// \param enable Enable flag for stream out /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetStreamOutEnable(GX2Boolean enable); /// @} /// @addtogroup GX2ShaderAllGroup /// @{ /// \brief Sets up the global shader export buffer. /// /// This maps a user buffer to the global SSBO that is shared by all shader /// types. /// /// \note Setting the buffer size to 0 disables the global SSBO. /// \note For more information see \ref GX2GLSLSSBOSect. /// /// \warning Changing shader export buffers results in a GPU flush since it /// is not context specific. Changing the shader export buffer frequently /// may cause a reduction in performance. /// /// \param buffer Pointer to the buffer where export data should be written. Alignment must be in multiples of \ref GX2_EXPORT_BUFFER_ALIGNMENT. /// \param size Size of the buffer where export data is to be written in bytes. Must be a multiple of \ref GX2_EXPORT_BUFFER_ALIGNMENT bytes. /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetShaderExportBuffer(void *buffer, u32 size); /// @} #ifdef __cplusplus } #endif // __cplusplus #endif // _CAFE_GX2_SHADERS_H_