]> Chaos Git - corbenik/ctrulib.git/commitdiff
* add code for alphablending, color logic op, alpha test and multitexturing.
authorStapleButter <thetotalworm@gmail.com>
Thu, 23 Oct 2014 15:56:56 +0000 (17:56 +0200)
committerStapleButter <thetotalworm@gmail.com>
Thu, 23 Oct 2014 15:56:56 +0000 (17:56 +0200)
* add GPU_FinishDrawing() to be called after a batch of GPU_DrawArray() calls if you're done drawing or if you intend to change the GPU configuration before drawing more. Also fix GPU_Finalize(). With those changes, the GPU no longer freezes if you call GPU_DrawArray() an even number of times.
* fix GPU_SetViewport() to allow color buffer reading, so blending and logicop work as expected.

libctru/include/3ds/gpu/gpu.h
libctru/source/gpu/gpu.c

index 0b2ee2ae99cf3b6c0044caf14c8b9ab512990b88..aaceb0a6100427ec890de3dc0e4e8660a03fc8e5 100644 (file)
@@ -9,6 +9,13 @@ void GPUCMD_Add(u32 cmd, u32* param, u32 paramlength);
 void GPUCMD_AddSingleParam(u32 cmd, u32 param);
 void GPUCMD_Finalize();
 
+typedef enum
+{
+       GPU_TEXUNIT0 = 0x1,
+       GPU_TEXUNIT1 = 0x2,
+       GPU_TEXUNIT2 = 0x4
+} GPU_TEXUNIT;
+
 typedef enum{
        GPU_RGBA8=0x0,
        GPU_RGB8=0x1,
@@ -37,6 +44,54 @@ typedef enum
        GPU_GEQUAL = 7
 }GPU_TESTFUNC;
 
+typedef enum
+{
+       GPU_BLEND_ADD = 0,
+       GPU_BLEND_SUBTRACT = 1,
+       GPU_BLEND_REVERSE_SUBTRACT = 2,
+       GPU_BLEND_MIN = 3,
+       GPU_BLEND_MAX = 4
+} GPU_BLENDEQUATION;
+
+typedef enum
+{
+       GPU_ZERO = 0,
+       GPU_ONE = 1,
+       GPU_SRC_COLOR = 2,
+       GPU_ONE_MINUS_SRC_COLOR = 3,
+       GPU_DST_COLOR = 4,
+       GPU_ONE_MINUS_DST_COLOR = 5,
+       GPU_SRC_ALPHA = 6,
+       GPU_ONE_MINUS_SRC_ALPHA = 7,
+       GPU_DST_ALPHA = 8,
+       GPU_ONE_MINUS_DST_ALPHA = 9,
+       GPU_CONSTANT_COLOR = 10,
+       GPU_ONE_MINUS_CONSTANT_COLOR = 11,
+       GPU_CONSTANT_ALPHA = 12,
+       GPU_ONE_MINUS_CONSTANT_ALPHA = 13,
+       GPU_SRC_ALPHA_SATURATE = 14
+} GPU_BLENDFACTOR;
+
+typedef enum
+{
+       GPU_LOGICOP_CLEAR = 0,
+       GPU_LOGICOP_AND = 1,
+       GPU_LOGICOP_AND_REVERSE = 2,
+       GPU_LOGICOP_COPY = 3,
+       GPU_LOGICOP_SET = 4,
+       GPU_LOGICOP_COPY_INVERTED = 5,
+       GPU_LOGICOP_NOOP = 6,
+       GPU_LOGICOP_INVERT = 7,
+       GPU_LOGICOP_NAND = 8,
+       GPU_LOGICOP_OR = 9,
+       GPU_LOGICOP_NOR = 10,
+       GPU_LOGICOP_XOR = 11,
+       GPU_LOGICOP_EQUIV = 12,
+       GPU_LOGICOP_AND_INVERTED = 13,
+       GPU_LOGICOP_OR_REVERSE = 14,
+       GPU_LOGICOP_OR_INVERTED = 15
+} GPU_LOGICOP;
+
 typedef enum{
        GPU_BYTE = 0,
        GPU_UNSIGNED_BYTE = 1,
@@ -84,14 +139,28 @@ typedef enum{
 }GPU_Primitive_t;
 
 void GPU_SetUniform(u32 startreg, u32* data, u32 numreg);
+
 void GPU_SetViewport(u32* depthBuffer, u32* colorBuffer, u32 x, u32 y, u32 w, u32 h);
+
 void GPU_DepthRange(float nearVal, float farVal);
+void GPU_SetAlphaTest(bool enable, GPU_TESTFUNC function, u8 ref);
 void GPU_SetDepthTest(bool enable, GPU_TESTFUNC function, u8 ref);
 void GPU_SetStencilTest(bool enable, GPU_TESTFUNC function, u8 ref);
 void GPU_SetFaceCulling(GPU_CULLMODE mode);
+
+// these two can't be used together
+void GPU_SetAlphaBlending(GPU_BLENDEQUATION colorEquation, GPU_BLENDEQUATION alphaEquation, 
+       GPU_BLENDFACTOR colorSrc, GPU_BLENDFACTOR colorDst, 
+       GPU_BLENDFACTOR alphaSrc, GPU_BLENDFACTOR alphaDst);
+void GPU_SetColorLogicOp(GPU_LOGICOP op);
+
 void GPU_SetAttributeBuffers(u8 totalAttributes, u32* baseAddress, u64 attributeFormats, u16 attributeMask, u64 attributePermutation, u8 numBuffers, u32 bufferOffsets[], u64 bufferPermutations[], u8 bufferNumAttributes[]);
-void GPU_SetTexture(u32* data, u16 width, u16 height, u32 param, GPU_TEXCOLOR colorType);
+
+void GPU_SetTextureEnable(GPU_TEXUNIT units); // GPU_TEXUNITx values can be ORed together to enable multiple texture units
+void GPU_SetTexture(GPU_TEXUNIT unit, u32* data, u16 width, u16 height, u32 param, GPU_TEXCOLOR colorType);
 void GPU_SetTexEnv(u8 id, u16 rgbSources, u16 alphaSources, u16 rgbOperands, u16 alphaOperands, GPU_COMBINEFUNC rgbCombine, GPU_COMBINEFUNC alphaCombine, u32 constantColor);
 
 void GPU_DrawArray(GPU_Primitive_t primitive, u32 n);
 void GPU_DrawElements(GPU_Primitive_t primitive, u32* indexArray, u32 n);
+
+void GPU_FinishDrawing();
index d6685e3ad6c2bd233d01111afa9d93229f1fa067..835f1fff801c4b0b2d1c4ed1867339bdc33846f4 100644 (file)
@@ -65,6 +65,9 @@ void GPUCMD_AddSingleParam(u32 cmd, u32 param)
 
 void GPUCMD_Finalize()
 {
+       GPUCMD_AddSingleParam(0x0008025E, 0x00000000);
+       GPUCMD_AddSingleParam(0x000F0111, 0x00000001);
+       GPUCMD_AddSingleParam(0x000F0110, 0x00000001);
        GPUCMD_AddSingleParam(0x000F0010, 0x12345678);
 }
 
@@ -272,7 +275,7 @@ void GPU_SetViewport(u32* depthBuffer, u32* colorBuffer, u32 x, u32 y, u32 w, u3
        GPUCMD_Add(0x800F0065, param, 0x00000003);
 
        //enable depth buffer
-       param[0x0]=0x00000000;
+       param[0x0]=0x0000000F;
        param[0x1]=0x0000000F;
        param[0x2]=0x00000002;
        param[0x3]=0x00000002;
@@ -286,6 +289,11 @@ void GPU_DepthRange(float nearVal, float farVal)
        GPUCMD_AddSingleParam(0x000F004E, f32tof24(farVal));
 }
 
+void GPU_SetAlphaTest(bool enable, GPU_TESTFUNC function, u8 ref)
+{
+       GPUCMD_AddSingleParam(0x000F0104, (enable&1)|((function&7)<<4)|(ref<<8));
+}
+
 void GPU_SetStencilTest(bool enable, GPU_TESTFUNC function, u8 ref)
 {
        GPUCMD_AddSingleParam(0x000F0105, (enable&1)|((function&7)<<4)|(ref<<8));
@@ -296,12 +304,54 @@ void GPU_SetDepthTest(bool enable, GPU_TESTFUNC function, u8 ref)
        GPUCMD_AddSingleParam(0x000F0107, (enable&1)|((function&7)<<4)|(ref<<8));
 }
 
-void GPU_SetTexture(u32* data, u16 width, u16 height, u32 param, GPU_TEXCOLOR colorType)
+void GPU_SetAlphaBlending(GPU_BLENDEQUATION colorEquation, GPU_BLENDEQUATION alphaEquation, 
+       GPU_BLENDFACTOR colorSrc, GPU_BLENDFACTOR colorDst, 
+       GPU_BLENDFACTOR alphaSrc, GPU_BLENDFACTOR alphaDst)
+{
+       // TODO: fixed color
+       // it is controlled by command 0103 but I haven't found were to place said command without freezing the GPU
+       
+       GPUCMD_AddSingleParam(0x000F0101, colorEquation | (alphaEquation<<8) | (colorSrc<<16) | (colorDst<<20) | (alphaSrc<<24) | (alphaDst<<28));
+       GPUCMD_AddSingleParam(0x00020100, 0x00000100);
+}
+
+void GPU_SetColorLogicOp(GPU_LOGICOP op)
+{
+       GPUCMD_AddSingleParam(0x000F0102, op);
+       GPUCMD_AddSingleParam(0x00020100, 0x00000000);
+}
+
+void GPU_SetTextureEnable(GPU_TEXUNIT units)
+{
+       GPUCMD_AddSingleParam(0x0002006F, units<<8);                    // enables texcoord outputs
+       GPUCMD_AddSingleParam(0x000F0080, 0x00011000|units);    // enables texture units
+}
+
+void GPU_SetTexture(GPU_TEXUNIT unit, u32* data, u16 width, u16 height, u32 param, GPU_TEXCOLOR colorType)
 {
-       GPUCMD_AddSingleParam(0x000F008E, colorType);
-       GPUCMD_AddSingleParam(0x000F0085, ((u32)data)>>3);
-       GPUCMD_AddSingleParam(0x000F0082, (width)|(height<<16));
-       GPUCMD_AddSingleParam(0x000F0083, param);
+       switch (unit)
+       {
+       case GPU_TEXUNIT0:
+               GPUCMD_AddSingleParam(0x000F008E, colorType);
+               GPUCMD_AddSingleParam(0x000F0085, ((u32)data)>>3);
+               GPUCMD_AddSingleParam(0x000F0082, (width)|(height<<16));
+               GPUCMD_AddSingleParam(0x000F0083, param);
+               break;
+               
+       case GPU_TEXUNIT1:
+               GPUCMD_AddSingleParam(0x000F0096, colorType);
+               GPUCMD_AddSingleParam(0x000F0095, ((u32)data)>>3);
+               GPUCMD_AddSingleParam(0x000F0092, (width)|(height<<16));
+               GPUCMD_AddSingleParam(0x000F0093, param);
+               break;
+               
+       case GPU_TEXUNIT2:
+               GPUCMD_AddSingleParam(0x000F009E, colorType);
+               GPUCMD_AddSingleParam(0x000F009D, ((u32)data)>>3);
+               GPUCMD_AddSingleParam(0x000F009A, (width)|(height<<16));
+               GPUCMD_AddSingleParam(0x000F009B, param);
+               break;
+       }
 }
 
 const u8 GPU_FORMATSIZE[4]={1,1,2,4};
@@ -385,7 +435,6 @@ void GPU_DrawArray(GPU_Primitive_t primitive, u32 n)
        GPUCMD_AddSingleParam(0x000F0231, 0x00000001);
 
        GPUCMD_AddSingleParam(0x000F0111, 0x00000001);
-       GPUCMD_AddSingleParam(0x000F0110, 0x00000001);
 }
 
 void GPU_DrawElements(GPU_Primitive_t primitive, u32* indexArray, u32 n)
@@ -405,4 +454,13 @@ void GPU_DrawElements(GPU_Primitive_t primitive, u32* indexArray, u32 n)
        GPUCMD_AddSingleParam(0x000F022F, 0x00000001);
        GPUCMD_AddSingleParam(0x00010245, 0x00000001);
        GPUCMD_AddSingleParam(0x000F0231, 0x00000001);
+       
+       // CHECKME: does this one also require command 0x0111 at the end?
+}
+
+void GPU_FinishDrawing()
+{
+       GPUCMD_AddSingleParam(0x000F0111, 0x00000001);
+       GPUCMD_AddSingleParam(0x000F0110, 0x00000001); 
+       GPUCMD_AddSingleParam(0x000F0063, 0x00000001);
 }