More specialization work.
This commit is contained in:
parent
4f7c23fe79
commit
290e9971a7
3 changed files with 77 additions and 27 deletions
|
@ -208,7 +208,7 @@ void ProcessRect(const VertexData& v0, const VertexData& v1)
|
||||||
bool state_check = !gstate.isModeClear();
|
bool state_check = !gstate.isModeClear();
|
||||||
bool alpha_check = true;
|
bool alpha_check = true;
|
||||||
if ((coord_check || !gstate.isTextureMapEnabled()) && state_check && alpha_check) {
|
if ((coord_check || !gstate.isTextureMapEnabled()) && state_check && alpha_check) {
|
||||||
Rasterizer::DrawPSXSprite(v0, v1);
|
Rasterizer::DrawSprite(v0, v1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1287,19 +1287,51 @@ void DrawTriangleSlice(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slow but can handle all input.
|
|
||||||
void SafeScanline(int s, int ds, int t, int x1, int x2, int y, int z, const u8 *texptr, int texbufw, Sampler::Funcs &sampler, Vec4<int> v0_color) {
|
// Through mode, with the specific Darkstalker settings.
|
||||||
for (int x = x1; x < x2; x++) {
|
inline void DrawSinglePixelFast(const DrawingCoords &p, const Vec4<int> &color_in) {
|
||||||
Vec4<int> prim_color = v0_color;
|
Vec4<int> prim_color = color_in.Clamp(0, 255);
|
||||||
Vec4<int> tex_color = Vec4<int>::FromRGBA(sampler.nearest(s, t, texptr, texbufw, 0));
|
if (gstate.isAlphaTestEnabled())
|
||||||
prim_color = GetTextureFunctionOutput(prim_color, tex_color);
|
if (!AlphaTestPassed(prim_color.a()))
|
||||||
DrawingCoords pos(x, y, z);
|
return;
|
||||||
DrawSinglePixel<false>(pos, (u16)z, 1.0f, prim_color);
|
|
||||||
s += ds;
|
const u32 old_color = GetPixelColor(p.x, p.y);
|
||||||
}
|
u32 new_color;
|
||||||
|
|
||||||
|
u8 stencil = GetPixelStencil(p.x, p.y);
|
||||||
|
|
||||||
|
// Dithering happens before the logic op and regardless of framebuffer format or clear mode.
|
||||||
|
// We do it while alpha blending because it happens before clamping.
|
||||||
|
if (gstate.isAlphaBlendEnabled()) {
|
||||||
|
const Vec4<int> dst = Vec4<int>::FromRGBA(old_color);
|
||||||
|
Vec3<int> blended = AlphaBlendingResult(prim_color, dst);
|
||||||
|
if (gstate.isDitherEnabled()) {
|
||||||
|
blended += Vec3<int>::AssignToAll(gstate.getDitherValue(p.x, p.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawPSXSprite(const VertexData& v0, const VertexData& v1) {
|
// ToRGB() always automatically clamps.
|
||||||
|
new_color = blended.ToRGB();
|
||||||
|
new_color |= stencil << 24;
|
||||||
|
} else {
|
||||||
|
if (gstate.isDitherEnabled()) {
|
||||||
|
// We'll discard alpha anyway.
|
||||||
|
prim_color += Vec4<int>::AssignToAll(gstate.getDitherValue(p.x, p.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_M_SSE)
|
||||||
|
new_color = Vec3<int>(prim_color.ivec).ToRGB();
|
||||||
|
new_color |= stencil << 24;
|
||||||
|
#else
|
||||||
|
new_color = Vec4<int>(prim_color.r(), prim_color.g(), prim_color.b(), stencil).ToRGBA();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
new_color = (new_color & ~gstate.getColorMask()) | (old_color & gstate.getColorMask());
|
||||||
|
SetPixelColor(p.x, p.y, new_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DrawSprite(const VertexData& v0, const VertexData& v1) {
|
||||||
const u8 *texptr = nullptr;
|
const u8 *texptr = nullptr;
|
||||||
|
|
||||||
GETextureFormat texfmt = gstate.getTextureFormat();
|
GETextureFormat texfmt = gstate.getTextureFormat();
|
||||||
|
@ -1309,7 +1341,7 @@ void DrawPSXSprite(const VertexData& v0, const VertexData& v1) {
|
||||||
texptr = Memory::GetPointerUnchecked(texaddr);
|
texptr = Memory::GetPointerUnchecked(texaddr);
|
||||||
|
|
||||||
ScreenCoords pprime(v0.screenpos.x, v0.screenpos.y, 0);
|
ScreenCoords pprime(v0.screenpos.x, v0.screenpos.y, 0);
|
||||||
Sampler::Funcs sampler = Sampler::GetFuncs();
|
Sampler::NearestFunc nearestFunc = Sampler::GetNearestFunc(); // Looks at gstate.
|
||||||
|
|
||||||
DrawingCoords pos0 = TransformUnit::ScreenToDrawing(v0.screenpos);
|
DrawingCoords pos0 = TransformUnit::ScreenToDrawing(v0.screenpos);
|
||||||
DrawingCoords pos1 = TransformUnit::ScreenToDrawing(v1.screenpos);
|
DrawingCoords pos1 = TransformUnit::ScreenToDrawing(v1.screenpos);
|
||||||
|
@ -1347,22 +1379,40 @@ void DrawPSXSprite(const VertexData& v0, const VertexData& v1) {
|
||||||
pos0.y = scissorTL.y;
|
pos0.y = scissorTL.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!gstate.isStencilTestEnabled() &&
|
||||||
|
!gstate.isDepthTestEnabled() &&
|
||||||
|
!gstate.isLogicOpEnabled() &&
|
||||||
|
!gstate.isColorTestEnabled()) {
|
||||||
int t = t_start;
|
int t = t_start;
|
||||||
for (int y = pos0.y; y < pos1.y; y++) {
|
for (int y = pos0.y; y < pos1.y; y++) {
|
||||||
int s = s_start;
|
int s = s_start;
|
||||||
SafeScanline(s, ds, t, pos0.x, pos1.x, y, z, texptr, texbufw, sampler, v0.color0);
|
// Not really that fast but faster than triangle.
|
||||||
/*
|
|
||||||
for (int x = pos0.x; x < pos1.x; x++) {
|
for (int x = pos0.x; x < pos1.x; x++) {
|
||||||
Vec4<int> prim_color = v0.color0;
|
Vec4<int> prim_color = v0.color0;
|
||||||
Vec4<int> tex_color = Vec4<int>::FromRGBA(sampler.nearest(s, t, texptr, texbufw, 0));
|
Vec4<int> tex_color = Vec4<int>::FromRGBA(nearestFunc(s, t, texptr, texbufw, 0));
|
||||||
prim_color = GetTextureFunctionOutput(prim_color, tex_color);
|
prim_color = GetTextureFunctionOutput(prim_color, tex_color);
|
||||||
DrawingCoords pos(x, y, z);
|
DrawingCoords pos(x, y, z);
|
||||||
DrawSinglePixel<false>(pos, (u16)z, fog, prim_color);
|
DrawSinglePixelFast(pos, prim_color);
|
||||||
s += ds;
|
s += ds;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
t += dt;
|
t += dt;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
int t = t_start;
|
||||||
|
for (int y = pos0.y; y < pos1.y; y++) {
|
||||||
|
int s = s_start;
|
||||||
|
// Not really that fast but faster than triangle.
|
||||||
|
for (int x = pos0.x; x < pos1.x; x++) {
|
||||||
|
Vec4<int> prim_color = v0.color0;
|
||||||
|
Vec4<int> tex_color = Vec4<int>::FromRGBA(nearestFunc(s, t, texptr, texbufw, 0));
|
||||||
|
prim_color = GetTextureFunctionOutput(prim_color, tex_color);
|
||||||
|
DrawingCoords pos(x, y, z);
|
||||||
|
DrawSinglePixel<false>(pos, (u16)z, 1.0f, prim_color);
|
||||||
|
s += ds;
|
||||||
|
}
|
||||||
|
t += dt;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (pos1.x > scissorBR.x) pos1.x = scissorBR.x;
|
if (pos1.x > scissorBR.x) pos1.x = scissorBR.x;
|
||||||
if (pos1.y > scissorBR.y) pos1.y = scissorBR.y;
|
if (pos1.y > scissorBR.y) pos1.y = scissorBR.y;
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace Rasterizer {
|
||||||
void DrawTriangle(const VertexData& v0, const VertexData& v1, const VertexData& v2);
|
void DrawTriangle(const VertexData& v0, const VertexData& v1, const VertexData& v2);
|
||||||
void DrawPoint(const VertexData &v0);
|
void DrawPoint(const VertexData &v0);
|
||||||
void DrawLine(const VertexData &v0, const VertexData &v1);
|
void DrawLine(const VertexData &v0, const VertexData &v1);
|
||||||
void DrawPSXSprite(const VertexData &v0, const VertexData &v1);
|
void DrawSprite(const VertexData &v0, const VertexData &v1);
|
||||||
void ClearRectangle(const VertexData &v0, const VertexData &v1);
|
void ClearRectangle(const VertexData &v0, const VertexData &v1);
|
||||||
|
|
||||||
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer);
|
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue