softgpu: Avoid texture/CLUT flush unless overlap.

Only need to flush here if there's some overlap in the target.
This commit is contained in:
Unknown W. Brackets 2022-01-15 23:24:58 -08:00
parent 9466dc6397
commit cc155ec460
5 changed files with 34 additions and 12 deletions

View file

@ -174,7 +174,7 @@ void BinManager::UpdateState() {
}
}
void BinManager::UpdateClut(void *src) {
void BinManager::UpdateClut(const void *src) {
if (cluts_.Full())
Flush();
clutIndex_ = (int)cluts_.Push(BinClut());

View file

@ -153,7 +153,7 @@ public:
~BinManager();
void UpdateState();
void UpdateClut(void *src);
void UpdateClut(const void *src);
const Rasterizer::RasterizerState &State() {
return states_[stateIndex_];

View file

@ -548,6 +548,10 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff) {
case GE_CMD_SCISSOR1:
case GE_CMD_SCISSOR2:
for (int i = 0; i < 8; ++i) {
// TODO: Narrow down the risk range, for now assuming 512x512 max texture.
drawEngine_->transformUnit.FlushIfOverlap(gstate.getTextureAddress(i), 4 * 512 * 512);
}
break;
case GE_CMD_MINZ:
@ -576,8 +580,8 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff) {
case GE_CMD_TEXADDR5:
case GE_CMD_TEXADDR6:
case GE_CMD_TEXADDR7:
// TODO: Try not flushing here, unless overlap with framebuf/depthbuf?
drawEngine_->transformUnit.Flush();
// TODO: Narrow down the risk range, for now assuming 512x512 max texture.
drawEngine_->transformUnit.FlushIfOverlap(gstate.getTextureAddress(cmd - GE_CMD_TEXADDR0), 4 * 512 * 512);
break;
case GE_CMD_TEXBUFWIDTH0:
@ -588,8 +592,8 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff) {
case GE_CMD_TEXBUFWIDTH5:
case GE_CMD_TEXBUFWIDTH6:
case GE_CMD_TEXBUFWIDTH7:
// TODO: Try not flushing here, unless overlap with framebuf/depthbuf?
drawEngine_->transformUnit.Flush();
// TODO: Narrow down the risk range, for now assuming 512x512 max texture.
drawEngine_->transformUnit.FlushIfOverlap(gstate.getTextureAddress(cmd - GE_CMD_TEXBUFWIDTH0), 4 * 512 * 512);
break;
case GE_CMD_CLUTADDR:
@ -598,13 +602,12 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff) {
case GE_CMD_LOADCLUT:
{
// Might be copying drawing into the CLUT, so flush.
// TODO: It seems worth copying the CLUT to state...
drawEngine_->transformUnit.Flush();
u32 clutAddr = gstate.getClutAddress();
u32 clutTotalBytes = gstate.getClutLoadBytes();
// Might be copying drawing into the CLUT, so flush.
drawEngine_->transformUnit.FlushIfOverlap(clutAddr, clutTotalBytes);
if (Memory::IsValidAddress(clutAddr)) {
u32 validSize = Memory::ValidSize(clutAddr, clutTotalBytes);
Memory::MemcpyUnchecked(clut, clutAddr, validSize);

View file

@ -613,7 +613,25 @@ void TransformUnit::Flush() {
GPUDebug::NotifyDraw();
}
void TransformUnit::NotifyClutUpdate(void *src) {
void TransformUnit::FlushIfOverlap(uint32_t addr, uint32_t sz) {
if (!Memory::IsVRAMAddress(addr))
return;
addr &= 0x0FFFFFFF;
uint32_t targetHeight = gstate.getScissorY2() + 1;
uint32_t target = gstate.getFrameBufAddress() & 0x0FFFFFFF;
uint32_t targetStride = gstate.FrameBufStride() * (gstate.FrameBufFormat() == GE_FORMAT_8888 ? 4 : 2);
uint32_t ztarget = gstate.getDepthBufAddress() & 0x0FFFFFFF;
uint32_t ztargetStride = gstate.DepthBufStride() * 2;
// TODO: Skip if the texture is between width and stride?
if (addr < target + targetHeight * targetStride && addr + sz >= target)
Flush();
else if (addr < ztarget + targetHeight * ztargetStride && addr + sz >= ztarget)
Flush();
}
void TransformUnit::NotifyClutUpdate(const void *src) {
binner_->UpdateClut(src);
}

View file

@ -120,7 +120,8 @@ public:
bool GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex> &vertices, std::vector<u16> &indices);
void Flush();
void NotifyClutUpdate(void *src);
void FlushIfOverlap(uint32_t addr, uint32_t sz);
void NotifyClutUpdate(const void *src);
private:
VertexData ReadVertex(VertexReader &vreader, bool &outside_range_flag);