]> Chaos Git - corbenik/ctrulib.git/commitdiff
Add shaderProgramSetGshMode() for configuring geoshader mode
authorfincs <fincs.alt1@gmail.com>
Sat, 5 Dec 2015 12:28:41 +0000 (13:28 +0100)
committerfincs <fincs.alt1@gmail.com>
Sat, 5 Dec 2015 12:28:41 +0000 (13:28 +0100)
libctru/include/3ds/gpu/shaderProgram.h
libctru/source/gpu/shaderProgram.c

index 70d2457537bad94f4d78cbf71d657ddf6005a330..90f16928d4c02ae255bc0237890eabdecc9886f9 100644 (file)
@@ -33,8 +33,18 @@ typedef struct
        shaderInstance_s* geometryShader; ///< Geometry shader.\r
        u32 geoShaderInputPermutation[2]; ///< Geometry shader input permutation.\r
        u8 geoShaderInputStride;          ///< Geometry shader input stride.\r
+       u8 geoShaderMode;                 ///< Geometry shader operation mode.\r
 }shaderProgram_s;\r
 \r
+/// Geometry shader operation modes.\r
+typedef enum\r
+{\r
+       GSH_NORMAL                    = 0, ///< Normal operation.\r
+       GSH_PARTICLE                  = 1, ///< Particle system.\r
+       GSH_SUBDIVISION_LOOP          = 2, ///< Loop subdivision surface.\r
+       GSH_SUBDIVISION_CATMULL_CLARK = 3, ///< Catmull-Clark subdivision surface.\r
+} geoShaderMode;\r
+\r
 /**\r
  * @brief Initializes a shader instance.\r
  * @param si Shader instance to initialize.\r
@@ -105,6 +115,13 @@ Result shaderProgramSetGsh(shaderProgram_s* sp, DVLE_s* dvle, u8 stride);
  */\r
 Result shaderProgramSetGshInputPermutation(shaderProgram_s* sp, u64 permutation);\r
 \r
+/**\r
+ * @brief Configures the operation mode of the geometry shader of a shader program.\r
+ * @param sp Shader program to use.\r
+ * @param mode Operation mode to use.\r
+ */\r
+Result shaderProgramSetGshMode(shaderProgram_s* sp, geoShaderMode mode);\r
+\r
 /**\r
  * @brief Configures the shader units to use the specified shader program.\r
  * @param sp Shader program to use.\r
index a891dcbe8649132eda4add6d0af21fb4afc2cb45..8b2c34e88d546e79d42a350ceab793b82dc4d32a 100644 (file)
@@ -168,6 +168,7 @@ Result shaderProgramSetGsh(shaderProgram_s* sp, DVLE_s* dvle, u8 stride)
        sp->geoShaderInputPermutation[0] = 0x76543210;\r
        sp->geoShaderInputPermutation[1] = 0xFEDCBA98;\r
        sp->geoShaderInputStride = stride;\r
+       sp->geoShaderMode = GSH_NORMAL;\r
 \r
        return shaderInstanceInit(sp->geometryShader, dvle);\r
 }\r
@@ -181,6 +182,14 @@ Result shaderProgramSetGshInputPermutation(shaderProgram_s* sp, u64 permutation)
        return 0;\r
 }\r
 \r
+Result shaderProgramSetGshMode(shaderProgram_s* sp, geoShaderMode mode)\r
+{\r
+       if(!sp || !sp->geometryShader)return -1;\r
+\r
+       sp->geoShaderMode = mode & 3;\r
+       return 0;\r
+}\r
+\r
 Result shaderProgramConfigure(shaderProgram_s* sp, bool sendVshCode, bool sendGshCode)\r
 {\r
        if(!sp)return -1;\r
@@ -212,8 +221,15 @@ Result shaderProgramConfigure(shaderProgram_s* sp, bool sendVshCode, bool sendGs
        GPUCMD_AddWrite(GPUREG_VSH_OUTMAP_TOTAL1, vshDvle->outmapData[0]-1); // ?\r
        GPUCMD_AddWrite(GPUREG_VSH_OUTMAP_TOTAL2, vshDvle->outmapData[0]-1); // ?\r
 \r
-       GPUCMD_AddMaskedWrite(GPUREG_GEOSTAGE_CONFIG, 0x8, 0x00000000); // ?\r
-       GPUCMD_AddWrite(GPUREG_GSH_MISC0, 0x00000000); // ?\r
+       bool subdivision = sp->geoShaderMode >= GSH_SUBDIVISION_LOOP;\r
+       GPUCMD_AddMaskedWrite(GPUREG_GEOSTAGE_CONFIG, 0x8, subdivision ? 0x80000000 : 0); // Enable or disable subdivision\r
+       u32 gshMisc = 0;\r
+       if (subdivision)\r
+               gshMisc = 1;\r
+       else if (sp->geoShaderMode == GSH_PARTICLE)\r
+               gshMisc = 0x01004302;\r
+       GPUCMD_AddWrite(GPUREG_GSH_MISC0, gshMisc);\r
+       GPUCMD_AddWrite(GPUREG_GSH_MISC1, sp->geoShaderMode);\r
 \r
        if(!sp->geometryShader)\r
        {\r
@@ -237,7 +253,7 @@ Result shaderProgramConfigure(shaderProgram_s* sp, bool sendVshCode, bool sendGs
                GPU_SetShaderOutmap((u32*)gshDvle->outmapData);\r
 \r
                //GSH input attributes stuff\r
-               GPUCMD_AddWrite(GPUREG_GSH_INPUTBUFFER_CONFIG, 0x08000000|(sp->geoShaderInputStride-1));\r
+               GPUCMD_AddWrite(GPUREG_GSH_INPUTBUFFER_CONFIG, 0x08000000|(sp->geoShaderInputStride-1)|(subdivision?0x100:0));\r
                GPUCMD_AddIncrementalWrites(GPUREG_GSH_ATTRIBUTES_PERMUTATION_LOW, sp->geoShaderInputPermutation, 2);\r
 \r
                GPUCMD_AddWrite(GPUREG_SH_OUTATTR_MODE, gshDvle->outmapMode);\r