mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
SoftGPU: Fix block transfer and self-render overlap tracking
- The block transfer overlap check passed the stride in pixels where bytes are expected, so it only covered part of the rectangle. - A selfrender/selfdepth flush in UpdateState dropped the current draw's pending writes and reads, so later transfers didn't wait for it. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
507bb0801b
commit
d6f8615d2a
2 files changed
+15
-4
No files matched your search
@@ -246,21 +246,32 @@ void BinManager::UpdateState() {
|
||||
if (newMaxTasks > MAX_POSSIBLE_TASKS)
|
||||
newMaxTasks = MAX_POSSIBLE_TASKS;
|
||||
// We don't want to overlap wrong, so flush any pending.
|
||||
bool flushed = false;
|
||||
if (maxTasks_ != newMaxTasks) {
|
||||
maxTasks_ = newMaxTasks;
|
||||
Flush("selfrender");
|
||||
flushed = true;
|
||||
}
|
||||
pendingOverlap_ = pendingOverlap_ || selfRender;
|
||||
|
||||
// Lastly, we have to check if we're newly writing depth we were texturing before.
|
||||
// This happens in Call of Duty (depth clear after depth texture), for example.
|
||||
if (!hadDepth && state.pixelID.depthWrite) {
|
||||
if (!flushed && !hadDepth && state.pixelID.depthWrite) {
|
||||
for (size_t i = 0; i < states_.Size(); ++i) {
|
||||
if (HasTextureWrite(states_.Peek(i))) {
|
||||
Flush("selfdepth");
|
||||
flushed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flushed) {
|
||||
// The flush forgot what this draw writes and reads, so record it again.
|
||||
MarkPendingWrites(state);
|
||||
MarkPendingReads(state);
|
||||
ClearDirty(SoftDirty::BINNER_RANGE);
|
||||
}
|
||||
pendingOverlap_ = pendingOverlap_ || selfRender;
|
||||
ClearDirty(SoftDirty::BINNER_OVERLAP);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -826,8 +826,8 @@ void SoftGPU::Execute_BlockTransferStart(u32 op, u32 diff) {
|
||||
|
||||
// Need to flush both source and target, so we overwrite properly.
|
||||
if (Memory::IsValidRange(src, srcSize) && Memory::IsValidRange(dst, dstSize)) {
|
||||
drawEngine_->transformUnit.FlushIfOverlap(this, "blockxfer", false, src, srcStride, width * bpp, height);
|
||||
drawEngine_->transformUnit.FlushIfOverlap(this, "blockxfer", true, dst, dstStride, width * bpp, height);
|
||||
drawEngine_->transformUnit.FlushIfOverlap(this, "blockxfer", false, src, srcStride * bpp, width * bpp, height);
|
||||
drawEngine_->transformUnit.FlushIfOverlap(this, "blockxfer", true, dst, dstStride * bpp, width * bpp, height);
|
||||
} else {
|
||||
drawEngine_->transformUnit.Flush(this, "blockxfer_wrap");
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user