diff --git a/dynamic.c b/dynamic.c index 6a8ede407d..3e89144f81 100644 --- a/dynamic.c +++ b/dynamic.c @@ -885,6 +885,23 @@ static bool dynamic_request_hw_context(enum retro_hw_context_type type, break; #endif + case RETRO_HW_CONTEXT_DIRECT3D: + switch(major) + { +#ifdef HAVE_D3D9 + case 9: +#endif +#ifdef HAVE_D3D11 + case 11: +#endif + RARCH_LOG("Requesting D3D%i context.\n", major); + break; + default: + goto unknown; + } + break; + +unknown: default: RARCH_LOG("Requesting unknown context.\n"); return false; @@ -912,6 +929,10 @@ static bool dynamic_verify_hw_context(enum retro_hw_context_type type, if (!string_is_equal(video_ident, "gl")) return false; break; + case RETRO_HW_CONTEXT_DIRECT3D: + if (!(string_is_equal(video_ident, "d3d11") && major == 11)) + return false; + break; default: break; } diff --git a/gfx/common/d3d11_common.h b/gfx/common/d3d11_common.h index 619110345b..68333f1605 100644 --- a/gfx/common/d3d11_common.h +++ b/gfx/common/d3d11_common.h @@ -2420,6 +2420,7 @@ D3D11UnmapBuffer(D3D11DeviceContext device_context, D3D11Buffer buffer, UINT sub #include #include #include +#include #include "../video_driver.h" #include "../drivers_shader/slang_process.h" @@ -2518,7 +2519,13 @@ typedef struct bool init_history; d3d11_shader_t shaders[GFX_MAX_SHADERS]; - struct + struct + { + bool enable; + struct retro_hw_render_interface_d3d11 iface; + } hw; + + struct { d3d11_shader_t shader; d3d11_shader_t shader_font; diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index fb8077f1cc..a33fa75ad1 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -900,6 +900,19 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i d3d11_gfx_set_shader(d3d11, RARCH_SHADER_SLANG, settings->paths.path_shader); } + if (video_driver_get_hw_context()->context_type == RETRO_HW_CONTEXT_DIRECT3D && + video_driver_get_hw_context()->version_major == 11) + { + d3d11->hw.enable = true; + d3d11->hw.iface.interface_type = RETRO_HW_RENDER_INTERFACE_D3D11; + d3d11->hw.iface.interface_version = RETRO_HW_RENDER_INTERFACE_D3D11_VERSION; + d3d11->hw.iface.handle = d3d11; + d3d11->hw.iface.device = d3d11->device; + d3d11->hw.iface.context = d3d11->context; + d3d11->hw.iface.featureLevel = d3d11->supportedFeatureLevel; + d3d11->hw.iface.D3DCompile = D3DCompile; + } + return d3d11; error: @@ -1076,6 +1089,12 @@ static bool d3d11_gfx_frame( D3D11SetPrimitiveTopology(context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + if (d3d11->hw.enable) + { + D3D11SetRenderTargets(context, 1, &d3d11->renderTargetView, NULL); + D3D11SetState(context, d3d11->state); + } + if (frame && width && height) { if (d3d11->shader_preset) @@ -1125,8 +1144,9 @@ static bool d3d11_gfx_frame( if (d3d11->resize_render_targets) d3d11_init_render_targets(d3d11, width, height); - d3d11_update_texture( - context, width, height, pitch, d3d11->format, frame, &d3d11->frame.texture[0]); + if (frame != RETRO_HW_FRAME_BUFFER_VALID) + d3d11_update_texture( + context, width, height, pitch, d3d11->format, frame, &d3d11->frame.texture[0]); } D3D11SetVertexBuffer(context, 0, d3d11->frame.vbo, sizeof(d3d11_vertex_t), 0); @@ -1203,7 +1223,11 @@ static bool d3d11_gfx_frame( texture_sem++; } - D3D11SetPShaderResources(context, 0, SLANG_NUM_BINDINGS, textures); + if (d3d11->hw.enable && (i == 0)) + D3D11SetPShaderResources(context, 1, SLANG_NUM_BINDINGS - 1, textures + 1); + else + D3D11SetPShaderResources(context, 0, SLANG_NUM_BINDINGS, textures); + D3D11SetPShaderSamplers(context, 0, SLANG_NUM_BINDINGS, samplers); } @@ -1230,7 +1254,8 @@ static bool d3d11_gfx_frame( if (texture) { d3d11_set_shader(context, &d3d11->shaders[VIDEO_SHADER_STOCK_BLEND]); - D3D11SetPShaderResources(context, 0, 1, &texture->view); + if (!d3d11->hw.enable || d3d11->shader_preset) + D3D11SetPShaderResources(context, 0, 1, &texture->view); D3D11SetPShaderSamplers( context, 0, 1, &d3d11->samplers[RARCH_FILTER_UNSPEC][RARCH_WRAP_DEFAULT]); D3D11SetVShaderConstantBuffers(context, 0, 1, &d3d11->frame.ubo); @@ -1270,15 +1295,15 @@ static bool d3d11_gfx_frame( } else if (video_info->statistics_show) { - struct font_params *osd_params = (struct font_params*) - &video_info->osd_stat_params; + struct font_params* osd_params = (struct font_params*)&video_info->osd_stat_params; if (osd_params) { D3D11SetViewports(context, 1, &d3d11->viewport); D3D11SetBlendState(d3d11->context, d3d11->blend_enable, NULL, D3D11_DEFAULT_SAMPLE_MASK); D3D11SetVertexBuffer(context, 0, d3d11->sprites.vbo, sizeof(d3d11_sprite_t), 0); - font_driver_render_msg(video_info, NULL, video_info->stat_text, + font_driver_render_msg( + video_info, NULL, video_info->stat_text, (const struct font_params*)&video_info->osd_stat_params); } } @@ -1443,7 +1468,7 @@ static void d3d11_gfx_set_osd_msg( if (d3d11) { if (d3d11->sprites.enabled) - font_driver_render_msg(video_info, font, msg, params); + font_driver_render_msg(video_info, font, msg, (const struct font_params*)params); else printf("OSD msg: %s\n", msg); } @@ -1507,6 +1532,14 @@ static void d3d11_gfx_unload_texture(void* data, uintptr_t handle) free(texture); } +static bool +d3d11_get_hw_render_interface(void* data, const struct retro_hw_render_interface** iface) +{ + d3d11_video_t* d3d11 = (d3d11_video_t*)data; + *iface = (const struct retro_hw_render_interface*)&d3d11->hw.iface; + return d3d11->hw.enable; +} + static const video_poke_interface_t d3d11_poke_interface = { NULL, /* set_coords */ NULL, /* set_mvp */ @@ -1528,7 +1561,7 @@ static const video_poke_interface_t d3d11_poke_interface = { NULL, /* grab_mouse_toggle */ d3d11_gfx_get_current_shader, NULL, /* get_current_software_framebuffer */ - NULL, /* get_hw_render_interface */ + d3d11_get_hw_render_interface, }; static void d3d11_gfx_get_poke_interface(void* data, const video_poke_interface_t** iface) diff --git a/gfx/drivers/d3d9.c b/gfx/drivers/d3d9.c index b9a5afcab1..24b54dcf77 100644 --- a/gfx/drivers/d3d9.c +++ b/gfx/drivers/d3d9.c @@ -1072,7 +1072,7 @@ static void d3d9_set_osd_msg(void *data, d3d->renderchain_driver->set_font_rect(d3d, params); d3d9_begin_scene(d3d->dev); - font_driver_render_msg(video_info, font, msg, params); + font_driver_render_msg(video_info, font, msg, (const struct font_params *)params); d3d9_end_scene(d3d->dev); } diff --git a/gfx/drivers/gdi_gfx.c b/gfx/drivers/gdi_gfx.c index 7025cd9711..6ac92b19c4 100644 --- a/gfx/drivers/gdi_gfx.c +++ b/gfx/drivers/gdi_gfx.c @@ -498,7 +498,7 @@ static void gdi_set_osd_msg(void *data, const char *msg, const void *params, void *font) { - font_driver_render_msg(video_info, font, msg, params); + font_driver_render_msg(video_info, font, msg, (const struct font_params *)params); } static void gdi_get_video_output_size(void *data, diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index 940e663dcb..720a4b238b 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -853,7 +853,7 @@ static void gl_set_osd_msg(void *data, const char *msg, const void *params, void *font) { - font_driver_render_msg(video_info, font, msg, params); + font_driver_render_msg(video_info, font, msg, (const struct font_params *)params); } #if defined(HAVE_MENU) diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index 722f45a176..cb62be8ffc 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -2219,7 +2219,7 @@ static void vulkan_set_osd_msg(void *data, const char *msg, const void *params, void *font) { - font_driver_render_msg(video_info, font, msg, params); + font_driver_render_msg(video_info, font, msg, (const struct font_params *)params); } static uintptr_t vulkan_load_texture(void *video_data, void *data, diff --git a/libretro-common/include/libretro.h b/libretro-common/include/libretro.h index 6155be31a2..bfe832c202 100644 --- a/libretro-common/include/libretro.h +++ b/libretro-common/include/libretro.h @@ -1088,8 +1088,12 @@ struct retro_vfs_interface_info enum retro_hw_render_interface_type { - RETRO_HW_RENDER_INTERFACE_VULKAN = 0, - RETRO_HW_RENDER_INTERFACE_DUMMY = INT_MAX + RETRO_HW_RENDER_INTERFACE_VULKAN = 0, + RETRO_HW_RENDER_INTERFACE_D3D9 = 1, + RETRO_HW_RENDER_INTERFACE_D3D10 = 2, + RETRO_HW_RENDER_INTERFACE_D3D11 = 3, + RETRO_HW_RENDER_INTERFACE_D3D12 = 4, + RETRO_HW_RENDER_INTERFACE_DUMMY = INT_MAX }; /* Base struct. All retro_hw_render_interface_* types @@ -1103,7 +1107,7 @@ struct retro_hw_render_interface #define RETRO_ENVIRONMENT_GET_LED_INTERFACE (46 | RETRO_ENVIRONMENT_EXPERIMENTAL) /* struct retro_led_interface * -- - * Gets an interface which is used by a libretro core to set + * Gets an interface which is used by a libretro core to set * state of LEDs. */ @@ -1851,6 +1855,10 @@ enum retro_hw_context_type /* Vulkan, see RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE. */ RETRO_HW_CONTEXT_VULKAN = 6, + /* Direct3D, set version_major to select the type of interface + * returned by RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE */ + RETRO_HW_CONTEXT_DIRECT3D = 7, + RETRO_HW_CONTEXT_DUMMY = INT_MAX }; diff --git a/libretro-common/include/libretro_d3d.h b/libretro-common/include/libretro_d3d.h new file mode 100644 index 0000000000..2ed71aa7c0 --- /dev/null +++ b/libretro-common/include/libretro_d3d.h @@ -0,0 +1,60 @@ +/* Copyright (C) 2010-2016 The RetroArch team + * + * --------------------------------------------------------------------------------------------- + * The following license statement only applies to this libretro API header (libretro_vulkan.h) + * --------------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the + * "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LIBRETRO_DIRECT3D_H__ +#define LIBRETRO_DIRECT3D_H__ + +#include "libretro.h" + +#ifdef HAVE_D3D11 + +#include +#include + +#define RETRO_HW_RENDER_INTERFACE_D3D11_VERSION 1 + +struct retro_hw_render_interface_d3d11 +{ + /* Must be set to RETRO_HW_RENDER_INTERFACE_D3D11. */ + enum retro_hw_render_interface_type interface_type; + /* Must be set to RETRO_HW_RENDER_INTERFACE_D3D11_VERSION. */ + unsigned interface_version; + + /* Opaque handle to the d3d11 backend in the frontend + * which must be passed along to all function pointers + * in this interface. + */ + void* handle; + ID3D11Device *device; + ID3D11DeviceContext *context; + D3D_FEATURE_LEVEL featureLevel; + pD3DCompile D3DCompile; +}; + + +#endif + +#endif /* LIBRETRO_DIRECT3D_H__ */ diff --git a/pkg/msvc/msvc-2015/RetroArch-msvc2015.vcxproj b/pkg/msvc/msvc-2015/RetroArch-msvc2015.vcxproj index 9016d5e002..eb0955f903 100644 --- a/pkg/msvc/msvc-2015/RetroArch-msvc2015.vcxproj +++ b/pkg/msvc/msvc-2015/RetroArch-msvc2015.vcxproj @@ -233,6 +233,7 @@ $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\gfx\include\dxsdk;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp + /bigobj Fast StreamingSIMDExtensions2 @@ -376,4 +377,4 @@ - \ No newline at end of file +