From d4b561f472b40c37a5111aec9974ee574d19bed9 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 5 Apr 2020 08:58:47 -0700 Subject: [PATCH] Fixed bug 5015 - SDL_RenderReadPixels on DirectX 11.1 backend seems to be broken Konrad It appears that I cannot use SDL_RenderReadPixels on a bound framebuffer (SDL_Texture set as render target) as it simply results in gibberish data. However, drawing that framebuffer into the default target (window surface) does render it correctly. Other backends (OpenGL, software, Direct3D) do work fine. It looks to me like D3D11_RenderReadPixels just gets the general backbuffer and not the current render target and its backbuffer. Here is the patch which actually fetches the current render target and its underlying ID3D11Resource which is ID3D11Texture2D. --- src/render/direct3d11/SDL_render_d3d11.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/render/direct3d11/SDL_render_d3d11.c b/src/render/direct3d11/SDL_render_d3d11.c index 735173e179786..d814abc5d7ea6 100644 --- a/src/render/direct3d11/SDL_render_d3d11.c +++ b/src/render/direct3d11/SDL_render_d3d11.c @@ -2325,6 +2325,7 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, void * pixels, int pitch) { D3D11_RenderData * data = (D3D11_RenderData *) renderer->driverdata; + ID3D11RenderTargetView *renderTargetView = NULL; ID3D11Texture2D *backBuffer = NULL; ID3D11Texture2D *stagingTexture = NULL; HRESULT result; @@ -2334,14 +2335,15 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, D3D11_BOX srcBox; D3D11_MAPPED_SUBRESOURCE textureMemory; - /* Retrieve a pointer to the back buffer: */ - result = IDXGISwapChain_GetBuffer(data->swapChain, - 0, - &SDL_IID_ID3D11Texture2D, - (void **)&backBuffer - ); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain1::GetBuffer [get back buffer]"), result); + ID3D11DeviceContext_OMGetRenderTargets(data->d3dContext, 1, &renderTargetView, NULL); + if (renderTargetView == NULL) { + SDL_SetError("%s, ID3D11DeviceContext::OMGetRenderTargets failed", __FUNCTION__); + goto done; + } + + ID3D11View_GetResource(renderTargetView, (ID3D11Resource**)&backBuffer); + if (backBuffer == NULL) { + SDL_SetError("%s, ID3D11View::GetResource failed", __FUNCTION__); goto done; }