1
0
mirror of https://github.com/libretro/RetroArch synced 2024-07-05 09:48:42 +00:00

Update Direct3D 10 driver

This commit is contained in:
twinaphex 2018-04-21 03:27:41 +02:00
parent 16df2ceb4e
commit 9f2b56a929
15 changed files with 2173 additions and 161 deletions

View File

@ -1267,7 +1267,9 @@ endif
ifeq ($(HAVE_D3D10), 1)
OBJ += gfx/drivers/d3d10.o \
gfx/common/d3d10_common.o
gfx/common/d3d10_common.o \
gfx/drivers_font/d3d10_font.o \
menu/drivers_display/menu_display_d3d10.o
DEFINES += -DHAVE_D3D10
endif

View File

@ -18,6 +18,7 @@
#include <gfx/scaler/pixconv.h>
#include "d3d10_common.h"
#include "d3dcompiler_common.h"
#ifdef HAVE_DYNAMIC
#include <dynamic/dylib.h>
@ -104,6 +105,7 @@ void d3d10_init_texture(D3D10Device device, d3d10_texture_t* texture)
}
void d3d10_update_texture(
D3D10Device ctx,
int width,
int height,
int pitch,
@ -112,8 +114,13 @@ void d3d10_update_texture(
d3d10_texture_t* texture)
{
D3D10_MAPPED_TEXTURE2D mapped_texture;
D3D10_BOX frame_box = { 0, 0, 0, width, height, 1 };
D3D10MapTexture2D(texture->staging, 0, D3D10_MAP_WRITE, 0,
if (!texture || !texture->staging)
return;
D3D10MapTexture2D(texture->staging,
0, D3D10_MAP_WRITE, 0,
&mapped_texture);
#if 0
@ -130,8 +137,11 @@ void d3d10_update_texture(
D3D10UnmapTexture2D(texture->staging, 0);
if (texture->desc.Usage == D3D10_USAGE_DEFAULT)
texture->dirty = true;
D3D10CopyTexture2DSubresourceRegion(
ctx, texture->handle, 0, 0, 0, 0, texture->staging, 0, &frame_box);
if (texture->desc.MiscFlags & D3D10_RESOURCE_MISC_GENERATE_MIPS)
D3D10GenerateMips(ctx, texture->view);
}
DXGI_FORMAT
@ -155,3 +165,65 @@ d3d10_get_closest_match(D3D10Device device,
assert(*format);
return *format;
}
bool d3d10_init_shader(
D3D10Device device,
const char* src,
size_t size,
const void* src_name,
LPCSTR vs_entry,
LPCSTR ps_entry,
LPCSTR gs_entry,
const D3D10_INPUT_ELEMENT_DESC* input_element_descs,
UINT num_elements,
d3d10_shader_t* out)
{
D3DBlob vs_code = NULL;
D3DBlob ps_code = NULL;
D3DBlob gs_code = NULL;
bool success = true;
if (!src) /* LPCWSTR filename */
{
if (vs_entry && !d3d_compile_from_file((LPCWSTR)src_name, vs_entry, "vs_5_0", &vs_code))
success = false;
if (ps_entry && !d3d_compile_from_file((LPCWSTR)src_name, ps_entry, "ps_5_0", &ps_code))
success = false;
if (gs_entry && !d3d_compile_from_file((LPCWSTR)src_name, gs_entry, "gs_5_0", &gs_code))
success = false;
}
else /* char array */
{
if (vs_entry && !d3d_compile(src, size, (LPCSTR)src_name, vs_entry, "vs_5_0", &vs_code))
success = false;
if (ps_entry && !d3d_compile(src, size, (LPCSTR)src_name, ps_entry, "ps_5_0", &ps_code))
success = false;
if (gs_entry && !d3d_compile(src, size, (LPCSTR)src_name, gs_entry, "gs_5_0", &gs_code))
success = false;
}
if (vs_code)
D3D10CreateVertexShader(
device, D3DGetBufferPointer(vs_code), D3DGetBufferSize(vs_code), &out->vs);
if (ps_code)
D3D10CreatePixelShader(
device, D3DGetBufferPointer(ps_code), D3DGetBufferSize(ps_code), &out->ps);
if (gs_code)
D3D10CreateGeometryShader(
device, D3DGetBufferPointer(gs_code), D3DGetBufferSize(gs_code), &out->gs);
if (vs_code && input_element_descs)
D3D10CreateInputLayout(
device,
(D3D10_INPUT_ELEMENT_DESC*)input_element_descs, num_elements, D3DGetBufferPointer(vs_code),
D3DGetBufferSize(vs_code), &out->layout);
Release(vs_code);
Release(ps_code);
Release(gs_code);
return success;
}

View File

@ -20,6 +20,12 @@
#include "dxgi_common.h"
#include <d3d10.h>
#include "../drivers_shader/slang_process.h"
typedef D3D10_MAPPED_TEXTURE3D D3D10_MAPPED_SUBRESOURCE;
typedef const ID3D10SamplerState* D3D10SamplerStateRef;
typedef ID3D10InputLayout* D3D10InputLayout;
typedef ID3D10RasterizerState* D3D10RasterizerState;
typedef ID3D10DepthStencilState* D3D10DepthStencilState;
@ -50,6 +56,7 @@ typedef ID3D10Debug* D3D10Debug;
typedef ID3D10SwitchToRef* D3D10SwitchToRef;
typedef ID3D10InfoQueue* D3D10InfoQueue;
#if !defined(__cplusplus) || defined(CINTERFACE)
static INLINE void D3D10SetResourceEvictionPriority(D3D10Resource resource, UINT eviction_priority)
{
@ -236,6 +243,7 @@ static INLINE void D3D10SetVShader(D3D10Device device, D3D10VertexShader vertex_
{
device->lpVtbl->VSSetShader(device, vertex_shader);
}
static INLINE void D3D10DrawIndexed(
D3D10Device device, UINT index_count, UINT start_index_location, INT base_vertex_location)
{
@ -265,6 +273,28 @@ static INLINE void D3D10SetVertexBuffers(
device->lpVtbl->IASetVertexBuffers(
device, start_slot, num_buffers, vertex_buffers, strides, offsets);
}
static INLINE void D3D10SetVertexBuffer(
D3D10Device device_context,
UINT slot,
D3D10Buffer const vertex_buffer,
UINT stride,
UINT offset)
{
D3D10SetVertexBuffers(device_context, slot, 1, (D3D10Buffer* const)&vertex_buffer, &stride, &offset);
}
static INLINE void D3D10SetVShaderConstantBuffer(
D3D10Device device_context, UINT slot, D3D10Buffer const constant_buffer)
{
D3D10SetVShaderConstantBuffers(device_context, slot, 1, (ID3D10Buffer ** const)&constant_buffer);
}
static INLINE void D3D10SetPShaderConstantBuffer(
D3D10Device device_context, UINT slot, D3D10Buffer const constant_buffer)
{
D3D10SetPShaderConstantBuffers(device_context, slot, 1, (ID3D10Buffer** const)&constant_buffer);
}
static INLINE void
D3D10SetIndexBuffer(D3D10Device device, D3D10Buffer index_buffer, DXGI_FORMAT format, UINT offset)
{
@ -1047,25 +1077,79 @@ typedef struct
D3D10Texture2D handle;
D3D10Texture2D staging;
D3D10_TEXTURE2D_DESC desc;
D3D10RenderTargetView rt_view;
D3D10ShaderResourceView view;
bool dirty;
bool ignore_alpha;
D3D10SamplerStateRef sampler;
float4_t size_data;
} d3d10_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;
} d3d10_sprite_t;
#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;
} d3d10_uniform_t;
static_assert(
(!(sizeof(d3d10_uniform_t) & 0xF)), "sizeof(d3d10_uniform_t) must be a multiple of 16");
typedef struct d3d10_shader_t
{
D3D10VertexShader vs;
D3D10PixelShader ps;
D3D10GeometryShader gs;
D3D10InputLayout layout;
} d3d10_shader_t;
typedef struct
{
unsigned cur_mon_id;
DXGISwapChain swapChain;
D3D10Device device;
D3D10RasterizerState state;
D3D10RenderTargetView renderTargetView;
D3D10InputLayout layout;
D3D10Buffer ubo;
d3d10_uniform_t ubo_values;
D3D10SamplerState samplers[RARCH_FILTER_MAX][RARCH_WRAP_MAX];
D3D10InputLayout layout;
D3D10VertexShader vs;
D3D10PixelShader ps;
D3D10SamplerState sampler_nearest;
D3D10SamplerState sampler_linear;
D3D10BlendState blend_enable;
D3D10BlendState blend_disable;
D3D10BlendState blend_pipeline;
D3D10Buffer menu_pipeline_vbo;
math_matrix_4x4 mvp, mvp_no_rot;
struct video_viewport vp;
D3D10_VIEWPORT viewport;
@ -1075,6 +1159,31 @@ typedef struct
bool resize_chain;
bool keep_aspect;
bool resize_viewport;
bool resize_render_targets;
bool init_history;
d3d10_shader_t shaders[GFX_MAX_SHADERS];
struct
{
d3d10_shader_t shader;
d3d10_shader_t shader_font;
D3D10Buffer vbo;
int offset;
int capacity;
bool enabled;
} sprites;
#ifdef HAVE_OVERLAY
struct
{
D3D10Buffer vbo;
d3d10_texture_t* textures;
bool enabled;
bool fullscreen;
int count;
} overlays;
#endif
struct
{
d3d10_texture_t texture;
@ -1085,18 +1194,41 @@ typedef struct
} menu;
struct
{
d3d10_texture_t texture;
d3d10_texture_t texture[GFX_MAX_FRAME_HISTORY + 1];
D3D10Buffer vbo;
D3D10Buffer ubo;
D3D10SamplerState sampler;
D3D10_VIEWPORT viewport;
float4_t output_size;
int rotation;
} frame;
struct
{
d3d10_shader_t shader;
D3D10Buffer buffers[SLANG_CBUFFER_MAX];
d3d10_texture_t rt;
d3d10_texture_t feedback;
D3D10_VIEWPORT viewport;
pass_semantics_t semantics;
uint32_t frame_count;
} pass[GFX_MAX_SHADERS];
struct video_shader* shader_preset;
d3d10_texture_t luts[GFX_MAX_TEXTURES];
} d3d10_video_t;
void d3d10_init_texture(D3D10Device device, d3d10_texture_t* texture);
static INLINE void d3d10_release_texture(d3d10_texture_t* texture)
{
Release(texture->handle);
Release(texture->staging);
Release(texture->view);
Release(texture->rt_view);
}
void d3d10_update_texture(
D3D10Device ctx,
int width,
int height,
int pitch,
@ -1107,6 +1239,26 @@ void d3d10_update_texture(
DXGI_FORMAT d3d10_get_closest_match(
D3D10Device device, DXGI_FORMAT desired_format, UINT desired_format_support);
bool d3d10_init_shader(
D3D10Device device,
const char* src,
size_t size,
const void* src_name,
LPCSTR vs_entry,
LPCSTR ps_entry,
LPCSTR gs_entry,
const D3D10_INPUT_ELEMENT_DESC* input_element_descs,
UINT num_elements,
d3d10_shader_t* out);
static INLINE void d3d10_release_shader(d3d10_shader_t* shader)
{
Release(shader->layout);
Release(shader->vs);
Release(shader->ps);
Release(shader->gs);
}
static INLINE DXGI_FORMAT
d3d10_get_closest_match_texture2D(D3D10Device device, DXGI_FORMAT desired_format)
{
@ -1114,3 +1266,20 @@ d3d10_get_closest_match_texture2D(D3D10Device device, DXGI_FORMAT desired_format
device, desired_format,
D3D10_FORMAT_SUPPORT_TEXTURE2D | D3D10_FORMAT_SUPPORT_SHADER_SAMPLE);
}
static INLINE void d3d10_set_shader(D3D10Device ctx, d3d10_shader_t* shader)
{
D3D10SetInputLayout(ctx, shader->layout);
D3D10SetVShader(ctx, shader->vs);
D3D10SetPShader(ctx, shader->ps);
D3D10SetGShader(ctx, shader->gs);
}
#if !defined(__cplusplus) || defined(CINTERFACE)
static INLINE void
d3d10_set_texture_and_sampler(D3D10Device ctx, UINT slot, d3d10_texture_t* texture)
{
D3D10SetPShaderResources(ctx, slot, 1, &texture->view);
D3D10SetPShaderSamplers(ctx, slot, 1, (D3D10SamplerState*)&texture->sampler);
}
#endif

View File

@ -140,11 +140,20 @@ void d3d11_update_texture(
if (!texture || !texture->staging)
return;
D3D11MapTexture2D(ctx, texture->staging, 0, D3D11_MAP_WRITE, 0, &mapped_texture);
D3D11MapTexture2D(ctx, texture->staging,
0, D3D11_MAP_WRITE, 0, &mapped_texture);
#if 0
PERF_START();
conv_rgb565_argb8888(mapped_texture.pData, data, width, height,
mapped_texture.RowPitch, pitch);
PERF_STOP();
#else
dxgi_copy(
width, height, format, pitch, data, texture->desc.Format, mapped_texture.RowPitch,
width, height, format, pitch, data,
texture->desc.Format, mapped_texture.RowPitch,
mapped_texture.pData);
#endif
D3D11UnmapTexture2D(ctx, texture->staging, 0);

View File

@ -237,6 +237,7 @@ static INLINE void D3D11SetPShaderSamplers(
device_context->lpVtbl->PSSetSamplers(
device_context, start_slot, num_samplers, samplers);
}
static INLINE void D3D11SetVShader(
D3D11DeviceContext device_context,
D3D11VertexShader vertex_shader,

File diff suppressed because it is too large Load Diff

View File

@ -996,6 +996,7 @@ static void d3d11_init_history(d3d11_video_t* d3d11, unsigned width, unsigned he
}
d3d11->init_history = false;
}
static void d3d11_init_render_targets(d3d11_video_t* d3d11, unsigned width, unsigned height)
{
unsigned i;

View File

@ -0,0 +1,379 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2011-2018 - Daniel De Matteis
* 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 <stdio.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include <encodings/utf.h>
#include "../font_driver.h"
#include "../video_driver.h"
#include "../common/d3d10_common.h"
#include "../../verbosity.h"
typedef struct
{
d3d10_texture_t texture;
const font_renderer_driver_t* font_driver;
void* font_data;
struct font_atlas* atlas;
} d3d10_font_t;
static void*
d3d10_font_init_font(void* data, const char* font_path, float font_size, bool is_threaded)
{
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
d3d10_font_t* font = (d3d10_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.sampler = d3d10->samplers[RARCH_FILTER_LINEAR][RARCH_WRAP_BORDER];
font->texture.desc.Width = font->atlas->width;
font->texture.desc.Height = font->atlas->height;
font->texture.desc.Format = DXGI_FORMAT_A8_UNORM;
d3d10_init_texture(d3d10->device, &font->texture);
d3d10_update_texture(
d3d10->device,
font->atlas->width, font->atlas->height, font->atlas->width,
DXGI_FORMAT_A8_UNORM, font->atlas->buffer, &font->texture);
font->atlas->dirty = false;
return font;
}
static void d3d10_font_free_font(void* data, bool is_threaded)
{
d3d10_font_t* font = (d3d10_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 d3d10_font_get_message_width(void* data, const char* msg, unsigned msg_len, float scale)
{
d3d10_font_t* font = (d3d10_font_t*)data;
unsigned i;
int delta_x = 0;
if (!font)
return 0;
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;
delta_x += glyph->advance_x;
}
return delta_x * scale;
}
static void d3d10_font_render_line(
video_frame_info_t* video_info,
d3d10_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;
D3D10_MAPPED_SUBRESOURCE mapped_vbo;
d3d10_sprite_t* v;
d3d10_video_t* d3d10 = (d3d10_video_t*)video_info->userdata;
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 ( !d3d10 ||
!d3d10->sprites.enabled ||
msg_len > (unsigned)d3d10->sprites.capacity)
return;
if (d3d10->sprites.offset + msg_len > (unsigned)d3d10->sprites.capacity)
d3d10->sprites.offset = 0;
switch (text_align)
{
case TEXT_ALIGN_RIGHT:
x -= d3d10_font_get_message_width(font, msg, msg_len, scale);
break;
case TEXT_ALIGN_CENTER:
x -= d3d10_font_get_message_width(font, msg, msg_len, scale) / 2;
break;
}
D3D10MapBuffer(d3d10->sprites.vbo, D3D10_MAP_WRITE_NO_OVERWRITE, 0, (void**)&mapped_vbo);
v = (d3d10_sprite_t*)mapped_vbo.pData + d3d10->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)d3d10->viewport.Width;
v->pos.y = (y + glyph->draw_offset_y) * scale / (float)d3d10->viewport.Height;
v->pos.w = glyph->width * scale / (float)d3d10->viewport.Width;
v->pos.h = glyph->height * scale / (float)d3d10->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 - ((d3d10_sprite_t*)mapped_vbo.pData + d3d10->sprites.offset);
D3D10UnmapBuffer(d3d10->sprites.vbo);
if (!count)
return;
if (font->atlas->dirty)
{
d3d10_update_texture(
d3d10->device,
font->atlas->width, font->atlas->height, font->atlas->width,
DXGI_FORMAT_A8_UNORM, font->atlas->buffer, &font->texture);
font->atlas->dirty = false;
}
d3d10_set_texture_and_sampler(d3d10->device, 0, &font->texture);
D3D10SetBlendState(d3d10->device, d3d10->blend_enable, NULL, D3D10_DEFAULT_SAMPLE_MASK);
D3D10SetPShader(d3d10->device, d3d10->sprites.shader_font.ps);
D3D10Draw(d3d10->device, count, d3d10->sprites.offset);
D3D10SetPShader(d3d10->device, d3d10->sprites.shader.ps);
d3d10->sprites.offset += count;
}
static void d3d10_font_render_message(
video_frame_info_t* video_info,
d3d10_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)
{
d3d10_font_render_line(
video_info, font, msg, strlen(msg), scale, color, pos_x, pos_y, text_align);
return;
}
line_height = font->font_driver->get_line_height(font->font_data) * scale / video_info->height;
for (;;)
{
const char* delim = strchr(msg, '\n');
/* Draw the line */
if (delim)
{
unsigned msg_len = delim - msg;
d3d10_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);
d3d10_font_render_line(
video_info, font, msg, msg_len, scale, color, pos_x,
pos_y - (float)lines * line_height, text_align);
break;
}
}
}
static void d3d10_font_render_msg(
video_frame_info_t* video_info, void* data,
const char* msg, const struct font_params *params)
{
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;
d3d10_font_t* font = (d3d10_font_t*)data;
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 = DXGI_COLOR_RGBA(r, g, b, alpha);
}
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);
d3d10_font_render_message(
video_info, font, msg, scale, color_dark,
x + scale * drop_x / width,
y + scale * drop_y / height, text_align);
}
d3d10_font_render_message(video_info, font, msg, scale,
color, x, y, text_align);
}
static const struct font_glyph* d3d10_font_get_glyph(void *data, uint32_t code)
{
d3d10_font_t* font = (d3d10_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 d3d10_font_bind_block(void* data, void *userdata)
{
(void)data;
}
font_renderer_t d3d10_font = {
d3d10_font_init_font,
d3d10_font_free_font,
d3d10_font_render_msg,
"d3d10font",
d3d10_font_get_glyph,
d3d10_font_bind_block,
NULL, /* flush */
d3d10_font_get_message_width,
};

View File

@ -310,6 +310,37 @@ static bool vulkan_font_init_first(
}
#endif
#ifdef HAVE_D3D10
static const font_renderer_t *d3d10_font_backends[] = {
&d3d10_font,
NULL,
};
static bool d3d10_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; d3d10_font_backends[i]; i++)
{
void *data = d3d10_font_backends[i]->init(video_data,
font_path, font_size,
is_threaded);
if (!data)
continue;
*font_driver = d3d10_font_backends[i];
*font_handle = data;
return true;
}
return false;
}
#endif
#ifdef HAVE_D3D11
static const font_renderer_t *d3d11_font_backends[] = {
&d3d11_font,
@ -493,6 +524,11 @@ static bool font_init_first(
return d3d9_font_init_first(font_driver, font_handle,
video_data, font_path, font_size, is_threaded);
#endif
#ifdef HAVE_D3D10
case FONT_DRIVER_RENDER_D3D10_API:
return d3d10_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,

View File

@ -163,6 +163,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 d3d10_font;
extern font_renderer_t d3d11_font;
extern font_renderer_t d3d12_font;
extern font_renderer_t caca_font;

View File

@ -84,6 +84,7 @@ enum font_driver_render_api
FONT_DRIVER_RENDER_OPENGL_API,
FONT_DRIVER_RENDER_D3D8_API,
FONT_DRIVER_RENDER_D3D9_API,
FONT_DRIVER_RENDER_D3D10_API,
FONT_DRIVER_RENDER_D3D11_API,
FONT_DRIVER_RENDER_D3D12_API,
FONT_DRIVER_RENDER_VITA2D,

View File

@ -510,6 +510,10 @@ FONTS
#include "../gfx/drivers_font/vulkan_raster_font.c"
#endif
#if defined(HAVE_D3D10)
#include "../gfx/drivers_font/d3d10_font.c"
#endif
#if defined(HAVE_D3D11)
#include "../gfx/drivers_font/d3d11_font.c"
#endif
@ -1169,6 +1173,10 @@ MENU
#include "../menu/drivers_display/menu_display_d3d9.c"
#endif
#if defined(HAVE_D3D10)
#include "../menu/drivers_display/menu_display_d3d10.c"
#endif
#if defined(HAVE_D3D11)
#include "../menu/drivers_display/menu_display_d3d11.c"
#endif

View File

@ -0,0 +1,289 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2011-2018 - Daniel De Matteis
* 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/d3d10_common.h"
static const float* menu_display_d3d10_get_default_vertices(void)
{
return NULL;
}
static const float* menu_display_d3d10_get_default_tex_coords(void)
{
return NULL;
}
static void* menu_display_d3d10_get_default_mvp(video_frame_info_t *video_info)
{
return NULL;
}
static void menu_display_d3d10_blend_begin(video_frame_info_t *video_info)
{
d3d10_video_t* d3d10 = video_info ? (d3d10_video_t*)video_info->userdata : NULL;
D3D10SetBlendState(d3d10->device,
d3d10->blend_enable, NULL, D3D10_DEFAULT_SAMPLE_MASK);
}
static void menu_display_d3d10_blend_end(video_frame_info_t *video_info)
{
d3d10_video_t* d3d10 = video_info ? (d3d10_video_t*)video_info->userdata : NULL;
D3D10SetBlendState(d3d10->device,
d3d10->blend_disable, NULL, D3D10_DEFAULT_SAMPLE_MASK);
}
static void menu_display_d3d10_viewport(void* data, video_frame_info_t *video_info)
{
}
static void menu_display_d3d10_draw(void* data, video_frame_info_t *video_info)
{
int vertex_count;
d3d10_video_t* d3d10 = video_info ? (d3d10_video_t*)video_info->userdata : NULL;
menu_display_ctx_draw_t* draw = (menu_display_ctx_draw_t*)data;
if (!d3d10 || !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:
d3d10_set_shader(d3d10->device, &d3d10->shaders[draw->pipeline.id]);
D3D10Draw(d3d10->device, draw->coords->vertices, 0);
D3D10SetBlendState(d3d10->device, d3d10->blend_enable, NULL, D3D10_DEFAULT_SAMPLE_MASK);
d3d10_set_shader(d3d10->device, &d3d10->sprites.shader);
D3D10SetVertexBuffer(d3d10->device, 0, d3d10->sprites.vbo, sizeof(d3d10_sprite_t), 0);
D3D10SetPrimitiveTopology(d3d10->device, D3D10_PRIMITIVE_TOPOLOGY_POINTLIST);
return;
}
if (draw->coords->vertex && draw->coords->tex_coord && draw->coords->color)
vertex_count = draw->coords->vertices;
else
vertex_count = 1;
if (!d3d10->sprites.enabled || vertex_count > d3d10->sprites.capacity)
return;
if (d3d10->sprites.offset + vertex_count > d3d10->sprites.capacity)
d3d10->sprites.offset = 0;
{
D3D10_MAPPED_SUBRESOURCE mapped_vbo;
d3d10_sprite_t* sprite = NULL;
D3D10MapBuffer(d3d10->sprites.vbo, D3D10_MAP_WRITE_NO_OVERWRITE, 0, (void**)&mapped_vbo);
sprite = (d3d10_sprite_t*)mapped_vbo.pData + d3d10->sprites.offset;
if (vertex_count == 1)
{
sprite->pos.x = draw->x / (float)d3d10->viewport.Width;
sprite->pos.y =
(d3d10->viewport.Height - draw->y - draw->height) / (float)d3d10->viewport.Height;
sprite->pos.w = draw->width / (float)d3d10->viewport.Width;
sprite->pos.h = draw->height / (float)d3d10->viewport.Height;
sprite->coords.u = 0.0f;
sprite->coords.v = 0.0f;
sprite->coords.w = 1.0f;
sprite->coords.h = 1.0f;
if (draw->scale_factor)
sprite->params.scaling = draw->scale_factor;
else
sprite->params.scaling = 1.0f;
sprite->params.rotation = draw->rotation;
sprite->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]);
sprite->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]);
sprite->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]);
sprite->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]);
}
else
{
int i;
const float* vertex = draw->coords->vertex;
const float* tex_coord = draw->coords->tex_coord;
const float* color = draw->coords->color;
for (i = 0; i < vertex_count; i++)
{
d3d10_vertex_t* v = (d3d10_vertex_t*)sprite;
v->position[0] = *vertex++;
v->position[1] = *vertex++;
v->texcoord[0] = *tex_coord++;
v->texcoord[1] = *tex_coord++;
v->color[0] = *color++;
v->color[1] = *color++;
v->color[2] = *color++;
v->color[3] = *color++;
sprite++;
}
d3d10_set_shader(d3d10->device, &d3d10->shaders[VIDEO_SHADER_STOCK_BLEND]);
D3D10SetPrimitiveTopology(d3d10->device, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
}
D3D10UnmapBuffer(d3d10->sprites.vbo);
}
d3d10_set_texture_and_sampler(d3d10->device, 0, (d3d10_texture_t*)draw->texture);
D3D10Draw(d3d10->device, vertex_count, d3d10->sprites.offset);
d3d10->sprites.offset += vertex_count;
if (vertex_count > 1)
{
d3d10_set_shader(d3d10->device, &d3d10->sprites.shader);
D3D10SetPrimitiveTopology(d3d10->device, D3D10_PRIMITIVE_TOPOLOGY_POINTLIST);
}
return;
}
static void menu_display_d3d10_draw_pipeline(void* data,
video_frame_info_t *video_info)
{
menu_display_ctx_draw_t* draw = (menu_display_ctx_draw_t*)data;
d3d10_video_t* d3d10 = video_info ? (d3d10_video_t*)video_info->userdata : NULL;
if (!d3d10 || !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 (!d3d10->menu_pipeline_vbo)
{
D3D10_BUFFER_DESC desc = { 0 };
desc.Usage = D3D10_USAGE_IMMUTABLE;
desc.ByteWidth = ca->coords.vertices * 2 * sizeof(float);
desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
D3D10_SUBRESOURCE_DATA vertexData = { ca->coords.vertex };
D3D10CreateBuffer(d3d10->device, &desc, &vertexData, &d3d10->menu_pipeline_vbo);
}
D3D10SetVertexBuffer(d3d10->device, 0, d3d10->menu_pipeline_vbo, 2 * sizeof(float), 0);
draw->coords->vertices = ca->coords.vertices;
D3D10SetBlendState(d3d10->device, d3d10->blend_pipeline, NULL, D3D10_DEFAULT_SAMPLE_MASK);
break;
}
case VIDEO_SHADER_MENU_3:
case VIDEO_SHADER_MENU_4:
case VIDEO_SHADER_MENU_5:
case VIDEO_SHADER_MENU_6:
D3D10SetVertexBuffer(d3d10->device, 0, d3d10->frame.vbo, sizeof(d3d10_vertex_t), 0);
draw->coords->vertices = 4;
break;
default:
return;
}
D3D10SetPrimitiveTopology(d3d10->device, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
d3d10->ubo_values.time += 0.01f;
{
D3D10_MAPPED_SUBRESOURCE mapped_ubo;
D3D10MapBuffer(d3d10->ubo, D3D10_MAP_WRITE_DISCARD, 0, (void**)&mapped_ubo);
*(d3d10_uniform_t*)mapped_ubo.pData = d3d10->ubo_values;
D3D10UnmapBuffer(d3d10->ubo);
}
}
static void menu_display_d3d10_restore_clear_color(void) {}
static void menu_display_d3d10_clear_color(
menu_display_ctx_clearcolor_t* clearcolor,
video_frame_info_t *video_info)
{
d3d10_video_t *d3d10 = video_info ?
(d3d10_video_t*)video_info->userdata : NULL;
if (!d3d10 || !clearcolor)
return;
D3D10ClearRenderTargetView(d3d10->device,
d3d10->renderTargetView, (float*)clearcolor);
}
static bool menu_display_d3d10_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_D3D10_API);
if (!new_handle)
return false;
*handle = new_handle;
return true;
}
menu_display_ctx_driver_t menu_display_ctx_d3d10 = {
menu_display_d3d10_draw,
menu_display_d3d10_draw_pipeline,
menu_display_d3d10_viewport,
menu_display_d3d10_blend_begin,
menu_display_d3d10_blend_end,
menu_display_d3d10_restore_clear_color,
menu_display_d3d10_clear_color,
menu_display_d3d10_get_default_mvp,
menu_display_d3d10_get_default_vertices,
menu_display_d3d10_get_default_tex_coords,
menu_display_d3d10_font_init_first,
MENU_VIDEO_DRIVER_DIRECT3D10,
"menu_display_d3d10",
true
};

View File

@ -236,6 +236,10 @@ static bool menu_display_check_compatibility(
if (string_is_equal(video_driver, "d3d9"))
return true;
break;
case MENU_VIDEO_DRIVER_DIRECT3D10:
if (string_is_equal(video_driver, "d3d10"))
return true;
break;
case MENU_VIDEO_DRIVER_DIRECT3D11:
if (string_is_equal(video_driver, "d3d11"))
return true;

View File

@ -285,6 +285,7 @@ enum menu_display_driver_type
MENU_VIDEO_DRIVER_VULKAN,
MENU_VIDEO_DRIVER_DIRECT3D8,
MENU_VIDEO_DRIVER_DIRECT3D9,
MENU_VIDEO_DRIVER_DIRECT3D10,
MENU_VIDEO_DRIVER_DIRECT3D11,
MENU_VIDEO_DRIVER_DIRECT3D12,
MENU_VIDEO_DRIVER_VITA2D,