From fae4190dcaad5150568958f2a8f20edeba2084e1 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 13 Sep 2013 17:42:46 -0700 Subject: [PATCH] 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 --- include/SDL_system.h | 14 ++++- src/render/direct3d/SDL_render_d3d.c | 91 ++++++++++++++++++++++------ src/video/SDL_sysvideo.h | 1 + src/video/SDL_video.c | 8 +++ 4 files changed, 96 insertions(+), 18 deletions(-) diff --git a/include/SDL_system.h b/include/SDL_system.h index 26e9eaa0a..68ff8990a 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 2ce22626b..d99057e3c 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 #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; id3dDLL = 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 084742fd8..2d36c9d7a 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 72bd07470..8622d731f 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) {