Merge pull request #6167 from aliaspider/master

(D3D10/11/12) add viewport settings.
This commit is contained in:
Twinaphex 2018-01-24 17:40:22 +01:00 committed by GitHub
commit 472abb1e8f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 624 additions and 217 deletions

View File

@ -253,6 +253,7 @@ $(BUILD_DIR)/$(TARGET): $(OBJ) .$(TARGET).last
%.depend: ; %.depend: ;
%.last: ; %.last: ;
%.h : ;
clean: clean:
rm -f $(OBJ) $(TARGET) rm -f $(OBJ) $(TARGET)

View File

@ -1073,6 +1073,9 @@ static inline HRESULT D3D10CreateTexture2DShaderResourceView(
/* internal */ /* internal */
#include <retro_math.h>
#include <gfx/math/matrix_4x4.h>
#include "gfx/video_driver.h"
#include <stdbool.h> #include <stdbool.h>
typedef struct d3d10_vertex_t typedef struct d3d10_vertex_t
@ -1099,13 +1102,22 @@ typedef struct
D3D10Device device; D3D10Device device;
D3D10RenderTargetView renderTargetView; D3D10RenderTargetView renderTargetView;
D3D10InputLayout layout; D3D10InputLayout layout;
D3D10Buffer ubo;
D3D10VertexShader vs; D3D10VertexShader vs;
D3D10PixelShader ps; D3D10PixelShader ps;
D3D10SamplerState sampler_nearest; D3D10SamplerState sampler_nearest;
D3D10SamplerState sampler_linear; D3D10SamplerState sampler_linear;
D3D10BlendState blend_enable; D3D10BlendState blend_enable;
D3D10BlendState blend_disable; D3D10BlendState blend_disable;
math_matrix_4x4 mvp, mvp_no_rot;
struct video_viewport vp;
D3D10_VIEWPORT viewport;
DXGI_FORMAT format;
float clearcolor[4]; float clearcolor[4];
bool vsync;
bool resize_chain;
bool keep_aspect;
bool resize_viewport;
struct struct
{ {
d3d10_texture_t texture; d3d10_texture_t texture;
@ -1118,12 +1130,11 @@ typedef struct
{ {
d3d10_texture_t texture; d3d10_texture_t texture;
D3D10Buffer vbo; D3D10Buffer vbo;
D3D10Buffer ubo;
D3D10SamplerState sampler; D3D10SamplerState sampler;
D3D10_VIEWPORT viewport;
int rotation;
} frame; } frame;
DXGI_FORMAT format;
bool vsync;
bool need_resize;
} d3d10_video_t; } d3d10_video_t;
void d3d10_init_texture(D3D10Device device, d3d10_texture_t* texture); void d3d10_init_texture(D3D10Device device, d3d10_texture_t* texture);

View File

@ -2449,6 +2449,11 @@ D3D11UnmapBuffer(D3D11DeviceContext device_context, D3D11Buffer buffer, UINT sub
device_context->lpVtbl->Unmap(device_context, (D3D11Resource)buffer, subresource); device_context->lpVtbl->Unmap(device_context, (D3D11Resource)buffer, subresource);
} }
/* internal */
#include <retro_math.h>
#include <gfx/math/matrix_4x4.h>
#include "gfx/video_driver.h"
#include <assert.h> #include <assert.h>
#include <stdbool.h> #include <stdbool.h>
@ -2477,13 +2482,22 @@ typedef struct
D3D11DeviceContext ctx; D3D11DeviceContext ctx;
D3D11RenderTargetView renderTargetView; D3D11RenderTargetView renderTargetView;
D3D11InputLayout layout; D3D11InputLayout layout;
D3D11Buffer ubo;
D3D11VertexShader vs; D3D11VertexShader vs;
D3D11PixelShader ps; D3D11PixelShader ps;
D3D11SamplerState sampler_nearest; D3D11SamplerState sampler_nearest;
D3D11SamplerState sampler_linear; D3D11SamplerState sampler_linear;
D3D11BlendState blend_enable; D3D11BlendState blend_enable;
D3D11BlendState blend_disable; D3D11BlendState blend_disable;
math_matrix_4x4 mvp, mvp_no_rot;
struct video_viewport vp;
D3D11_VIEWPORT viewport;
DXGI_FORMAT format;
float clearcolor[4]; float clearcolor[4];
bool vsync;
bool resize_chain;
bool keep_aspect;
bool resize_viewport;
struct struct
{ {
d3d11_texture_t texture; d3d11_texture_t texture;
@ -2496,12 +2510,11 @@ typedef struct
{ {
d3d11_texture_t texture; d3d11_texture_t texture;
D3D11Buffer vbo; D3D11Buffer vbo;
D3D11Buffer ubo;
D3D11SamplerState sampler; D3D11SamplerState sampler;
D3D11_VIEWPORT viewport;
int rotation;
} frame; } frame;
DXGI_FORMAT format;
bool vsync;
bool need_resize;
} d3d11_video_t; } d3d11_video_t;
void d3d11_init_texture(D3D11Device device, d3d11_texture_t* texture); void d3d11_init_texture(D3D11Device device, d3d11_texture_t* texture);

View File

@ -305,17 +305,26 @@ bool d3d12_init_descriptors(d3d12_video_t* d3d12)
}, },
}; };
static const D3D12_ROOT_PARAMETER rootParameters[] = { static const D3D12_ROOT_PARAMETER rootParameters[ROOT_INDEX_MAX] = {
{ [ROOT_INDEX_TEXTURE_TABLE] =
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, {
.DescriptorTable = { countof(srv_table), srv_table }, .ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL, .DescriptorTable = { countof(srv_table), srv_table },
}, .ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL,
{ },
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, [ROOT_INDEX_SAMPLER_TABLE] =
.DescriptorTable = { countof(sampler_table), sampler_table }, {
.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL, .ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
}, .DescriptorTable = { countof(sampler_table), sampler_table },
.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL,
},
[ROOT_INDEX_UBO] =
{
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV,
.Descriptor.ShaderRegister = 0,
.Descriptor.RegisterSpace = 0,
.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX,
},
}; };
static const D3D12_ROOT_SIGNATURE_DESC desc = { static const D3D12_ROOT_SIGNATURE_DESC desc = {
.NumParameters = countof(rootParameters), .NumParameters = countof(rootParameters),
@ -454,8 +463,8 @@ bool d3d12_init_pipeline(d3d12_video_t* d3d12)
return true; return true;
} }
void d3d12_create_vertex_buffer( D3D12_GPU_VIRTUAL_ADDRESS
D3D12Device device, D3D12_VERTEX_BUFFER_VIEW* view, D3D12Resource* vbo) d3d12_create_buffer(D3D12Device device, UINT size_in_bytes, D3D12Resource* buffer)
{ {
static const D3D12_HEAP_PROPERTIES heap_props = { static const D3D12_HEAP_PROPERTIES heap_props = {
.Type = D3D12_HEAP_TYPE_UPLOAD, .Type = D3D12_HEAP_TYPE_UPLOAD,
@ -465,7 +474,7 @@ void d3d12_create_vertex_buffer(
D3D12_RESOURCE_DESC resource_desc = { D3D12_RESOURCE_DESC resource_desc = {
.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER, .Dimension = D3D12_RESOURCE_DIMENSION_BUFFER,
.Width = view->SizeInBytes, .Width = size_in_bytes,
.Height = 1, .Height = 1,
.DepthOrArraySize = 1, .DepthOrArraySize = 1,
.MipLevels = 1, .MipLevels = 1,
@ -475,8 +484,9 @@ void d3d12_create_vertex_buffer(
D3D12CreateCommittedResource( D3D12CreateCommittedResource(
device, (D3D12_HEAP_PROPERTIES*)&heap_props, D3D12_HEAP_FLAG_NONE, &resource_desc, device, (D3D12_HEAP_PROPERTIES*)&heap_props, D3D12_HEAP_FLAG_NONE, &resource_desc,
D3D12_RESOURCE_STATE_GENERIC_READ, NULL, vbo); D3D12_RESOURCE_STATE_GENERIC_READ, NULL, buffer);
view->BufferLocation = D3D12GetGPUVirtualAddress(*vbo);
return D3D12GetGPUVirtualAddress(*buffer);
} }
void d3d12_init_texture( void d3d12_init_texture(
@ -565,15 +575,15 @@ void d3d12_create_fullscreen_quad_vbo(
D3D12Device device, D3D12_VERTEX_BUFFER_VIEW* view, D3D12Resource* vbo) D3D12Device device, D3D12_VERTEX_BUFFER_VIEW* view, D3D12Resource* vbo)
{ {
static const d3d12_vertex_t vertices[] = { static const d3d12_vertex_t vertices[] = {
{ { -1.0f, -1.0f }, { 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, { { 0.0f, 0.0f }, { 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { -1.0f, 1.0f }, { 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, { { 0.0f, 1.0f }, { 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, -1.0f }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, { { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, { { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
}; };
view->SizeInBytes = sizeof(vertices); view->SizeInBytes = sizeof(vertices);
view->StrideInBytes = sizeof(*vertices); view->StrideInBytes = sizeof(*vertices);
d3d12_create_vertex_buffer(device, view, vbo); view->BufferLocation = d3d12_create_buffer(device, view->SizeInBytes, vbo);
{ {
void* vertex_data_begin; void* vertex_data_begin;

View File

@ -1285,7 +1285,11 @@ D3D12GetGPUDescriptorHandleForHeapStart(D3D12DescriptorHeap descriptor_heap)
} }
#endif #endif
/* internal */ /* internal */
#include <retro_math.h>
#include <gfx/math/matrix_4x4.h>
#include "gfx/video_driver.h"
typedef struct d3d12_vertex_t typedef struct d3d12_vertex_t
{ {
@ -1316,6 +1320,7 @@ typedef struct
UINT64 total_bytes; UINT64 total_bytes;
bool dirty; bool dirty;
} d3d12_texture_t; } d3d12_texture_t;
typedef struct typedef struct
{ {
unsigned cur_mon_id; unsigned cur_mon_id;
@ -1356,10 +1361,15 @@ typedef struct
struct struct
{ {
D3D12Resource vbo; D3D12Resource ubo;
D3D12_VERTEX_BUFFER_VIEW vbo_view; D3D12_CONSTANT_BUFFER_VIEW_DESC ubo_view;
d3d12_texture_t texture; D3D12Resource vbo;
D3D12_GPU_DESCRIPTOR_HANDLE sampler; D3D12_VERTEX_BUFFER_VIEW vbo_view;
d3d12_texture_t texture;
D3D12_GPU_DESCRIPTOR_HANDLE sampler;
D3D12_VIEWPORT viewport;
D3D12_RECT scissorRect;
int rotation;
} frame; } frame;
struct struct
@ -1374,10 +1384,16 @@ typedef struct
bool fullscreen; bool fullscreen;
} menu; } menu;
DXGI_FORMAT format; D3D12Resource ubo;
D3D12_GPU_DESCRIPTOR_HANDLE sampler_linear; D3D12_CONSTANT_BUFFER_VIEW_DESC ubo_view;
D3D12_GPU_DESCRIPTOR_HANDLE sampler_nearest; DXGI_FORMAT format;
bool need_resize; D3D12_GPU_DESCRIPTOR_HANDLE sampler_linear;
D3D12_GPU_DESCRIPTOR_HANDLE sampler_nearest;
math_matrix_4x4 mvp, mvp_no_rot;
struct video_viewport vp;
bool resize_chain;
bool keep_aspect;
bool resize_viewport;
#ifdef DEBUG #ifdef DEBUG
D3D12Debug debugController; D3D12Debug debugController;
@ -1386,9 +1402,12 @@ typedef struct
enum enum
{ {
DESC_TABLE_INDEX_SRV_TEXTURE = 0, ROOT_INDEX_TEXTURE_TABLE = 0,
DESC_TABLE_INDEX_SAMPLER, ROOT_INDEX_SAMPLER_TABLE,
}; ROOT_INDEX_UBO,
ROOT_INDEX_MAX,
} root_signature_parameter_index_t;
typedef enum { typedef enum {
SAMPLER_HEAP_SLOT_LINEAR = 0, SAMPLER_HEAP_SLOT_LINEAR = 0,
SAMPLER_HEAP_SLOT_NEAREST, SAMPLER_HEAP_SLOT_NEAREST,
@ -1406,8 +1425,8 @@ bool d3d12_init_pipeline(d3d12_video_t* d3d12);
bool d3d12_init_swapchain(d3d12_video_t* d3d12, int width, int height, HWND hwnd); bool d3d12_init_swapchain(d3d12_video_t* d3d12, int width, int height, HWND hwnd);
bool d3d12_init_queue(d3d12_video_t* d3d12); bool d3d12_init_queue(d3d12_video_t* d3d12);
void d3d12_create_vertex_buffer( D3D12_GPU_VIRTUAL_ADDRESS
D3D12Device device, D3D12_VERTEX_BUFFER_VIEW* view, D3D12Resource* vbo); d3d12_create_buffer(D3D12Device device, UINT size_in_bytes, D3D12Resource* buffer);
void d3d12_init_texture( void d3d12_init_texture(
D3D12Device device, D3D12Device device,
@ -1439,13 +1458,13 @@ static inline void d3d12_resource_transition(
static inline void d3d12_set_texture(D3D12GraphicsCommandList cmd, const d3d12_texture_t* texture) static inline void d3d12_set_texture(D3D12GraphicsCommandList cmd, const d3d12_texture_t* texture)
{ {
D3D12SetGraphicsRootDescriptorTable(cmd, DESC_TABLE_INDEX_SRV_TEXTURE, texture->gpu_descriptor); D3D12SetGraphicsRootDescriptorTable(cmd, ROOT_INDEX_TEXTURE_TABLE, texture->gpu_descriptor);
} }
static inline void static inline void
d3d12_set_sampler(D3D12GraphicsCommandList cmd, D3D12_GPU_DESCRIPTOR_HANDLE sampler) d3d12_set_sampler(D3D12GraphicsCommandList cmd, D3D12_GPU_DESCRIPTOR_HANDLE sampler)
{ {
D3D12SetGraphicsRootDescriptorTable(cmd, DESC_TABLE_INDEX_SAMPLER, sampler); D3D12SetGraphicsRootDescriptorTable(cmd, ROOT_INDEX_SAMPLER_TABLE, sampler);
} }
static inline void d3d12_update_texture( static inline void d3d12_update_texture(

View File

@ -25,6 +25,48 @@
#include "gfx/common/dxgi_common.h" #include "gfx/common/dxgi_common.h"
#include "gfx/common/d3dcompiler_common.h" #include "gfx/common/d3dcompiler_common.h"
static void d3d10_set_filtering(void* data, unsigned index, bool smooth)
{
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
if (smooth)
d3d10->frame.sampler = d3d10->sampler_linear;
else
d3d10->frame.sampler = d3d10->sampler_nearest;
}
static void d3d10_gfx_set_rotation(void* data, unsigned rotation)
{
math_matrix_4x4 rot;
math_matrix_4x4* mvp;
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
d3d10->frame.rotation = 3 * rotation;
matrix_4x4_rotate_z(rot, d3d10->frame.rotation * (M_PI / 2.0f));
matrix_4x4_multiply(d3d10->mvp, rot, d3d10->mvp_no_rot);
D3D10MapBuffer(d3d10->frame.ubo, D3D10_MAP_WRITE_DISCARD, 0, (void**)&mvp);
*mvp = d3d10->mvp;
D3D10UnmapBuffer(d3d10->frame.ubo);
}
static void d3d10_update_viewport(void* data, bool force_full)
{
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
video_driver_update_viewport(&d3d10->vp, force_full, d3d10->keep_aspect);
d3d10->frame.viewport.TopLeftX = (float)d3d10->vp.x;
d3d10->frame.viewport.TopLeftY = (float)d3d10->vp.y;
d3d10->frame.viewport.Width = (float)d3d10->vp.width;
d3d10->frame.viewport.Height = (float)d3d10->vp.height;
d3d10->frame.viewport.MaxDepth = 0.0f;
d3d10->frame.viewport.MaxDepth = 1.0f;
d3d10->resize_viewport = false;
}
static void* static void*
d3d10_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data) d3d10_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data)
{ {
@ -56,8 +98,10 @@ d3d10_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
.BufferDesc.Width = video->width, .BufferDesc.Width = video->width,
.BufferDesc.Height = video->height, .BufferDesc.Height = video->height,
.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM, .BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM,
// .BufferDesc.RefreshRate.Numerator = 60, #if 0
// .BufferDesc.RefreshRate.Denominator = 1, .BufferDesc.RefreshRate.Numerator = 60,
.BufferDesc.RefreshRate.Denominator = 1,
#endif
.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT, .BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT,
.OutputWindow = main_window.hwnd, .OutputWindow = main_window.hwnd,
.SampleDesc.Count = 1, .SampleDesc.Count = 1,
@ -65,9 +109,9 @@ d3d10_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
.Windowed = TRUE, .Windowed = TRUE,
.SwapEffect = DXGI_SWAP_EFFECT_DISCARD, .SwapEffect = DXGI_SWAP_EFFECT_DISCARD,
#if 0 #if 0
.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL, .SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL,
.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, .SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL,
.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD, .SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD,
#endif #endif
}; };
@ -89,19 +133,26 @@ d3d10_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
} }
D3D10SetRenderTargets(d3d10->device, 1, &d3d10->renderTargetView, NULL); D3D10SetRenderTargets(d3d10->device, 1, &d3d10->renderTargetView, NULL);
d3d10->vp.full_width = video->width;
d3d10->vp.full_height = video->height;
d3d10->viewport.Width = video->width;
d3d10->viewport.Height = video->height;
d3d10->resize_viewport = true;
matrix_4x4_ortho(d3d10->mvp_no_rot, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
{ {
D3D10_VIEWPORT vp = { 0, 0, video->width, video->height, 0.0f, 1.0f }; D3D10_BUFFER_DESC desc = {
D3D10SetViewports(d3d10->device, 1, &vp); .ByteWidth = sizeof(math_matrix_4x4),
.Usage = D3D10_USAGE_DYNAMIC,
.BindFlags = D3D10_BIND_CONSTANT_BUFFER,
.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE,
};
D3D10_SUBRESOURCE_DATA ubo_data = { &d3d10->mvp_no_rot };
D3D10CreateBuffer(d3d10->device, &desc, &ubo_data, &d3d10->ubo);
D3D10CreateBuffer(d3d10->device, &desc, NULL, &d3d10->frame.ubo);
} }
d3d10_gfx_set_rotation(d3d10, 0);
d3d10->vsync = video->vsync;
d3d10->format = video->rgb32 ? DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM;
d3d10->frame.texture.desc.Format =
d3d10_get_closest_match_texture2D(d3d10->device, d3d10->format);
d3d10->frame.texture.desc.Usage = D3D10_USAGE_DEFAULT;
d3d10->menu.texture.desc.Usage = D3D10_USAGE_DEFAULT;
{ {
D3D10_SAMPLER_DESC desc = { D3D10_SAMPLER_DESC desc = {
@ -120,11 +171,22 @@ d3d10_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
D3D10CreateSamplerState(d3d10->device, &desc, &d3d10->sampler_linear); D3D10CreateSamplerState(d3d10->device, &desc, &d3d10->sampler_linear);
} }
d3d10_set_filtering(d3d10, 0, video->smooth);
d3d10->keep_aspect = video->force_aspect;
d3d10->vsync = video->vsync;
d3d10->format = video->rgb32 ? DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM;
d3d10->frame.texture.desc.Format =
d3d10_get_closest_match_texture2D(d3d10->device, d3d10->format);
d3d10->frame.texture.desc.Usage = D3D10_USAGE_DEFAULT;
d3d10->menu.texture.desc.Usage = D3D10_USAGE_DEFAULT;
{ {
d3d10_vertex_t vertices[] = { d3d10_vertex_t vertices[] = {
{ { -1.0f, -1.0f }, { 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, { { 0.0f, 0.0f }, { 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { -1.0f, 1.0f }, { 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, { { 0.0f, 1.0f }, { 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, -1.0f }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, { { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, { { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
}; };
@ -218,10 +280,9 @@ static bool d3d10_gfx_frame(
d3d10_video_t* d3d10 = (d3d10_video_t*)data; d3d10_video_t* d3d10 = (d3d10_video_t*)data;
if (d3d10->need_resize) if (d3d10->resize_chain)
{ {
D3D10Texture2D backBuffer; D3D10Texture2D backBuffer;
D3D10_VIEWPORT vp = { 0, 0, video_info->width, video_info->height, 0.0f, 1.0f };
Release(d3d10->renderTargetView); Release(d3d10->renderTargetView);
DXGIResizeBuffers(d3d10->swapChain, 0, 0, 0, 0, 0); DXGIResizeBuffers(d3d10->swapChain, 0, 0, 0, 0, 0);
@ -232,9 +293,11 @@ static bool d3d10_gfx_frame(
Release(backBuffer); Release(backBuffer);
D3D10SetRenderTargets(d3d10->device, 1, &d3d10->renderTargetView, NULL); D3D10SetRenderTargets(d3d10->device, 1, &d3d10->renderTargetView, NULL);
D3D10SetViewports(d3d10->device, 1, &vp); d3d10->viewport.Width = video_info->width;
d3d10->viewport.Height = video_info->height;
d3d10->need_resize = false; d3d10->resize_chain = false;
d3d10->resize_viewport = true;
} }
PERF_START(); PERF_START();
@ -260,24 +323,34 @@ static bool d3d10_gfx_frame(
{ {
UINT stride = sizeof(d3d10_vertex_t); UINT stride = sizeof(d3d10_vertex_t);
UINT offset = 0; UINT offset = 0;
#if 0 /* custom viewport doesn't call apply_state_changes, so we can't rely on this for now */
if (d3d10->resize_viewport)
#endif
d3d10_update_viewport(d3d10, false);
D3D10SetViewports(d3d10->device, 1, &d3d10->frame.viewport);
D3D10SetVertexBuffers(d3d10->device, 0, 1, &d3d10->frame.vbo, &stride, &offset); D3D10SetVertexBuffers(d3d10->device, 0, 1, &d3d10->frame.vbo, &stride, &offset);
D3D10SetVShaderConstantBuffers(d3d10->device, 0, 1, &d3d10->frame.ubo);
D3D10SetPShaderResources(d3d10->device, 0, 1, &d3d10->frame.texture.view); D3D10SetPShaderResources(d3d10->device, 0, 1, &d3d10->frame.texture.view);
D3D10SetPShaderSamplers(d3d10->device, 0, 1, &d3d10->sampler_linear); D3D10SetPShaderSamplers(d3d10->device, 0, 1, &d3d10->frame.sampler);
D3D10SetBlendState(d3d10->device, d3d10->blend_disable, NULL, D3D10_DEFAULT_SAMPLE_MASK); D3D10SetBlendState(d3d10->device, d3d10->blend_disable, NULL, D3D10_DEFAULT_SAMPLE_MASK);
D3D10Draw(d3d10->device, 4, 0); D3D10Draw(d3d10->device, 4, 0);
D3D10SetBlendState(d3d10->device, d3d10->blend_enable, NULL, D3D10_DEFAULT_SAMPLE_MASK); D3D10SetBlendState(d3d10->device, d3d10->blend_enable, NULL, D3D10_DEFAULT_SAMPLE_MASK);
if (d3d10->menu.enabled) if (d3d10->menu.enabled && d3d10->menu.texture.handle)
{ {
if (d3d10->menu.texture.dirty) if (d3d10->menu.texture.dirty)
D3D10CopyTexture2DSubresourceRegion( D3D10CopyTexture2DSubresourceRegion(
d3d10->device, d3d10->menu.texture.handle, 0, 0, 0, 0, d3d10->device, d3d10->menu.texture.handle, 0, 0, 0, 0,
d3d10->menu.texture.staging, 0, NULL); d3d10->menu.texture.staging, 0, NULL);
if (d3d10->menu.fullscreen)
D3D10SetViewports(d3d10->device, 1, &d3d10->viewport);
D3D10SetVertexBuffers(d3d10->device, 0, 1, &d3d10->menu.vbo, &stride, &offset); D3D10SetVertexBuffers(d3d10->device, 0, 1, &d3d10->menu.vbo, &stride, &offset);
D3D10SetVShaderConstantBuffers(d3d10->device, 0, 1, &d3d10->ubo);
D3D10SetPShaderResources(d3d10->device, 0, 1, &d3d10->menu.texture.view); D3D10SetPShaderResources(d3d10->device, 0, 1, &d3d10->menu.texture.view);
D3D10SetPShaderSamplers(d3d10->device, 0, 1, &d3d10->sampler_linear); D3D10SetPShaderSamplers(d3d10->device, 0, 1, &d3d10->menu.sampler);
D3D10Draw(d3d10->device, 4, 0); D3D10Draw(d3d10->device, 4, 0);
} }
@ -300,18 +373,13 @@ static void d3d10_gfx_set_nonblock_state(void* data, bool toggle)
static bool d3d10_gfx_alive(void* data) static bool d3d10_gfx_alive(void* data)
{ {
(void)data; bool quit;
bool quit;
bool resize;
unsigned width;
unsigned height;
d3d10_video_t* d3d10 = (d3d10_video_t*)data; d3d10_video_t* d3d10 = (d3d10_video_t*)data;
win32_check_window(&quit, &d3d10->need_resize, &width, &height); win32_check_window(&quit, &d3d10->resize_chain, &d3d10->vp.full_width, &d3d10->vp.full_height);
if (width != 0 && height != 0) if (d3d10->resize_chain && d3d10->vp.full_width != 0 && d3d10->vp.full_height != 0)
video_driver_set_size(&width, &height); video_driver_set_size(&d3d10->vp.full_width, &d3d10->vp.full_height);
return !quit; return !quit;
} }
@ -335,16 +403,18 @@ static void d3d10_gfx_free(void* data)
{ {
d3d10_video_t* d3d10 = (d3d10_video_t*)data; d3d10_video_t* d3d10 = (d3d10_video_t*)data;
Release(d3d10->frame.ubo);
Release(d3d10->frame.vbo);
Release(d3d10->frame.texture.view); Release(d3d10->frame.texture.view);
Release(d3d10->frame.texture.handle); Release(d3d10->frame.texture.handle);
Release(d3d10->frame.texture.staging); Release(d3d10->frame.texture.staging);
Release(d3d10->frame.vbo);
Release(d3d10->menu.texture.handle); Release(d3d10->menu.texture.handle);
Release(d3d10->menu.texture.staging); Release(d3d10->menu.texture.staging);
Release(d3d10->menu.texture.view); Release(d3d10->menu.texture.view);
Release(d3d10->menu.vbo); Release(d3d10->menu.vbo);
Release(d3d10->ubo);
Release(d3d10->blend_enable); Release(d3d10->blend_enable);
Release(d3d10->blend_disable); Release(d3d10->blend_disable);
Release(d3d10->sampler_nearest); Release(d3d10->sampler_nearest);
@ -370,16 +440,11 @@ static bool d3d10_gfx_set_shader(void* data, enum rarch_shader_type type, const
return false; return false;
} }
static void d3d10_gfx_set_rotation(void* data, unsigned rotation)
{
(void)data;
(void)rotation;
}
static void d3d10_gfx_viewport_info(void* data, struct video_viewport* vp) static void d3d10_gfx_viewport_info(void* data, struct video_viewport* vp)
{ {
(void)data; d3d10_video_t* d3d10 = (d3d10_video_t*)data;
(void)vp;
*vp = d3d10->vp;
} }
static bool d3d10_gfx_read_viewport(void* data, uint8_t* buffer, bool is_idle) static bool d3d10_gfx_read_viewport(void* data, uint8_t* buffer, bool is_idle)
@ -406,6 +471,8 @@ static void d3d10_set_menu_texture_frame(
} }
d3d10_update_texture(width, height, pitch, format, frame, &d3d10->menu.texture); d3d10_update_texture(width, height, pitch, format, frame, &d3d10->menu.texture);
d3d10->menu.sampler = config_get_ptr()->bools.menu_linear_filter ? d3d10->sampler_linear
: d3d10->sampler_nearest;
} }
static void d3d10_set_menu_texture_enable(void* data, bool state, bool full_screen) static void d3d10_set_menu_texture_enable(void* data, bool state, bool full_screen)
{ {
@ -415,28 +482,47 @@ static void d3d10_set_menu_texture_enable(void* data, bool state, bool full_scre
d3d10->menu.fullscreen = full_screen; d3d10->menu.fullscreen = full_screen;
} }
static void d3d10_gfx_set_aspect_ratio(void* data, unsigned aspect_ratio_idx)
{
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
if (!d3d10)
return;
d3d10->keep_aspect = true;
d3d10->resize_viewport = true;
}
static void d3d10_gfx_apply_state_changes(void* data)
{
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
// if (d3d10)
// d3d10->resize_viewport = true;
}
static const video_poke_interface_t d3d10_poke_interface = { static const video_poke_interface_t d3d10_poke_interface = {
NULL, /* set_coords */ NULL, /* set_coords */
NULL, /* set_mvp */ NULL, /* set_mvp */
NULL, /* load_texture */ NULL, /* load_texture */
NULL, /* unload_texture */ NULL, /* unload_texture */
NULL, /* set_video_mode */ NULL, /* set_video_mode */
NULL, /* set_filtering */ d3d10_set_filtering,
NULL, /* get_video_output_size */ NULL, /* get_video_output_size */
NULL, /* get_video_output_prev */ NULL, /* get_video_output_prev */
NULL, /* get_video_output_next */ NULL, /* get_video_output_next */
NULL, /* get_current_framebuffer */ NULL, /* get_current_framebuffer */
NULL, /* get_proc_address */ NULL, /* get_proc_address */
NULL, /* set_aspect_ratio */ d3d10_gfx_set_aspect_ratio,
NULL, /* apply_state_changes */ d3d10_gfx_apply_state_changes,
d3d10_set_menu_texture_frame, /* set_texture_frame */ d3d10_set_menu_texture_frame,
d3d10_set_menu_texture_enable, /* set_texture_enable */ d3d10_set_menu_texture_enable,
NULL, /* set_osd_msg */ NULL, /* set_osd_msg */
NULL, /* show_mouse */ NULL, /* show_mouse */
NULL, /* grab_mouse_toggle */ NULL, /* grab_mouse_toggle */
NULL, /* get_current_shader */ NULL, /* get_current_shader */
NULL, /* get_current_software_framebuffer */ NULL, /* get_current_software_framebuffer */
NULL, /* get_hw_render_interface */ NULL, /* get_hw_render_interface */
}; };
static void d3d10_gfx_get_poke_interface(void* data, const video_poke_interface_t** iface) static void d3d10_gfx_get_poke_interface(void* data, const video_poke_interface_t** iface)

View File

@ -28,6 +28,49 @@
#include "../common/d3dcompiler_common.h" #include "../common/d3dcompiler_common.h"
#include "../../performance_counters.h" #include "../../performance_counters.h"
static void d3d11_set_filtering(void* data, unsigned index, bool smooth)
{
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
if (smooth)
d3d11->frame.sampler = d3d11->sampler_linear;
else
d3d11->frame.sampler = d3d11->sampler_nearest;
}
static void d3d11_gfx_set_rotation(void* data, unsigned rotation)
{
math_matrix_4x4 rot;
math_matrix_4x4* mvp;
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
d3d11->frame.rotation = 3 * rotation;
matrix_4x4_rotate_z(rot, d3d11->frame.rotation * (M_PI / 2.0f));
matrix_4x4_multiply(d3d11->mvp, rot, d3d11->mvp_no_rot);
D3D11_MAPPED_SUBRESOURCE mapped_ubo;
D3D11MapBuffer(d3d11->ctx, d3d11->frame.ubo, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_ubo);
*(math_matrix_4x4*)mapped_ubo.pData = d3d11->mvp;
D3D11UnmapBuffer(d3d11->ctx, d3d11->frame.ubo, 0);
}
static void d3d11_update_viewport(void* data, bool force_full)
{
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
video_driver_update_viewport(&d3d11->vp, force_full, d3d11->keep_aspect);
d3d11->frame.viewport.TopLeftX = (float)d3d11->vp.x;
d3d11->frame.viewport.TopLeftY = (float)d3d11->vp.y;
d3d11->frame.viewport.Width = (float)d3d11->vp.width;
d3d11->frame.viewport.Height = (float)d3d11->vp.height;
d3d11->frame.viewport.MaxDepth = 0.0f;
d3d11->frame.viewport.MaxDepth = 1.0f;
d3d11->resize_viewport = false;
}
static void* static void*
d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data) d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data)
{ {
@ -95,11 +138,11 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
D3D11SetRenderTargets(d3d11->ctx, 1, &d3d11->renderTargetView, NULL); D3D11SetRenderTargets(d3d11->ctx, 1, &d3d11->renderTargetView, NULL);
{ d3d11->vp.full_width = video->width;
D3D11_VIEWPORT vp = { 0, 0, video->width, video->height, 0.0f, 1.0f }; d3d11->vp.full_height = video->height;
D3D11SetViewports(d3d11->ctx, 1, &vp); d3d11->viewport.Width = video->width;
} d3d11->viewport.Height = video->height;
d3d11->resize_viewport = true;
d3d11->vsync = video->vsync; d3d11->vsync = video->vsync;
d3d11->format = video->rgb32 ? DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM; d3d11->format = video->rgb32 ? DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM;
@ -110,6 +153,21 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
d3d11->menu.texture.desc.Format = DXGI_FORMAT_B4G4R4A4_UNORM; d3d11->menu.texture.desc.Format = DXGI_FORMAT_B4G4R4A4_UNORM;
d3d11->menu.texture.desc.Usage = D3D11_USAGE_DEFAULT; d3d11->menu.texture.desc.Usage = D3D11_USAGE_DEFAULT;
matrix_4x4_ortho(d3d11->mvp_no_rot, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
{
D3D11_BUFFER_DESC desc = {
.ByteWidth = sizeof(math_matrix_4x4),
.Usage = D3D11_USAGE_DYNAMIC,
.BindFlags = D3D11_BIND_CONSTANT_BUFFER,
.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE,
};
D3D11_SUBRESOURCE_DATA ubo_data = { &d3d11->mvp_no_rot };
D3D11CreateBuffer(d3d11->device, &desc, &ubo_data, &d3d11->ubo);
D3D11CreateBuffer(d3d11->device, &desc, NULL, &d3d11->frame.ubo);
}
d3d11_gfx_set_rotation(d3d11, 0);
{ {
D3D11_SAMPLER_DESC desc = { D3D11_SAMPLER_DESC desc = {
.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT, .Filter = D3D11_FILTER_MIN_MAG_MIP_POINT,
@ -127,11 +185,13 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
D3D11CreateSamplerState(d3d11->device, &desc, &d3d11->sampler_linear); D3D11CreateSamplerState(d3d11->device, &desc, &d3d11->sampler_linear);
} }
d3d11_set_filtering(d3d11, 0, video->smooth);
{ {
d3d11_vertex_t vertices[] = { d3d11_vertex_t vertices[] = {
{ { -1.0f, -1.0f }, { 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, { { 0.0f, 0.0f }, { 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { -1.0f, 1.0f }, { 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, { { 0.0f, 1.0f }, { 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, -1.0f }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, { { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
{ { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, { { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },
}; };
@ -144,11 +204,10 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE, .CPUAccessFlags = D3D11_CPU_ACCESS_WRITE,
}; };
D3D11_SUBRESOURCE_DATA vertexData = { vertices }; D3D11_SUBRESOURCE_DATA vertexData = { vertices };
D3D11CreateBuffer(d3d11->device, &desc, &vertexData, &d3d11->frame.vbo); D3D11CreateBuffer(d3d11->device, &desc, &vertexData, &d3d11->menu.vbo);
desc.Usage = D3D11_USAGE_IMMUTABLE; desc.Usage = D3D11_USAGE_IMMUTABLE;
desc.CPUAccessFlags = 0; desc.CPUAccessFlags = 0;
D3D11CreateBuffer(d3d11->device, &desc, &vertexData, &d3d11->frame.vbo);
D3D11CreateBuffer(d3d11->device, &desc, &vertexData, &d3d11->menu.vbo);
} }
D3D11SetPrimitiveTopology(d3d11->ctx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); D3D11SetPrimitiveTopology(d3d11->ctx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
} }
@ -231,10 +290,9 @@ static bool d3d11_gfx_frame(
{ {
d3d11_video_t* d3d11 = (d3d11_video_t*)data; d3d11_video_t* d3d11 = (d3d11_video_t*)data;
if (d3d11->need_resize) if (d3d11->resize_chain)
{ {
D3D11Texture2D backBuffer; D3D11Texture2D backBuffer;
D3D11_VIEWPORT vp = { 0, 0, video_info->width, video_info->height, 0.0f, 1.0f };
Release(d3d11->renderTargetView); Release(d3d11->renderTargetView);
DXGIResizeBuffers(d3d11->swapChain, 0, 0, 0, 0, 0); DXGIResizeBuffers(d3d11->swapChain, 0, 0, 0, 0, 0);
@ -245,9 +303,11 @@ static bool d3d11_gfx_frame(
Release(backBuffer); Release(backBuffer);
D3D11SetRenderTargets(d3d11->ctx, 1, &d3d11->renderTargetView, NULL); D3D11SetRenderTargets(d3d11->ctx, 1, &d3d11->renderTargetView, NULL);
D3D11SetViewports(d3d11->ctx, 1, &vp); d3d11->viewport.Width = video_info->width;
d3d11->viewport.Height = video_info->height;
d3d11->need_resize = false; d3d11->resize_chain = false;
d3d11->resize_viewport = true;
} }
PERF_START(); PERF_START();
@ -274,9 +334,17 @@ static bool d3d11_gfx_frame(
{ {
UINT stride = sizeof(d3d11_vertex_t); UINT stride = sizeof(d3d11_vertex_t);
UINT offset = 0; UINT offset = 0;
#if 0 /* custom viewport doesn't call apply_state_changes, so we can't rely on this for now */
if (d3d11->resize_viewport)
#endif
d3d11_update_viewport(d3d11, false);
D3D11SetViewports(d3d11->ctx, 1, &d3d11->frame.viewport);
D3D11SetVertexBuffers(d3d11->ctx, 0, 1, &d3d11->frame.vbo, &stride, &offset); 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); D3D11SetPShaderResources(d3d11->ctx, 0, 1, &d3d11->frame.texture.view);
D3D11SetPShaderSamplers(d3d11->ctx, 0, 1, &d3d11->sampler_linear); D3D11SetPShaderSamplers(d3d11->ctx, 0, 1, &d3d11->frame.sampler);
D3D11SetBlendState(d3d11->ctx, d3d11->blend_disable, NULL, D3D11_DEFAULT_SAMPLE_MASK); D3D11SetBlendState(d3d11->ctx, d3d11->blend_disable, NULL, D3D11_DEFAULT_SAMPLE_MASK);
D3D11Draw(d3d11->ctx, 4, 0); D3D11Draw(d3d11->ctx, 4, 0);
@ -289,9 +357,12 @@ static bool d3d11_gfx_frame(
d3d11->ctx, d3d11->menu.texture.handle, 0, 0, 0, 0, d3d11->menu.texture.staging, d3d11->ctx, d3d11->menu.texture.handle, 0, 0, 0, 0, d3d11->menu.texture.staging,
0, NULL); 0, NULL);
if (d3d11->menu.fullscreen)
D3D11SetViewports(d3d11->ctx, 1, &d3d11->viewport);
D3D11SetVertexBuffers(d3d11->ctx, 0, 1, &d3d11->menu.vbo, &stride, &offset); D3D11SetVertexBuffers(d3d11->ctx, 0, 1, &d3d11->menu.vbo, &stride, &offset);
D3D11SetVShaderConstantBuffers(d3d11->ctx, 0, 1, &d3d11->ubo);
D3D11SetPShaderResources(d3d11->ctx, 0, 1, &d3d11->menu.texture.view); D3D11SetPShaderResources(d3d11->ctx, 0, 1, &d3d11->menu.texture.view);
D3D11SetPShaderSamplers(d3d11->ctx, 0, 1, &d3d11->sampler_linear); D3D11SetPShaderSamplers(d3d11->ctx, 0, 1, &d3d11->menu.sampler);
D3D11Draw(d3d11->ctx, 4, 0); D3D11Draw(d3d11->ctx, 4, 0);
} }
@ -318,17 +389,13 @@ static void d3d11_gfx_set_nonblock_state(void* data, bool toggle)
static bool d3d11_gfx_alive(void* data) static bool d3d11_gfx_alive(void* data)
{ {
bool quit; bool quit;
bool resize;
unsigned width;
unsigned height;
d3d11_video_t* d3d11 = (d3d11_video_t*)data; d3d11_video_t* d3d11 = (d3d11_video_t*)data;
win32_check_window(&quit, &d3d11->need_resize, &width, &height); win32_check_window(&quit, &d3d11->resize_chain, &d3d11->vp.full_width, &d3d11->vp.full_height);
if (width != 0 && height != 0) if (d3d11->resize_chain && d3d11->vp.full_width != 0 && d3d11->vp.full_height != 0)
video_driver_set_size(&width, &height); video_driver_set_size(&d3d11->vp.full_width, &d3d11->vp.full_height);
return !quit; return !quit;
} }
@ -355,6 +422,7 @@ static void d3d11_gfx_free(void* data)
if (!d3d11) if (!d3d11)
return; return;
Release(d3d11->frame.ubo);
Release(d3d11->frame.texture.view); Release(d3d11->frame.texture.view);
Release(d3d11->frame.texture.handle); Release(d3d11->frame.texture.handle);
Release(d3d11->frame.texture.staging); Release(d3d11->frame.texture.staging);
@ -365,6 +433,7 @@ static void d3d11_gfx_free(void* data)
Release(d3d11->menu.texture.view); Release(d3d11->menu.texture.view);
Release(d3d11->menu.vbo); Release(d3d11->menu.vbo);
Release(d3d11->ubo);
Release(d3d11->blend_enable); Release(d3d11->blend_enable);
Release(d3d11->blend_disable); Release(d3d11->blend_disable);
Release(d3d11->sampler_nearest); Release(d3d11->sampler_nearest);
@ -391,16 +460,11 @@ static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const
return false; return false;
} }
static void d3d11_gfx_set_rotation(void* data, unsigned rotation)
{
(void)data;
(void)rotation;
}
static void d3d11_gfx_viewport_info(void* data, struct video_viewport* vp) static void d3d11_gfx_viewport_info(void* data, struct video_viewport* vp)
{ {
(void)data; d3d11_video_t* d3d11 = (d3d11_video_t*)data;
(void)vp;
*vp = d3d11->vp;
} }
static bool d3d11_gfx_read_viewport(void* data, uint8_t* buffer, bool is_idle) static bool d3d11_gfx_read_viewport(void* data, uint8_t* buffer, bool is_idle)
@ -427,6 +491,8 @@ static void d3d11_set_menu_texture_frame(
} }
d3d11_update_texture(d3d11->ctx, width, height, pitch, format, frame, &d3d11->menu.texture); d3d11_update_texture(d3d11->ctx, width, height, pitch, format, frame, &d3d11->menu.texture);
d3d11->menu.sampler = config_get_ptr()->bools.menu_linear_filter ? d3d11->sampler_linear
: d3d11->sampler_nearest;
} }
static void d3d11_set_menu_texture_enable(void* data, bool state, bool full_screen) static void d3d11_set_menu_texture_enable(void* data, bool state, bool full_screen)
{ {
@ -439,28 +505,47 @@ static void d3d11_set_menu_texture_enable(void* data, bool state, bool full_scre
d3d11->menu.fullscreen = full_screen; d3d11->menu.fullscreen = full_screen;
} }
static void d3d11_gfx_set_aspect_ratio(void* data, unsigned aspect_ratio_idx)
{
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
if (!d3d11)
return;
d3d11->keep_aspect = true;
d3d11->resize_viewport = true;
}
static void d3d11_gfx_apply_state_changes(void* data)
{
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
if (d3d11)
d3d11->resize_viewport = true;
}
static const video_poke_interface_t d3d11_poke_interface = { static const video_poke_interface_t d3d11_poke_interface = {
NULL, /* set_coords */ NULL, /* set_coords */
NULL, /* set_mvp */ NULL, /* set_mvp */
NULL, /* load_texture */ NULL, /* load_texture */
NULL, /* unload_texture */ NULL, /* unload_texture */
NULL, /* set_video_mode */ NULL, /* set_video_mode */
NULL, /* set_filtering */ d3d11_set_filtering,
NULL, /* get_video_output_size */ NULL, /* get_video_output_size */
NULL, /* get_video_output_prev */ NULL, /* get_video_output_prev */
NULL, /* get_video_output_next */ NULL, /* get_video_output_next */
NULL, /* get_current_framebuffer */ NULL, /* get_current_framebuffer */
NULL, /* get_proc_address */ NULL, /* get_proc_address */
NULL, /* set_aspect_ratio */ d3d11_gfx_set_aspect_ratio,
NULL, /* apply_state_changes */ d3d11_gfx_apply_state_changes,
d3d11_set_menu_texture_frame, /* set_texture_frame */ d3d11_set_menu_texture_frame,
d3d11_set_menu_texture_enable, /* set_texture_enable */ d3d11_set_menu_texture_enable,
NULL, /* set_osd_msg */ NULL, /* set_osd_msg */
NULL, /* show_mouse */ NULL, /* show_mouse */
NULL, /* grab_mouse_toggle */ NULL, /* grab_mouse_toggle */
NULL, /* get_current_shader */ NULL, /* get_current_shader */
NULL, /* get_current_software_framebuffer */ NULL, /* get_current_software_framebuffer */
NULL, /* get_hw_render_interface */ NULL, /* get_hw_render_interface */
}; };
static void d3d11_gfx_get_poke_interface(void* data, const video_poke_interface_t** iface) static void d3d11_gfx_get_poke_interface(void* data, const video_poke_interface_t** iface)

View File

@ -35,6 +35,45 @@ static void d3d12_set_filtering(void* data, unsigned index, bool smooth)
d3d12->frame.sampler = d3d12->sampler_nearest; d3d12->frame.sampler = d3d12->sampler_nearest;
} }
static void d3d12_gfx_set_rotation(void* data, unsigned rotation)
{
math_matrix_4x4 rot;
math_matrix_4x4* mvp;
D3D12_RANGE read_range = { 0, 0 };
d3d12_video_t* d3d12 = (d3d12_video_t*)data;
d3d12->frame.rotation = 3 * rotation;
matrix_4x4_rotate_z(rot, d3d12->frame.rotation * (M_PI / 2.0f));
matrix_4x4_multiply(d3d12->mvp, rot, d3d12->mvp_no_rot);
D3D12Map(d3d12->frame.ubo, 0, &read_range, (void**)&mvp);
*mvp = d3d12->mvp;
D3D12Unmap(d3d12->frame.ubo, 0, NULL);
}
static void d3d12_update_viewport(void* data, bool force_full)
{
d3d12_video_t* d3d12 = (d3d12_video_t*)data;
video_driver_update_viewport(&d3d12->vp, force_full, d3d12->keep_aspect);
d3d12->frame.viewport.TopLeftX = (float)d3d12->vp.x;
d3d12->frame.viewport.TopLeftY = (float)d3d12->vp.y;
d3d12->frame.viewport.Width = (float)d3d12->vp.width;
d3d12->frame.viewport.Height = (float)d3d12->vp.height;
d3d12->frame.viewport.MaxDepth = 0.0f;
d3d12->frame.viewport.MaxDepth = 1.0f;
/* having to add vp.x and vp.y here doesn't make any sense */
d3d12->frame.scissorRect.top = 0;
d3d12->frame.scissorRect.left = 0;
d3d12->frame.scissorRect.right = d3d12->vp.x + d3d12->vp.width;
d3d12->frame.scissorRect.bottom = d3d12->vp.y + d3d12->vp.height;
d3d12->resize_viewport = false;
}
static void* static void*
d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data) d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** input_data)
{ {
@ -79,9 +118,34 @@ d3d12_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
d3d12_set_filtering(d3d12, 0, video->smooth); d3d12_set_filtering(d3d12, 0, video->smooth);
d3d12->keep_aspect = video->force_aspect;
d3d12->chain.vsync = video->vsync; d3d12->chain.vsync = video->vsync;
d3d12->format = video->rgb32 ? DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM; d3d12->format = video->rgb32 ? DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM;
d3d12->frame.texture.desc.Format = d3d12_get_closest_match_texture2D(d3d12->device, d3d12->format); d3d12->frame.texture.desc.Format =
d3d12_get_closest_match_texture2D(d3d12->device, d3d12->format);
d3d12->ubo_view.SizeInBytes = sizeof(math_matrix_4x4);
d3d12->ubo_view.BufferLocation =
d3d12_create_buffer(d3d12->device, d3d12->ubo_view.SizeInBytes, &d3d12->ubo);
d3d12->frame.ubo_view.SizeInBytes = sizeof(math_matrix_4x4);
d3d12->frame.ubo_view.BufferLocation =
d3d12_create_buffer(d3d12->device, d3d12->frame.ubo_view.SizeInBytes, &d3d12->frame.ubo);
matrix_4x4_ortho(d3d12->mvp_no_rot, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
{
math_matrix_4x4* mvp;
D3D12_RANGE read_range = { 0, 0 };
D3D12Map(d3d12->ubo, 0, &read_range, (void**)&mvp);
*mvp = d3d12->mvp_no_rot;
D3D12Unmap(d3d12->ubo, 0, NULL);
}
d3d12_gfx_set_rotation(d3d12, 0);
d3d12->vp.full_width = video->width;
d3d12->vp.full_height = video->height;
d3d12->resize_viewport = true;
return d3d12; return d3d12;
@ -103,7 +167,7 @@ static bool d3d12_gfx_frame(
{ {
d3d12_video_t* d3d12 = (d3d12_video_t*)data; d3d12_video_t* d3d12 = (d3d12_video_t*)data;
if (d3d12->need_resize) if (d3d12->resize_chain)
{ {
int i; int i;
@ -119,16 +183,11 @@ static bool d3d12_gfx_frame(
d3d12->device, d3d12->chain.renderTargets[i], NULL, d3d12->chain.desc_handles[i]); d3d12->device, d3d12->chain.renderTargets[i], NULL, d3d12->chain.desc_handles[i]);
} }
d3d12->chain.viewport.Width = video_info->width;
d3d12->chain.viewport.Height = video_info->height;
d3d12->chain.scissorRect.right = video_info->width;
d3d12->chain.scissorRect.bottom = video_info->height;
d3d12->chain.frame_index = DXGIGetCurrentBackBufferIndex(d3d12->chain.handle); d3d12->chain.frame_index = DXGIGetCurrentBackBufferIndex(d3d12->chain.handle);
d3d12->resize_chain = false;
d3d12->need_resize = false; d3d12->resize_viewport = true;
} }
PERF_START(); PERF_START();
D3D12ResetCommandAllocator(d3d12->queue.allocator); D3D12ResetCommandAllocator(d3d12->queue.allocator);
@ -144,8 +203,6 @@ static bool d3d12_gfx_frame(
d3d12->queue.cmd, d3d12->chain.renderTargets[d3d12->chain.frame_index], d3d12->queue.cmd, d3d12->chain.renderTargets[d3d12->chain.frame_index],
D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
D3D12RSSetViewports(d3d12->queue.cmd, 1, &d3d12->chain.viewport);
D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &d3d12->chain.scissorRect);
D3D12OMSetRenderTargets( D3D12OMSetRenderTargets(
d3d12->queue.cmd, 1, &d3d12->chain.desc_handles[d3d12->chain.frame_index], FALSE, NULL); d3d12->queue.cmd, 1, &d3d12->chain.desc_handles[d3d12->chain.frame_index], FALSE, NULL);
D3D12ClearRenderTargetView( D3D12ClearRenderTargetView(
@ -153,11 +210,9 @@ static bool d3d12_gfx_frame(
d3d12->chain.clearcolor, 0, NULL); d3d12->chain.clearcolor, 0, NULL);
D3D12IASetPrimitiveTopology(d3d12->queue.cmd, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); D3D12IASetPrimitiveTopology(d3d12->queue.cmd, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
if (data && width && height) if (data && width && height)
{ {
if (!d3d12->frame.texture.handle || (d3d12->frame.texture.desc.Width != width) || if (d3d12->frame.texture.desc.Width != width || d3d12->frame.texture.desc.Height != height)
(d3d12->frame.texture.desc.Height != height))
{ {
d3d12->frame.texture.desc.Width = width; d3d12->frame.texture.desc.Width = width;
d3d12->frame.texture.desc.Height = height; d3d12->frame.texture.desc.Height = height;
@ -169,7 +224,16 @@ static bool d3d12_gfx_frame(
d3d12_upload_texture(d3d12->queue.cmd, &d3d12->frame.texture); d3d12_upload_texture(d3d12->queue.cmd, &d3d12->frame.texture);
} }
#if 0 /* custom viewport doesn't call apply_state_changes, so we can't rely on this for now */
if (d3d12->resize_viewport)
#endif
d3d12_update_viewport(d3d12, false);
D3D12RSSetViewports(d3d12->queue.cmd, 1, &d3d12->frame.viewport);
D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &d3d12->frame.scissorRect);
D3D12SetGraphicsRootConstantBufferView(
d3d12->queue.cmd, ROOT_INDEX_UBO, d3d12->frame.ubo_view.BufferLocation);
d3d12_set_texture(d3d12->queue.cmd, &d3d12->frame.texture); d3d12_set_texture(d3d12->queue.cmd, &d3d12->frame.texture);
d3d12_set_sampler(d3d12->queue.cmd, d3d12->frame.sampler); d3d12_set_sampler(d3d12->queue.cmd, d3d12->frame.sampler);
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->frame.vbo_view); D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->frame.vbo_view);
@ -180,6 +244,15 @@ static bool d3d12_gfx_frame(
if (d3d12->menu.texture.dirty) if (d3d12->menu.texture.dirty)
d3d12_upload_texture(d3d12->queue.cmd, &d3d12->menu.texture); d3d12_upload_texture(d3d12->queue.cmd, &d3d12->menu.texture);
D3D12SetGraphicsRootConstantBufferView(
d3d12->queue.cmd, ROOT_INDEX_UBO, d3d12->ubo_view.BufferLocation);
if (d3d12->menu.fullscreen)
{
D3D12RSSetViewports(d3d12->queue.cmd, 1, &d3d12->chain.viewport);
D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &d3d12->chain.scissorRect);
}
d3d12_set_texture(d3d12->queue.cmd, &d3d12->menu.texture); d3d12_set_texture(d3d12->queue.cmd, &d3d12->menu.texture);
d3d12_set_sampler(d3d12->queue.cmd, d3d12->menu.sampler); d3d12_set_sampler(d3d12->queue.cmd, d3d12->menu.sampler);
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->menu.vbo_view); D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->menu.vbo_view);
@ -228,18 +301,13 @@ static void d3d12_gfx_set_nonblock_state(void* data, bool toggle)
static bool d3d12_gfx_alive(void* data) static bool d3d12_gfx_alive(void* data)
{ {
(void)data; bool quit;
bool quit;
bool resize;
unsigned width;
unsigned height;
d3d12_video_t* d3d12 = (d3d12_video_t*)data; d3d12_video_t* d3d12 = (d3d12_video_t*)data;
win32_check_window(&quit, &d3d12->need_resize, &width, &height); win32_check_window(&quit, &d3d12->resize_chain, &d3d12->vp.full_width, &d3d12->vp.full_height);
if (width != 0 && height != 0) if (d3d12->resize_chain && d3d12->vp.full_width != 0 && d3d12->vp.full_height != 0)
video_driver_set_size(&width, &height); video_driver_set_size(&d3d12->vp.full_width, &d3d12->vp.full_height);
return !quit; return !quit;
} }
@ -263,6 +331,7 @@ static void d3d12_gfx_free(void* data)
{ {
d3d12_video_t* d3d12 = (d3d12_video_t*)data; d3d12_video_t* d3d12 = (d3d12_video_t*)data;
Release(d3d12->frame.ubo);
Release(d3d12->frame.vbo); Release(d3d12->frame.vbo);
Release(d3d12->frame.texture.handle); Release(d3d12->frame.texture.handle);
Release(d3d12->frame.texture.upload_buffer); Release(d3d12->frame.texture.upload_buffer);
@ -270,6 +339,7 @@ static void d3d12_gfx_free(void* data)
Release(d3d12->menu.texture.handle); Release(d3d12->menu.texture.handle);
Release(d3d12->menu.texture.upload_buffer); Release(d3d12->menu.texture.upload_buffer);
Release(d3d12->ubo);
Release(d3d12->pipe.sampler_heap.handle); Release(d3d12->pipe.sampler_heap.handle);
Release(d3d12->pipe.srv_heap.handle); Release(d3d12->pipe.srv_heap.handle);
Release(d3d12->pipe.rtv_heap.handle); Release(d3d12->pipe.rtv_heap.handle);
@ -304,16 +374,11 @@ static bool d3d12_gfx_set_shader(void* data, enum rarch_shader_type type, const
return false; return false;
} }
static void d3d12_gfx_set_rotation(void* data, unsigned rotation)
{
(void)data;
(void)rotation;
}
static void d3d12_gfx_viewport_info(void* data, struct video_viewport* vp) static void d3d12_gfx_viewport_info(void* data, struct video_viewport* vp)
{ {
(void)data; d3d12_video_t* d3d12 = (d3d12_video_t*)data;
(void)vp;
*vp = d3d12->vp;
} }
static bool d3d12_gfx_read_viewport(void* data, uint8_t* buffer, bool is_idle) static bool d3d12_gfx_read_viewport(void* data, uint8_t* buffer, bool is_idle)
@ -366,28 +431,47 @@ static void d3d12_set_menu_texture_enable(void* data, bool state, bool full_scre
d3d12->menu.fullscreen = full_screen; d3d12->menu.fullscreen = full_screen;
} }
static void d3d12_gfx_set_aspect_ratio(void* data, unsigned aspect_ratio_idx)
{
d3d12_video_t* d3d12 = (d3d12_video_t*)data;
if (!d3d12)
return;
d3d12->keep_aspect = true;
d3d12->resize_viewport = true;
}
static void d3d12_gfx_apply_state_changes(void* data)
{
d3d12_video_t* d3d12 = (d3d12_video_t*)data;
if (d3d12)
d3d12->resize_viewport = true;
}
static const video_poke_interface_t d3d12_poke_interface = { static const video_poke_interface_t d3d12_poke_interface = {
NULL, /* set_coords */ NULL, /* set_coords */
NULL, /* set_mvp */ NULL, /* set_mvp */
NULL, /* load_texture */ NULL, /* load_texture */
NULL, /* unload_texture */ NULL, /* unload_texture */
NULL, /* set_video_mode */ NULL, /* set_video_mode */
NULL, /* set_filtering */ d3d12_set_filtering,
NULL, /* get_video_output_size */ NULL, /* get_video_output_size */
NULL, /* get_video_output_prev */ NULL, /* get_video_output_prev */
NULL, /* get_video_output_next */ NULL, /* get_video_output_next */
NULL, /* get_current_framebuffer */ NULL, /* get_current_framebuffer */
NULL, /* get_proc_address */ NULL, /* get_proc_address */
NULL, /* set_aspect_ratio */ d3d12_gfx_set_aspect_ratio,
NULL, /* apply_state_changes */ d3d12_gfx_apply_state_changes,
d3d12_set_menu_texture_frame, /* set_texture_frame */ d3d12_set_menu_texture_frame,
d3d12_set_menu_texture_enable, /* set_texture_enable */ d3d12_set_menu_texture_enable,
NULL, /* set_osd_msg */ NULL, /* set_osd_msg */
NULL, /* show_mouse */ NULL, /* show_mouse */
NULL, /* grab_mouse_toggle */ NULL, /* grab_mouse_toggle */
NULL, /* get_current_shader */ NULL, /* get_current_shader */
NULL, /* get_current_software_framebuffer */ NULL, /* get_current_software_framebuffer */
NULL, /* get_hw_render_interface */ NULL, /* get_hw_render_interface */
}; };
static void d3d12_gfx_get_poke_interface(void* data, const video_poke_interface_t** iface) static void d3d12_gfx_get_poke_interface(void* data, const video_poke_interface_t** iface)

View File

@ -7,10 +7,11 @@ SRC(
float2 texcoord : TEXCOORD0; float2 texcoord : TEXCOORD0;
float4 color : COLOR; float4 color : COLOR;
}; };
uniform float4x4 modelViewProj;
PSInput VSMain(float4 position : POSITION, float2 texcoord : TEXCOORD0, float4 color : COLOR) PSInput VSMain(float4 position : POSITION, float2 texcoord : TEXCOORD0, float4 color : COLOR)
{ {
PSInput result; PSInput result;
result.position = position; result.position = mul(modelViewProj, position);
result.texcoord = texcoord; result.texcoord = texcoord;
result.color = color; result.color = color;
return result; return result;

View File

@ -1764,12 +1764,108 @@ void video_driver_monitor_reset(void)
void video_driver_set_aspect_ratio(void) void video_driver_set_aspect_ratio(void)
{ {
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
switch (settings->uints.video_aspect_ratio_idx)
{
case ASPECT_RATIO_SQUARE:
video_driver_set_viewport_square_pixel();
break;
case ASPECT_RATIO_CORE:
video_driver_set_viewport_core();
break;
case ASPECT_RATIO_CONFIG:
video_driver_set_viewport_config();
break;
default:
break;
}
video_driver_set_aspect_ratio_value(
aspectratio_lut[settings->uints.video_aspect_ratio_idx].value);
if (!video_driver_poke || !video_driver_poke->set_aspect_ratio) if (!video_driver_poke || !video_driver_poke->set_aspect_ratio)
return; return;
video_driver_poke->set_aspect_ratio( video_driver_poke->set_aspect_ratio(
video_driver_data, settings->uints.video_aspect_ratio_idx); video_driver_data, settings->uints.video_aspect_ratio_idx);
} }
void video_driver_update_viewport(struct video_viewport* vp, bool force_full, bool keep_aspect)
{
gfx_ctx_aspect_t aspect_data;
float device_aspect = (float)vp->full_width / vp->full_height;
settings_t* settings = config_get_ptr();
aspect_data.aspect = &device_aspect;
aspect_data.width = vp->full_width;
aspect_data.height = vp->full_height;
video_context_driver_translate_aspect(&aspect_data);
vp->x = 0;
vp->y = 0;
vp->width = vp->full_width;
vp->height = vp->full_height;
if (settings->bools.video_scale_integer && !force_full)
{
video_viewport_get_scaled_integer(
vp, vp->full_width, vp->full_height, video_driver_get_aspect_ratio(), keep_aspect);
}
else if (keep_aspect && !force_full)
{
float desired_aspect = video_driver_get_aspect_ratio();
#if defined(HAVE_MENU)
if (settings->uints.video_aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
{
const struct video_viewport* custom = video_viewport_get_custom();
vp->x = custom->x;
vp->y = custom->y;
vp->width = custom->width;
vp->height = custom->height;
}
else
#endif
{
float delta;
if (fabsf(device_aspect - desired_aspect) < 0.0001f)
{
/* If the aspect ratios of screen and desired aspect
* ratio are sufficiently equal (floating point stuff),
* assume they are actually equal.
*/
}
else if (device_aspect > desired_aspect)
{
delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f;
vp->x = (int)roundf(vp->full_width * (0.5f - delta));
vp->width = (unsigned)roundf(2.0f * vp->full_width * delta);
vp->y = 0;
vp->height = vp->full_height;
}
else
{
vp->x = 0;
vp->width = vp->full_width;
delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f;
vp->y = (int)roundf(vp->full_height * (0.5f - delta));
vp->height = (unsigned)roundf(2.0f * vp->full_height * delta);
}
}
}
#if defined(RARCH_MOBILE)
/* In portrait mode, we want viewport to gravitate to top of screen. */
if (device_aspect < 1.0f)
d3d12->vp.y = 0;
#endif
}
void video_driver_show_mouse(void) void video_driver_show_mouse(void)
{ {
if (video_driver_poke && video_driver_poke->show_mouse) if (video_driver_poke && video_driver_poke->show_mouse)

View File

@ -934,6 +934,7 @@ void video_driver_free(void);
void video_driver_free_hw_context(void); void video_driver_free_hw_context(void);
void video_driver_monitor_reset(void); void video_driver_monitor_reset(void);
void video_driver_set_aspect_ratio(void); void video_driver_set_aspect_ratio(void);
void video_driver_update_viewport(struct video_viewport* vp, bool force_full, bool keep_aspect);
void video_driver_show_mouse(void); void video_driver_show_mouse(void);
void video_driver_hide_mouse(void); void video_driver_hide_mouse(void);
void video_driver_set_nonblock_state(bool toggle); void video_driver_set_nonblock_state(bool toggle);