softgpu: Lots of clearmode fixes.

This commit is contained in:
Tony Wasserka 2013-07-23 22:56:49 +02:00 committed by neobrain
parent f35e085859
commit 62b384e052
3 changed files with 37 additions and 19 deletions

View file

@ -225,6 +225,7 @@ struct GPUgstate
bool isClearModeDepthWriteEnabled() const { return (clearmode&0x400) != 0; }
bool isClearModeColorMask() const { return (clearmode&0x100) != 0; }
bool isClearModeAlphaMask() const { return (clearmode&0x200) != 0; }
u32 getClearModeColorMask() const { return ((clearmode&0x100) ? 0xFFFFFF : 0) | ((clearmode&0x200) ? 0xFF000000 : 0); } // TODO: Different convention than getColorMask, confusing!
// Blend
int getBlendFuncA() const { return blend & 0xF; }

View file

@ -454,7 +454,7 @@ void DrawTriangle(const VertexData& v0, const VertexData& v1, const VertexData&
if (z < gstate.getDepthRangeMin() || z > gstate.getDepthRangeMax())
continue;
if (gstate.isColorTestEnabled()) {
if (gstate.isColorTestEnabled() && !gstate.isModeClear()) {
bool pass = false;
Vec3<int> ref = Vec3<int>::FromRGB(gstate.colorref&(gstate.colormask&0xFFFFFF));
Vec3<int> color = Vec3<int>::FromRGB(prim_color_rgb.ToRGB()&(gstate.colormask&0xFFFFFF));
@ -476,10 +476,10 @@ void DrawTriangle(const VertexData& v0, const VertexData& v1, const VertexData&
continue;
}
if (gstate.isAlphaTestEnabled()) {
if (gstate.isAlphaTestEnabled() && !gstate.isModeClear()) {
bool pass = false;
u8 ref = (gstate.alphatest>>8) & (gstate.alphatest>>16);
u8 alpha = prim_color_a & (gstate.alphatest>>16);
u8 ref = ((gstate.alphatest>>8) & (gstate.alphatest>>16)) & 0xFF;
u8 alpha = (prim_color_a & (gstate.alphatest>>16)) & 0xFF;
switch (gstate.alphatest & 0x7) {
case GE_COMP_NEVER:
@ -557,8 +557,10 @@ void DrawTriangle(const VertexData& v0, const VertexData& v1, const VertexData&
} else {
ApplyStencilOp(gstate.getStencilOpZPass(), p.x, p.y);
}
// TODO: Is this condition correct?
if (gstate.isDepthWriteEnabled() || ((gstate.clearmode&0x40) && gstate.isModeClear()))
if (gstate.isModeClear() && gstate.isClearModeDepthWriteEnabled())
SetPixelDepth(p.x, p.y, z);
else if (!gstate.isModeClear() && gstate.isDepthWriteEnabled())
SetPixelDepth(p.x, p.y, z);
}
if (gstate.isAlphaBlendEnabled() && !gstate.isModeClear()) {
@ -680,7 +682,7 @@ void DrawTriangle(const VertexData& v0, const VertexData& v1, const VertexData&
u32 old_color = GetPixelColor(p.x, p.y);
// TODO: Is alpha blending still performed if logic ops are enabled?
if (gstate.isLogicOpEnabled()) {
if (gstate.isLogicOpEnabled() && !gstate.isModeClear()) {
switch (gstate.getLogicOp()) {
case GE_LOGIC_CLEAR:
new_color = 0;
@ -748,7 +750,11 @@ void DrawTriangle(const VertexData& v0, const VertexData& v1, const VertexData&
}
}
new_color = (new_color & ~gstate.getColorMask()) | (old_color & gstate.getColorMask());
if (gstate.isModeClear()) {
new_color = (new_color & gstate.getClearModeColorMask()) | (old_color & ~gstate.getClearModeColorMask());
} else {
new_color = (new_color & ~gstate.getColorMask()) | (old_color & gstate.getColorMask());
}
SetPixelColor(p.x, p.y, new_color);
}

View file

@ -190,7 +190,10 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, u32 prim_type
switch (prim_type) {
case GE_PRIM_TRIANGLES:
{
if (!gstate.getCullMode())
if (!gstate.isCullEnabled() || gstate.isModeClear()) {
Clipper::ProcessTriangle(data[0], data[1], data[2]);
Clipper::ProcessTriangle(data[2], data[1], data[0]);
} else if (!gstate.getCullMode())
Clipper::ProcessTriangle(data[2], data[1], data[0]);
else
Clipper::ProcessTriangle(data[0], data[1], data[2]);
@ -225,12 +228,16 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, u32 prim_type
continue;
}
// We need to reverse the vertex order for each second primitive,
// but we additionally need to do that for every primitive if CCW cullmode is used.
if ((!gstate.getCullMode()) ^ (vtx % 2))
Clipper::ProcessTriangle(data[2], data[1], data[0]);
else
if (!gstate.isCullEnabled() || gstate.isModeClear()) {
Clipper::ProcessTriangle(data[0], data[1], data[2]);
Clipper::ProcessTriangle(data[2], data[1], data[0]);
} else if ((!gstate.getCullMode()) ^ (vtx % 2)) {
// We need to reverse the vertex order for each second primitive,
// but we additionally need to do that for every primitive if CCW cullmode is used.
Clipper::ProcessTriangle(data[2], data[1], data[0]);
} else {
Clipper::ProcessTriangle(data[0], data[1], data[2]);
}
}
} else if (prim_type == GE_PRIM_TRIANGLE_FAN) {
VertexData data[3];
@ -261,12 +268,16 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, u32 prim_type
continue;
}
// We need to reverse the vertex order for each second primitive,
// but we additionally need to do that for every primitive if CCW cullmode is used.
if ((!gstate.getCullMode()) ^ (vtx % 2))
Clipper::ProcessTriangle(data[2], data[1], data[0]);
else
if (!gstate.isCullEnabled() || gstate.isModeClear()) {
Clipper::ProcessTriangle(data[0], data[1], data[2]);
Clipper::ProcessTriangle(data[2], data[1], data[0]);
} else if ((!gstate.getCullMode()) ^ (vtx % 2)) {
// We need to reverse the vertex order for each second primitive,
// but we additionally need to do that for every primitive if CCW cullmode is used.
Clipper::ProcessTriangle(data[2], data[1], data[0]);
} else {
Clipper::ProcessTriangle(data[0], data[1], data[2]);
}
}
}
}