mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 12:32:52 +00:00
Merge pull request #6169 from aliaspider/master
(D3D11) font + menu display drivers.
This commit is contained in:
commit
3bfc13223c
@ -1302,7 +1302,8 @@ ifeq ($(HAVE_D3D10), 1)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_D3D11), 1)
|
||||
OBJ += gfx/drivers/d3d11.o gfx/common/d3d11_common.o
|
||||
OBJ += gfx/drivers/d3d11.o gfx/common/d3d11_common.o \
|
||||
gfx/drivers_font/d3d11_font.o menu/drivers_display/menu_display_d3d11.o
|
||||
DEFINES += -DHAVE_D3D11
|
||||
endif
|
||||
|
||||
|
@ -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);
|
||||
|
||||
{
|
||||
|
@ -2473,6 +2473,24 @@ typedef struct
|
||||
bool dirty;
|
||||
} d3d11_texture_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
float x, y, w, h;
|
||||
} pos;
|
||||
struct
|
||||
{
|
||||
float u, v, w, h;
|
||||
} coords;
|
||||
UINT32 colors[4];
|
||||
struct
|
||||
{
|
||||
float scaling;
|
||||
float rotation;
|
||||
}params;
|
||||
} d3d11_sprite_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned cur_mon_id;
|
||||
@ -2480,6 +2498,7 @@ typedef struct
|
||||
D3D11Device device;
|
||||
D3D_FEATURE_LEVEL supportedFeatureLevel;
|
||||
D3D11DeviceContext ctx;
|
||||
D3D11RasterizerState state;
|
||||
D3D11RenderTargetView renderTargetView;
|
||||
D3D11InputLayout layout;
|
||||
D3D11Buffer ubo;
|
||||
@ -2515,6 +2534,18 @@ typedef struct
|
||||
D3D11_VIEWPORT viewport;
|
||||
int rotation;
|
||||
} frame;
|
||||
struct
|
||||
{
|
||||
D3D11VertexShader vs;
|
||||
D3D11PixelShader ps;
|
||||
D3D11PixelShader ps_8bit;
|
||||
D3D11GeometryShader gs;
|
||||
D3D11Buffer vbo;
|
||||
D3D11InputLayout layout;
|
||||
int offset;
|
||||
int capacity;
|
||||
bool enabled;
|
||||
} sprites;
|
||||
} d3d11_video_t;
|
||||
|
||||
void d3d11_init_texture(D3D11Device device, d3d11_texture_t* texture);
|
||||
|
@ -19,6 +19,14 @@
|
||||
#include "gfx/common/d3dcompiler_common.h"
|
||||
#include "verbosity.h"
|
||||
|
||||
static dylib_t d3dcompiler_dll;
|
||||
static const char* d3dcompiler_dll_list[] = {
|
||||
"D3DCompiler_47.dll", "D3DCompiler_46.dll", "D3DCompiler_45.dll", "D3DCompiler_44.dll",
|
||||
"D3DCompiler_43.dll", "D3DCompiler_42.dll", "D3DCompiler_41.dll", "D3DCompiler_40.dll",
|
||||
"D3DCompiler_39.dll", "D3DCompiler_38.dll", "D3DCompiler_37.dll", "D3DCompiler_36.dll",
|
||||
"D3DCompiler_35.dll", "D3DCompiler_34.dll", "D3DCompiler_33.dll", NULL,
|
||||
};
|
||||
|
||||
HRESULT WINAPI D3DCompile(
|
||||
LPCVOID pSrcData,
|
||||
SIZE_T SrcDataSize,
|
||||
@ -32,22 +40,13 @@ HRESULT WINAPI D3DCompile(
|
||||
ID3DBlob** ppCode,
|
||||
ID3DBlob** ppErrorMsgs)
|
||||
{
|
||||
static dylib_t d3dcompiler_dll;
|
||||
static const char* dll_list[] = {
|
||||
"D3DCompiler_47.dll", "D3DCompiler_46.dll", "D3DCompiler_45.dll", "D3DCompiler_44.dll",
|
||||
"D3DCompiler_43.dll", "D3DCompiler_42.dll", "D3DCompiler_41.dll", "D3DCompiler_40.dll",
|
||||
"D3DCompiler_39.dll", "D3DCompiler_38.dll", "D3DCompiler_37.dll", "D3DCompiler_36.dll",
|
||||
"D3DCompiler_35.dll", "D3DCompiler_34.dll", "D3DCompiler_33.dll", NULL,
|
||||
};
|
||||
const char** dll_name = dll_list;
|
||||
|
||||
const char** dll_name = d3dcompiler_dll_list;
|
||||
while (!d3dcompiler_dll && *dll_name)
|
||||
d3dcompiler_dll = dylib_load(*dll_name++);
|
||||
|
||||
if (d3dcompiler_dll)
|
||||
{
|
||||
static pD3DCompile fp;
|
||||
|
||||
if (!fp)
|
||||
fp = (pD3DCompile)dylib_proc(d3dcompiler_dll, "D3DCompile");
|
||||
|
||||
@ -60,6 +59,40 @@ HRESULT WINAPI D3DCompile(
|
||||
return TYPE_E_CANTLOADLIBRARY;
|
||||
}
|
||||
|
||||
HRESULT WINAPI D3DCompileFromFile(
|
||||
LPCWSTR pFileName,
|
||||
const D3D_SHADER_MACRO* pDefines,
|
||||
ID3DInclude* pInclude,
|
||||
LPCSTR pEntrypoint,
|
||||
LPCSTR pTarget,
|
||||
UINT Flags1,
|
||||
UINT Flags2,
|
||||
ID3DBlob** ppCode,
|
||||
ID3DBlob** ppErrorMsgs)
|
||||
{
|
||||
const char** dll_name = d3dcompiler_dll_list;
|
||||
while (!d3dcompiler_dll && *dll_name)
|
||||
d3dcompiler_dll = dylib_load(*dll_name++);
|
||||
|
||||
if (d3dcompiler_dll)
|
||||
{
|
||||
typedef HRESULT(WINAPI * pD3DCompileFromFile)(
|
||||
LPCWSTR pFileName, const D3D_SHADER_MACRO* pDefines, ID3DInclude* pInclude,
|
||||
LPCSTR pEntrypoint, LPCSTR pTarget, UINT Flags1, UINT Flags2, ID3DBlob** ppCode,
|
||||
ID3DBlob** ppErrorMsgs);
|
||||
static pD3DCompileFromFile fp;
|
||||
if (!fp)
|
||||
fp = (pD3DCompileFromFile)dylib_proc(d3dcompiler_dll, "D3DCompileFromFile");
|
||||
|
||||
if (fp)
|
||||
return fp(
|
||||
pFileName, pDefines, pInclude, pEntrypoint, pTarget, Flags1, Flags2, ppCode,
|
||||
ppErrorMsgs);
|
||||
}
|
||||
|
||||
return TYPE_E_CANTLOADLIBRARY;
|
||||
}
|
||||
|
||||
bool d3d_compile(const char* src, size_t size, LPCSTR entrypoint, LPCSTR target, D3DBlob* out)
|
||||
{
|
||||
D3DBlob error_msg;
|
||||
@ -71,12 +104,35 @@ bool d3d_compile(const char* src, size_t size, LPCSTR entrypoint, LPCSTR target,
|
||||
|
||||
if (FAILED(D3DCompile(
|
||||
src, size, NULL, NULL, NULL, entrypoint, target, compileflags, 0, out, &error_msg)))
|
||||
return false;
|
||||
|
||||
if (error_msg)
|
||||
{
|
||||
RARCH_ERR("D3DCompile failed :\n%s\n", (const char*)D3DGetBufferPointer(error_msg));
|
||||
Release(error_msg);
|
||||
if (error_msg)
|
||||
{
|
||||
RARCH_ERR("D3DCompile failed :\n%s\n", (const char*)D3DGetBufferPointer(error_msg));
|
||||
Release(error_msg);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool d3d_compile_from_file(LPCWSTR filename, LPCSTR entrypoint, LPCSTR target, D3DBlob* out)
|
||||
{
|
||||
D3DBlob error_msg;
|
||||
UINT compileflags = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
compileflags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
|
||||
#endif
|
||||
|
||||
if (FAILED(D3DCompileFromFile(
|
||||
filename, NULL, NULL, entrypoint, target, compileflags, 0, out, &error_msg)))
|
||||
{
|
||||
if (error_msg)
|
||||
{
|
||||
RARCH_ERR("D3DCompile failed :\n%s\n", (const char*)D3DGetBufferPointer(error_msg));
|
||||
Release(error_msg);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -89,3 +89,4 @@ D3DUnregisterDestructionCallback(D3DDestructionNotifier destruction_notifier, UI
|
||||
/* end of auto-generated */
|
||||
|
||||
bool d3d_compile(const char* src, size_t size, LPCSTR entrypoint, LPCSTR target, D3DBlob* out);
|
||||
bool d3d_compile_from_file(LPCWSTR filename, LPCSTR entrypoint, LPCSTR target, D3DBlob* out);
|
||||
|
@ -76,6 +76,20 @@ DXGI_FORMAT* dxgi_get_format_fallback_list(DXGI_FORMAT format)
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN };
|
||||
return formats;
|
||||
}
|
||||
case DXGI_FORMAT_A8_UNORM:
|
||||
{
|
||||
static DXGI_FORMAT formats[] = { DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_R8_UNORM,
|
||||
DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN };
|
||||
return formats;
|
||||
}
|
||||
case DXGI_FORMAT_R8_UNORM:
|
||||
{
|
||||
static DXGI_FORMAT formats[] = { DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_A8_UNORM,
|
||||
DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN };
|
||||
return formats;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
@ -87,7 +101,8 @@ DXGI_FORMAT* dxgi_get_format_fallback_list(DXGI_FORMAT format)
|
||||
dst_gb, dst_bb, dst_ab, dst_rs, dst_gs, dst_bs, dst_as) \
|
||||
do \
|
||||
{ \
|
||||
if (((src_rs == dst_rs && src_rb == dst_rb) || !dst_rb) && \
|
||||
if ((sizeof(src_type) == sizeof(dst_type)) && \
|
||||
((src_rs == dst_rs && src_rb == dst_rb) || !dst_rb) && \
|
||||
((src_gs == dst_gs && src_gb == dst_gb) || !dst_gb) && \
|
||||
((src_bs == dst_bs && src_bb == dst_bb) || !dst_bb) && \
|
||||
((src_as == dst_as && src_ab == dst_ab) || !dst_ab)) \
|
||||
@ -184,6 +199,8 @@ DXGI_FORMAT* dxgi_get_format_fallback_list(DXGI_FORMAT format)
|
||||
#define DXGI_FORMAT_R8G8B8A8_UNORM_DESCS UINT32, 8, 8, 8, 8, 0, 8, 16, 24
|
||||
#define DXGI_FORMAT_B8G8R8X8_UNORM_DESCS UINT32, 8, 8, 8, 0, 16, 8, 0, 0
|
||||
#define DXGI_FORMAT_B8G8R8A8_UNORM_DESCS UINT32, 8, 8, 8, 8, 16, 8, 0, 24
|
||||
#define DXGI_FORMAT_A8_UNORM_DESCS UINT8, 0, 0, 0, 8, 0, 0, 0, 0
|
||||
#define DXGI_FORMAT_R8_UNORM_DESCS UINT8, 8, 0, 0, 0, 0, 0, 0, 0
|
||||
#define DXGI_FORMAT_B5G6R5_UNORM_DESCS UINT16, 5, 6, 5, 0, 11, 5, 0, 0
|
||||
#define DXGI_FORMAT_B5G5R5A1_UNORM_DESCS UINT16, 5, 5, 5, 1, 10, 5, 0, 11
|
||||
#define DXGI_FORMAT_B4G4R4A4_UNORM_DESCS UINT16, 4, 4, 4, 4, 8, 4, 0, 12
|
||||
@ -192,6 +209,8 @@ DXGI_FORMAT* dxgi_get_format_fallback_list(DXGI_FORMAT format)
|
||||
#define FORMAT_SRC_LIST() \
|
||||
FORMAT_SRC(DXGI_FORMAT_R8G8B8A8_UNORM); \
|
||||
FORMAT_SRC(DXGI_FORMAT_B8G8R8X8_UNORM); \
|
||||
FORMAT_SRC(DXGI_FORMAT_A8_UNORM); \
|
||||
FORMAT_SRC(DXGI_FORMAT_R8_UNORM); \
|
||||
FORMAT_SRC(DXGI_FORMAT_B5G6R5_UNORM); \
|
||||
FORMAT_SRC(DXGI_FORMAT_B5G5R5A1_UNORM); \
|
||||
FORMAT_SRC(DXGI_FORMAT_B4G4R4A4_UNORM); \
|
||||
@ -201,6 +220,8 @@ DXGI_FORMAT* dxgi_get_format_fallback_list(DXGI_FORMAT format)
|
||||
#define FORMAT_DST_LIST(srcfmt) \
|
||||
FORMAT_DST(srcfmt, DXGI_FORMAT_R8G8B8A8_UNORM); \
|
||||
FORMAT_DST(srcfmt, DXGI_FORMAT_B8G8R8X8_UNORM); \
|
||||
FORMAT_DST(srcfmt, DXGI_FORMAT_A8_UNORM); \
|
||||
FORMAT_DST(srcfmt, DXGI_FORMAT_R8_UNORM); \
|
||||
FORMAT_DST(srcfmt, DXGI_FORMAT_B5G6R5_UNORM); \
|
||||
FORMAT_DST(srcfmt, DXGI_FORMAT_B5G5R5A1_UNORM); \
|
||||
FORMAT_DST(srcfmt, DXGI_FORMAT_B4G4R4A4_UNORM); \
|
||||
|
@ -542,6 +542,8 @@ static inline HRESULT DXGICreateFactory(DXGIFactory* factory)
|
||||
|
||||
/* internal */
|
||||
|
||||
#define DXGI_COLOR_RGBA(r, g, b, a) (((UINT32)(a) << 24) | ((UINT32)(b) << 16) | ((UINT32)(g) << 8) | ((UINT32)(r) << 0))
|
||||
|
||||
typedef enum {
|
||||
DXGI_FORMAT_EX_A4R4G4B4_UNORM = 1000,
|
||||
} DXGI_FORMAT_EX;
|
||||
|
@ -22,11 +22,13 @@
|
||||
#include "../../verbosity.h"
|
||||
#include "../configuration.h"
|
||||
#include "../video_driver.h"
|
||||
#include "../font_driver.h"
|
||||
#include "../common/win32_common.h"
|
||||
#include "../common/d3d11_common.h"
|
||||
#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)
|
||||
{
|
||||
@ -71,10 +73,59 @@ static void d3d11_update_viewport(void* data, bool force_full)
|
||||
d3d11->resize_viewport = false;
|
||||
}
|
||||
|
||||
static void d3d11_gfx_free(void* data)
|
||||
{
|
||||
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
|
||||
|
||||
if (!d3d11)
|
||||
return;
|
||||
|
||||
Release(d3d11->frame.ubo);
|
||||
Release(d3d11->frame.texture.view);
|
||||
Release(d3d11->frame.texture.handle);
|
||||
Release(d3d11->frame.texture.staging);
|
||||
Release(d3d11->frame.vbo);
|
||||
|
||||
Release(d3d11->menu.texture.handle);
|
||||
Release(d3d11->menu.texture.staging);
|
||||
Release(d3d11->menu.texture.view);
|
||||
Release(d3d11->menu.vbo);
|
||||
|
||||
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);
|
||||
|
||||
Release(d3d11->ubo);
|
||||
Release(d3d11->blend_enable);
|
||||
Release(d3d11->blend_disable);
|
||||
Release(d3d11->sampler_nearest);
|
||||
Release(d3d11->sampler_linear);
|
||||
Release(d3d11->ps);
|
||||
Release(d3d11->vs);
|
||||
Release(d3d11->layout);
|
||||
Release(d3d11->state);
|
||||
Release(d3d11->renderTargetView);
|
||||
Release(d3d11->swapChain);
|
||||
|
||||
font_driver_free_osd();
|
||||
|
||||
Release(d3d11->ctx);
|
||||
Release(d3d11->device);
|
||||
|
||||
win32_monitor_from_window();
|
||||
win32_destroy_window();
|
||||
free(d3d11);
|
||||
}
|
||||
|
||||
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));
|
||||
@ -87,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;
|
||||
@ -100,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,
|
||||
@ -138,13 +199,12 @@ 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;
|
||||
d3d11->vsync = video->vsync;
|
||||
d3d11->format = video->rgb32 ? DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM;
|
||||
|
||||
d3d11->frame.texture.desc.Format =
|
||||
d3d11_get_closest_match_texture2D(d3d11->device, d3d11->format);
|
||||
@ -171,9 +231,9 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
|
||||
{
|
||||
D3D11_SAMPLER_DESC desc = {
|
||||
.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT,
|
||||
.AddressU = D3D11_TEXTURE_ADDRESS_BORDER,
|
||||
.AddressV = D3D11_TEXTURE_ADDRESS_BORDER,
|
||||
.AddressW = D3D11_TEXTURE_ADDRESS_BORDER,
|
||||
.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP,
|
||||
.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP,
|
||||
.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP,
|
||||
.MaxAnisotropy = 1,
|
||||
.ComparisonFunc = D3D11_COMPARISON_NEVER,
|
||||
.MinLOD = -D3D11_FLOAT32_MAX,
|
||||
@ -197,19 +257,20 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
|
||||
|
||||
{
|
||||
D3D11_BUFFER_DESC desc = {
|
||||
.Usage = D3D11_USAGE_DYNAMIC,
|
||||
.ByteWidth = sizeof(vertices),
|
||||
.BindFlags = D3D11_BIND_VERTEX_BUFFER,
|
||||
.StructureByteStride = 0, /* sizeof(Vertex) ? */
|
||||
.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE,
|
||||
.Usage = D3D11_USAGE_IMMUTABLE,
|
||||
.ByteWidth = sizeof(vertices),
|
||||
.BindFlags = D3D11_BIND_VERTEX_BUFFER,
|
||||
};
|
||||
D3D11_SUBRESOURCE_DATA vertexData = { vertices };
|
||||
D3D11CreateBuffer(d3d11->device, &desc, &vertexData, &d3d11->menu.vbo);
|
||||
desc.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
desc.CPUAccessFlags = 0;
|
||||
D3D11CreateBuffer(d3d11->device, &desc, &vertexData, &d3d11->frame.vbo);
|
||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
D3D11CreateBuffer(d3d11->device, &desc, &vertexData, &d3d11->menu.vbo);
|
||||
|
||||
d3d11->sprites.capacity = 4096;
|
||||
desc.ByteWidth = sizeof(d3d11_sprite_t) * d3d11->sprites.capacity;
|
||||
D3D11CreateBuffer(d3d11->device, &desc, NULL, &d3d11->sprites.vbo);
|
||||
}
|
||||
D3D11SetPrimitiveTopology(d3d11->ctx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
}
|
||||
|
||||
{
|
||||
@ -246,9 +307,72 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
|
||||
Release(ps_code);
|
||||
}
|
||||
|
||||
D3D11SetInputLayout(d3d11->ctx, d3d11->layout);
|
||||
D3D11SetVShader(d3d11->ctx, d3d11->vs, NULL, 0);
|
||||
D3D11SetPShader(d3d11->ctx, d3d11->ps, NULL, 0);
|
||||
{
|
||||
D3DBlob vs_code;
|
||||
D3DBlob ps_code;
|
||||
D3DBlob ps_A8_code;
|
||||
D3DBlob gs_code;
|
||||
|
||||
static const char sprite[] =
|
||||
#include "d3d_shaders/sprite_sm4.hlsl.h"
|
||||
;
|
||||
|
||||
D3D11_INPUT_ELEMENT_DESC desc[] = {
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d11_sprite_t, pos),
|
||||
D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d11_sprite_t, coords),
|
||||
D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(d3d11_sprite_t, colors[0]),
|
||||
D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(d3d11_sprite_t, colors[1]),
|
||||
D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 2, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(d3d11_sprite_t, colors[2]),
|
||||
D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 3, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(d3d11_sprite_t, colors[3]),
|
||||
D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "PARAMS", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d11_sprite_t, params),
|
||||
D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
};
|
||||
#if 0
|
||||
d3d_compile(sprite, sizeof(sprite), "VSMain", "vs_5_0", &vs_code);
|
||||
d3d_compile(sprite, sizeof(sprite), "PSMain", "ps_5_0", &ps_code);
|
||||
d3d_compile(sprite, sizeof(sprite), "PSMainA8", "ps_5_0", &ps_A8_code);
|
||||
d3d_compile(sprite, sizeof(sprite), "GSMain", "gs_5_0", &gs_code);
|
||||
#else
|
||||
if (!d3d_compile_from_file(
|
||||
L"gfx/drivers/d3d_shaders/sprite_sm4.hlsl", "VSMain", "vs_5_0", &vs_code))
|
||||
goto error;
|
||||
if (!d3d_compile_from_file(
|
||||
L"gfx/drivers/d3d_shaders/sprite_sm4.hlsl", "PSMain", "ps_5_0", &ps_code))
|
||||
goto error;
|
||||
if (!d3d_compile_from_file(
|
||||
L"gfx/drivers/d3d_shaders/sprite_sm4.hlsl", "PSMainA8", "ps_5_0", &ps_A8_code))
|
||||
goto error;
|
||||
if (!d3d_compile_from_file(
|
||||
L"gfx/drivers/d3d_shaders/sprite_sm4.hlsl", "GSMain", "gs_5_0", &gs_code))
|
||||
goto error;
|
||||
#endif
|
||||
D3D11CreateVertexShader(
|
||||
d3d11->device, D3DGetBufferPointer(vs_code), D3DGetBufferSize(vs_code), NULL,
|
||||
&d3d11->sprites.vs);
|
||||
D3D11CreatePixelShader(
|
||||
d3d11->device, D3DGetBufferPointer(ps_code), D3DGetBufferSize(ps_code), NULL,
|
||||
&d3d11->sprites.ps);
|
||||
D3D11CreatePixelShader(
|
||||
d3d11->device, D3DGetBufferPointer(ps_A8_code), D3DGetBufferSize(ps_A8_code), NULL,
|
||||
&d3d11->sprites.ps_8bit);
|
||||
D3D11CreateGeometryShader(
|
||||
d3d11->device, D3DGetBufferPointer(gs_code), D3DGetBufferSize(gs_code), NULL,
|
||||
&d3d11->sprites.gs);
|
||||
D3D11CreateInputLayout(
|
||||
d3d11->device, desc, countof(desc), D3DGetBufferPointer(vs_code),
|
||||
D3DGetBufferSize(vs_code), &d3d11->sprites.layout);
|
||||
|
||||
Release(vs_code);
|
||||
Release(ps_code);
|
||||
Release(ps_A8_code);
|
||||
Release(gs_code);
|
||||
}
|
||||
|
||||
{
|
||||
D3D11_BLEND_DESC blend_desc = {
|
||||
@ -270,11 +394,22 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
|
||||
blend_desc.RenderTarget[0].BlendEnable = FALSE;
|
||||
D3D11CreateBlendState(d3d11->device, &blend_desc, &d3d11->blend_disable);
|
||||
}
|
||||
{
|
||||
D3D11_RASTERIZER_DESC desc = {
|
||||
.FillMode = D3D11_FILL_SOLID,
|
||||
.CullMode = D3D11_CULL_NONE,
|
||||
.DepthClipEnable = TRUE,
|
||||
};
|
||||
D3D11CreateRasterizerState(d3d11->device, &desc, &d3d11->state);
|
||||
}
|
||||
D3D11SetState(d3d11->ctx, d3d11->state);
|
||||
|
||||
font_driver_init_osd(d3d11, false, video->is_threaded, FONT_DRIVER_RENDER_D3D11_API);
|
||||
|
||||
return d3d11;
|
||||
|
||||
error:
|
||||
free(d3d11);
|
||||
d3d11_gfx_free(d3d11);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -308,10 +443,16 @@ 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();
|
||||
D3D11ClearRenderTargetView(d3d11->ctx, d3d11->renderTargetView, d3d11->clearcolor);
|
||||
D3D11SetVShader(d3d11->ctx, d3d11->vs, NULL, 0);
|
||||
D3D11SetPShader(d3d11->ctx, d3d11->ps, NULL, 0);
|
||||
D3D11SetGShader(d3d11->ctx, NULL, NULL, 0);
|
||||
D3D11SetInputLayout(d3d11->ctx, d3d11->layout);
|
||||
D3D11SetPrimitiveTopology(d3d11->ctx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
|
||||
if (frame && width && height)
|
||||
{
|
||||
@ -341,21 +482,24 @@ static bool d3d11_gfx_frame(
|
||||
d3d11_update_viewport(d3d11, false);
|
||||
|
||||
D3D11SetViewports(d3d11->ctx, 1, &d3d11->frame.viewport);
|
||||
D3D11SetVertexBuffers(d3d11->ctx, 0, 1, &d3d11->frame.vbo, &stride, &offset);
|
||||
D3D11SetVShaderConstantBuffers(d3d11->ctx, 0, 1, &d3d11->frame.ubo);
|
||||
D3D11SetPShaderResources(d3d11->ctx, 0, 1, &d3d11->frame.texture.view);
|
||||
D3D11SetPShaderSamplers(d3d11->ctx, 0, 1, &d3d11->frame.sampler);
|
||||
|
||||
D3D11SetVertexBuffers(d3d11->ctx, 0, 1, &d3d11->frame.vbo, &stride, &offset);
|
||||
D3D11SetVShaderConstantBuffers(d3d11->ctx, 0, 1, &d3d11->frame.ubo);
|
||||
D3D11SetBlendState(d3d11->ctx, d3d11->blend_disable, NULL, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
D3D11Draw(d3d11->ctx, 4, 0);
|
||||
D3D11SetBlendState(d3d11->ctx, d3d11->blend_enable, NULL, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
// D3D11SetBlendState(d3d11->ctx, d3d11->blend_enable, NULL, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
|
||||
if (d3d11->menu.enabled && d3d11->menu.texture.handle)
|
||||
{
|
||||
if (d3d11->menu.texture.dirty)
|
||||
{
|
||||
D3D11CopyTexture2DSubresourceRegion(
|
||||
d3d11->ctx, d3d11->menu.texture.handle, 0, 0, 0, 0, d3d11->menu.texture.staging,
|
||||
0, NULL);
|
||||
d3d11->menu.texture.dirty = false;
|
||||
}
|
||||
|
||||
if (d3d11->menu.fullscreen)
|
||||
D3D11SetViewports(d3d11->ctx, 1, &d3d11->viewport);
|
||||
@ -367,13 +511,35 @@ static bool d3d11_gfx_frame(
|
||||
D3D11Draw(d3d11->ctx, 4, 0);
|
||||
}
|
||||
}
|
||||
{
|
||||
UINT sprite_stride = sizeof(d3d11_sprite_t);
|
||||
UINT offset = 0;
|
||||
D3D11SetViewports(d3d11->ctx, 1, &d3d11->viewport);
|
||||
D3D11SetVShader(d3d11->ctx, d3d11->sprites.vs, NULL, 0);
|
||||
D3D11SetPShader(d3d11->ctx, d3d11->sprites.ps, NULL, 0);
|
||||
D3D11SetGShader(d3d11->ctx, d3d11->sprites.gs, NULL, 0);
|
||||
D3D11SetInputLayout(d3d11->ctx, d3d11->sprites.layout);
|
||||
D3D11SetPrimitiveTopology(d3d11->ctx, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
D3D11SetVertexBuffers(d3d11->ctx, 0, 1, &d3d11->sprites.vbo, &sprite_stride, &offset);
|
||||
D3D11SetPShaderSamplers(d3d11->ctx, 0, 1, &d3d11->sampler_linear);
|
||||
D3D11SetBlendState(d3d11->ctx, d3d11->blend_enable, NULL, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
|
||||
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);
|
||||
gfx_ctx_d3d.update_window_title(NULL, video_info);
|
||||
}
|
||||
d3d11->sprites.enabled = false;
|
||||
}
|
||||
|
||||
DXGIPresent(d3d11->swapChain, !!d3d11->vsync, 0);
|
||||
PERF_STOP();
|
||||
|
||||
if (msg && *msg)
|
||||
gfx_ctx_d3d.update_window_title(NULL, video_info);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -415,42 +581,6 @@ static bool d3d11_gfx_has_windowed(void* data)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void d3d11_gfx_free(void* data)
|
||||
{
|
||||
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
|
||||
|
||||
if (!d3d11)
|
||||
return;
|
||||
|
||||
Release(d3d11->frame.ubo);
|
||||
Release(d3d11->frame.texture.view);
|
||||
Release(d3d11->frame.texture.handle);
|
||||
Release(d3d11->frame.texture.staging);
|
||||
Release(d3d11->frame.vbo);
|
||||
|
||||
Release(d3d11->menu.texture.handle);
|
||||
Release(d3d11->menu.texture.staging);
|
||||
Release(d3d11->menu.texture.view);
|
||||
Release(d3d11->menu.vbo);
|
||||
|
||||
Release(d3d11->ubo);
|
||||
Release(d3d11->blend_enable);
|
||||
Release(d3d11->blend_disable);
|
||||
Release(d3d11->sampler_nearest);
|
||||
Release(d3d11->sampler_linear);
|
||||
Release(d3d11->ps);
|
||||
Release(d3d11->vs);
|
||||
Release(d3d11->layout);
|
||||
Release(d3d11->renderTargetView);
|
||||
Release(d3d11->swapChain);
|
||||
Release(d3d11->ctx);
|
||||
Release(d3d11->device);
|
||||
|
||||
win32_monitor_from_window();
|
||||
win32_destroy_window();
|
||||
free(d3d11);
|
||||
}
|
||||
|
||||
static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const char* path)
|
||||
{
|
||||
(void)data;
|
||||
@ -524,11 +654,64 @@ static void d3d11_gfx_apply_state_changes(void* data)
|
||||
d3d11->resize_viewport = true;
|
||||
}
|
||||
|
||||
static void d3d11_gfx_set_osd_msg(
|
||||
void* data, video_frame_info_t* video_info, const char* msg, const void* params, void* font)
|
||||
{
|
||||
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
|
||||
|
||||
if (d3d11)
|
||||
{
|
||||
if (d3d11->sprites.enabled)
|
||||
font_driver_render_msg(video_info, font, msg, params);
|
||||
else
|
||||
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 */
|
||||
@ -540,7 +723,7 @@ static const video_poke_interface_t d3d11_poke_interface = {
|
||||
d3d11_gfx_apply_state_changes,
|
||||
d3d11_set_menu_texture_frame,
|
||||
d3d11_set_menu_texture_enable,
|
||||
NULL, /* set_osd_msg */
|
||||
d3d11_gfx_set_osd_msg,
|
||||
NULL, /* show_mouse */
|
||||
NULL, /* grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
|
83
gfx/drivers/d3d_shaders/sprite_sm4.hlsl.h
Normal file
83
gfx/drivers/d3d_shaders/sprite_sm4.hlsl.h
Normal file
@ -0,0 +1,83 @@
|
||||
|
||||
#define SRC(src) #src
|
||||
SRC(
|
||||
|
||||
struct VSInput
|
||||
{
|
||||
float4 position : POSITION;
|
||||
float4 texcoord : TEXCOORD0;
|
||||
float4 color0 : COLOR0;
|
||||
float4 color1 : COLOR1;
|
||||
float4 color2 : COLOR2;
|
||||
float4 color3 : COLOR3;
|
||||
};
|
||||
struct GSInput
|
||||
{
|
||||
float4 position : POSITION;
|
||||
float4 texcoord : TEXCOORD0;
|
||||
float4 color0 : COLOR0;
|
||||
float4 color1 : COLOR1;
|
||||
float4 color2 : COLOR2;
|
||||
float4 color3 : COLOR3;
|
||||
};
|
||||
struct PSInput
|
||||
{
|
||||
float4 position : SV_POSITION;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
float4 color : COLOR;
|
||||
};
|
||||
|
||||
GSInput VSMain(VSInput input)
|
||||
{
|
||||
GSInput output;
|
||||
output.position = input.position * 2.0;
|
||||
output.position.w *= -1.0;
|
||||
output.position.x = output.position.x - 1.0;
|
||||
output.position.y = 1.0 - output.position.y;
|
||||
output.texcoord = input.texcoord;
|
||||
output.color0 = input.color0;
|
||||
output.color1 = input.color1;
|
||||
output.color2 = input.color2;
|
||||
output.color3 = input.color3;
|
||||
return output;
|
||||
}
|
||||
|
||||
[maxvertexcount(4)]
|
||||
void GSMain(point GSInput input[1], inout TriangleStream<PSInput> triStream)
|
||||
{
|
||||
PSInput output;
|
||||
output.position.zw = float2(0.0f, 1.0f);
|
||||
|
||||
output.position.xy = input[0].position.xy + input[0].position.zw * float2(1.0, 0.0);
|
||||
output.texcoord = input[0].texcoord.xy + input[0].texcoord.zw * float2(1.0, 0.0);
|
||||
output.color = input[0].color0;
|
||||
triStream.Append(output);
|
||||
|
||||
output.position.xy = input[0].position.xy + input[0].position.zw * float2(0.0, 0.0);
|
||||
output.texcoord = input[0].texcoord.xy + input[0].texcoord.zw * float2(0.0, 0.0);
|
||||
output.color = input[0].color1;
|
||||
triStream.Append(output);
|
||||
|
||||
output.position.xy = input[0].position.xy + input[0].position.zw * float2(1.0, 1.0);
|
||||
output.texcoord = input[0].texcoord.xy + input[0].texcoord.zw * float2(1.0, 1.0);
|
||||
output.color = input[0].color2;
|
||||
triStream.Append(output);
|
||||
|
||||
output.position.xy = input[0].position.xy + input[0].position.zw * float2(0.0, 1.0);
|
||||
output.texcoord = input[0].texcoord.xy + input[0].texcoord.zw * float2(0.0, 1.0);
|
||||
output.color = input[0].color3;
|
||||
triStream.Append(output);
|
||||
}
|
||||
|
||||
uniform sampler s0;
|
||||
uniform Texture2D <float4> t0;
|
||||
float4 PSMain(PSInput input) : SV_TARGET
|
||||
{
|
||||
return input.color * t0.Sample(s0, input.texcoord);
|
||||
};
|
||||
float4 PSMainA8(PSInput input) : SV_TARGET
|
||||
{
|
||||
return input.color * t0.Sample(s0, input.texcoord).a;
|
||||
};
|
||||
|
||||
)
|
372
gfx/drivers_font/d3d11_font.c
Normal file
372
gfx/drivers_font/d3d11_font.c
Normal file
@ -0,0 +1,372 @@
|
||||
/* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <math.h>
|
||||
#include <encodings/utf.h>
|
||||
|
||||
#include "gfx/font_driver.h"
|
||||
#include "gfx/video_driver.h"
|
||||
#include "gfx/common/d3d11_common.h"
|
||||
|
||||
#include "verbosity.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
d3d11_texture_t texture;
|
||||
const font_renderer_driver_t* font_driver;
|
||||
void* font_data;
|
||||
struct font_atlas* atlas;
|
||||
} d3d11_font_t;
|
||||
|
||||
static void*
|
||||
d3d11_font_init_font(void* data, const char* font_path, float font_size, bool is_threaded)
|
||||
{
|
||||
uint32_t i;
|
||||
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
|
||||
d3d11_font_t* font = (d3d11_font_t*)calloc(1, sizeof(*font));
|
||||
|
||||
if (!font)
|
||||
return NULL;
|
||||
|
||||
if (!font_renderer_create_default(
|
||||
(const void**)&font->font_driver, &font->font_data, font_path, font_size))
|
||||
{
|
||||
RARCH_WARN("Couldn't initialize font renderer.\n");
|
||||
free(font);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
font->atlas = font->font_driver->get_atlas(font->font_data);
|
||||
font->texture.desc.Width = font->atlas->width;
|
||||
font->texture.desc.Height = font->atlas->height;
|
||||
font->texture.desc.Format =
|
||||
d3d11_get_closest_match_texture2D(d3d11->device, DXGI_FORMAT_A8_UNORM);
|
||||
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);
|
||||
font->texture.dirty = true;
|
||||
font->atlas->dirty = false;
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
static void d3d11_font_free_font(void* data, bool is_threaded)
|
||||
{
|
||||
d3d11_font_t* font = (d3d11_font_t*)data;
|
||||
|
||||
if (!font)
|
||||
return;
|
||||
|
||||
if (font->font_driver && font->font_data && font->font_driver->free)
|
||||
font->font_driver->free(font->font_data);
|
||||
|
||||
Release(font->texture.handle);
|
||||
Release(font->texture.staging);
|
||||
Release(font->texture.view);
|
||||
free(font);
|
||||
}
|
||||
|
||||
static int d3d11_font_get_message_width(void* data, const char* msg, unsigned msg_len, float scale)
|
||||
{
|
||||
d3d11_font_t* font = (d3d11_font_t*)data;
|
||||
|
||||
unsigned i;
|
||||
int delta_x = 0;
|
||||
|
||||
if (!font)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < msg_len; i++)
|
||||
{
|
||||
const char* msg_tmp = &msg[i];
|
||||
unsigned code = utf8_walk(&msg_tmp);
|
||||
unsigned skip = msg_tmp - &msg[i];
|
||||
|
||||
if (skip > 1)
|
||||
i += skip - 1;
|
||||
|
||||
const struct font_glyph* 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, '?');
|
||||
|
||||
if (!glyph)
|
||||
continue;
|
||||
|
||||
delta_x += glyph->advance_x;
|
||||
}
|
||||
|
||||
return delta_x * scale;
|
||||
}
|
||||
|
||||
static void d3d11_font_render_line(
|
||||
video_frame_info_t* video_info,
|
||||
d3d11_font_t* font,
|
||||
const char* msg,
|
||||
unsigned msg_len,
|
||||
float scale,
|
||||
const unsigned int color,
|
||||
float pos_x,
|
||||
float pos_y,
|
||||
unsigned text_align)
|
||||
{
|
||||
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 || msg_len > d3d11->sprites.capacity)
|
||||
return;
|
||||
|
||||
if (d3d11->sprites.offset + msg_len > d3d11->sprites.capacity)
|
||||
d3d11->sprites.offset = 0;
|
||||
|
||||
switch (text_align)
|
||||
{
|
||||
case TEXT_ALIGN_RIGHT:
|
||||
x -= d3d11_font_get_message_width(font, msg, msg_len, scale);
|
||||
break;
|
||||
|
||||
case TEXT_ALIGN_CENTER:
|
||||
x -= d3d11_font_get_message_width(font, msg, msg_len, scale) / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
D3D11MapBuffer(d3d11->ctx, d3d11->sprites.vbo, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mapped_vbo);
|
||||
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];
|
||||
|
||||
if (skip > 1)
|
||||
i += skip - 1;
|
||||
|
||||
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, '?');
|
||||
|
||||
if (!glyph)
|
||||
continue;
|
||||
|
||||
v->pos.x = (x + glyph->draw_offset_x) * scale / (float)d3d11->viewport.Width;
|
||||
v->pos.y = (y + glyph->draw_offset_y) * scale / (float)d3d11->viewport.Height;
|
||||
v->pos.w = glyph->width * scale / (float)d3d11->viewport.Width;
|
||||
v->pos.h = glyph->height * scale / (float)d3d11->viewport.Height;
|
||||
|
||||
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->params.scaling = 1;
|
||||
v->params.rotation = 0;
|
||||
|
||||
v->colors[0] = color;
|
||||
v->colors[1] = color;
|
||||
v->colors[2] = color;
|
||||
v->colors[3] = color;
|
||||
|
||||
v++;
|
||||
|
||||
x += glyph->advance_x * scale;
|
||||
y += glyph->advance_y * scale;
|
||||
}
|
||||
|
||||
count = v - ((d3d11_sprite_t*)mapped_vbo.pData + d3d11->sprites.offset);
|
||||
D3D11UnmapBuffer(d3d11->ctx, d3d11->sprites.vbo, 0);
|
||||
|
||||
if (!count)
|
||||
return;
|
||||
|
||||
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;
|
||||
font->texture.dirty = true;
|
||||
}
|
||||
|
||||
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);
|
||||
font->texture.dirty = false;
|
||||
}
|
||||
|
||||
D3D11SetPShader(d3d11->ctx, d3d11->sprites.ps_8bit, NULL, 0);
|
||||
D3D11SetPShaderResources(d3d11->ctx, 0, 1, &font->texture.view);
|
||||
D3D11Draw(d3d11->ctx, count, d3d11->sprites.offset);
|
||||
D3D11SetPShader(d3d11->ctx, d3d11->sprites.ps, NULL, 0);
|
||||
|
||||
d3d11->sprites.offset += count;
|
||||
}
|
||||
|
||||
static void d3d11_font_render_message(
|
||||
video_frame_info_t* video_info,
|
||||
d3d11_font_t* font,
|
||||
const char* msg,
|
||||
float scale,
|
||||
const unsigned int color,
|
||||
float pos_x,
|
||||
float pos_y,
|
||||
unsigned text_align)
|
||||
{
|
||||
int lines = 0;
|
||||
float line_height;
|
||||
|
||||
if (!msg || !*msg)
|
||||
return;
|
||||
|
||||
/* If the font height is not supported just draw as usual */
|
||||
if (!font->font_driver->get_line_height)
|
||||
{
|
||||
d3d11_font_render_line(
|
||||
video_info, font, msg, strlen(msg), scale, color, pos_x, pos_y, text_align);
|
||||
return;
|
||||
}
|
||||
|
||||
line_height = scale / font->font_driver->get_line_height(font->font_data);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const char* delim = strchr(msg, '\n');
|
||||
|
||||
/* Draw the line */
|
||||
if (delim)
|
||||
{
|
||||
unsigned msg_len = delim - msg;
|
||||
d3d11_font_render_line(
|
||||
video_info, font, msg, msg_len, scale, color, pos_x,
|
||||
pos_y - (float)lines * line_height, text_align);
|
||||
msg += msg_len + 1;
|
||||
lines++;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned msg_len = strlen(msg);
|
||||
d3d11_font_render_line(
|
||||
video_info, font, msg, msg_len, scale, color, pos_x,
|
||||
pos_y - (float)lines * line_height, text_align);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void d3d11_font_render_msg(
|
||||
video_frame_info_t* video_info, void* data, const char* msg, const void* userdata)
|
||||
{
|
||||
float x, y, scale, drop_mod, drop_alpha;
|
||||
int drop_x, drop_y;
|
||||
enum text_alignment text_align;
|
||||
unsigned color, color_dark, r, g, b, alpha, r_dark, g_dark, b_dark, alpha_dark;
|
||||
d3d11_font_t* font = (d3d11_font_t*)data;
|
||||
const struct font_params* params = (const struct font_params*)userdata;
|
||||
unsigned width = video_info->width;
|
||||
unsigned height = video_info->height;
|
||||
|
||||
if (!font || !msg || !*msg)
|
||||
return;
|
||||
|
||||
if (params)
|
||||
{
|
||||
x = params->x;
|
||||
y = params->y;
|
||||
scale = params->scale;
|
||||
text_align = params->text_align;
|
||||
drop_x = params->drop_x;
|
||||
drop_y = params->drop_y;
|
||||
drop_mod = params->drop_mod;
|
||||
drop_alpha = params->drop_alpha;
|
||||
r = FONT_COLOR_GET_RED(params->color);
|
||||
g = FONT_COLOR_GET_GREEN(params->color);
|
||||
b = FONT_COLOR_GET_BLUE(params->color);
|
||||
alpha = FONT_COLOR_GET_ALPHA(params->color);
|
||||
color = params->color;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = video_info->font_msg_pos_x;
|
||||
y = video_info->font_msg_pos_y;
|
||||
scale = 1.0f;
|
||||
text_align = TEXT_ALIGN_LEFT;
|
||||
|
||||
r = (video_info->font_msg_color_r * 255);
|
||||
g = (video_info->font_msg_color_g * 255);
|
||||
b = (video_info->font_msg_color_b * 255);
|
||||
alpha = 255;
|
||||
color = DXGI_COLOR_RGBA(r, g, b, alpha);
|
||||
|
||||
drop_x = -2;
|
||||
drop_y = -2;
|
||||
drop_mod = 0.3f;
|
||||
drop_alpha = 1.0f;
|
||||
}
|
||||
|
||||
if (drop_x || drop_y)
|
||||
{
|
||||
r_dark = r * drop_mod;
|
||||
g_dark = g * drop_mod;
|
||||
b_dark = b * drop_mod;
|
||||
alpha_dark = alpha * drop_alpha;
|
||||
color_dark = DXGI_COLOR_RGBA(r_dark, g_dark, b_dark, alpha_dark);
|
||||
|
||||
d3d11_font_render_message(
|
||||
video_info, font, msg, scale, color_dark, x + scale * drop_x / width,
|
||||
y + scale * drop_y / height, text_align);
|
||||
}
|
||||
|
||||
d3d11_font_render_message(video_info, font, msg, scale, color, x, y, text_align);
|
||||
}
|
||||
|
||||
static const struct font_glyph* d3d11_font_get_glyph(void* data, uint32_t code)
|
||||
{
|
||||
d3d11_font_t* font = (d3d11_font_t*)data;
|
||||
|
||||
if (!font || !font->font_driver)
|
||||
return NULL;
|
||||
|
||||
if (!font->font_driver->ident)
|
||||
return NULL;
|
||||
|
||||
return font->font_driver->get_glyph((void*)font->font_driver, code);
|
||||
}
|
||||
|
||||
static void d3d11_font_bind_block(void* data, void* userdata) { (void)data; }
|
||||
|
||||
font_renderer_t d3d11_font = {
|
||||
d3d11_font_init_font,
|
||||
d3d11_font_free_font,
|
||||
d3d11_font_render_msg,
|
||||
"d3d11font",
|
||||
d3d11_font_get_glyph,
|
||||
d3d11_font_bind_block,
|
||||
NULL, /* flush */
|
||||
d3d11_font_get_message_width,
|
||||
};
|
@ -278,6 +278,37 @@ static bool vulkan_font_init_first(
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_D3D11
|
||||
static const font_renderer_t *d3d11_font_backends[] = {
|
||||
&d3d11_font,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static bool d3d11_font_init_first(
|
||||
const void **font_driver, void **font_handle,
|
||||
void *video_data, const char *font_path,
|
||||
float font_size, bool is_threaded)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; d3d11_font_backends[i]; i++)
|
||||
{
|
||||
void *data = d3d11_font_backends[i]->init(video_data,
|
||||
font_path, font_size,
|
||||
is_threaded);
|
||||
|
||||
if (!data)
|
||||
continue;
|
||||
|
||||
*font_driver = d3d11_font_backends[i];
|
||||
*font_handle = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_VITA2D
|
||||
static const font_renderer_t *vita2d_font_backends[] = {
|
||||
&vita2d_vita_font
|
||||
@ -394,6 +425,11 @@ static bool font_init_first(
|
||||
return vulkan_font_init_first(font_driver, font_handle,
|
||||
video_data, font_path, font_size, is_threaded);
|
||||
#endif
|
||||
#ifdef HAVE_D3D11
|
||||
case FONT_DRIVER_RENDER_D3D11_API:
|
||||
return d3d11_font_init_first(font_driver, font_handle,
|
||||
video_data, font_path, font_size, is_threaded);
|
||||
#endif
|
||||
#ifdef HAVE_VITA2D
|
||||
case FONT_DRIVER_RENDER_VITA2D:
|
||||
return vita2d_font_init_first(font_driver, font_handle,
|
||||
|
@ -31,6 +31,7 @@ enum font_driver_render_api
|
||||
FONT_DRIVER_RENDER_DONT_CARE,
|
||||
FONT_DRIVER_RENDER_OPENGL_API,
|
||||
FONT_DRIVER_RENDER_DIRECT3D_API,
|
||||
FONT_DRIVER_RENDER_D3D11_API,
|
||||
FONT_DRIVER_RENDER_VITA2D,
|
||||
FONT_DRIVER_RENDER_CTR,
|
||||
FONT_DRIVER_RENDER_WIIU,
|
||||
@ -184,6 +185,7 @@ extern font_renderer_t vita2d_vita_font;
|
||||
extern font_renderer_t ctr_font;
|
||||
extern font_renderer_t wiiu_font;
|
||||
extern font_renderer_t vulkan_raster_font;
|
||||
extern font_renderer_t d3d11_font;
|
||||
extern font_renderer_t caca_font;
|
||||
extern font_renderer_t gdi_font;
|
||||
extern font_renderer_t vga_font;
|
||||
|
@ -512,6 +512,10 @@ FONTS
|
||||
#include "../gfx/drivers_font/vulkan_raster_font.c"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_D3D11)
|
||||
#include "../gfx/drivers_font/d3d11_font.c"
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
INPUT
|
||||
============================================================ */
|
||||
@ -1158,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
|
||||
|
@ -633,6 +633,8 @@ static void xmb_draw_icon(
|
||||
|
||||
draw.width = icon_size;
|
||||
draw.height = icon_size;
|
||||
draw.rotation = rotation;
|
||||
draw.scale_factor = scale_factor;
|
||||
#if defined(VITA) || defined(WIIU)
|
||||
draw.width *= scale_factor;
|
||||
draw.height *= scale_factor;
|
||||
|
146
menu/drivers_display/menu_display_d3d11.c
Normal file
146
menu/drivers_display/menu_display_d3d11.c
Normal file
@ -0,0 +1,146 @@
|
||||
/* 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)
|
||||
d3d11->sprites.offset = 0;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
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[11]);
|
||||
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]);
|
||||
|
||||
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",
|
||||
};
|
@ -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;
|
||||
@ -608,9 +615,11 @@ void menu_display_draw_bg(menu_display_ctx_draw_t *draw,
|
||||
coords.vertex = new_vertex;
|
||||
coords.tex_coord = new_tex_coord;
|
||||
coords.lut_tex_coord = new_tex_coord;
|
||||
coords.color = (const float*)draw->color;
|
||||
coords.color = (const float*)draw->color;
|
||||
|
||||
draw->coords = &coords;
|
||||
draw->coords = &coords;
|
||||
draw->scale_factor = 1.0f;
|
||||
draw->rotation = 0.0f;
|
||||
|
||||
if (draw->texture)
|
||||
add_opacity_to_wallpaper = true;
|
||||
@ -653,15 +662,17 @@ void menu_display_draw_quad(
|
||||
if (menu_disp && menu_disp->blend_begin)
|
||||
menu_disp->blend_begin();
|
||||
|
||||
draw.x = x;
|
||||
draw.y = (int)height - y - (int)h;
|
||||
draw.width = w;
|
||||
draw.height = h;
|
||||
draw.coords = &coords;
|
||||
draw.matrix_data = NULL;
|
||||
draw.texture = menu_display_white_texture;
|
||||
draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP;
|
||||
draw.pipeline.id = 0;
|
||||
draw.x = x;
|
||||
draw.y = (int)height - y - (int)h;
|
||||
draw.width = w;
|
||||
draw.height = h;
|
||||
draw.coords = &coords;
|
||||
draw.matrix_data = NULL;
|
||||
draw.texture = menu_display_white_texture;
|
||||
draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP;
|
||||
draw.pipeline.id = 0;
|
||||
draw.scale_factor = 1.0f;
|
||||
draw.rotation = 0.0f;
|
||||
|
||||
menu_display_draw(&draw);
|
||||
|
||||
|
@ -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,
|
||||
@ -378,6 +379,8 @@ typedef struct menu_display_ctx_draw
|
||||
size_t backend_data_size;
|
||||
bool active;
|
||||
} pipeline;
|
||||
float rotation;
|
||||
float scale_factor;
|
||||
} menu_display_ctx_draw_t;
|
||||
|
||||
typedef struct menu_display_ctx_rotate_draw
|
||||
@ -732,6 +735,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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user