Commit fae4190dcaad5150568958f2a8f20edeba2084e1

Sam Lantinga 2013-09-13T17:42:46

Added SDL_Direct3D9GetAdapterIndex(), which returns the adapter index you would pass into CreateDevice to get your device on the right monitor in full screen mode. This fixes the default adapter in SDL_render_d3d.c, which means that tests will work fullscreen off the main monitor now. CR: Sam

diff --git a/include/SDL_system.h b/include/SDL_system.h
index 26e9eaa..68ff899 100644
--- a/include/SDL_system.h
+++ b/include/SDL_system.h
@@ -41,6 +41,19 @@
 extern "C" {
 #endif
 
+
+/* Platform specific functions for Windows */
+#ifdef __WIN32__
+
+/* Returns the D3D9 adapter index that matches the specified display index.
+   This adapter index can be passed to IDirect3D9::CreateDevice and controls
+   on which monitor a full screen application will appear.
+*/
+extern DECLSPEC int SDLCALL SDL_Direct3D9GetAdapterIndex( int displayIndex );
+
+#endif /* __WIN32__ */
+
+
 /* Platform specific functions for iOS */
 #if defined(__IPHONEOS__) && __IPHONEOS__
 
@@ -93,7 +106,6 @@ extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath();
 
 #endif /* __ANDROID__ */
 
-
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
 }
diff --git a/src/render/direct3d/SDL_render_d3d.c b/src/render/direct3d/SDL_render_d3d.c
index 2ce2262..d99057e 100644
--- a/src/render/direct3d/SDL_render_d3d.c
+++ b/src/render/direct3d/SDL_render_d3d.c
@@ -29,6 +29,8 @@
 #include "SDL_loadso.h"
 #include "SDL_syswm.h"
 #include "../SDL_sysrender.h"
+#include "../../video/SDL_sysvideo.h"
+#include "../../video/windows/SDL_windowsmodes.h"
 #include <stdio.h>
 
 #if SDL_VIDEO_RENDER_D3D
@@ -531,6 +533,72 @@ D3D_ActivateRenderer(SDL_Renderer * renderer)
     return 0;
 }
 
+SDL_bool 
+D3D_LoadDLL( void **pD3DDLL, IDirect3D9 **pDirect3D9Interface )
+{
+	*pD3DDLL = SDL_LoadObject("D3D9.DLL");
+	if (*pD3DDLL) {
+		IDirect3D9 *(WINAPI * D3DCreate) (UINT SDKVersion);
+
+		D3DCreate =
+			(IDirect3D9 * (WINAPI *) (UINT)) SDL_LoadFunction(*pD3DDLL,
+			"Direct3DCreate9");
+		if (D3DCreate) {
+			*pDirect3D9Interface = D3DCreate(D3D_SDK_VERSION);
+		}
+		if (!*pDirect3D9Interface) {
+			SDL_UnloadObject(*pD3DDLL);
+			*pD3DDLL = NULL;
+			return SDL_FALSE;
+		}
+
+		return SDL_TRUE;
+	} else {
+		*pDirect3D9Interface = NULL;
+		return SDL_FALSE;
+	}
+}
+
+
+int 
+SDL_Direct3D9GetAdapterIndex( int displayIndex )
+{
+	void *pD3DDLL;
+	IDirect3D9 *pD3D;
+	if (!D3D_LoadDLL( &pD3DDLL, &pD3D)) {
+		SDL_SetError("Unable to create Direct3D interface");
+		return D3DADAPTER_DEFAULT;
+	} else {
+		SDL_DisplayData *pData = (SDL_DisplayData *)SDL_GetDisplayDriverData( displayIndex );
+		int adapterIndex = D3DADAPTER_DEFAULT;
+
+		if (!pData) {
+			SDL_SetError( "Invalid display index" );
+		} else {
+			char *displayName = WIN_StringToUTF8( pData->DeviceName );
+			unsigned int count = IDirect3D9_GetAdapterCount( pD3D );
+			unsigned int i;
+			for (i=0; i<count; i++) {
+				D3DADAPTER_IDENTIFIER9 id;
+				IDirect3D9_GetAdapterIdentifier(pD3D, i, 0, &id);
+
+				if (SDL_strcmp(id.DeviceName, displayName) == 0) {
+					adapterIndex = i;
+					break;
+				}
+			}
+			SDL_free( displayName );
+		}
+
+		/* free up the D3D stuff we inited */
+		IDirect3D9_Release(pD3D);
+		SDL_UnloadObject(pD3DDLL);
+
+		return adapterIndex;
+	}
+}
+
+
 SDL_Renderer *
 D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
 {
@@ -546,6 +614,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
     SDL_DisplayMode fullscreen_mode;
     int d3dxVersion;
     char d3dxDLLFile[50];
+	int displayIndex;
 
     renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
     if (!renderer) {
@@ -560,21 +629,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
         return NULL;
     }
 
-    data->d3dDLL = SDL_LoadObject("D3D9.DLL");
-    if (data->d3dDLL) {
-        IDirect3D9 *(WINAPI * D3DCreate) (UINT SDKVersion);
-
-        D3DCreate =
-            (IDirect3D9 * (WINAPI *) (UINT)) SDL_LoadFunction(data->d3dDLL,
-                                                            "Direct3DCreate9");
-        if (D3DCreate) {
-            data->d3d = D3DCreate(D3D_SDK_VERSION);
-        }
-        if (!data->d3d) {
-            SDL_UnloadObject(data->d3dDLL);
-            data->d3dDLL = NULL;
-        }
-
+	if( D3D_LoadDLL( &data->d3dDLL, &data->d3d ) ) {
         for (d3dxVersion=50;d3dxVersion>0;d3dxVersion--) {
             LPTSTR dllName;
             SDL_snprintf(d3dxDLLFile, sizeof(d3dxDLLFile), "D3DX9_%02d.dll", d3dxVersion);
@@ -667,8 +722,10 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
         pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
     }
 
-    /* FIXME: Which adapter? */
-    data->adapter = D3DADAPTER_DEFAULT;
+    /* Get the adapter for the display that the window is on */
+	displayIndex = SDL_GetWindowDisplayIndex( window );
+    data->adapter = SDL_Direct3D9GetAdapterIndex( displayIndex );
+
     IDirect3D9_GetDeviceCaps(data->d3d, data->adapter, D3DDEVTYPE_HAL, &caps);
 
     result = IDirect3D9_CreateDevice(data->d3d, data->adapter,
diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h
index 084742f..2d36c9d 100644
--- a/src/video/SDL_sysvideo.h
+++ b/src/video/SDL_sysvideo.h
@@ -371,6 +371,7 @@ extern int SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode);
 extern int SDL_AddVideoDisplay(const SDL_VideoDisplay * display);
 extern SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode * mode);
 extern SDL_VideoDisplay *SDL_GetDisplayForWindow(SDL_Window *window);
+extern void *SDL_GetDisplayDriverData( int displayIndex );
 
 extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);
 
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index 72bd074..8622d73 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -615,6 +615,14 @@ SDL_GetIndexOfDisplay(SDL_VideoDisplay *display)
     return 0;
 }
 
+void *
+SDL_GetDisplayDriverData( int displayIndex )
+{
+	CHECK_DISPLAY_INDEX( displayIndex, NULL );
+
+	return _this->displays[displayIndex].driverdata;
+}
+
 const char *
 SDL_GetDisplayName(int displayIndex)
 {