Added SDL_DXGIGetOutputInfo which returns the adapter and output indices that are used to create DX10 and DX11 devices and swap chains on a particular display. CR: SamL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
diff --git a/include/SDL_system.h b/include/SDL_system.h
index 7913ddf..99ef822 100644
--- a/include/SDL_system.h
+++ b/include/SDL_system.h
@@ -55,6 +55,12 @@ extern DECLSPEC int SDLCALL SDL_Direct3D9GetAdapterIndex( int displayIndex );
typedef struct IDirect3DDevice9 IDirect3DDevice9;
extern DECLSPEC IDirect3DDevice9* SDLCALL SDL_RenderGetD3D9Device(SDL_Renderer * renderer);
+/* Returns the DXGI Adapter and Output indices for the specified display index.
+ These can be passed to EnumAdapters and EnumOutputs respectively to get the objects
+ required to create a DX10 or DX11 device and swap chain.
+ */
+extern DECLSPEC void SDLCALL SDL_DXGIGetOutputInfo( int displayIndex, int *adapterIndex, int *outputIndex );
+
#endif /* __WIN32__ */
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index e6234cb..5ae7927 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -574,3 +574,4 @@
#define SDL_HasAVX SDL_HasAVX_REAL
#define SDL_GetDefaultAssertionHandler SDL_GetDefaultAssertionHandler_REAL
#define SDL_GetAssertionHandler SDL_GetAssertionHandler_REAL
+#define SDL_DXGIGetOutputInfo SDL_DXGIGetOutputInfo_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index 362bb83..260bf13 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -70,6 +70,7 @@ SDL_DYNAPI_PROC(void,SDL_MemoryBarrierAcquire,(void),(),)
SDL_DYNAPI_PROC(int,SDL_RegisterApp,(char *a, Uint32 b, void *c),(a,b,c),return)
SDL_DYNAPI_PROC(void,SDL_UnregisterApp,(void),(),)
SDL_DYNAPI_PROC(int,SDL_Direct3D9GetAdapterIndex,(int a),(a),return)
+SDL_DYNAPI_PROC(void,SDL_DXGIGetOutputInfo,(int a,int *b, int *c),(a,b,c),)
SDL_DYNAPI_PROC(IDirect3DDevice9*,SDL_RenderGetD3D9Device,(SDL_Renderer *a),(a),return)
#endif
diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c
index b2b87a1..c03da03 100644
--- a/src/test/SDL_test_common.c
+++ b/src/test/SDL_test_common.c
@@ -706,6 +706,7 @@ SDLTest_CommonInit(SDLTest_CommonState * state)
Uint32 Rmask, Gmask, Bmask, Amask;
#if SDL_VIDEO_DRIVER_WINDOWS
int adapterIndex = 0;
+ int outputIndex = 0;
#endif
n = SDL_GetNumVideoDisplays();
fprintf(stderr, "Number of displays: %d\n", n);
@@ -761,9 +762,13 @@ SDLTest_CommonInit(SDLTest_CommonState * state)
}
#if SDL_VIDEO_DRIVER_WINDOWS
- /* Print the adapter index */
+ /* Print the D3D9 adapter index */
adapterIndex = SDL_Direct3D9GetAdapterIndex( i );
- fprintf( stderr, "Adapter Index: %d", adapterIndex );
+ fprintf( stderr, "D3D9 Adapter Index: %d", adapterIndex );
+
+ /* Print the DXGI adapter and output indices */
+ SDL_DXGIGetOutputInfo(i, &adapterIndex, &outputIndex);
+ fprintf( stderr, "DXGI Adapter Index: %d Output Index: %d", adapterIndex, outputIndex );
#endif
}
}
diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c
index 9ad5613..dde2622 100644
--- a/src/video/windows/SDL_windowsvideo.c
+++ b/src/video/windows/SDL_windowsvideo.c
@@ -245,6 +245,91 @@ SDL_Direct3D9GetAdapterIndex( int displayIndex )
}
}
+#define CINTERFACE
+#define COBJMACROS
+#include <DXGI.h>
+
+SDL_bool
+DXGI_LoadDLL( void **pDXGIDLL , IDXGIFactory **pDXGIFactory )
+{
+ *pDXGIDLL = SDL_LoadObject("DXGI.DLL");
+ if (*pDXGIDLL ) {
+ HRESULT (WINAPI *CreateDXGI)( REFIID riid, void **ppFactory );
+
+ CreateDXGI =
+ (HRESULT (WINAPI *) (REFIID, void**)) SDL_LoadFunction(*pDXGIDLL,
+ "CreateDXGIFactory");
+ if (CreateDXGI) {
+ GUID dxgiGUID = {0x7b7166ec,0x21c7,0x44ae,{0xb2,0x1a,0xc9,0xae,0x32,0x1a,0xe3,0x69}};
+ if( !SUCCEEDED( CreateDXGI( &dxgiGUID, pDXGIFactory ))) {
+ *pDXGIFactory = NULL;
+ }
+ }
+ if (!*pDXGIFactory) {
+ SDL_UnloadObject(*pDXGIDLL);
+ *pDXGIDLL = NULL;
+ return SDL_FALSE;
+ }
+
+ return SDL_TRUE;
+ } else {
+ *pDXGIFactory = NULL;
+ return SDL_FALSE;
+ }
+}
+
+
+void
+SDL_DXGIGetOutputInfo( int displayIndex, int *adapterIndex, int *outputIndex )
+{
+ void *pDXGIDLL;
+ IDXGIFactory *pDXGIFactory;
+
+ *adapterIndex = -1;
+ *outputIndex = -1;
+
+ if (!DXGI_LoadDLL(&pDXGIDLL, &pDXGIFactory)) {
+ SDL_SetError("Unable to create DXGI interface");
+ } else {
+ SDL_DisplayData *pData = (SDL_DisplayData *)SDL_GetDisplayDriverData(displayIndex);
+
+ if (!pData) {
+ SDL_SetError("Invalid display index");
+ } else {
+ char *displayName = WIN_StringToUTF8(pData->DeviceName);
+ int nAdapter = 0, nOutput = 0;
+ IDXGIAdapter* pDXGIAdapter;
+ while ( *adapterIndex == -1 && IDXGIFactory_EnumAdapters(pDXGIFactory, nAdapter, &pDXGIAdapter) != DXGI_ERROR_NOT_FOUND ) {
+ IDXGIOutput* pDXGIOutput;
+ while ( *adapterIndex == -1 && IDXGIAdapter_EnumOutputs(pDXGIAdapter, nOutput, &pDXGIOutput) != DXGI_ERROR_NOT_FOUND ) {
+ DXGI_OUTPUT_DESC outputDesc;
+ if (SUCCEEDED(IDXGIOutput_GetDesc(pDXGIOutput, &outputDesc))) {
+ char *outputName = WIN_StringToUTF8(outputDesc.DeviceName);
+
+ if(!SDL_strcmp(outputName, displayName)) {
+ *adapterIndex = nAdapter;
+ *outputIndex = nOutput;
+ }
+
+ SDL_free( outputName );
+ }
+
+ IDXGIOutput_Release( pDXGIOutput );
+ nOutput++;
+ }
+
+ IDXGIAdapter_Release( pDXGIAdapter );
+ nAdapter++;
+ }
+ SDL_free(displayName);
+ }
+
+ /* free up the D3D stuff we inited */
+ IDXGIFactory_AddRef( pDXGIFactory );
+ SDL_UnloadObject(pDXGIDLL);
+ }
+}
+
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
/* vim: set ts=4 sw=4 expandtab: */