1
0
mirror of https://github.com/libretro/RetroArch synced 2024-07-08 12:15:49 +00:00

(D3D11) add menu display driver.

This commit is contained in:
aliaspider 2018-01-25 00:20:06 +01:00
parent 840bd459df
commit 812eefa601
10 changed files with 250 additions and 43 deletions

View File

@ -1303,7 +1303,7 @@ endif
ifeq ($(HAVE_D3D11), 1)
OBJ += gfx/drivers/d3d11.o gfx/common/d3d11_common.o \
gfx/drivers_font/d3d11_font.o
gfx/drivers_font/d3d11_font.o menu/drivers_display/menu_display_d3d11.o
DEFINES += -DHAVE_D3D11
endif

View File

@ -67,8 +67,9 @@ void d3d11_init_texture(D3D11Device device, d3d11_texture_t* texture)
texture->desc.SampleDesc.Count = 1;
texture->desc.SampleDesc.Quality = 0;
texture->desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
texture->desc.CPUAccessFlags = 0;
texture->desc.MiscFlags = 0;
texture->desc.CPUAccessFlags =
texture->desc.Usage == D3D11_USAGE_DYNAMIC ? D3D11_CPU_ACCESS_WRITE : 0;
texture->desc.MiscFlags = 0;
D3D11CreateTexture2D(device, &texture->desc, NULL, &texture->handle);
{

View File

@ -2538,7 +2538,7 @@ typedef struct
D3D11Buffer vbo;
D3D11InputLayout layout;
int offset;
int size;
int capacity;
bool enabled;
} sprites;
} d3d11_video_t;

View File

@ -28,6 +28,7 @@
#include "../common/dxgi_common.h"
#include "../common/d3dcompiler_common.h"
#include "../../performance_counters.h"
#include "../../menu/menu_driver.h"
static void d3d11_set_filtering(void* data, unsigned index, bool smooth)
{
@ -92,6 +93,7 @@ static void d3d11_gfx_free(void* data)
Release(d3d11->sprites.vs);
Release(d3d11->sprites.ps);
Release(d3d11->sprites.ps_8bit);
Release(d3d11->sprites.gs);
Release(d3d11->sprites.vbo);
Release(d3d11->sprites.layout);
@ -107,6 +109,9 @@ static void d3d11_gfx_free(void* data)
Release(d3d11->state);
Release(d3d11->renderTargetView);
Release(d3d11->swapChain);
font_driver_free_osd();
Release(d3d11->ctx);
Release(d3d11->device);
@ -119,6 +124,8 @@ static void*
d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data)
{
WNDCLASSEX wndclass = { 0 };
MONITORINFOEX current_mon;
HMONITOR hm_to_use;
settings_t* settings = config_get_ptr();
gfx_ctx_input_t inp = { input, input_data };
d3d11_video_t* d3d11 = (d3d11_video_t*)calloc(1, sizeof(*d3d11));
@ -131,7 +138,17 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
wndclass.lpfnWndProc = WndProcD3D;
win32_window_init(&wndclass, true, NULL);
if (!win32_set_video_mode(d3d11, video->width, video->height, video->fullscreen))
win32_monitor_info(&current_mon, &hm_to_use, &d3d11->cur_mon_id);
d3d11->vp.full_width = video->width;
d3d11->vp.full_height = video->height;
if (!d3d11->vp.full_width)
d3d11->vp.full_width = current_mon.rcMonitor.right - current_mon.rcMonitor.left;
if (!d3d11->vp.full_height)
d3d11->vp.full_height = current_mon.rcMonitor.bottom - current_mon.rcMonitor.top;
if (!win32_set_video_mode(d3d11, d3d11->vp.full_width, d3d11->vp.full_height, video->fullscreen))
{
RARCH_ERR("[D3D11]: win32_set_video_mode failed.\n");
goto error;
@ -144,8 +161,8 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
D3D_FEATURE_LEVEL requested_feature_level = D3D_FEATURE_LEVEL_11_0;
DXGI_SWAP_CHAIN_DESC desc = {
.BufferCount = 1,
.BufferDesc.Width = video->width,
.BufferDesc.Height = video->height,
.BufferDesc.Width = d3d11->vp.full_width,
.BufferDesc.Height = d3d11->vp.full_height,
.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM,
.BufferDesc.RefreshRate.Numerator = 60,
.BufferDesc.RefreshRate.Denominator = 1,
@ -182,10 +199,9 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
D3D11SetRenderTargets(d3d11->ctx, 1, &d3d11->renderTargetView, NULL);
d3d11->vp.full_width = video->width;
d3d11->vp.full_height = video->height;
d3d11->viewport.Width = video->width;
d3d11->viewport.Height = video->height;
video_driver_set_size(&d3d11->vp.full_width, &d3d11->vp.full_height);
d3d11->viewport.Width = d3d11->vp.full_width;
d3d11->viewport.Height = d3d11->vp.full_height;
d3d11->resize_viewport = true;
d3d11->vsync = video->vsync;
d3d11->format = video->rgb32 ? DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM;
@ -251,8 +267,8 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
D3D11CreateBuffer(d3d11->device, &desc, &vertexData, &d3d11->menu.vbo);
d3d11->sprites.size = sizeof(d3d11_sprite_t) * 1024;
desc.ByteWidth = d3d11->sprites.size;
d3d11->sprites.capacity = 4096;
desc.ByteWidth = sizeof(d3d11_sprite_t) * d3d11->sprites.capacity;
D3D11CreateBuffer(d3d11->device, &desc, NULL, &d3d11->sprites.vbo);
}
}
@ -425,6 +441,7 @@ static bool d3d11_gfx_frame(
d3d11->resize_chain = false;
d3d11->resize_viewport = true;
video_driver_set_size(&video_info->width, &video_info->height);
}
PERF_START();
@ -508,6 +525,9 @@ static bool d3d11_gfx_frame(
d3d11->sprites.offset = 0;
d3d11->sprites.enabled = true;
if (d3d11->menu.enabled)
menu_driver_frame(video_info);
if (msg && *msg)
{
font_driver_render_msg(video_info, NULL, msg, NULL);
@ -646,11 +666,51 @@ static void d3d11_gfx_set_osd_msg(
printf("OSD msg: %s\n", msg);
}
}
static uintptr_t d3d11_gfx_load_texture(
void* video_data, void* data, bool threaded, enum texture_filter_type filter_type)
{
d3d11_video_t* d3d11 = (d3d11_video_t*)video_data;
struct texture_image* image = (struct texture_image*)data;
D3D11_BOX frame_box = { 0, 0, 0, image->width, image->height, 1 };
if (!d3d11)
return 0;
d3d11_texture_t* texture = calloc(1, sizeof(*texture));
texture->desc.Width = image->width;
texture->desc.Height = image->height;
texture->desc.Format =
d3d11_get_closest_match_texture2D(d3d11->device, DXGI_FORMAT_B8G8R8A8_UNORM);
d3d11_init_texture(d3d11->device, texture);
d3d11_update_texture(
d3d11->ctx, image->width, image->height, 0, DXGI_FORMAT_B8G8R8A8_UNORM, image->pixels,
texture);
D3D11CopyTexture2DSubresourceRegion(
d3d11->ctx, texture->handle, 0, 0, 0, 0, texture->staging, 0, &frame_box);
return (uintptr_t)texture;
}
static void d3d11_gfx_unload_texture(void* data, uintptr_t handle)
{
d3d11_texture_t* texture = (d3d11_texture_t*)handle;
if (!texture)
return;
Release(texture->view);
Release(texture->staging);
Release(texture->handle);
free(texture);
}
static const video_poke_interface_t d3d11_poke_interface = {
NULL, /* set_coords */
NULL, /* set_mvp */
NULL, /* load_texture */
NULL, /* unload_texture */
d3d11_gfx_load_texture,
d3d11_gfx_unload_texture,
NULL, /* set_video_mode */
d3d11_set_filtering,
NULL, /* get_video_output_size */

View File

@ -74,13 +74,10 @@ SRC(
float4 PSMain(PSInput input) : SV_TARGET
{
return input.color * t0.Sample(s0, input.texcoord);
// return input.color;
};
float4 PSMainA8(PSInput input) : SV_TARGET
{
// return t0.Sample(s0, input.texcoord).a;
return input.color * t0.Sample(s0, input.texcoord).a;
// return input.color;
};
)

View File

@ -56,13 +56,12 @@ d3d11_font_init_font(void* data, const char* font_path, float font_size, bool is
font->texture.desc.Height = font->atlas->height;
font->texture.desc.Format =
d3d11_get_closest_match_texture2D(d3d11->device, DXGI_FORMAT_A8_UNORM);
DEBUG_INT(font->texture.desc.Format);
d3d11_init_texture(d3d11->device, &font->texture);
d3d11_update_texture(
d3d11->ctx, font->atlas->width, font->atlas->height, font->atlas->width, DXGI_FORMAT_A8_UNORM,
font->atlas->buffer, &font->texture);
d3d11->ctx, font->atlas->width, font->atlas->height, font->atlas->width,
DXGI_FORMAT_A8_UNORM, font->atlas->buffer, &font->texture);
font->texture.dirty = true;
font->atlas->dirty = false;
font->atlas->dirty = false;
return font;
}
@ -127,14 +126,16 @@ static void d3d11_font_render_line(
float pos_y,
unsigned text_align)
{
unsigned i;
d3d11_video_t* d3d11 = (d3d11_video_t*)video_driver_get_ptr(false);
unsigned width = video_info->width;
unsigned height = video_info->height;
int x = roundf(pos_x * width);
int y = roundf((1.0 - pos_y) * height);
unsigned i, count;
D3D11_MAPPED_SUBRESOURCE mapped_vbo;
d3d11_sprite_t* v;
d3d11_video_t* d3d11 = (d3d11_video_t*)video_driver_get_ptr(false);
unsigned width = video_info->width;
unsigned height = video_info->height;
int x = roundf(pos_x * width);
int y = roundf((1.0 - pos_y) * height);
if (!d3d11->sprites.enabled || d3d11->sprites.offset + msg_len > d3d11->sprites.size)
if (!d3d11->sprites.enabled || d3d11->sprites.offset + msg_len > d3d11->sprites.capacity)
return;
switch (text_align)
@ -148,12 +149,12 @@ static void d3d11_font_render_line(
break;
}
D3D11_MAPPED_SUBRESOURCE mapped_vbo;
D3D11MapBuffer(d3d11->ctx, d3d11->sprites.vbo, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mapped_vbo);
d3d11_sprite_t* v = (d3d11_sprite_t*)mapped_vbo.pData + d3d11->sprites.offset;
v = (d3d11_sprite_t*)mapped_vbo.pData + d3d11->sprites.offset;
for (i = 0; i < msg_len; i++)
{
const struct font_glyph* glyph;
const char* msg_tmp = &msg[i];
unsigned code = utf8_walk(&msg_tmp);
unsigned skip = msg_tmp - &msg[i];
@ -161,7 +162,7 @@ static void d3d11_font_render_line(
if (skip > 1)
i += skip - 1;
const struct font_glyph* glyph = font->font_driver->get_glyph(font->font_data, code);
glyph = font->font_driver->get_glyph(font->font_data, code);
if (!glyph) /* Do something smarter here ... */
glyph = font->font_driver->get_glyph(font->font_data, '?');
@ -177,7 +178,7 @@ static void d3d11_font_render_line(
v->coords.u = glyph->atlas_offset_x / (float)font->texture.desc.Width;
v->coords.v = glyph->atlas_offset_y / (float)font->texture.desc.Height;
v->coords.w = glyph->width / (float)font->texture.desc.Width;
v->coords.h = glyph->height / (float)font->texture.desc.Height;
v->coords.h = glyph->height / (float)font->texture.desc.Height;
v->colors[0] = color;
v->colors[1] = color;
@ -190,9 +191,7 @@ static void d3d11_font_render_line(
y += glyph->advance_y * scale;
}
v++;
int count = v - ((d3d11_sprite_t*)mapped_vbo.pData + d3d11->sprites.offset);
count = v - ((d3d11_sprite_t*)mapped_vbo.pData + d3d11->sprites.offset);
D3D11UnmapBuffer(d3d11->ctx, d3d11->sprites.vbo, 0);
if (!count)
@ -200,20 +199,18 @@ static void d3d11_font_render_line(
if (font->atlas->dirty)
{
d3d11_update_texture(
d3d11->ctx, font->atlas->width, font->atlas->height, font->atlas->width, DXGI_FORMAT_A8_UNORM,
font->atlas->buffer, &font->texture);
font->atlas->dirty = false;
d3d11->ctx, font->atlas->width, font->atlas->height, font->atlas->width,
DXGI_FORMAT_A8_UNORM, font->atlas->buffer, &font->texture);
font->atlas->dirty = false;
font->texture.dirty = true;
}
if(font->texture.dirty)
if (font->texture.dirty)
{
D3D11_BOX frame_box = { 0, 0, 0, font->atlas->width, font->atlas->height, 1 };
D3D11CopyTexture2DSubresourceRegion(
d3d11->ctx, font->texture.handle, 0, 0, 0, 0, font->texture.staging, 0,
&frame_box);
d3d11->ctx, font->texture.handle, 0, 0, 0, 0, font->texture.staging, 0, &frame_box);
font->texture.dirty = false;
}

View File

@ -1162,6 +1162,10 @@ MENU
#include "../menu/drivers_display/menu_display_d3d.c"
#endif
#if defined(HAVE_D3D11)
#include "../menu/drivers_display/menu_display_d3d11.c"
#endif
#ifdef HAVE_OPENGL
#include "../menu/drivers_display/menu_display_gl.c"
#endif

View File

@ -0,0 +1,139 @@
/* 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/>.
*/
#include <retro_miscellaneous.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "menu/menu_driver.h"
#include "retroarch.h"
#include "gfx/font_driver.h"
#include "gfx/video_driver.h"
#include "gfx/common/d3d11_common.h"
static const float* menu_display_d3d11_get_default_vertices(void) { return NULL; }
static const float* menu_display_d3d11_get_default_tex_coords(void) { return NULL; }
static void* menu_display_d3d11_get_default_mvp(void) { return NULL; }
static void menu_display_d3d11_blend_begin(void) {}
static void menu_display_d3d11_blend_end(void) {}
static void menu_display_d3d11_viewport(void* data) {}
static void menu_display_d3d11_draw(void* data)
{
d3d11_video_t* d3d11 = (d3d11_video_t*)video_driver_get_ptr(false);
menu_display_ctx_draw_t* draw = (menu_display_ctx_draw_t*)data;
if (!d3d11 || !draw || !draw->texture)
return;
if (draw->pipeline.id)
return;
if (!d3d11->sprites.enabled)
return;
if(d3d11->sprites.offset + 1 > d3d11->sprites.capacity)
return;
D3D11_MAPPED_SUBRESOURCE mapped_vbo;
D3D11MapBuffer(d3d11->ctx, d3d11->sprites.vbo, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mapped_vbo);
d3d11_sprite_t* v = (d3d11_sprite_t*)mapped_vbo.pData + d3d11->sprites.offset;
v->pos.x = draw->x / (float)d3d11->viewport.Width;
v->pos.y = (d3d11->viewport.Height - draw->y - draw->height) / (float)d3d11->viewport.Height;
v->pos.w = draw->width / (float)d3d11->viewport.Width;
v->pos.h = draw->height / (float)d3d11->viewport.Height;
v->coords.u = 0.0f;
v->coords.v = 0.0f;
v->coords.w = 1.0f;
v->coords.h = 1.0f;
v->colors[0] = 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[1] = 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[2] = DXGI_COLOR_RGBA(
0xFF * draw->coords->color[8], 0xFF * draw->coords->color[9],
0xFF * draw->coords->color[10], 0xFF * draw->coords->color[11]);
v->colors[3] = DXGI_COLOR_RGBA(
0xFF * draw->coords->color[12], 0xFF * draw->coords->color[13],
0xFF * draw->coords->color[14], 0xFF * draw->coords->color[15]);
D3D11UnmapBuffer(d3d11->ctx, d3d11->sprites.vbo, 0);
#if 0
D3D11SetPShader(d3d11->ctx, d3d11->sprites.ps, NULL, 0);
#endif
D3D11SetPShaderResources(d3d11->ctx, 0, 1, &((d3d11_texture_t*)draw->texture)->view);
D3D11Draw(d3d11->ctx, 1, d3d11->sprites.offset);
d3d11->sprites.offset++;
return;
}
static void menu_display_d3d11_draw_pipeline(void* data) {}
static void menu_display_d3d11_restore_clear_color(void) {}
static void menu_display_d3d11_clear_color(menu_display_ctx_clearcolor_t* clearcolor)
{
DWORD clear_color = 0;
d3d11_video_t* d3d11 = (d3d11_video_t*)video_driver_get_ptr(false);
if (!d3d11 || !clearcolor)
return;
D3D11ClearRenderTargetView(d3d11->ctx, d3d11->renderTargetView, (float*)clearcolor);
}
static bool menu_display_d3d11_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;
*handle = font_driver_init_first(
video_data, font_path, font_size, true, is_threaded, FONT_DRIVER_RENDER_D3D11_API);
return *handle;
}
menu_display_ctx_driver_t menu_display_ctx_d3d11 = {
menu_display_d3d11_draw,
menu_display_d3d11_draw_pipeline,
menu_display_d3d11_viewport,
menu_display_d3d11_blend_begin,
menu_display_d3d11_blend_end,
menu_display_d3d11_restore_clear_color,
menu_display_d3d11_clear_color,
menu_display_d3d11_get_default_mvp,
menu_display_d3d11_get_default_vertices,
menu_display_d3d11_get_default_tex_coords,
menu_display_d3d11_font_init_first,
MENU_VIDEO_DRIVER_DIRECT3D11,
"menu_display_d3d11",
};

View File

@ -90,6 +90,9 @@ static menu_display_ctx_driver_t *menu_display_ctx_drivers[] = {
#ifdef HAVE_D3D
&menu_display_ctx_d3d,
#endif
#ifdef HAVE_D3D11
&menu_display_ctx_d3d11,
#endif
#ifdef HAVE_OPENGL
&menu_display_ctx_gl,
#endif
@ -222,6 +225,10 @@ static bool menu_display_check_compatibility(
)
return true;
break;
case MENU_VIDEO_DRIVER_DIRECT3D11:
if (string_is_equal(video_driver, "d3d11"))
return true;
break;
case MENU_VIDEO_DRIVER_VITA2D:
if (string_is_equal(video_driver, "vita2d"))
return true;

View File

@ -279,6 +279,7 @@ enum menu_display_driver_type
MENU_VIDEO_DRIVER_OPENGL,
MENU_VIDEO_DRIVER_VULKAN,
MENU_VIDEO_DRIVER_DIRECT3D,
MENU_VIDEO_DRIVER_DIRECT3D11,
MENU_VIDEO_DRIVER_VITA2D,
MENU_VIDEO_DRIVER_CTR,
MENU_VIDEO_DRIVER_WIIU,
@ -732,6 +733,7 @@ extern uintptr_t menu_display_white_texture;
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_d3d;
extern menu_display_ctx_driver_t menu_display_ctx_d3d11;
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_wiiu;