Skip to content

Commit

Permalink
Added SDL_DXGIGetOutputInfo which returns the adapter and output indi…
Browse files Browse the repository at this point in the history
…ces that are used to create DX10 and DX11 devices and swap chains on a particular display.

CR: SamL
  • Loading branch information
slouken committed Feb 13, 2014
1 parent e34da68 commit c52c910
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 2 deletions.
6 changes: 6 additions & 0 deletions include/SDL_system.h
Expand Up @@ -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__ */


Expand Down
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_overrides.h
Expand Up @@ -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
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_procs.h
Expand Up @@ -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

Expand Down
9 changes: 7 additions & 2 deletions src/test/SDL_test_common.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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
}
}
Expand Down
85 changes: 85 additions & 0 deletions src/video/windows/SDL_windowsvideo.c
Expand Up @@ -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: */

0 comments on commit c52c910

Please sign in to comment.