diff --git a/Makefile.common b/Makefile.common index 554fd92033..25704171f1 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1333,9 +1333,19 @@ ifeq ($(HAVE_DX_COMMON), 1) LIBS += -ldxguid endif +ifeq ($(HAVE_D3D8), 1) + DEFINES += -DHAVE_D3D8 + OBJ += gfx/drivers/d3d9.o +endif + +ifeq ($(HAVE_D3D9), 1) + DEFINES += -DHAVE_D3D9 + OBJ += gfx/drivers/d3d9.o +endif + ifeq ($(HAVE_D3D_COMMON), 1) DEFINES += -DHAVE_D3D - OBJ += gfx/drivers/d3d.o \ + OBJ += \ gfx/common/d3d_common.o \ gfx/drivers_context/d3d_ctx.o diff --git a/configuration.c b/configuration.c index 446be959af..c8db513feb 100644 --- a/configuration.c +++ b/configuration.c @@ -126,11 +126,11 @@ enum video_driver_enum VIDEO_WII, VIDEO_WIIU, VIDEO_XENON360, - VIDEO_XDK_D3D, VIDEO_PSP1, VIDEO_VITA2D, VIDEO_CTR, VIDEO_SWITCH, + VIDEO_D3D8, VIDEO_D3D9, VIDEO_D3D11, VIDEO_D3D12, @@ -283,10 +283,10 @@ static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_WII; static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_WIIU; #elif defined(XENON) static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_XENON360; -#elif (defined(_XBOX1) || defined(_XBOX360)) && (defined(HAVE_D3D8) || defined(HAVE_D3D9)) -static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_XDK_D3D; #elif defined(HAVE_D3D9) static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D9; +#elif defined(HAVE_D3D8) +static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D8; #elif defined(HAVE_VG) static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_VG; #elif defined(HAVE_VITA2D) @@ -694,9 +694,10 @@ const char *config_get_default_video(void) return "gx2"; case VIDEO_XENON360: return "xenon360"; - case VIDEO_XDK_D3D: + case VIDEO_D3D8: + return "d3d8"; case VIDEO_D3D9: - return "d3d"; + return "d3d9"; case VIDEO_D3D11: return "d3d11"; case VIDEO_D3D12: diff --git a/gfx/common/d3d_common.c b/gfx/common/d3d_common.c index 1224111356..635dc7373d 100644 --- a/gfx/common/d3d_common.c +++ b/gfx/common/d3d_common.c @@ -53,6 +53,8 @@ #endif +static enum d3d_comm_api d3d_common_api = D3D_COMM_NONE; + #ifdef _XBOX #include #endif @@ -206,44 +208,48 @@ static dylib_t dylib_load_d3dx(void) #endif -bool d3d_initialize_symbols(void) +bool d3d_initialize_symbols(enum d3d_comm_api api) { #ifdef HAVE_DYNAMIC_D3D if (dylib_initialized) return true; + switch (api) + { + case D3D_COMM_D3D9: #if defined(HAVE_D3D9) #if defined(DEBUG) || defined(_DEBUG) - g_d3d_dll = dylib_load("d3d9d.dll"); - if(!g_d3d_dll) + g_d3d_dll = dylib_load("d3d9d.dll"); + if(!g_d3d_dll) #endif - g_d3d_dll = dylib_load("d3d9.dll"); + g_d3d_dll = dylib_load("d3d9.dll"); #ifdef HAVE_D3DX - g_d3dx_dll = dylib_load_d3dx(); -#endif + g_d3dx_dll = dylib_load_d3dx(); - if (!g_d3d_dll) - return false; -#ifdef HAVE_D3DX - if (!g_d3dx_dll) - return false; + if (!g_d3dx_dll) + return false; #endif - + break; + case D3D_COMM_D3D8: #elif defined(HAVE_D3D8) #if defined(DEBUG) || defined(_DEBUG) - g_d3d_dll = dylib_load("d3d8d.dll"); - if(!g_d3d_dll) + g_d3d_dll = dylib_load("d3d8d.dll"); + if(!g_d3d_dll) #endif - g_d3d_dll = dylib_load("d3d8.dll"); + g_d3d_dll = dylib_load("d3d8.dll"); +#endif + break; + case D3D_COMM_NONE: + break; + } + if (!g_d3d_dll) return false; #endif -#endif + + d3d_common_api = api; -#if defined(HAVE_D3D9) - SDKVersion = 31; #ifdef HAVE_DYNAMIC_D3D - D3DCreate = (D3DCreate_t)dylib_proc(g_d3d_dll, "Direct3DCreate9"); #ifdef HAVE_D3DX #ifdef UNICODE D3DCreateFontIndirect = (D3DXCreateFontIndirect_t)dylib_proc(g_d3dx_dll, "D3DXCreateFontIndirectW"); @@ -255,7 +261,6 @@ bool d3d_initialize_symbols(void) D3DCompileShader = (D3DCompileShader_t)dylib_proc(g_d3dx_dll, "D3DXCompileShader"); #endif #else - D3DCreate = Direct3DCreate9; #ifdef HAVE_D3DX D3DCreateFontIndirect = D3DXCreateFontIndirect; D3DCreateTextureFromFile = D3DXCreateTextureFromFileExA; @@ -263,28 +268,42 @@ bool d3d_initialize_symbols(void) D3DCompileShader = D3DXCompileShader; #endif #endif -#elif defined(HAVE_D3D8) - SDKVersion = 220; + + switch (api) + { + case D3D_COMM_D3D9: + SDKVersion = 31; +#ifdef HAVE_D3D9 #ifdef HAVE_DYNAMIC_D3D - D3DCreate = (D3DCreate_t)dylib_proc(g_d3d_dll, "Direct3DCreate8"); + D3DCreate = (D3DCreate_t)dylib_proc(g_d3d_dll, "Direct3DCreate9"); +#else + D3DCreate = Direct3DCreate9; +#endif +#endif + break; + case D3D_COMM_D3D8: + SDKVersion = 220; +#ifdef HAVE_D3D8 +#ifdef HAVE_DYNAMIC_D3D + D3DCreate = (D3DCreate_t)dylib_proc(g_d3d_dll, "Direct3DCreate8"); #ifdef HAVE_D3DX - D3DCreateFontIndirect = D3DXCreateFontIndirect; - D3DCreateTextureFromFile = D3DXCreateTextureFromFileExA; + D3DCreateFontIndirect = D3DXCreateFontIndirect; + D3DCreateTextureFromFile = D3DXCreateTextureFromFileExA; #endif #else - D3DCreate = Direct3DCreate8; -#ifdef HAVE_D3DX - D3DCreateFontIndirect = D3DXCreateFontIndirect; - D3DCreateTextureFromFile = D3DXCreateTextureFromFileExA; -#endif + D3DCreate = Direct3DCreate8; #endif #endif + break; + case D3D_COMM_NONE: + break; + } if (!D3DCreate) goto error; #ifdef _XBOX - SDKVersion = 0; + SDKVersion = 0; #endif #ifdef HAVE_DYNAMIC_D3D dylib_initialized = true; @@ -305,12 +324,13 @@ void d3d_deinitialize_symbols(void) #ifdef HAVE_D3DX if (g_d3dx_dll) dylib_close(g_d3dx_dll); - g_d3dx_dll = NULL; + g_d3dx_dll = NULL; #endif - g_d3d_dll = NULL; + g_d3d_dll = NULL; dylib_initialized = false; #endif + d3d_common_api = D3D_COMM_NONE; } bool d3d_check_device_type(LPDIRECT3D d3d, @@ -321,31 +341,54 @@ bool d3d_check_device_type(LPDIRECT3D d3d, { if (!d3d) return false; -#if defined(HAVE_D3D9) && !defined(__cplusplus) - if (FAILED(IDirect3D9_CheckDeviceType(d3d, - 0, - D3DDEVTYPE_HAL, - disp_format, - backbuffer_format, - windowed_mode))) - return false; -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - if (FAILED(IDirect3D8_CheckDeviceType(d3d, - 0, - D3DDEVTYPE_HAL, - disp_format, - backbuffer_format, - windowed_mode))) - return false; + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + if (FAILED(d3d->CheckDeviceType( + 0, + D3DDEVTYPE_HAL, + disp_format, + backbuffer_format, + windowed_mode))) + return false; #else - if (FAILED(d3d->CheckDeviceType( - 0, - D3DDEVTYPE_HAL, - disp_format, - backbuffer_format, - windowed_mode))) - return false; + if (FAILED(IDirect3D9_CheckDeviceType(d3d, + 0, + D3DDEVTYPE_HAL, + disp_format, + backbuffer_format, + windowed_mode))) + return false; #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + if (FAILED(d3d->CheckDeviceType( + 0, + D3DDEVTYPE_HAL, + disp_format, + backbuffer_format, + windowed_mode))) + return false; +#else + if (FAILED(IDirect3D8_CheckDeviceType(d3d, + 0, + D3DDEVTYPE_HAL, + disp_format, + backbuffer_format, + windowed_mode))) + return false; +#endif +#endif + break; + case D3D_COMM_NONE: + return false; + } + return true; } @@ -355,57 +398,112 @@ bool d3d_get_adapter_display_mode(LPDIRECT3D d3d, { if (!display_mode || !d3d) return false; -#if defined(HAVE_D3D9) && !defined(__cplusplus) + + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 #ifdef _XBOX - return true; + return true; +#elif defined(__cplusplus) + if (FAILED(d3d->GetAdapterDisplayMode(idx, display_mode))) + return false; #else - if (FAILED(IDirect3D9_GetAdapterDisplayMode(d3d, idx, display_mode))) - return false; + if (FAILED(IDirect3D9_GetAdapterDisplayMode(d3d, idx, display_mode))) + return false; #endif -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - if (FAILED(IDirect3D8_GetAdapterDisplayMode(d3d, idx, display_mode))) - return false; +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + if (FAILED(d3d->GetAdapterDisplayMode(idx, display_mode))) + return false; #else - if (FAILED(d3d->GetAdapterDisplayMode(idx, display_mode))) - return false; + if (FAILED(IDirect3D8_GetAdapterDisplayMode(d3d, idx, display_mode))) + return false; #endif +#endif + break; + case D3D_COMM_NONE: + return false; + } + return true; } bool d3d_swap(void *data, LPDIRECT3DDEVICE dev) { -#if defined(HAVE_D3D9) && !defined(__cplusplus) + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus #ifdef _XBOX - IDirect3DDevice9_Present(dev, NULL, NULL, NULL, NULL); + dev->Present(NULL, NULL, NULL, NULL); #else - if (IDirect3DDevice9_Present(dev, NULL, NULL, NULL, NULL) == D3DERR_DEVICELOST) - return false; + if (dev->Present(NULL, NULL, NULL, NULL) != D3D_OK) + return false; #endif -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - if (IDirect3DDevice8_Present(dev, NULL, NULL, NULL, NULL) == D3DERR_DEVICELOST) - return false; #else - if (dev->Present(NULL, NULL, NULL, NULL) != D3D_OK) - return false; +#ifdef _XBOX + IDirect3DDevice9_Present(dev, NULL, NULL, NULL, NULL); +#else + if (IDirect3DDevice9_Present(dev, NULL, NULL, NULL, NULL) + == D3DERR_DEVICELOST) + return false; #endif +#endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + if (dev->Present(NULL, NULL, NULL, NULL) != D3D_OK) + return false; +#else + if (IDirect3DDevice8_Present(dev, NULL, NULL, NULL, NULL) + == D3DERR_DEVICELOST) + return false; +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } return true; } void d3d_set_transform(LPDIRECT3DDEVICE dev, D3DTRANSFORMSTATETYPE state, CONST D3DMATRIX *matrix) { -#if !defined(_XBOX360) - /* XBox 360 D3D9 does not support fixed-function pipeline. */ - -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DDevice9_SetTransform(dev, state, matrix); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - IDirect3DDevice8_SetTransform(dev, state, matrix); + switch (d3d_common_api) + { + case D3D_COMM_D3D9: + /* XBox 360 D3D9 does not support fixed-function pipeline. */ +#ifdef HAVE_D3D9 +#ifndef _XBOX +#ifdef __cplusplus + dev->SetTransform(state, matrix); #else - dev->SetTransform(state, matrix); + IDirect3DDevice9_SetTransform(dev, state, matrix); #endif +#endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + dev->SetTransform(state, matrix); +#else + IDirect3DDevice8_SetTransform(dev, state, matrix); +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } -#endif } bool d3d_texture_get_level_desc(LPDIRECT3DTEXTURE tex, @@ -413,21 +511,39 @@ bool d3d_texture_get_level_desc(LPDIRECT3DTEXTURE tex, { if (!tex) return false; -#if defined(HAVE_D3D9) && !defined(__cplusplus) + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + if (SUCCEEDED(tex->GetLevelDesc(idx, (D3DSURFACE_DESC*)_ppsurface_level))) + return true; +#else #if defined(_XBOX) - D3DTexture_GetLevelDesc(tex, idx, (D3DSURFACE_DESC*)_ppsurface_level); - return true; + D3DTexture_GetLevelDesc(tex, idx, (D3DSURFACE_DESC*)_ppsurface_level); + return true; #else - if (SUCCEEDED(IDirect3DTexture9_GetLevelDesc(tex, idx, (D3DSURFACE_DESC*)_ppsurface_level))) - return true; + if (SUCCEEDED(IDirect3DTexture9_GetLevelDesc(tex, idx, (D3DSURFACE_DESC*)_ppsurface_level))) + return true; #endif -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - if (SUCCEEDED(IDirect3DTexture8_GetLevelDesc(tex, idx, (D3DSURFACE_DESC*)_ppsurface_level))) - return true; +#endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + if (SUCCEEDED(tex->GetLevelDesc(idx, (D3DSURFACE_DESC*)_ppsurface_level))) + return true; #else - if (SUCCEEDED(tex->GetLevelDesc(idx, (D3DSURFACE_DESC*)_ppsurface_level))) - return true; + if (SUCCEEDED(IDirect3DTexture8_GetLevelDesc(tex, idx, (D3DSURFACE_DESC*)_ppsurface_level))) + return true; #endif +#endif + break; + case D3D_COMM_NONE: + break; + } + return false; } @@ -436,16 +552,35 @@ bool d3d_texture_get_surface_level(LPDIRECT3DTEXTURE tex, { if (!tex) return false; -#if defined(HAVE_D3D9) && !defined(__cplusplus) - if (SUCCEEDED(IDirect3DTexture9_GetSurfaceLevel(tex, idx, (IDirect3DSurface9**)_ppsurface_level))) - return true; -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - if (SUCCEEDED(IDirect3DTexture8_GetSurfaceLevel(tex, idx, (IDirect3DSurface8**)_ppsurface_level))) - return true; + + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + if (SUCCEEDED(tex->GetSurfaceLevel(idx, (ID3DSURFACE**)_ppsurface_level))) + return true; #else - if (SUCCEEDED(tex->GetSurfaceLevel(idx, (ID3DSURFACE**)_ppsurface_level))) - return true; + if (SUCCEEDED(IDirect3DTexture9_GetSurfaceLevel(tex, idx, (IDirect3DSurface9**)_ppsurface_level))) + return true; #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + if (SUCCEEDED(tex->GetSurfaceLevel(idx, (ID3DSURFACE**)_ppsurface_level))) + return true; +#else + if (SUCCEEDED(IDirect3DTexture8_GetSurfaceLevel(tex, idx, (IDirect3DSurface8**)_ppsurface_level))) + return true; +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } + return false; } @@ -458,8 +593,8 @@ static LPDIRECT3DTEXTURE d3d_texture_new_from_file( D3DCOLOR color_key, void *src_info_data, PALETTEENTRY *palette) { - LPDIRECT3DTEXTURE buf; - HRESULT hr = D3DCreateTextureFromFile(dev, + LPDIRECT3DTEXTURE buf = NULL; + HRESULT hr = D3DCreateTextureFromFile(dev, path, width, height, miplevels, usage, format, pool, filter, mipfilter, color_key, src_info_data, palette, &buf); @@ -478,48 +613,56 @@ LPDIRECT3DTEXTURE d3d_texture_new(LPDIRECT3DDEVICE dev, D3DCOLOR color_key, void *src_info_data, PALETTEENTRY *palette, bool want_mipmap) { - HRESULT hr; - LPDIRECT3DTEXTURE buf; + HRESULT hr = S_OK; + LPDIRECT3DTEXTURE buf = NULL; -#ifndef _XBOX -#ifdef HAVE_D3D9 - if (want_mipmap) - usage |= D3DUSAGE_AUTOGENMIPMAP; -#endif -#endif - -#ifdef HAVE_D3DX if (path) + { +#ifdef HAVE_D3DX return d3d_texture_new_from_file(dev, path, width, height, miplevels, usage, format, pool, filter, mipfilter, color_key, src_info_data, palette); #else - if (path) return NULL; #endif + } -#if defined(HAVE_D3D9) + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifndef _XBOX + if (want_mipmap) + usage |= D3DUSAGE_AUTOGENMIPMAP; +#endif #ifdef __cplusplus - hr = dev->CreateTexture( - width, height, miplevels, usage, - format, pool, &buf, NULL); + hr = dev->CreateTexture( + width, height, miplevels, usage, + format, pool, &buf, NULL); #else - hr = IDirect3DDevice9_CreateTexture(dev, - width, height, miplevels, usage, - format, pool, &buf, NULL); + hr = IDirect3DDevice9_CreateTexture(dev, + width, height, miplevels, usage, + format, pool, &buf, NULL); #endif -#elif defined(HAVE_D3D8) +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 #ifdef __cplusplus - hr = dev->CreateTexture( - width, height, miplevels, usage, - format, pool, &buf); + hr = dev->CreateTexture( + width, height, miplevels, usage, + format, pool, &buf); #else - hr = IDirect3DDevice8_CreateTexture(dev, - width, height, miplevels, usage, - format, pool, &buf); + hr = IDirect3DDevice8_CreateTexture(dev, + width, height, miplevels, usage, + format, pool, &buf); #endif #endif + break; + case D3D_COMM_NONE: + break; + } if (FAILED(hr)) return NULL; @@ -529,52 +672,104 @@ LPDIRECT3DTEXTURE d3d_texture_new(LPDIRECT3DDEVICE dev, void d3d_texture_free(LPDIRECT3DTEXTURE tex) { - if (tex) + if (!tex) + return; + + switch (d3d_common_api) { -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DTexture9_Release(tex); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - IDirect3DTexture8_Release(tex); + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + tex->Release(); #else - tex->Release(); + IDirect3DTexture9_Release(tex); #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + tex->Release(); +#else + IDirect3DTexture8_Release(tex); +#endif +#endif + break; + case D3D_COMM_NONE: + break; } } bool d3d_surface_lock_rect(void *data, void *data2) { LPDIRECT3DSURFACE surf = (LPDIRECT3DSURFACE)data; -#if defined(HAVE_D3D9) && !defined(__cplusplus) + + if (!surf) + return false; + + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + if (FAILED(surf->LockRect((D3DLOCKED_RECT*)data2, NULL, D3DLOCK_READONLY))) + return false; +#else #if defined(_XBOX) - IDirect3DSurface9_LockRect(surf, (D3DLOCKED_RECT*)data2, NULL, D3DLOCK_READONLY); + IDirect3DSurface9_LockRect(surf, (D3DLOCKED_RECT*)data2, NULL, D3DLOCK_READONLY); #else - if (FAILED(IDirect3DSurface9_LockRect(surf, (D3DLOCKED_RECT*)data2, NULL, D3DLOCK_READONLY))) - return false; + if (FAILED(IDirect3DSurface9_LockRect(surf, (D3DLOCKED_RECT*)data2, NULL, D3DLOCK_READONLY))) + return false; #endif -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - if (FAILED(IDirect3DSurface8_LockRect(surf, (D3DLOCKED_RECT*)data2, NULL, D3DLOCK_READONLY))) - return false; -#elif defined(_XBOX) - surf->LockRect((D3DLOCKED_RECT*)data2, NULL, D3DLOCK_READONLY); +#endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + if (FAILED(surf->LockRect((D3DLOCKED_RECT*)data2, NULL, D3DLOCK_READONLY))) + return false; #else - if (FAILED(surf->LockRect((D3DLOCKED_RECT*)data2, NULL, D3DLOCK_READONLY))) - return false; + if (FAILED(IDirect3DSurface8_LockRect(surf, (D3DLOCKED_RECT*)data2, NULL, D3DLOCK_READONLY))) + return false; #endif +#endif + break; + case D3D_COMM_NONE: + break; + } + return true; } void d3d_surface_unlock_rect(void *data) { LPDIRECT3DSURFACE surf = (LPDIRECT3DSURFACE)data; - if (surf) + if (!surf) + return; + + switch (d3d_common_api) { -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DSurface9_UnlockRect(surf); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - IDirect3DSurface8_UnlockRect(surf); + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + surf->UnlockRect(); #else - surf->UnlockRect(); + IDirect3DSurface9_UnlockRect(surf); #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + surf->UnlockRect(); +#else + IDirect3DSurface8_UnlockRect(surf); +#endif +#endif + break; + case D3D_COMM_NONE: + break; } } @@ -583,49 +778,84 @@ void d3d_surface_free(void *data) LPDIRECT3DSURFACE surf = (LPDIRECT3DSURFACE)data; if (!surf) return; -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DSurface9_Release(surf); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - IDirect3DSurface8_Release(surf); + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + surf->Release(); #else - surf->Release(); + IDirect3DSurface9_Release(surf); #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + surf->Release(); +#else + IDirect3DSurface8_Release(surf); +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } } void d3d_vertex_declaration_free(void *data) { if (!data) return; -#if defined(HAVE_D3D8) - /* empty */ -#elif defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DVertexDeclaration9_Release((LPDIRECT3DVERTEXDECLARATION)data); -#else + + switch (d3d_common_api) { - LPDIRECT3DVERTEXDECLARATION vertex_decl = - (LPDIRECT3DVERTEXDECLARATION)data; - if (vertex_decl) - vertex_decl->Release(); - } + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + { + LPDIRECT3DVERTEXDECLARATION vertex_decl = + (LPDIRECT3DVERTEXDECLARATION)data; + if (vertex_decl) + vertex_decl->Release(); + } +#else + IDirect3DVertexDeclaration9_Release((LPDIRECT3DVERTEXDECLARATION)data); #endif +#endif + break; + case D3D_COMM_D3D8: + case D3D_COMM_NONE: + break; + } } bool d3d_vertex_declaration_new(LPDIRECT3DDEVICE dev, const void *vertex_data, void **decl_data) { + switch (d3d_common_api) + { + case D3D_COMM_D3D9: #ifdef HAVE_D3D9 - const D3DVERTEXELEMENT *vertex_elements = (const D3DVERTEXELEMENT*)vertex_data; - LPDIRECT3DVERTEXDECLARATION **vertex_decl = (LPDIRECT3DVERTEXDECLARATION**)decl_data; + { + const D3DVERTEXELEMENT *vertex_elements = (const D3DVERTEXELEMENT*)vertex_data; + LPDIRECT3DVERTEXDECLARATION **vertex_decl = (LPDIRECT3DVERTEXDECLARATION**)decl_data; #if defined(__cplusplus) - if (SUCCEEDED(dev->CreateVertexDeclaration(vertex_elements, (IDirect3DVertexDeclaration9**)vertex_decl))) - return true; + if (SUCCEEDED(dev->CreateVertexDeclaration(vertex_elements, (IDirect3DVertexDeclaration9**)vertex_decl))) + return true; #else - if (SUCCEEDED(IDirect3DDevice9_CreateVertexDeclaration(dev, vertex_elements, (IDirect3DVertexDeclaration9**)vertex_decl))) - return true; + if (SUCCEEDED(IDirect3DDevice9_CreateVertexDeclaration(dev, vertex_elements, (IDirect3DVertexDeclaration9**)vertex_decl))) + return true; #endif + } +#endif + break; + case D3D_COMM_D3D8: + case D3D_COMM_NONE: + break; + } -#endif return false; } @@ -633,33 +863,48 @@ LPDIRECT3DVERTEXBUFFER d3d_vertex_buffer_new(LPDIRECT3DDEVICE dev, unsigned length, unsigned usage, unsigned fvf, D3DPOOL pool, void *handle) { - HRESULT hr; - LPDIRECT3DVERTEXBUFFER buf; + HRESULT hr = S_OK; + LPDIRECT3DVERTEXBUFFER buf = NULL; -#ifndef _XBOX - if (usage == 0) + switch (d3d_common_api) { -#if defined(HAVE_D3D9) + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 + if (usage == 0) + { +#ifndef _XBOX #ifdef __cplusplus - if (dev->GetSoftwareVertexProcessing()) - usage = D3DUSAGE_SOFTWAREPROCESSING; + if (dev->GetSoftwareVertexProcessing()) + usage = D3DUSAGE_SOFTWAREPROCESSING; #else - if (IDirect3DDevice9_GetSoftwareVertexProcessing(dev)) - usage = D3DUSAGE_SOFTWAREPROCESSING; + if (IDirect3DDevice9_GetSoftwareVertexProcessing(dev)) + usage = D3DUSAGE_SOFTWAREPROCESSING; #endif #endif - } + } + +#ifdef __cplusplus + hr = dev->CreateVertexBuffer(length, usage, fvf, pool, &buf, NULL); +#else + hr = IDirect3DDevice9_CreateVertexBuffer(dev, length, usage, fvf, pool, + &buf, NULL); #endif -#if defined(HAVE_D3D9) && !defined(__cplusplus) - hr = IDirect3DDevice9_CreateVertexBuffer(dev, length, usage, fvf, pool, - &buf, NULL); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - hr = IDirect3DDevice8_CreateVertexBuffer(dev, length, usage, fvf, pool, - &buf); -#else - hr = dev->CreateVertexBuffer(length, usage, fvf, pool, &buf, NULL); #endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + hr = dev->CreateVertexBuffer(length, usage, fvf, pool, &buf, NULL); +#else + hr = IDirect3DDevice8_CreateVertexBuffer(dev, length, usage, fvf, pool, + &buf); +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } if (FAILED(hr)) return NULL; @@ -671,13 +916,33 @@ void d3d_vertex_buffer_unlock(void *vertbuf_ptr) { LPDIRECT3DVERTEXBUFFER vertbuf = (LPDIRECT3DVERTEXBUFFER)vertbuf_ptr; -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DVertexBuffer9_Unlock(vertbuf); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - IDirect3DVertexBuffer8_Unlock(vertbuf); + if (!vertbuf) + return; + + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + vertbuf->Unlock(); #else - vertbuf->Unlock(); + IDirect3DVertexBuffer9_Unlock(vertbuf); #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + vertbuf->Unlock(); +#else + IDirect3DVertexBuffer8_Unlock(vertbuf); +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } + } void *d3d_vertex_buffer_lock(void *vertbuf_ptr) @@ -685,13 +950,29 @@ void *d3d_vertex_buffer_lock(void *vertbuf_ptr) void *buf = NULL; LPDIRECT3DVERTEXBUFFER vertbuf = (LPDIRECT3DVERTEXBUFFER)vertbuf_ptr; -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DVertexBuffer9_Lock(vertbuf, 0, 0, &buf, 0); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - IDirect3DVertexBuffer8_Lock(vertbuf, 0, 0, (BYTE**)&buf, 0); + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + vertbuf->Lock(0, 0, &buf, 0); #else - vertbuf->Lock(0, 0, &buf, 0); + IDirect3DVertexBuffer9_Lock(vertbuf, 0, 0, &buf, 0); #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + vertbuf->Lock(0, 0, &buf, 0); +#else + IDirect3DVertexBuffer8_Lock(vertbuf, 0, 0, (BYTE**)&buf, 0); +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } if (!buf) return NULL; @@ -701,27 +982,46 @@ void *d3d_vertex_buffer_lock(void *vertbuf_ptr) void d3d_vertex_buffer_free(void *vertex_data, void *vertex_declaration) { - if (vertex_data) + switch (d3d_common_api) { - LPDIRECT3DVERTEXBUFFER buf = (LPDIRECT3DVERTEXBUFFER)vertex_data; -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DVertexBuffer9_Release(buf); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - IDirect3DVertexBuffer8_Release(buf); -#else - buf->Release(); -#endif - buf = NULL; - } - + case D3D_COMM_D3D9: #ifdef HAVE_D3D9 - if (vertex_declaration) - { - LPDIRECT3DVERTEXDECLARATION vertex_decl = (LPDIRECT3DVERTEXDECLARATION)vertex_declaration; - d3d_vertex_declaration_free(vertex_decl); - vertex_decl = NULL; - } + if (vertex_data) + { + LPDIRECT3DVERTEXBUFFER buf = (LPDIRECT3DVERTEXBUFFER)vertex_data; +#ifdef __cplusplus + buf->Release(); +#else + IDirect3DVertexBuffer9_Release(buf); #endif + buf = NULL; + } + + if (vertex_declaration) + { + LPDIRECT3DVERTEXDECLARATION vertex_decl = (LPDIRECT3DVERTEXDECLARATION)vertex_declaration; + d3d_vertex_declaration_free(vertex_decl); + vertex_decl = NULL; + } +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 + if (vertex_data) + { + LPDIRECT3DVERTEXBUFFER buf = (LPDIRECT3DVERTEXBUFFER)vertex_data; +#ifdef __cplusplus + buf->Release(); +#else + IDirect3DVertexBuffer8_Release(buf); +#endif + buf = NULL; + } +#endif + break; + case D3D_COMM_NONE: + break; + } } void d3d_set_stream_source(LPDIRECT3DDEVICE dev, unsigned stream_no, @@ -729,15 +1029,35 @@ void d3d_set_stream_source(LPDIRECT3DDEVICE dev, unsigned stream_no, unsigned stride) { LPDIRECT3DVERTEXBUFFER stream_vertbuf = (LPDIRECT3DVERTEXBUFFER)stream_vertbuf_ptr; -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DDevice9_SetStreamSource(dev, stream_no, stream_vertbuf, - offset_bytes, - stride); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - IDirect3DDevice8_SetStreamSource(dev, stream_no, stream_vertbuf, stride); + + if (!stream_vertbuf) + return; + + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + dev->SetStreamSource(stream_no, stream_vertbuf, offset_bytes, stride); #else - dev->SetStreamSource(stream_no, stream_vertbuf, offset_bytes, stride); + IDirect3DDevice9_SetStreamSource(dev, stream_no, stream_vertbuf, + offset_bytes, + stride); #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + dev->SetStreamSource(stream_no, stream_vertbuf, offset_bytes, stride); +#else + IDirect3DDevice8_SetStreamSource(dev, stream_no, stream_vertbuf, stride); +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } } bool d3d_device_create_offscreen_plain_surface( @@ -749,142 +1069,281 @@ bool d3d_device_create_offscreen_plain_surface( void **surf_data, void *data) { -#if defined(HAVE_D3D9) && !defined(_XBOX) + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifndef _XBOX +#ifdef HAVE_D3D9 #ifdef __cplusplus - if (SUCCEEDED(dev->CreateOffscreenPlainSurface(width, height, - (D3DFORMAT)format, (D3DPOOL)pool, - (LPDIRECT3DSURFACE*)surf_data, - (HANDLE*)data))) - return true; + if (SUCCEEDED(dev->CreateOffscreenPlainSurface(width, height, + (D3DFORMAT)format, (D3DPOOL)pool, + (LPDIRECT3DSURFACE*)surf_data, + (HANDLE*)data))) + return true; #else - if (SUCCEEDED(IDirect3DDevice9_CreateOffscreenPlainSurface(dev, - width, height, - (D3DFORMAT)format, (D3DPOOL)pool, - (LPDIRECT3DSURFACE*)surf_data, - (HANDLE*)data))) - return true; + if (SUCCEEDED(IDirect3DDevice9_CreateOffscreenPlainSurface(dev, + width, height, + (D3DFORMAT)format, (D3DPOOL)pool, + (LPDIRECT3DSURFACE*)surf_data, + (HANDLE*)data))) + return true; #endif #endif +#endif + break; + case D3D_COMM_D3D8: + case D3D_COMM_NONE: + break; + } + return false; } -#ifndef _XBOX360 -/* XBox 360 has no fixed-function pipeline. */ static void d3d_set_texture_stage_state(LPDIRECT3DDEVICE dev, unsigned sampler, unsigned type, unsigned value) { -#if defined(HAVE_D3D9) && !defined(__cplusplus) - if (IDirect3DDevice9_SetTextureStageState(dev, sampler, (D3DTEXTURESTAGESTATETYPE)type, value) != D3D_OK) - RARCH_ERR("SetTextureStageState call failed, sampler: %d, value: %d, type: %d\n", sampler, value, type); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - if (IDirect3DDevice8_SetTextureStageState(dev, sampler, (D3DTEXTURESTAGESTATETYPE)type, value) != D3D_OK) - RARCH_ERR("SetTextureStageState call failed, sampler: %d, value: %d, type: %d\n", sampler, value, type); + switch (d3d_common_api) + { + case D3D_COMM_D3D9: + /* XBox 360 has no fixed-function pipeline. */ +#ifndef _XBOX +#ifdef HAVE_D3D9 +#ifdef __cplusplus + if (dev->SetTextureStageState(sampler, (D3DTEXTURESTAGESTATETYPE)type, value) != D3D_OK) + RARCH_ERR("SetTextureStageState call failed, sampler: %d, value: %d, type: %d\n", sampler, value, type); #else - if (dev->SetTextureStageState(sampler, (D3DTEXTURESTAGESTATETYPE)type, value) != D3D_OK) - RARCH_ERR("SetTextureStageState call failed, sampler: %d, value: %d, type: %d\n", sampler, value, type); + if (IDirect3DDevice9_SetTextureStageState(dev, sampler, (D3DTEXTURESTAGESTATETYPE)type, value) != D3D_OK) + RARCH_ERR("SetTextureStageState call failed, sampler: %d, value: %d, type: %d\n", sampler, value, type); #endif +#endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + if (dev->SetTextureStageState(sampler, (D3DTEXTURESTAGESTATETYPE)type, value) != D3D_OK) + RARCH_ERR("SetTextureStageState call failed, sampler: %d, value: %d, type: %d\n", sampler, value, type); +#else + if (IDirect3DDevice8_SetTextureStageState(dev, sampler, (D3DTEXTURESTAGESTATETYPE)type, value) != D3D_OK) + RARCH_ERR("SetTextureStageState call failed, sampler: %d, value: %d, type: %d\n", sampler, value, type); +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } } -#endif void d3d_set_sampler_address_u(LPDIRECT3DDEVICE dev, unsigned sampler, unsigned value) { -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DDevice9_SetSamplerState(dev, sampler, D3DSAMP_ADDRESSU, value); -#elif defined(HAVE_D3D8) - d3d_set_texture_stage_state(dev, sampler, D3DTSS_ADDRESSU, value); + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + dev->SetSamplerState(sampler, D3DSAMP_ADDRESSU, value); #else - dev->SetSamplerState(sampler, D3DSAMP_ADDRESSU, value); + IDirect3DDevice9_SetSamplerState(dev, sampler, D3DSAMP_ADDRESSU, value); #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 + d3d_set_texture_stage_state(dev, sampler, D3DTSS_ADDRESSU, value); +#endif + break; + case D3D_COMM_NONE: + break; + } } void d3d_set_sampler_address_v(LPDIRECT3DDEVICE dev, unsigned sampler, unsigned value) { -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DDevice9_SetSamplerState(dev, sampler, D3DSAMP_ADDRESSV, value); -#elif defined(HAVE_D3D8) - d3d_set_texture_stage_state(dev, sampler, D3DTSS_ADDRESSV, value); + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + dev->SetSamplerState(sampler, D3DSAMP_ADDRESSV, value); #else - dev->SetSamplerState(sampler, D3DSAMP_ADDRESSV, value); + IDirect3DDevice9_SetSamplerState(dev, sampler, D3DSAMP_ADDRESSV, value); #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 + d3d_set_texture_stage_state(dev, sampler, D3DTSS_ADDRESSV, value); +#endif + break; + case D3D_COMM_NONE: + break; + } } void d3d_set_sampler_minfilter(LPDIRECT3DDEVICE dev, unsigned sampler, unsigned value) { -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DDevice9_SetSamplerState(dev, sampler, D3DSAMP_MINFILTER, value); -#elif defined(HAVE_D3D8) - d3d_set_texture_stage_state(dev, sampler, D3DTSS_MINFILTER, value); + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + dev->SetSamplerState(sampler, D3DSAMP_MINFILTER, value); #else - dev->SetSamplerState(sampler, D3DSAMP_MINFILTER, value); + IDirect3DDevice9_SetSamplerState(dev, sampler, D3DSAMP_MINFILTER, value); #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 + d3d_set_texture_stage_state(dev, sampler, D3DTSS_MINFILTER, value); +#endif + break; + case D3D_COMM_NONE: + break; + } } void d3d_set_sampler_magfilter(LPDIRECT3DDEVICE dev, unsigned sampler, unsigned value) { -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DDevice9_SetSamplerState(dev, sampler, D3DSAMP_MAGFILTER, value); -#elif defined(HAVE_D3D8) - d3d_set_texture_stage_state(dev, sampler, D3DTSS_MAGFILTER, value); + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + dev->SetSamplerState(sampler, D3DSAMP_MAGFILTER, value); #else - dev->SetSamplerState(sampler, D3DSAMP_MAGFILTER, value); + IDirect3DDevice9_SetSamplerState(dev, sampler, D3DSAMP_MAGFILTER, value); #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 + d3d_set_texture_stage_state(dev, sampler, D3DTSS_MAGFILTER, value); +#endif + break; + case D3D_COMM_NONE: + break; + } } void d3d_set_sampler_mipfilter(LPDIRECT3DDEVICE dev, unsigned sampler, unsigned value) { -#if defined(HAVE_D3D9) - IDirect3DDevice9_SetSamplerState(dev, sampler, D3DSAMP_MIPFILTER, value); + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 + IDirect3DDevice9_SetSamplerState(dev, sampler, D3DSAMP_MIPFILTER, value); #endif + break; + case D3D_COMM_D3D8: + case D3D_COMM_NONE: + break; + } } bool d3d_begin_scene(LPDIRECT3DDEVICE dev) { -#if defined(HAVE_D3D9) && !defined(__cplusplus) + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + if (FAILED(dev->BeginScene())) + return false; +#else #if defined(_XBOX) - IDirect3DDevice9_BeginScene(dev); + IDirect3DDevice9_BeginScene(dev); #else - if (FAILED(IDirect3DDevice9_BeginScene(dev))) - return false; + if (FAILED(IDirect3DDevice9_BeginScene(dev))) + return false; #endif -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - if (FAILED(IDirect3DDevice8_BeginScene(dev))) - return false; -#elif defined(_XBOX) - dev->BeginScene(); +#endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus +#ifdef _XBOX + dev->BeginScene(); #else - if (FAILED(dev->BeginScene())) - return false; + if (FAILED(dev->BeginScene())) + return false; #endif +#else +#ifdef _XBOX + IDirect3DDevice8_BeginScene(dev); +#else + if (FAILED(IDirect3DDevice8_BeginScene(dev))) + return false; +#endif +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } return true; } void d3d_end_scene(LPDIRECT3DDEVICE dev) { -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DDevice9_EndScene(dev); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - IDirect3DDevice8_EndScene(dev); + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + dev->EndScene(); #else - dev->EndScene(); + IDirect3DDevice9_EndScene(dev); #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + dev->EndScene(); +#else + IDirect3DDevice8_EndScene(dev); +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } } static void d3d_draw_primitive_internal(LPDIRECT3DDEVICE dev, D3DPRIMITIVETYPE type, unsigned start, unsigned count) { -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DDevice9_DrawPrimitive(dev, type, start, count); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - IDirect3DDevice8_DrawPrimitive(dev, type, start, count); + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + dev->DrawPrimitive(type, start, count); #else - dev->DrawPrimitive(type, start, count); + IDirect3DDevice9_DrawPrimitive(dev, type, start, count); #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + dev->DrawPrimitive(type, start, count); +#else + IDirect3DDevice8_DrawPrimitive(dev, type, start, count); +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } } void d3d_draw_primitive(LPDIRECT3DDEVICE dev, @@ -901,34 +1360,58 @@ void d3d_clear(LPDIRECT3DDEVICE dev, unsigned count, const D3DRECT *rects, unsigned flags, D3DCOLOR color, float z, unsigned stencil) { -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DDevice9_Clear(dev, count, rects, flags, - color, z, stencil); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - IDirect3DDevice8_Clear(dev, count, rects, flags, - color, z, stencil); + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + dev->Clear(count, rects, flags, color, z, stencil); #else - dev->Clear(count, rects, flags, color, z, stencil); + IDirect3DDevice9_Clear(dev, count, rects, flags, + color, z, stencil); #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + dev->Clear(count, rects, flags, color, z, stencil); +#else + IDirect3DDevice8_Clear(dev, count, rects, flags, + color, z, stencil); +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } } bool d3d_device_get_render_target_data(LPDIRECT3DDEVICE dev, void *_src, void *_dst) { -#if defined(HAVE_D3D9) LPDIRECT3DSURFACE src = (LPDIRECT3DSURFACE)_src; LPDIRECT3DSURFACE dst = (LPDIRECT3DSURFACE)_dst; + switch (d3d_common_api) + { + case D3D_COMM_D3D9: #ifndef _XBOX +#ifdef HAVE_D3D9 #ifdef __cplusplus - if (SUCCEEDED(dev->GetRenderTargetData(src, dst))) - return true; + if (SUCCEEDED(dev->GetRenderTargetData(src, dst))) + return true; #else - if (SUCCEEDED(IDirect3DDevice9_GetRenderTargetData(dev, src, dst))) - return true; + if (SUCCEEDED(IDirect3DDevice9_GetRenderTargetData(dev, src, dst))) + return true; #endif #endif #endif + break; + case D3D_COMM_D3D8: + case D3D_COMM_NONE: + break; + } return false; } @@ -939,27 +1422,38 @@ bool d3d_device_get_render_target(LPDIRECT3DDEVICE dev, if (!dev) return false; -#if defined(HAVE_D3D9) + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 #ifdef __cplusplus - if (SUCCEEDED(dev->GetRenderTarget(idx, - (LPDIRECT3DSURFACE*)data))) - return true; + if (SUCCEEDED(dev->GetRenderTarget(idx, + (LPDIRECT3DSURFACE*)data))) + return true; #else - if (SUCCEEDED(IDirect3DDevice9_GetRenderTarget(dev, - idx, (LPDIRECT3DSURFACE*)data))) - return true; + if (SUCCEEDED(IDirect3DDevice9_GetRenderTarget(dev, + idx, (LPDIRECT3DSURFACE*)data))) + return true; #endif -#elif defined(HAVE_D3D8) +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 #ifdef __cplusplus - if (SUCCEEDED(dev->GetRenderTarget( - (LPDIRECT3DSURFACE*)data))) - return true; + if (SUCCEEDED(dev->GetRenderTarget( + (LPDIRECT3DSURFACE*)data))) + return true; #else - if (SUCCEEDED(IDirect3DDevice8_GetRenderTarget(dev, - (LPDIRECT3DSURFACE*)data))) - return true; + if (SUCCEEDED(IDirect3DDevice8_GetRenderTarget(dev, + (LPDIRECT3DSURFACE*)data))) + return true; #endif #endif + break; + case D3D_COMM_NONE: + break; + } + return false; } @@ -968,34 +1462,66 @@ bool d3d_lock_rectangle(LPDIRECT3DTEXTURE tex, unsigned level, D3DLOCKED_RECT *lock_rect, RECT *rect, unsigned rectangle_height, unsigned flags) { -#if defined(HAVE_D3D9) && !defined(__cplusplus) + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + if (FAILED(tex->LockRect(level, lock_rect, rect, flags))) + return false; +#else #ifdef _XBOX - IDirect3DTexture9_LockRect(tex, level, lock_rect, (const RECT*)rect, flags); + IDirect3DTexture9_LockRect(tex, level, lock_rect, (const RECT*)rect, flags); #else - if (IDirect3DTexture9_LockRect(tex, level, lock_rect, (const RECT*)rect, flags) != D3D_OK) - return false; + if (IDirect3DTexture9_LockRect(tex, level, lock_rect, (const RECT*)rect, flags) != D3D_OK) + return false; #endif -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - if (IDirect3DTexture8_LockRect(tex, level, lock_rect, rect, flags) != D3D_OK) - return false; +#endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + if (FAILED(tex->LockRect(level, lock_rect, rect, flags))) + return false; #else - if (FAILED(tex->LockRect(level, lock_rect, rect, flags))) - return false; + if (IDirect3DTexture8_LockRect(tex, level, lock_rect, rect, flags) != D3D_OK) + return false; #endif +#endif + break; + case D3D_COMM_NONE: + break; + } + return true; } void d3d_unlock_rectangle(LPDIRECT3DTEXTURE tex) { -#ifdef _XBOX - D3DTexture_UnlockRect(tex, 0); -#elif defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DTexture9_UnlockRect(tex, 0); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - IDirect3DTexture8_UnlockRect(tex, 0); + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + tex->UnlockRect(0); #else - tex->UnlockRect(0); + IDirect3DTexture9_UnlockRect(tex, 0); #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + tex->UnlockRect(0); +#else + IDirect3DTexture8_UnlockRect(tex, 0); +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } } void d3d_lock_rectangle_clear(LPDIRECT3DTEXTURE tex, @@ -1011,136 +1537,241 @@ void d3d_lock_rectangle_clear(LPDIRECT3DTEXTURE tex, void d3d_set_viewports(LPDIRECT3DDEVICE dev, D3DVIEWPORT *vp) { -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DDevice9_SetViewport(dev, vp); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - IDirect3DDevice8_SetViewport(dev, vp); + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + dev->SetViewport(vp); #else - dev->SetViewport(vp); + IDirect3DDevice9_SetViewport(dev, vp); #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + dev->SetViewport(vp); +#else + IDirect3DDevice8_SetViewport(dev, vp); +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } } void d3d_set_texture(LPDIRECT3DDEVICE dev, unsigned sampler, void *tex_data) { LPDIRECT3DTEXTURE tex = (LPDIRECT3DTEXTURE)tex_data; -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DDevice9_SetTexture(dev, sampler, (IDirect3DBaseTexture9*)tex); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - IDirect3DDevice8_SetTexture(dev, sampler, (IDirect3DBaseTexture8*)tex); + + if (!tex) + return; + + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + dev->SetTexture(sampler, tex); #else - dev->SetTexture(sampler, tex); + IDirect3DDevice9_SetTexture(dev, sampler, (IDirect3DBaseTexture9*)tex); #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + dev->SetTexture(sampler, tex); +#else + IDirect3DDevice8_SetTexture(dev, sampler, (IDirect3DBaseTexture8*)tex); +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } } void d3d_free_vertex_shader(LPDIRECT3DDEVICE dev, void *data) { + switch (d3d_common_api) + { + case D3D_COMM_D3D9: #ifdef HAVE_D3D9 - IDirect3DVertexShader9 *vs = (IDirect3DVertexShader9*)data; - if (!dev || !vs) - return; + { + IDirect3DVertexShader9 *vs = (IDirect3DVertexShader9*)data; + if (!dev || !vs) + return; #ifdef __cplusplus - vs->Release(); + vs->Release(); #else - IDirect3DVertexShader9_Release(vs); + IDirect3DVertexShader9_Release(vs); #endif + } #endif + break; + case D3D_COMM_D3D8: + case D3D_COMM_NONE: + break; + } } void d3d_free_pixel_shader(LPDIRECT3DDEVICE dev, void *data) { + switch (d3d_common_api) + { + case D3D_COMM_D3D9: #ifdef HAVE_D3D9 - IDirect3DPixelShader9 *ps = (IDirect3DPixelShader9*)data; - if (!dev || !ps) - return; + { + IDirect3DPixelShader9 *ps = (IDirect3DPixelShader9*)data; + if (!dev || !ps) + return; #ifdef __cplusplus - ps->Release(); + ps->Release(); #else - IDirect3DPixelShader9_Release(ps); + IDirect3DPixelShader9_Release(ps); #endif + } #endif + break; + case D3D_COMM_D3D8: + case D3D_COMM_NONE: + break; + } } bool d3d_create_vertex_shader(LPDIRECT3DDEVICE dev, const DWORD *a, void **b) { -#ifdef HAVE_D3D9 if (!dev) return false; + + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 #if defined(__cplusplus) - if (dev->CreateVertexShader(a, (IDirect3DVertexShader9**)b) != D3D_OK) - return false; + if (dev->CreateVertexShader(a, (IDirect3DVertexShader9**)b) == D3D_OK) + return true; #else - if (IDirect3DDevice9_CreateVertexShader(dev, a, - (LPDIRECT3DVERTEXSHADER*)b) != D3D_OK) - return false; + if (IDirect3DDevice9_CreateVertexShader(dev, a, + (LPDIRECT3DVERTEXSHADER*)b) == D3D_OK) + return true; #endif - return true; -#else +#endif + break; + case D3D_COMM_D3D8: + break; + case D3D_COMM_NONE: + break; + } + return false; -#endif } bool d3d_create_pixel_shader(LPDIRECT3DDEVICE dev, const DWORD *a, void **b) { -#ifdef HAVE_D3D9 if (!dev) return false; -#if defined(__cplusplus) - if (dev->CreatePixelShader(a, (IDirect3DPixelShader9**)b) != D3D_OK) - return false; + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + if (dev->CreatePixelShader(a, (IDirect3DPixelShader9**)b) == D3D_OK) + return true; #else - if (IDirect3DDevice9_CreatePixelShader(dev, a, - (LPDIRECT3DPIXELSHADER*)b) != D3D_OK) - return false; + if (IDirect3DDevice9_CreatePixelShader(dev, a, + (LPDIRECT3DPIXELSHADER*)b) == D3D_OK) + return true; #endif - return true; -#else +#endif + break; + case D3D_COMM_D3D8: + case D3D_COMM_NONE: + break; + } + return false; -#endif } bool d3d_set_pixel_shader(LPDIRECT3DDEVICE dev, void *data) { + switch (d3d_common_api) + { + case D3D_COMM_D3D9: #ifdef HAVE_D3D9 - LPDIRECT3DPIXELSHADER d3dps = (LPDIRECT3DPIXELSHADER)data; - if (!dev || !d3dps) - return false; + { + LPDIRECT3DPIXELSHADER d3dps = (LPDIRECT3DPIXELSHADER)data; + if (!dev || !d3dps) + return false; #if defined(__cplusplus) - if (dev->SetPixelShader(d3dps) == D3D_OK) - return true; + if (dev->SetPixelShader(d3dps) == D3D_OK) + return true; #else #ifdef _XBOX - /* Returns void on Xbox */ - IDirect3DDevice9_SetPixelShader(dev, d3dps); - return true; + /* Returns void on Xbox */ + IDirect3DDevice9_SetPixelShader(dev, d3dps); + return true; #else - if (IDirect3DDevice9_SetPixelShader(dev, d3dps) == D3D_OK) - return true; + if (IDirect3DDevice9_SetPixelShader(dev, d3dps) == D3D_OK) + return true; #endif #endif + } #endif + break; + case D3D_COMM_D3D8: + case D3D_COMM_NONE: + break; + } + return false; } bool d3d_set_vertex_shader(LPDIRECT3DDEVICE dev, unsigned index, void *data) { -#if defined(HAVE_D3D8) && !defined(__cplusplus) - if (IDirect3DDevice8_SetVertexShader(dev, index) != D3D_OK) - return false; -#elif defined(HAVE_D3D9) && !defined(__cplusplus) - LPDIRECT3DVERTEXSHADER shader = (LPDIRECT3DVERTEXSHADER)data; + switch (d3d_common_api) + { + case D3D_COMM_D3D9: + { +#ifdef HAVE_D3D9 + LPDIRECT3DVERTEXSHADER shader = (LPDIRECT3DVERTEXSHADER)data; +#ifdef __cplusplus + if (dev->SetVertexShader(shader) != D3D_OK) + return false; +#else #ifdef _XBOX - IDirect3DDevice9_SetVertexShader(dev, shader); + IDirect3DDevice9_SetVertexShader(dev, shader); #else - if (IDirect3DDevice9_SetVertexShader(dev, shader) != D3D_OK) - return false; + if (IDirect3DDevice9_SetVertexShader(dev, shader) != D3D_OK) + return false; #endif +#endif +#endif + } + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 + { +#ifdef __cplusplus + LPDIRECT3DVERTEXSHADER shader = (LPDIRECT3DVERTEXSHADER)data; + if (dev->SetVertexShader(shader) != D3D_OK) + return false; #else - LPDIRECT3DVERTEXSHADER shader = (LPDIRECT3DVERTEXSHADER)data; - if (dev->SetVertexShader(shader) != D3D_OK) - return false; + if (IDirect3DDevice8_SetVertexShader(dev, index) != D3D_OK) + return false; #endif + } +#endif + break; + case D3D_COMM_NONE: + break; + } + return true; } @@ -1148,21 +1779,37 @@ bool d3d_set_vertex_shader_constantf(LPDIRECT3DDEVICE dev, UINT start_register,const float* constant_data, unsigned vector4f_count) { + switch (d3d_common_api) + { + case D3D_COMM_D3D9: #if defined(HAVE_D3D9) #ifdef __cplusplus - return (dev->SetVertexShaderConstantF( - start_register, constant_data, vector4f_count) == D3D_OK); +#ifdef _XBOX + dev->SetVertexShaderConstantF( + start_register, constant_data, vector4f_count); +#else + if (dev->SetVertexShaderConstantF( + start_register, constant_data, vector4f_count) == D3D_OK) + return true; +#endif #else #ifdef _XBOX - IDirect3DDevice9_SetVertexShaderConstantF(dev, - start_register, constant_data, vector4f_count); - return true; + IDirect3DDevice9_SetVertexShaderConstantF(dev, + start_register, constant_data, vector4f_count); + return true; #else - return (IDirect3DDevice9_SetVertexShaderConstantF(dev, - start_register, constant_data, vector4f_count) == D3D_OK); + if (IDirect3DDevice9_SetVertexShaderConstantF(dev, + start_register, constant_data, vector4f_count) == D3D_OK) + return true; #endif #endif #endif + break; + case D3D_COMM_D3D8: + case D3D_COMM_NONE: + break; + } + return false; } @@ -1187,21 +1834,39 @@ bool d3d_get_render_state(void *data, D3DRENDERSTATETYPE state, DWORD *value) if (!dev) return false; -#if defined(HAVE_D3D9) && !defined(__cplusplus) + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + if (dev->GetRenderState(state, value) == D3D_OK) + return true; +#else #ifdef _XBOX - IDirect3DDevice9_GetRenderState(dev, state, value); - return true; + IDirect3DDevice9_GetRenderState(dev, state, value); + return true; #else - if (IDirect3DDevice9_GetRenderState(dev, state, value) == D3D_OK) - return true; + if (IDirect3DDevice9_GetRenderState(dev, state, value) == D3D_OK) + return true; #endif -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - if (IDirect3DDevice8_GetRenderState(dev, state, value) == D3D_OK) - return true; +#endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + if (dev->GetRenderState(state, value) == D3D_OK) + return true; #else - if (dev->GetRenderState(state, value) == D3D_OK) - return true; + if (IDirect3DDevice8_GetRenderState(dev, state, value) == D3D_OK) + return true; #endif +#endif + break; + case D3D_COMM_NONE: + break; + } + return false; } @@ -1212,13 +1877,29 @@ void d3d_set_render_state(void *data, D3DRENDERSTATETYPE state, DWORD value) if (!dev) return; -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DDevice9_SetRenderState(dev, state, value); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - IDirect3DDevice8_SetRenderState(dev, state, value); + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + dev->SetRenderState(state, value); #else - dev->SetRenderState(state, value); + IDirect3DDevice9_SetRenderState(dev, state, value); #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + dev->SetRenderState(state, value); +#else + IDirect3DDevice8_SetRenderState(dev, state, value); +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } } void d3d_enable_blend_func(void *data) @@ -1237,13 +1918,30 @@ void d3d_device_set_render_target(LPDIRECT3DDEVICE dev, unsigned idx, void *data) { LPDIRECT3DSURFACE surf = (LPDIRECT3DSURFACE)data; -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DDevice9_SetRenderTarget(dev, idx, surf); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - IDirect3DDevice8_SetRenderTarget(dev, surf, NULL); + + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + dev->SetRenderTarget(idx, surf); #else - dev->SetRenderTarget(idx, surf); + IDirect3DDevice9_SetRenderTarget(dev, idx, surf); #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + dev->SetRenderTarget(idx, surf); +#else + IDirect3DDevice8_SetRenderTarget(dev, surf, NULL); +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } } void d3d_enable_alpha_blend_texture_func(void *data) @@ -1253,31 +1951,41 @@ void d3d_enable_alpha_blend_texture_func(void *data) if (!dev) return; -#ifndef _XBOX360 /* Also blend the texture with the set alpha value. */ d3d_set_texture_stage_state(dev, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); d3d_set_texture_stage_state(dev, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); d3d_set_texture_stage_state(dev, 0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); -#endif } void d3d_frame_postprocess(void *data) { -#if defined(_XBOX1) - global_t *global = global_get_ptr(); + switch (d3d_common_api) + { + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 + { +#if defined(_XBOX) + global_t *global = global_get_ptr(); #ifdef __cplusplus - LPDIRECT3DDEVICE dev = (LPDIRECT3DDEVICE)data; - if (!dev) - return; + LPDIRECT3DDEVICE dev = (LPDIRECT3DDEVICE)data; + if (!dev) + return; - dev->SetFlickerFilter(global->console.screen.flicker_filter_index); - dev->SetSoftDisplayFilter(global->console.softfilter_enable); + dev->SetFlickerFilter(global->console.screen.flicker_filter_index); + dev->SetSoftDisplayFilter(global->console.softfilter_enable); #else - D3DDevice_SetFlickerFilter(global->console.screen.flicker_filter_index); - D3DDevice_SetSoftDisplayFilter(global->console.softfilter_enable); + D3DDevice_SetFlickerFilter(global->console.screen.flicker_filter_index); + D3DDevice_SetSoftDisplayFilter(global->console.softfilter_enable); #endif #endif + } +#endif + break; + case D3D_COMM_D3D9: + case D3D_COMM_NONE: + break; + } } void d3d_disable_blend_func(void *data) @@ -1292,43 +2000,95 @@ void d3d_disable_blend_func(void *data) void d3d_set_vertex_declaration(void *data, void *vertex_data) { -#if defined(HAVE_D3D9) LPDIRECT3DDEVICE dev = (LPDIRECT3DDEVICE)data; if (!dev) return; + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#if defined(HAVE_D3D9) #ifdef __cplusplus - dev->SetVertexDeclaration((LPDIRECT3DVERTEXDECLARATION)vertex_data); + dev->SetVertexDeclaration((LPDIRECT3DVERTEXDECLARATION)vertex_data); #else - IDirect3DDevice9_SetVertexDeclaration(dev, (LPDIRECT3DVERTEXDECLARATION)vertex_data); + IDirect3DDevice9_SetVertexDeclaration(dev, (LPDIRECT3DVERTEXDECLARATION)vertex_data); #endif #endif + break; + case D3D_COMM_D3D8: + case D3D_COMM_NONE: + break; + } } static bool d3d_reset_internal(LPDIRECT3DDEVICE dev, D3DPRESENT_PARAMETERS *d3dpp ) { -#if defined(HAVE_D3D9) && !defined(__cplusplus) - return (IDirect3DDevice9_Reset(dev, d3dpp) == D3D_OK); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - return (IDirect3DDevice8_Reset(dev, d3dpp) == D3D_OK); + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + if ((dev->Reset(d3dpp) == D3D_OK)) + return true; #else - return (dev->Reset(d3dpp) == D3D_OK); + if (IDirect3DDevice9_Reset(dev, d3dpp) == D3D_OK) + return true; #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + if ((dev->Reset(d3dpp) == D3D_OK)) + return true; +#else + if (IDirect3DDevice8_Reset(dev, d3dpp) == D3D_OK) + return true; +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } + + return false; } static HRESULT d3d_test_cooperative_level(LPDIRECT3DDEVICE dev) { -#if defined(HAVE_D3D9) && !defined(__cplusplus) && !defined(_XBOX) - return IDirect3DDevice9_TestCooperativeLevel(dev); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) && !defined(_XBOX) - return IDirect3DDevice8_TestCooperativeLevel(dev); -#elif defined(_XBOX) - return E_FAIL; + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifndef _XBOX +#ifdef HAVE_D3D9 +#ifdef __cplusplus + return dev->TestCooperativeLevel(); #else - return dev->TestCooperativeLevel(); + return IDirect3DDevice9_TestCooperativeLevel(dev); #endif +#else + break; +#endif +#endif + case D3D_COMM_D3D8: +#ifndef _XBOX +#ifdef HAVE_D3D8 +#ifdef __cplusplus + return dev->TestCooperativeLevel(); +#else + return IDirect3DDevice8_TestCooperativeLevel(dev); +#endif +#else + break; +#endif +#endif + case D3D_COMM_NONE: + break; + } + + return E_FAIL; } static bool d3d_create_device_internal(LPDIRECT3DDEVICE *dev, @@ -1338,34 +2098,58 @@ static bool d3d_create_device_internal(LPDIRECT3DDEVICE *dev, unsigned cur_mon_id, DWORD behavior_flags) { -#if defined(HAVE_D3D9) && !defined(__cplusplus) - if (SUCCEEDED(IDirect3D9_CreateDevice(d3d, - cur_mon_id, - D3DDEVTYPE_HAL, - focus_window, - behavior_flags, - d3dpp, - dev))) - return true; -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - if (SUCCEEDED(IDirect3D8_CreateDevice(d3d, - cur_mon_id, - D3DDEVTYPE_HAL, - focus_window, - behavior_flags, - d3dpp, - dev))) - return true; + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 +#ifdef __cplusplus + if (SUCCEEDED(d3d->CreateDevice( + cur_mon_id, + D3DDEVTYPE_HAL, + focus_window, + behavior_flags, + d3dpp, + dev))) + return true; #else - if (SUCCEEDED(d3d->CreateDevice( - cur_mon_id, - D3DDEVTYPE_HAL, - focus_window, - behavior_flags, - d3dpp, - dev))) - return true; + if (SUCCEEDED(IDirect3D9_CreateDevice(d3d, + cur_mon_id, + D3DDEVTYPE_HAL, + focus_window, + behavior_flags, + d3dpp, + dev))) + return true; #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 +#ifdef __cplusplus + if (SUCCEEDED(d3d->CreateDevice( + cur_mon_id, + D3DDEVTYPE_HAL, + focus_window, + behavior_flags, + d3dpp, + dev))) + return true; +#else + if (SUCCEEDED(IDirect3D8_CreateDevice(d3d, + cur_mon_id, + D3DDEVTYPE_HAL, + focus_window, + behavior_flags, + d3dpp, + dev))) + return true; +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } + return false; } @@ -1430,33 +2214,43 @@ bool d3d_device_get_backbuffer(LPDIRECT3DDEVICE dev, if (!dev) return false; -#if defined(HAVE_D3D9) + switch (d3d_common_api) + { + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 #ifdef __cplusplus - if (SUCCEEDED(dev->GetBackBuffer( - swapchain_idx, idx, - (D3DBACKBUFFER_TYPE)backbuffer_type, - (LPDIRECT3DSURFACE*)data))) - return true; + if (SUCCEEDED(dev->GetBackBuffer( + swapchain_idx, idx, + (D3DBACKBUFFER_TYPE)backbuffer_type, + (LPDIRECT3DSURFACE*)data))) + return true; #else - if (SUCCEEDED(IDirect3DDevice9_GetBackBuffer(dev, - swapchain_idx, idx, - (D3DBACKBUFFER_TYPE)backbuffer_type, - (LPDIRECT3DSURFACE*)data))) - return true; + if (SUCCEEDED(IDirect3DDevice9_GetBackBuffer(dev, + swapchain_idx, idx, + (D3DBACKBUFFER_TYPE)backbuffer_type, + (LPDIRECT3DSURFACE*)data))) + return true; #endif -#elif defined(HAVE_D3D8) +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 #ifdef __cplusplus - if (SUCCEEDED(dev->GetBackBuffer(idx, - (D3DBACKBUFFER_TYPE)backbuffer_type, - (LPDIRECT3DSURFACE*)data))) - return true; + if (SUCCEEDED(dev->GetBackBuffer(idx, + (D3DBACKBUFFER_TYPE)backbuffer_type, + (LPDIRECT3DSURFACE*)data))) + return true; #else - if (SUCCEEDED(IDirect3DDevice8_GetBackBuffer(dev, idx, - (D3DBACKBUFFER_TYPE)backbuffer_type, - (LPDIRECT3DSURFACE*)data))) - return true; + if (SUCCEEDED(IDirect3DDevice8_GetBackBuffer(dev, idx, + (D3DBACKBUFFER_TYPE)backbuffer_type, + (LPDIRECT3DSURFACE*)data))) + return true; #endif #endif + break; + case D3D_COMM_NONE: + break; + } return false; } @@ -1464,26 +2258,55 @@ bool d3d_device_get_backbuffer(LPDIRECT3DDEVICE dev, void d3d_device_free(LPDIRECT3DDEVICE dev, LPDIRECT3D pd3d) { - if (dev) + switch (d3d_common_api) { -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3DDevice9_Release(dev); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - IDirect3DDevice8_Release(dev); + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 + if (dev) + { +#ifdef __cplusplus + dev->Release(); #else - dev->Release(); + IDirect3DDevice9_Release(dev); #endif - } - if (pd3d) - { -#if defined(HAVE_D3D9) && !defined(__cplusplus) - IDirect3D9_Release(pd3d); -#elif defined(HAVE_D3D8) && !defined(__cplusplus) - IDirect3D8_Release(pd3d); + } + + if (pd3d) + { +#ifdef __cplusplus + pd3d->Release(); #else - pd3d->Release(); + IDirect3D9_Release(pd3d); #endif + } +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3D8 + + if (dev) + { +#ifdef __cplusplus + dev->Release(); +#else + IDirect3DDevice8_Release(dev); +#endif + } + + if (pd3d) + { +#if defined(__cplusplus) + pd3d->Release(); +#else + IDirect3D8_Release(pd3d); +#endif + } +#endif + break; + case D3D_COMM_NONE: + break; } + } D3DTEXTUREFILTERTYPE d3d_translate_filter(unsigned type) @@ -1591,51 +2414,70 @@ void *d3d_matrix_rotation_z(void *_pout, float angle) bool d3dx_create_font_indirect(LPDIRECT3DDEVICE dev, void *desc, void **font_data) { + switch (d3d_common_api) + { + case D3D_COMM_D3D9: #ifdef HAVE_D3DX - -#if defined(HAVE_D3D9) +#ifdef HAVE_D3D9 #ifdef __cplusplus - if (FAILED(D3DCreateFontIndirect( - dev, (D3DXFONT_DESC*)desc, font_data))) - return false; + if (SUCCEEDED(D3DCreateFontIndirect( + dev, (D3DXFONT_DESC*)desc, font_data))) + return true; #else - if (FAILED(D3DCreateFontIndirect( - dev, (D3DXFONT_DESC*)desc, - (struct ID3DXFont**)font_data))) - return false; + if (SUCCEEDED(D3DCreateFontIndirect( + dev, (D3DXFONT_DESC*)desc, + (struct ID3DXFont**)font_data))) + return true; #endif -#elif defined(HAVE_D3D8) - if (FAILED(D3DCreateFontIndirect( - dev, (CONST LOGFONT*)desc, - (struct ID3DXFont**)font_data))) - return false; #endif +#endif + break; + case D3D_COMM_D3D8: +#ifdef HAVE_D3DX +#ifdef HAVE_D3D8 + if (SUCCEEDED(D3DCreateFontIndirect( + dev, (CONST LOGFONT*)desc, + (struct ID3DXFont**)font_data))) + return true; +#endif +#endif + break; + case D3D_COMM_NONE: + break; + } - return true; -#else return false; -#endif } void d3dxbuffer_release(void *data) { + switch (d3d_common_api) + { + case D3D_COMM_D3D9: + { #ifdef HAVE_D3D9 #ifdef HAVE_D3DX #ifdef __cplusplus - ID3DXBuffer *p = (ID3DXBuffer*)data; + ID3DXBuffer *p = (ID3DXBuffer*)data; #else - LPD3DXBUFFER p = (LPD3DXBUFFER)data; + LPD3DXBUFFER p = (LPD3DXBUFFER)data; #endif - if (!p) - return; + if (!p) + return; #ifdef __cplusplus - p->Release(); + p->Release(); #else - p->lpVtbl->Release(p); + p->lpVtbl->Release(p); #endif #endif #endif + } + break; + case D3D_COMM_D3D8: + case D3D_COMM_NONE: + break; + } } bool d3dx_compile_shader( @@ -1650,24 +2492,29 @@ bool d3dx_compile_shader( void *pperrormsgs, void *ppconstanttable) { -#if defined(HAVE_D3DX) && defined(HAVE_D3D9) - if (D3DCompileShader) + switch (d3d_common_api) { - if (D3DCompileShader( - (LPCTSTR)src, - (UINT)src_data_len, - (const D3DXMACRO*)pdefines, - (LPD3DXINCLUDE)pinclude, - (LPCSTR)pfunctionname, - (LPCSTR)pprofile, - (DWORD)flags, - (LPD3DXBUFFER*)ppshader, - (LPD3DXBUFFER*)pperrormsgs, - (LPD3DXCONSTANTTABLE*)ppconstanttable) < 0) - return false; - return true; - } + case D3D_COMM_D3D9: +#if defined(HAVE_D3DX) && defined(HAVE_D3D9) + if (D3DCompileShader) + if (D3DCompileShader( + (LPCTSTR)src, + (UINT)src_data_len, + (const D3DXMACRO*)pdefines, + (LPD3DXINCLUDE)pinclude, + (LPCSTR)pfunctionname, + (LPCSTR)pprofile, + (DWORD)flags, + (LPD3DXBUFFER*)ppshader, + (LPD3DXBUFFER*)pperrormsgs, + (LPD3DXCONSTANTTABLE*)ppconstanttable) >= 0) + return true; #endif + break; + case D3D_COMM_D3D8: + case D3D_COMM_NONE: + break; + } return false; } @@ -1682,23 +2529,28 @@ bool d3dx_compile_shader_from_file( void *pperrormsgs, void *ppconstanttable) { -#if defined(HAVE_D3DX) && defined(HAVE_D3D9) - if (D3DCompileShaderFromFile) + switch (d3d_common_api) { - if (D3DCompileShaderFromFile( - (LPCTSTR)src, - (const D3DXMACRO*)pdefines, - (LPD3DXINCLUDE)pinclude, - (LPCSTR)pfunctionname, - (LPCSTR)pprofile, - (DWORD)flags, - (LPD3DXBUFFER*)ppshader, - (LPD3DXBUFFER*)pperrormsgs, - (LPD3DXCONSTANTTABLE*)ppconstanttable) < 0) - return false; - return true; - } + case D3D_COMM_D3D9: +#if defined(HAVE_D3DX) && defined(HAVE_D3D9) + if (D3DCompileShaderFromFile) + if (D3DCompileShaderFromFile( + (LPCTSTR)src, + (const D3DXMACRO*)pdefines, + (LPD3DXINCLUDE)pinclude, + (LPCSTR)pfunctionname, + (LPCSTR)pprofile, + (DWORD)flags, + (LPD3DXBUFFER*)ppshader, + (LPD3DXBUFFER*)pperrormsgs, + (LPD3DXCONSTANTTABLE*)ppconstanttable) >= 0) + return true; #endif + break; + case D3D_COMM_D3D8: + case D3D_COMM_NONE: + break; + } return false; } diff --git a/gfx/common/d3d_common.h b/gfx/common/d3d_common.h index a15210f2a5..9feee7b59c 100644 --- a/gfx/common/d3d_common.h +++ b/gfx/common/d3d_common.h @@ -19,11 +19,17 @@ #include #include -#include "win32_common.h" #include "../../defines/d3d_defines.h" RETRO_BEGIN_DECLS +enum d3d_comm_api +{ + D3D_COMM_NONE = 0, + D3D_COMM_D3D8, + D3D_COMM_D3D9 +}; + typedef struct d3d_texture { LPDIRECT3DTEXTURE data; @@ -207,7 +213,7 @@ void d3d_device_free(LPDIRECT3DDEVICE dev, LPDIRECT3D pd3d); void *d3d_create(void); -bool d3d_initialize_symbols(void); +bool d3d_initialize_symbols(enum d3d_comm_api api); void d3d_deinitialize_symbols(void); diff --git a/gfx/drivers/d3d.c b/gfx/drivers/d3d8.c similarity index 93% rename from gfx/drivers/d3d.c rename to gfx/drivers/d3d8.c index 0426a53dae..73b7c0ff9a 100644 --- a/gfx/drivers/d3d.c +++ b/gfx/drivers/d3d8.c @@ -121,8 +121,9 @@ static bool d3d_init_chain(d3d_video_t *d3d, const video_info_t *video_info) link_info.tex_h = video_info->input_scale * RARCH_SCALE_BASE; link_info.pass = &d3d->shader.pass[0]; - if (!renderchain_d3d_init_first(&d3d->renderchain_driver, - &d3d->renderchain_data)) + if (!renderchain_d3d_init_first(D3D_COMM_D3D8, + &d3d->renderchain_driver, + &d3d->renderchain_data)) { RARCH_ERR("[D3D]: Renderchain could not be initialized.\n"); return false; @@ -390,26 +391,7 @@ static void d3d_overlay_render(d3d_video_t *d3d, d3d_vertex_buffer_unlock(overlay->vert_buf); d3d_enable_blend_func(d3d->dev); -#if defined(HAVE_D3D9) - { - LPDIRECT3DVERTEXDECLARATION vertex_decl; - /* set vertex declaration for overlay. */ - D3DVERTEXELEMENT vElems[4] = { - {0, offsetof(Vertex, x), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, - D3DDECLUSAGE_POSITION, 0}, - {0, offsetof(Vertex, u), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, - D3DDECLUSAGE_TEXCOORD, 0}, - {0, offsetof(Vertex, color), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, - D3DDECLUSAGE_COLOR, 0}, - D3DDECL_END() - }; - d3d_vertex_declaration_new(d3d->dev, &vElems, (void**)&vertex_decl); - d3d_set_vertex_declaration(d3d->dev, vertex_decl); - d3d_vertex_declaration_free(vertex_decl); - } -#elif defined(HAVE_D3D8) d3d_set_vertex_shader(d3d->dev, D3DFVF_CUSTOMVERTEX, NULL); -#endif d3d_set_stream_source(d3d->dev, 0, overlay->vert_buf, 0, sizeof(*vert)); @@ -474,11 +456,7 @@ static void d3d_deinitialize(d3d_video_t *d3d) d3d->menu_display.decl = NULL; } -#if defined(HAVE_D3D8) #define FS_PRESENTINTERVAL(pp) ((pp)->FullScreen_PresentationInterval) -#else -#define FS_PRESENTINTERVAL(pp) ((pp)->PresentationInterval) -#endif static D3DFORMAT d3d_get_color_format_backbuffer(bool rgb32, bool windowed) { @@ -497,13 +475,6 @@ static D3DFORMAT d3d_get_color_format_backbuffer(bool rgb32, bool windowed) return fmt; } -#ifdef _XBOX360 -static D3DFORMAT d3d_get_color_format_front_buffer(void) -{ - return D3DFMT_LE_X8R8G8B8; -} -#endif - static bool d3d_is_windowed_enable(bool info_fullscreen) { #ifndef _XBOX @@ -520,12 +491,6 @@ void d3d_make_d3dpp(void *data, const video_info_t *info, D3DPRESENT_PARAMETERS *d3dpp) { d3d_video_t *d3d = (d3d_video_t*)data; -#ifdef _XBOX360 - /* TODO/FIXME - get rid of global state dependencies. */ - global_t *global = global_get_ptr(); - bool gamma_enable = global ? - global->console.screen.gamma_correction : false; -#endif bool windowed_enable = d3d_is_windowed_enable(info->fullscreen); memset(d3dpp, 0, sizeof(*d3dpp)); @@ -555,11 +520,9 @@ void d3d_make_d3dpp(void *data, } } -#ifdef HAVE_D3D8 /* PresentationInterval must be zero for windowed mode on DX8. */ if (d3dpp->Windowed) FS_PRESENTINTERVAL(d3dpp) = D3DPRESENT_INTERVAL_DEFAULT; -#endif d3dpp->SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp->BackBufferCount = 2; @@ -569,18 +532,6 @@ void d3d_make_d3dpp(void *data, d3dpp->hDeviceWindow = win32_get_window(); #endif -#ifdef _XBOX360 - d3dpp->FrontBufferFormat = d3d_get_color_format_front_buffer(); - - if (gamma_enable) - { - d3dpp->BackBufferFormat = (D3DFORMAT)MAKESRGBFMT( - d3dpp->BackBufferFormat); - d3dpp->FrontBufferFormat = (D3DFORMAT)MAKESRGBFMT( - d3dpp->FrontBufferFormat); - } -#endif - if (!windowed_enable) { #ifdef _XBOX @@ -603,7 +554,6 @@ void d3d_make_d3dpp(void *data, #ifdef _XBOX d3dpp->MultiSampleType = D3DMULTISAMPLE_NONE; d3dpp->EnableAutoDepthStencil = FALSE; -#if defined(_XBOX1) { /* Get the "video mode" */ DWORD video_mode = XGetVideoFlags(); @@ -638,13 +588,6 @@ void d3d_make_d3dpp(void *data, d3dpp->Flags |= D3DPRESENTFLAG_WIDESCREEN; #endif } -#elif defined(_XBOX360) -#if 0 - if (!widescreen_mode) - d3dpp->Flags |= D3DPRESENTFLAG_NO_LETTERBOX; -#endif - d3dpp->MultiSampleQuality = 0; -#endif #endif } @@ -851,31 +794,10 @@ static bool d3d_initialize(d3d_video_t *d3d, const video_info_t *info) d3d_set_viewport(d3d, width, height, false, true); -#if defined(_XBOX360) - strlcpy(settings->paths.path_font, "game:\\media\\Arial_12.xpr", - sizeof(settings->paths.path_font)); -#endif font_driver_init_osd(d3d, false, info->is_threaded, FONT_DRIVER_RENDER_DIRECT3D_API); -#ifdef HAVE_D3D9 - { - static const D3DVERTEXELEMENT VertexElements[4] = { - {0, offsetof(Vertex, x), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, - D3DDECLUSAGE_POSITION, 0}, - {0, offsetof(Vertex, u), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, - D3DDECLUSAGE_TEXCOORD, 0}, - {0, offsetof(Vertex, color), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, - D3DDECLUSAGE_COLOR, 0}, - D3DDECL_END() - }; - if (!d3d_vertex_declaration_new(d3d->dev, - (void*)VertexElements, (void**)&d3d->menu_display.decl)) - return false; - } -#endif - d3d->menu_display.offset = 0; d3d->menu_display.size = 1024; d3d->menu_display.buffer = d3d_vertex_buffer_new( @@ -1174,16 +1096,9 @@ static void d3d_show_mouse(void *data, bool state) static const gfx_ctx_driver_t *d3d_get_context(void *data) { - /* Default to Direct3D9 for now. - TODO: GL core contexts through ANGLE? */ unsigned minor = 0; -#if defined(HAVE_D3D8) unsigned major = 8; enum gfx_ctx_api api = GFX_CTX_DIRECT3D8_API; -#else - unsigned major = 9; - enum gfx_ctx_api api = GFX_CTX_DIRECT3D9_API; -#endif settings_t *settings = config_get_ptr(); return video_context_driver_init_first(data, @@ -1197,7 +1112,7 @@ static void *d3d_init(const video_info_t *info, d3d_video_t *d3d = NULL; const gfx_ctx_driver_t *ctx_driver = NULL; - if (!d3d_initialize_symbols()) + if (!d3d_initialize_symbols(D3D_COMM_D3D8)) return NULL; d3d = (d3d_video_t*)calloc(1, sizeof(*d3d)); @@ -1314,7 +1229,7 @@ static void d3d_overlay_tex_geom( d3d->overlays[index].tex_coords[1] = y; d3d->overlays[index].tex_coords[2] = w; d3d->overlays[index].tex_coords[3] = h; -#ifdef _XBOX1 +#ifdef _XBOX d3d->overlays[index].tex_coords[0] *= d3d->overlays[index].tex_w; d3d->overlays[index].tex_coords[1] *= d3d->overlays[index].tex_h; d3d->overlays[index].tex_coords[2] *= d3d->overlays[index].tex_w; @@ -1639,7 +1554,7 @@ static void d3d_set_menu_texture_frame(void *data, d3d->menu->tex_w = width; d3d->menu->tex_h = height; -#ifdef _XBOX1 +#ifdef _XBOX d3d->menu->tex_coords [2] = width; d3d->menu->tex_coords[3] = height; #endif @@ -1710,17 +1625,9 @@ static void video_texture_load_d3d(d3d_video_t *d3d, uintptr_t *id) { D3DLOCKED_RECT d3dlr; - LPDIRECT3DTEXTURE tex = NULL; unsigned usage = 0; bool want_mipmap = false; - -#ifndef HAVE_D3D8 - if((filter_type == TEXTURE_FILTER_MIPMAP_LINEAR) || - (filter_type == TEXTURE_FILTER_MIPMAP_NEAREST)) - want_mipmap = true; -#endif - - tex = d3d_texture_new(d3d->dev, NULL, + LPDIRECT3DTEXTURE tex = d3d_texture_new(d3d->dev, NULL, ti->width, ti->height, 0, usage, d3d_get_argb8888_format(), D3DPOOL_MANAGED, 0, 0, 0, @@ -1830,7 +1737,7 @@ static void d3d_get_poke_interface(void *data, *iface = &d3d_poke_interface; } -video_driver_t video_d3d = { +video_driver_t video_d3d8 = { d3d_init, d3d_frame, d3d_set_nonblock_state, @@ -1840,7 +1747,7 @@ video_driver_t video_d3d = { NULL, /* has_windowed */ d3d_set_shader, d3d_free, - "d3d", + "d3d8", d3d_set_viewport, d3d_set_rotation, d3d_viewport_info, diff --git a/gfx/drivers/d3d9.c b/gfx/drivers/d3d9.c new file mode 100644 index 0000000000..2a0e188253 --- /dev/null +++ b/gfx/drivers/d3d9.c @@ -0,0 +1,1780 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2012-2014 - OV2 + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifdef _XBOX +#include +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include "d3d.h" +#include "../video_coord_array.h" +#include "../../configuration.h" +#include "../../dynamic.h" +#include "../video_driver.h" + +#ifdef HAVE_THREADS +#include "../video_thread_wrapper.h" +#endif + +#include "../common/win32_common.h" + +#ifndef _XBOX +#define HAVE_MONITOR +#define HAVE_WINDOW +#endif + +#ifdef HAVE_MENU +#include "../../menu/menu_driver.h" +#endif + +#include "../font_driver.h" + +#include "../../core.h" + +#include "../../defines/d3d_defines.h" +#include "../../verbosity.h" + +static LPDIRECT3D g_pD3D; + +static bool d3d_init_imports(d3d_video_t *d3d) +{ + retro_ctx_memory_info_t mem_info; + state_tracker_t *state_tracker = NULL; + struct state_tracker_info tracker_info = {0}; + + if (!d3d->shader.variables) + return true; + + mem_info.id = RETRO_MEMORY_SYSTEM_RAM; + + core_get_memory(&mem_info); + + tracker_info.script_class = NULL; + tracker_info.wram = (uint8_t*)mem_info.data; + tracker_info.info = d3d->shader.variable; + tracker_info.info_elem = d3d->shader.variables; + tracker_info.script = NULL; + tracker_info.script_is_file = false; + +#ifdef HAVE_PYTHON + if (*d3d->shader.script_path) + { + tracker_info.script = d3d->shader.script_path; + tracker_info.script_is_file = true; + } + + if (*d3d->shader.script_class) + tracker_info.script_class = d3d->shader.script_class; +#endif + + state_tracker = + state_tracker_init(&tracker_info); + + if (!state_tracker) + { + RARCH_ERR("[D3D]: Failed to initialize state tracker.\n"); + return false; + } + + d3d->renderchain_driver->add_state_tracker( + d3d->renderchain_data, state_tracker); + + return true; +} + +static bool d3d_init_chain(d3d_video_t *d3d, const video_info_t *video_info) +{ + struct LinkInfo link_info; + unsigned current_width, current_height, out_width, out_height; + unsigned i = 0; + + (void)i; + (void)current_width; + (void)current_height; + (void)out_width; + (void)out_height; + + /* Setup information for first pass. */ + link_info.pass = NULL; + link_info.tex_w = video_info->input_scale * RARCH_SCALE_BASE; + link_info.tex_h = video_info->input_scale * RARCH_SCALE_BASE; + link_info.pass = &d3d->shader.pass[0]; + + if (!renderchain_d3d_init_first(D3D_COMM_D3D9, + &d3d->renderchain_driver, + &d3d->renderchain_data)) + { + RARCH_ERR("[D3D]: Renderchain could not be initialized.\n"); + return false; + } + + if (!d3d->renderchain_driver || !d3d->renderchain_data) + return false; + + if ( + !d3d->renderchain_driver->init( + d3d, + &d3d->video_info, + d3d->dev, &d3d->final_viewport, &link_info, + d3d->video_info.rgb32) + ) + { + RARCH_ERR("[D3D]: Failed to init render chain.\n"); + return false; + } + + RARCH_LOG("[D3D]: Renderchain driver: %s\n", d3d->renderchain_driver->ident); + +#ifndef _XBOX + current_width = link_info.tex_w; + current_height = link_info.tex_h; + out_width = 0; + out_height = 0; + + for (i = 1; i < d3d->shader.passes; i++) + { + d3d->renderchain_driver->convert_geometry(d3d->renderchain_data, + &link_info, + &out_width, &out_height, + current_width, current_height, &d3d->final_viewport); + + link_info.pass = &d3d->shader.pass[i]; + link_info.tex_w = next_pow2(out_width); + link_info.tex_h = next_pow2(out_height); + + current_width = out_width; + current_height = out_height; + + if (!d3d->renderchain_driver->add_pass( + d3d->renderchain_data, &link_info)) + { + RARCH_ERR("[D3D]: Failed to add pass.\n"); + return false; + } + } +#endif + + if (d3d->renderchain_driver) + { + if (d3d->renderchain_driver->add_lut) + { + unsigned i; + settings_t *settings = config_get_ptr(); + + for (i = 0; i < d3d->shader.luts; i++) + { + if (!d3d->renderchain_driver->add_lut( + d3d->renderchain_data, + d3d->shader.lut[i].id, d3d->shader.lut[i].path, + d3d->shader.lut[i].filter == RARCH_FILTER_UNSPEC ? + settings->bools.video_smooth : + (d3d->shader.lut[i].filter == RARCH_FILTER_LINEAR))) + { + RARCH_ERR("[D3D]: Failed to init LUTs.\n"); + return false; + } + } + } + + if (d3d->renderchain_driver->add_state_tracker) + { + if (!d3d_init_imports(d3d)) + { + RARCH_ERR("[D3D]: Failed to init imports.\n"); + return false; + } + } + } + + return true; +} + +static bool d3d_init_singlepass(d3d_video_t *d3d) +{ + struct video_shader_pass *pass = NULL; + + if (!d3d) + return false; + + memset(&d3d->shader, 0, sizeof(d3d->shader)); + d3d->shader.passes = 1; + + pass = (struct video_shader_pass*) + &d3d->shader.pass[0]; + + pass->fbo.valid = true; + pass->fbo.scale_y = 1.0; + pass->fbo.type_y = RARCH_SCALE_VIEWPORT; + pass->fbo.scale_x = pass->fbo.scale_y; + pass->fbo.type_x = pass->fbo.type_y; + + if (!string_is_empty(d3d->shader_path)) + strlcpy(pass->source.path, d3d->shader_path, + sizeof(pass->source.path)); + + return true; +} + +static bool d3d_init_multipass(d3d_video_t *d3d, const char *shader_path) +{ + unsigned i; + bool use_extra_pass = false; + struct video_shader_pass *pass = NULL; + config_file_t *conf = config_file_new(shader_path); + + if (!conf) + { + RARCH_ERR("[D3D]: Failed to load preset.\n"); + return false; + } + + memset(&d3d->shader, 0, sizeof(d3d->shader)); + + if (!video_shader_read_conf_cgp(conf, &d3d->shader)) + { + config_file_free(conf); + RARCH_ERR("[D3D]: Failed to parse CGP file.\n"); + return false; + } + + config_file_free(conf); + + if (!string_is_empty(shader_path)) + video_shader_resolve_relative(&d3d->shader, shader_path); + RARCH_LOG("[D3D]: Found %u shaders.\n", d3d->shader.passes); + + for (i = 0; i < d3d->shader.passes; i++) + { + if (d3d->shader.pass[i].fbo.valid) + continue; + + d3d->shader.pass[i].fbo.scale_y = 1.0f; + d3d->shader.pass[i].fbo.scale_x = 1.0f; + d3d->shader.pass[i].fbo.type_x = RARCH_SCALE_INPUT; + d3d->shader.pass[i].fbo.type_y = RARCH_SCALE_INPUT; + } + + use_extra_pass = d3d->shader.passes < GFX_MAX_SHADERS && + d3d->shader.pass[d3d->shader.passes - 1].fbo.valid; + + if (use_extra_pass) + { + d3d->shader.passes++; + pass = (struct video_shader_pass*) + &d3d->shader.pass[d3d->shader.passes - 1]; + + pass->fbo.scale_x = 1.0f; + pass->fbo.scale_y = 1.0f; + pass->fbo.type_x = RARCH_SCALE_VIEWPORT; + pass->fbo.type_y = RARCH_SCALE_VIEWPORT; + pass->filter = RARCH_FILTER_UNSPEC; + } + else + { + pass = (struct video_shader_pass*) + &d3d->shader.pass[d3d->shader.passes - 1]; + + pass->fbo.scale_x = 1.0f; + pass->fbo.scale_y = 1.0f; + pass->fbo.type_x = RARCH_SCALE_VIEWPORT; + pass->fbo.type_y = RARCH_SCALE_VIEWPORT; + } + + return true; +} + +static bool d3d_process_shader(d3d_video_t *d3d) +{ + const char *shader_path = d3d->shader_path; + if (d3d && !string_is_empty(shader_path) && + string_is_equal(path_get_extension(shader_path), "cgp")) + return d3d_init_multipass(d3d, shader_path); + + return d3d_init_singlepass(d3d); +} + +static void d3d_viewport_info(void *data, struct video_viewport *vp) +{ + d3d_video_t *d3d = (d3d_video_t*)data; + + if ( d3d && + d3d->renderchain_driver && + d3d->renderchain_driver->viewport_info) + d3d->renderchain_driver->viewport_info(d3d, vp); +} + +static void d3d_set_mvp(void *data, + void *shader_data, + const void *mat_data) +{ + d3d_video_t *d3d = (d3d_video_t*)data; + + if ( d3d && + d3d->renderchain_driver && + d3d->renderchain_driver->set_mvp) + d3d->renderchain_driver->set_mvp(d3d, d3d->renderchain_data, shader_data, mat_data); +} + +static void d3d_overlay_render(d3d_video_t *d3d, + video_frame_info_t *video_info, + overlay_t *overlay) +{ + LPDIRECT3DVERTEXDECLARATION vertex_decl; + struct video_viewport vp; + void *verts; + unsigned i; + Vertex vert[4]; + D3DVERTEXELEMENT vElems[4] = { + {0, offsetof(Vertex, x), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, + D3DDECLUSAGE_POSITION, 0}, + {0, offsetof(Vertex, u), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, + D3DDECLUSAGE_TEXCOORD, 0}, + {0, offsetof(Vertex, color), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, + D3DDECLUSAGE_COLOR, 0}, + D3DDECL_END() + }; + unsigned width = video_info->width; + unsigned height = video_info->height; + + if (!d3d || !overlay || !overlay->tex) + return; + + if (!overlay->vert_buf) + { + overlay->vert_buf = d3d_vertex_buffer_new( + d3d->dev, sizeof(vert), D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, NULL); + + if (!overlay->vert_buf) + return; + } + + for (i = 0; i < 4; i++) + { + vert[i].z = 0.5f; + vert[i].color = (((uint32_t)(overlay->alpha_mod * 0xFF)) << 24) | 0xFFFFFF; + } + + d3d_viewport_info(d3d, &vp); + + vert[0].x = overlay->vert_coords[0]; + vert[1].x = overlay->vert_coords[0] + overlay->vert_coords[2]; + vert[2].x = overlay->vert_coords[0]; + vert[3].x = overlay->vert_coords[0] + overlay->vert_coords[2]; + vert[0].y = overlay->vert_coords[1]; + vert[1].y = overlay->vert_coords[1]; + vert[2].y = overlay->vert_coords[1] + overlay->vert_coords[3]; + vert[3].y = overlay->vert_coords[1] + overlay->vert_coords[3]; + + vert[0].u = overlay->tex_coords[0]; + vert[1].u = overlay->tex_coords[0] + overlay->tex_coords[2]; + vert[2].u = overlay->tex_coords[0]; + vert[3].u = overlay->tex_coords[0] + overlay->tex_coords[2]; + vert[0].v = overlay->tex_coords[1]; + vert[1].v = overlay->tex_coords[1]; + vert[2].v = overlay->tex_coords[1] + overlay->tex_coords[3]; + vert[3].v = overlay->tex_coords[1] + overlay->tex_coords[3]; + + verts = d3d_vertex_buffer_lock(overlay->vert_buf); + memcpy(verts, vert, sizeof(vert)); + d3d_vertex_buffer_unlock(overlay->vert_buf); + + d3d_enable_blend_func(d3d->dev); + + /* set vertex declaration for overlay. */ + d3d_vertex_declaration_new(d3d->dev, &vElems, (void**)&vertex_decl); + d3d_set_vertex_declaration(d3d->dev, vertex_decl); + d3d_vertex_declaration_free(vertex_decl); + + d3d_set_stream_source(d3d->dev, 0, overlay->vert_buf, + 0, sizeof(*vert)); + + if (overlay->fullscreen) + { + D3DVIEWPORT vp_full; + + vp_full.X = 0; + vp_full.Y = 0; + vp_full.Width = width; + vp_full.Height = height; + vp_full.MinZ = 0.0f; + vp_full.MaxZ = 1.0f; + d3d_set_viewports(d3d->dev, &vp_full); + } + + /* Render overlay. */ + d3d_set_texture(d3d->dev, 0, overlay->tex); + d3d_set_sampler_address_u(d3d->dev, 0, D3DTADDRESS_BORDER); + d3d_set_sampler_address_v(d3d->dev, 0, D3DTADDRESS_BORDER); + d3d_set_sampler_minfilter(d3d->dev, 0, D3DTEXF_LINEAR); + d3d_set_sampler_magfilter(d3d->dev, 0, D3DTEXF_LINEAR); + d3d_draw_primitive(d3d->dev, D3DPT_TRIANGLESTRIP, 0, 2); + + /* Restore previous state. */ + d3d_disable_blend_func(d3d->dev); + d3d_set_viewports(d3d->dev, &d3d->final_viewport); +} + +static void d3d_free_overlay(d3d_video_t *d3d, overlay_t *overlay) +{ + if (!d3d) + return; + + d3d_texture_free(overlay->tex); + d3d_vertex_buffer_free(overlay->vert_buf, NULL); +} + +static void d3d_deinit_chain(d3d_video_t *d3d) +{ + if (!d3d || !d3d->renderchain_driver) + return; + + if (d3d->renderchain_driver->chain_free) + d3d->renderchain_driver->chain_free(d3d->renderchain_data); + + d3d->renderchain_driver = NULL; + d3d->renderchain_data = NULL; +} + +static void d3d_deinitialize(d3d_video_t *d3d) +{ + if (!d3d) + return; + + font_driver_free_osd(); + + d3d_deinit_chain(d3d); + d3d_vertex_buffer_free(d3d->menu_display.buffer, d3d->menu_display.decl); + d3d->menu_display.buffer = NULL; + d3d->menu_display.decl = NULL; +} + +#define FS_PRESENTINTERVAL(pp) ((pp)->PresentationInterval) + +static D3DFORMAT d3d_get_color_format_backbuffer(bool rgb32, bool windowed) +{ + D3DFORMAT fmt = D3DFMT_X8R8G8B8; +#ifdef _XBOX + if (!rgb32) + fmt = d3d_get_rgb565_format(); +#else + if (windowed) + { + D3DDISPLAYMODE display_mode; + if (d3d_get_adapter_display_mode(g_pD3D, 0, &display_mode)) + fmt = display_mode.Format; + } +#endif + return fmt; +} + +#ifdef _XBOX +static D3DFORMAT d3d_get_color_format_front_buffer(void) +{ + return D3DFMT_LE_X8R8G8B8; +} +#endif + +static bool d3d_is_windowed_enable(bool info_fullscreen) +{ +#ifndef _XBOX + settings_t *settings = config_get_ptr(); + if (!info_fullscreen) + return true; + if (settings) + return settings->bools.video_windowed_fullscreen; +#endif + return false; +} + +void d3d_make_d3dpp(void *data, + const video_info_t *info, D3DPRESENT_PARAMETERS *d3dpp) +{ + d3d_video_t *d3d = (d3d_video_t*)data; +#ifdef _XBOX + /* TODO/FIXME - get rid of global state dependencies. */ + global_t *global = global_get_ptr(); + bool gamma_enable = global ? + global->console.screen.gamma_correction : false; +#endif + bool windowed_enable = d3d_is_windowed_enable(info->fullscreen); + + memset(d3dpp, 0, sizeof(*d3dpp)); + + d3dpp->Windowed = windowed_enable; + FS_PRESENTINTERVAL(d3dpp) = D3DPRESENT_INTERVAL_IMMEDIATE; + + if (info->vsync) + { + settings_t *settings = config_get_ptr(); + + switch (settings->uints.video_swap_interval) + { + default: + case 1: + FS_PRESENTINTERVAL(d3dpp) = D3DPRESENT_INTERVAL_ONE; + break; + case 2: + FS_PRESENTINTERVAL(d3dpp) = D3DPRESENT_INTERVAL_TWO; + break; + case 3: + FS_PRESENTINTERVAL(d3dpp) = D3DPRESENT_INTERVAL_THREE; + break; + case 4: + FS_PRESENTINTERVAL(d3dpp) = D3DPRESENT_INTERVAL_FOUR; + break; + } + } + + d3dpp->SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp->BackBufferCount = 2; + d3dpp->BackBufferFormat = d3d_get_color_format_backbuffer( + info->rgb32, windowed_enable); + +#ifdef _XBOX + d3dpp->FrontBufferFormat = d3d_get_color_format_front_buffer(); + + if (gamma_enable) + { + d3dpp->BackBufferFormat = (D3DFORMAT)MAKESRGBFMT( + d3dpp->BackBufferFormat); + d3dpp->FrontBufferFormat = (D3DFORMAT)MAKESRGBFMT( + d3dpp->FrontBufferFormat); + } +#else + d3dpp->hDeviceWindow = win32_get_window(); +#endif + + if (!windowed_enable) + { +#ifdef _XBOX + gfx_ctx_mode_t mode; + unsigned width = 0; + unsigned height = 0; + + video_context_driver_get_video_size(&mode); + + width = mode.width; + height = mode.height; + mode.width = 0; + mode.height = 0; + video_driver_set_size(&width, &height); +#endif + video_driver_get_size(&d3dpp->BackBufferWidth, + &d3dpp->BackBufferHeight); + } + +#ifdef _XBOX + d3dpp->MultiSampleType = D3DMULTISAMPLE_NONE; + d3dpp->EnableAutoDepthStencil = FALSE; +#if 0 + if (!widescreen_mode) + d3dpp->Flags |= D3DPRESENTFLAG_NO_LETTERBOX; +#endif + d3dpp->MultiSampleQuality = 0; +#endif +} + +static bool d3d_init_base(void *data, const video_info_t *info) +{ + D3DPRESENT_PARAMETERS d3dpp; + HWND focus_window = NULL; + d3d_video_t *d3d = (d3d_video_t*)data; + +#ifndef _XBOX + focus_window = win32_get_window(); +#endif + + memset(&d3dpp, 0, sizeof(d3dpp)); + + g_pD3D = (LPDIRECT3D)d3d_create(); + + /* this needs g_pD3D created first */ + d3d_make_d3dpp(d3d, info, &d3dpp); + + if (!g_pD3D) + { + RARCH_ERR("[D3D]: Failed to create D3D interface.\n"); + return false; + } + + if (!d3d_create_device(&d3d->dev, &d3dpp, + g_pD3D, + focus_window, + d3d->cur_mon_id) + ) + { + RARCH_ERR("[D3D]: Failed to initialize device.\n"); + return false; + } + + return true; +} + +static void d3d_calculate_rect(void *data, + unsigned *width, unsigned *height, + int *x, int *y, + bool force_full, + bool allow_rotate) +{ + gfx_ctx_aspect_t aspect_data; + float device_aspect = (float)*width / *height; + d3d_video_t *d3d = (d3d_video_t*)data; + settings_t *settings = config_get_ptr(); + + video_driver_get_size(width, height); + + aspect_data.aspect = &device_aspect; + aspect_data.width = *width; + aspect_data.height = *height; + + video_context_driver_translate_aspect(&aspect_data); + + *x = 0; + *y = 0; + + if (settings->bools.video_scale_integer && !force_full) + { + struct video_viewport vp; + + vp.x = 0; + vp.y = 0; + vp.width = 0; + vp.height = 0; + vp.full_width = 0; + vp.full_height = 0; + + video_viewport_get_scaled_integer(&vp, + *width, + *height, + video_driver_get_aspect_ratio(), + d3d->keep_aspect); + + *x = vp.x; + *y = vp.y; + *width = vp.width; + *height = vp.height; + } + else if (d3d->keep_aspect && !force_full) + { + float desired_aspect = video_driver_get_aspect_ratio(); + +#if defined(HAVE_MENU) + if (settings->uints.video_aspect_ratio_idx == ASPECT_RATIO_CUSTOM) + { + video_viewport_t *custom = video_viewport_get_custom(); + + *x = custom->x; + *y = custom->y; + *width = custom->width; + *height = custom->height; + } + else +#endif + { + float delta; + + if (fabsf(device_aspect - desired_aspect) < 0.0001f) + { + /* If the aspect ratios of screen and desired aspect + * ratio are sufficiently equal (floating point stuff), + * assume they are actually equal. + */ + } + else if (device_aspect > desired_aspect) + { + delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f; + *x = (int)(roundf(*width * (0.5f - delta))); + *width = (unsigned)(roundf(2.0f * (*width) * delta)); + } + else + { + delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; + *y = (int)(roundf(*height * (0.5f - delta))); + *height = (unsigned)(roundf(2.0f * (*height) * delta)); + } + } + } +} + +static void d3d_set_viewport(void *data, + unsigned width, unsigned height, + bool force_full, + bool allow_rotate) +{ + D3DVIEWPORT viewport; + int x = 0; + int y = 0; + d3d_video_t *d3d = (d3d_video_t*)data; + + d3d_calculate_rect(data, &width, &height, &x, &y, + force_full, allow_rotate); + + /* D3D doesn't support negative X/Y viewports ... */ + if (x < 0) + x = 0; + if (y < 0) + y = 0; + + viewport.X = x; + viewport.Y = y; + viewport.Width = width; + viewport.Height = height; + viewport.MinZ = 0.0f; + viewport.MaxZ = 1.0f; + + d3d->final_viewport = viewport; + + if (d3d->renderchain_driver && d3d->renderchain_driver->set_font_rect) + d3d->renderchain_driver->set_font_rect(d3d, NULL); +} + +static bool d3d_initialize(d3d_video_t *d3d, const video_info_t *info) +{ + unsigned width, height; + bool ret = true; + settings_t *settings = config_get_ptr(); + + if (!d3d) + return false; + + if (!g_pD3D) + ret = d3d_init_base(d3d, info); + else if (d3d->needs_restore) + { + D3DPRESENT_PARAMETERS d3dpp; + + d3d_make_d3dpp(d3d, info, &d3dpp); + + /* the D3DX font driver uses POOL_DEFAULT resources + * and will prevent a clean reset here + * another approach would be to keep track of all created D3D + * font objects and free/realloc them around the d3d_reset call */ + + menu_driver_ctl(RARCH_MENU_CTL_DEINIT, NULL); + if (!d3d_reset(d3d->dev, &d3dpp)) + { + d3d_deinitialize(d3d); + d3d_device_free(NULL, g_pD3D); + g_pD3D = NULL; + + ret = d3d_init_base(d3d, info); + if (ret) + RARCH_LOG("[D3D]: Recovered from dead state.\n"); + } + menu_driver_init(info->is_threaded); + } + + if (!ret) + return ret; + + if (!d3d_init_chain(d3d, info)) + { + RARCH_ERR("[D3D]: Failed to initialize render chain.\n"); + return false; + } + + video_driver_get_size(&width, &height); + d3d_set_viewport(d3d, + width, height, false, true); + +#ifdef _XBOX + strlcpy(settings->paths.path_font, "game:\\media\\Arial_12.xpr", + sizeof(settings->paths.path_font)); +#endif + font_driver_init_osd(d3d, false, + info->is_threaded, + FONT_DRIVER_RENDER_DIRECT3D_API); + + { + static const D3DVERTEXELEMENT VertexElements[4] = { + {0, offsetof(Vertex, x), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, + D3DDECLUSAGE_POSITION, 0}, + {0, offsetof(Vertex, u), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, + D3DDECLUSAGE_TEXCOORD, 0}, + {0, offsetof(Vertex, color), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, + D3DDECLUSAGE_COLOR, 0}, + D3DDECL_END() + }; + if (!d3d_vertex_declaration_new(d3d->dev, + (void*)VertexElements, (void**)&d3d->menu_display.decl)) + return false; + } + + d3d->menu_display.offset = 0; + d3d->menu_display.size = 1024; + d3d->menu_display.buffer = d3d_vertex_buffer_new( + d3d->dev, d3d->menu_display.size * sizeof(Vertex), + D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, + NULL); + + if (!d3d->menu_display.buffer) + return false; + + d3d_matrix_ortho_off_center_lh(&d3d->mvp_transposed, 0, 1, 0, 1, 0, 1); + d3d_matrix_transpose(&d3d->mvp, &d3d->mvp_transposed); + + d3d_set_render_state(d3d->dev, D3DRS_CULLMODE, D3DCULL_NONE); + + return true; +} + +static bool d3d_restore(void *data) +{ + d3d_video_t *d3d = (d3d_video_t*)data; + + if (!d3d) + return false; + + d3d_deinitialize(d3d); + + if (!d3d_initialize(d3d, &d3d->video_info)) + { + RARCH_ERR("[D3D]: Restore error.\n"); + return false; + } + + d3d->needs_restore = false; + + return true; +} + + +static void d3d_set_nonblock_state(void *data, bool state) +{ + unsigned interval = state ? 0 : 1; + d3d_video_t *d3d = (d3d_video_t*)data; + + if (!d3d) + return; + + d3d->video_info.vsync = !state; + + video_context_driver_swap_interval(&interval); +#ifndef _XBOX + d3d->needs_restore = true; + d3d_restore(d3d); +#endif +} + +static bool d3d_alive(void *data) +{ + gfx_ctx_size_t size_data; + unsigned temp_width = 0; + unsigned temp_height = 0; + bool ret = false; + d3d_video_t *d3d = (d3d_video_t*)data; + bool quit = false; + bool resize = false; + + /* Needed because some context drivers don't track their sizes */ + video_driver_get_size(&temp_width, &temp_height); + + size_data.quit = &quit; + size_data.resize = &resize; + size_data.width = &temp_width; + size_data.height = &temp_height; + + if (video_context_driver_check_window(&size_data)) + { + if (quit) + d3d->quitting = quit; + + if (resize) + { + d3d->should_resize = true; + video_driver_set_resize(temp_width, temp_height); + d3d_restore(d3d); + } + + ret = !quit; + } + + if (temp_width != 0 && temp_height != 0) + video_driver_set_size(&temp_width, &temp_height); + + return ret; +} + +static bool d3d_suppress_screensaver(void *data, bool enable) +{ + bool enabled = enable; + return video_context_driver_suppress_screensaver(&enabled); +} + +static void d3d_set_aspect_ratio(void *data, unsigned aspect_ratio_idx) +{ + d3d_video_t *d3d = (d3d_video_t*)data; + + switch (aspect_ratio_idx) + { + case ASPECT_RATIO_SQUARE: + video_driver_set_viewport_square_pixel(); + break; + + case ASPECT_RATIO_CORE: + video_driver_set_viewport_core(); + break; + + case ASPECT_RATIO_CONFIG: + video_driver_set_viewport_config(); + break; + + default: + break; + } + + video_driver_set_aspect_ratio_value( + aspectratio_lut[aspect_ratio_idx].value); + + if (!d3d) + return; + + d3d->keep_aspect = true; + d3d->should_resize = true; +} + +static void d3d_apply_state_changes(void *data) +{ + d3d_video_t *d3d = (d3d_video_t*)data; + if (d3d) + d3d->should_resize = true; +} + +static void d3d_set_osd_msg(void *data, + video_frame_info_t *video_info, + const char *msg, + const void *params, void *font) +{ + d3d_video_t *d3d = (d3d_video_t*)data; + + if (d3d->renderchain_driver->set_font_rect && params) + d3d->renderchain_driver->set_font_rect(d3d, params); + + font_driver_render_msg(video_info, font, msg, params); +} + +static bool d3d_init_internal(d3d_video_t *d3d, + const video_info_t *info, const input_driver_t **input, + void **input_data) +{ + gfx_ctx_input_t inp; +#ifdef HAVE_MONITOR + bool windowed_full; + RECT mon_rect; + MONITORINFOEX current_mon; + HMONITOR hm_to_use; +#endif +#ifdef HAVE_WINDOW + DWORD style; + unsigned win_width = 0; + unsigned win_height = 0; + RECT rect = {0}; +#endif + unsigned full_x = 0; + unsigned full_y = 0; + settings_t *settings = config_get_ptr(); + overlay_t *menu = (overlay_t*)calloc(1, sizeof(*menu)); + + if (!menu) + return false; + + d3d->menu = menu; + d3d->cur_mon_id = 0; + d3d->menu->tex_coords[0] = 0; + d3d->menu->tex_coords[1] = 0; + d3d->menu->tex_coords[2] = 1; + d3d->menu->tex_coords[3] = 1; + d3d->menu->vert_coords[0] = 0; + d3d->menu->vert_coords[1] = 1; + d3d->menu->vert_coords[2] = 1; + d3d->menu->vert_coords[3] = -1; + + memset(&d3d->windowClass, 0, sizeof(d3d->windowClass)); + +#ifdef HAVE_WINDOW + d3d->windowClass.lpfnWndProc = WndProcD3D; + win32_window_init(&d3d->windowClass, true, NULL); +#endif + +#ifdef HAVE_MONITOR + win32_monitor_info(¤t_mon, &hm_to_use, &d3d->cur_mon_id); + + mon_rect = current_mon.rcMonitor; + g_resize_width = info->width; + g_resize_height = info->height; + + windowed_full = settings->bools.video_windowed_fullscreen; + + full_x = (windowed_full || info->width == 0) ? + (mon_rect.right - mon_rect.left) : info->width; + full_y = (windowed_full || info->height == 0) ? + (mon_rect.bottom - mon_rect.top) : info->height; + + RARCH_LOG("[D3D]: Monitor size: %dx%d.\n", + (int)(mon_rect.right - mon_rect.left), + (int)(mon_rect.bottom - mon_rect.top)); +#else + { + gfx_ctx_mode_t mode; + + video_context_driver_get_video_size(&mode); + + full_x = mode.width; + full_y = mode.height; + } +#endif + { + unsigned new_width = info->fullscreen ? full_x : info->width; + unsigned new_height = info->fullscreen ? full_y : info->height; + video_driver_set_size(&new_width, &new_height); + } + +#ifdef HAVE_WINDOW + video_driver_get_size(&win_width, &win_height); + + win32_set_style(¤t_mon, &hm_to_use, &win_width, &win_height, + info->fullscreen, windowed_full, &rect, &mon_rect, &style); + + win32_window_create(d3d, style, &mon_rect, win_width, + win_height, info->fullscreen); + + win32_set_window(&win_width, &win_height, info->fullscreen, + windowed_full, &rect); +#endif + + /* This should only be done once here + * to avoid set_shader() to be overridden + * later. */ + if (settings->bools.video_shader_enable) + { + enum rarch_shader_type type = + video_shader_parse_type(settings->paths.path_shader, + RARCH_SHADER_NONE); + + switch (type) + { + case RARCH_SHADER_CG: + if (!string_is_empty(d3d->shader_path)) + free(d3d->shader_path); + if (!string_is_empty(settings->paths.path_shader)) + d3d->shader_path = strdup(settings->paths.path_shader); + break; + default: + break; + } + } + + if (!d3d_process_shader(d3d)) + return false; + + d3d->video_info = *info; + if (!d3d_initialize(d3d, &d3d->video_info)) + return false; + + inp.input = input; + inp.input_data = input_data; + + video_context_driver_input_driver(&inp); + + RARCH_LOG("[D3D]: Init complete.\n"); + return true; +} + +static void d3d_set_rotation(void *data, unsigned rot) +{ + d3d_video_t *d3d = (d3d_video_t*)data; + struct video_ortho ortho = {0, 1, 0, 1, -1, 1}; + + if (!d3d) + return; + + d3d->dev_rotation = rot; +} + +static void d3d_show_mouse(void *data, bool state) +{ + video_context_driver_show_mouse(&state); +} + +static const gfx_ctx_driver_t *d3d_get_context(void *data) +{ + /* TODO: GL core contexts through ANGLE? */ + unsigned minor = 0; + unsigned major = 9; + enum gfx_ctx_api api = GFX_CTX_DIRECT3D9_API; + settings_t *settings = config_get_ptr(); + + return video_context_driver_init_first(data, + settings->arrays.video_context_driver, + api, major, minor, false); +} + +static void *d3d_init(const video_info_t *info, + const input_driver_t **input, void **input_data) +{ + d3d_video_t *d3d = NULL; + const gfx_ctx_driver_t *ctx_driver = NULL; + + if (!d3d_initialize_symbols(D3D_COMM_D3D9)) + return NULL; + + d3d = (d3d_video_t*)calloc(1, sizeof(*d3d)); + if (!d3d) + goto error; + + ctx_driver = d3d_get_context(d3d); + if (!ctx_driver) + goto error; + + /* Default values */ + d3d->dev = NULL; + d3d->dev_rotation = 0; + d3d->needs_restore = false; +#ifdef HAVE_OVERLAY + d3d->overlays_enabled = false; +#endif + d3d->should_resize = false; + d3d->menu = NULL; + + video_context_driver_set((const gfx_ctx_driver_t*)ctx_driver); + + if (!d3d_init_internal(d3d, info, input, input_data)) + { + RARCH_ERR("[D3D]: Failed to init D3D.\n"); + goto error; + } + + d3d->keep_aspect = info->force_aspect; + + return d3d; + +error: + video_context_driver_destroy(); + if (d3d) + free(d3d); + return NULL; +} + +#ifdef HAVE_OVERLAY +static void d3d_free_overlays(d3d_video_t *d3d) +{ + unsigned i; + + if (!d3d) + return; + + for (i = 0; i < d3d->overlays_size; i++) + d3d_free_overlay(d3d, &d3d->overlays[i]); + free(d3d->overlays); + d3d->overlays = NULL; + d3d->overlays_size = 0; +} +#endif + +static void d3d_free(void *data) +{ + d3d_video_t *d3d = (d3d_video_t*)data; + + if (!d3d) + return; + +#ifdef HAVE_OVERLAY + d3d_free_overlays(d3d); + if (d3d->overlays) + free(d3d->overlays); + d3d->overlays = NULL; + d3d->overlays_size = 0; +#endif + + d3d_free_overlay(d3d, d3d->menu); + if (d3d->menu) + free(d3d->menu); + d3d->menu = NULL; + + d3d_deinitialize(d3d); + + video_context_driver_free(); + + if (!string_is_empty(d3d->shader_path)) + free(d3d->shader_path); + + d3d->shader_path = NULL; + d3d_device_free(d3d->dev, g_pD3D); + d3d->dev = NULL; + g_pD3D = NULL; + +#ifndef _XBOX + win32_monitor_from_window(); +#endif + + if (d3d) + free(d3d); + + d3d_deinitialize_symbols(); + +#ifndef _XBOX + win32_destroy_window(); +#endif +} + +#ifdef HAVE_OVERLAY +static void d3d_overlay_tex_geom( + void *data, + unsigned index, + float x, float y, + float w, float h) +{ + d3d_video_t *d3d = (d3d_video_t*)data; + if (!d3d) + return; + + d3d->overlays[index].tex_coords[0] = x; + d3d->overlays[index].tex_coords[1] = y; + d3d->overlays[index].tex_coords[2] = w; + d3d->overlays[index].tex_coords[3] = h; +} + +static void d3d_overlay_vertex_geom( + void *data, + unsigned index, + float x, float y, + float w, float h) +{ + d3d_video_t *d3d = (d3d_video_t*)data; + if (!d3d) + return; + + y = 1.0f - y; + h = -h; + d3d->overlays[index].vert_coords[0] = x; + d3d->overlays[index].vert_coords[1] = y; + d3d->overlays[index].vert_coords[2] = w; + d3d->overlays[index].vert_coords[3] = h; +} + +static bool d3d_overlay_load(void *data, + const void *image_data, unsigned num_images) +{ + unsigned i, y; + overlay_t *new_overlays = NULL; + d3d_video_t *d3d = (d3d_video_t*)data; + const struct texture_image *images = (const struct texture_image*) + image_data; + + if (!d3d) + return false; + + d3d_free_overlays(d3d); + d3d->overlays = (overlay_t*)calloc(num_images, sizeof(*d3d->overlays)); + d3d->overlays_size = num_images; + + for (i = 0; i < num_images; i++) + { + D3DLOCKED_RECT d3dlr; + unsigned width = images[i].width; + unsigned height = images[i].height; + overlay_t *overlay = (overlay_t*)&d3d->overlays[i]; + + overlay->tex = d3d_texture_new(d3d->dev, NULL, + width, height, 1, + 0, + d3d_get_argb8888_format(), + D3DPOOL_MANAGED, 0, 0, 0, + NULL, NULL, false); + + if (!overlay->tex) + { + RARCH_ERR("[D3D]: Failed to create overlay texture\n"); + return false; + } + + if (d3d_lock_rectangle(overlay->tex, 0, &d3dlr, + NULL, 0, D3DLOCK_NOSYSLOCK)) + { + uint32_t *dst = (uint32_t*)(d3dlr.pBits); + const uint32_t *src = images[i].pixels; + unsigned pitch = d3dlr.Pitch >> 2; + + for (y = 0; y < height; y++, dst += pitch, src += width) + memcpy(dst, src, width << 2); + d3d_unlock_rectangle(overlay->tex); + } + + overlay->tex_w = width; + overlay->tex_h = height; + + /* Default. Stretch to whole screen. */ + d3d_overlay_tex_geom(d3d, i, 0, 0, 1, 1); + d3d_overlay_vertex_geom(d3d, i, 0, 0, 1, 1); + } + + return true; +} + +static void d3d_overlay_enable(void *data, bool state) +{ + unsigned i; + d3d_video_t *d3d = (d3d_video_t*)data; + + if (!d3d) + return; + + for (i = 0; i < d3d->overlays_size; i++) + d3d->overlays_enabled = state; + + video_context_driver_show_mouse(&state); +} + +static void d3d_overlay_full_screen(void *data, bool enable) +{ + unsigned i; + d3d_video_t *d3d = (d3d_video_t*)data; + + for (i = 0; i < d3d->overlays_size; i++) + d3d->overlays[i].fullscreen = enable; +} + +static void d3d_overlay_set_alpha(void *data, unsigned index, float mod) +{ + d3d_video_t *d3d = (d3d_video_t*)data; + if (d3d) + d3d->overlays[index].alpha_mod = mod; +} + +static const video_overlay_interface_t d3d_overlay_interface = { + d3d_overlay_enable, + d3d_overlay_load, + d3d_overlay_tex_geom, + d3d_overlay_vertex_geom, + d3d_overlay_full_screen, + d3d_overlay_set_alpha, +}; + +static void d3d_get_overlay_interface(void *data, + const video_overlay_interface_t **iface) +{ + (void)data; + *iface = &d3d_overlay_interface; +} +#endif + +static bool d3d_frame(void *data, const void *frame, + unsigned frame_width, unsigned frame_height, + uint64_t frame_count, unsigned pitch, + const char *msg, video_frame_info_t *video_info) +{ + D3DVIEWPORT screen_vp; + unsigned i = 0; + d3d_video_t *d3d = (d3d_video_t*)data; + unsigned width = video_info->width; + unsigned height = video_info->height; + (void)i; + + if (!frame) + return true; + + /* We cannot recover in fullscreen. */ + if (d3d->needs_restore) + { +#ifndef _XBOX + HWND window = win32_get_window(); + if (IsIconic(window)) + return true; +#endif + + if (!d3d_restore(d3d)) + { + RARCH_ERR("[D3D]: Failed to restore.\n"); + return false; + } + } + + if (d3d->should_resize) + { + d3d_set_viewport(d3d, width, height, false, true); + if (d3d->renderchain_driver->set_final_viewport) + d3d->renderchain_driver->set_final_viewport(d3d, + d3d->renderchain_data, &d3d->final_viewport); + + d3d->should_resize = false; + } + + /* render_chain() only clears out viewport, + * clear out everything. */ + screen_vp.X = 0; + screen_vp.Y = 0; + screen_vp.MinZ = 0; + screen_vp.MaxZ = 1; + screen_vp.Width = width; + screen_vp.Height = height; + d3d_set_viewports(d3d->dev, &screen_vp); + d3d_clear(d3d->dev, 0, 0, D3DCLEAR_TARGET, 0, 1, 0); + + /* Insert black frame first, so we + * can screenshot, etc. */ + if (video_info->black_frame_insertion) + { + if (!d3d_swap(d3d, d3d->dev) || d3d->needs_restore) + return true; + d3d_clear(d3d->dev, 0, 0, D3DCLEAR_TARGET, 0, 1, 0); + } + + if (!d3d->renderchain_driver->render( + d3d, + frame, frame_width, frame_height, + pitch, d3d->dev_rotation)) + { + RARCH_ERR("[D3D]: Failed to render scene.\n"); + return false; + } + + +#ifdef HAVE_MENU + if (d3d->menu && d3d->menu->enabled) + { + d3d_set_mvp(d3d, NULL, &d3d->mvp); + d3d_overlay_render(d3d, video_info, d3d->menu); + + d3d->menu_display.offset = 0; + d3d_set_vertex_declaration(d3d->dev, d3d->menu_display.decl); + d3d_set_stream_source(d3d->dev, 0, d3d->menu_display.buffer, 0, sizeof(Vertex)); + + d3d_set_viewports(d3d->dev, &screen_vp); + menu_driver_frame(video_info); + } +#endif + +#ifdef HAVE_OVERLAY + if (d3d->overlays_enabled) + { + d3d_set_mvp(d3d, NULL, &d3d->mvp); + for (i = 0; i < d3d->overlays_size; i++) + d3d_overlay_render(d3d, video_info, &d3d->overlays[i]); + } +#endif + + if (msg && *msg) + { + d3d_set_viewports(d3d->dev, &screen_vp); + font_driver_render_msg(video_info, NULL, msg, NULL); + } + + video_info->cb_update_window_title( + video_info->context_data, video_info); + + video_info->cb_swap_buffers( + video_info->context_data, video_info); + + return true; +} + +static bool d3d_read_viewport(void *data, uint8_t *buffer, bool is_idle) +{ + d3d_video_t *d3d = (d3d_video_t*)data; + + if ( !d3d || + !d3d->renderchain_driver || + !d3d->renderchain_driver->read_viewport) + return false; + + return d3d->renderchain_driver->read_viewport(d3d, buffer, false); +} + +static bool d3d_set_shader(void *data, + enum rarch_shader_type type, const char *path) +{ + d3d_video_t *d3d = (d3d_video_t*)data; + char *old_shader = (d3d && !string_is_empty(d3d->shader_path)) ? strdup(d3d->shader_path) : NULL; + + if (!string_is_empty(d3d->shader_path)) + free(d3d->shader_path); + d3d->shader_path = NULL; + + switch (type) + { + case RARCH_SHADER_CG: + case RARCH_SHADER_HLSL: + if (!string_is_empty(path)) + d3d->shader_path = strdup(path); + break; + default: + break; + } + + if (!d3d_process_shader(d3d) || !d3d_restore(d3d)) + { + RARCH_ERR("[D3D]: Setting shader failed.\n"); + if (!string_is_empty(old_shader)) + { + d3d->shader_path = strdup(old_shader); + d3d_process_shader(d3d); + d3d_restore(d3d); + } + free(old_shader); + return false; + } + + return true; +} + +static void d3d_set_menu_texture_frame(void *data, + const void *frame, bool rgb32, unsigned width, unsigned height, + float alpha) +{ + D3DLOCKED_RECT d3dlr; + d3d_video_t *d3d = (d3d_video_t*)data; + + (void)d3dlr; + (void)frame; + (void)rgb32; + (void)width; + (void)height; + (void)alpha; + + if ( !d3d->menu->tex || + d3d->menu->tex_w != width || + d3d->menu->tex_h != height) + { + if (d3d->menu) + d3d_texture_free(d3d->menu->tex); + + d3d->menu->tex = d3d_texture_new(d3d->dev, NULL, + width, height, 1, + 0, d3d_get_argb8888_format(), + D3DPOOL_MANAGED, 0, 0, 0, NULL, NULL, false); + + if (!d3d->menu->tex) + { + RARCH_ERR("[D3D]: Failed to create menu texture.\n"); + return; + } + + d3d->menu->tex_w = width; + d3d->menu->tex_h = height; + } + + d3d->menu->alpha_mod = alpha; + + if (d3d_lock_rectangle(d3d->menu->tex, 0, &d3dlr, + NULL, 0, D3DLOCK_NOSYSLOCK)) + { + unsigned h, w; + if (rgb32) + { + uint8_t *dst = (uint8_t*)d3dlr.pBits; + const uint32_t *src = (const uint32_t*)frame; + + for (h = 0; h < height; h++, dst += d3dlr.Pitch, src += width) + { + memcpy(dst, src, width * sizeof(uint32_t)); + memset(dst + width * sizeof(uint32_t), 0, + d3dlr.Pitch - width * sizeof(uint32_t)); + } + } + else + { + uint32_t *dst = (uint32_t*)d3dlr.pBits; + const uint16_t *src = (const uint16_t*)frame; + + for (h = 0; h < height; h++, dst += d3dlr.Pitch >> 2, src += width) + { + for (w = 0; w < width; w++) + { + uint16_t c = src[w]; + uint32_t r = (c >> 12) & 0xf; + uint32_t g = (c >> 8) & 0xf; + uint32_t b = (c >> 4) & 0xf; + uint32_t a = (c >> 0) & 0xf; + r = ((r << 4) | r) << 16; + g = ((g << 4) | g) << 8; + b = ((b << 4) | b) << 0; + a = ((a << 4) | a) << 24; + dst[w] = r | g | b | a; + } + } + } + + + if (d3d->menu) + d3d_unlock_rectangle(d3d->menu->tex); + } +} + +static void d3d_set_menu_texture_enable(void *data, + bool state, bool full_screen) +{ + d3d_video_t *d3d = (d3d_video_t*)data; + + if (!d3d || !d3d->menu) + return; + + d3d->menu->enabled = state; + d3d->menu->fullscreen = full_screen; +} + +static void video_texture_load_d3d(d3d_video_t *d3d, + struct texture_image *ti, + enum texture_filter_type filter_type, + uintptr_t *id) +{ + D3DLOCKED_RECT d3dlr; + LPDIRECT3DTEXTURE tex = NULL; + unsigned usage = 0; + bool want_mipmap = false; + + if((filter_type == TEXTURE_FILTER_MIPMAP_LINEAR) || + (filter_type == TEXTURE_FILTER_MIPMAP_NEAREST)) + want_mipmap = true; + + tex = d3d_texture_new(d3d->dev, NULL, + ti->width, ti->height, 0, + usage, d3d_get_argb8888_format(), + D3DPOOL_MANAGED, 0, 0, 0, + NULL, NULL, want_mipmap); + + if (!tex) + { + RARCH_ERR("[D3D]: Failed to create texture\n"); + return; + } + + if (d3d_lock_rectangle(tex, 0, &d3dlr, + NULL, 0, D3DLOCK_NOSYSLOCK)) + { + unsigned i; + uint32_t *dst = (uint32_t*)(d3dlr.pBits); + const uint32_t *src = ti->pixels; + unsigned pitch = d3dlr.Pitch >> 2; + + for (i = 0; i < ti->height; i++, dst += pitch, src += ti->width) + memcpy(dst, src, ti->width << 2); + d3d_unlock_rectangle(tex); + } + + *id = (uintptr_t)tex; +} + +static int video_texture_load_wrap_d3d_mipmap(void *data) +{ + uintptr_t id = 0; + video_texture_load_d3d((d3d_video_t*)video_driver_get_ptr(true), + (struct texture_image*)data, TEXTURE_FILTER_MIPMAP_LINEAR, &id); + return id; +} + +static int video_texture_load_wrap_d3d(void *data) +{ + uintptr_t id = 0; + video_texture_load_d3d((d3d_video_t*)video_driver_get_ptr(true), + (struct texture_image*)data, TEXTURE_FILTER_LINEAR, &id); + return id; +} + +static uintptr_t d3d_load_texture(void *video_data, void *data, + bool threaded, enum texture_filter_type filter_type) +{ + uintptr_t id = 0; + + if (threaded) + { + custom_command_method_t func = video_texture_load_wrap_d3d; + + switch (filter_type) + { + case TEXTURE_FILTER_MIPMAP_LINEAR: + case TEXTURE_FILTER_MIPMAP_NEAREST: + func = video_texture_load_wrap_d3d_mipmap; + break; + default: + func = video_texture_load_wrap_d3d; + break; + } + + return video_thread_texture_load(data, func); + } + + video_texture_load_d3d((d3d_video_t*)video_driver_get_ptr(false), + (struct texture_image*)data, filter_type, &id); + return id; +} + +static void d3d_unload_texture(void *data, uintptr_t id) +{ + LPDIRECT3DTEXTURE texid; + if (!id) + return; + + texid = (LPDIRECT3DTEXTURE)id; + d3d_texture_free(texid); +} + +static const video_poke_interface_t d3d_poke_interface = { + NULL, /* set_coords */ + d3d_set_mvp, + d3d_load_texture, + d3d_unload_texture, + NULL, + NULL, + NULL, /* get_video_output_size */ + NULL, /* get_video_output_prev */ + NULL, /* get_video_output_next */ + NULL, /* get_current_framebuffer */ + NULL, /* get_proc_address */ + d3d_set_aspect_ratio, + d3d_apply_state_changes, + d3d_set_menu_texture_frame, + d3d_set_menu_texture_enable, + d3d_set_osd_msg, + + d3d_show_mouse, +}; + +static void d3d_get_poke_interface(void *data, + const video_poke_interface_t **iface) +{ + (void)data; + *iface = &d3d_poke_interface; +} + +video_driver_t video_d3d9 = { + d3d_init, + d3d_frame, + d3d_set_nonblock_state, + d3d_alive, + NULL, /* focus */ + d3d_suppress_screensaver, + NULL, /* has_windowed */ + d3d_set_shader, + d3d_free, + "d3d9", + d3d_set_viewport, + d3d_set_rotation, + d3d_viewport_info, + d3d_read_viewport, + NULL, /* read_frame_raw */ +#ifdef HAVE_OVERLAY + d3d_get_overlay_interface, +#endif + d3d_get_poke_interface +}; diff --git a/gfx/drivers_renderchain/d3d8_renderchain.c b/gfx/drivers_renderchain/d3d8_renderchain.c index c3614a8d9e..9020200650 100644 --- a/gfx/drivers_renderchain/d3d8_renderchain.c +++ b/gfx/drivers_renderchain/d3d8_renderchain.c @@ -144,7 +144,7 @@ static void d3d8_renderchain_set_vertices(void *data, unsigned pass, vert[2].v = tex_h; vert[3].u = tex_w; vert[3].v = tex_h; -#ifndef _XBOX1 +#ifndef _XBOX vert[1].u /= chain->tex_w; vert[2].v /= chain->tex_h; vert[3].u /= chain->tex_w; diff --git a/gfx/drivers_renderchain/d3d9_hlsl_renderchain.c b/gfx/drivers_renderchain/d3d9_hlsl_renderchain.c index 48308457ba..d4a9488c35 100644 --- a/gfx/drivers_renderchain/d3d9_hlsl_renderchain.c +++ b/gfx/drivers_renderchain/d3d9_hlsl_renderchain.c @@ -184,8 +184,10 @@ static void hlsl_d3d9_renderchain_set_vertices( d3d_vertex_buffer_unlock(chain->vertex_buf); } - hlsl_d3d9_renderchain_set_mvp(chain, - d3d, width, height, d3d->dev_rotation); + /* TODO/FIXME - last parameter is mat_data, should be set to + something other than NULL */ + hlsl_d3d9_renderchain_set_mvp(d3d, chain, &d3d->shader, + NULL); shader_info.data = d3d; shader_info.idx = pass; @@ -386,8 +388,10 @@ static bool hlsl_d3d9_renderchain_render(void *data, const void *frame, d3d_set_stream_source(d3dr, i, chain->vertex_buf, 0, sizeof(Vertex)); d3d_draw_primitive(d3dr, D3DPT_TRIANGLESTRIP, 0, 2); - hlsl_d3d9_renderchain_set_mvp( - chain, d3d, width, height, d3d->dev_rotation); + /* TODO/FIXME - last parameter is mat_data - should be something + other than NULL */ + hlsl_d3d9_renderchain_set_mvp(d3d, + chain, &d3d->shader, NULL); return true; } diff --git a/gfx/video_driver.c b/gfx/video_driver.c index cf19329940..2ef37d1215 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -268,8 +268,11 @@ static const video_driver_t *video_drivers[] = { #if defined(HAVE_D3D12) &video_d3d12, #endif -#if defined(HAVE_D3D) - &video_d3d, +#if defined(HAVE_D3D9) + &video_d3d9, +#endif +#if defined(HAVE_D3D8) + &video_d3d8, #endif #ifdef HAVE_VITA2D &video_vita2d, @@ -413,19 +416,6 @@ static const shader_backend_t *shader_ctx_drivers[] = { NULL }; -static const d3d_renderchain_driver_t *renderchain_d3d_drivers[] = { -#if defined(_WIN32) && defined(HAVE_D3D9) && defined(HAVE_CG) - &cg_d3d9_renderchain, -#endif -#if defined(_WIN32) && defined(HAVE_D3D9) && defined(HAVE_HLSL) - &hlsl_d3d9_renderchain, -#endif -#if defined(_WIN32) && defined(HAVE_D3D8) - &d3d8_d3d_renderchain, -#endif - &null_d3d_renderchain, - NULL -}; static const gl_renderchain_driver_t *renderchain_gl_drivers[] = { #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) @@ -3436,23 +3426,59 @@ void video_driver_set_mvp(video_shader_ctx_mvp_t *mvp) } bool renderchain_d3d_init_first( + enum d3d_comm_api api, const d3d_renderchain_driver_t **renderchain_driver, void **renderchain_handle) { unsigned i; - for (i = 0; renderchain_d3d_drivers[i]; i++) + switch (api) { - void *data = renderchain_d3d_drivers[i]->chain_new(); + case D3D_COMM_D3D9: +#ifdef HAVE_D3D9 + { + static const d3d_renderchain_driver_t *renderchain_d3d_drivers[] = { +#if defined(_WIN32) && defined(HAVE_CG) + &cg_d3d9_renderchain, +#endif +#if defined(_WIN32) && defined(HAVE_HLSL) + &hlsl_d3d9_renderchain, +#endif + &null_d3d_renderchain, + NULL + }; + for (i = 0; renderchain_d3d_drivers[i]; i++) + { + void *data = renderchain_d3d_drivers[i]->chain_new(); - if (!data) - continue; + if (!data) + continue; - *renderchain_driver = renderchain_d3d_drivers[i]; - *renderchain_handle = data; - return true; + *renderchain_driver = renderchain_d3d_drivers[i]; + *renderchain_handle = data; + return true; + } + } +#endif + break; + case D3D_COMM_D3D8: + { +#ifdef HAVE_D3D8 + void *data = d3d8_d3d_renderchain.chain_new(); + + if (data) + { + *renderchain_driver = &d3d8_d3d_renderchain; + *renderchain_handle = data; + } +#endif + } + break; + case D3D_COMM_NONE: + break; } + return false; } diff --git a/gfx/video_driver.h b/gfx/video_driver.h index af527041b8..b95bf78b9b 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -33,6 +33,10 @@ #include "../input/input_overlay.h" #endif +#ifdef HAVE_D3D +#include "common/d3d_common.h" +#endif + #include "video_defines.h" #include "video_coord_array.h" #include "video_filter.h" @@ -1317,6 +1321,7 @@ bool video_shader_driver_compile_program(struct shader_program_info *program_inf bool video_shader_driver_wrap_type(video_shader_ctx_wrap_t *wrap); bool renderchain_d3d_init_first( + enum d3d_comm_api api, const d3d_renderchain_driver_t **renderchain_driver, void **renderchain_handle); @@ -1335,7 +1340,8 @@ extern video_driver_t video_psp1; extern video_driver_t video_vita2d; extern video_driver_t video_ctr; extern video_driver_t video_switch; -extern video_driver_t video_d3d; +extern video_driver_t video_d3d8; +extern video_driver_t video_d3d9; extern video_driver_t video_d3d11; extern video_driver_t video_d3d12; extern video_driver_t video_gx; diff --git a/griffin/griffin.c b/griffin/griffin.c index 5efee2185f..c0607d7a36 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -324,14 +324,15 @@ VIDEO DRIVER ============================================================ */ #if defined(HAVE_D3D) #include "../gfx/common/d3d_common.c" -#include "../gfx/drivers/d3d.c" #include "../gfx/drivers_context/d3d_ctx.c" #if defined(HAVE_D3D8) +#include "../gfx/drivers/d3d8.c" #include "../gfx/drivers_renderchain/d3d8_renderchain.c" #endif #if defined(HAVE_D3D9) +#include "../gfx/drivers/d3d9.c" #ifdef HAVE_HLSL #include "../gfx/drivers_renderchain/d3d9_hlsl_renderchain.c" diff --git a/menu/menu_driver.c b/menu/menu_driver.c index 97a43a449e..93de7a32f3 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -217,7 +217,9 @@ static bool menu_display_check_compatibility( return true; break; case MENU_VIDEO_DRIVER_DIRECT3D: - if (string_is_equal(video_driver, "d3d")) + if ( string_is_equal(video_driver, "d3d9") || + string_is_equal(video_driver, "d3d8") + ) return true; break; case MENU_VIDEO_DRIVER_VITA2D: