diff --git a/Makefile.common b/Makefile.common
index 92d363a2ab..49dd6d3292 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -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
diff --git a/gfx/common/d3d11_common.c b/gfx/common/d3d11_common.c
index b3cd629ec1..bb913b8934 100644
--- a/gfx/common/d3d11_common.c
+++ b/gfx/common/d3d11_common.c
@@ -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);
{
diff --git a/gfx/common/d3d11_common.h b/gfx/common/d3d11_common.h
index b8666daeec..12184ca7f1 100644
--- a/gfx/common/d3d11_common.h
+++ b/gfx/common/d3d11_common.h
@@ -2538,7 +2538,7 @@ typedef struct
D3D11Buffer vbo;
D3D11InputLayout layout;
int offset;
- int size;
+ int capacity;
bool enabled;
} sprites;
} d3d11_video_t;
diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c
index d2b3e4f6ef..1ac809e2f1 100644
--- a/gfx/drivers/d3d11.c
+++ b/gfx/drivers/d3d11.c
@@ -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(¤t_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 */
diff --git a/gfx/drivers/d3d_shaders/sprite_sm4.hlsl.h b/gfx/drivers/d3d_shaders/sprite_sm4.hlsl.h
index 2e1c081eb1..8448599210 100644
--- a/gfx/drivers/d3d_shaders/sprite_sm4.hlsl.h
+++ b/gfx/drivers/d3d_shaders/sprite_sm4.hlsl.h
@@ -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;
};
)
diff --git a/gfx/drivers_font/d3d11_font.c b/gfx/drivers_font/d3d11_font.c
index 4f91e77e2a..8cce456f5d 100644
--- a/gfx/drivers_font/d3d11_font.c
+++ b/gfx/drivers_font/d3d11_font.c
@@ -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;
}
diff --git a/griffin/griffin.c b/griffin/griffin.c
index 26a7fdbc3d..8a5f02c6c9 100644
--- a/griffin/griffin.c
+++ b/griffin/griffin.c
@@ -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
diff --git a/menu/drivers_display/menu_display_d3d11.c b/menu/drivers_display/menu_display_d3d11.c
new file mode 100644
index 0000000000..f7b5faab41
--- /dev/null
+++ b/menu/drivers_display/menu_display_d3d11.c
@@ -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 .
+ */
+
+#include
+
+#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",
+};
diff --git a/menu/menu_driver.c b/menu/menu_driver.c
index acd2f4456b..bebf064d09 100644
--- a/menu/menu_driver.c
+++ b/menu/menu_driver.c
@@ -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;
diff --git a/menu/menu_driver.h b/menu/menu_driver.h
index 030fba6aff..fdedb7765d 100644
--- a/menu/menu_driver.h
+++ b/menu/menu_driver.h
@@ -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;