From 244b79e194334aa91f2fa5dfb0a11d2b4a62401f Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sun, 4 Nov 2018 14:31:56 -0400 Subject: [PATCH] metal: SDL_RenderReadPixels on macOS synchronizes the render target's texture data if it's managed, before reading from it. --- src/render/metal/SDL_render_metal.m | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/render/metal/SDL_render_metal.m b/src/render/metal/SDL_render_metal.m index d5e009d04..06e4ef681 100644 --- a/src/render/metal/SDL_render_metal.m +++ b/src/render/metal/SDL_render_metal.m @@ -1196,14 +1196,28 @@ METAL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL); - // Commit any current command buffer, and waitUntilCompleted, so any output is ready to be read. [data.mtlcmdencoder endEncoding]; + id mtltexture = data.mtlpassdesc.colorAttachments[0].texture; + +#ifdef __MACOSX__ + /* on macOS with managed-storage textures, we need to tell the driver to + * update the CPU-side copy of the texture data. + * NOTE: Currently all of our textures are managed on macOS. We'll need some + * extra copying for any private textures. */ + if (mtltexture.storageMode == MTLStorageModeManaged) { + id blit = [data.mtlcmdbuffer blitCommandEncoder]; + [blit synchronizeResource:mtltexture]; + [blit endEncoding]; + } +#endif + + /* Commit the current command buffer and wait until it's completed, to make + * sure the GPU has finished rendering to it by the time we read it. */ [data.mtlcmdbuffer commit]; [data.mtlcmdbuffer waitUntilCompleted]; data.mtlcmdencoder = nil; data.mtlcmdbuffer = nil; - id mtltexture = data.mtlpassdesc.colorAttachments[0].texture; MTLRegion mtlregion = MTLRegionMake2D(rect->x, rect->y, rect->w, rect->h); // we only do BGRA8 or RGBA8 at the moment, so 4 will do.