Fixed menu system displaying incorrectly in HDR on D3D11, D3D12 and Vulkan

This commit is contained in:
MajorPainTheCactus authored and LibretroAdmin committed 2026-01-26 09:25:27 +01:00
1 parent 93a37bd22d
commit 12d188ee1d
5 files changed
+258 -195

No files matched your search

+40 -31
View File
@@ -1630,7 +1630,7 @@ static void d3d11_set_hdr_paper_white_nits(void* data, float paper_white_nits)
{
for (unsigned i = 0; i < d3d11->shader_preset->passes; i++)
{
d3d11->pass[i].paper_white_nits = paper_white_nits;
d3d11->pass[i].paper_white_nits = paper_white_nits;
}
}
}
@@ -3305,7 +3305,6 @@ static bool d3d11_gfx_frame(
bool d3d11_hdr_enable = (d3d11->flags & D3D11_ST_FLAG_HDR_ENABLE) ? true : false;
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) : d3d11->chain_formats[d3d11->chain_bit_depth];
bool use_back_buffer = back_buffer_format != d3d11->chain_formats[d3d11->chain_bit_depth];
#endif
if (d3d11->flags & D3D11_ST_FLAG_WAITABLE_SWAPCHAINS)
@@ -3736,30 +3735,15 @@ static bool d3d11_gfx_frame(
}
}
#ifdef HAVE_DXGI_HDR
if ( (d3d11->flags & D3D11_ST_FLAG_HDR_ENABLE)
&& use_back_buffer)
{
context->lpVtbl->OMSetRenderTargets(context, 1,
&d3d11->back_buffer.rt_view, NULL);
context->lpVtbl->ClearRenderTargetView(context,
d3d11->back_buffer.rt_view, d3d11->clearcolor);
}
else
#endif
{
context->lpVtbl->OMSetRenderTargets(context, 1, &rtv, NULL);
context->lpVtbl->ClearRenderTargetView(context, rtv, d3d11->clearcolor);
}
context->lpVtbl->OMSetRenderTargets(context, 1, &rtv, NULL);
context->lpVtbl->ClearRenderTargetView(context, rtv, d3d11->clearcolor);
context->lpVtbl->RSSetViewports(context, 1, &d3d11->frame.viewport);
if (texture)
{
#ifdef HAVE_DXGI_HDR
if ((d3d11->flags & D3D11_ST_FLAG_HDR_ENABLE)
&& !use_back_buffer)
if (d3d11->flags & D3D11_ST_FLAG_HDR_ENABLE)
{
d3d11_shader_t *shader = &d3d11->shaders[VIDEO_SHADER_STOCK_HDR];
context->lpVtbl->IASetInputLayout(context, shader->layout);
@@ -3767,8 +3751,6 @@ static bool d3d11_gfx_frame(
context->lpVtbl->PSSetShader(context, shader->ps, NULL, 0);
context->lpVtbl->GSSetShader(context, shader->gs, NULL, 0);
if( d3d11->hdr.ubo_values.source_size.width != width || d3d11->hdr.ubo_values.source_size.height != height ||
d3d11->hdr.ubo_values.output_size.width != d3d11->frame.output_size.x || d3d11->hdr.ubo_values.output_size.height != d3d11->frame.output_size.y)
{
d3d11->hdr.ubo_values.source_size.width = width;
d3d11->hdr.ubo_values.source_size.height = height;
@@ -3776,10 +3758,13 @@ static bool d3d11_gfx_frame(
d3d11->hdr.ubo_values.output_size.width = d3d11->frame.output_size.x;
d3d11->hdr.ubo_values.output_size.height = d3d11->frame.output_size.y;
settings_t* settings = config_get_ptr();
d3d11->hdr.ubo_values.scanlines = settings->bools.video_hdr_scanlines ? 1.0f : 0.0f;
D3D11_MAPPED_SUBRESOURCE mapped_ubo;
d3d11->context->lpVtbl->Map(
d3d11->context, (D3D11Resource)d3d11->hdr.ubo, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mapped_ubo);
d3d11->context, (D3D11Resource)d3d11->hdr.ubo, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_ubo);
{
dxgi_hdr_uniform_t *ubo = (dxgi_hdr_uniform_t*)mapped_ubo.pData;
*ubo = d3d11->hdr.ubo_values;
@@ -3837,6 +3822,19 @@ static bool d3d11_gfx_frame(
context->lpVtbl->Draw(context, 4, 0);
#ifdef HAVE_DXGI_HDR
if((d3d11->flags & D3D11_ST_FLAG_HDR_ENABLE) &&
(d3d11->flags & D3D11_ST_FLAG_MENU_ENABLE))
{
context->lpVtbl->OMSetRenderTargets(context, 1,
&d3d11->back_buffer.rt_view, NULL);
float clear_colour[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
context->lpVtbl->ClearRenderTargetView(context,
d3d11->back_buffer.rt_view, clear_colour);
}
#endif
context->lpVtbl->RSSetState(context, d3d11->scissor_enabled);
d3d11->context->lpVtbl->RSSetScissorRects(d3d11->context, 1, &d3d11->scissor);
context->lpVtbl->OMSetBlendState(context, d3d11->blend_enable,
@@ -3973,12 +3971,11 @@ static bool d3d11_gfx_frame(
#ifdef HAVE_DXGI_HDR
/* Copy over back buffer to swap chain render targets */
if ( (d3d11->flags & D3D11_ST_FLAG_HDR_ENABLE)
&& use_back_buffer)
if((d3d11->flags & D3D11_ST_FLAG_HDR_ENABLE) &&
(d3d11->flags & D3D11_ST_FLAG_MENU_ENABLE))
{
ID3D11ShaderResourceView* nullSRV[1] = {NULL};
context->lpVtbl->OMSetRenderTargets(context, 1, &rtv, NULL);
context->lpVtbl->ClearRenderTargetView(context, rtv, d3d11->clearcolor);
context->lpVtbl->RSSetViewports(context, 1, &d3d11->viewport);
context->lpVtbl->RSSetScissorRects(context, 1, &d3d11->scissor);
@@ -3989,15 +3986,29 @@ static bool d3d11_gfx_frame(
context->lpVtbl->PSSetShader(context, shader->ps, NULL, 0);
context->lpVtbl->GSSetShader(context, shader->gs, NULL, 0);
}
{
d3d11->hdr.ubo_values.scanlines = false;
D3D11_MAPPED_SUBRESOURCE mapped_ubo;
d3d11->context->lpVtbl->Map(
d3d11->context, (D3D11Resource)d3d11->hdr.ubo, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_ubo);
{
dxgi_hdr_uniform_t *ubo = (dxgi_hdr_uniform_t*)mapped_ubo.pData;
*ubo = d3d11->hdr.ubo_values;
}
d3d11->context->lpVtbl->Unmap(d3d11->context, (D3D11Resource)d3d11->hdr.ubo, 0);
}
context->lpVtbl->VSSetConstantBuffers(context, 0, 1, &d3d11->hdr.ubo);
context->lpVtbl->PSSetConstantBuffers(context, 0, 1, &d3d11->hdr.ubo);
context->lpVtbl->PSSetShaderResources(
context, 0, 1,
&d3d11->back_buffer.view);
context->lpVtbl->PSSetSamplers(
context, 0, 1,
&d3d11->samplers[RARCH_FILTER_UNSPEC][RARCH_WRAP_DEFAULT]);
context->lpVtbl->PSSetConstantBuffers(
context, 0, 1, &d3d11->hdr.ubo);
{
UINT stride = sizeof(d3d11_vertex_t);
UINT offset = 0;
@@ -4006,7 +4017,7 @@ static bool d3d11_gfx_frame(
}
context->lpVtbl->RSSetState(context, d3d11->scissor_disabled);
d3d11->context->lpVtbl->OMSetBlendState(d3d11->context, d3d11->blend_disable,
d3d11->context->lpVtbl->OMSetBlendState(d3d11->context, d3d11->blend_enable,
NULL, D3D11_DEFAULT_SAMPLE_MASK);
context->lpVtbl->IASetPrimitiveTopology(context,
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
@@ -4016,8 +4027,6 @@ static bool d3d11_gfx_frame(
context->lpVtbl->PSSetShaderResources(
context, 0, 1, nullSRV);
context->lpVtbl->RSSetState(context, d3d11->scissor_enabled);
d3d11->context->lpVtbl->OMSetBlendState(d3d11->context, d3d11->blend_enable,
NULL, D3D11_DEFAULT_SAMPLE_MASK);
context->lpVtbl->IASetPrimitiveTopology(context,
D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
}
+90 -109
View File
@@ -335,6 +335,8 @@ typedef struct
dxgi_hdr_uniform_t ubo_values;
D3D12Resource ubo;
D3D12_CONSTANT_BUFFER_VIEW_DESC ubo_view;
D3D12Resource ubo_post;
D3D12_CONSTANT_BUFFER_VIEW_DESC ubo_post_view;
float max_output_nits;
float min_output_nits;
float max_cll;
@@ -1846,19 +1848,11 @@ static void d3d12_render_overlay(d3d12_video_t *d3d12)
#ifdef HAVE_DXGI_HDR
static void d3d12_set_hdr_max_nits(void* data, float max_nits)
{
D3D12_RANGE read_range;
dxgi_hdr_uniform_t *mapped_ubo = NULL;
d3d12_video_t *d3d12 = (d3d12_video_t*)data;
d3d12->hdr.max_output_nits = max_nits;
d3d12->hdr.ubo_values.max_nits = max_nits;
read_range.Begin = 0;
read_range.End = 0;
D3D12Map(d3d12->hdr.ubo, 0, &read_range, (void**)&mapped_ubo);
*mapped_ubo = d3d12->hdr.ubo_values;
D3D12Unmap(d3d12->hdr.ubo, 0, NULL);
dxgi_set_hdr_metadata(
d3d12->chain.handle,
(d3d12->flags & D3D12_ST_FLAG_HDR_SUPPORT) ? true : false,
@@ -1880,17 +1874,9 @@ static void d3d12_set_hdr_max_nits(void* data, float max_nits)
static void d3d12_set_hdr_paper_white_nits(void* data, float paper_white_nits)
{
D3D12_RANGE read_range;
dxgi_hdr_uniform_t *mapped_ubo = NULL;
d3d12_video_t *d3d12 = (d3d12_video_t*)data;
d3d12->hdr.ubo_values.paper_white_nits = paper_white_nits;
read_range.Begin = 0;
read_range.End = 0;
D3D12Map(d3d12->hdr.ubo, 0, &read_range, (void**)&mapped_ubo);
*mapped_ubo = d3d12->hdr.ubo_values;
D3D12Unmap(d3d12->hdr.ubo, 0, NULL);
if(d3d12->shader_preset)
{
@@ -1903,17 +1889,9 @@ static void d3d12_set_hdr_paper_white_nits(void* data, float paper_white_nits)
static void d3d12_set_hdr_expand_gamut(void* data, bool expand_gamut)
{
D3D12_RANGE read_range;
dxgi_hdr_uniform_t *mapped_ubo = NULL;
d3d12_video_t *d3d12 = (d3d12_video_t*)data;
d3d12->hdr.ubo_values.expand_gamut = expand_gamut ? 1.0f : 0.0f;
read_range.Begin = 0;
read_range.End = 0;
D3D12Map(d3d12->hdr.ubo, 0, &read_range, (void**)&mapped_ubo);
*mapped_ubo = d3d12->hdr.ubo_values;
D3D12Unmap(d3d12->hdr.ubo, 0, NULL);
if(d3d12->shader_preset)
{
@@ -1926,17 +1904,9 @@ static void d3d12_set_hdr_expand_gamut(void* data, bool expand_gamut)
static void d3d12_set_hdr_scanlines(void* data, bool scanlines)
{
D3D12_RANGE read_range;
dxgi_hdr_uniform_t *mapped_ubo = NULL;
d3d12_video_t *d3d12 = (d3d12_video_t*)data;
d3d12->hdr.ubo_values.scanlines = scanlines ? 1.0f : 0.0f;
read_range.Begin = 0;
read_range.End = 0;
D3D12Map(d3d12->hdr.ubo, 0, &read_range, (void**)&mapped_ubo);
*mapped_ubo = d3d12->hdr.ubo_values;
D3D12Unmap(d3d12->hdr.ubo, 0, NULL);
if(d3d12->shader_preset)
{
@@ -1949,17 +1919,9 @@ static void d3d12_set_hdr_scanlines(void* data, bool scanlines)
static void d3d12_set_hdr_subpixel_layout(void* data, unsigned subpixel_layout)
{
D3D12_RANGE read_range;
dxgi_hdr_uniform_t *mapped_ubo = NULL;
d3d12_video_t *d3d12 = (d3d12_video_t*)data;
d3d12->hdr.ubo_values.subpixel_layout = subpixel_layout;
read_range.Begin = 0;
read_range.End = 0;
D3D12Map(d3d12->hdr.ubo, 0, &read_range, (void**)&mapped_ubo);
*mapped_ubo = d3d12->hdr.ubo_values;
D3D12Unmap(d3d12->hdr.ubo, 0, NULL);
if(d3d12->shader_preset)
{
@@ -1972,16 +1934,7 @@ static void d3d12_set_hdr_subpixel_layout(void* data, unsigned subpixel_layout)
static void d3d12_set_hdr_inverse_tonemap(d3d12_video_t* d3d12, bool inverse_tonemap)
{
D3D12_RANGE read_range;
dxgi_hdr_uniform_t *mapped_ubo = NULL;
d3d12->hdr.ubo_values.inverse_tonemap = inverse_tonemap ? 1.0f : 0.0f;
read_range.Begin = 0;
read_range.End = 0;
D3D12Map(d3d12->hdr.ubo, 0, &read_range, (void**)&mapped_ubo);
*mapped_ubo = d3d12->hdr.ubo_values;
D3D12Unmap(d3d12->hdr.ubo, 0, NULL);
if(d3d12->shader_preset)
{
@@ -1994,16 +1947,7 @@ static void d3d12_set_hdr_inverse_tonemap(d3d12_video_t* d3d12, bool inverse_ton
static void d3d12_set_hdr10(d3d12_video_t* d3d12, bool hdr10)
{
D3D12_RANGE read_range;
dxgi_hdr_uniform_t *mapped_ubo = NULL;
d3d12->hdr.ubo_values.hdr10 = hdr10 ? 1.0f : 0.0f;
read_range.Begin = 0;
read_range.End = 0;
D3D12Map(d3d12->hdr.ubo, 0, &read_range, (void**)&mapped_ubo);
*mapped_ubo = d3d12->hdr.ubo_values;
D3D12Unmap(d3d12->hdr.ubo, 0, NULL);
if(d3d12->shader_preset)
{
@@ -2461,7 +2405,7 @@ static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12)
settings_t * settings = config_get_ptr();
D3D12_GRAPHICS_PIPELINE_STATE_DESC desc = { d3d12->desc.rootSignature };
desc.BlendState.RenderTarget[0] = d3d12_blend_disable_desc;
desc.BlendState.RenderTarget[0] = d3d12_blend_enable_desc;
#ifdef HAVE_DXGI_HDR
desc.RTVFormats[0] = DXGI_FORMAT_R10G10B10A2_UNORM;
@@ -2492,6 +2436,12 @@ static bool d3d12_gfx_init_pipelines(d3d12_video_t* d3d12)
d3d12->device, vs_code, ps_code, NULL, &desc,
&d3d12->pipes[VIDEO_SHADER_STOCK_HDR]);
desc.BlendState.RenderTarget[0] = d3d12_blend_disable_desc;
d3d12_init_pipeline(
d3d12->device, vs_code, ps_code, NULL, &desc,
&d3d12->pipes[VIDEO_SHADER_STOCK_NOBLEND_HDR]);
Release(vs_code);
Release(ps_code);
vs_code = NULL;
@@ -2777,6 +2727,7 @@ static void d3d12_gfx_free(void* data)
#ifdef HAVE_DXGI_HDR
Release(d3d12->hdr.ubo);
Release(d3d12->hdr.ubo_post);
#endif
Release(d3d12->frame.ubo);
@@ -3536,13 +3487,16 @@ static void *d3d12_gfx_init(const video_info_t* video,
}
#ifdef HAVE_DXGI_HDR
d3d12->hdr.ubo_view.SizeInBytes = sizeof(dxgi_hdr_uniform_t);
d3d12->hdr.ubo_view.BufferLocation =
d3d12->hdr.ubo_view.SizeInBytes = sizeof(dxgi_hdr_uniform_t);
d3d12->hdr.ubo_view.BufferLocation =
d3d12_create_buffer(d3d12->device, d3d12->hdr.ubo_view.SizeInBytes, &d3d12->hdr.ubo);
d3d12->hdr.ubo_post_view.SizeInBytes = sizeof(dxgi_hdr_uniform_t);
d3d12->hdr.ubo_post_view.BufferLocation =
d3d12_create_buffer(d3d12->device, d3d12->hdr.ubo_post_view.SizeInBytes, &d3d12->hdr.ubo_post);
d3d12->hdr.ubo_values.mvp = d3d12->mvp_no_rot;
d3d12->hdr.ubo_values.max_nits = settings->floats.video_hdr_max_nits;
d3d12->hdr.ubo_values.paper_white_nits = settings->floats.video_hdr_paper_white_nits;
d3d12->hdr.ubo_values.mvp = d3d12->mvp_no_rot;
d3d12->hdr.ubo_values.max_nits = settings->floats.video_hdr_max_nits;
d3d12->hdr.ubo_values.paper_white_nits = settings->floats.video_hdr_paper_white_nits;
d3d12->hdr.ubo_values.source_size.width = 0.0f;
d3d12->hdr.ubo_values.source_size.height = 0.0f;
@@ -3553,8 +3507,8 @@ static void *d3d12_gfx_init(const video_info_t* video,
d3d12->hdr.ubo_values.scanlines = settings->bools.video_hdr_scanlines;
d3d12->hdr.ubo_values.expand_gamut = settings->bools.video_hdr_expand_gamut;
d3d12->hdr.ubo_values.inverse_tonemap = 1.0f; /* Use this to turn on/off the inverse tonemap */
d3d12->hdr.ubo_values.hdr10 = 1.0f; /* Use this to turn on/off the hdr10 */
d3d12->hdr.ubo_values.inverse_tonemap = 1.0f; /* Use this to turn on/off the inverse tonemap */
d3d12->hdr.ubo_values.hdr10 = 1.0f; /* Use this to turn on/off the hdr10 */
{
dxgi_hdr_uniform_t* mapped_ubo;
@@ -3565,6 +3519,16 @@ static void *d3d12_gfx_init(const video_info_t* video,
*mapped_ubo = d3d12->hdr.ubo_values;
D3D12Unmap(d3d12->hdr.ubo, 0, NULL);
}
{
dxgi_hdr_uniform_t* mapped_ubo;
D3D12_RANGE read_range;
read_range.Begin = 0;
read_range.End = 0;
D3D12Map(d3d12->hdr.ubo_post, 0, &read_range, (void**)&mapped_ubo);
*mapped_ubo = d3d12->hdr.ubo_values;
D3D12Unmap(d3d12->hdr.ubo_post, 0, NULL);
}
#endif
matrix_4x4_identity(d3d12->identity);
@@ -3868,7 +3832,6 @@ static bool d3d12_gfx_frame(
bool d3d12_hdr_enable = false;
bool video_hdr_enable = video_info->hdr_enable;
DXGI_FORMAT back_buffer_format = d3d12->shader_preset && d3d12->shader_preset->passes ? glslang_format_to_dxgi(d3d12->pass[d3d12->shader_preset->passes - 1].semantics.format) : d3d12->chain.formats[d3d12->chain.bit_depth];
bool use_back_buffer = back_buffer_format != d3d12->chain.formats[d3d12->chain.bit_depth];
#endif
D3D12GraphicsCommandList cmd = d3d12->queue.cmd;
@@ -4420,13 +4383,10 @@ static bool d3d12_gfx_frame(
d3d12->desc.rootSignature);
#ifdef HAVE_DXGI_HDR
if ((d3d12->flags & D3D12_ST_FLAG_HDR_ENABLE)
&& !use_back_buffer)
if (d3d12->flags & D3D12_ST_FLAG_HDR_ENABLE)
{
cmd->lpVtbl->SetPipelineState(cmd, d3d12->pipes[VIDEO_SHADER_STOCK_HDR]);
cmd->lpVtbl->SetPipelineState(cmd, d3d12->pipes[VIDEO_SHADER_STOCK_NOBLEND_HDR]);
if(d3d12->hdr.ubo_values.source_size.width != width || d3d12->hdr.ubo_values.source_size.height != height ||
d3d12->hdr.ubo_values.output_size.width != d3d12->frame.output_size.x || d3d12->hdr.ubo_values.output_size.height != d3d12->frame.output_size.y)
{
d3d12->hdr.ubo_values.source_size.width = width;
d3d12->hdr.ubo_values.source_size.height = height;
@@ -4434,6 +4394,9 @@ static bool d3d12_gfx_frame(
d3d12->hdr.ubo_values.output_size.width = d3d12->frame.output_size.x;
d3d12->hdr.ubo_values.output_size.height = d3d12->frame.output_size.y;
settings_t* settings = config_get_ptr();
d3d12->hdr.ubo_values.scanlines = settings->bools.video_hdr_scanlines ? 1.0f : 0.0f;
{
dxgi_hdr_uniform_t* mapped_ubo;
D3D12_RANGE read_range;
@@ -4443,11 +4406,11 @@ static bool d3d12_gfx_frame(
*mapped_ubo = d3d12->hdr.ubo_values;
D3D12Unmap(d3d12->hdr.ubo, 0, NULL);
}
}
cmd->lpVtbl->SetGraphicsRootConstantBufferView(
cmd, ROOT_ID_UBO,
d3d12->hdr.ubo_view.BufferLocation);
cmd->lpVtbl->SetGraphicsRootConstantBufferView(
cmd, ROOT_ID_UBO,
d3d12->hdr.ubo_view.BufferLocation);
}
}
else
#endif
@@ -4471,33 +4434,6 @@ static bool d3d12_gfx_frame(
d3d12->chain.frame_index = DXGIGetCurrentBackBufferIndex(
d3d12->chain.handle);
#ifdef HAVE_DXGI_HDR
if ((d3d12->flags & D3D12_ST_FLAG_HDR_ENABLE) && use_back_buffer)
{
D3D12_RESOURCE_TRANSITION(
cmd,
d3d12->chain.back_buffer.handle,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
D3D12_RESOURCE_STATE_RENDER_TARGET);
cmd->lpVtbl->OMSetRenderTargets(
cmd, 1,
&d3d12->chain.back_buffer.rt_view,
FALSE, NULL);
/* TODO/FIXME - fix this warning that shows up with Debug logging
* EXECUTIONWARNING #820: CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE
* We need to set clear value during resource creation to NULL for
* D3D12_RESOURCE_DIMENSION_BUFFER, yet we get spammed with this
* warning
*/
cmd->lpVtbl->ClearRenderTargetView(
cmd,
d3d12->chain.back_buffer.rt_view,
d3d12->chain.clearcolor,
0, NULL);
}
else
#endif
{
D3D12_RESOURCE_TRANSITION(
cmd,
@@ -4549,6 +4485,36 @@ static bool d3d12_gfx_frame(
cmd->lpVtbl->SetPipelineState(cmd, d3d12->pipes[VIDEO_SHADER_STOCK_BLEND]);
cmd->lpVtbl->SetGraphicsRootSignature(cmd, d3d12->desc.rootSignature);
#ifdef HAVE_DXGI_HDR
if ((d3d12->flags & D3D12_ST_FLAG_HDR_ENABLE) &&
(d3d12->flags & D3D12_ST_FLAG_MENU_ENABLE))
{
D3D12_RESOURCE_TRANSITION(
cmd,
d3d12->chain.back_buffer.handle,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
D3D12_RESOURCE_STATE_RENDER_TARGET);
cmd->lpVtbl->OMSetRenderTargets(
cmd, 1,
&d3d12->chain.back_buffer.rt_view,
FALSE, NULL);
/* TODO/FIXME - fix this warning that shows up with Debug logging
* EXECUTIONWARNING #820: CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE
* We need to set clear value during resource creation to NULL for
* D3D12_RESOURCE_DIMENSION_BUFFER, yet we get spammed with this
* warning
*/
float clear_colour[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
cmd->lpVtbl->ClearRenderTargetView(
cmd,
d3d12->chain.back_buffer.rt_view,
clear_colour,
0, NULL);
}
#endif
if ( (d3d12->flags & D3D12_ST_FLAG_MENU_ENABLE)
&& d3d12->menu.texture.handle)
{
@@ -4638,7 +4604,8 @@ static bool d3d12_gfx_frame(
#ifdef HAVE_DXGI_HDR
/* 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) &&
(d3d12->flags & D3D12_ST_FLAG_MENU_ENABLE))
{
D3D12_RESOURCE_TRANSITION(
cmd,
@@ -4656,17 +4623,31 @@ static bool d3d12_gfx_frame(
cmd->lpVtbl->OMSetRenderTargets(
cmd, 1, &d3d12->chain.desc_handles[d3d12->chain.frame_index],
FALSE, NULL);
cmd->lpVtbl->ClearRenderTargetView(
cmd, d3d12->chain.desc_handles[d3d12->chain.frame_index],
d3d12->chain.clearcolor, 0, NULL);
cmd->lpVtbl->SetGraphicsRootSignature(cmd, d3d12->desc.rootSignature);
cmd->lpVtbl->SetGraphicsRootDescriptorTable(cmd, ROOT_ID_TEXTURE_T,
d3d12->chain.back_buffer.gpu_descriptor[0]);
cmd->lpVtbl->SetGraphicsRootDescriptorTable(cmd, ROOT_ID_SAMPLER_T,
d3d12->samplers[RARCH_FILTER_UNSPEC][RARCH_WRAP_DEFAULT]);
cmd->lpVtbl->SetGraphicsRootConstantBufferView(cmd, ROOT_ID_UBO,
d3d12->hdr.ubo_view.BufferLocation);
{
d3d12->hdr.ubo_values.scanlines = false;
{
dxgi_hdr_uniform_t* mapped_ubo;
D3D12_RANGE read_range;
read_range.Begin = 0;
read_range.End = 0;
D3D12Map(d3d12->hdr.ubo_post, 0, &read_range, (void**)&mapped_ubo);
*mapped_ubo = d3d12->hdr.ubo_values;
D3D12Unmap(d3d12->hdr.ubo_post, 0, NULL);
}
cmd->lpVtbl->SetGraphicsRootConstantBufferView(
cmd, ROOT_ID_UBO,
d3d12->hdr.ubo_post_view.BufferLocation);
}
cmd->lpVtbl->IASetVertexBuffers(cmd, 0, 1, &d3d12->frame.vbo_view);
cmd->lpVtbl->IASetPrimitiveTopology(cmd, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
-1
View File
@@ -89,7 +89,6 @@ static const float k_crt_green_scanline_max = 0.70f;
static const float k_crt_green_scanline_attack = 0.30f;
static const float k_crt_blue_scanline_min = 0.45f;
static const float k_crt_blue_scanline_max = 0.70f;
static const float k_crt_blue_scanline_attack = 0.30f;
static const float k_crt_red_beam_sharpness = 1.30f;
+118 -45
View File
@@ -179,6 +179,7 @@ typedef struct vk
struct vk_image *backbuffer;
#ifdef VULKAN_HDR_SWAPCHAIN
VkRenderPass readback_render_pass;
struct vk_image main_buffer;
struct vk_image readback_image;
#endif /* VULKAN_HDR_SWAPCHAIN */
@@ -198,6 +199,7 @@ typedef struct vk
math_matrix_4x4 mvp, mvp_no_rot, mvp_menu; /* float alignment */
VkViewport vk_vp;
VkRenderPass render_pass;
VkRenderPass keep_render_pass;
struct video_viewport vp;
float translate_x;
float translate_y;
@@ -230,6 +232,7 @@ typedef struct vk
VkPipeline font;
VkPipeline rgb565_to_rgba8888;
#ifdef VULKAN_HDR_SWAPCHAIN
VkPipeline hdr;
VkPipeline hdr_to_sdr; /* for readback */
#endif /* VULKAN_HDR_SWAPCHAIN */
VkDescriptorSetLayout set_layout;
@@ -246,11 +249,13 @@ typedef struct vk
#ifdef VULKAN_HDR_SWAPCHAIN
struct
{
struct vk_buffer ubo;
float max_output_nits;
float min_output_nits;
float max_cll;
float max_fall;
vulkan_hdr_uniform_t ubo_values;
struct vk_buffer ubo;
struct vk_buffer ubo_post;
float max_output_nits;
float min_output_nits;
float max_cll;
float max_fall;
} hdr;
#endif /* VULKAN_HDR_SWAPCHAIN */
@@ -2241,6 +2246,12 @@ static void vulkan_init_render_pass(
vkCreateRenderPass(vk->context->device,
&rp_info, NULL, &vk->render_pass);
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
attachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
vkCreateRenderPass(vk->context->device,
&rp_info, NULL, &vk->keep_render_pass);
}
@@ -2417,6 +2428,9 @@ static void vulkan_init_pipeline_layout(
static void vulkan_init_pipelines(vk_t *vk)
{
#ifdef VULKAN_HDR_SWAPCHAIN
static const uint32_t hdr_frag[] =
#include "vulkan_shaders/hdr.frag.inc"
;
static const uint32_t hdr_tonemap_frag[] =
#include "vulkan_shaders/hdr_tonemap.frag.inc"
;
@@ -2641,9 +2655,33 @@ static void vulkan_init_pipelines(vk_t *vk)
#ifdef VULKAN_HDR_SWAPCHAIN
if (vk->context->flags & VK_CTX_FLAG_HDR_SUPPORT)
{
blend_attachment.blendEnable = VK_FALSE;
/* HDR pipeline. */
blend_attachment.blendEnable = VK_TRUE;
/* HDR pipeline. */
module_info.codeSize = sizeof(hdr_frag);
module_info.pCode = hdr_frag;
shader_stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
shader_stages[1].pName = "main";
vkCreateShaderModule(vk->context->device,
&module_info, NULL, &shader_stages[1].module);
vkCreateGraphicsPipelines(vk->context->device, vk->pipelines.cache,
1, &pipe, NULL, &vk->pipelines.hdr);
/* Build display hdr pipelines. */
for (i = 4; i < 6; i++)
{
input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
vkCreateGraphicsPipelines(vk->context->device, vk->pipelines.cache,
1, &pipe, NULL, &vk->display.pipelines[i]);
}
vkDestroyShaderModule(vk->context->device, shader_stages[1].module, NULL);
/* HDR->SDR tonemapping readback pipeline. */
blend_attachment.blendEnable = VK_FALSE;
module_info.codeSize = sizeof(hdr_tonemap_frag);
module_info.pCode = hdr_tonemap_frag;
shader_stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
@@ -2948,6 +2986,8 @@ static void vulkan_deinit_pipelines(vk_t *vk)
#ifdef VULKAN_HDR_SWAPCHAIN
if (vk->context->flags & VK_CTX_FLAG_HDR_SUPPORT)
{
vkDestroyPipeline(vk->context->device,
vk->pipelines.hdr, NULL);
vkDestroyPipeline(vk->context->device,
vk->pipelines.hdr_to_sdr, NULL);
}
@@ -2984,10 +3024,9 @@ static void vulkan_deinit_hdr_readback_render_pass(vk_t *vk)
static void vulkan_set_hdr_max_nits(void* data, float max_nits)
{
vk_t *vk = (vk_t*)data;
vulkan_hdr_uniform_t* mapped_ubo = (vulkan_hdr_uniform_t*)vk->hdr.ubo.mapped;
vk->hdr.max_output_nits = max_nits;
mapped_ubo->max_nits = max_nits;
vk->hdr.ubo_values.max_nits = max_nits;
if(vk->filter_chain)
{
@@ -3004,9 +3043,8 @@ static void vulkan_set_hdr_max_nits(void* data, float max_nits)
static void vulkan_set_hdr_paper_white_nits(void* data, float paper_white_nits)
{
vk_t *vk = (vk_t*)data;
vulkan_hdr_uniform_t* mapped_ubo = (vulkan_hdr_uniform_t*)vk->hdr.ubo.mapped;
mapped_ubo->paper_white_nits = paper_white_nits;
vk->hdr.ubo_values.paper_white_nits = paper_white_nits;
if(vk->filter_chain)
{
@@ -3023,9 +3061,8 @@ static void vulkan_set_hdr_paper_white_nits(void* data, float paper_white_nits)
static void vulkan_set_hdr_expand_gamut(void* data, bool expand_gamut)
{
vk_t *vk = (vk_t*)data;
vulkan_hdr_uniform_t* mapped_ubo = (vulkan_hdr_uniform_t*)vk->hdr.ubo.mapped;
mapped_ubo->expand_gamut = expand_gamut ? 1.0f : 0.0f;
vk->hdr.ubo_values.expand_gamut = expand_gamut ? 1.0f : 0.0f;
if(vk->filter_chain)
{
@@ -3073,9 +3110,7 @@ static void vulkan_set_hdr_subpixel_layout(void* data, unsigned subpixel_layout)
static void vulkan_set_hdr_inverse_tonemap(vk_t* vk, vulkan_filter_chain_t* filter_chain, bool inverse_tonemap)
{
vulkan_hdr_uniform_t* mapped_ubo = (vulkan_hdr_uniform_t*)vk->hdr.ubo.mapped;
mapped_ubo->inverse_tonemap = inverse_tonemap ? 1.0f : 0.0f;
vk->hdr.ubo_values.inverse_tonemap = inverse_tonemap ? 1.0f : 0.0f;
vulkan_filter_chain_set_inverse_tonemap(
filter_chain, inverse_tonemap ? 1.0f : 0.0f);
@@ -3083,9 +3118,7 @@ static void vulkan_set_hdr_inverse_tonemap(vk_t* vk, vulkan_filter_chain_t* filt
static void vulkan_set_hdr10(vk_t* vk, vulkan_filter_chain_t* filter_chain, bool hdr10)
{
vulkan_hdr_uniform_t* mapped_ubo = (vulkan_hdr_uniform_t*)vk->hdr.ubo.mapped;
mapped_ubo->hdr10 = hdr10 ? 1.0f : 0.0f;
vk->hdr.ubo_values.hdr10 = hdr10 ? 1.0f : 0.0f;
vulkan_filter_chain_set_hdr10(
filter_chain, hdr10 ? 1.0f : 0.0f);
@@ -3445,6 +3478,8 @@ static void vulkan_free(void *data)
if (vk->context->flags & VK_CTX_FLAG_HDR_SUPPORT)
{
vulkan_destroy_buffer(vk->context->device, &vk->hdr.ubo);
vulkan_destroy_buffer(vk->context->device, &vk->hdr.ubo_post);
vulkan_destroy_hdr_buffer(vk->context->device, &vk->main_buffer);
vulkan_destroy_hdr_buffer(vk->context->device, &vk->readback_image);
vulkan_deinit_hdr_readback_render_pass(vk);
video_driver_unset_hdr_support();
@@ -3777,15 +3812,17 @@ static void *vulkan_init(const video_info_t *video,
#ifdef VULKAN_HDR_SWAPCHAIN
vk->hdr.ubo = vulkan_create_buffer(vk->context, sizeof(vulkan_hdr_uniform_t), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
vk->hdr.ubo_post = vulkan_create_buffer(vk->context, sizeof(vulkan_hdr_uniform_t), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
mapped_ubo = (vulkan_hdr_uniform_t*)vk->hdr.ubo.mapped;
vk->hdr.ubo_values.mvp = vk->mvp_no_rot;
vk->hdr.ubo_values.max_nits = settings->floats.video_hdr_max_nits;
vk->hdr.ubo_values.paper_white_nits = settings->floats.video_hdr_paper_white_nits;
vk->hdr.ubo_values.expand_gamut = settings->bools.video_hdr_expand_gamut;
vk->hdr.ubo_values.inverse_tonemap = 1.0f; /* Use this to turn on/off the inverse tonemap */
vk->hdr.ubo_values.hdr10 = 1.0f; /* Use this to turn on/off the hdr10 */
mapped_ubo->mvp = vk->mvp_no_rot;
mapped_ubo->max_nits = settings->floats.video_hdr_max_nits;
mapped_ubo->paper_white_nits = settings->floats.video_hdr_paper_white_nits;
mapped_ubo->expand_gamut = settings->bools.video_hdr_expand_gamut;
mapped_ubo->inverse_tonemap = 1.0f; /* Use this to turn on/off the inverse tonemap */
mapped_ubo->hdr10 = 1.0f; /* Use this to turn on/off the hdr10 */
#endif /* VULKAN_HDR_SWAPCHAIN */
vulkan_init_hw_render(vk);
@@ -4537,13 +4574,12 @@ static void vulkan_init_render_target(struct vk_image* image, uint32_t width, ui
vkCreateFramebuffer(ctx->device, &info, NULL, &image->framebuffer);
}
static void vulkan_run_hdr_pipeline(VkPipeline pipeline, VkRenderPass render_pass, const struct vk_image* source_image, struct vk_image* render_target, vk_t* vk)
static void vulkan_run_hdr_pipeline(VkPipeline pipeline, VkRenderPass render_pass, const struct vk_image* source_image, struct vk_image* render_target, vk_t* vk, struct vk_buffer* ubo)
{
vulkan_hdr_uniform_t* mapped_ubo = (vulkan_hdr_uniform_t*)vk->hdr.ubo.mapped;
VkRenderPassBeginInfo rp_info;
VkClearValue clear_color;
mapped_ubo->mvp = vk->mvp_no_rot;
vk->hdr.ubo_values.mvp = vk->mvp_no_rot;
rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
rp_info.pNext = NULL;
@@ -4582,12 +4618,16 @@ static void vulkan_run_hdr_pipeline(VkPipeline pipeline, VkRenderPass render_pas
vk->context->device,
&vk->chain->descriptor_manager);
vulkan_hdr_uniform_t* mapped_ubo = (vulkan_hdr_uniform_t*)ubo->mapped;
*mapped_ubo = vk->hdr.ubo_values;
VULKAN_SET_UNIFORM_BUFFER(vk->context->device,
set,
0,
vk->hdr.ubo.buffer,
ubo->buffer,
0,
vk->hdr.ubo.size);
ubo->size);
image_info.sampler = vk->samplers.nearest;
image_info.imageView = source_image->view;
@@ -4699,7 +4739,6 @@ static bool vulkan_frame(void *data, const void *frame,
unsigned swapchain_index =
vk->context->current_swapchain_index;
bool overlay_behind_menu = video_info->overlay_behind_menu;
bool use_main_buffer = true;
/* Fast toggle shader filter chain logic */
filter_chain = vk->filter_chain;
@@ -4718,12 +4757,6 @@ static bool vulkan_frame(void *data, const void *frame,
if (!filter_chain && vk->filter_chain_default)
filter_chain = vk->filter_chain_default;
#ifdef VULKAN_HDR_SWAPCHAIN
use_main_buffer =
( vk->context->flags & VK_CTX_FLAG_HDR_ENABLE)
&& (!filter_chain || !vulkan_filter_chain_emits_hdr10(filter_chain));
#endif /* VULKAN_HDR_SWAPCHAIN */
/* Bookkeeping on start of frame. */
struct vk_per_frame *chain = &vk->swapchain[frame_index];
struct vk_image *backbuffer = &vk->backbuffers[swapchain_index];
@@ -5041,6 +5074,22 @@ static bool vulkan_frame(void *data, const void *frame,
(vulkan_filter_chain_t*)filter_chain, vk->cmd,
&vk->vk_vp, vk->mvp.data);
#ifdef VULKAN_HDR_SWAPCHAIN
if ((vk->context->flags & VK_CTX_FLAG_HDR_ENABLE) &&
(vk->flags & VK_FLAG_MENU_ENABLE) &&
(!filter_chain || !vulkan_filter_chain_emits_hdr10(filter_chain)))
{
vkCmdEndRenderPass(vk->cmd);
backbuffer = &vk->main_buffer;
rp_info.framebuffer = backbuffer->framebuffer;
/* Begin render pass and set up viewport */
vkCmdBeginRenderPass(vk->cmd, &rp_info, VK_SUBPASS_CONTENTS_INLINE);
}
#endif /* VULKAN_HDR_SWAPCHAIN */
#ifdef HAVE_OVERLAY
if ((vk->flags & VK_FLAG_OVERLAY_ENABLE) && overlay_behind_menu)
vulkan_render_overlay(vk, video_width, video_height);
@@ -5107,6 +5156,24 @@ static bool vulkan_frame(void *data, const void *frame,
/* End the render pass. We're done rendering to backbuffer now. */
vkCmdEndRenderPass(vk->cmd);
#ifdef VULKAN_HDR_SWAPCHAIN
/* Copy over back buffer to swap chain render targets */
if ((vk->context->flags & VK_CTX_FLAG_HDR_ENABLE) &&
(vk->flags & VK_FLAG_MENU_ENABLE) &&
(!filter_chain || !vulkan_filter_chain_emits_hdr10(filter_chain)))
{
backbuffer = &vk->backbuffers[swapchain_index];
/* Prepare source buffer for reading */
VULKAN_IMAGE_LAYOUT_TRANSITION(vk->cmd, vk->main_buffer.image,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
vulkan_run_hdr_pipeline(vk->pipelines.hdr, vk->keep_render_pass, &vk->main_buffer, backbuffer, vk, &vk->hdr.ubo);
}
#endif /* VULKAN_HDR_SWAPCHAIN */
}
/* End the filter chain frame.
@@ -5124,15 +5191,17 @@ static bool vulkan_frame(void *data, const void *frame,
{
VkImageLayout backbuffer_layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
#ifdef VULKAN_HDR_SWAPCHAIN
if (use_main_buffer)
{
backbuffer = &vk->backbuffers[swapchain_index];
}
struct vk_image* readback_source = backbuffer;
if (vk->context->flags & VK_CTX_FLAG_HDR_ENABLE)
if((vk->context->flags & VK_CTX_FLAG_HDR_ENABLE) &&
(!filter_chain || !vulkan_filter_chain_emits_hdr10(filter_chain)))
{
if (!use_main_buffer)
if (vk->flags & VK_FLAG_MENU_ENABLE)
{
/* Read directly from sdr main buffer instead of tonemapping */
readback_source = &vk->main_buffer;
/* No need to transition layout, it's already read-only optimal */
}
else
{
/* Prepare backbuffer for reading */
backbuffer_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
@@ -5142,7 +5211,7 @@ static bool vulkan_frame(void *data, const void *frame,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
}
vulkan_run_hdr_pipeline(vk->pipelines.hdr_to_sdr, vk->readback_render_pass, readback_source, &vk->readback_image, vk);
vulkan_run_hdr_pipeline(vk->pipelines.hdr_to_sdr, vk->readback_render_pass, readback_source, &vk->readback_image, vk, &vk->hdr.ubo);
readback_source = &vk->readback_image;
}
#endif /* VULKAN_HDR_SWAPCHAIN */
@@ -5326,6 +5395,7 @@ static bool vulkan_frame(void *data, const void *frame,
#ifdef HAVE_THREADS
slock_unlock(vk->context->queue_lock);
#endif
vulkan_destroy_hdr_buffer(vk->context->device, &vk->main_buffer);
vulkan_destroy_hdr_buffer(vk->context->device, &vk->readback_image);
}
else
@@ -5343,6 +5413,9 @@ static bool vulkan_frame(void *data, const void *frame,
#ifdef VULKAN_HDR_SWAPCHAIN
if (vk->context->flags & VK_CTX_FLAG_HDR_ENABLE)
{
/* Create intermediary buffer to render filter chain output to */
vulkan_init_render_target(&vk->main_buffer, video_width, video_height,
VK_FORMAT_B8G8R8A8_UNORM, vk->render_pass, vk->context);
/* Create image for readback target in bgra8 format */
vulkan_init_render_target(&vk->readback_image, video_width, video_height,
VK_FORMAT_B8G8R8A8_UNORM, vk->readback_render_pass, vk->context);
+10 -9
View File
@@ -51,15 +51,16 @@
#define MEASURE_FRAME_TIME_SAMPLES_COUNT (2 * 1024)
#define VIDEO_SHADER_STOCK_BLEND (GFX_MAX_SHADERS - 1)
#define VIDEO_SHADER_MENU (GFX_MAX_SHADERS - 2)
#define VIDEO_SHADER_MENU_2 (GFX_MAX_SHADERS - 3)
#define VIDEO_SHADER_MENU_3 (GFX_MAX_SHADERS - 4)
#define VIDEO_SHADER_MENU_4 (GFX_MAX_SHADERS - 5)
#define VIDEO_SHADER_MENU_5 (GFX_MAX_SHADERS - 6)
#define VIDEO_SHADER_MENU_6 (GFX_MAX_SHADERS - 7)
#define VIDEO_SHADER_STOCK_HDR (GFX_MAX_SHADERS - 8)
#define VIDEO_SHADER_STOCK_NOBLEND (GFX_MAX_SHADERS - 9)
#define VIDEO_SHADER_STOCK_BLEND (GFX_MAX_SHADERS - 1)
#define VIDEO_SHADER_MENU (GFX_MAX_SHADERS - 2)
#define VIDEO_SHADER_MENU_2 (GFX_MAX_SHADERS - 3)
#define VIDEO_SHADER_MENU_3 (GFX_MAX_SHADERS - 4)
#define VIDEO_SHADER_MENU_4 (GFX_MAX_SHADERS - 5)
#define VIDEO_SHADER_MENU_5 (GFX_MAX_SHADERS - 6)
#define VIDEO_SHADER_MENU_6 (GFX_MAX_SHADERS - 7)
#define VIDEO_SHADER_STOCK_HDR (GFX_MAX_SHADERS - 8)
#define VIDEO_SHADER_STOCK_NOBLEND_HDR (GFX_MAX_SHADERS - 9)
#define VIDEO_SHADER_STOCK_NOBLEND (GFX_MAX_SHADERS - 10)
#if defined(_XBOX360)
#define DEFAULT_SHADER_TYPE RARCH_SHADER_HLSL