From ec33da05b30ab5b05ef10ad91e50bfae73d5c648 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 7 Sep 2025 11:00:59 -0700 Subject: [PATCH] Added SDL_HINT_RENDER_DIRECT3D11_WARP Fixes https://github.com/libsdl-org/SDL/issues/13002 --- include/SDL3/SDL_hints.h | 17 ++++++++++++++++ src/render/direct3d11/SDL_render_d3d11.c | 26 ++++++++++++++++-------- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index b3103ae7f7..fe502be18d 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -2964,6 +2964,23 @@ extern "C" { */ #define SDL_HINT_RENDER_DIRECT3D11_DEBUG "SDL_RENDER_DIRECT3D11_DEBUG" +/** + * A variable controlling whether to use the Direct3D 11 WARP software rasterizer. + * + * For more information, see: + * https://learn.microsoft.com/en-us/windows/win32/direct3darticles/directx-warp + * + * The variable can be set to the following values: + * + * - "0": Disable WARP rasterizer. (default) + * - "1": Enable WARP rasterizer. + * + * This hint should be set before creating a renderer. + * + * \since This hint is available since SDL 3.4.0. + */ +#define SDL_HINT_RENDER_DIRECT3D11_WARP "SDL_RENDER_DIRECT3D11_WARP" + /** * A variable controlling whether to enable Vulkan Validation Layers. * diff --git a/src/render/direct3d11/SDL_render_d3d11.c b/src/render/direct3d11/SDL_render_d3d11.c index 89bbe74011..f595da09a0 100644 --- a/src/render/direct3d11/SDL_render_d3d11.c +++ b/src/render/direct3d11/SDL_render_d3d11.c @@ -154,7 +154,6 @@ typedef struct SDL_SharedObject *hDXGIMod; SDL_SharedObject *hD3D11Mod; IDXGIFactory2 *dxgiFactory; - IDXGIAdapter *dxgiAdapter; IDXGIDebug *dxgiDebug; ID3D11Device1 *d3dDevice; ID3D11DeviceContext1 *d3dContext; @@ -369,7 +368,6 @@ static void D3D11_ReleaseAll(SDL_Renderer *renderer) SAFE_RELEASE(data->d3dContext); SAFE_RELEASE(data->d3dDevice); - SAFE_RELEASE(data->dxgiAdapter); SAFE_RELEASE(data->dxgiFactory); data->swapEffect = (DXGI_SWAP_EFFECT)0; @@ -512,10 +510,12 @@ static HRESULT D3D11_CreateDeviceResources(SDL_Renderer *renderer) PFN_CREATE_DXGI_FACTORY2 CreateDXGIFactory2Func = NULL; D3D11_RenderData *data = (D3D11_RenderData *)renderer->internal; PFN_D3D11_CREATE_DEVICE D3D11CreateDeviceFunc; + IDXGIAdapter *dxgiAdapter = NULL; ID3D11Device *d3dDevice = NULL; ID3D11DeviceContext *d3dContext = NULL; IDXGIDevice1 *dxgiDevice = NULL; HRESULT result = S_OK; + D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_UNKNOWN; UINT creationFlags = 0; bool createDebug; #ifdef HAVE_DXGI1_5_H @@ -625,11 +625,18 @@ static HRESULT D3D11_CreateDeviceResources(SDL_Renderer *renderer) } #endif // HAVE_DXGI1_5_H - // FIXME: Should we use the default adapter? - result = IDXGIFactory2_EnumAdapters(data->dxgiFactory, 0, &data->dxgiAdapter); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("D3D11CreateDevice"), result); - goto done; + if (SDL_GetHintBoolean(SDL_HINT_RENDER_DIRECT3D11_WARP, false)) { + driverType = D3D_DRIVER_TYPE_WARP; + dxgiAdapter = NULL; + } else { + driverType = D3D_DRIVER_TYPE_UNKNOWN; + + // FIXME: Should we use the default adapter? + result = IDXGIFactory2_EnumAdapters(data->dxgiFactory, 0, &dxgiAdapter); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("EnumAdapters"), result); + goto done; + } } /* This flag adds support for surfaces with a different color channel ordering @@ -649,8 +656,8 @@ static HRESULT D3D11_CreateDeviceResources(SDL_Renderer *renderer) // Create the Direct3D 11 API device object and a corresponding context. result = D3D11CreateDeviceFunc( - data->dxgiAdapter, - D3D_DRIVER_TYPE_UNKNOWN, + dxgiAdapter, + driverType, NULL, creationFlags, // Set set debug and Direct2D compatibility flags. featureLevels, // List of feature levels this app can support. @@ -779,6 +786,7 @@ static HRESULT D3D11_CreateDeviceResources(SDL_Renderer *renderer) SDL_SetPointerProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_D3D11_DEVICE_POINTER, data->d3dDevice); done: + SAFE_RELEASE(dxgiAdapter); SAFE_RELEASE(d3dDevice); SAFE_RELEASE(d3dContext); SAFE_RELEASE(dxgiDevice);