GS: only flush queued draws for an upload the queue can see

GSTexture::Update drained the whole deferred-draw queue before every upload.
Almost none of those uploads touch a texture the queue has heard of - the
texture cache uploads into surfaces it just fetched from the pool - so the
flush was throwing away coalescing for nothing.

Use the narrow form, which flushes only when a queued draw actually reads or
writes this texture. That is the same test the pool and deferred-clear paths
already use.

Attributing every flush in a four-frame Dirge of Cerberus capture put uploads
at 46 of 305, second only to draws that carry a barrier. Removing them takes
the capture from 543 render passes to 523; the rest of the corpus is unmoved
and every frame hash is still identical to the unscheduled path.
This commit is contained in:
Brian Degenhardt
2026-07-25 17:56:02 -07:00
parent 8c702e0d1d
commit f2213660f0
+5 -1
View File
@@ -18,7 +18,11 @@ GSTexture::~GSTexture() = default;
bool GSTexture::Update(const GSVector4i& r, const void* data, int pitch, int layer)
{
g_gs_device->FlushDeferredDraws();
// An upload only conflicts with a queued draw that reads or writes this very texture -
// and the overwhelming majority are into a source the queue has never seen, since the
// texture cache uploads into freshly pooled surfaces. Flushing for all of them was 15%
// of every flush on Dirge of Cerberus.
g_gs_device->FlushDeferredDrawsFor(this);
return DoUpdate(r, data, pitch, layer);
}