mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
[Fix] (DirectVulkan, MG_State): make a shader-written storage buffer readable on Magma
Reading a buffer a compute shader wrote gave zeros: the frontend shadow that MapBuffer resolves against is only maintained by uploads, and Magma had no path back. Every KHR-GL40.texture_gather case ends by dispatching a compute shader into an SSBO and comparing the mapped result, so 66 of 75 failed on it. Magma needs no readback: EnsureGpuResidentStorage - the same host-visible coherent adoption the transform feedback capture already uses - makes the shadow BE the memory the shader writes, so binding a buffer as a shader storage buffer now adopts it. What coherence does not give is ordering: the writes are visible once they have happened, and the CPU was reading before the dispatch had retired. The readback op therefore submits the recorded work and waits. That exposed a mistake in the frontend flag this rides on: MarkGpuWritten skipped GPU-resident buffers, reasoning there was no shadow to refresh. True, but the wait is still needed - "reconcile with the GPU write" is not always "copy it back", and which of the two it is belongs to the backend. The flag now only says a write is outstanding; DirectGLES's readback still skips its persistent-mapped buffers when copying. KHR-GL40.texture_gather on Magma: 66 failures -> 19 (the rest are rectangle textures, mipmap completeness and tessellation, all still to do). Espryt stays at 75/75.
This commit is contained in:
@@ -175,9 +175,6 @@ namespace MobileGL::MG_State::GLState {
|
||||
}
|
||||
|
||||
void BufferObject::MarkGpuWritten() {
|
||||
// A GPU-resident buffer has no separate shadow to refresh: reads already resolve
|
||||
// against the coherent map the shader wrote into.
|
||||
if (m_resource.IsGpuResident()) return;
|
||||
m_gpuWritePending = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -157,8 +157,10 @@ namespace MobileGL {
|
||||
void WritebackFromBackend(DataPtr data, SizeT atOffset);
|
||||
|
||||
// A draw or dispatch just ran with this buffer bound where a shader can write
|
||||
// it (shader storage / atomic counter): the GPU copy may now differ from the
|
||||
// shadow, so the next read has to pull it back.
|
||||
// it (shader storage / atomic counter). The next read has to reconcile with
|
||||
// that: pull the bytes back, or - when the shadow already IS coherent GPU
|
||||
// memory - wait for the work that wrote them to retire. Which of the two is
|
||||
// the backend's business; the flag only says a GPU write is outstanding.
|
||||
void MarkGpuWritten();
|
||||
// Refreshes the shadow from the backend when a GPU write is outstanding. Called
|
||||
// from every path that reads the shadow on the app's behalf.
|
||||
|
||||
Reference in New Issue
Block a user