* add code for alphablending, color logic op, alpha test and multitexturing.

* 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.
This commit is contained in:
StapleButter 2014-10-23 17:56:56 +02:00
parent 1f413a7d44
commit af31a7c861
2 changed files with 135 additions and 8 deletions

View 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();

View 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)
{
GPUCMD_AddSingleParam(0x000F008E, colorType);
GPUCMD_AddSingleParam(0x000F0085, ((u32)data)>>3);
GPUCMD_AddSingleParam(0x000F0082, (width)|(height<<16));
GPUCMD_AddSingleParam(0x000F0083, param);
// 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)
{
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);
}