mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #15411 from unknownbrackets/softgpu-range
softgpu: Apply region x2/y2 as a scissor
This commit is contained in:
commit
eb765a80f8
4 changed files with 53 additions and 49 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue