Commit a99bf4d705f0d1909fb37acc9c5433ea68dabb12

David Ludwig 2014-03-24T22:51:03

WinRT: Call IDXGIDevice3::Trim before app-suspend, as required on Windows 8.1 Thanks to Sylvain Becker for pointing this out!

diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp
index 1e32e3a..3a9f597 100644
--- a/src/core/winrt/SDL_winrtapp_direct3d.cpp
+++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp
@@ -70,6 +70,13 @@ extern "C" {
 #include "SDL_winrtapp_common.h"
 #include "SDL_winrtapp_direct3d.h"
 
+#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED
+/* Calling IDXGIDevice3::Trim on the active Direct3D 11.x device is necessary
+ * when Windows 8.1 apps are about to get suspended.
+ */
+extern "C" void D3D11_Trim(SDL_Renderer *);
+#endif
+
 
 // Compile-time debugging options:
 // To enable, uncomment; to disable, comment them out.
@@ -616,6 +623,18 @@ void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ a
         // WinRT.
         SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND);
 
+        // Let the Direct3D 11 renderer prepare for the app to be backgrounded.
+        // This is necessary for Windows 8.1, possibly elsewhere in the future.
+        // More details at: http://msdn.microsoft.com/en-us/library/windows/apps/Hh994929.aspx
+#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED
+        if (WINRT_GlobalSDLWindow) {
+            SDL_Renderer * renderer = SDL_GetRenderer(WINRT_GlobalSDLWindow);
+            if (renderer && (SDL_strcmp(renderer->info.name, "direct3d11") == 0)) {
+                D3D11_Trim(renderer);
+            }
+        }
+#endif
+
         deferral->Complete();
     });
 }
diff --git a/src/render/direct3d11/SDL_render_d3d11.c b/src/render/direct3d11/SDL_render_d3d11.c
index df6983d..806846c 100644
--- a/src/render/direct3d11/SDL_render_d3d11.c
+++ b/src/render/direct3d11/SDL_render_d3d11.c
@@ -35,6 +35,10 @@
 
 #ifdef __WINRT__
 
+#if NTDDI_VERSION > NTDDI_WIN8
+#include <DXGI1_3.h>
+#endif
+
 #include "SDL_render_winrt.h"
 
 #if WINAPI_FAMILY == WINAPI_FAMILY_APP
@@ -134,6 +138,7 @@ typedef struct
 /* Defined here so we don't have to include uuid.lib */
 static const GUID IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } };
 static const GUID IID_IDXGIDevice1 = { 0x77db970f, 0x6276, 0x48ba, { 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c } };
+static const GUID IID_IDXGIDevice3 = { 0x6007896c, 0x3244, 0x4afd, { 0xbf, 0x18, 0xa6, 0xd3, 0xbe, 0xda, 0x50, 0x23 } };
 static const GUID IID_ID3D11Texture2D = { 0x6f15aaf2, 0xd208, 0x4e89, { 0x9a, 0xb4, 0x48, 0x95, 0x35, 0xd3, 0x4f, 0x9c } };
 static const GUID IID_ID3D11Device1 = { 0xa04bfb29, 0x08ef, 0x43d6, { 0xa4, 0x9c, 0xa9, 0xbd, 0xbd, 0xcb, 0xe6, 0x86 } };
 static const GUID IID_ID3D11DeviceContext1 = { 0xbb2c6faa, 0xb5fb, 0x4082, { 0x8e, 0x6b, 0x38, 0x8b, 0x8c, 0xfa, 0x90, 0xe1 } };
@@ -1601,6 +1606,27 @@ D3D11_HandleDeviceLost(SDL_Renderer * renderer)
     return S_OK;
 }
 
+void
+D3D11_Trim(SDL_Renderer * renderer)
+{
+#ifdef __WINRT__
+#if NTDDI_VERSION > NTDDI_WIN8
+    D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
+    HRESULT result = S_OK;
+    IDXGIDevice3 *dxgiDevice = NULL;
+
+    result = ID3D11Device_QueryInterface(data->d3dDevice, &IID_IDXGIDevice3, &dxgiDevice);
+    if (FAILED(result)) {
+        //WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to IDXGIDevice3", result);
+        return;
+    }
+
+    IDXGIDevice3_Trim(dxgiDevice);
+    SAFE_RELEASE(dxgiDevice);
+#endif
+#endif
+}
+
 static void
 D3D11_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
 {