(D3D11/12) Cleanups (#15025)

This commit is contained in:
sonninnos 2023-02-26 14:27:05 +02:00 committed by GitHub
parent e34168e44c
commit 6622cbb69d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 233 additions and 178 deletions

View File

@ -465,7 +465,8 @@ static void d3d11_gfx_set_rotation(void* data, unsigned rotation)
static void d3d11_update_viewport(d3d11_video_t *d3d11, bool force_full) static void d3d11_update_viewport(d3d11_video_t *d3d11, bool force_full)
{ {
video_driver_update_viewport(&d3d11->vp, force_full, d3d11->flags & D3D11_ST_FLAG_KEEP_ASPECT); video_driver_update_viewport(&d3d11->vp, force_full,
d3d11->flags & D3D11_ST_FLAG_KEEP_ASPECT);
d3d11->frame.viewport.TopLeftX = d3d11->vp.x; d3d11->frame.viewport.TopLeftX = d3d11->vp.x;
d3d11->frame.viewport.TopLeftY = d3d11->vp.y; d3d11->frame.viewport.TopLeftY = d3d11->vp.y;
@ -474,8 +475,9 @@ static void d3d11_update_viewport(d3d11_video_t *d3d11, bool force_full)
d3d11->frame.viewport.MaxDepth = 0.0f; d3d11->frame.viewport.MaxDepth = 0.0f;
d3d11->frame.viewport.MaxDepth = 1.0f; d3d11->frame.viewport.MaxDepth = 1.0f;
if (d3d11->shader_preset && (d3d11->frame.output_size.x != d3d11->vp.width || if (d3d11->shader_preset
d3d11->frame.output_size.y != d3d11->vp.height)) && ( d3d11->frame.output_size.x != d3d11->vp.width
|| d3d11->frame.output_size.y != d3d11->vp.height))
d3d11->flags |= D3D11_ST_FLAG_RESIZE_RTS; d3d11->flags |= D3D11_ST_FLAG_RESIZE_RTS;
d3d11->frame.output_size.x = d3d11->vp.width; d3d11->frame.output_size.x = d3d11->vp.width;
@ -489,6 +491,7 @@ static void d3d11_update_viewport(d3d11_video_t *d3d11, bool force_full)
static void d3d11_free_shader_preset(d3d11_video_t* d3d11) static void d3d11_free_shader_preset(d3d11_video_t* d3d11)
{ {
int i; int i;
if (!d3d11->shader_preset) if (!d3d11->shader_preset)
return; return;
@ -531,8 +534,9 @@ static void d3d11_free_shader_preset(d3d11_video_t* d3d11)
free(d3d11->shader_preset); free(d3d11->shader_preset);
d3d11->shader_preset = NULL; d3d11->shader_preset = NULL;
d3d11->flags &= ~( D3D11_ST_FLAG_INIT_HISTORY d3d11->flags &= ~(D3D11_ST_FLAG_INIT_HISTORY
| D3D11_ST_FLAG_RESIZE_RTS); | D3D11_ST_FLAG_RESIZE_RTS
);
} }
static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const char* path) static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const char* path)
@ -692,6 +696,7 @@ static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const
} }
} }
#ifdef HAVE_DXGI_HDR
if (d3d11->flags & D3D11_ST_FLAG_HDR_ENABLE) if (d3d11->flags & D3D11_ST_FLAG_HDR_ENABLE)
{ {
if (d3d11->shader_preset && d3d11->shader_preset->passes && (d3d11->pass[d3d11->shader_preset->passes - 1].semantics.format == SLANG_FORMAT_A2B10G10R10_UNORM_PACK32)) if (d3d11->shader_preset && d3d11->shader_preset->passes && (d3d11->pass[d3d11->shader_preset->passes - 1].semantics.format == SLANG_FORMAT_A2B10G10R10_UNORM_PACK32))
@ -699,14 +704,14 @@ static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const
/* If the last shader pass uses a RGB10A2 back buffer and hdr has been enabled assume we want to skip the inverse tonemapper and hdr10 conversion */ /* If the last shader pass uses a RGB10A2 back buffer and hdr has been enabled assume we want to skip the inverse tonemapper and hdr10 conversion */
d3d11_set_hdr_inverse_tonemap(d3d11, false); d3d11_set_hdr_inverse_tonemap(d3d11, false);
d3d11_set_hdr10(d3d11, false); d3d11_set_hdr10(d3d11, false);
d3d11->flags |= D3D11_ST_FLAG_RESIZE_CHAIN; d3d11->flags |= D3D11_ST_FLAG_RESIZE_CHAIN;
} }
else if (d3d11->shader_preset && d3d11->shader_preset->passes && (d3d11->pass[d3d11->shader_preset->passes - 1].semantics.format == SLANG_FORMAT_R16G16B16A16_SFLOAT)) else if (d3d11->shader_preset && d3d11->shader_preset->passes && (d3d11->pass[d3d11->shader_preset->passes - 1].semantics.format == SLANG_FORMAT_R16G16B16A16_SFLOAT))
{ {
/* If the last shader pass uses a RGBA16 back buffer and hdr has been enabled assume we want to skip the inverse tonemapper */ /* If the last shader pass uses a RGBA16 back buffer and hdr has been enabled assume we want to skip the inverse tonemapper */
d3d11_set_hdr_inverse_tonemap(d3d11, false); d3d11_set_hdr_inverse_tonemap(d3d11, false);
d3d11_set_hdr10(d3d11, true); d3d11_set_hdr10(d3d11, true);
d3d11->flags |= D3D11_ST_FLAG_RESIZE_CHAIN; d3d11->flags |= D3D11_ST_FLAG_RESIZE_CHAIN;
} }
else else
{ {
@ -714,6 +719,7 @@ static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const
d3d11_set_hdr10(d3d11, true); d3d11_set_hdr10(d3d11, true);
} }
} }
#endif /* HAVE_DXGI_HDR */
for (i = 0; i < d3d11->shader_preset->luts; i++) for (i = 0; i < d3d11->shader_preset->luts; i++)
{ {
@ -741,7 +747,7 @@ static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const
image_texture_free(&image); image_texture_free(&image);
} }
d3d11->flags|= D3D11_ST_FLAG_RESIZE_RTS | D3D11_ST_FLAG_INIT_HISTORY; d3d11->flags |= D3D11_ST_FLAG_INIT_HISTORY | D3D11_ST_FLAG_RESIZE_RTS;
return true; return true;
@ -760,6 +766,11 @@ static void d3d11_gfx_free(void* data)
if (!d3d11) if (!d3d11)
return; return;
if (d3d11->flags & D3D11_ST_FLAG_WAITABLE_SWAPCHAINS)
CloseHandle(d3d11->frameLatencyWaitableObject);
font_driver_free_osd();
#ifdef HAVE_OVERLAY #ifdef HAVE_OVERLAY
d3d11_free_overlays(d3d11); d3d11_free_overlays(d3d11);
#endif #endif
@ -806,8 +817,6 @@ static void d3d11_gfx_free(void* data)
Release(d3d11->scissor_disabled); Release(d3d11->scissor_disabled);
Release(d3d11->swapChain); Release(d3d11->swapChain);
font_driver_free_osd();
video_st_flags = video_driver_get_st_flags(); video_st_flags = video_driver_get_st_flags();
if (video_st_flags & VIDEO_FLAG_CACHE_CONTEXT) if (video_st_flags & VIDEO_FLAG_CACHE_CONTEXT)
{ {
@ -849,7 +858,7 @@ static bool d3d11_init_swapchain(d3d11_video_t* d3d11,
D3D11DeviceContext *cached_context, D3D11DeviceContext *cached_context,
void *corewindow) void *corewindow)
{ {
HWND hwnd; HWND hwnd = (HWND)corewindow;
#ifdef __WINRT__ #ifdef __WINRT__
IDXGIFactory2* dxgiFactory = NULL; IDXGIFactory2* dxgiFactory = NULL;
#else #else
@ -882,8 +891,6 @@ static bool d3d11_init_swapchain(d3d11_video_t* d3d11,
d3d11->chain_formats[DXGI_SWAPCHAIN_BIT_DEPTH_16] = DXGI_FORMAT_R16G16B16A16_UNORM; d3d11->chain_formats[DXGI_SWAPCHAIN_BIT_DEPTH_16] = DXGI_FORMAT_R16G16B16A16_UNORM;
#endif #endif
hwnd = (HWND)corewindow;
#ifdef HAVE_DXGI_HDR #ifdef HAVE_DXGI_HDR
if (dxgi_check_display_hdr_support(d3d11->factory, hwnd)) if (dxgi_check_display_hdr_support(d3d11->factory, hwnd))
d3d11->flags |= D3D11_ST_FLAG_HDR_SUPPORT; d3d11->flags |= D3D11_ST_FLAG_HDR_SUPPORT;
@ -929,7 +936,7 @@ static bool d3d11_init_swapchain(d3d11_video_t* d3d11,
#endif #endif
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
#ifdef HAVE_WINDOW #ifdef HAVE_WINDOW
desc.OutputWindow = (HWND)corewindow; desc.OutputWindow = hwnd;
#endif #endif
desc.SampleDesc.Count = 1; desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0; desc.SampleDesc.Quality = 0;
@ -941,7 +948,6 @@ static bool d3d11_init_swapchain(d3d11_video_t* d3d11,
flags |= D3D11_CREATE_DEVICE_DEBUG; flags |= D3D11_CREATE_DEVICE_DEBUG;
#endif #endif
if (*cached_device && *cached_context) if (*cached_device && *cached_context)
{ {
d3d11->device = *cached_device; d3d11->device = *cached_device;
@ -1062,8 +1068,9 @@ static bool d3d11_init_swapchain(d3d11_video_t* d3d11,
/* Failed to create swapchain, try non-flip model */ /* Failed to create swapchain, try non-flip model */
desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
desc.Flags &= ~DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING; desc.Flags &= ~DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
d3d11->flags &= ~( D3D11_ST_FLAG_HAS_FLIP_MODEL d3d11->flags &= ~(D3D11_ST_FLAG_HAS_FLIP_MODEL
| D3D11_ST_FLAG_HAS_ALLOW_TEARING); | D3D11_ST_FLAG_HAS_ALLOW_TEARING
);
if (FAILED(dxgiFactory->lpVtbl->CreateSwapChain( if (FAILED(dxgiFactory->lpVtbl->CreateSwapChain(
dxgiFactory, (IUnknown*)d3d11->device, dxgiFactory, (IUnknown*)d3d11->device,
@ -1104,7 +1111,6 @@ static bool d3d11_init_swapchain(d3d11_video_t* d3d11,
RARCH_LOG("[D3D11]: Requesting %u maximum frame latency, using %u.\n", max_latency, cur_latency); RARCH_LOG("[D3D11]: Requesting %u maximum frame latency, using %u.\n", max_latency, cur_latency);
} }
#ifdef HAVE_DXGI_HDR #ifdef HAVE_DXGI_HDR
/* Check display HDR support and /* Check display HDR support and
initialize ST.2084 support to match initialize ST.2084 support to match
@ -1244,13 +1250,21 @@ static void *d3d11_gfx_init(const video_info_t* video,
d3d11->viewport.Height = d3d11->vp.full_height; d3d11->viewport.Height = d3d11->vp.full_height;
d3d11->scissor.right = d3d11->vp.full_width; d3d11->scissor.right = d3d11->vp.full_width;
d3d11->scissor.bottom = d3d11->vp.full_height; d3d11->scissor.bottom = d3d11->vp.full_height;
d3d11->flags |= D3D11_ST_FLAG_RESIZE_VIEWPORT;
d3d11->flags |= D3D11_ST_FLAG_RESIZE_VIEWPORT;
if (video->force_aspect) if (video->force_aspect)
d3d11->flags |= D3D11_ST_FLAG_KEEP_ASPECT; d3d11->flags |= D3D11_ST_FLAG_KEEP_ASPECT;
else
d3d11->flags &= ~D3D11_ST_FLAG_KEEP_ASPECT;
if (video->vsync) if (video->vsync)
d3d11->flags |= D3D11_ST_FLAG_VSYNC; d3d11->flags |= D3D11_ST_FLAG_VSYNC;
d3d11->format = video->rgb32 ? else
DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM; d3d11->flags &= ~D3D11_ST_FLAG_VSYNC;
d3d11->format = (video->rgb32)
? DXGI_FORMAT_B8G8R8X8_UNORM : DXGI_FORMAT_B5G6R5_UNORM;
d3d11->frame.texture[0].desc.Format = d3d11->format; d3d11->frame.texture[0].desc.Format = d3d11->format;
d3d11->frame.texture[0].desc.Usage = D3D11_USAGE_DEFAULT; d3d11->frame.texture[0].desc.Usage = D3D11_USAGE_DEFAULT;
@ -1807,8 +1821,9 @@ static void d3d11_init_render_targets(d3d11_video_t* d3d11, unsigned width, unsi
RARCH_LOG("[D3D11]: Updating framebuffer size %ux%u.\n", width, height); RARCH_LOG("[D3D11]: Updating framebuffer size %ux%u.\n", width, height);
if ((i != (d3d11->shader_preset->passes - 1)) || (width != d3d11->vp.width) || if ( (i != (d3d11->shader_preset->passes - 1))
(height != d3d11->vp.height)) || (width != d3d11->vp.width)
|| (height != d3d11->vp.height))
{ {
d3d11->pass[i].viewport.Width = width; d3d11->pass[i].viewport.Width = width;
d3d11->pass[i].viewport.Height = height; d3d11->pass[i].viewport.Height = height;
@ -1853,15 +1868,15 @@ static bool d3d11_gfx_frame(
const char* msg, const char* msg,
video_frame_info_t* video_info) video_frame_info_t* video_info)
{ {
unsigned i; unsigned i;
d3d11_texture_t* texture = NULL; d3d11_texture_t* texture = NULL;
D3D11RenderTargetView rtv = NULL; D3D11RenderTargetView rtv = NULL;
d3d11_video_t* d3d11 = (d3d11_video_t*)data; d3d11_video_t* d3d11 = (d3d11_video_t*)data;
D3D11DeviceContext context = d3d11->context; D3D11DeviceContext context = d3d11->context;
bool vsync = d3d11->flags & D3D11_ST_FLAG_VSYNC; bool vsync = d3d11->flags & D3D11_ST_FLAG_VSYNC;
bool wait_for_vblank = d3d11->flags & D3D11_ST_FLAG_WAIT_FOR_VBLANK; bool wait_for_vblank = d3d11->flags & D3D11_ST_FLAG_WAIT_FOR_VBLANK;
unsigned present_flags = (vsync || !(d3d11->flags & unsigned present_flags = (vsync || !(d3d11->flags & D3D11_ST_FLAG_HAS_ALLOW_TEARING))
D3D11_ST_FLAG_HAS_ALLOW_TEARING)) ? 0 : DXGI_PRESENT_ALLOW_TEARING; ? 0 : DXGI_PRESENT_ALLOW_TEARING;
const char *stat_text = video_info->stat_text; const char *stat_text = video_info->stat_text;
unsigned video_width = video_info->width; unsigned video_width = video_info->width;
unsigned video_height = video_info->height; unsigned video_height = video_info->height;
@ -1873,21 +1888,31 @@ D3D11_ST_FLAG_HAS_ALLOW_TEARING)) ? 0 : DXGI_PRESENT_ALLOW_TEARING;
bool widgets_active = video_info->widgets_active; bool widgets_active = video_info->widgets_active;
#endif #endif
#ifdef HAVE_DXGI_HDR #ifdef HAVE_DXGI_HDR
bool d3d11_hdr_enable = d3d11->flags & D3D11_ST_FLAG_HDR_ENABLE;
bool video_hdr_enable = video_info->hdr_enable; bool video_hdr_enable = video_info->hdr_enable;
DXGI_FORMAT back_buffer_format = d3d11->shader_preset && d3d11->shader_preset->passes ? glslang_format_to_dxgi(d3d11->pass[d3d11->shader_preset->passes - 1].semantics.format) : DXGI_FORMAT_R8G8B8A8_UNORM; DXGI_FORMAT back_buffer_format = d3d11->shader_preset && d3d11->shader_preset->passes ? glslang_format_to_dxgi(d3d11->pass[d3d11->shader_preset->passes - 1].semantics.format) : DXGI_FORMAT_R8G8B8A8_UNORM;
bool use_back_buffer = back_buffer_format != d3d11->chain_formats[d3d11->chain_bit_depth]; bool use_back_buffer = back_buffer_format != d3d11->chain_formats[d3d11->chain_bit_depth];
bool hdr_enable = d3d11->flags & D3D11_ST_FLAG_HDR_ENABLE; #endif
if (d3d11->flags & D3D11_ST_FLAG_WAITABLE_SWAPCHAINS)
WaitForSingleObjectEx(
d3d11->frameLatencyWaitableObject,
1000,
true);
#ifdef HAVE_DXGI_HDR
if ( (d3d11->flags & D3D11_ST_FLAG_RESIZE_CHAIN) if ( (d3d11->flags & D3D11_ST_FLAG_RESIZE_CHAIN)
|| (hdr_enable != video_hdr_enable)) || (d3d11_hdr_enable != video_hdr_enable))
#else #else
if (d3d11->resize_chain) if (d3d11->flags & D3D11_ST_FLAG_RESIZE_CHAIN)
#endif #endif
{ {
UINT swapchain_flags = (d3d11->flags & UINT swapchain_flags = (d3d11->flags & D3D11_ST_FLAG_HAS_ALLOW_TEARING)
D3D11_ST_FLAG_HAS_ALLOW_TEARING) ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0;
? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0;
if (d3d11->flags & D3D11_ST_FLAG_WAITABLE_SWAPCHAINS) if (d3d11->flags & D3D11_ST_FLAG_WAITABLE_SWAPCHAINS)
swapchain_flags |= DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; swapchain_flags |= DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
#ifdef HAVE_DXGI_HDR #ifdef HAVE_DXGI_HDR
if (video_hdr_enable) if (video_hdr_enable)
d3d11->flags |= D3D11_ST_FLAG_HDR_ENABLE; d3d11->flags |= D3D11_ST_FLAG_HDR_ENABLE;
@ -1896,6 +1921,7 @@ D3D11_ST_FLAG_HAS_ALLOW_TEARING)) ? 0 : DXGI_PRESENT_ALLOW_TEARING;
if (d3d11->flags & D3D11_ST_FLAG_HDR_ENABLE) if (d3d11->flags & D3D11_ST_FLAG_HDR_ENABLE)
d3d11_release_texture(&d3d11->back_buffer); d3d11_release_texture(&d3d11->back_buffer);
DXGIResizeBuffers(d3d11->swapChain, 0, 0, 0, DXGIResizeBuffers(d3d11->swapChain, 0, 0, 0,
d3d11->chain_formats[d3d11->chain_bit_depth], d3d11->chain_formats[d3d11->chain_bit_depth],
swapchain_flags); swapchain_flags);
@ -1905,16 +1931,17 @@ D3D11_ST_FLAG_HAS_ALLOW_TEARING)) ? 0 : DXGI_PRESENT_ALLOW_TEARING;
swapchain_flags); swapchain_flags);
#endif #endif
d3d11->viewport.Width = video_width; d3d11->viewport.Width = video_width;
d3d11->viewport.Height = video_height; d3d11->viewport.Height = video_height;
d3d11->scissor.right = video_width; d3d11->scissor.right = video_width;
d3d11->scissor.bottom = video_height; d3d11->scissor.bottom = video_height;
d3d11->ubo_values.OutputSize.width = d3d11->viewport.Width; d3d11->ubo_values.OutputSize.width = d3d11->viewport.Width;
d3d11->ubo_values.OutputSize.height = d3d11->viewport.Height; d3d11->ubo_values.OutputSize.height = d3d11->viewport.Height;
d3d11->flags &= ~D3D11_ST_FLAG_RESIZE_CHAIN; d3d11->flags &= ~D3D11_ST_FLAG_RESIZE_CHAIN;
d3d11->flags |= D3D11_ST_FLAG_RESIZE_VIEWPORT; d3d11->flags |= D3D11_ST_FLAG_RESIZE_VIEWPORT;
video_driver_set_size(video_width, video_height); video_driver_set_size(video_width, video_height);
#ifdef HAVE_DXGI_HDR #ifdef HAVE_DXGI_HDR
@ -1970,11 +1997,6 @@ D3D11_ST_FLAG_HAS_ALLOW_TEARING)) ? 0 : DXGI_PRESENT_ALLOW_TEARING;
d3d11->hdr.max_fall); d3d11->hdr.max_fall);
#endif #endif
} }
else if (d3d11->flags & D3D11_ST_FLAG_WAITABLE_SWAPCHAINS)
WaitForSingleObjectEx(
d3d11->frameLatencyWaitableObject,
1000,
true);
{ {
D3D11Texture2D back_buffer; D3D11Texture2D back_buffer;
@ -1985,8 +2007,8 @@ D3D11_ST_FLAG_HAS_ALLOW_TEARING)) ? 0 : DXGI_PRESENT_ALLOW_TEARING;
Release(back_buffer); Release(back_buffer);
} }
/* custom viewport doesn't call apply_state_changes, so we can't rely on this for now */
#if 0 #if 0
/* Custom viewport doesn't call apply_state_changes, so we can't rely on this for now */
if (d3d11->resize_viewport) if (d3d11->resize_viewport)
#endif #endif
d3d11_update_viewport(d3d11, false); d3d11_update_viewport(d3d11, false);
@ -2018,8 +2040,8 @@ D3D11_ST_FLAG_HAS_ALLOW_TEARING)) ? 0 : DXGI_PRESENT_ALLOW_TEARING;
if (d3d11->shader_preset) if (d3d11->shader_preset)
{ {
if (d3d11->frame.texture[0].desc.Width != width || if ( (d3d11->frame.texture[0].desc.Width != width)
d3d11->frame.texture[0].desc.Height != height) || (d3d11->frame.texture[0].desc.Height != height))
d3d11->flags |= D3D11_ST_FLAG_RESIZE_RTS; d3d11->flags |= D3D11_ST_FLAG_RESIZE_RTS;
if (d3d11->flags & D3D11_ST_FLAG_RESIZE_RTS) if (d3d11->flags & D3D11_ST_FLAG_RESIZE_RTS)
@ -2049,7 +2071,7 @@ D3D11_ST_FLAG_HAS_ALLOW_TEARING)) ? 0 : DXGI_PRESENT_ALLOW_TEARING;
} }
} }
/* either no history, or we moved a texture of a different size in the front slot */ /* Either no history, or we moved a texture of a different size in the front slot */
if ( d3d11->frame.texture[0].desc.Width != width if ( d3d11->frame.texture[0].desc.Width != width
|| d3d11->frame.texture[0].desc.Height != height) || d3d11->frame.texture[0].desc.Height != height)
{ {
@ -2144,15 +2166,15 @@ D3D11_ST_FLAG_HAS_ALLOW_TEARING)) ? 0 : DXGI_PRESENT_ALLOW_TEARING;
D3D11_MAPPED_SUBRESOURCE res; D3D11_MAPPED_SUBRESOURCE res;
uniform_sem_t* uniform = buffer_sem->uniforms; uniform_sem_t* uniform = buffer_sem->uniforms;
d3d11->context->lpVtbl->Map( d3d11->context->lpVtbl->Map(
d3d11->context, (D3D11Resource)buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &res); d3d11->context, (D3D11Resource)buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &res);
while (uniform->size) while (uniform->size)
{ {
if (uniform->data) if (uniform->data)
memcpy((uint8_t*)res.pData + uniform->offset, uniform->data, uniform->size); memcpy((uint8_t*)res.pData + uniform->offset, uniform->data, uniform->size);
uniform++; uniform++;
} }
context->lpVtbl->Unmap(context, (D3D11Resource)buffer, 0); context->lpVtbl->Unmap(context, (D3D11Resource)buffer, 0);
if (buffer_sem->stage_mask & SLANG_STAGE_VERTEX_MASK) if (buffer_sem->stage_mask & SLANG_STAGE_VERTEX_MASK)
context->lpVtbl->VSSetConstantBuffers(context, context->lpVtbl->VSSetConstantBuffers(context,
@ -2439,6 +2461,7 @@ D3D11_ST_FLAG_HAS_ALLOW_TEARING)) ? 0 : DXGI_PRESENT_ALLOW_TEARING;
IDXGIOutput *pOutput; IDXGIOutput *pOutput;
DXGIGetContainingOutput(d3d11->swapChain, &pOutput); DXGIGetContainingOutput(d3d11->swapChain, &pOutput);
DXGIWaitForVBlank(pOutput); DXGIWaitForVBlank(pOutput);
Release(pOutput);
} }
Release(rtv); Release(rtv);
@ -2460,22 +2483,23 @@ static void d3d11_gfx_set_nonblock_state(void* data,
d3d11->flags &= ~D3D11_ST_FLAG_VSYNC; d3d11->flags &= ~D3D11_ST_FLAG_VSYNC;
else else
d3d11->flags |= D3D11_ST_FLAG_VSYNC; d3d11->flags |= D3D11_ST_FLAG_VSYNC;
d3d11->swap_interval = (!toggle) ? swap_interval : 0; d3d11->swap_interval = (!toggle) ? swap_interval : 0;
} }
static bool d3d11_gfx_alive(void* data) static bool d3d11_gfx_alive(void* data)
{ {
bool quit; bool quit;
bool d3d11_resize_chain = false; bool resize_chain = false;
d3d11_video_t* d3d11 = (d3d11_video_t*)data; d3d11_video_t* d3d11 = (d3d11_video_t*)data;
win32_check_window(NULL, win32_check_window(NULL,
&quit, &quit,
&d3d11_resize_chain, &resize_chain,
&d3d11->vp.full_width, &d3d11->vp.full_width,
&d3d11->vp.full_height); &d3d11->vp.full_height);
if (d3d11_resize_chain) if (resize_chain)
d3d11->flags |= D3D11_ST_FLAG_RESIZE_CHAIN; d3d11->flags |= D3D11_ST_FLAG_RESIZE_CHAIN;
else else
d3d11->flags &= ~D3D11_ST_FLAG_RESIZE_CHAIN; d3d11->flags &= ~D3D11_ST_FLAG_RESIZE_CHAIN;
@ -2509,7 +2533,8 @@ static void d3d11_gfx_viewport_info(void* data, struct video_viewport* vp)
} }
static void d3d11_set_menu_texture_frame( static void d3d11_set_menu_texture_frame(
void* data, const void* frame, bool rgb32, unsigned width, unsigned height, float alpha) void* data, const void* frame, bool rgb32,
unsigned width, unsigned height, float alpha)
{ {
d3d11_video_t* d3d11 = (d3d11_video_t*)data; d3d11_video_t* d3d11 = (d3d11_video_t*)data;
settings_t* settings = config_get_ptr(); settings_t* settings = config_get_ptr();
@ -2545,13 +2570,14 @@ static void d3d11_set_menu_texture_enable(void* data, bool state, bool full_scre
return; return;
if (state) if (state)
d3d11->flags |= D3D11_ST_FLAG_MENU_ENABLE; d3d11->flags |= D3D11_ST_FLAG_MENU_ENABLE;
else else
d3d11->flags &= ~D3D11_ST_FLAG_MENU_ENABLE; d3d11->flags &= ~D3D11_ST_FLAG_MENU_ENABLE;
if (full_screen) if (full_screen)
d3d11->flags |= D3D11_ST_FLAG_MENU_FULLSCREEN; d3d11->flags |= D3D11_ST_FLAG_MENU_FULLSCREEN;
else else
d3d11->flags &= ~D3D11_ST_FLAG_MENU_FULLSCREEN; d3d11->flags &= ~D3D11_ST_FLAG_MENU_FULLSCREEN;
} }
static void d3d11_gfx_set_aspect_ratio(void* data, unsigned aspect_ratio_idx) static void d3d11_gfx_set_aspect_ratio(void* data, unsigned aspect_ratio_idx)
@ -2566,7 +2592,7 @@ static void d3d11_gfx_apply_state_changes(void* data)
{ {
d3d11_video_t* d3d11 = (d3d11_video_t*)data; d3d11_video_t* d3d11 = (d3d11_video_t*)data;
if (d3d11) if (d3d11)
d3d11->flags |= D3D11_ST_FLAG_RESIZE_VIEWPORT; d3d11->flags |= D3D11_ST_FLAG_RESIZE_VIEWPORT;
} }
static void d3d11_gfx_set_osd_msg( static void d3d11_gfx_set_osd_msg(
@ -2632,6 +2658,7 @@ static uintptr_t d3d11_gfx_load_texture(
return (uintptr_t)texture; return (uintptr_t)texture;
} }
static void d3d11_gfx_unload_texture(void* data, static void d3d11_gfx_unload_texture(void* data,
bool threaded, uintptr_t handle) bool threaded, uintptr_t handle)
{ {

View File

@ -93,7 +93,6 @@ static D3D12_RENDER_TARGET_BLEND_DESC d3d12_blend_disable_desc = {
/* Temporary workaround for d3d12 not being able to poll flags during init */ /* Temporary workaround for d3d12 not being able to poll flags during init */
static gfx_ctx_driver_t d3d12_fake_context; static gfx_ctx_driver_t d3d12_fake_context;
static uint32_t d3d12_get_flags(void *data);
static void d3d12_gfx_sync(d3d12_video_t* d3d12) static void d3d12_gfx_sync(d3d12_video_t* d3d12)
{ {
@ -106,6 +105,20 @@ static void d3d12_gfx_sync(d3d12_video_t* d3d12)
} }
} }
static uint32_t d3d12_get_flags(void *data)
{
uint32_t flags = 0;
BIT32_SET(flags, GFX_CTX_FLAGS_CUSTOMIZABLE_FRAME_LATENCY);
BIT32_SET(flags, GFX_CTX_FLAGS_MENU_FRAME_FILTERING);
BIT32_SET(flags, GFX_CTX_FLAGS_OVERLAY_BEHIND_MENU_SUPPORTED);
#if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS)
BIT32_SET(flags, GFX_CTX_FLAGS_SHADERS_SLANG);
#endif
return flags;
}
#ifdef HAVE_OVERLAY #ifdef HAVE_OVERLAY
static void d3d12_free_overlays(d3d12_video_t* d3d12) static void d3d12_free_overlays(d3d12_video_t* d3d12)
{ {
@ -490,15 +503,10 @@ static void d3d12_update_viewport(d3d12_video_t *d3d12, bool force_full)
d3d12->frame.viewport.MaxDepth = 0.0f; d3d12->frame.viewport.MaxDepth = 0.0f;
d3d12->frame.viewport.MaxDepth = 1.0f; d3d12->frame.viewport.MaxDepth = 1.0f;
/* having to add vp.x and vp.y here doesn't make any sense */ if (d3d12->shader_preset
d3d12->frame.scissorRect.top = d3d12->vp.y; && ( d3d12->frame.output_size.x != d3d12->vp.width
d3d12->frame.scissorRect.left = d3d12->vp.x; || d3d12->frame.output_size.y != d3d12->vp.height))
d3d12->frame.scissorRect.right = d3d12->vp.x + d3d12->vp.width; d3d12->flags |= D3D12_ST_FLAG_RESIZE_RTS;
d3d12->frame.scissorRect.bottom = d3d12->vp.y + d3d12->vp.height;
if (d3d12->shader_preset && (d3d12->frame.output_size.x != d3d12->vp.width ||
d3d12->frame.output_size.y != d3d12->vp.height))
d3d12->flags |= D3D12_ST_FLAG_RESIZE_RTS;
d3d12->frame.output_size.x = d3d12->vp.width; d3d12->frame.output_size.x = d3d12->vp.width;
d3d12->frame.output_size.y = d3d12->vp.height; d3d12->frame.output_size.y = d3d12->vp.height;
@ -511,6 +519,7 @@ static void d3d12_update_viewport(d3d12_video_t *d3d12, bool force_full)
static void d3d12_free_shader_preset(d3d12_video_t* d3d12) static void d3d12_free_shader_preset(d3d12_video_t* d3d12)
{ {
size_t i; size_t i;
if (!d3d12->shader_preset) if (!d3d12->shader_preset)
return; return;
@ -555,7 +564,8 @@ static void d3d12_free_shader_preset(d3d12_video_t* d3d12)
free(d3d12->shader_preset); free(d3d12->shader_preset);
d3d12->shader_preset = NULL; d3d12->shader_preset = NULL;
d3d12->flags &= ~(D3D12_ST_FLAG_INIT_HISTORY d3d12->flags &= ~(D3D12_ST_FLAG_INIT_HISTORY
| D3D12_ST_FLAG_RESIZE_RTS); | D3D12_ST_FLAG_RESIZE_RTS
);
} }
static void d3d12_init_pipeline( static void d3d12_init_pipeline(
@ -813,8 +823,8 @@ static bool d3d12_gfx_set_shader(void* data, enum rarch_shader_type type, const
image_texture_free(&image); image_texture_free(&image);
} }
d3d12->flags |= (D3D12_ST_FLAG_INIT_HISTORY d3d12->flags |= D3D12_ST_FLAG_INIT_HISTORY | D3D12_ST_FLAG_RESIZE_RTS;
| D3D12_ST_FLAG_RESIZE_RTS);
return true; return true;
error: error:
@ -1125,14 +1135,17 @@ static void d3d12_gfx_free(void* data)
d3d12_gfx_sync(d3d12); d3d12_gfx_sync(d3d12);
if (d3d12->flags & D3D12_ST_FLAG_WAITABLE_SWAPCHAINS)
CloseHandle(d3d12->chain.frameLatencyWaitableObject);
font_driver_free_osd();
#ifdef HAVE_OVERLAY #ifdef HAVE_OVERLAY
d3d12_free_overlays(d3d12); d3d12_free_overlays(d3d12);
#endif #endif
d3d12_free_shader_preset(d3d12); d3d12_free_shader_preset(d3d12);
font_driver_free_osd();
Release(d3d12->sprites.vbo); Release(d3d12->sprites.vbo);
Release(d3d12->menu_pipeline_vbo); Release(d3d12->menu_pipeline_vbo);
@ -1174,14 +1187,18 @@ static void d3d12_gfx_free(void* data)
Release(d3d12->sprites.pipe_font); Release(d3d12->sprites.pipe_font);
Release(d3d12->queue.fence); Release(d3d12->queue.fence);
Release(d3d12->chain.renderTargets[0]);
Release(d3d12->chain.renderTargets[1]);
Release(d3d12->chain.handle);
Release(d3d12->queue.cmd); Release(d3d12->queue.cmd);
Release(d3d12->queue.allocator); Release(d3d12->queue.allocator);
Release(d3d12->queue.handle); Release(d3d12->queue.handle);
Release(d3d12->chain.renderTargets[0]);
Release(d3d12->chain.renderTargets[1]);
#if 0
/* Releasing this will crash eventually (?!) */
Release(d3d12->chain.handle);
#endif
Release(d3d12->factory); Release(d3d12->factory);
Release(d3d12->device); Release(d3d12->device);
Release(d3d12->adapter); Release(d3d12->adapter);
@ -1309,7 +1326,6 @@ static bool d3d12_init_swapchain(d3d12_video_t* d3d12,
RARCH_LOG("[D3D12]: Requesting %u maximum frame latency, using %u.\n", max_latency, cur_latency); RARCH_LOG("[D3D12]: Requesting %u maximum frame latency, using %u.\n", max_latency, cur_latency);
} }
#ifdef HAVE_WINDOW #ifdef HAVE_WINDOW
DXGIMakeWindowAssociation(d3d12->factory, hwnd, DXGI_MWA_NO_ALT_ENTER); DXGIMakeWindowAssociation(d3d12->factory, hwnd, DXGI_MWA_NO_ALT_ENTER);
#endif #endif
@ -1366,6 +1382,7 @@ static bool d3d12_init_swapchain(d3d12_video_t* d3d12,
d3d12->chain.viewport.Width = width; d3d12->chain.viewport.Width = width;
d3d12->chain.viewport.Height = height; d3d12->chain.viewport.Height = height;
d3d12->chain.scissorRect.left = d3d12->vp.x; d3d12->chain.scissorRect.left = d3d12->vp.x;
d3d12->chain.scissorRect.top = d3d12->vp.y; d3d12->chain.scissorRect.top = d3d12->vp.y;
d3d12->chain.scissorRect.right = d3d12->vp.x + width; d3d12->chain.scissorRect.right = d3d12->vp.x + width;
@ -1920,16 +1937,22 @@ static void *d3d12_gfx_init(const video_info_t* video,
video_driver_set_size(d3d12->vp.full_width, d3d12->vp.full_height); video_driver_set_size(d3d12->vp.full_width, d3d12->vp.full_height);
d3d12->chain.viewport.Width = d3d12->vp.full_width; d3d12->chain.viewport.Width = d3d12->vp.full_width;
d3d12->chain.viewport.Height = d3d12->vp.full_height; d3d12->chain.viewport.Height = d3d12->vp.full_height;
d3d12->flags |= D3D12_ST_FLAG_RESIZE_VIEWPORT; d3d12->flags |= D3D12_ST_FLAG_RESIZE_VIEWPORT;
if (video->force_aspect) if (video->force_aspect)
d3d12->flags |= D3D12_ST_FLAG_KEEP_ASPECT; d3d12->flags |= D3D12_ST_FLAG_KEEP_ASPECT;
else else
d3d12->flags &= ~D3D12_ST_FLAG_KEEP_ASPECT; d3d12->flags &= ~D3D12_ST_FLAG_KEEP_ASPECT;
if (video->vsync) if (video->vsync)
d3d12->flags |= D3D12_ST_FLAG_VSYNC; d3d12->flags |= D3D12_ST_FLAG_VSYNC;
else else
d3d12->flags &= ~D3D12_ST_FLAG_VSYNC; d3d12->flags &= ~D3D12_ST_FLAG_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[0].desc.Format = d3d12->format; d3d12->frame.texture[0].desc.Format = d3d12->format;
d3d12->frame.texture[0].desc.Width = 4; d3d12->frame.texture[0].desc.Width = 4;
d3d12->frame.texture[0].desc.Height = 4; d3d12->frame.texture[0].desc.Height = 4;
@ -1983,13 +2006,13 @@ static void d3d12_init_history(d3d12_video_t* d3d12, unsigned width, unsigned he
static void d3d12_init_render_targets(d3d12_video_t* d3d12, unsigned width, unsigned height) static void d3d12_init_render_targets(d3d12_video_t* d3d12, unsigned width, unsigned height)
{ {
size_t i; size_t i;
for (i = 0; i < d3d12->shader_preset->passes; i++) for (i = 0; i < d3d12->shader_preset->passes; i++)
{ {
struct video_shader_pass* pass = &d3d12->shader_preset->pass[i]; struct video_shader_pass* pass = &d3d12->shader_preset->pass[i];
if (pass->fbo.flags & FBO_SCALE_FLAG_VALID) if (pass->fbo.flags & FBO_SCALE_FLAG_VALID)
{ {
switch (pass->fbo.type_x) switch (pass->fbo.type_x)
{ {
case RARCH_SCALE_INPUT: case RARCH_SCALE_INPUT:
@ -2067,8 +2090,9 @@ static void d3d12_init_render_targets(d3d12_video_t* d3d12, unsigned width, unsi
d3d12->pass[i].scissorRect.bottom = height; d3d12->pass[i].scissorRect.bottom = height;
} }
if ((i != (d3d12->shader_preset->passes - 1)) || (width != d3d12->vp.width) || if ( (i != (d3d12->shader_preset->passes - 1))
(height != d3d12->vp.height)) || (width != d3d12->vp.width)
|| (height != d3d12->vp.height))
{ {
d3d12->pass[i].rt.desc.Width = width; d3d12->pass[i].rt.desc.Width = width;
d3d12->pass[i].rt.desc.Height = height; d3d12->pass[i].rt.desc.Height = height;
@ -2114,12 +2138,11 @@ static bool d3d12_gfx_frame(
const char* msg, const char* msg,
video_frame_info_t* video_info) video_frame_info_t* video_info)
{ {
unsigned i; unsigned i;
d3d12_texture_t* texture = NULL; d3d12_texture_t* texture = NULL;
d3d12_video_t* d3d12 = (d3d12_video_t*)data; d3d12_video_t* d3d12 = (d3d12_video_t*)data;
bool vsync = d3d12->flags & D3D12_ST_FLAG_VSYNC; bool vsync = d3d12->flags & D3D12_ST_FLAG_VSYNC;
bool wait_for_vblank = d3d12->flags & D3D12_ST_FLAG_WAIT_FOR_VBLANK; bool wait_for_vblank = d3d12->flags & D3D12_ST_FLAG_WAIT_FOR_VBLANK;
unsigned sync_interval = (vsync) ? d3d12->chain.swap_interval : 0;
unsigned present_flags = (vsync) ? 0 : DXGI_PRESENT_ALLOW_TEARING; unsigned present_flags = (vsync) ? 0 : DXGI_PRESENT_ALLOW_TEARING;
const char *stat_text = video_info->stat_text; const char *stat_text = video_info->stat_text;
bool statistics_show = video_info->statistics_show; bool statistics_show = video_info->statistics_show;
@ -2139,15 +2162,27 @@ static bool d3d12_gfx_frame(
bool use_back_buffer = back_buffer_format != d3d12->chain.formats[d3d12->chain.bit_depth]; bool use_back_buffer = back_buffer_format != d3d12->chain.formats[d3d12->chain.bit_depth];
#endif #endif
if (d3d12->flags & D3D12_ST_FLAG_WAITABLE_SWAPCHAINS)
WaitForSingleObjectEx(
d3d12->chain.frameLatencyWaitableObject,
1000,
true);
d3d12_gfx_sync(d3d12); d3d12_gfx_sync(d3d12);
#ifdef HAVE_DXGI_HDR #ifdef HAVE_DXGI_HDR
d3d12_hdr_enable = d3d12->flags & D3D12_ST_FLAG_HDR_ENABLE; d3d12_hdr_enable = d3d12->flags & D3D12_ST_FLAG_HDR_ENABLE;
if ((d3d12->flags & D3D12_ST_FLAG_RESIZE_CHAIN) || (d3d12_hdr_enable != video_hdr_enable)) if ( (d3d12->flags & D3D12_ST_FLAG_RESIZE_CHAIN)
|| (d3d12_hdr_enable != video_hdr_enable))
#else #else
if (d3d12->flags & D3D12_ST_FLAG_RESIZE_CHAIN) if (d3d12->flags & D3D12_ST_FLAG_RESIZE_CHAIN)
#endif #endif
{ {
UINT swapchain_flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
if (d3d12->flags & D3D12_ST_FLAG_WAITABLE_SWAPCHAINS)
swapchain_flags |= DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
#ifdef HAVE_DXGI_HDR #ifdef HAVE_DXGI_HDR
if (video_hdr_enable) if (video_hdr_enable)
d3d12->flags |= D3D12_ST_FLAG_HDR_ENABLE; d3d12->flags |= D3D12_ST_FLAG_HDR_ENABLE;
@ -2164,19 +2199,20 @@ static bool d3d12_gfx_frame(
d3d12_release_texture(&d3d12->chain.back_buffer); d3d12_release_texture(&d3d12->chain.back_buffer);
d3d12->chain.back_buffer.handle = NULL; d3d12->chain.back_buffer.handle = NULL;
} }
DXGIResizeBuffers(d3d12->chain.handle, DXGIResizeBuffers(d3d12->chain.handle,
countof(d3d12->chain.renderTargets), countof(d3d12->chain.renderTargets),
video_width, video_width,
video_height, video_height,
d3d12->chain.formats[d3d12->chain.bit_depth], d3d12->chain.formats[d3d12->chain.bit_depth],
DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING); swapchain_flags);
#else #else
DXGIResizeBuffers(d3d12->chain.handle, DXGIResizeBuffers(d3d12->chain.handle,
0, 0,
0, 0,
0, 0,
DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN,
DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING); swapchain_flags);
#endif #endif
for (i = 0; i < countof(d3d12->chain.renderTargets); i++) for (i = 0; i < countof(d3d12->chain.renderTargets); i++)
@ -2190,16 +2226,18 @@ static bool d3d12_gfx_frame(
d3d12->chain.viewport.Width = video_width; d3d12->chain.viewport.Width = video_width;
d3d12->chain.viewport.Height = video_height; d3d12->chain.viewport.Height = video_height;
d3d12->chain.scissorRect.left = d3d12->vp.x;
d3d12->chain.scissorRect.top = d3d12->vp.y; d3d12->chain.scissorRect.left = 0;
d3d12->chain.scissorRect.right = d3d12->vp.x + video_width; d3d12->chain.scissorRect.top = 0;
d3d12->chain.scissorRect.bottom = d3d12->vp.y + video_height; d3d12->chain.scissorRect.right = d3d12->vp.full_width;
d3d12->flags &= ~D3D12_ST_FLAG_RESIZE_CHAIN; d3d12->chain.scissorRect.bottom = d3d12->vp.full_height;
d3d12->flags |= D3D12_ST_FLAG_RESIZE_VIEWPORT;
d3d12->ubo_values.OutputSize.width = d3d12->chain.viewport.Width; d3d12->ubo_values.OutputSize.width = d3d12->chain.viewport.Width;
d3d12->ubo_values.OutputSize.height = d3d12->chain.viewport.Height; d3d12->ubo_values.OutputSize.height = d3d12->chain.viewport.Height;
d3d12->flags &= ~D3D12_ST_FLAG_RESIZE_CHAIN;
d3d12->flags |= D3D12_ST_FLAG_RESIZE_VIEWPORT;
video_driver_set_size(video_width, video_height); video_driver_set_size(video_width, video_height);
#ifdef HAVE_DXGI_HDR #ifdef HAVE_DXGI_HDR
@ -2262,13 +2300,6 @@ static bool d3d12_gfx_frame(
d3d12->hdr.max_fall); d3d12->hdr.max_fall);
#endif #endif
} }
else if (d3d12->flags & D3D12_ST_FLAG_WAITABLE_SWAPCHAINS)
{
WaitForSingleObjectEx(
d3d12->chain.frameLatencyWaitableObject,
1000,
true);
}
D3D12ResetCommandAllocator(d3d12->queue.allocator); D3D12ResetCommandAllocator(d3d12->queue.allocator);
@ -2284,11 +2315,10 @@ static bool d3d12_gfx_frame(
} }
#if 0 #if 0
/* Custom viewport doesn't call apply_state_changes, /* Custom viewport doesn't call apply_state_changes, so we can't rely on this for now */
so we can't rely on this for now */
if (d3d12->resize_viewport) if (d3d12->resize_viewport)
#endif #endif
d3d12_update_viewport(d3d12, false); d3d12_update_viewport(d3d12, false);
D3D12IASetPrimitiveTopology(d3d12->queue.cmd, D3D12IASetPrimitiveTopology(d3d12->queue.cmd,
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
@ -2302,14 +2332,13 @@ static bool d3d12_gfx_frame(
d3d12_upload_texture(d3d12->queue.cmd, &d3d12->luts[i], d3d12_upload_texture(d3d12->queue.cmd, &d3d12->luts[i],
d3d12); d3d12);
if ( (d3d12->frame.texture[0].desc.Width != width) if ( (d3d12->frame.texture[0].desc.Width != width)
|| (d3d12->frame.texture[0].desc.Height != height)) || (d3d12->frame.texture[0].desc.Height != height))
d3d12->flags |= D3D12_ST_FLAG_RESIZE_RTS; d3d12->flags |= D3D12_ST_FLAG_RESIZE_RTS;
if (d3d12->flags & D3D12_ST_FLAG_RESIZE_RTS) if (d3d12->flags & D3D12_ST_FLAG_RESIZE_RTS)
{ {
/* Release all render targets first /* Release all Render Targets (RT) first to avoid memory fragmentation */
to avoid memory fragmentation */
for (i = 0; i < d3d12->shader_preset->passes; i++) for (i = 0; i < d3d12->shader_preset->passes; i++)
{ {
d3d12_release_texture(&d3d12->pass[i].rt); d3d12_release_texture(&d3d12->pass[i].rt);
@ -2337,10 +2366,9 @@ static bool d3d12_gfx_frame(
} }
} }
/* Either no history, or we moved a texture /* Either no history, or we moved a texture of a different size in the front slot */
of a different size in the front slot */ if ( d3d12->frame.texture[0].desc.Width != width
if (d3d12->frame.texture[0].desc.Width != width || || d3d12->frame.texture[0].desc.Height != height)
d3d12->frame.texture[0].desc.Height != height)
{ {
d3d12->frame.texture[0].desc.Width = width; d3d12->frame.texture[0].desc.Width = width;
d3d12->frame.texture[0].desc.Height = height; d3d12->frame.texture[0].desc.Height = height;
@ -2514,7 +2542,7 @@ static bool d3d12_gfx_frame(
{ {
D3D12_RESOURCE_TRANSITION( D3D12_RESOURCE_TRANSITION(
d3d12->queue.cmd, d3d12->queue.cmd,
d3d12->pass[i].rt.handle, d3d12->pass[i].rt.handle,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
D3D12_RESOURCE_STATE_RENDER_TARGET); D3D12_RESOURCE_STATE_RENDER_TARGET);
@ -2537,7 +2565,7 @@ static bool d3d12_gfx_frame(
D3D12_RESOURCE_TRANSITION( D3D12_RESOURCE_TRANSITION(
d3d12->queue.cmd, d3d12->queue.cmd,
d3d12->pass[i].rt.handle, d3d12->pass[i].rt.handle,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RENDER_TARGET,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
texture = &d3d12->pass[i].rt; texture = &d3d12->pass[i].rt;
@ -2557,12 +2585,11 @@ static bool d3d12_gfx_frame(
D3D12SetGraphicsRootSignature(d3d12->queue.cmd, D3D12SetGraphicsRootSignature(d3d12->queue.cmd,
d3d12->desc.rootSignature); d3d12->desc.rootSignature);
D3D12SetGraphicsRootDescriptorTable(d3d12->queue.cmd, D3D12SetGraphicsRootDescriptorTable(d3d12->queue.cmd,
ROOT_ID_TEXTURE_T, ROOT_ID_TEXTURE_T,
d3d12->frame.texture[0].gpu_descriptor[0]); d3d12->frame.texture[0].gpu_descriptor[0]);
D3D12SetGraphicsRootDescriptorTable(d3d12->queue.cmd, D3D12SetGraphicsRootDescriptorTable(d3d12->queue.cmd,
ROOT_ID_SAMPLER_T, ROOT_ID_SAMPLER_T,
d3d12->samplers[ d3d12->samplers[RARCH_FILTER_UNSPEC][RARCH_WRAP_DEFAULT]);
RARCH_FILTER_UNSPEC][RARCH_WRAP_DEFAULT]);
D3D12SetGraphicsRootConstantBufferView( D3D12SetGraphicsRootConstantBufferView(
d3d12->queue.cmd, ROOT_ID_UBO, d3d12->queue.cmd, ROOT_ID_UBO,
d3d12->frame.ubo_view.BufferLocation); d3d12->frame.ubo_view.BufferLocation);
@ -2576,13 +2603,14 @@ static bool d3d12_gfx_frame(
{ {
D3D12_RESOURCE_TRANSITION( D3D12_RESOURCE_TRANSITION(
d3d12->queue.cmd, d3d12->queue.cmd,
d3d12->chain.back_buffer.handle, d3d12->chain.back_buffer.handle,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
D3D12_RESOURCE_STATE_RENDER_TARGET); D3D12_RESOURCE_STATE_RENDER_TARGET);
D3D12OMSetRenderTargets( D3D12OMSetRenderTargets(
d3d12->queue.cmd, 1, d3d12->queue.cmd, 1,
&d3d12->chain.back_buffer.rt_view, FALSE, NULL); &d3d12->chain.back_buffer.rt_view,
FALSE, NULL);
/* TODO/FIXME - fix this warning that shows up with Debug logging /* TODO/FIXME - fix this warning that shows up with Debug logging
* EXECUTIONWARNING #820: CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE * EXECUTIONWARNING #820: CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE
* We need to set clear value during resource creation to NULL for * We need to set clear value during resource creation to NULL for
@ -2590,8 +2618,10 @@ static bool d3d12_gfx_frame(
* warning * warning
*/ */
D3D12ClearRenderTargetView( D3D12ClearRenderTargetView(
d3d12->queue.cmd, d3d12->chain.back_buffer.rt_view, d3d12->queue.cmd,
d3d12->chain.clearcolor, 0, NULL); d3d12->chain.back_buffer.rt_view,
d3d12->chain.clearcolor,
0, NULL);
} }
else else
#endif #endif
@ -2609,7 +2639,8 @@ static bool d3d12_gfx_frame(
D3D12ClearRenderTargetView( D3D12ClearRenderTargetView(
d3d12->queue.cmd, d3d12->queue.cmd,
d3d12->chain.desc_handles[d3d12->chain.frame_index], d3d12->chain.desc_handles[d3d12->chain.frame_index],
d3d12->chain.clearcolor, 0, NULL); d3d12->chain.clearcolor,
0, NULL);
} }
D3D12RSSetViewports(d3d12->queue.cmd, 1, &d3d12->frame.viewport); D3D12RSSetViewports(d3d12->queue.cmd, 1, &d3d12->frame.viewport);
@ -2638,11 +2669,11 @@ static bool d3d12_gfx_frame(
} }
D3D12SetGraphicsRootDescriptorTable(d3d12->queue.cmd, D3D12SetGraphicsRootDescriptorTable(d3d12->queue.cmd,
ROOT_ID_TEXTURE_T, ROOT_ID_TEXTURE_T,
d3d12->menu.texture.gpu_descriptor[0]); d3d12->menu.texture.gpu_descriptor[0]);
D3D12SetGraphicsRootDescriptorTable(d3d12->queue.cmd, D3D12SetGraphicsRootDescriptorTable(d3d12->queue.cmd,
ROOT_ID_SAMPLER_T, ROOT_ID_SAMPLER_T,
d3d12->menu.texture.sampler); d3d12->menu.texture.sampler);
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->menu.vbo_view); D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->menu.vbo_view);
D3D12DrawInstanced(d3d12->queue.cmd, 4, 1, 0, 0); D3D12DrawInstanced(d3d12->queue.cmd, 4, 1, 0, 0);
} }
@ -2719,45 +2750,48 @@ static bool d3d12_gfx_frame(
} }
d3d12->flags &= ~D3D12_ST_FLAG_SPRITES_ENABLE; d3d12->flags &= ~D3D12_ST_FLAG_SPRITES_ENABLE;
#if defined(_WIN32) && !defined(__WINRT__)
win32_update_title();
#endif
#ifdef HAVE_DXGI_HDR #ifdef HAVE_DXGI_HDR
/* Copy over back buffer to swap chain render targets */ /* Copy over back buffer to swap chain render targets */
if ((d3d12->flags & D3D12_ST_FLAG_HDR_ENABLE) && use_back_buffer) if ((d3d12->flags & D3D12_ST_FLAG_HDR_ENABLE) && use_back_buffer)
{ {
D3D12_RESOURCE_TRANSITION( D3D12_RESOURCE_TRANSITION(
d3d12->queue.cmd, d3d12->queue.cmd,
d3d12->chain.renderTargets[d3d12->chain.frame_index], d3d12->chain.renderTargets[d3d12->chain.frame_index],
D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_PRESENT,
D3D12_RESOURCE_STATE_RENDER_TARGET); D3D12_RESOURCE_STATE_RENDER_TARGET);
D3D12_RESOURCE_TRANSITION( D3D12_RESOURCE_TRANSITION(
d3d12->queue.cmd, d3d12->queue.cmd,
d3d12->chain.back_buffer.handle, d3d12->chain.back_buffer.handle,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RENDER_TARGET,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
D3D12SetPipelineState(d3d12->queue.cmd, D3D12SetPipelineState(d3d12->queue.cmd,
d3d12->pipes[VIDEO_SHADER_STOCK_HDR]); d3d12->pipes[VIDEO_SHADER_STOCK_HDR]);
D3D12OMSetRenderTargets( D3D12OMSetRenderTargets(
d3d12->queue.cmd, 1, d3d12->queue.cmd, 1,
&d3d12->chain.desc_handles[d3d12->chain.frame_index], &d3d12->chain.desc_handles[d3d12->chain.frame_index],
FALSE, NULL); FALSE, NULL);
D3D12ClearRenderTargetView( D3D12ClearRenderTargetView(
d3d12->queue.cmd, d3d12->queue.cmd,
d3d12->chain.desc_handles[d3d12->chain.frame_index], d3d12->chain.desc_handles[d3d12->chain.frame_index],
d3d12->chain.clearcolor, 0, NULL); d3d12->chain.clearcolor, 0, NULL);
D3D12SetGraphicsRootSignature(d3d12->queue.cmd, D3D12SetGraphicsRootSignature(d3d12->queue.cmd,
d3d12->desc.rootSignature); d3d12->desc.rootSignature);
D3D12SetGraphicsRootDescriptorTable(d3d12->queue.cmd, D3D12SetGraphicsRootDescriptorTable(d3d12->queue.cmd,
ROOT_ID_TEXTURE_T, ROOT_ID_TEXTURE_T,
d3d12->chain.back_buffer.gpu_descriptor[0]); d3d12->chain.back_buffer.gpu_descriptor[0]);
D3D12SetGraphicsRootDescriptorTable(d3d12->queue.cmd, D3D12SetGraphicsRootDescriptorTable(d3d12->queue.cmd,
ROOT_ID_SAMPLER_T, ROOT_ID_SAMPLER_T,
d3d12->samplers[ d3d12->samplers[RARCH_FILTER_UNSPEC][RARCH_WRAP_DEFAULT]);
RARCH_FILTER_UNSPEC][RARCH_WRAP_DEFAULT]);
D3D12SetGraphicsRootConstantBufferView( D3D12SetGraphicsRootConstantBufferView(
d3d12->queue.cmd, ROOT_ID_UBO, d3d12->queue.cmd, ROOT_ID_UBO,
d3d12->hdr.ubo_view.BufferLocation); d3d12->hdr.ubo_view.BufferLocation);
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1,
&d3d12->frame.vbo_view); &d3d12->frame.vbo_view);
@ -2784,36 +2818,40 @@ static bool d3d12_gfx_frame(
D3D12ExecuteGraphicsCommandLists(d3d12->queue.handle, 1, D3D12ExecuteGraphicsCommandLists(d3d12->queue.handle, 1,
&d3d12->queue.cmd); &d3d12->queue.cmd);
#if defined(_WIN32) && !defined(__WINRT__) DXGIPresent(d3d12->chain.handle, d3d12->chain.swap_interval, present_flags);
win32_update_title();
#endif
DXGIPresent(d3d12->chain.handle, sync_interval, present_flags);
if (vsync && wait_for_vblank) if (vsync && wait_for_vblank)
{ {
IDXGIOutput *pOutput; IDXGIOutput *pOutput;
DXGIGetContainingOutput(d3d12->chain.handle, &pOutput); DXGIGetContainingOutput(d3d12->chain.handle, &pOutput);
DXGIWaitForVBlank(pOutput); DXGIWaitForVBlank(pOutput);
Release(pOutput);
} }
return true; return true;
} }
static void d3d12_gfx_set_nonblock_state(void* data, bool toggle, static void d3d12_gfx_set_nonblock_state(void* data,
bool toggle,
bool adaptive_vsync_enabled, bool adaptive_vsync_enabled,
unsigned swap_interval) unsigned swap_interval)
{ {
d3d12_video_t* d3d12 = (d3d12_video_t*)data; d3d12_video_t* d3d12 = (d3d12_video_t*)data;
if (!d3d12)
return;
if (toggle) if (toggle)
d3d12->flags &= ~D3D12_ST_FLAG_VSYNC; d3d12->flags &= ~D3D12_ST_FLAG_VSYNC;
else else
d3d12->flags |= D3D12_ST_FLAG_VSYNC; d3d12->flags |= D3D12_ST_FLAG_VSYNC;
d3d12->chain.swap_interval = swap_interval;
d3d12->chain.swap_interval = (!toggle) ? swap_interval : 0;
} }
static bool d3d12_gfx_alive(void* data) static bool d3d12_gfx_alive(void* data)
{ {
bool quit; bool quit;
bool resize_chain = false; bool resize_chain = false;
d3d12_video_t* d3d12 = (d3d12_video_t*)data; d3d12_video_t* d3d12 = (d3d12_video_t*)data;
@ -2906,7 +2944,7 @@ static void d3d12_set_menu_texture_frame(
static void d3d12_set_menu_texture_enable(void* data, static void d3d12_set_menu_texture_enable(void* data,
bool state, bool fullscreen) bool state, bool fullscreen)
{ {
d3d12_video_t* d3d12 = (d3d12_video_t*)data; d3d12_video_t* d3d12 = (d3d12_video_t*)data;
if (!d3d12) if (!d3d12)
return; return;
@ -2925,6 +2963,7 @@ static void d3d12_gfx_set_aspect_ratio(
void* data, unsigned aspect_ratio_idx) void* data, unsigned aspect_ratio_idx)
{ {
d3d12_video_t* d3d12 = (d3d12_video_t*)data; d3d12_video_t* d3d12 = (d3d12_video_t*)data;
if (d3d12) if (d3d12)
d3d12->flags |= D3D12_ST_FLAG_KEEP_ASPECT | D3D12_ST_FLAG_RESIZE_VIEWPORT; d3d12->flags |= D3D12_ST_FLAG_KEEP_ASPECT | D3D12_ST_FLAG_RESIZE_VIEWPORT;
} }
@ -2943,8 +2982,10 @@ static void d3d12_gfx_set_osd_msg(
void* font) void* font)
{ {
d3d12_video_t* d3d12 = (d3d12_video_t*)data; d3d12_video_t* d3d12 = (d3d12_video_t*)data;
if (d3d12 && (d3d12->flags & D3D12_ST_FLAG_SPRITES_ENABLE)) if (d3d12 && (d3d12->flags & D3D12_ST_FLAG_SPRITES_ENABLE))
font_driver_render_msg(d3d12, msg, font_driver_render_msg(d3d12,
msg,
(const struct font_params*)params, font); (const struct font_params*)params, font);
} }
@ -2994,6 +3035,7 @@ static uintptr_t d3d12_gfx_load_texture(
return (uintptr_t)texture; return (uintptr_t)texture;
} }
static void d3d12_gfx_unload_texture(void* data, static void d3d12_gfx_unload_texture(void* data,
bool threaded, uintptr_t handle) bool threaded, uintptr_t handle)
{ {
@ -3007,20 +3049,6 @@ static void d3d12_gfx_unload_texture(void* data,
free(texture); free(texture);
} }
static uint32_t d3d12_get_flags(void *data)
{
uint32_t flags = 0;
BIT32_SET(flags, GFX_CTX_FLAGS_CUSTOMIZABLE_FRAME_LATENCY);
BIT32_SET(flags, GFX_CTX_FLAGS_MENU_FRAME_FILTERING);
BIT32_SET(flags, GFX_CTX_FLAGS_OVERLAY_BEHIND_MENU_SUPPORTED);
#if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS)
BIT32_SET(flags, GFX_CTX_FLAGS_SHADERS_SLANG);
#endif
return flags;
}
#ifndef __WINRT__ #ifndef __WINRT__
static void d3d12_get_video_output_size(void *data, static void d3d12_get_video_output_size(void *data,
unsigned *width, unsigned *height, char *desc, size_t desc_len) unsigned *width, unsigned *height, char *desc, size_t desc_len)
@ -3080,7 +3108,7 @@ static const video_poke_interface_t d3d12_poke_interface = {
d3d12_set_hdr_max_nits, d3d12_set_hdr_max_nits,
d3d12_set_hdr_paper_white_nits, d3d12_set_hdr_paper_white_nits,
d3d12_set_hdr_contrast, d3d12_set_hdr_contrast,
d3d12_set_hdr_expand_gamut, d3d12_set_hdr_expand_gamut
#else #else
NULL, /* set_hdr_max_nits */ NULL, /* set_hdr_max_nits */
NULL, /* set_hdr_paper_white_nits */ NULL, /* set_hdr_paper_white_nits */