mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Detect sprite drawing (1:1 texture mapping), run a simpler function without the triangle state tracking.
This will allow further simplification and specialization.
This commit is contained in:
parent
510229b68b
commit
c7f6724f7e
5 changed files with 104 additions and 0 deletions
|
@ -197,6 +197,7 @@
|
|||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<ForcedIncludeFiles>Common/DbgNew.h</ForcedIncludeFiles>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
|
|
@ -184,6 +184,39 @@ void ProcessRect(const VertexData& v0, const VertexData& v1)
|
|||
ProcessTriangle(*topleft, *bottomleft, *bottomright, buf[3]);
|
||||
} else {
|
||||
// through mode handling
|
||||
|
||||
// Check for simple case: No depth, alpha != 0 testing only, no blend, texture mapping 1:1 etc.
|
||||
// Also check for scissor rectangle etc.
|
||||
// That is, state commonly used in PSX games and ports like Darkstalker.
|
||||
// In that case we can call DrawPSXSprite.
|
||||
int xdiff = v1.screenpos.x - v0.screenpos.x;
|
||||
int ydiff = v1.screenpos.y - v0.screenpos.y;
|
||||
int udiff = (v1.texturecoords.x - v0.texturecoords.x) * 16.0f;
|
||||
int vdiff = (v1.texturecoords.y - v0.texturecoords.y) * 16.0f;
|
||||
bool coord_check =
|
||||
(xdiff == udiff /* || xdiff == -udiff*/) &&
|
||||
(ydiff == vdiff /* || ydiff == -vdiff*/);
|
||||
// TODO: The U/V mirror support is off by one somehow. Predecrement?
|
||||
|
||||
/*
|
||||
bool state_check =
|
||||
!gstate.isModeClear() &&
|
||||
!gstate.isFogEnabled() &&
|
||||
gstate.isTextureMapEnabled() &&
|
||||
!gstate.isDepthTestEnabled() &&
|
||||
!gstate.isStencilTestEnabled();
|
||||
bool alpha_check =
|
||||
gstate.getAlphaTestFunction() == GEComparison::GE_COMP_GREATER &&
|
||||
gstate.getAlphaTestMask() == 0xFF &&
|
||||
gstate.getAlphaTestRef() == 0;
|
||||
*/
|
||||
bool state_check = !gstate.isModeClear();
|
||||
bool alpha_check = true;
|
||||
if ((coord_check || !gstate.isTextureMapEnabled()) && state_check && alpha_check) {
|
||||
Rasterizer::DrawPSXSprite(v0, v1);
|
||||
return;
|
||||
}
|
||||
|
||||
VertexData buf[4];
|
||||
buf[0].screenpos = ScreenCoords(v0.screenpos.x, v0.screenpos.y, v1.screenpos.z);
|
||||
buf[0].texturecoords = v0.texturecoords;
|
||||
|
|
|
@ -1287,6 +1287,54 @@ void DrawTriangleSlice(
|
|||
}
|
||||
}
|
||||
|
||||
void DrawPSXSprite(const VertexData& v0, const VertexData& v1) {
|
||||
u8 *texptr = nullptr;
|
||||
|
||||
GETextureFormat texfmt = gstate.getTextureFormat();
|
||||
u32 texaddr = gstate.getTextureAddress(0);
|
||||
int texbufw = GetTextureBufw(0, texaddr, texfmt);
|
||||
if (Memory::IsValidAddress(texaddr))
|
||||
texptr = Memory::GetPointerUnchecked(texaddr);
|
||||
|
||||
ScreenCoords pprime(v0.screenpos.x, v0.screenpos.y, 0);
|
||||
Sampler::Funcs sampler = Sampler::GetFuncs();
|
||||
|
||||
DrawingCoords pos0 = TransformUnit::ScreenToDrawing(v0.screenpos);
|
||||
DrawingCoords pos1 = TransformUnit::ScreenToDrawing(v1.screenpos);
|
||||
|
||||
int z = pos0.z;
|
||||
float fog = 1.0f;
|
||||
|
||||
if (gstate.isTextureMapEnabled()) {
|
||||
// 1:1 (but with mirror support) texture mapping!
|
||||
int s = v0.texturecoords.x;
|
||||
int t = v0.texturecoords.y;
|
||||
int ds = v1.texturecoords.x > v0.texturecoords.x ? 1 : -1;
|
||||
int dt = v1.texturecoords.y > v0.texturecoords.y ? 1 : -1;
|
||||
for (int y = pos0.y; y < pos1.y; y++) {
|
||||
s = v0.texturecoords.x;
|
||||
for (int x = pos0.x; x < pos1.x; x++) {
|
||||
Vec4<int> prim_color = v0.color0;
|
||||
Vec4<int> tex_color = Vec4<int>::FromRGBA(sampler.nearest(s, t, texptr, texbufw, 0));
|
||||
prim_color = GetTextureFunctionOutput(prim_color, tex_color);
|
||||
DrawingCoords pos(x, y, z);
|
||||
DrawSinglePixel<false>(pos, (u16)z, fog, prim_color);
|
||||
s += ds;
|
||||
}
|
||||
t += dt;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int y = pos0.y; y < pos1.y; y++) {
|
||||
for (int x = pos0.x; x < pos1.x; x++) {
|
||||
Vec4<int> prim_color = v0.color0;
|
||||
DrawingCoords pos(x, y, z);
|
||||
DrawSinglePixel<false>(pos, (u16)z, fog, prim_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draws triangle, vertices specified in counter-clockwise direction
|
||||
void DrawTriangle(const VertexData& v0, const VertexData& v1, const VertexData& v2)
|
||||
{
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace Rasterizer {
|
|||
void DrawTriangle(const VertexData& v0, const VertexData& v1, const VertexData& v2);
|
||||
void DrawPoint(const VertexData &v0);
|
||||
void DrawLine(const VertexData &v0, const VertexData &v1);
|
||||
void DrawPSXSprite(const VertexData &v0, const VertexData &v1);
|
||||
void ClearRectangle(const VertexData &v0, const VertexData &v1);
|
||||
|
||||
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer);
|
||||
|
|
|
@ -470,6 +470,27 @@ void TransformUnit::SubmitPrimitive(void* vertices, void* indices, GEPrimitiveTy
|
|||
data[2].color0 == data[3].color0) {
|
||||
// It's a rectangle!
|
||||
Clipper::ProcessRect(data[0], data[3]);
|
||||
break;
|
||||
}
|
||||
// There's the other vertex order too...
|
||||
if (data[0].screenpos.x == data[2].screenpos.x &&
|
||||
data[0].screenpos.y == data[1].screenpos.y &&
|
||||
data[1].screenpos.x == data[3].screenpos.x &&
|
||||
data[2].screenpos.y == data[3].screenpos.y &&
|
||||
data[2].screenpos.y > data[0].screenpos.y && // Avoid rotation handling
|
||||
data[1].screenpos.x > data[0].screenpos.x &&
|
||||
data[0].texturecoords.x == data[2].texturecoords.x &&
|
||||
data[0].texturecoords.y == data[1].texturecoords.y &&
|
||||
data[1].texturecoords.x == data[3].texturecoords.x &&
|
||||
data[2].texturecoords.y == data[3].texturecoords.y &&
|
||||
data[2].texturecoords.y > data[0].texturecoords.y &&
|
||||
data[1].texturecoords.x > data[0].texturecoords.x &&
|
||||
data[0].color0 == data[1].color0 &&
|
||||
data[1].color0 == data[2].color0 &&
|
||||
data[2].color0 == data[3].color0) {
|
||||
// It's a rectangle!
|
||||
Clipper::ProcessRect(data[0], data[3]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue