Add shaderProgramSetGshMode() for configuring geoshader mode

This commit is contained in:
fincs 2015-12-05 13:28:41 +01:00
parent c14634f323
commit c048221f86
2 changed files with 36 additions and 3 deletions

View File

@ -33,8 +33,18 @@ typedef struct
shaderInstance_s* geometryShader; ///< Geometry shader.
u32 geoShaderInputPermutation[2]; ///< Geometry shader input permutation.
u8 geoShaderInputStride; ///< Geometry shader input stride.
u8 geoShaderMode; ///< Geometry shader operation mode.
}shaderProgram_s;
/// Geometry shader operation modes.
typedef enum
{
GSH_NORMAL = 0, ///< Normal operation.
GSH_PARTICLE = 1, ///< Particle system.
GSH_SUBDIVISION_LOOP = 2, ///< Loop subdivision surface.
GSH_SUBDIVISION_CATMULL_CLARK = 3, ///< Catmull-Clark subdivision surface.
} geoShaderMode;
/**
* @brief Initializes a shader instance.
* @param si Shader instance to initialize.
@ -105,6 +115,13 @@ Result shaderProgramSetGsh(shaderProgram_s* sp, DVLE_s* dvle, u8 stride);
*/
Result shaderProgramSetGshInputPermutation(shaderProgram_s* sp, u64 permutation);
/**
* @brief Configures the operation mode of the geometry shader of a shader program.
* @param sp Shader program to use.
* @param mode Operation mode to use.
*/
Result shaderProgramSetGshMode(shaderProgram_s* sp, geoShaderMode mode);
/**
* @brief Configures the shader units to use the specified shader program.
* @param sp Shader program to use.

View File

@ -168,6 +168,7 @@ Result shaderProgramSetGsh(shaderProgram_s* sp, DVLE_s* dvle, u8 stride)
sp->geoShaderInputPermutation[0] = 0x76543210;
sp->geoShaderInputPermutation[1] = 0xFEDCBA98;
sp->geoShaderInputStride = stride;
sp->geoShaderMode = GSH_NORMAL;
return shaderInstanceInit(sp->geometryShader, dvle);
}
@ -181,6 +182,14 @@ Result shaderProgramSetGshInputPermutation(shaderProgram_s* sp, u64 permutation)
return 0;
}
Result shaderProgramSetGshMode(shaderProgram_s* sp, geoShaderMode mode)
{
if(!sp || !sp->geometryShader)return -1;
sp->geoShaderMode = mode & 3;
return 0;
}
Result shaderProgramConfigure(shaderProgram_s* sp, bool sendVshCode, bool sendGshCode)
{
if(!sp)return -1;
@ -212,8 +221,15 @@ Result shaderProgramConfigure(shaderProgram_s* sp, bool sendVshCode, bool sendGs
GPUCMD_AddWrite(GPUREG_VSH_OUTMAP_TOTAL1, vshDvle->outmapData[0]-1); // ?
GPUCMD_AddWrite(GPUREG_VSH_OUTMAP_TOTAL2, vshDvle->outmapData[0]-1); // ?
GPUCMD_AddMaskedWrite(GPUREG_GEOSTAGE_CONFIG, 0x8, 0x00000000); // ?
GPUCMD_AddWrite(GPUREG_GSH_MISC0, 0x00000000); // ?
bool subdivision = sp->geoShaderMode >= GSH_SUBDIVISION_LOOP;
GPUCMD_AddMaskedWrite(GPUREG_GEOSTAGE_CONFIG, 0x8, subdivision ? 0x80000000 : 0); // Enable or disable subdivision
u32 gshMisc = 0;
if (subdivision)
gshMisc = 1;
else if (sp->geoShaderMode == GSH_PARTICLE)
gshMisc = 0x01004302;
GPUCMD_AddWrite(GPUREG_GSH_MISC0, gshMisc);
GPUCMD_AddWrite(GPUREG_GSH_MISC1, sp->geoShaderMode);
if(!sp->geometryShader)
{
@ -237,7 +253,7 @@ Result shaderProgramConfigure(shaderProgram_s* sp, bool sendVshCode, bool sendGs
GPU_SetShaderOutmap((u32*)gshDvle->outmapData);
//GSH input attributes stuff
GPUCMD_AddWrite(GPUREG_GSH_INPUTBUFFER_CONFIG, 0x08000000|(sp->geoShaderInputStride-1));
GPUCMD_AddWrite(GPUREG_GSH_INPUTBUFFER_CONFIG, 0x08000000|(sp->geoShaderInputStride-1)|(subdivision?0x100:0));
GPUCMD_AddIncrementalWrites(GPUREG_GSH_ATTRIBUTES_PERMUTATION_LOW, sp->geoShaderInputPermutation, 2);
GPUCMD_AddWrite(GPUREG_SH_OUTATTR_MODE, gshDvle->outmapMode);