https://bugs.winehq.org/show_bug.cgi?id=45901
--- Comment #6 from Andrew Wesie awesie@gmail.com --- (In reply to Józef Kucia from comment #5)
I don't think that you are using the classic Radeon driver. You probably use one of the Gallium drivers, radeonsi most likely.
You are correct. Those were the wrong parts of Mesa to highlight.
In ./mesa/state_tracker/st_cb_texture.c:st_GetTexSubImage, which is the code path for Gallium drivers, it will blit into a tmp texture, map the PBO, map the tmp texture, and memcpy:
st->pipe->blit(st->pipe, &blit); pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels); map = pipe_transfer_map_3d(pipe, dst, 0, PIPE_TRANSFER_READ, ...); ... memcpy(dest, slice_map, bytesPerRow); ... pipe_transfer_unmap(pipe, tex_xfer); _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
In mesa/state_tracker/st_cb_readpixels.c:st_ReadPixels it has a fast path for PBOs:
if (st->pbo.download_enabled && _mesa_is_bufferobj(pack->BufferObj)) { if (try_pbo_readpixels(st, strb, st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP, x, y, width, height, src_format, dst_format, pack, pixels)) return; }
The rationale for using glReadPixels is the lack of hardware support for GetTexSubImage in Mesa's Gallium drivers.
While try_pbo_readpixels looks very complex, to me at least, it avoids the very costly CPU-GPU synchronization.