mirror of
https://github.com/libretro/RetroArch
synced 2025-04-16 08:43:10 +00:00
(D3D12) add menu display driver.
This commit is contained in:
parent
92afd7387d
commit
0d88799e6d
@ -1269,7 +1269,7 @@ endif
|
|||||||
|
|
||||||
ifeq ($(HAVE_D3D12), 1)
|
ifeq ($(HAVE_D3D12), 1)
|
||||||
OBJ += gfx/drivers/d3d12.o gfx/common/d3d12_common.o \
|
OBJ += gfx/drivers/d3d12.o gfx/common/d3d12_common.o \
|
||||||
gfx/drivers_font/d3d12_font.o
|
gfx/drivers_font/d3d12_font.o menu/drivers_display/menu_display_d3d12.o
|
||||||
DEFINES += -DHAVE_D3D12
|
DEFINES += -DHAVE_D3D12
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ HAVE_LANGEXTRA := 1
|
|||||||
HAVE_CHEEVOS := 1
|
HAVE_CHEEVOS := 1
|
||||||
HAVE_KEYMAPPER := 1
|
HAVE_KEYMAPPER := 1
|
||||||
HAVE_SHADERPIPELINE := 1
|
HAVE_SHADERPIPELINE := 1
|
||||||
|
HAVE_IMAGEVIEWER := 1
|
||||||
|
|
||||||
include Makefile.common
|
include Makefile.common
|
||||||
INCLUDE_DIRS := $(patsubst -isystem%,-I%,$(INCLUDE_DIRS))
|
INCLUDE_DIRS := $(patsubst -isystem%,-I%,$(INCLUDE_DIRS))
|
||||||
|
@ -1311,7 +1311,27 @@ typedef struct
|
|||||||
bool dirty;
|
bool dirty;
|
||||||
} d3d12_texture_t;
|
} d3d12_texture_t;
|
||||||
|
|
||||||
#define TEXTURE_DESC_SLOTS_COUNT 128
|
#ifndef ALIGN
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define ALIGN(x) __declspec(align(x))
|
||||||
|
#else
|
||||||
|
#define ALIGN(x) __attribute__((aligned(x)))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct ALIGN(16)
|
||||||
|
{
|
||||||
|
math_matrix_4x4 mvp;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
float width;
|
||||||
|
float height;
|
||||||
|
} OutputSize;
|
||||||
|
float time;
|
||||||
|
} d3d12_uniform_t;
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
(!(sizeof(d3d12_uniform_t) & 0xF)), "sizeof(d3d12_uniform_t) must be a multiple of 16");
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -1386,6 +1406,7 @@ typedef struct
|
|||||||
} sprites;
|
} sprites;
|
||||||
|
|
||||||
D3D12PipelineState pipes[GFX_MAX_SHADERS];
|
D3D12PipelineState pipes[GFX_MAX_SHADERS];
|
||||||
|
d3d12_uniform_t ubo_values;
|
||||||
D3D12Resource ubo;
|
D3D12Resource ubo;
|
||||||
D3D12_CONSTANT_BUFFER_VIEW_DESC ubo_view;
|
D3D12_CONSTANT_BUFFER_VIEW_DESC ubo_view;
|
||||||
DXGI_FORMAT format;
|
DXGI_FORMAT format;
|
||||||
@ -1395,6 +1416,8 @@ typedef struct
|
|||||||
bool resize_chain;
|
bool resize_chain;
|
||||||
bool keep_aspect;
|
bool keep_aspect;
|
||||||
bool resize_viewport;
|
bool resize_viewport;
|
||||||
|
D3D12Resource menu_pipeline_vbo;
|
||||||
|
D3D12_VERTEX_BUFFER_VIEW menu_pipeline_vbo_view;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
D3D12Debug debugController;
|
D3D12Debug debugController;
|
||||||
|
@ -26,11 +26,13 @@
|
|||||||
#include "../common/d3d12_common.h"
|
#include "../common/d3d12_common.h"
|
||||||
#include "../common/d3dcompiler_common.h"
|
#include "../common/d3dcompiler_common.h"
|
||||||
|
|
||||||
//#include "../../menu/menu_driver.h"
|
#include "../../menu/menu_driver.h"
|
||||||
#include "../../driver.h"
|
#include "../../driver.h"
|
||||||
#include "../../verbosity.h"
|
#include "../../verbosity.h"
|
||||||
#include "../../configuration.h"
|
#include "../../configuration.h"
|
||||||
|
|
||||||
|
#include "wiiu/wiiu_dbg.h"
|
||||||
|
|
||||||
static void d3d12_set_filtering(void* data, unsigned index, bool smooth)
|
static void d3d12_set_filtering(void* data, unsigned index, bool smooth)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -71,10 +73,10 @@ static void d3d12_update_viewport(void* data, bool force_full)
|
|||||||
|
|
||||||
video_driver_update_viewport(&d3d12->vp, force_full, d3d12->keep_aspect);
|
video_driver_update_viewport(&d3d12->vp, force_full, d3d12->keep_aspect);
|
||||||
|
|
||||||
d3d12->frame.viewport.TopLeftX = (float)d3d12->vp.x;
|
d3d12->frame.viewport.TopLeftX = d3d12->vp.x;
|
||||||
d3d12->frame.viewport.TopLeftY = (float)d3d12->vp.y;
|
d3d12->frame.viewport.TopLeftY = d3d12->vp.y;
|
||||||
d3d12->frame.viewport.Width = (float)d3d12->vp.width;
|
d3d12->frame.viewport.Width = d3d12->vp.width;
|
||||||
d3d12->frame.viewport.Height = (float)d3d12->vp.height;
|
d3d12->frame.viewport.Height = d3d12->vp.height;
|
||||||
d3d12->frame.viewport.MaxDepth = 0.0f;
|
d3d12->frame.viewport.MaxDepth = 0.0f;
|
||||||
d3d12->frame.viewport.MaxDepth = 1.0f;
|
d3d12->frame.viewport.MaxDepth = 1.0f;
|
||||||
|
|
||||||
@ -160,6 +162,7 @@ static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12)
|
|||||||
if (!d3d_compile(shader, sizeof(shader), NULL, "GSMain", "gs_5_0", &gs_code))
|
if (!d3d_compile(shader, sizeof(shader), NULL, "GSMain", "gs_5_0", &gs_code))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
// desc.BlendState.RenderTarget[0].BlendEnable = false;
|
||||||
desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
|
desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
|
||||||
desc.InputLayout.pInputElementDescs = inputElementDesc;
|
desc.InputLayout.pInputElementDescs = inputElementDesc;
|
||||||
desc.InputLayout.NumElements = countof(inputElementDesc);
|
desc.InputLayout.NumElements = countof(inputElementDesc);
|
||||||
@ -301,9 +304,9 @@ static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12)
|
|||||||
vs_code = NULL;
|
vs_code = NULL;
|
||||||
ps_code = NULL;
|
ps_code = NULL;
|
||||||
|
|
||||||
if (!d3d_compile(ribbon_simple, sizeof(ribbon), NULL, "VSMain", "vs_5_0", &vs_code))
|
if (!d3d_compile(ribbon_simple, sizeof(ribbon_simple), NULL, "VSMain", "vs_5_0", &vs_code))
|
||||||
goto error;
|
goto error;
|
||||||
if (!d3d_compile(ribbon_simple, sizeof(ribbon), NULL, "PSMain", "ps_5_0", &ps_code))
|
if (!d3d_compile(ribbon_simple, sizeof(ribbon_simple), NULL, "PSMain", "ps_5_0", &ps_code))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!d3d12_init_pipeline(
|
if (!d3d12_init_pipeline(
|
||||||
@ -383,6 +386,8 @@ static void*
|
|||||||
d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data)
|
d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data)
|
||||||
{
|
{
|
||||||
WNDCLASSEX wndclass = { 0 };
|
WNDCLASSEX wndclass = { 0 };
|
||||||
|
MONITORINFOEX current_mon;
|
||||||
|
HMONITOR hm_to_use;
|
||||||
settings_t* settings = config_get_ptr();
|
settings_t* settings = config_get_ptr();
|
||||||
d3d12_video_t* d3d12 = (d3d12_video_t*)calloc(1, sizeof(*d3d12));
|
d3d12_video_t* d3d12 = (d3d12_video_t*)calloc(1, sizeof(*d3d12));
|
||||||
|
|
||||||
@ -394,7 +399,17 @@ d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
|
|||||||
wndclass.lpfnWndProc = WndProcD3D;
|
wndclass.lpfnWndProc = WndProcD3D;
|
||||||
win32_window_init(&wndclass, true, NULL);
|
win32_window_init(&wndclass, true, NULL);
|
||||||
|
|
||||||
if (!win32_set_video_mode(d3d12, video->width, video->height, video->fullscreen))
|
win32_monitor_info(¤t_mon, &hm_to_use, &d3d12->cur_mon_id);
|
||||||
|
|
||||||
|
d3d12->vp.full_width = video->width;
|
||||||
|
d3d12->vp.full_height = video->height;
|
||||||
|
|
||||||
|
if (!d3d12->vp.full_width)
|
||||||
|
d3d12->vp.full_width = current_mon.rcMonitor.right - current_mon.rcMonitor.left;
|
||||||
|
if (!d3d12->vp.full_height)
|
||||||
|
d3d12->vp.full_height = current_mon.rcMonitor.bottom - current_mon.rcMonitor.top;
|
||||||
|
|
||||||
|
if (!win32_set_video_mode(d3d12, d3d12->vp.full_width, d3d12->vp.full_height, video->fullscreen))
|
||||||
{
|
{
|
||||||
RARCH_ERR("[D3D12]: win32_set_video_mode failed.\n");
|
RARCH_ERR("[D3D12]: win32_set_video_mode failed.\n");
|
||||||
goto error;
|
goto error;
|
||||||
@ -414,7 +429,7 @@ d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
|
|||||||
if (!d3d12_init_queue(d3d12))
|
if (!d3d12_init_queue(d3d12))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!d3d12_init_swapchain(d3d12, video->width, video->height, main_window.hwnd))
|
if (!d3d12_init_swapchain(d3d12, d3d12->vp.full_width, d3d12->vp.full_height, main_window.hwnd))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
d3d12_init_samplers(d3d12);
|
d3d12_init_samplers(d3d12);
|
||||||
@ -429,21 +444,20 @@ d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
|
|||||||
d3d12->sprites.vbo_view.BufferLocation = d3d12_create_buffer(
|
d3d12->sprites.vbo_view.BufferLocation = d3d12_create_buffer(
|
||||||
d3d12->device, d3d12->sprites.vbo_view.SizeInBytes, &d3d12->sprites.vbo);
|
d3d12->device, d3d12->sprites.vbo_view.SizeInBytes, &d3d12->sprites.vbo);
|
||||||
|
|
||||||
d3d12->keep_aspect = video->force_aspect;
|
d3d12->ubo_view.SizeInBytes = sizeof(d3d12_uniform_t);
|
||||||
d3d12->chain.vsync = video->vsync;
|
|
||||||
d3d12->format = video->rgb32 ? DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM;
|
|
||||||
d3d12->frame.texture.desc.Format = d3d12->format;
|
|
||||||
|
|
||||||
d3d12->ubo_view.SizeInBytes = sizeof(math_matrix_4x4);
|
|
||||||
d3d12->ubo_view.BufferLocation =
|
d3d12->ubo_view.BufferLocation =
|
||||||
d3d12_create_buffer(d3d12->device, d3d12->ubo_view.SizeInBytes, &d3d12->ubo);
|
d3d12_create_buffer(d3d12->device, d3d12->ubo_view.SizeInBytes, &d3d12->ubo);
|
||||||
|
|
||||||
d3d12->frame.ubo_view.SizeInBytes = sizeof(math_matrix_4x4);
|
d3d12->frame.ubo_view.SizeInBytes = sizeof(d3d12_uniform_t);
|
||||||
d3d12->frame.ubo_view.BufferLocation =
|
d3d12->frame.ubo_view.BufferLocation =
|
||||||
d3d12_create_buffer(d3d12->device, d3d12->frame.ubo_view.SizeInBytes, &d3d12->frame.ubo);
|
d3d12_create_buffer(d3d12->device, d3d12->frame.ubo_view.SizeInBytes, &d3d12->frame.ubo);
|
||||||
|
|
||||||
matrix_4x4_ortho(d3d12->mvp_no_rot, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
|
matrix_4x4_ortho(d3d12->mvp_no_rot, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
|
||||||
|
|
||||||
|
d3d12->ubo_values.mvp = d3d12->mvp_no_rot;
|
||||||
|
d3d12->ubo_values.OutputSize.width = d3d12->chain.viewport.Width;
|
||||||
|
d3d12->ubo_values.OutputSize.height = d3d12->chain.viewport.Height;
|
||||||
|
|
||||||
{
|
{
|
||||||
math_matrix_4x4* mvp;
|
math_matrix_4x4* mvp;
|
||||||
D3D12_RANGE read_range = { 0, 0 };
|
D3D12_RANGE read_range = { 0, 0 };
|
||||||
@ -453,9 +467,14 @@ d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
|
|||||||
}
|
}
|
||||||
|
|
||||||
d3d12_gfx_set_rotation(d3d12, 0);
|
d3d12_gfx_set_rotation(d3d12, 0);
|
||||||
d3d12->vp.full_width = video->width;
|
video_driver_set_size(&d3d12->vp.full_width, &d3d12->vp.full_height);
|
||||||
d3d12->vp.full_height = video->height;
|
d3d12->chain.viewport.Width = d3d12->vp.full_width;
|
||||||
d3d12->resize_viewport = true;
|
d3d12->chain.viewport.Height = d3d12->vp.full_height;
|
||||||
|
d3d12->resize_viewport = true;
|
||||||
|
d3d12->keep_aspect = video->force_aspect;
|
||||||
|
d3d12->chain.vsync = video->vsync;
|
||||||
|
d3d12->format = video->rgb32 ? DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM;
|
||||||
|
d3d12->frame.texture.desc.Format = d3d12->format;
|
||||||
|
|
||||||
font_driver_init_osd(d3d12, false, video->is_threaded, FONT_DRIVER_RENDER_D3D12_API);
|
font_driver_init_osd(d3d12, false, video->is_threaded, FONT_DRIVER_RENDER_D3D12_API);
|
||||||
|
|
||||||
@ -496,8 +515,18 @@ static bool d3d12_gfx_frame(
|
|||||||
}
|
}
|
||||||
|
|
||||||
d3d12->chain.frame_index = DXGIGetCurrentBackBufferIndex(d3d12->chain.handle);
|
d3d12->chain.frame_index = DXGIGetCurrentBackBufferIndex(d3d12->chain.handle);
|
||||||
d3d12->resize_chain = false;
|
|
||||||
d3d12->resize_viewport = true;
|
d3d12->chain.viewport.Width = video_info->width;
|
||||||
|
d3d12->chain.viewport.Height = video_info->height;
|
||||||
|
d3d12->chain.scissorRect.right = video_info->width;
|
||||||
|
d3d12->chain.scissorRect.bottom = video_info->height;
|
||||||
|
d3d12->resize_chain = false;
|
||||||
|
d3d12->resize_viewport = true;
|
||||||
|
|
||||||
|
d3d12->ubo_values.OutputSize.width = d3d12->chain.viewport.Width;
|
||||||
|
d3d12->ubo_values.OutputSize.height = d3d12->chain.viewport.Height;
|
||||||
|
|
||||||
|
video_driver_set_size(&video_info->width, &video_info->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
PERF_START();
|
PERF_START();
|
||||||
@ -578,7 +607,7 @@ static bool d3d12_gfx_frame(
|
|||||||
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->sprites.vbo_view);
|
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->sprites.vbo_view);
|
||||||
|
|
||||||
d3d12->sprites.enabled = true;
|
d3d12->sprites.enabled = true;
|
||||||
#if 0
|
#if 1
|
||||||
if (d3d12->menu.enabled)
|
if (d3d12->menu.enabled)
|
||||||
menu_driver_frame(video_info);
|
menu_driver_frame(video_info);
|
||||||
#endif
|
#endif
|
||||||
@ -589,7 +618,6 @@ static bool d3d12_gfx_frame(
|
|||||||
}
|
}
|
||||||
d3d12->sprites.enabled = false;
|
d3d12->sprites.enabled = false;
|
||||||
|
|
||||||
|
|
||||||
d3d12_resource_transition(
|
d3d12_resource_transition(
|
||||||
d3d12->queue.cmd, d3d12->chain.renderTargets[d3d12->chain.frame_index],
|
d3d12->queue.cmd, d3d12->chain.renderTargets[d3d12->chain.frame_index],
|
||||||
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
|
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
|
||||||
@ -759,11 +787,64 @@ static void d3d12_gfx_set_osd_msg(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uintptr_t d3d12_gfx_load_texture(
|
||||||
|
void* video_data, void* data, bool threaded, enum texture_filter_type filter_type)
|
||||||
|
{
|
||||||
|
d3d12_texture_t* texture = NULL;
|
||||||
|
d3d12_video_t* d3d12 = (d3d12_video_t*)video_data;
|
||||||
|
struct texture_image* image = (struct texture_image*)data;
|
||||||
|
|
||||||
|
if (!d3d12)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
texture = (d3d12_texture_t*)calloc(1, sizeof(*texture));
|
||||||
|
|
||||||
|
if (!texture)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* todo : mipmapping */
|
||||||
|
switch (filter_type)
|
||||||
|
{
|
||||||
|
case TEXTURE_FILTER_MIPMAP_LINEAR:
|
||||||
|
/* fallthrough */
|
||||||
|
case TEXTURE_FILTER_LINEAR:
|
||||||
|
texture->sampler = d3d12->samplers[RARCH_FILTER_LINEAR][RARCH_WRAP_DEFAULT];
|
||||||
|
break;
|
||||||
|
case TEXTURE_FILTER_MIPMAP_NEAREST:
|
||||||
|
/* fallthrough */
|
||||||
|
case TEXTURE_FILTER_NEAREST:
|
||||||
|
texture->sampler = d3d12->samplers[RARCH_FILTER_NEAREST][RARCH_WRAP_DEFAULT];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture->desc.Width = image->width;
|
||||||
|
texture->desc.Height = image->height;
|
||||||
|
texture->desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
texture->srv_heap = &d3d12->desc.srv_heap;
|
||||||
|
|
||||||
|
d3d12_init_texture(d3d12->device, texture);
|
||||||
|
|
||||||
|
d3d12_update_texture(
|
||||||
|
image->width, image->height, 0, DXGI_FORMAT_B8G8R8A8_UNORM, image->pixels, texture);
|
||||||
|
|
||||||
|
return (uintptr_t)texture;
|
||||||
|
}
|
||||||
|
static void d3d12_gfx_unload_texture(void* data, uintptr_t handle)
|
||||||
|
{
|
||||||
|
d3d12_texture_t* texture = (d3d12_texture_t*)handle;
|
||||||
|
|
||||||
|
if (!texture)
|
||||||
|
return;
|
||||||
|
|
||||||
|
d3d12_release_texture(texture);
|
||||||
|
free(texture);
|
||||||
|
}
|
||||||
|
|
||||||
static const video_poke_interface_t d3d12_poke_interface = {
|
static const video_poke_interface_t d3d12_poke_interface = {
|
||||||
NULL, /* set_coords */
|
NULL, /* set_coords */
|
||||||
NULL, /* set_mvp */
|
NULL, /* set_mvp */
|
||||||
NULL, /* load_texture */
|
d3d12_gfx_load_texture,
|
||||||
NULL, /* unload_texture */
|
d3d12_gfx_unload_texture,
|
||||||
NULL, /* set_video_mode */
|
NULL, /* set_video_mode */
|
||||||
d3d12_set_filtering,
|
d3d12_set_filtering,
|
||||||
NULL, /* get_video_output_size */
|
NULL, /* get_video_output_size */
|
||||||
|
@ -1172,6 +1172,10 @@ MENU
|
|||||||
#include "../menu/drivers_display/menu_display_d3d11.c"
|
#include "../menu/drivers_display/menu_display_d3d11.c"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_D3D12)
|
||||||
|
#include "../menu/drivers_display/menu_display_d3d12.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_OPENGL
|
#ifdef HAVE_OPENGL
|
||||||
#include "../menu/drivers_display/menu_display_gl.c"
|
#include "../menu/drivers_display/menu_display_gl.c"
|
||||||
#endif
|
#endif
|
||||||
|
244
menu/drivers_display/menu_display_d3d12.c
Normal file
244
menu/drivers_display/menu_display_d3d12.c
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
/* RetroArch - A frontend for libretro.
|
||||||
|
* Copyright (C) 2014-2018 - Ali Bouhlel
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CINTERFACE
|
||||||
|
|
||||||
|
#include <retro_miscellaneous.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../menu_driver.h"
|
||||||
|
|
||||||
|
#include "../../retroarch.h"
|
||||||
|
#include "../../gfx/font_driver.h"
|
||||||
|
#include "../../gfx/video_driver.h"
|
||||||
|
#include "../../gfx/common/d3d12_common.h"
|
||||||
|
|
||||||
|
static const float* menu_display_d3d12_get_default_vertices(void) { return NULL; }
|
||||||
|
|
||||||
|
static const float* menu_display_d3d12_get_default_tex_coords(void) { return NULL; }
|
||||||
|
|
||||||
|
static void* menu_display_d3d12_get_default_mvp(void) { return NULL; }
|
||||||
|
|
||||||
|
static void menu_display_d3d12_blend_begin(void)
|
||||||
|
{
|
||||||
|
d3d12_video_t* d3d12 = (d3d12_video_t*)video_driver_get_ptr(false);
|
||||||
|
|
||||||
|
/*todo: d3d12->sprites.pipe_blend */
|
||||||
|
D3D12SetPipelineState(d3d12->queue.cmd, d3d12->sprites.pipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_display_d3d12_blend_end(void)
|
||||||
|
{
|
||||||
|
d3d12_video_t* d3d12 = (d3d12_video_t*)video_driver_get_ptr(false);
|
||||||
|
|
||||||
|
/*todo: d3d12->sprites.pipe_noblend */
|
||||||
|
D3D12SetPipelineState(d3d12->queue.cmd, d3d12->sprites.pipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_display_d3d12_viewport(void* data) {}
|
||||||
|
|
||||||
|
static void menu_display_d3d12_draw(void* data)
|
||||||
|
{
|
||||||
|
d3d12_video_t* d3d12 = (d3d12_video_t*)video_driver_get_ptr(false);
|
||||||
|
menu_display_ctx_draw_t* draw = (menu_display_ctx_draw_t*)data;
|
||||||
|
|
||||||
|
if (!d3d12 || !draw || !draw->texture)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (draw->pipeline.id)
|
||||||
|
{
|
||||||
|
case VIDEO_SHADER_MENU:
|
||||||
|
case VIDEO_SHADER_MENU_2:
|
||||||
|
case VIDEO_SHADER_MENU_3:
|
||||||
|
case VIDEO_SHADER_MENU_4:
|
||||||
|
case VIDEO_SHADER_MENU_5:
|
||||||
|
case VIDEO_SHADER_MENU_6:
|
||||||
|
D3D12SetPipelineState(d3d12->queue.cmd, d3d12->pipes[draw->pipeline.id]);
|
||||||
|
D3D12DrawInstanced(d3d12->queue.cmd, draw->coords->vertices, 1, 0, 0);
|
||||||
|
D3D12SetPipelineState(d3d12->queue.cmd, d3d12->sprites.pipe);
|
||||||
|
D3D12IASetPrimitiveTopology(d3d12->queue.cmd, D3D_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||||
|
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->sprites.vbo_view);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!d3d12->sprites.enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (d3d12->sprites.offset + 1 > d3d12->sprites.capacity)
|
||||||
|
d3d12->sprites.offset = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
d3d12_sprite_t* v;
|
||||||
|
D3D12_RANGE range = { 0, 0 };
|
||||||
|
D3D12Map(d3d12->sprites.vbo, 0, &range, (void**)&v);
|
||||||
|
v += d3d12->sprites.offset;
|
||||||
|
|
||||||
|
v->pos.x = draw->x / (float)d3d12->chain.viewport.Width;
|
||||||
|
v->pos.y = (d3d12->chain.viewport.Height - draw->y - draw->height) /
|
||||||
|
(float)d3d12->chain.viewport.Height;
|
||||||
|
v->pos.w = draw->width / (float)d3d12->chain.viewport.Width;
|
||||||
|
v->pos.h = draw->height / (float)d3d12->chain.viewport.Height;
|
||||||
|
|
||||||
|
v->coords.u = 0.0f;
|
||||||
|
v->coords.v = 0.0f;
|
||||||
|
v->coords.w = 1.0f;
|
||||||
|
v->coords.h = 1.0f;
|
||||||
|
|
||||||
|
if (draw->scale_factor)
|
||||||
|
v->params.scaling = draw->scale_factor;
|
||||||
|
else
|
||||||
|
v->params.scaling = 1.0f;
|
||||||
|
|
||||||
|
v->params.rotation = draw->rotation;
|
||||||
|
|
||||||
|
v->colors[3] = DXGI_COLOR_RGBA(
|
||||||
|
0xFF * draw->coords->color[0], 0xFF * draw->coords->color[1],
|
||||||
|
0xFF * draw->coords->color[2], 0xFF * draw->coords->color[3]);
|
||||||
|
v->colors[2] = DXGI_COLOR_RGBA(
|
||||||
|
0xFF * draw->coords->color[4], 0xFF * draw->coords->color[5],
|
||||||
|
0xFF * draw->coords->color[6], 0xFF * draw->coords->color[7]);
|
||||||
|
v->colors[1] = DXGI_COLOR_RGBA(
|
||||||
|
0xFF * draw->coords->color[8], 0xFF * draw->coords->color[9],
|
||||||
|
0xFF * draw->coords->color[10], 0xFF * draw->coords->color[12]);
|
||||||
|
v->colors[0] = DXGI_COLOR_RGBA(
|
||||||
|
0xFF * draw->coords->color[12], 0xFF * draw->coords->color[13],
|
||||||
|
0xFF * draw->coords->color[14], 0xFF * draw->coords->color[15]);
|
||||||
|
|
||||||
|
range.Begin = d3d12->sprites.offset * sizeof(*v);
|
||||||
|
range.End = (d3d12->sprites.offset + 1) * sizeof(*v);
|
||||||
|
D3D12Unmap(d3d12->sprites.vbo, 0, &range);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
d3d12_texture_t* texture = (d3d12_texture_t*)draw->texture;
|
||||||
|
if (texture->dirty)
|
||||||
|
d3d12_upload_texture(d3d12->queue.cmd, texture);
|
||||||
|
d3d12_set_texture_and_sampler(d3d12->queue.cmd, texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12DrawInstanced(d3d12->queue.cmd, 1, 1, d3d12->sprites.offset, 0);
|
||||||
|
d3d12->sprites.offset++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_display_d3d12_draw_pipeline(void* data)
|
||||||
|
{
|
||||||
|
menu_display_ctx_draw_t* draw = (menu_display_ctx_draw_t*)data;
|
||||||
|
d3d12_video_t* d3d12 = (d3d12_video_t*)video_driver_get_ptr(false);
|
||||||
|
|
||||||
|
if (!d3d12 || !draw)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (draw->pipeline.id)
|
||||||
|
{
|
||||||
|
case VIDEO_SHADER_MENU:
|
||||||
|
case VIDEO_SHADER_MENU_2:
|
||||||
|
{
|
||||||
|
video_coord_array_t* ca = menu_display_get_coords_array();
|
||||||
|
|
||||||
|
if (!d3d12->menu_pipeline_vbo)
|
||||||
|
{
|
||||||
|
void* vertex_data_begin;
|
||||||
|
D3D12_RANGE read_range = { 0, 0 };
|
||||||
|
|
||||||
|
d3d12->menu_pipeline_vbo_view.StrideInBytes = 2 * sizeof(float);
|
||||||
|
d3d12->menu_pipeline_vbo_view.SizeInBytes =
|
||||||
|
ca->coords.vertices * d3d12->menu_pipeline_vbo_view.StrideInBytes;
|
||||||
|
d3d12->menu_pipeline_vbo_view.BufferLocation = d3d12_create_buffer(
|
||||||
|
d3d12->device, d3d12->menu_pipeline_vbo_view.SizeInBytes,
|
||||||
|
&d3d12->menu_pipeline_vbo);
|
||||||
|
|
||||||
|
D3D12Map(d3d12->menu_pipeline_vbo, 0, &read_range, &vertex_data_begin);
|
||||||
|
memcpy(vertex_data_begin, ca->coords.vertex, d3d12->menu_pipeline_vbo_view.SizeInBytes);
|
||||||
|
D3D12Unmap(d3d12->menu_pipeline_vbo, 0, NULL);
|
||||||
|
}
|
||||||
|
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->menu_pipeline_vbo_view);
|
||||||
|
draw->coords->vertices = ca->coords.vertices;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case VIDEO_SHADER_MENU_3:
|
||||||
|
case VIDEO_SHADER_MENU_4:
|
||||||
|
case VIDEO_SHADER_MENU_5:
|
||||||
|
case VIDEO_SHADER_MENU_6:
|
||||||
|
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->frame.vbo_view);
|
||||||
|
draw->coords->vertices = 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
D3D12IASetPrimitiveTopology(d3d12->queue.cmd, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||||
|
|
||||||
|
d3d12->ubo_values.time += 0.01f;
|
||||||
|
|
||||||
|
{
|
||||||
|
D3D12_RANGE read_range = { 0, 0 };
|
||||||
|
d3d12_uniform_t* mapped_ubo;
|
||||||
|
D3D12Map(d3d12->ubo, 0, &read_range, (void**)&mapped_ubo);
|
||||||
|
*mapped_ubo = d3d12->ubo_values;
|
||||||
|
D3D12Unmap(d3d12->ubo, 0, NULL);
|
||||||
|
}
|
||||||
|
D3D12SetGraphicsRootConstantBufferView(
|
||||||
|
d3d12->queue.cmd, ROOT_ID_UBO, d3d12->ubo_view.BufferLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_display_d3d12_restore_clear_color(void) {}
|
||||||
|
|
||||||
|
static void menu_display_d3d12_clear_color(menu_display_ctx_clearcolor_t* clearcolor)
|
||||||
|
{
|
||||||
|
d3d12_video_t* d3d12 = (d3d12_video_t*)video_driver_get_ptr(false);
|
||||||
|
|
||||||
|
if (!d3d12 || !clearcolor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
D3D12ClearRenderTargetView(
|
||||||
|
d3d12->queue.cmd, d3d12->chain.desc_handles[d3d12->chain.frame_index], (float*)clearcolor,
|
||||||
|
0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool menu_display_d3d12_font_init_first(
|
||||||
|
void** font_handle,
|
||||||
|
void* video_data,
|
||||||
|
const char* font_path,
|
||||||
|
float font_size,
|
||||||
|
bool is_threaded)
|
||||||
|
{
|
||||||
|
font_data_t** handle = (font_data_t**)font_handle;
|
||||||
|
font_data_t* new_handle = font_driver_init_first(
|
||||||
|
video_data, font_path, font_size, true, is_threaded, FONT_DRIVER_RENDER_D3D12_API);
|
||||||
|
if (!new_handle)
|
||||||
|
return false;
|
||||||
|
*handle = new_handle;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
menu_display_ctx_driver_t menu_display_ctx_d3d12 = {
|
||||||
|
menu_display_d3d12_draw,
|
||||||
|
menu_display_d3d12_draw_pipeline,
|
||||||
|
menu_display_d3d12_viewport,
|
||||||
|
menu_display_d3d12_blend_begin,
|
||||||
|
menu_display_d3d12_blend_end,
|
||||||
|
menu_display_d3d12_restore_clear_color,
|
||||||
|
menu_display_d3d12_clear_color,
|
||||||
|
menu_display_d3d12_get_default_mvp,
|
||||||
|
menu_display_d3d12_get_default_vertices,
|
||||||
|
menu_display_d3d12_get_default_tex_coords,
|
||||||
|
menu_display_d3d12_font_init_first,
|
||||||
|
MENU_VIDEO_DRIVER_DIRECT3D12,
|
||||||
|
"menu_display_d3d12",
|
||||||
|
};
|
@ -93,6 +93,9 @@ static menu_display_ctx_driver_t *menu_display_ctx_drivers[] = {
|
|||||||
#ifdef HAVE_D3D11
|
#ifdef HAVE_D3D11
|
||||||
&menu_display_ctx_d3d11,
|
&menu_display_ctx_d3d11,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_D3D12
|
||||||
|
&menu_display_ctx_d3d12,
|
||||||
|
#endif
|
||||||
#ifdef HAVE_OPENGL
|
#ifdef HAVE_OPENGL
|
||||||
&menu_display_ctx_gl,
|
&menu_display_ctx_gl,
|
||||||
#endif
|
#endif
|
||||||
@ -229,6 +232,10 @@ static bool menu_display_check_compatibility(
|
|||||||
if (string_is_equal(video_driver, "d3d11"))
|
if (string_is_equal(video_driver, "d3d11"))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
case MENU_VIDEO_DRIVER_DIRECT3D12:
|
||||||
|
if (string_is_equal(video_driver, "d3d12"))
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
case MENU_VIDEO_DRIVER_VITA2D:
|
case MENU_VIDEO_DRIVER_VITA2D:
|
||||||
if (string_is_equal(video_driver, "vita2d"))
|
if (string_is_equal(video_driver, "vita2d"))
|
||||||
return true;
|
return true;
|
||||||
|
@ -280,6 +280,7 @@ enum menu_display_driver_type
|
|||||||
MENU_VIDEO_DRIVER_VULKAN,
|
MENU_VIDEO_DRIVER_VULKAN,
|
||||||
MENU_VIDEO_DRIVER_DIRECT3D,
|
MENU_VIDEO_DRIVER_DIRECT3D,
|
||||||
MENU_VIDEO_DRIVER_DIRECT3D11,
|
MENU_VIDEO_DRIVER_DIRECT3D11,
|
||||||
|
MENU_VIDEO_DRIVER_DIRECT3D12,
|
||||||
MENU_VIDEO_DRIVER_VITA2D,
|
MENU_VIDEO_DRIVER_VITA2D,
|
||||||
MENU_VIDEO_DRIVER_CTR,
|
MENU_VIDEO_DRIVER_CTR,
|
||||||
MENU_VIDEO_DRIVER_WIIU,
|
MENU_VIDEO_DRIVER_WIIU,
|
||||||
@ -735,6 +736,7 @@ extern menu_display_ctx_driver_t menu_display_ctx_gl;
|
|||||||
extern menu_display_ctx_driver_t menu_display_ctx_vulkan;
|
extern menu_display_ctx_driver_t menu_display_ctx_vulkan;
|
||||||
extern menu_display_ctx_driver_t menu_display_ctx_d3d;
|
extern menu_display_ctx_driver_t menu_display_ctx_d3d;
|
||||||
extern menu_display_ctx_driver_t menu_display_ctx_d3d11;
|
extern menu_display_ctx_driver_t menu_display_ctx_d3d11;
|
||||||
|
extern menu_display_ctx_driver_t menu_display_ctx_d3d12;
|
||||||
extern menu_display_ctx_driver_t menu_display_ctx_vita2d;
|
extern menu_display_ctx_driver_t menu_display_ctx_vita2d;
|
||||||
extern menu_display_ctx_driver_t menu_display_ctx_ctr;
|
extern menu_display_ctx_driver_t menu_display_ctx_ctr;
|
||||||
extern menu_display_ctx_driver_t menu_display_ctx_wiiu;
|
extern menu_display_ctx_driver_t menu_display_ctx_wiiu;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user