Merge pull request #15411 from unknownbrackets/softgpu-range

softgpu: Apply region x2/y2 as a scissor
This commit is contained in:
Henrik Rydgård 2022-02-20 21:42:00 +01:00 committed by GitHub
commit eb765a80f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 49 deletions

View file

@ -183,7 +183,7 @@ void BinManager::UpdateState() {
if (HasDirty(SoftDirty::BINNER_RANGE)) {
DrawingCoords scissorTL(gstate.getScissorX1(), gstate.getScissorY1());
DrawingCoords scissorBR(gstate.getScissorX2(), gstate.getScissorY2());
DrawingCoords scissorBR(std::min(gstate.getScissorX2(), gstate.getRegionX2()), std::min(gstate.getScissorY2(), gstate.getRegionY2()));
ScreenCoords screenScissorTL = TransformUnit::DrawingToScreen(scissorTL, 0);
ScreenCoords screenScissorBR = TransformUnit::DrawingToScreen(scissorBR, 0);

View file

@ -208,19 +208,6 @@ static inline void SetPixelDepth(int x, int y, int stride, u16 value) {
depthbuf.Set16(x, y, stride, value);
}
static inline u8 GetPixelStencil(GEBufferFormat fmt, int fbStride, int x, int y) {
if (fmt == GE_FORMAT_565) {
// Always treated as 0 for comparison purposes.
return 0;
} else if (fmt == GE_FORMAT_5551) {
return ((fb.Get16(x, y, fbStride) & 0x8000) != 0) ? 0xFF : 0;
} else if (fmt == GE_FORMAT_4444) {
return Convert4To8(fb.Get16(x, y, fbStride) >> 12);
} else {
return fb.Get32(x, y, fbStride) >> 24;
}
}
static inline bool IsRightSideOrFlatBottomLine(const Vec2<int>& vertex, const Vec2<int>& line1, const Vec2<int>& line2)
{
if (line1.y == line2.y) {
@ -1402,21 +1389,6 @@ void DrawLine(const VertexData &v0, const VertexData &v1, const BinCoords &range
}
}
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
int w = gstate.getRegionX2() + 1;
int h = gstate.getRegionY2() + 1;
buffer.Allocate(w, h, GPU_DBG_FORMAT_8BIT);
u8 *row = buffer.GetData();
for (int y = 0; y < w; ++y) {
for (int x = 0; x < h; ++x) {
row[x] = GetPixelStencil(gstate.FrameBufFormat(), gstate.FrameBufStride(), x, y);
}
row += w;
}
return true;
}
bool GetCurrentTexture(GPUDebugBuffer &buffer, int level)
{
if (!gstate.isTextureMapEnabled()) {

View file

@ -76,7 +76,6 @@ void DrawPoint(const VertexData &v0, const BinCoords &range, const RasterizerSta
void DrawLine(const VertexData &v0, const VertexData &v1, const BinCoords &range, const RasterizerState &state);
void ClearRectangle(const VertexData &v0, const VertexData &v1, const BinCoords &range, const RasterizerState &state);
bool GetCurrentStencilbuffer(GPUDebugBuffer &buffer);
bool GetCurrentTexture(GPUDebugBuffer &buffer, int level);
// Shared functions with RasterizerRectangle.cpp

View file

@ -235,9 +235,9 @@ const SoftwareCommandTableEntry softgpuCommandTable[] = {
{ GE_CMD_MAXZ, 0, SoftDirty::PIXEL_BASIC | SoftDirty::PIXEL_CACHED },
// Region doesn't seem to affect scissor or anything.
// TODO: Double check, the registers are always set so they ought to... do something?
{ GE_CMD_REGION1 },
{ GE_CMD_REGION2 },
// As long as REGION1 is zero, REGION2 is effectively another scissor.
{ GE_CMD_REGION1, 0, SoftDirty::BINNER_RANGE },
{ GE_CMD_REGION2, 0, SoftDirty::BINNER_RANGE },
// Scissor, only used by the binner.
{ GE_CMD_SCISSOR1, 0, SoftDirty::BINNER_RANGE },
@ -1167,26 +1167,38 @@ bool SoftGPU::FramebufferReallyDirty() {
return true;
}
static DrawingCoords GetTargetSize(int stride) {
int w = std::min(stride, std::max(gstate.getRegionX2(), gstate.getScissorX2()) + 1);
int h = std::max(gstate.getRegionY2(), gstate.getScissorY2()) + 1;
if (gstate.getRegionX2() == 1023 && gstate.getRegionY2() == 1023) {
// Some games max out region, but always scissor to an appropriate size.
// Both values always scissor, we just prefer region as it's usually a more stable size.
w = std::max(stride, gstate.getScissorX2() + 1);
h = std::max(272, gstate.getScissorY2() + 1);
}
return DrawingCoords((s16)w, (s16)h);
}
bool SoftGPU::GetCurrentFramebuffer(GPUDebugBuffer &buffer, GPUDebugFramebufferType type, int maxRes) {
int w = gstate.getRegionX2() + 1;
int h = gstate.getRegionY2() + 1;
int stride = gstate.FrameBufStride();
DrawingCoords size = GetTargetSize(stride);
GEBufferFormat fmt = gstate.FrameBufFormat();
if (type == GPU_DBG_FRAMEBUF_DISPLAY) {
w = 480;
h = 272;
size.x = 480;
size.y = 272;
stride = displayStride_;
fmt = displayFormat_;
}
buffer.Allocate(w, h, fmt);
buffer.Allocate(size.x, size.y, fmt);
const int depth = fmt == GE_FORMAT_8888 ? 4 : 2;
const u8 *src = fb.data;
u8 *dst = buffer.GetData();
const int byteWidth = w * depth;
for (int y = 0; y < h; ++y) {
const int byteWidth = size.x * depth;
for (int16_t y = 0; y < size.y; ++y) {
memcpy(dst, src, byteWidth);
dst += byteWidth;
src += stride * depth;
@ -1199,24 +1211,45 @@ bool SoftGPU::GetOutputFramebuffer(GPUDebugBuffer &buffer) {
}
bool SoftGPU::GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
const int w = gstate.getRegionX2() + 1;
const int h = gstate.getRegionY2() + 1;
buffer.Allocate(w, h, GPU_DBG_FORMAT_16BIT);
DrawingCoords size = GetTargetSize(gstate.DepthBufStride());
buffer.Allocate(size.x, size.y, GPU_DBG_FORMAT_16BIT);
const int depth = 2;
const u8 *src = depthbuf.data;
u8 *dst = buffer.GetData();
for (int y = 0; y < h; ++y) {
memcpy(dst, src, w * depth);
dst += w * depth;
for (int16_t y = 0; y < size.y; ++y) {
memcpy(dst, src, size.x * depth);
dst += size.x * depth;
src += gstate.DepthBufStride() * depth;
}
return true;
}
bool SoftGPU::GetCurrentStencilbuffer(GPUDebugBuffer &buffer)
{
return Rasterizer::GetCurrentStencilbuffer(buffer);
static inline u8 GetPixelStencil(GEBufferFormat fmt, int fbStride, int x, int y) {
if (fmt == GE_FORMAT_565) {
// Always treated as 0 for comparison purposes.
return 0;
} else if (fmt == GE_FORMAT_5551) {
return ((fb.Get16(x, y, fbStride) & 0x8000) != 0) ? 0xFF : 0;
} else if (fmt == GE_FORMAT_4444) {
return Convert4To8(fb.Get16(x, y, fbStride) >> 12);
} else {
return fb.Get32(x, y, fbStride) >> 24;
}
}
bool SoftGPU::GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
DrawingCoords size = GetTargetSize(gstate.FrameBufStride());
buffer.Allocate(size.x, size.y, GPU_DBG_FORMAT_8BIT);
u8 *row = buffer.GetData();
for (int16_t y = 0; y < size.x; ++y) {
for (int16_t x = 0; x < size.y; ++x) {
row[x] = GetPixelStencil(gstate.FrameBufFormat(), gstate.FrameBufStride(), x, y);
}
row += size.x;
}
return true;
}
bool SoftGPU::GetCurrentTexture(GPUDebugBuffer &buffer, int level)