mirror of
https://github.com/libretro/RetroArch
synced 2025-02-28 22:13:51 +00:00
add D3D12 HW_render support. (#15177)
This commit is contained in:
parent
4350ec24be
commit
0adbd6905f
@ -25,6 +25,8 @@
|
||||
#include "dxgi_common.h"
|
||||
#include <d3d12.h>
|
||||
|
||||
#include <libretro_d3d.h>
|
||||
|
||||
#include "../common/d3dcompiler_common.h"
|
||||
#include "../drivers_shader/slang_process.h"
|
||||
|
||||
@ -166,7 +168,8 @@ enum d3d12_video_flags
|
||||
D3D12_ST_FLAG_HDR_ENABLE = (1 << 11),
|
||||
D3D12_ST_FLAG_VSYNC = (1 << 12),
|
||||
D3D12_ST_FLAG_WAITABLE_SWAPCHAINS = (1 << 13),
|
||||
D3D12_ST_FLAG_WAIT_FOR_VBLANK = (1 << 14)
|
||||
D3D12_ST_FLAG_WAIT_FOR_VBLANK = (1 << 14),
|
||||
D3D12_ST_FLAG_HW_IFACE_ENABLE = (1 << 15)
|
||||
};
|
||||
|
||||
typedef struct
|
||||
@ -188,6 +191,10 @@ typedef struct
|
||||
#endif /* DEBUG */
|
||||
#endif /* DEVICE_DEBUG */
|
||||
|
||||
struct retro_hw_render_interface_d3d12 hw_iface;
|
||||
D3D12Resource hw_render_texture;
|
||||
DXGI_FORMAT hw_render_texture_format;
|
||||
|
||||
IDXGIAdapter1 *adapters[D3D12_MAX_GPU_COUNT];
|
||||
struct string_list *gpu_list;
|
||||
|
||||
|
@ -887,7 +887,7 @@ static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12)
|
||||
}
|
||||
#endif
|
||||
|
||||
desc.BlendState.RenderTarget[0] = d3d12_blend_enable_desc;
|
||||
desc.BlendState.RenderTarget[0] = d3d12_blend_disable_desc;
|
||||
desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
|
||||
{
|
||||
@ -1738,7 +1738,7 @@ static void d3d12_init_queue(d3d12_video_t* d3d12)
|
||||
{
|
||||
static const D3D12_COMMAND_QUEUE_DESC desc = {
|
||||
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||
0,
|
||||
D3D12_COMMAND_QUEUE_PRIORITY_NORMAL,
|
||||
D3D12_COMMAND_QUEUE_FLAG_NONE,
|
||||
0
|
||||
};
|
||||
@ -1793,6 +1793,13 @@ static void d3d12_create_fullscreen_quad_vbo(
|
||||
D3D12Unmap(*vbo, 0, NULL);
|
||||
}
|
||||
|
||||
static void d3d12_set_hw_render_texture(void* data, ID3D12Resource* texture, DXGI_FORMAT format)
|
||||
{
|
||||
d3d12_video_t* d3d12 = (d3d12_video_t*)data;
|
||||
d3d12->hw_render_texture = texture;
|
||||
d3d12->hw_render_texture_format = format;
|
||||
}
|
||||
|
||||
static void *d3d12_gfx_init(const video_info_t* video,
|
||||
input_driver_t** input, void** input_data)
|
||||
{
|
||||
@ -1982,6 +1989,20 @@ static void *d3d12_gfx_init(const video_info_t* video,
|
||||
d3d12_gfx_set_shader(d3d12, type, shader_preset);
|
||||
}
|
||||
|
||||
if ( video_driver_get_hw_context()->context_type == RETRO_HW_CONTEXT_DIRECT3D
|
||||
&& video_driver_get_hw_context()->version_major == 12)
|
||||
{
|
||||
d3d12->flags |= D3D12_ST_FLAG_HW_IFACE_ENABLE;
|
||||
d3d12->hw_iface.interface_type = RETRO_HW_RENDER_INTERFACE_D3D12;
|
||||
d3d12->hw_iface.interface_version = RETRO_HW_RENDER_INTERFACE_D3D12_VERSION;
|
||||
d3d12->hw_iface.handle = d3d12;
|
||||
d3d12->hw_iface.device = d3d12->device;
|
||||
d3d12->hw_iface.queue = d3d12->queue.handle;
|
||||
d3d12->hw_iface.required_state = D3D12_RESOURCE_STATE_COPY_SOURCE;
|
||||
d3d12->hw_iface.set_texture = d3d12_set_hw_render_texture;
|
||||
d3d12->hw_iface.D3DCompile = D3DCompile;
|
||||
}
|
||||
|
||||
return d3d12;
|
||||
|
||||
error:
|
||||
@ -2332,6 +2353,20 @@ static bool d3d12_gfx_frame(
|
||||
|
||||
if (frame && width && height)
|
||||
{
|
||||
if (frame == RETRO_HW_FRAME_BUFFER_VALID)
|
||||
{
|
||||
if (d3d12->frame.texture[0].desc.Format != d3d12->hw_render_texture_format)
|
||||
{
|
||||
d3d12->frame.texture[0].desc.Width = width;
|
||||
d3d12->frame.texture[0].desc.Height = height;
|
||||
d3d12->frame.texture[0].desc.Format = d3d12->hw_render_texture_format;
|
||||
d3d12_release_texture(&d3d12->frame.texture[0]);
|
||||
d3d12_init_texture(d3d12->device, &d3d12->frame.texture[0]);
|
||||
|
||||
d3d12->flags |= D3D12_ST_FLAG_INIT_HISTORY;
|
||||
}
|
||||
}
|
||||
|
||||
if (d3d12->shader_preset)
|
||||
{
|
||||
if (d3d12->shader_preset->luts && d3d12->luts[0].dirty)
|
||||
@ -2387,11 +2422,51 @@ static bool d3d12_gfx_frame(
|
||||
if (d3d12->flags & D3D12_ST_FLAG_RESIZE_RTS)
|
||||
d3d12_init_render_targets(d3d12, width, height);
|
||||
|
||||
if(frame == RETRO_HW_FRAME_BUFFER_VALID)
|
||||
{
|
||||
D3D12_BOX src_box;
|
||||
D3D12_TEXTURE_COPY_LOCATION src, dst;
|
||||
|
||||
src_box.left = 0;
|
||||
src_box.top = 0;
|
||||
src_box.front = 0;
|
||||
src_box.right = width;
|
||||
src_box.bottom = height;
|
||||
src_box.back = 1;
|
||||
|
||||
src.pResource = d3d12->hw_render_texture;
|
||||
src.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
src.SubresourceIndex = 0;
|
||||
|
||||
dst.pResource = d3d12->frame.texture[0].handle;
|
||||
dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
dst.SubresourceIndex = 0;
|
||||
|
||||
D3D12_RESOURCE_TRANSITION(
|
||||
d3d12->queue.cmd,
|
||||
d3d12->frame.texture[0].handle,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
|
||||
D3D12CopyTextureRegion(d3d12->queue.cmd, &dst, 0, 0, 0, &src, &src_box);
|
||||
|
||||
D3D12_RESOURCE_TRANSITION(
|
||||
d3d12->queue.cmd,
|
||||
d3d12->frame.texture[0].handle,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
|
||||
d3d12->hw_render_texture = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
d3d12_update_texture(width, height, pitch, d3d12->format,
|
||||
frame, &d3d12->frame.texture[0]);
|
||||
|
||||
d3d12_upload_texture(d3d12->queue.cmd, &d3d12->frame.texture[0],
|
||||
d3d12);
|
||||
|
||||
}
|
||||
}
|
||||
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->frame.vbo_view);
|
||||
|
||||
@ -3058,6 +3133,15 @@ static void d3d12_gfx_unload_texture(void* data,
|
||||
free(texture);
|
||||
}
|
||||
|
||||
static bool d3d12_get_hw_render_interface(
|
||||
void* data, const struct retro_hw_render_interface** iface)
|
||||
{
|
||||
d3d12_video_t* d3d12 = (d3d12_video_t*)data;
|
||||
*iface = (const struct retro_hw_render_interface*)
|
||||
&d3d12->hw_iface;
|
||||
return d3d12->flags & D3D12_ST_FLAG_HW_IFACE_ENABLE;
|
||||
}
|
||||
|
||||
#ifndef __WINRT__
|
||||
static void d3d12_get_video_output_size(void *data,
|
||||
unsigned *width, unsigned *height, char *desc, size_t desc_len)
|
||||
@ -3112,7 +3196,7 @@ static const video_poke_interface_t d3d12_poke_interface = {
|
||||
NULL, /* grab_mouse_toggle */
|
||||
d3d12_gfx_get_current_shader,
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL, /* get_hw_render_interface */
|
||||
d3d12_get_hw_render_interface,
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
d3d12_set_hdr_max_nits,
|
||||
d3d12_set_hdr_paper_white_nits,
|
||||
|
@ -505,6 +505,10 @@ const char *hw_render_context_name(
|
||||
if (type == RETRO_HW_CONTEXT_DIRECT3D && major == 11)
|
||||
return "d3d11";
|
||||
#endif
|
||||
#ifdef HAVE_D3D12
|
||||
if (type == RETRO_HW_CONTEXT_DIRECT3D && major == 12)
|
||||
return "d3d12";
|
||||
#endif
|
||||
#ifdef HAVE_D3D9
|
||||
#if defined(HAVE_HLSL)
|
||||
if (type == RETRO_HW_CONTEXT_DIRECT3D && major == 9)
|
||||
|
@ -56,4 +56,32 @@ struct retro_hw_render_interface_d3d11
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_D3D12
|
||||
|
||||
#include <d3d12.h>
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
#define RETRO_HW_RENDER_INTERFACE_D3D12_VERSION 1
|
||||
|
||||
struct retro_hw_render_interface_d3d12
|
||||
{
|
||||
/* Must be set to RETRO_HW_RENDER_INTERFACE_D3D12. */
|
||||
enum retro_hw_render_interface_type interface_type;
|
||||
/* Must be set to RETRO_HW_RENDER_INTERFACE_D3D12_VERSION. */
|
||||
unsigned interface_version;
|
||||
|
||||
/* Opaque handle to the d3d12 backend in the frontend
|
||||
* which must be passed along to all function pointers
|
||||
* in this interface.
|
||||
*/
|
||||
void* handle;
|
||||
ID3D12Device *device;
|
||||
ID3D12CommandQueue *queue;
|
||||
pD3DCompile D3DCompile;
|
||||
D3D12_RESOURCE_STATES required_state;
|
||||
void (*set_texture)(void* handle, ID3D12Resource* texture, DXGI_FORMAT format);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* LIBRETRO_DIRECT3D_H__ */
|
||||
|
10
runloop.c
10
runloop.c
@ -740,7 +740,8 @@ static bool dynamic_verify_hw_context(
|
||||
return false;
|
||||
break;
|
||||
case RETRO_HW_CONTEXT_DIRECT3D:
|
||||
if (!(string_is_equal(video_ident, "d3d11") && major == 11))
|
||||
if (!((string_is_equal(video_ident, "d3d11") && major == 11) ||
|
||||
(string_is_equal(video_ident, "d3d12") && major == 12)))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
@ -834,7 +835,7 @@ static bool dynamic_request_hw_context(enum retro_hw_context_type type,
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_D3D9) || defined(HAVE_D3D11)
|
||||
#if defined(HAVE_D3D9) || defined(HAVE_D3D11) || defined(HAVE_D3D12)
|
||||
case RETRO_HW_CONTEXT_DIRECT3D:
|
||||
switch (major)
|
||||
{
|
||||
@ -847,6 +848,11 @@ static bool dynamic_request_hw_context(enum retro_hw_context_type type,
|
||||
case 11:
|
||||
RARCH_LOG("Requesting D3D11 context.\n");
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_D3D12
|
||||
case 12:
|
||||
RARCH_LOG("Requesting D3D12 context.\n");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
RARCH_LOG("Requesting unknown context.\n");
|
||||
|
Loading…
x
Reference in New Issue
Block a user