mirror of
https://github.com/libretro/RetroArch.git
synced 2025-02-21 10:11:18 +00:00
Add HDR support for D3D12 (rebased PR from MajorPainTheCactus) (#12917)
* Add HDR support
* Attempt to fix Mingw build and Metal builds
* (D3D12) Fix relative header includes
* Add missing hdr_sm5.hlsl.h
* (d3d12_common.c) Some C89 build fixes
* Fix MSVC build
* - Attempt to fix build on mingw/msys unix with dirty hack
- Fix shader compilation of hdr_sm5.hlsl.h on MSVC/Visual Studio -
the define was seen as an error and was causing the first pipeline
to error out
- Make sure we manually set handle of backBuffer to NULL
* Moving the release of the texture above the freeing of desc.srv_heap
and desc.rtv_heap solves the hard crashes on teardown/setup in RA -
it was crashing hard in d3d12_release_texture before
* Add HAVE_D3D12_HDR ifdef - needs to be disabled for WinRT for now
because of several things that are Windows desktop-specific right now
(GetWindowRect)
* Add dirty GUID hack - should work for both mingw/msys on Windows/Linux
as well as MSVC/Visual Studio (hopefully)
* Change HAVE_D3D12_HDR to HAVE_DXGI_HDR
* Move away from camelcase named variables
* Fix RARCH_ERR logs - they need a newline at the end
* d3d12_check_display_hdr_support - make it return a bool on return
and set d3d12->hdr.support and d3d12->hdr.enable outside of the
function
* (DXGI) Remove D3D12 dependencies from dxgi_check_display_hdr_support and
move it to dxgi_common.c instead
* (DXGI) move d3d12_swapchain_color_space over to dxgi_common.c and
rename it dxgi_swapchain_color_space
* (DXGI) move d3d12_set_hdr_metadata to dxgi_common.c and
rename it dxgi_set_hdr_metadata
* (DXGI) dxgi_check_display_hdr_support - better error handling?
* Fix typo
* Remove video_force_resolution
* (D3D12) Address TODO/FIXME
* (D3D12) Backport
c1b6c0bff2
- Fixed resource transition for present when HDR is off
Fixed cel shader displaying all black as blending was enabled when the hdr shader was being applied - turned off blending during this shader
* Move d3d12_hdr_uniform_t to dxgi_common.h and
rename it dxgi_hdr_uniform_t
* (D3D11) Add HDR support
* Add TODO/FIXME notes
* Cache hdr_enable in video_frame_info_t
* Update comment
This commit is contained in:
parent
868865c388
commit
7b9cbc08d7
297
.vscode/c_cpp_properties.json
vendored
297
.vscode/c_cpp_properties.json
vendored
@ -1,155 +1,156 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Mac",
|
||||
"includePath": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}",
|
||||
"${workspaceRoot}/libretro-common/include"
|
||||
],
|
||||
"defines": [],
|
||||
"intelliSenseMode": "clang-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}"
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Mac",
|
||||
"includePath": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}",
|
||||
"${workspaceRoot}/libretro-common/include"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
},
|
||||
"macFrameworkPath": [
|
||||
"/System/Library/Frameworks",
|
||||
"/Library/Frameworks"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}",
|
||||
"${workspaceFolder}/libretro-common/include",
|
||||
"${workspaceRoot}/libretro-common/include"
|
||||
],
|
||||
"defines": [],
|
||||
"intelliSenseMode": "clang-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}"
|
||||
"defines": [],
|
||||
"intelliSenseMode": "clang-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
},
|
||||
"macFrameworkPath": [
|
||||
"/System/Library/Frameworks",
|
||||
"/Library/Frameworks"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}",
|
||||
"${workspaceFolder}/libretro-common/include",
|
||||
"${workspaceRoot}/libretro-common/include"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Win32",
|
||||
"includePath": [
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/um",
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/ucrt",
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/shared",
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/winrt",
|
||||
"${workspaceRoot}",
|
||||
"${workspaceFolder}/libretro-common/include"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE"
|
||||
],
|
||||
"intelliSenseMode": "msvc-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/um",
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/ucrt",
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/shared",
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/winrt",
|
||||
"${workspaceRoot}"
|
||||
"defines": [],
|
||||
"intelliSenseMode": "clang-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Win32",
|
||||
"includePath": [
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/um",
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/ucrt",
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/shared",
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/winrt",
|
||||
"${workspaceRoot}",
|
||||
"${workspaceFolder}/libretro-common/include"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
},
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17"
|
||||
},
|
||||
{
|
||||
"name": "msys2-mingw32",
|
||||
"includePath": [
|
||||
"C:/msys64/mingw32/include",
|
||||
"C:/msys64/mingw32/i686-w64-mingw32/include",
|
||||
"${workspaceRoot}/libretro-common/include",
|
||||
"${workspaceRoot}/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE"
|
||||
],
|
||||
"intelliSenseMode": "msvc-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"C:/msys64/mingw32/include",
|
||||
"C:/msys64/mingw32/i686-w64-mingw32/include",
|
||||
"${workspaceRoot}/libretro-common/include",
|
||||
"${workspaceRoot}/include",
|
||||
"${workspaceRoot}"
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "msys2-mingw64",
|
||||
"includePath": [
|
||||
"C:/msys64/mingw64/include",
|
||||
"C:/msys64/mingw64/x86_64-w64-mingw32/include",
|
||||
"${workspaceRoot}/libretro-common/include",
|
||||
"${workspaceRoot}/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE"
|
||||
],
|
||||
"intelliSenseMode": "msvc-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"C:/msys64/mingw64/include",
|
||||
"C:/msys64/mingw64/x86_64-w64-mingw32/include",
|
||||
"${workspaceRoot}/libretro-common/include",
|
||||
"${workspaceRoot}/include",
|
||||
"${workspaceRoot}"
|
||||
"intelliSenseMode": "msvc-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/um",
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/ucrt",
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/shared",
|
||||
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/winrt",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
},
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17",
|
||||
"configurationProvider": "ms-vscode.makefile-tools"
|
||||
},
|
||||
{
|
||||
"name": "msys2-mingw32",
|
||||
"includePath": [
|
||||
"C:/msys64/mingw32/include",
|
||||
"C:/msys64/mingw32/i686-w64-mingw32/include",
|
||||
"${workspaceRoot}/libretro-common/include",
|
||||
"${workspaceRoot}/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Switch",
|
||||
"includePath": [
|
||||
"/opt/devkitpro/devkitA64/aarch64-none-elf/include",
|
||||
"/opt/devkitpro/devkitA64/lib/gcc/aarch64-none-elf/8.3.0/include",
|
||||
"/opt/devkitpro/libnx/include",
|
||||
"/opt/devkitpro/portlibs/switch/include",
|
||||
"/opt/devkitpro/portlibs/switch/include/freetype2",
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"_UNICODE",
|
||||
"__aarch64__",
|
||||
"__SWITCH__",
|
||||
"HAVE_LIBNX"
|
||||
],
|
||||
"windowsSdkVersion": "10.0.17763.0",
|
||||
"compilerPath": "/opt/devkitpro/devkitA64/bin/aarch64-none-elf-gcc",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++11",
|
||||
"intelliSenseMode": "gcc-x64"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE"
|
||||
],
|
||||
"intelliSenseMode": "msvc-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"C:/msys64/mingw32/include",
|
||||
"C:/msys64/mingw32/i686-w64-mingw32/include",
|
||||
"${workspaceRoot}/libretro-common/include",
|
||||
"${workspaceRoot}/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "msys2-mingw64",
|
||||
"includePath": [
|
||||
"C:/msys64/mingw64/include",
|
||||
"C:/msys64/mingw64/x86_64-w64-mingw32/include",
|
||||
"${workspaceRoot}/libretro-common/include",
|
||||
"${workspaceRoot}/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE"
|
||||
],
|
||||
"intelliSenseMode": "msvc-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"C:/msys64/mingw64/include",
|
||||
"C:/msys64/mingw64/x86_64-w64-mingw32/include",
|
||||
"${workspaceRoot}/libretro-common/include",
|
||||
"${workspaceRoot}/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"databaseFilename": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Switch",
|
||||
"includePath": [
|
||||
"/opt/devkitpro/devkitA64/aarch64-none-elf/include",
|
||||
"/opt/devkitpro/devkitA64/lib/gcc/aarch64-none-elf/8.3.0/include",
|
||||
"/opt/devkitpro/libnx/include",
|
||||
"/opt/devkitpro/portlibs/switch/include",
|
||||
"/opt/devkitpro/portlibs/switch/include/freetype2",
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"_UNICODE",
|
||||
"__aarch64__",
|
||||
"__SWITCH__",
|
||||
"HAVE_LIBNX"
|
||||
],
|
||||
"windowsSdkVersion": "10.0.17763.0",
|
||||
"compilerPath": "/opt/devkitpro/devkitA64/bin/aarch64-none-elf-gcc",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++11",
|
||||
"intelliSenseMode": "gcc-x64"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
15
config.def.h
15
config.def.h
@ -412,6 +412,21 @@
|
||||
#define DEFAULT_SHADER_ENABLE false
|
||||
#endif
|
||||
|
||||
/* Should we enable hdr when its supported*/
|
||||
#define DEFAULT_VIDEO_HDR_ENABLE false
|
||||
|
||||
/* The maximum nunmber of nits the actual display can show - needs to be calibrated */
|
||||
#define DEFAULT_VIDEO_HDR_MAX_NITS 1000.0f
|
||||
|
||||
/* The number of nits that paper white is at */
|
||||
#define DEFAULT_VIDEO_HDR_PAPER_WHITE_NITS 200.0f
|
||||
|
||||
/* The contrast setting for hdr used to calculate the display gamma by dividing gamma 2.2 by this value */
|
||||
#define DEFAULT_VIDEO_HDR_CONTRAST 1.0f
|
||||
|
||||
/* Should we expand the colour gamut when using hdr */
|
||||
#define DEFAULT_VIDEO_HDR_EXPAND_GAMUT true
|
||||
|
||||
/* When presets are saved they will be saved using the #reference
|
||||
* directive by default */
|
||||
#define DEFAULT_VIDEO_SHADER_PRESET_SAVE_REFERENCE_ENABLE true
|
||||
|
@ -1656,7 +1656,7 @@ static struct config_bool_setting *populate_settings_bool(
|
||||
SETTING_BOOL("video_scale_integer", &settings->bools.video_scale_integer, true, DEFAULT_SCALE_INTEGER, false);
|
||||
SETTING_BOOL("video_scale_integer_overscale", &settings->bools.video_scale_integer_overscale, true, DEFAULT_SCALE_INTEGER_OVERSCALE, false);
|
||||
SETTING_BOOL("video_smooth", &settings->bools.video_smooth, true, DEFAULT_VIDEO_SMOOTH, false);
|
||||
SETTING_BOOL("video_ctx_scaling", &settings->bools.video_ctx_scaling, true, DEFAULT_VIDEO_CTX_SCALING, false);
|
||||
SETTING_BOOL("video_ctx_scaling", &settings->bools.video_ctx_scaling, true, DEFAULT_VIDEO_CTX_SCALING, false);
|
||||
SETTING_BOOL("video_force_aspect", &settings->bools.video_force_aspect, true, DEFAULT_FORCE_ASPECT, false);
|
||||
#if defined(DINGUX)
|
||||
SETTING_BOOL("video_dingux_ipu_keep_aspect", &settings->bools.video_dingux_ipu_keep_aspect, true, DEFAULT_DINGUX_IPU_KEEP_ASPECT, false);
|
||||
@ -1666,6 +1666,8 @@ static struct config_bool_setting *populate_settings_bool(
|
||||
SETTING_BOOL("auto_screenshot_filename", &settings->bools.auto_screenshot_filename, true, DEFAULT_AUTO_SCREENSHOT_FILENAME, false);
|
||||
SETTING_BOOL("video_force_srgb_disable", &settings->bools.video_force_srgb_disable, true, false, false);
|
||||
SETTING_BOOL("video_fullscreen", &settings->bools.video_fullscreen, true, DEFAULT_FULLSCREEN, false);
|
||||
SETTING_BOOL("video_hdr_enable", &settings->bools.video_hdr_enable, true, DEFAULT_VIDEO_HDR_ENABLE, false);
|
||||
SETTING_BOOL("video_hdr_expand_gamut", &settings->bools.video_hdr_expand_gamut, true, DEFAULT_VIDEO_HDR_EXPAND_GAMUT, false);
|
||||
SETTING_BOOL("bundle_assets_extract_enable", &settings->bools.bundle_assets_extract_enable, true, DEFAULT_BUNDLE_ASSETS_EXTRACT_ENABLE, false);
|
||||
SETTING_BOOL("video_vsync", &settings->bools.video_vsync, true, DEFAULT_VSYNC, false);
|
||||
SETTING_BOOL("video_adaptive_vsync", &settings->bools.video_adaptive_vsync, true, DEFAULT_ADAPTIVE_VSYNC, false);
|
||||
@ -2039,6 +2041,10 @@ static struct config_float_setting *populate_settings_float(
|
||||
SETTING_FLOAT("input_analog_sensitivity", &settings->floats.input_analog_sensitivity, true, DEFAULT_ANALOG_SENSITIVITY, false);
|
||||
SETTING_FLOAT("video_msg_bgcolor_opacity", &settings->floats.video_msg_bgcolor_opacity, true, message_bgcolor_opacity, false);
|
||||
|
||||
SETTING_FLOAT("video_hdr_max_nits", &settings->floats.video_hdr_max_nits, true, DEFAULT_VIDEO_HDR_MAX_NITS, false);
|
||||
SETTING_FLOAT("video_hdr_paper_white_nits", &settings->floats.video_hdr_paper_white_nits, true, DEFAULT_VIDEO_HDR_PAPER_WHITE_NITS, false);
|
||||
SETTING_FLOAT("video_hdr_contrast", &settings->floats.video_hdr_contrast, true, DEFAULT_VIDEO_HDR_CONTRAST, false);
|
||||
|
||||
*size = count;
|
||||
|
||||
return tmp;
|
||||
|
@ -345,6 +345,9 @@ typedef struct settings
|
||||
float video_msg_color_g;
|
||||
float video_msg_color_b;
|
||||
float video_msg_bgcolor_opacity;
|
||||
float video_hdr_max_nits;
|
||||
float video_hdr_paper_white_nits;
|
||||
float video_hdr_contrast;
|
||||
|
||||
float menu_scale_factor;
|
||||
float menu_widget_scale_factor;
|
||||
@ -553,6 +556,8 @@ typedef struct settings
|
||||
#ifdef HAVE_VIDEO_LAYOUT
|
||||
bool video_layout_enable;
|
||||
#endif
|
||||
bool video_hdr_enable;
|
||||
bool video_hdr_expand_gamut;
|
||||
|
||||
/* Accessibility */
|
||||
bool accessibility_enable;
|
||||
|
@ -2529,6 +2529,9 @@ typedef struct
|
||||
D3D11RasterizerState scissor_disabled;
|
||||
D3D11Buffer ubo;
|
||||
d3d11_uniform_t ubo_values;
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
d3d11_texture_t back_buffer;
|
||||
#endif
|
||||
D3D11SamplerState samplers[RARCH_FILTER_MAX][RARCH_WRAP_MAX];
|
||||
D3D11BlendState blend_enable;
|
||||
D3D11BlendState blend_disable;
|
||||
@ -2549,6 +2552,12 @@ typedef struct
|
||||
bool has_flip_model;
|
||||
bool has_allow_tearing;
|
||||
d3d11_shader_t shaders[GFX_MAX_SHADERS];
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
enum dxgi_swapchain_bit_depth
|
||||
chain_bit_depth;
|
||||
DXGI_COLOR_SPACE_TYPE chain_color_space;
|
||||
DXGI_FORMAT chain_formats[DXGI_SWAPCHAIN_BIT_DEPTH_COUNT];
|
||||
#endif
|
||||
#ifdef __WINRT__
|
||||
DXGIFactory2 factory;
|
||||
#else
|
||||
@ -2562,6 +2571,20 @@ typedef struct
|
||||
struct retro_hw_render_interface_d3d11 iface;
|
||||
} hw;
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
struct
|
||||
{
|
||||
dxgi_hdr_uniform_t ubo_values;
|
||||
D3D11Buffer ubo;
|
||||
float max_output_nits;
|
||||
float min_output_nits;
|
||||
float max_cll;
|
||||
float max_fall;
|
||||
bool support;
|
||||
bool enable;
|
||||
} hdr;
|
||||
#endif
|
||||
|
||||
struct
|
||||
{
|
||||
d3d11_shader_t shader;
|
||||
|
@ -174,7 +174,6 @@ bool d3d12_init_base(d3d12_video_t* d3d12)
|
||||
#else
|
||||
DXGICreateFactory(&d3d12->factory);
|
||||
#endif
|
||||
|
||||
{
|
||||
int i = 0;
|
||||
settings_t *settings = config_get_ptr();
|
||||
@ -200,7 +199,6 @@ bool d3d12_init_base(d3d12_video_t* d3d12)
|
||||
if (FAILED(DXGIEnumAdapters(d3d12->factory, i, &adapter)))
|
||||
break;
|
||||
#endif
|
||||
|
||||
IDXGIAdapter_GetDesc(adapter, &desc);
|
||||
|
||||
utf16_to_char_string((const uint16_t*)desc.Description, str, sizeof(str));
|
||||
@ -284,13 +282,30 @@ bool d3d12_init_swapchain(d3d12_video_t* d3d12,
|
||||
{
|
||||
unsigned i;
|
||||
HRESULT hr;
|
||||
HWND hwnd;
|
||||
#ifdef __WINRT__
|
||||
DXGI_SWAP_CHAIN_DESC1 desc;
|
||||
memset(&desc, 0, sizeof(DXGI_SWAP_CHAIN_DESC1));
|
||||
DXGI_SWAP_CHAIN_DESC1 desc = {{0}};
|
||||
#else
|
||||
DXGI_SWAP_CHAIN_DESC desc;
|
||||
HWND hwnd = (HWND)corewindow;
|
||||
memset(&desc, 0, sizeof(DXGI_SWAP_CHAIN_DESC));
|
||||
DXGI_SWAP_CHAIN_DESC desc = {{0}};
|
||||
#endif
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
DXGI_COLOR_SPACE_TYPE color_space;
|
||||
|
||||
d3d12->chain.formats[DXGI_SWAPCHAIN_BIT_DEPTH_8] = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
d3d12->chain.formats[DXGI_SWAPCHAIN_BIT_DEPTH_10] = DXGI_FORMAT_R10G10B10A2_UNORM;
|
||||
d3d12->chain.formats[DXGI_SWAPCHAIN_BIT_DEPTH_16] = DXGI_FORMAT_R16G16B16A16_UNORM;
|
||||
#endif
|
||||
|
||||
hwnd = (HWND)corewindow;
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
if (!(d3d12->hdr.support =
|
||||
dxgi_check_display_hdr_support(d3d12->factory, hwnd)))
|
||||
d3d12->hdr.enable = false;
|
||||
|
||||
d3d12->chain.bit_depth = d3d12->hdr.enable
|
||||
? DXGI_SWAPCHAIN_BIT_DEPTH_10
|
||||
: DXGI_SWAPCHAIN_BIT_DEPTH_8;
|
||||
#endif
|
||||
|
||||
desc.BufferCount = countof(d3d12->chain.renderTargets);
|
||||
@ -298,24 +313,37 @@ bool d3d12_init_swapchain(d3d12_video_t* d3d12,
|
||||
#ifdef __WINRT__
|
||||
desc.Width = width;
|
||||
desc.Height = height;
|
||||
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
#else
|
||||
desc.BufferDesc.Width = width;
|
||||
desc.BufferDesc.Height = height;
|
||||
desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
desc.BufferDesc.RefreshRate.Numerator = 0;
|
||||
desc.BufferDesc.RefreshRate.Denominator = 1;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
#ifdef __WINRT__
|
||||
desc.Format = d3d12->chain.formats[d3d12->chain.bit_depth];
|
||||
#else
|
||||
desc.BufferDesc.Format = d3d12->chain.formats[d3d12->chain.bit_depth];
|
||||
#endif
|
||||
#else
|
||||
#ifdef __WINRT__
|
||||
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
#else
|
||||
desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
#ifdef HAVE_WINDOW
|
||||
desc.OutputWindow = hwnd;
|
||||
desc.Windowed = TRUE;
|
||||
desc.OutputWindow = hwnd;
|
||||
desc.Windowed = TRUE;
|
||||
#endif
|
||||
#if 0
|
||||
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||
#else
|
||||
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
#endif
|
||||
desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
|
||||
|
||||
@ -334,6 +362,34 @@ bool d3d12_init_swapchain(d3d12_video_t* d3d12,
|
||||
DXGIMakeWindowAssociation(d3d12->factory, hwnd, DXGI_MWA_NO_ALT_ENTER);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
/* Check display HDR support and
|
||||
initialize ST.2084 support to match
|
||||
the display's support. */
|
||||
#if 0
|
||||
d3d12->hdr.max_output_nits = 300.0f;
|
||||
d3d12->hdr.min_output_nits = 0.001f;
|
||||
d3d12->hdr.max_cll = 0.0f;
|
||||
d3d12->hdr.max_fall = 0.0f;
|
||||
#endif
|
||||
color_space =
|
||||
d3d12->hdr.enable
|
||||
? DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020
|
||||
: DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
|
||||
|
||||
dxgi_swapchain_color_space(d3d12->chain.handle,
|
||||
&d3d12->chain.color_space, color_space);
|
||||
dxgi_set_hdr_metadata(
|
||||
d3d12->chain.handle,
|
||||
d3d12->hdr.support,
|
||||
d3d12->chain.bit_depth,
|
||||
d3d12->chain.color_space,
|
||||
d3d12->hdr.max_output_nits,
|
||||
d3d12->hdr.min_output_nits,
|
||||
d3d12->hdr.max_cll,
|
||||
d3d12->hdr.max_fall);
|
||||
#endif
|
||||
|
||||
d3d12->chain.frame_index = DXGIGetCurrentBackBufferIndex(d3d12->chain.handle);
|
||||
|
||||
for (i = 0; i < countof(d3d12->chain.renderTargets); i++)
|
||||
@ -343,10 +399,28 @@ bool d3d12_init_swapchain(d3d12_video_t* d3d12,
|
||||
d3d12->device, d3d12->chain.renderTargets[i], NULL, d3d12->chain.desc_handles[i]);
|
||||
}
|
||||
|
||||
d3d12->chain.viewport.Width = width;
|
||||
d3d12->chain.viewport.Height = height;
|
||||
d3d12->chain.scissorRect.right = width;
|
||||
d3d12->chain.scissorRect.bottom = height;
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
memset(&d3d12->chain.back_buffer,
|
||||
0, sizeof(d3d12->chain.back_buffer));
|
||||
d3d12->chain.back_buffer.desc.Width = width;
|
||||
d3d12->chain.back_buffer.desc.Height = height;
|
||||
d3d12->chain.back_buffer.desc.Format =
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
d3d12->chain.back_buffer.desc.Flags =
|
||||
D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||
d3d12->chain.back_buffer.srv_heap =
|
||||
&d3d12->desc.srv_heap;
|
||||
d3d12->chain.back_buffer.rt_view.ptr =
|
||||
d3d12->desc.rtv_heap.cpu.ptr
|
||||
+ (countof(d3d12->chain.renderTargets))
|
||||
* d3d12->desc.rtv_heap.stride;
|
||||
d3d12_init_texture(d3d12->device, &d3d12->chain.back_buffer);
|
||||
#endif
|
||||
|
||||
d3d12->chain.viewport.Width = width;
|
||||
d3d12->chain.viewport.Height = height;
|
||||
d3d12->chain.scissorRect.right = width;
|
||||
d3d12->chain.scissorRect.bottom = height;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -619,6 +693,19 @@ D3D12_RENDER_TARGET_BLEND_DESC d3d12_blend_enable_desc = {
|
||||
D3D12_COLOR_WRITE_ENABLE_ALL,
|
||||
};
|
||||
|
||||
D3D12_RENDER_TARGET_BLEND_DESC d3d12_blend_disable_desc = {
|
||||
FALSE,
|
||||
FALSE,
|
||||
D3D12_BLEND_SRC_ALPHA,
|
||||
D3D12_BLEND_INV_SRC_ALPHA,
|
||||
D3D12_BLEND_OP_ADD,
|
||||
D3D12_BLEND_SRC_ALPHA,
|
||||
D3D12_BLEND_INV_SRC_ALPHA,
|
||||
D3D12_BLEND_OP_ADD,
|
||||
D3D12_LOGIC_OP_NOOP,
|
||||
D3D12_COLOR_WRITE_ENABLE_ALL,
|
||||
};
|
||||
|
||||
bool d3d12_init_pipeline(
|
||||
D3D12Device device,
|
||||
D3DBlob vs_code,
|
||||
|
@ -1385,6 +1385,9 @@ typedef struct
|
||||
{
|
||||
DXGISwapChain handle;
|
||||
D3D12Resource renderTargets[2];
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
d3d12_texture_t back_buffer;
|
||||
#endif
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE desc_handles[2];
|
||||
D3D12_VIEWPORT viewport;
|
||||
D3D12_RECT scissorRect;
|
||||
@ -1392,6 +1395,11 @@ typedef struct
|
||||
int frame_index;
|
||||
bool vsync;
|
||||
unsigned swap_interval;
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
enum dxgi_swapchain_bit_depth bit_depth;
|
||||
DXGI_COLOR_SPACE_TYPE color_space;
|
||||
DXGI_FORMAT formats[DXGI_SWAPCHAIN_BIT_DEPTH_COUNT];
|
||||
#endif
|
||||
} chain;
|
||||
|
||||
struct
|
||||
@ -1407,6 +1415,21 @@ typedef struct
|
||||
int rotation;
|
||||
} frame;
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
struct
|
||||
{
|
||||
dxgi_hdr_uniform_t ubo_values;
|
||||
D3D12Resource ubo;
|
||||
D3D12_CONSTANT_BUFFER_VIEW_DESC ubo_view;
|
||||
float max_output_nits;
|
||||
float min_output_nits;
|
||||
float max_cll;
|
||||
float max_fall;
|
||||
bool support;
|
||||
bool enable;
|
||||
} hdr;
|
||||
#endif
|
||||
|
||||
struct
|
||||
{
|
||||
D3D12Resource vbo;
|
||||
@ -1490,19 +1513,20 @@ typedef enum {
|
||||
ROOT_ID_SAMPLER_T,
|
||||
ROOT_ID_UBO,
|
||||
ROOT_ID_PC,
|
||||
ROOT_ID_MAX,
|
||||
ROOT_ID_MAX
|
||||
} root_signature_parameter_index_t;
|
||||
|
||||
typedef enum {
|
||||
CS_ROOT_ID_TEXTURE_T = 0,
|
||||
CS_ROOT_ID_UAV_T,
|
||||
CS_ROOT_ID_CONSTANTS,
|
||||
CS_ROOT_ID_MAX,
|
||||
CS_ROOT_ID_MAX
|
||||
} compute_root_index_t;
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
extern D3D12_RENDER_TARGET_BLEND_DESC d3d12_blend_enable_desc;
|
||||
extern D3D12_RENDER_TARGET_BLEND_DESC d3d12_blend_disable_desc;
|
||||
|
||||
bool d3d12_init_base(d3d12_video_t* d3d12);
|
||||
|
||||
|
@ -140,7 +140,8 @@ bool d3d_compile(const char* src, size_t size, LPCSTR src_name, LPCSTR entrypoin
|
||||
{
|
||||
if (error_msg)
|
||||
{
|
||||
RARCH_ERR("D3DCompile failed :\n%s\n", (const char*)D3DGetBufferPointer(error_msg));
|
||||
const char* msg = (const char*)D3DGetBufferPointer(error_msg);
|
||||
RARCH_ERR("D3DCompile failed :\n%s\n", msg); /* Place a breakpoint here, if you want, to see shader compilation issues */
|
||||
Release(error_msg);
|
||||
}
|
||||
return false;
|
||||
|
@ -31,6 +31,18 @@
|
||||
#include "../frontend/frontend_driver.h"
|
||||
#include "win32_common.h"
|
||||
|
||||
const GUID DECLSPEC_SELECTANY libretro_IID_IDXGIOutput6 = { 0x068346e8,0xaaec,
|
||||
0x4b84, {0xad,0xd7,0x13,0x7f,0x51,0x3f,0x77,0xa1 } };
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
typedef enum hdr_root_constants
|
||||
{
|
||||
HDR_ROOT_CONSTANTS_REFERENCE_WHITE_NITS = 0,
|
||||
HDR_ROOT_CONSTANTS_DISPLAY_CURVE,
|
||||
HDR_ROOT_CONSTANTS_COUNT
|
||||
} hdr_root_constants_t;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DYNAMIC) && !defined(__WINRT__)
|
||||
#include <dynamic/dylib.h>
|
||||
|
||||
@ -347,3 +359,260 @@ DXGI_FORMAT glslang_format_to_dxgi(glslang_format fmt)
|
||||
|
||||
return DXGI_FORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
typedef struct display_chromaticities
|
||||
{
|
||||
float red_x;
|
||||
float red_y;
|
||||
float green_x;
|
||||
float green_y;
|
||||
float blue_x;
|
||||
float blue_y;
|
||||
float white_x;
|
||||
float white_y;
|
||||
} display_chromaticities_t;
|
||||
|
||||
inline static int dxgi_compute_intersection_area(
|
||||
int ax1, int ay1, int ax2, int ay2,
|
||||
int bx1, int by1, int bx2, int by2)
|
||||
{
|
||||
return max(0, min(ax2, bx2) -
|
||||
max(ax1, bx1))
|
||||
* max(0, min(ay2, by2) - max(ay1, by1));
|
||||
}
|
||||
|
||||
#ifdef __WINRT__
|
||||
bool dxgi_check_display_hdr_support(DXGIFactory2 factory, HWND hwnd)
|
||||
#else
|
||||
bool dxgi_check_display_hdr_support(DXGIFactory factory, HWND hwnd)
|
||||
#endif
|
||||
{
|
||||
DXGIOutput6 output6 = NULL;
|
||||
DXGIOutput best_output = NULL;
|
||||
DXGIOutput current_output = NULL;
|
||||
DXGIAdapter dxgi_adapter = NULL;
|
||||
UINT i = 0;
|
||||
bool supported = false;
|
||||
float best_intersect_area = -1;
|
||||
|
||||
if (!DXGIIsCurrent(factory))
|
||||
{
|
||||
if (FAILED(DXGICreateFactory(&factory)))
|
||||
{
|
||||
RARCH_ERR("[DXGI]: Failed to create DXGI factory\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (FAILED(DXGIEnumAdapters(factory, 0, &dxgi_adapter)))
|
||||
{
|
||||
RARCH_ERR("[DXGI]: Failed to enumerate adapters\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
while ( DXGIEnumOutputs(dxgi_adapter, i, ¤t_output)
|
||||
!= DXGI_ERROR_NOT_FOUND)
|
||||
{
|
||||
RECT r, rect;
|
||||
DXGI_OUTPUT_DESC desc;
|
||||
int intersect_area;
|
||||
int bx1, by1, bx2, by2;
|
||||
int ax1 = 0;
|
||||
int ay1 = 0;
|
||||
int ax2 = 0;
|
||||
int ay2 = 0;
|
||||
|
||||
if (GetWindowRect(hwnd, &rect)) /* TODO/FIXME - won't work for WinRT */
|
||||
{
|
||||
ax1 = rect.left;
|
||||
ay1 = rect.top;
|
||||
ax2 = rect.right;
|
||||
ay2 = rect.bottom;
|
||||
}
|
||||
|
||||
/* Get the rectangle bounds of current output */
|
||||
if (FAILED(DXGIGetOutputDesc(current_output, &desc)))
|
||||
{
|
||||
RARCH_ERR("[DXGI]: Failed to get DXGI output description\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* TODO/FIXME - DesktopCoordinates won't work for WinRT */
|
||||
r = desc.DesktopCoordinates;
|
||||
bx1 = r.left;
|
||||
by1 = r.top;
|
||||
bx2 = r.right;
|
||||
by2 = r.bottom;
|
||||
|
||||
/* Compute the intersection */
|
||||
intersect_area = dxgi_compute_intersection_area(
|
||||
ax1, ay1, ax2, ay2, bx1, by1, bx2, by2);
|
||||
|
||||
if (intersect_area > best_intersect_area)
|
||||
{
|
||||
best_output = current_output;
|
||||
AddRef(best_output);
|
||||
best_intersect_area = (float)intersect_area;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(best_output->lpVtbl->QueryInterface(
|
||||
best_output,
|
||||
&libretro_IID_IDXGIOutput6, (void**)&output6)))
|
||||
{
|
||||
DXGI_OUTPUT_DESC1 desc1;
|
||||
if (SUCCEEDED(DXGIGetOutputDesc1(output6, &desc1)))
|
||||
{
|
||||
supported = (desc1.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020);
|
||||
|
||||
if (supported)
|
||||
video_driver_set_hdr_support();
|
||||
else
|
||||
{
|
||||
settings_t* settings = config_get_ptr();
|
||||
settings->modified = true;
|
||||
settings->bools.video_hdr_enable = false;
|
||||
|
||||
video_driver_unset_hdr_support();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RARCH_ERR("[DXGI]: Failed to get DXGI Output 6 description\n");
|
||||
}
|
||||
Release(output6);
|
||||
}
|
||||
else
|
||||
{
|
||||
RARCH_ERR("[DXGI]: Failed to get DXGI Output 6 from best output\n");
|
||||
}
|
||||
|
||||
error:
|
||||
Release(best_output);
|
||||
Release(current_output);
|
||||
Release(dxgi_adapter);
|
||||
|
||||
return supported;
|
||||
}
|
||||
|
||||
void dxgi_swapchain_color_space(
|
||||
DXGISwapChain chain_handle,
|
||||
DXGI_COLOR_SPACE_TYPE *chain_color_space,
|
||||
DXGI_COLOR_SPACE_TYPE color_space)
|
||||
{
|
||||
if (*chain_color_space != color_space)
|
||||
{
|
||||
UINT color_space_support = 0;
|
||||
if (SUCCEEDED(DXGICheckColorSpaceSupport(
|
||||
chain_handle, color_space,
|
||||
&color_space_support))
|
||||
&& ((color_space_support &
|
||||
DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT)
|
||||
== DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT))
|
||||
{
|
||||
if (FAILED(DXGISetColorSpace1(chain_handle, color_space)))
|
||||
{
|
||||
RARCH_ERR("[DXGI]: Failed to set DXGI swapchain colour space\n");
|
||||
/* TODO/FIXME/CLARIFICATION: Was this fall-through intentional?
|
||||
* Should chain color space still be set even when this fails?
|
||||
* Going to assume this was wrong and early return instead
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
*chain_color_space = color_space;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dxgi_set_hdr_metadata(
|
||||
DXGISwapChain handle,
|
||||
bool hdr_supported,
|
||||
enum dxgi_swapchain_bit_depth chain_bit_depth,
|
||||
DXGI_COLOR_SPACE_TYPE chain_color_space,
|
||||
float max_output_nits,
|
||||
float min_output_nits,
|
||||
float max_cll,
|
||||
float max_fall
|
||||
)
|
||||
{
|
||||
static const display_chromaticities_t
|
||||
display_chromaticity_list[] =
|
||||
{
|
||||
{ 0.64000f, 0.33000f, 0.30000f, 0.60000f, 0.15000f, 0.06000f, 0.31270f, 0.32900f }, /* Rec709 */
|
||||
{ 0.70800f, 0.29200f, 0.17000f, 0.79700f, 0.13100f, 0.04600f, 0.31270f, 0.32900f }, /* Rec2020 */
|
||||
};
|
||||
const display_chromaticities_t* chroma = NULL;
|
||||
DXGI_HDR_METADATA_HDR10 hdr10_meta_data = {0};
|
||||
int selected_chroma = 0;
|
||||
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
/* Clear the hdr meta data if the monitor does not support HDR */
|
||||
if (!hdr_supported)
|
||||
{
|
||||
if (FAILED(DXGISetHDRMetaData(handle,
|
||||
DXGI_HDR_METADATA_TYPE_NONE, 0, NULL)))
|
||||
{
|
||||
RARCH_ERR("[DXGI]: Failed to set HDR meta data to none\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Now select the chromacity based on colour space */
|
||||
if ( chain_bit_depth == DXGI_SWAPCHAIN_BIT_DEPTH_10
|
||||
&& chain_color_space ==
|
||||
DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020)
|
||||
selected_chroma = 1;
|
||||
else
|
||||
{
|
||||
if (FAILED(DXGISetHDRMetaData(handle,
|
||||
DXGI_HDR_METADATA_TYPE_NONE, 0, NULL)))
|
||||
{
|
||||
RARCH_ERR("[DXGI]: Failed to set HDR meta data to none\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the HDR meta data */
|
||||
chroma =
|
||||
&display_chromaticity_list[selected_chroma];
|
||||
hdr10_meta_data.RedPrimary[0] =
|
||||
(UINT16)(chroma->red_x * 50000.0f);
|
||||
hdr10_meta_data.RedPrimary[1] =
|
||||
(UINT16)(chroma->red_y * 50000.0f);
|
||||
hdr10_meta_data.GreenPrimary[0] =
|
||||
(UINT16)(chroma->green_x * 50000.0f);
|
||||
hdr10_meta_data.GreenPrimary[1] =
|
||||
(UINT16)(chroma->green_y * 50000.0f);
|
||||
hdr10_meta_data.BluePrimary[0] =
|
||||
(UINT16)(chroma->blue_x * 50000.0f);
|
||||
hdr10_meta_data.BluePrimary[1] =
|
||||
(UINT16)(chroma->blue_y * 50000.0f);
|
||||
hdr10_meta_data.WhitePoint[0] =
|
||||
(UINT16)(chroma->white_x * 50000.0f);
|
||||
hdr10_meta_data.WhitePoint[1] =
|
||||
(UINT16)(chroma->white_y * 50000.0f);
|
||||
hdr10_meta_data.MaxMasteringLuminance =
|
||||
(UINT)(max_output_nits * 10000.0f);
|
||||
hdr10_meta_data.MinMasteringLuminance =
|
||||
(UINT)(min_output_nits * 10000.0f);
|
||||
hdr10_meta_data.MaxContentLightLevel =
|
||||
(UINT16)(max_cll);
|
||||
hdr10_meta_data.MaxFrameAverageLightLevel =
|
||||
(UINT16)(max_fall);
|
||||
|
||||
if (FAILED(DXGISetHDRMetaData(handle,
|
||||
DXGI_HDR_METADATA_TYPE_HDR10,
|
||||
sizeof(DXGI_HDR_METADATA_HDR10), &hdr10_meta_data)))
|
||||
{
|
||||
RARCH_ERR("[DXGI]: Failed to set HDR meta data for HDR10\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -2,6 +2,41 @@
|
||||
|
||||
#include <retro_inline.h>
|
||||
|
||||
#ifndef __WINRT__
|
||||
#ifndef HAVE_DXGI_HDR
|
||||
#define HAVE_DXGI_HDR
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
#ifndef ALIGN
|
||||
#ifdef _MSC_VER
|
||||
#define ALIGN(x) __declspec(align(x))
|
||||
#else
|
||||
#define ALIGN(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <gfx/math/matrix_4x4.h>
|
||||
|
||||
typedef struct ALIGN(16)
|
||||
{
|
||||
math_matrix_4x4 mvp;
|
||||
float contrast; /* 2.0f */
|
||||
float paperWhiteNits; /* 200.0f */
|
||||
float maxNits; /* 1000.0f */
|
||||
float expandGamut; /* 1.0f */
|
||||
} dxgi_hdr_uniform_t;
|
||||
|
||||
enum dxgi_swapchain_bit_depth
|
||||
{
|
||||
DXGI_SWAPCHAIN_BIT_DEPTH_8 = 0,
|
||||
DXGI_SWAPCHAIN_BIT_DEPTH_10,
|
||||
DXGI_SWAPCHAIN_BIT_DEPTH_16,
|
||||
DXGI_SWAPCHAIN_BIT_DEPTH_COUNT
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#define __REQUIRED_RPCNDR_H_VERSION__ 475
|
||||
/* Pointer parameters */
|
||||
@ -233,7 +268,7 @@
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <dxgi1_5.h>
|
||||
#include <dxgi1_6.h>
|
||||
|
||||
#ifndef countof
|
||||
#define countof(a) (sizeof(a) / sizeof(*a))
|
||||
@ -281,6 +316,7 @@ typedef IDXGIResource* DXGIResource;
|
||||
typedef IDXGIKeyedMutex* DXGIKeyedMutex;
|
||||
typedef IDXGISurface1* DXGISurface;
|
||||
typedef IDXGIOutput* DXGIOutput;
|
||||
typedef IDXGIOutput6* DXGIOutput6;
|
||||
typedef IDXGIDevice* DXGIDevice;
|
||||
typedef IDXGIFactory1* DXGIFactory;
|
||||
#ifdef __WINRT__
|
||||
@ -292,7 +328,7 @@ typedef IDXGIOutputDuplication* DXGIOutputDuplication;
|
||||
typedef IDXGIDecodeSwapChain* DXGIDecodeSwapChain;
|
||||
typedef IDXGIFactoryMedia* DXGIFactoryMedia;
|
||||
typedef IDXGISwapChainMedia* DXGISwapChainMedia;
|
||||
typedef IDXGISwapChain3* DXGISwapChain;
|
||||
typedef IDXGISwapChain4* DXGISwapChain;
|
||||
|
||||
#if !defined(__cplusplus) || defined(CINTERFACE)
|
||||
static INLINE ULONG DXGIReleaseDeviceSubObject(DXGIDeviceSubObject device_sub_object)
|
||||
@ -392,6 +428,14 @@ static INLINE HRESULT DXGIGetDisplaySurfaceData(DXGIOutput output, DXGISurface d
|
||||
{
|
||||
return output->lpVtbl->GetDisplaySurfaceData(output, (IDXGISurface*)destination);
|
||||
}
|
||||
static INLINE HRESULT DXGIGetOutputDesc(DXGIOutput output, DXGI_OUTPUT_DESC* desc)
|
||||
{
|
||||
return output->lpVtbl->GetDesc(output, desc);
|
||||
}
|
||||
static INLINE HRESULT DXGIGetOutputDesc1(DXGIOutput6 output, DXGI_OUTPUT_DESC1* desc)
|
||||
{
|
||||
return output->lpVtbl->GetDesc1(output, desc);
|
||||
}
|
||||
static INLINE ULONG DXGIReleaseDevice(DXGIDevice device) { return device->lpVtbl->Release(device); }
|
||||
static INLINE HRESULT DXGICreateSurface(
|
||||
DXGIDevice device,
|
||||
@ -769,11 +813,14 @@ static INLINE HRESULT DXGICheckColorSpaceSupport(
|
||||
{
|
||||
return swap_chain->lpVtbl->CheckColorSpaceSupport(swap_chain, color_space, color_space_support);
|
||||
}
|
||||
static INLINE HRESULT
|
||||
DXGISetColorSpace1(DXGISwapChain swap_chain, DXGI_COLOR_SPACE_TYPE color_space)
|
||||
static INLINE HRESULT DXGISetColorSpace1(DXGISwapChain swap_chain, DXGI_COLOR_SPACE_TYPE color_space)
|
||||
{
|
||||
return swap_chain->lpVtbl->SetColorSpace1(swap_chain, color_space);
|
||||
}
|
||||
static INLINE HRESULT DXGISetHDRMetaData(DXGISwapChain swap_chain, DXGI_HDR_METADATA_TYPE type, UINT size, void *metaData)
|
||||
{
|
||||
return swap_chain->lpVtbl->SetHDRMetaData(swap_chain, type, size, metaData);
|
||||
}
|
||||
#endif
|
||||
/* end of auto-generated */
|
||||
|
||||
@ -821,6 +868,26 @@ void dxgi_copy(
|
||||
int dst_pitch,
|
||||
void* dst_data);
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
#ifdef __WINRT__
|
||||
bool dxgi_check_display_hdr_support(DXGIFactory2 factory, HWND hwnd);
|
||||
#else
|
||||
bool dxgi_check_display_hdr_support(DXGIFactory factory, HWND hwnd);
|
||||
#endif
|
||||
void dxgi_swapchain_color_space(DXGISwapChain handle, DXGI_COLOR_SPACE_TYPE
|
||||
*chain_color_space, DXGI_COLOR_SPACE_TYPE color_space);
|
||||
void dxgi_set_hdr_metadata(
|
||||
DXGISwapChain handle,
|
||||
bool hdr_supported,
|
||||
enum dxgi_swapchain_bit_depth chain_bit_depth,
|
||||
DXGI_COLOR_SPACE_TYPE chain_color_space,
|
||||
float max_output_nits,
|
||||
float min_output_nits,
|
||||
float max_cll,
|
||||
float max_fall
|
||||
);
|
||||
#endif
|
||||
|
||||
DXGI_FORMAT glslang_format_to_dxgi(glslang_format fmt);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
@ -932,6 +932,12 @@ static LRESULT CALLBACK wnd_proc_common(
|
||||
/* fall-through */
|
||||
case WM_MOVE:
|
||||
win32_save_position();
|
||||
#if 0
|
||||
#if !defined(_XBOX)
|
||||
if(d3d12)
|
||||
d3d12_check_display_hdr_support(d3d12, hwnd);
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
case WM_SIZE:
|
||||
/* Do not send resize message if we minimize. */
|
||||
|
@ -270,6 +270,10 @@ static const video_poke_interface_t caca_poke_interface = {
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void caca_gfx_get_poke_interface(void *data,
|
||||
|
@ -1535,7 +1535,11 @@ static const video_poke_interface_t ctr_poke_interface = {
|
||||
NULL, /* grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL /* get_hw_render_interface */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void ctr_get_poke_interface(void* data,
|
||||
|
@ -1008,7 +1008,7 @@ static void *d3d10_gfx_init(const video_info_t* video,
|
||||
#else
|
||||
DXGICreateFactory(&d3d10->factory);
|
||||
#endif
|
||||
|
||||
|
||||
{
|
||||
int i = 0;
|
||||
int gpu_index = settings->ints.d3d10_gpu_index;
|
||||
@ -1800,6 +1800,10 @@ static const video_poke_interface_t d3d10_poke_interface = {
|
||||
#else
|
||||
NULL, /* get_hw_render_interface */
|
||||
#endif
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void d3d10_gfx_get_poke_interface(void* data, const video_poke_interface_t** iface)
|
||||
|
@ -255,6 +255,79 @@ static void d3d11_get_overlay_interface(
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
static void d3d11_set_hdr_max_nits(void *data, float max_nits)
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mapped_ubo;
|
||||
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
|
||||
|
||||
d3d11->hdr.max_output_nits = max_nits;
|
||||
d3d11->hdr.ubo_values.maxNits = max_nits;
|
||||
|
||||
D3D11MapBuffer(d3d11->context, d3d11->hdr.ubo,
|
||||
0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mapped_ubo);
|
||||
{
|
||||
dxgi_hdr_uniform_t *ubo = (dxgi_hdr_uniform_t*)mapped_ubo.pData;
|
||||
*ubo = d3d11->hdr.ubo_values;
|
||||
}
|
||||
D3D11UnmapBuffer(d3d11->context, d3d11->hdr.ubo, 0);
|
||||
|
||||
dxgi_set_hdr_metadata(
|
||||
d3d11->swapChain,
|
||||
d3d11->hdr.support,
|
||||
d3d11->chain_bit_depth,
|
||||
d3d11->chain_color_space,
|
||||
d3d11->hdr.max_output_nits,
|
||||
d3d11->hdr.min_output_nits,
|
||||
d3d11->hdr.max_cll,
|
||||
d3d11->hdr.max_fall);
|
||||
}
|
||||
|
||||
static void d3d11_set_hdr_paper_white_nits(void* data, float paper_white_nits)
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mapped_ubo;
|
||||
dxgi_hdr_uniform_t *ubo = NULL;
|
||||
d3d11_video_t *d3d11 = (d3d11_video_t*)data;
|
||||
|
||||
d3d11->hdr.ubo_values.paperWhiteNits = paper_white_nits;
|
||||
|
||||
D3D11MapBuffer(d3d11->context, d3d11->hdr.ubo,
|
||||
0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_ubo);
|
||||
ubo = (dxgi_hdr_uniform_t*)mapped_ubo.pData;
|
||||
*ubo = d3d11->hdr.ubo_values;
|
||||
D3D11UnmapBuffer(d3d11->context, d3d11->hdr.ubo, 0);
|
||||
}
|
||||
|
||||
static void d3d11_set_hdr_contrast(void* data, float contrast)
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mapped_ubo;
|
||||
dxgi_hdr_uniform_t *ubo = NULL;
|
||||
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
|
||||
|
||||
d3d11->hdr.ubo_values.contrast = contrast;
|
||||
|
||||
D3D11MapBuffer(d3d11->context, d3d11->hdr.ubo,
|
||||
0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_ubo);
|
||||
ubo = (dxgi_hdr_uniform_t*)mapped_ubo.pData;
|
||||
*ubo = d3d11->hdr.ubo_values;
|
||||
D3D11UnmapBuffer(d3d11->context, d3d11->hdr.ubo, 0);
|
||||
}
|
||||
|
||||
static void d3d11_set_hdr_expand_gamut(void* data, bool expand_gamut)
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mapped_ubo;
|
||||
dxgi_hdr_uniform_t *ubo = NULL;
|
||||
d3d11_video_t* d3d11 = (d3d11_video_t*)data;
|
||||
|
||||
d3d11->hdr.ubo_values.expandGamut = expand_gamut;
|
||||
|
||||
D3D11MapBuffer(d3d11->context, d3d11->hdr.ubo, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_ubo);
|
||||
ubo = (dxgi_hdr_uniform_t*)mapped_ubo.pData;
|
||||
*ubo = d3d11->hdr.ubo_values;
|
||||
D3D11UnmapBuffer(d3d11->context, d3d11->hdr.ubo, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void d3d11_set_filtering(void* data, unsigned index,
|
||||
bool smooth, bool ctx_scaling)
|
||||
{
|
||||
@ -559,6 +632,10 @@ static void d3d11_gfx_free(void* data)
|
||||
d3d11_release_texture(&d3d11->menu.texture);
|
||||
Release(d3d11->menu.vbo);
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
Release(d3d11->hdr.ubo);
|
||||
#endif
|
||||
|
||||
d3d11_release_shader(&d3d11->sprites.shader);
|
||||
d3d11_release_shader(&d3d11->sprites.shader_font);
|
||||
Release(d3d11->sprites.vbo);
|
||||
@ -580,6 +657,10 @@ static void d3d11_gfx_free(void* data)
|
||||
Release(d3d11->samplers[RARCH_FILTER_NEAREST][i]);
|
||||
}
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
d3d11_release_texture(&d3d11->back_buffer);
|
||||
#endif
|
||||
|
||||
Release(d3d11->scissor_enabled);
|
||||
Release(d3d11->scissor_disabled);
|
||||
Release(d3d11->swapChain);
|
||||
@ -607,6 +688,10 @@ static void d3d11_gfx_free(void* data)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
video_driver_unset_hdr_support();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MONITOR
|
||||
win32_monitor_from_window();
|
||||
#endif
|
||||
@ -622,6 +707,7 @@ static bool d3d11_init_swapchain(d3d11_video_t* d3d11,
|
||||
D3D11DeviceContext *cached_context,
|
||||
void *corewindow)
|
||||
{
|
||||
HWND hwnd;
|
||||
#ifdef __WINRT__
|
||||
IDXGIFactory2* dxgiFactory = NULL;
|
||||
#else
|
||||
@ -646,19 +732,51 @@ static bool d3d11_init_swapchain(d3d11_video_t* d3d11,
|
||||
#endif
|
||||
UINT number_feature_levels = ARRAY_SIZE(requested_feature_levels);
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
DXGI_COLOR_SPACE_TYPE color_space;
|
||||
|
||||
d3d11->chain_formats[DXGI_SWAPCHAIN_BIT_DEPTH_8] = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
d3d11->chain_formats[DXGI_SWAPCHAIN_BIT_DEPTH_10] = DXGI_FORMAT_R10G10B10A2_UNORM;
|
||||
d3d11->chain_formats[DXGI_SWAPCHAIN_BIT_DEPTH_16] = DXGI_FORMAT_R16G16B16A16_UNORM;
|
||||
#endif
|
||||
|
||||
hwnd = (HWND)corewindow;
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
if (!(d3d11->hdr.support =
|
||||
dxgi_check_display_hdr_support(d3d11->factory, hwnd)))
|
||||
d3d11->hdr.enable = false;
|
||||
|
||||
d3d11->chain_bit_depth = d3d11->hdr.enable
|
||||
? DXGI_SWAPCHAIN_BIT_DEPTH_10
|
||||
: DXGI_SWAPCHAIN_BIT_DEPTH_8;
|
||||
#endif
|
||||
|
||||
#ifdef __WINRT__
|
||||
/* Flip model forces us to do double-buffering */
|
||||
desc.BufferCount = 2;
|
||||
|
||||
desc.Width = width;
|
||||
desc.Height = height;
|
||||
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
if (d3d11->hdr.support)
|
||||
desc.Format = d3d11->chain_formats[
|
||||
d3d11->chain_bit_depth];
|
||||
else
|
||||
#endif
|
||||
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
#else
|
||||
desc.BufferCount = 2;
|
||||
|
||||
desc.BufferDesc.Width = width;
|
||||
desc.BufferDesc.Height = height;
|
||||
desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
if (d3d11->hdr.support)
|
||||
desc.BufferDesc.Format = d3d11->chain_formats[
|
||||
d3d11->chain_bit_depth];
|
||||
else
|
||||
#endif
|
||||
desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
desc.BufferDesc.RefreshRate.Numerator = 60;
|
||||
desc.BufferDesc.RefreshRate.Denominator = 1;
|
||||
#endif
|
||||
@ -777,7 +895,44 @@ static bool d3d11_init_swapchain(d3d11_video_t* d3d11,
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __WINRT__
|
||||
#endif /* __WINRT__ */
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
/* Check display HDR support and
|
||||
initialize ST.2084 support to match
|
||||
the display's support. */
|
||||
#if 0
|
||||
d3d11->hdr.max_output_nits = 300.0f;
|
||||
d3d11->hdr.min_output_nits = 0.001f;
|
||||
d3d11->hdr.max_cll = 0.0f;
|
||||
d3d11->hdr.max_fall = 0.0f;
|
||||
#endif
|
||||
color_space =
|
||||
d3d11->hdr.enable
|
||||
? DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020
|
||||
: DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
|
||||
|
||||
dxgi_swapchain_color_space(
|
||||
d3d11->swapChain,
|
||||
&d3d11->chain_color_space,
|
||||
color_space);
|
||||
dxgi_set_hdr_metadata(
|
||||
d3d11->swapChain,
|
||||
d3d11->hdr.support,
|
||||
d3d11->chain_bit_depth,
|
||||
d3d11->chain_color_space,
|
||||
d3d11->hdr.max_output_nits,
|
||||
d3d11->hdr.min_output_nits,
|
||||
d3d11->hdr.max_cll,
|
||||
d3d11->hdr.max_fall);
|
||||
|
||||
memset(&d3d11->back_buffer, 0, sizeof(d3d11->back_buffer));
|
||||
d3d11->back_buffer.desc.Width = width;
|
||||
d3d11->back_buffer.desc.Height = height;
|
||||
d3d11->back_buffer.desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
d3d11->back_buffer.desc.BindFlags = D3D11_BIND_RENDER_TARGET;
|
||||
d3d11_init_texture(d3d11->device, &d3d11->back_buffer);
|
||||
#endif
|
||||
|
||||
dxgiFactory->lpVtbl->Release(dxgiFactory);
|
||||
adapter->lpVtbl->Release(adapter);
|
||||
@ -840,6 +995,19 @@ static void *d3d11_gfx_init(const video_info_t* video,
|
||||
|
||||
d3d_input_driver(settings->arrays.input_driver, settings->arrays.input_joypad_driver, input, input_data);
|
||||
|
||||
#ifdef __WINRT__
|
||||
DXGICreateFactory2(&d3d11->factory);
|
||||
#else
|
||||
DXGICreateFactory(&d3d11->factory);
|
||||
#endif
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
d3d11->hdr.enable = settings->bools.video_hdr_enable;
|
||||
d3d11->hdr.max_output_nits = settings->floats.video_hdr_max_nits;
|
||||
d3d11->hdr.min_output_nits = 0.001f;
|
||||
d3d11->hdr.max_cll = 0.0f;
|
||||
d3d11->hdr.max_fall = 0.0f;
|
||||
#endif
|
||||
|
||||
#ifdef __WINRT__
|
||||
if (!d3d11_init_swapchain(d3d11,
|
||||
d3d11->vp.full_width,
|
||||
@ -905,6 +1073,39 @@ static void *d3d11_gfx_init(const video_info_t* video,
|
||||
|
||||
d3d11_gfx_set_rotation(d3d11, 0);
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
if (d3d11->hdr.enable)
|
||||
{
|
||||
D3D11_BUFFER_DESC desc;
|
||||
D3D11_SUBRESOURCE_DATA ubo_data;
|
||||
matrix_4x4_ortho(d3d11->mvp_no_rot, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
|
||||
|
||||
d3d11->hdr.ubo_values.mvp =
|
||||
d3d11->mvp_no_rot;
|
||||
d3d11->hdr.ubo_values.maxNits =
|
||||
settings->floats.video_hdr_max_nits;
|
||||
d3d11->hdr.ubo_values.paperWhiteNits =
|
||||
settings->floats.video_hdr_paper_white_nits;
|
||||
d3d11->hdr.ubo_values.contrast =
|
||||
settings->floats.video_hdr_contrast;
|
||||
d3d11->hdr.ubo_values.expandGamut =
|
||||
settings->bools.video_hdr_expand_gamut;
|
||||
|
||||
desc.ByteWidth = sizeof(dxgi_hdr_uniform_t);
|
||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
desc.MiscFlags = 0;
|
||||
desc.StructureByteStride = 0;
|
||||
|
||||
ubo_data.pSysMem = &d3d11->hdr.ubo_values.mvp;
|
||||
ubo_data.SysMemPitch = 0;
|
||||
ubo_data.SysMemSlicePitch = 0;
|
||||
|
||||
D3D11CreateBuffer(d3d11->device, &desc, &ubo_data, &d3d11->hdr.ubo);
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
D3D11_SAMPLER_DESC desc = { D3D11_FILTER_MIN_MAG_MIP_POINT };
|
||||
desc.MaxAnisotropy = 1;
|
||||
@ -974,6 +1175,33 @@ static void *d3d11_gfx_init(const video_info_t* video,
|
||||
D3D11CreateBuffer(d3d11->device, &desc, NULL, &d3d11->sprites.vbo);
|
||||
}
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
if (d3d11->hdr.enable)
|
||||
{
|
||||
D3D11_INPUT_ELEMENT_DESC desc[] = {
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0,
|
||||
offsetof(d3d11_vertex_t, position),
|
||||
D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0,
|
||||
offsetof(d3d11_vertex_t, texcoord),
|
||||
D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0,
|
||||
offsetof(d3d11_vertex_t, color),
|
||||
D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
};
|
||||
|
||||
static const char shader[] =
|
||||
#include "d3d_shaders/hdr_sm5.hlsl.h"
|
||||
;
|
||||
|
||||
if (!d3d11_init_shader(
|
||||
d3d11->device, shader, sizeof(shader),
|
||||
NULL, "VSMain", "PSMain", NULL, desc,
|
||||
countof(desc), &d3d11->shaders[VIDEO_SHADER_STOCK_HDR]))
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
D3D11_INPUT_ELEMENT_DESC desc[] = {
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d11_vertex_t, position),
|
||||
@ -1156,12 +1384,6 @@ static void *d3d11_gfx_init(const video_info_t* video,
|
||||
d3d11->hw.iface.D3DCompile = D3DCompile;
|
||||
}
|
||||
|
||||
#ifdef __WINRT__
|
||||
DXGICreateFactory2(&d3d11->factory);
|
||||
#else
|
||||
DXGICreateFactory(&d3d11->factory);
|
||||
#endif
|
||||
|
||||
{
|
||||
int i = 0;
|
||||
int gpu_index = settings->ints.d3d11_gpu_index;
|
||||
@ -1384,32 +1606,91 @@ static bool d3d11_gfx_frame(
|
||||
#ifdef HAVE_GFX_WIDGETS
|
||||
bool widgets_active = video_info->widgets_active;
|
||||
#endif
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
bool video_hdr_enable = video_info->hdr_enable;
|
||||
|
||||
if ( d3d11->resize_chain ||
|
||||
(d3d11->hdr.enable != video_hdr_enable))
|
||||
#else
|
||||
if (d3d11->resize_chain)
|
||||
#endif
|
||||
{
|
||||
UINT swapchain_flags = d3d11->has_allow_tearing
|
||||
UINT swapchain_flags = d3d11->has_allow_tearing
|
||||
? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0;
|
||||
DXGIResizeBuffers(d3d11->swapChain, 0, 0, 0, DXGI_FORMAT_UNKNOWN,
|
||||
swapchain_flags);
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
d3d11->hdr.enable = video_hdr_enable;
|
||||
|
||||
d3d11->viewport.Width = video_width;
|
||||
d3d11->viewport.Height = video_height;
|
||||
d3d11->scissor.right = video_width;
|
||||
d3d11->scissor.bottom = video_height;
|
||||
if(d3d11->hdr.enable)
|
||||
d3d11_release_texture(&d3d11->back_buffer);
|
||||
DXGIResizeBuffers(d3d11->swapChain, 0, 0, 0,
|
||||
d3d11->chain_formats[d3d11->chain_bit_depth],
|
||||
swapchain_flags);
|
||||
#else
|
||||
DXGIResizeBuffers(d3d11->swapChain, 0, 0, 0,
|
||||
DXGI_FORMAT_UNKNOWN,
|
||||
swapchain_flags);
|
||||
#endif
|
||||
|
||||
d3d11->viewport.Width = video_width;
|
||||
d3d11->viewport.Height = video_height;
|
||||
d3d11->scissor.right = video_width;
|
||||
d3d11->scissor.bottom = video_height;
|
||||
|
||||
d3d11->ubo_values.OutputSize.width = d3d11->viewport.Width;
|
||||
d3d11->ubo_values.OutputSize.height = d3d11->viewport.Height;
|
||||
|
||||
d3d11->resize_chain = false;
|
||||
d3d11->resize_viewport = true;
|
||||
d3d11->resize_chain = false;
|
||||
d3d11->resize_viewport = true;
|
||||
video_driver_set_size(video_width, video_height);
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
#ifdef __WINRT__
|
||||
if (!(d3d11->hdr.support =
|
||||
dxgi_check_display_hdr_support(d3d11->factory, uwp_get_corewindow())))
|
||||
d3d11->hdr.enable = false;
|
||||
#else
|
||||
if (!(d3d11->hdr.support =
|
||||
dxgi_check_display_hdr_support(d3d11->factory, main_window.hwnd)))
|
||||
d3d11->hdr.enable = false;
|
||||
#endif
|
||||
|
||||
if(d3d11->hdr.enable)
|
||||
{
|
||||
memset(&d3d11->back_buffer, 0, sizeof(d3d11->back_buffer));
|
||||
d3d11->back_buffer.desc.Width = video_width;
|
||||
d3d11->back_buffer.desc.Height = video_height;
|
||||
d3d11->back_buffer.desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
d3d11->back_buffer.desc.BindFlags = D3D11_BIND_RENDER_TARGET;
|
||||
d3d11_init_texture(d3d11->device, &d3d11->back_buffer);
|
||||
|
||||
dxgi_swapchain_color_space(
|
||||
d3d11->swapChain,
|
||||
&d3d11->chain_color_space,
|
||||
DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020);
|
||||
}
|
||||
else
|
||||
dxgi_swapchain_color_space(
|
||||
d3d11->swapChain,
|
||||
&d3d11->chain_color_space,
|
||||
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709);
|
||||
|
||||
dxgi_set_hdr_metadata(
|
||||
d3d11->swapChain,
|
||||
d3d11->hdr.support,
|
||||
d3d11->chain_bit_depth,
|
||||
d3d11->chain_color_space,
|
||||
d3d11->hdr.max_output_nits,
|
||||
d3d11->hdr.min_output_nits,
|
||||
d3d11->hdr.max_cll,
|
||||
d3d11->hdr.max_fall);
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
D3D11Texture2D backBuffer;
|
||||
DXGIGetSwapChainBufferD3D11(d3d11->swapChain, 0, &backBuffer);
|
||||
D3D11CreateTexture2DRenderTargetView(d3d11->device, backBuffer, NULL, &rtv);
|
||||
Release(backBuffer);
|
||||
D3D11Texture2D back_buffer;
|
||||
DXGIGetSwapChainBufferD3D11(d3d11->swapChain, 0, &back_buffer);
|
||||
D3D11CreateTexture2DRenderTargetView(d3d11->device, back_buffer, NULL, &rtv);
|
||||
Release(back_buffer);
|
||||
}
|
||||
|
||||
/* custom viewport doesn't call apply_state_changes, so we can't rely on this for now */
|
||||
@ -1603,8 +1884,25 @@ static bool d3d11_gfx_frame(
|
||||
}
|
||||
}
|
||||
|
||||
D3D11SetRenderTargets(context, 1, &rtv, NULL);
|
||||
D3D11ClearRenderTargetView(context, rtv, d3d11->clearcolor);
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
if(d3d11->hdr.enable)
|
||||
{
|
||||
/* TODO/FIXME -
|
||||
* following D3D11 warnings are spammed in Debug mode -
|
||||
* Forcing PS shader resource slot 0 to NULL. [ STATE_SETTING WARNING #7: DEVICE_PSSETSHADERRESOURCES_HAZARD]
|
||||
* Resource being set to OM RenderTarget slot 0 is still bound on input! [ STATE_SETTING WARNING #9: DEVICE_OMSETRENDERTARGETS_HAZARD]
|
||||
*/
|
||||
D3D11SetRenderTargets(context, 1, &d3d11->back_buffer.rt_view, NULL);
|
||||
D3D11ClearRenderTargetView(context, d3d11->back_buffer.rt_view, d3d11->clearcolor);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
D3D11SetRenderTargets(context, 1, &rtv, NULL);
|
||||
D3D11ClearRenderTargetView(context, rtv, d3d11->clearcolor);
|
||||
}
|
||||
|
||||
D3D11SetViewports(context, 1, &d3d11->frame.viewport);
|
||||
|
||||
if (texture)
|
||||
@ -1702,6 +2000,41 @@ static bool d3d11_gfx_frame(
|
||||
#if defined(_WIN32) && !defined(__WINRT__)
|
||||
win32_update_title();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
/* Copy over back buffer to swap chain render targets */
|
||||
if(d3d11->hdr.enable)
|
||||
{
|
||||
D3D11SetRenderTargets(context, 1, &rtv, NULL);
|
||||
D3D11ClearRenderTargetView(context, rtv,
|
||||
d3d11->clearcolor);
|
||||
D3D11SetViewports(context, 1,
|
||||
&d3d11->viewport);
|
||||
D3D11SetScissorRects(context, 1,
|
||||
&d3d11->scissor);
|
||||
|
||||
d3d11_set_shader(context,
|
||||
&d3d11->shaders[VIDEO_SHADER_STOCK_HDR]);
|
||||
D3D11SetVShaderConstantBuffer(context, 0,
|
||||
d3d11->hdr.ubo);
|
||||
D3D11SetPShaderResources(context, 0, 1,
|
||||
&d3d11->back_buffer.view);
|
||||
D3D11SetPShaderSamplers(context, 0, 1,
|
||||
&d3d11->samplers[RARCH_FILTER_UNSPEC][RARCH_WRAP_DEFAULT]);
|
||||
D3D11SetPShaderConstantBuffer(context, 0, d3d11->hdr.ubo);
|
||||
D3D11SetVertexBuffer(context, 0, d3d11->frame.vbo,
|
||||
sizeof(d3d11_vertex_t), 0);
|
||||
|
||||
D3D11SetRasterizerState(context, d3d11->scissor_disabled);
|
||||
D3D11SetBlendState(context, d3d11->blend_disable, NULL,
|
||||
D3D11_DEFAULT_SAMPLE_MASK);
|
||||
D3D11SetPrimitiveTopology(context,
|
||||
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
|
||||
D3D11Draw(context, 4, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
DXGIPresent(d3d11->swapChain, !!vsync, present_flags);
|
||||
Release(rtv);
|
||||
|
||||
@ -1957,6 +2290,17 @@ static const video_poke_interface_t d3d11_poke_interface = {
|
||||
d3d11_gfx_get_current_shader,
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
d3d11_get_hw_render_interface,
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
d3d11_set_hdr_max_nits,
|
||||
d3d11_set_hdr_paper_white_nits,
|
||||
d3d11_set_hdr_contrast,
|
||||
d3d11_set_hdr_expand_gamut
|
||||
#else
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
#endif
|
||||
};
|
||||
|
||||
static void d3d11_gfx_get_poke_interface(void* data,
|
||||
|
@ -238,6 +238,78 @@ static void d3d12_get_overlay_interface(void* data, const video_overlay_interfac
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
d3d12->hdr.max_output_nits = settings->floats.video_hdr_max_nits;
|
||||
d3d12->hdr.ubo_values.maxNits = settings->floats.video_hdr_max_nits;
|
||||
d3d12->hdr.ubo_values.paperWhiteNits = settings->floats.video_hdr_paper_white_nits;
|
||||
d3d12->hdr.ubo_values.contrast = settings->floats.video_hdr_contrast;
|
||||
d3d12->hdr.ubo_values.expandGamut = settings->bools.video_hdr_expand_gamut;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
static void d3d12_set_hdr_max_nits(void* data, float max_nits)
|
||||
{
|
||||
dxgi_hdr_uniform_t *mapped_ubo = NULL;
|
||||
D3D12_RANGE read_range = { 0, 0 };
|
||||
d3d12_video_t *d3d12 = (d3d12_video_t*)data;
|
||||
|
||||
d3d12->hdr.max_output_nits = max_nits;
|
||||
d3d12->hdr.ubo_values.maxNits = max_nits;
|
||||
|
||||
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->hdr.support,
|
||||
d3d12->chain.bit_depth,
|
||||
d3d12->chain.color_space,
|
||||
d3d12->hdr.max_output_nits,
|
||||
d3d12->hdr.min_output_nits,
|
||||
d3d12->hdr.max_cll,
|
||||
d3d12->hdr.max_fall);
|
||||
}
|
||||
|
||||
static void d3d12_set_hdr_paper_white_nits(void* data, float paper_white_nits)
|
||||
{
|
||||
D3D12_RANGE read_range = { 0, 0 };
|
||||
dxgi_hdr_uniform_t *mapped_ubo = NULL;
|
||||
d3d12_video_t *d3d12 = (d3d12_video_t*)data;
|
||||
|
||||
d3d12->hdr.ubo_values.paperWhiteNits = paper_white_nits;
|
||||
|
||||
D3D12Map(d3d12->hdr.ubo, 0, &read_range, (void**)&mapped_ubo);
|
||||
*mapped_ubo = d3d12->hdr.ubo_values;
|
||||
D3D12Unmap(d3d12->hdr.ubo, 0, NULL);
|
||||
}
|
||||
|
||||
static void d3d12_set_hdr_contrast(void* data, float contrast)
|
||||
{
|
||||
D3D12_RANGE read_range = { 0, 0 };
|
||||
d3d12_video_t *d3d12 = (d3d12_video_t*)data;
|
||||
dxgi_hdr_uniform_t *mapped_ubo = NULL;
|
||||
|
||||
d3d12->hdr.ubo_values.contrast = contrast;
|
||||
|
||||
D3D12Map(d3d12->hdr.ubo, 0, &read_range, (void**)&mapped_ubo);
|
||||
*mapped_ubo = d3d12->hdr.ubo_values;
|
||||
D3D12Unmap(d3d12->hdr.ubo, 0, NULL);
|
||||
}
|
||||
|
||||
static void d3d12_set_hdr_expand_gamut(void* data, bool expand_gamut)
|
||||
{
|
||||
D3D12_RANGE read_range = { 0, 0 };
|
||||
dxgi_hdr_uniform_t *mapped_ubo = NULL;
|
||||
d3d12_video_t *d3d12 = (d3d12_video_t*)data;
|
||||
|
||||
d3d12->hdr.ubo_values.expandGamut = expand_gamut;
|
||||
D3D12Map(d3d12->hdr.ubo, 0, &read_range, (void**)&mapped_ubo);
|
||||
*mapped_ubo = d3d12->hdr.ubo_values;
|
||||
D3D12Unmap(d3d12->hdr.ubo, 0, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void d3d12_set_filtering(void* data, unsigned index, bool smooth, bool ctx_scaling)
|
||||
{
|
||||
int i;
|
||||
@ -494,9 +566,18 @@ static bool d3d12_gfx_set_shader(void* data, enum rarch_shader_type type, const
|
||||
if (!d3d12->pass[i].pipe)
|
||||
goto error;
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
d3d12->pass[i].rt.rt_view.ptr =
|
||||
d3d12->desc.rtv_heap.cpu.ptr +
|
||||
(countof(d3d12->chain.renderTargets) + (2 * i)) * d3d12->desc.rtv_heap.stride;
|
||||
d3d12->desc.rtv_heap.cpu.ptr +
|
||||
(countof(d3d12->chain.renderTargets) + 1 + (2 * i))
|
||||
* d3d12->desc.rtv_heap.stride;
|
||||
#else
|
||||
d3d12->pass[i].rt.rt_view.ptr =
|
||||
d3d12->desc.rtv_heap.cpu.ptr +
|
||||
(countof(d3d12->chain.renderTargets) + (2 * i))
|
||||
* d3d12->desc.rtv_heap.stride;
|
||||
#endif
|
||||
|
||||
d3d12->pass[i].feedback.rt_view.ptr = d3d12->pass[i].rt.rt_view.ptr + d3d12->desc.rtv_heap.stride;
|
||||
|
||||
d3d12->pass[i].textures.ptr =
|
||||
@ -562,12 +643,51 @@ 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;
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
desc.RTVFormats[0] = DXGI_FORMAT_R10G10B10A2_UNORM;
|
||||
|
||||
{
|
||||
static const char shader[] =
|
||||
#include "d3d_shaders/hdr_sm5.hlsl.h"
|
||||
;
|
||||
|
||||
static const D3D12_INPUT_ELEMENT_DESC inputElementDesc[] = {
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d12_vertex_t, position),
|
||||
D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(d3d12_vertex_t, texcoord),
|
||||
D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(d3d12_vertex_t, color),
|
||||
D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
};
|
||||
|
||||
if (!d3d_compile(shader, sizeof(shader), NULL, "VSMain", "vs_5_0", &vs_code))
|
||||
goto error;
|
||||
if (!d3d_compile(shader, sizeof(shader), NULL, "PSMain", "ps_5_0", &ps_code))
|
||||
goto error;
|
||||
|
||||
desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
desc.InputLayout.pInputElementDescs = inputElementDesc;
|
||||
desc.InputLayout.NumElements = countof(inputElementDesc);
|
||||
|
||||
if (!d3d12_init_pipeline(
|
||||
d3d12->device, vs_code, ps_code, NULL, &desc,
|
||||
&d3d12->pipes[VIDEO_SHADER_STOCK_HDR]))
|
||||
goto error;
|
||||
|
||||
Release(vs_code);
|
||||
Release(ps_code);
|
||||
vs_code = NULL;
|
||||
ps_code = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
desc.BlendState.RenderTarget[0] = d3d12_blend_enable_desc;
|
||||
desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
|
||||
{
|
||||
static const char shader[] =
|
||||
#include "../drivers/d3d_shaders/opaque_sm5.hlsl.h"
|
||||
#include "d3d_shaders/opaque_sm5.hlsl.h"
|
||||
;
|
||||
|
||||
static const D3D12_INPUT_ELEMENT_DESC inputElementDesc[] = {
|
||||
@ -839,6 +959,10 @@ static void d3d12_gfx_free(void* data)
|
||||
Release(d3d12->sprites.vbo);
|
||||
Release(d3d12->menu_pipeline_vbo);
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
Release(d3d12->hdr.ubo);
|
||||
#endif
|
||||
|
||||
Release(d3d12->frame.ubo);
|
||||
Release(d3d12->frame.vbo);
|
||||
Release(d3d12->frame.texture[0].handle);
|
||||
@ -847,6 +971,10 @@ static void d3d12_gfx_free(void* data)
|
||||
Release(d3d12->menu.texture.handle);
|
||||
Release(d3d12->menu.texture.upload_buffer);
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
d3d12_release_texture(&d3d12->chain.back_buffer);
|
||||
d3d12->chain.back_buffer.handle = NULL;
|
||||
#endif
|
||||
free(d3d12->desc.sampler_heap.map);
|
||||
free(d3d12->desc.srv_heap.map);
|
||||
free(d3d12->desc.rtv_heap.map);
|
||||
@ -890,6 +1018,10 @@ static void d3d12_gfx_free(void* data)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
video_driver_unset_hdr_support();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MONITOR
|
||||
win32_monitor_from_window();
|
||||
#endif
|
||||
@ -951,6 +1083,14 @@ static void *d3d12_gfx_init(const video_info_t* video,
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
d3d12->hdr.enable = settings->bools.video_hdr_enable;
|
||||
d3d12->hdr.max_output_nits = settings->floats.video_hdr_max_nits;
|
||||
d3d12->hdr.min_output_nits = 0.001f;
|
||||
d3d12->hdr.max_cll = 0.0f;
|
||||
d3d12->hdr.max_fall = 0.0f;
|
||||
#endif
|
||||
|
||||
d3d_input_driver(settings->arrays.input_driver, settings->arrays.input_joypad_driver, input, input_data);
|
||||
|
||||
if (!d3d12_init_base(d3d12))
|
||||
@ -1007,6 +1147,26 @@ static void *d3d12_gfx_init(const video_info_t* video,
|
||||
D3D12Unmap(d3d12->ubo, 0, NULL);
|
||||
}
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
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_values.mvp = d3d12->mvp_no_rot;
|
||||
d3d12->hdr.ubo_values.maxNits = settings->floats.video_hdr_max_nits;
|
||||
d3d12->hdr.ubo_values.paperWhiteNits = settings->floats.video_hdr_paper_white_nits;
|
||||
d3d12->hdr.ubo_values.contrast = settings->floats.video_hdr_contrast;
|
||||
d3d12->hdr.ubo_values.expandGamut = settings->bools.video_hdr_expand_gamut;
|
||||
|
||||
{
|
||||
dxgi_hdr_uniform_t* mapped_ubo;
|
||||
D3D12_RANGE read_range = { 0, 0 };
|
||||
D3D12Map(d3d12->hdr.ubo, 0, &read_range, (void**)&mapped_ubo);
|
||||
*mapped_ubo = d3d12->hdr.ubo_values;
|
||||
D3D12Unmap(d3d12->hdr.ubo, 0, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
d3d12_gfx_set_rotation(d3d12, 0);
|
||||
video_driver_set_size(d3d12->vp.full_width, d3d12->vp.full_height);
|
||||
d3d12->chain.viewport.Width = d3d12->vp.full_width;
|
||||
@ -1197,53 +1357,132 @@ static bool d3d12_gfx_frame(
|
||||
#ifdef HAVE_GFX_WIDGETS
|
||||
bool widgets_active = video_info->widgets_active;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
bool video_hdr_enable = video_info->hdr_enable;
|
||||
if (d3d12->resize_chain || (d3d12->hdr.enable != video_hdr_enable))
|
||||
#else
|
||||
if (d3d12->resize_chain)
|
||||
#endif
|
||||
{
|
||||
unsigned i;
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
d3d12->hdr.enable = video_hdr_enable;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < countof(d3d12->chain.renderTargets); i++)
|
||||
Release(d3d12->chain.renderTargets[i]);
|
||||
|
||||
DXGIResizeBuffers(d3d12->chain.handle, 0, 0, 0, DXGI_FORMAT_UNKNOWN, DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING);
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
if (d3d12->hdr.enable)
|
||||
{
|
||||
d3d12_release_texture(&d3d12->chain.back_buffer);
|
||||
d3d12->chain.back_buffer.handle = NULL;
|
||||
}
|
||||
DXGIResizeBuffers(d3d12->chain.handle,
|
||||
countof(d3d12->chain.renderTargets),
|
||||
video_width,
|
||||
video_height,
|
||||
d3d12->chain.formats[d3d12->chain.bit_depth],
|
||||
DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING);
|
||||
#else
|
||||
DXGIResizeBuffers(d3d12->chain.handle,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
DXGI_FORMAT_UNKNOWN,
|
||||
DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < countof(d3d12->chain.renderTargets); i++)
|
||||
{
|
||||
DXGIGetSwapChainBuffer(d3d12->chain.handle, i, &d3d12->chain.renderTargets[i]);
|
||||
DXGIGetSwapChainBuffer(d3d12->chain.handle, i,
|
||||
&d3d12->chain.renderTargets[i]);
|
||||
D3D12CreateRenderTargetView(
|
||||
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_width;
|
||||
d3d12->chain.viewport.Height = video_height;
|
||||
d3d12->chain.scissorRect.right = video_width;
|
||||
d3d12->chain.scissorRect.bottom = video_height;
|
||||
d3d12->resize_chain = false;
|
||||
d3d12->resize_viewport = true;
|
||||
d3d12->chain.viewport.Width = video_width;
|
||||
d3d12->chain.viewport.Height = video_height;
|
||||
d3d12->chain.scissorRect.right = video_width;
|
||||
d3d12->chain.scissorRect.bottom = video_height;
|
||||
d3d12->resize_chain = false;
|
||||
d3d12->resize_viewport = true;
|
||||
|
||||
d3d12->ubo_values.OutputSize.width = d3d12->chain.viewport.Width;
|
||||
d3d12->ubo_values.OutputSize.height = d3d12->chain.viewport.Height;
|
||||
|
||||
video_driver_set_size(video_width, video_height);
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
#ifdef __WINRT__
|
||||
if (!(d3d12->hdr.support =
|
||||
dxgi_check_display_hdr_support(d3d12->factory, uwp_get_corewindow())))
|
||||
d3d12->hdr.enable = false;
|
||||
#else
|
||||
if (!(d3d12->hdr.support =
|
||||
dxgi_check_display_hdr_support(d3d12->factory, main_window.hwnd)))
|
||||
d3d12->hdr.enable = false;
|
||||
#endif
|
||||
|
||||
if(d3d12->hdr.enable)
|
||||
{
|
||||
memset(&d3d12->chain.back_buffer,
|
||||
0, sizeof(d3d12->chain.back_buffer));
|
||||
d3d12->chain.back_buffer.desc.Width = video_width;
|
||||
d3d12->chain.back_buffer.desc.Height = video_height;
|
||||
d3d12->chain.back_buffer.desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
d3d12->chain.back_buffer.desc.Flags =
|
||||
D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||
d3d12->chain.back_buffer.srv_heap = &d3d12->desc.srv_heap;
|
||||
d3d12->chain.back_buffer.rt_view.ptr =
|
||||
d3d12->desc.rtv_heap.cpu.ptr
|
||||
+ countof(d3d12->chain.renderTargets)
|
||||
* d3d12->desc.rtv_heap.stride;
|
||||
d3d12_init_texture(d3d12->device, &d3d12->chain.back_buffer);
|
||||
|
||||
dxgi_swapchain_color_space(d3d12->chain.handle,
|
||||
&d3d12->chain.color_space,
|
||||
DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020);
|
||||
}
|
||||
else
|
||||
dxgi_swapchain_color_space(d3d12->chain.handle,
|
||||
&d3d12->chain.color_space,
|
||||
DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709);
|
||||
|
||||
dxgi_set_hdr_metadata(
|
||||
d3d12->chain.handle,
|
||||
d3d12->hdr.support,
|
||||
d3d12->chain.bit_depth,
|
||||
d3d12->chain.color_space,
|
||||
d3d12->hdr.max_output_nits,
|
||||
d3d12->hdr.min_output_nits,
|
||||
d3d12->hdr.max_cll,
|
||||
d3d12->hdr.max_fall);
|
||||
#endif
|
||||
}
|
||||
|
||||
D3D12ResetCommandAllocator(d3d12->queue.allocator);
|
||||
|
||||
D3D12ResetGraphicsCommandList(
|
||||
d3d12->queue.cmd, d3d12->queue.allocator, d3d12->pipes[VIDEO_SHADER_STOCK_BLEND]);
|
||||
d3d12->queue.cmd, d3d12->queue.allocator,
|
||||
d3d12->pipes[VIDEO_SHADER_STOCK_BLEND]);
|
||||
|
||||
{
|
||||
D3D12DescriptorHeap desc_heaps[] = { d3d12->desc.srv_heap.handle,
|
||||
d3d12->desc.sampler_heap.handle };
|
||||
D3D12SetDescriptorHeaps(d3d12->queue.cmd, countof(desc_heaps), desc_heaps);
|
||||
D3D12SetDescriptorHeaps(d3d12->queue.cmd,
|
||||
countof(desc_heaps), desc_heaps);
|
||||
}
|
||||
|
||||
#if 0 /* custom viewport doesn't call apply_state_changes, so we can't rely on this for now */
|
||||
#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);
|
||||
|
||||
D3D12IASetPrimitiveTopology(d3d12->queue.cmd, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
D3D12IASetPrimitiveTopology(d3d12->queue.cmd,
|
||||
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
|
||||
if (frame && width && height)
|
||||
{
|
||||
@ -1260,7 +1499,8 @@ static bool d3d12_gfx_frame(
|
||||
|
||||
if (d3d12->resize_render_targets)
|
||||
{
|
||||
/* release all render targets first to avoid memory fragmentation */
|
||||
/* Release all render targets first
|
||||
to avoid memory fragmentation */
|
||||
for (i = 0; i < d3d12->shader_preset->passes; i++)
|
||||
{
|
||||
d3d12_release_texture(&d3d12->pass[i].rt);
|
||||
@ -1277,9 +1517,10 @@ static bool d3d12_gfx_frame(
|
||||
else
|
||||
{
|
||||
int k;
|
||||
/* todo: what about frame-duping ?
|
||||
/* TODO/FIXME: what about frame-duping ?
|
||||
* maybe clone d3d12_texture_t with AddRef */
|
||||
d3d12_texture_t tmp = d3d12->frame.texture[d3d12->shader_preset->history_size];
|
||||
d3d12_texture_t tmp =
|
||||
d3d12->frame.texture[d3d12->shader_preset->history_size];
|
||||
for (k = d3d12->shader_preset->history_size; k > 0; k--)
|
||||
d3d12->frame.texture[k] = d3d12->frame.texture[k - 1];
|
||||
d3d12->frame.texture[0] = tmp;
|
||||
@ -1287,8 +1528,9 @@ static bool d3d12_gfx_frame(
|
||||
}
|
||||
}
|
||||
|
||||
/* either no history, or we moved a texture of a different size in the front slot */
|
||||
if (d3d12->frame.texture[0].desc.Width != width ||
|
||||
/* Either no history, or we moved a texture
|
||||
of a different size in the front slot */
|
||||
if (d3d12->frame.texture[0].desc.Width != width ||
|
||||
d3d12->frame.texture[0].desc.Height != height)
|
||||
{
|
||||
d3d12->frame.texture[0].desc.Width = width;
|
||||
@ -1300,7 +1542,8 @@ static bool d3d12_gfx_frame(
|
||||
if (d3d12->resize_render_targets)
|
||||
d3d12_init_render_targets(d3d12, width, height);
|
||||
|
||||
d3d12_update_texture(width, height, pitch, d3d12->format, frame, &d3d12->frame.texture[0]);
|
||||
d3d12_update_texture(width, height, pitch, d3d12->format,
|
||||
frame, &d3d12->frame.texture[0]);
|
||||
|
||||
d3d12_upload_texture(d3d12->queue.cmd, &d3d12->frame.texture[0],
|
||||
d3d12);
|
||||
@ -1311,7 +1554,8 @@ static bool d3d12_gfx_frame(
|
||||
|
||||
if (d3d12->shader_preset)
|
||||
{
|
||||
D3D12SetGraphicsRootSignature(d3d12->queue.cmd, d3d12->desc.sl_rootSignature);
|
||||
D3D12SetGraphicsRootSignature(d3d12->queue.cmd,
|
||||
d3d12->desc.sl_rootSignature);
|
||||
|
||||
for (i = 0; i < d3d12->shader_preset->passes; i++)
|
||||
{
|
||||
@ -1330,16 +1574,17 @@ static bool d3d12_gfx_frame(
|
||||
D3D12SetPipelineState(d3d12->queue.cmd, d3d12->pass[i].pipe);
|
||||
|
||||
if (d3d12->shader_preset->pass[i].frame_count_mod)
|
||||
d3d12->pass[i].frame_count =
|
||||
frame_count % d3d12->shader_preset->pass[i].frame_count_mod;
|
||||
d3d12->pass[i].frame_count = frame_count
|
||||
% d3d12->shader_preset->pass[i].frame_count_mod;
|
||||
else
|
||||
d3d12->pass[i].frame_count = frame_count;
|
||||
|
||||
#ifdef HAVE_REWIND
|
||||
d3d12->pass[i].frame_direction = state_manager_frame_is_reversed() ? -1 : 1;
|
||||
#else
|
||||
d3d12->pass[i].frame_direction = 1;
|
||||
if (state_manager_frame_is_reversed())
|
||||
d3d12->pass[i].frame_direction = -1;
|
||||
else
|
||||
#endif
|
||||
d3d12->pass[i].frame_direction = 1;
|
||||
|
||||
for (j = 0; j < SLANG_CBUFFER_MAX; j++)
|
||||
{
|
||||
@ -1351,17 +1596,21 @@ static bool d3d12_gfx_frame(
|
||||
uint8_t* mapped_data = NULL;
|
||||
uniform_sem_t* uniform = buffer_sem->uniforms;
|
||||
|
||||
D3D12Map(d3d12->pass[i].buffers[j], 0, &range, (void**)&mapped_data);
|
||||
D3D12Map(d3d12->pass[i].buffers[j], 0, &range,
|
||||
(void**)&mapped_data);
|
||||
while (uniform->size)
|
||||
{
|
||||
if (uniform->data)
|
||||
memcpy(mapped_data + uniform->offset, uniform->data, uniform->size);
|
||||
memcpy(mapped_data + uniform->offset,
|
||||
uniform->data, uniform->size);
|
||||
uniform++;
|
||||
}
|
||||
D3D12Unmap(d3d12->pass[i].buffers[j], 0, NULL);
|
||||
|
||||
D3D12SetGraphicsRootConstantBufferView(
|
||||
d3d12->queue.cmd, j == SLANG_CBUFFER_UBO ? ROOT_ID_UBO : ROOT_ID_PC,
|
||||
d3d12->queue.cmd, j == SLANG_CBUFFER_UBO
|
||||
? ROOT_ID_UBO
|
||||
: ROOT_ID_PC,
|
||||
d3d12->pass[i].buffer_view[j].BufferLocation);
|
||||
}
|
||||
}
|
||||
@ -1375,15 +1624,19 @@ static bool d3d12_gfx_frame(
|
||||
{
|
||||
{
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE handle = {
|
||||
d3d12->pass[i].textures.ptr - d3d12->desc.srv_heap.gpu.ptr +
|
||||
d3d12->desc.srv_heap.cpu.ptr +
|
||||
texture_sem->binding * d3d12->desc.srv_heap.stride
|
||||
d3d12->pass[i].textures.ptr
|
||||
- d3d12->desc.srv_heap.gpu.ptr
|
||||
+ d3d12->desc.srv_heap.cpu.ptr
|
||||
+ texture_sem->binding * d3d12->desc.srv_heap.stride
|
||||
};
|
||||
d3d12_texture_t* tex = (d3d12_texture_t*)texture_sem->texture_data;
|
||||
d3d12_texture_t* tex =
|
||||
(d3d12_texture_t*)texture_sem->texture_data;
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC desc = { tex->desc.Format };
|
||||
|
||||
desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||
desc.Shader4ComponentMapping =
|
||||
D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
desc.ViewDimension =
|
||||
D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||
desc.Texture2D.MipLevels = tex->desc.MipLevels;
|
||||
|
||||
D3D12CreateShaderResourceView(d3d12->device,
|
||||
@ -1392,9 +1645,11 @@ static bool d3d12_gfx_frame(
|
||||
|
||||
{
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE handle = {
|
||||
d3d12->pass[i].samplers.ptr - d3d12->desc.sampler_heap.gpu.ptr +
|
||||
d3d12->desc.sampler_heap.cpu.ptr +
|
||||
texture_sem->binding * d3d12->desc.sampler_heap.stride
|
||||
d3d12->pass[i].samplers.ptr
|
||||
- d3d12->desc.sampler_heap.gpu.ptr
|
||||
+ d3d12->desc.sampler_heap.cpu.ptr
|
||||
+ texture_sem->binding
|
||||
* d3d12->desc.sampler_heap.stride
|
||||
};
|
||||
D3D12_SAMPLER_DESC desc = { D3D12_FILTER_MIN_MAG_MIP_LINEAR };
|
||||
|
||||
@ -1435,29 +1690,37 @@ static bool d3d12_gfx_frame(
|
||||
}
|
||||
|
||||
D3D12SetGraphicsRootDescriptorTable(
|
||||
d3d12->queue.cmd, ROOT_ID_TEXTURE_T, d3d12->pass[i].textures);
|
||||
d3d12->queue.cmd, ROOT_ID_TEXTURE_T,
|
||||
d3d12->pass[i].textures);
|
||||
D3D12SetGraphicsRootDescriptorTable(
|
||||
d3d12->queue.cmd, ROOT_ID_SAMPLER_T, d3d12->pass[i].samplers);
|
||||
d3d12->queue.cmd, ROOT_ID_SAMPLER_T,
|
||||
d3d12->pass[i].samplers);
|
||||
}
|
||||
|
||||
if (d3d12->pass[i].rt.handle)
|
||||
{
|
||||
d3d12_resource_transition(
|
||||
d3d12->queue.cmd, d3d12->pass[i].rt.handle,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
|
||||
D3D12OMSetRenderTargets(d3d12->queue.cmd, 1, &d3d12->pass[i].rt.rt_view, FALSE, NULL);
|
||||
D3D12OMSetRenderTargets(d3d12->queue.cmd, 1,
|
||||
&d3d12->pass[i].rt.rt_view, FALSE, NULL);
|
||||
#if 0
|
||||
D3D12ClearRenderTargetView(
|
||||
d3d12->queue.cmd, d3d12->pass[i].rt.rt_view, d3d12->chain.clearcolor, 0, NULL);
|
||||
d3d12->queue.cmd, d3d12->pass[i].rt.rt_view,
|
||||
d3d12->chain.clearcolor, 0, NULL);
|
||||
#endif
|
||||
D3D12RSSetViewports(d3d12->queue.cmd, 1, &d3d12->pass[i].viewport);
|
||||
D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &d3d12->pass[i].scissorRect);
|
||||
D3D12RSSetViewports(d3d12->queue.cmd, 1,
|
||||
&d3d12->pass[i].viewport);
|
||||
D3D12RSSetScissorRects(d3d12->queue.cmd, 1,
|
||||
&d3d12->pass[i].scissorRect);
|
||||
|
||||
D3D12DrawInstanced(d3d12->queue.cmd, 4, 1, 0, 0);
|
||||
|
||||
d3d12_resource_transition(
|
||||
d3d12->queue.cmd, d3d12->pass[i].rt.handle, D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
d3d12->queue.cmd, d3d12->pass[i].rt.handle,
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
texture = &d3d12->pass[i].rt;
|
||||
}
|
||||
@ -1471,31 +1734,68 @@ static bool d3d12_gfx_frame(
|
||||
|
||||
if (texture)
|
||||
{
|
||||
D3D12SetPipelineState(d3d12->queue.cmd, d3d12->pipes[VIDEO_SHADER_STOCK_BLEND]);
|
||||
D3D12SetGraphicsRootSignature(d3d12->queue.cmd, d3d12->desc.rootSignature);
|
||||
D3D12SetPipelineState(d3d12->queue.cmd,
|
||||
d3d12->pipes[VIDEO_SHADER_STOCK_BLEND]);
|
||||
D3D12SetGraphicsRootSignature(d3d12->queue.cmd,
|
||||
d3d12->desc.rootSignature);
|
||||
d3d12_set_texture(d3d12->queue.cmd, &d3d12->frame.texture[0]);
|
||||
d3d12_set_sampler(d3d12->queue.cmd, d3d12->samplers[RARCH_FILTER_UNSPEC][RARCH_WRAP_DEFAULT]);
|
||||
d3d12_set_sampler(d3d12->queue.cmd,
|
||||
d3d12->samplers[RARCH_FILTER_UNSPEC][RARCH_WRAP_DEFAULT]);
|
||||
D3D12SetGraphicsRootConstantBufferView(
|
||||
d3d12->queue.cmd, ROOT_ID_UBO, d3d12->frame.ubo_view.BufferLocation);
|
||||
d3d12->queue.cmd, ROOT_ID_UBO,
|
||||
d3d12->frame.ubo_view.BufferLocation);
|
||||
}
|
||||
|
||||
d3d12->chain.frame_index = DXGIGetCurrentBackBufferIndex(d3d12->chain.handle);
|
||||
d3d12_resource_transition(
|
||||
d3d12->queue.cmd, d3d12->chain.renderTargets[d3d12->chain.frame_index],
|
||||
D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
d3d12->chain.frame_index = DXGIGetCurrentBackBufferIndex(
|
||||
d3d12->chain.handle);
|
||||
|
||||
D3D12OMSetRenderTargets(
|
||||
d3d12->queue.cmd, 1, &d3d12->chain.desc_handles[d3d12->chain.frame_index], FALSE, NULL);
|
||||
D3D12ClearRenderTargetView(
|
||||
d3d12->queue.cmd, d3d12->chain.desc_handles[d3d12->chain.frame_index],
|
||||
d3d12->chain.clearcolor, 0, NULL);
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
if(d3d12->hdr.enable)
|
||||
{
|
||||
d3d12_resource_transition(
|
||||
d3d12->queue.cmd, d3d12->chain.back_buffer.handle,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
|
||||
D3D12OMSetRenderTargets(
|
||||
d3d12->queue.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
|
||||
*/
|
||||
D3D12ClearRenderTargetView(
|
||||
d3d12->queue.cmd, d3d12->chain.back_buffer.rt_view,
|
||||
d3d12->chain.clearcolor, 0, NULL);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
d3d12_resource_transition(
|
||||
d3d12->queue.cmd,
|
||||
d3d12->chain.renderTargets[d3d12->chain.frame_index],
|
||||
D3D12_RESOURCE_STATE_PRESENT,
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
|
||||
D3D12OMSetRenderTargets(
|
||||
d3d12->queue.cmd, 1,
|
||||
&d3d12->chain.desc_handles[d3d12->chain.frame_index],
|
||||
FALSE, NULL);
|
||||
D3D12ClearRenderTargetView(
|
||||
d3d12->queue.cmd,
|
||||
d3d12->chain.desc_handles[d3d12->chain.frame_index],
|
||||
d3d12->chain.clearcolor, 0, NULL);
|
||||
}
|
||||
|
||||
D3D12RSSetViewports(d3d12->queue.cmd, 1, &d3d12->frame.viewport);
|
||||
D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &d3d12->frame.scissorRect);
|
||||
|
||||
D3D12DrawInstanced(d3d12->queue.cmd, 4, 1, 0, 0);
|
||||
|
||||
D3D12SetPipelineState(d3d12->queue.cmd, d3d12->pipes[VIDEO_SHADER_STOCK_BLEND]);
|
||||
D3D12SetPipelineState(d3d12->queue.cmd,
|
||||
d3d12->pipes[VIDEO_SHADER_STOCK_BLEND]);
|
||||
D3D12SetGraphicsRootSignature(d3d12->queue.cmd, d3d12->desc.rootSignature);
|
||||
|
||||
if (d3d12->menu.enabled && d3d12->menu.texture.handle)
|
||||
@ -1520,7 +1820,8 @@ static bool d3d12_gfx_frame(
|
||||
|
||||
d3d12->sprites.pipe = d3d12->sprites.pipe_noblend;
|
||||
D3D12SetPipelineState(d3d12->queue.cmd, d3d12->sprites.pipe);
|
||||
D3D12IASetPrimitiveTopology(d3d12->queue.cmd, D3D_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
D3D12IASetPrimitiveTopology(d3d12->queue.cmd,
|
||||
D3D_PRIMITIVE_TOPOLOGY_POINTLIST);
|
||||
|
||||
d3d12->sprites.enabled = true;
|
||||
|
||||
@ -1529,9 +1830,12 @@ static bool d3d12_gfx_frame(
|
||||
if (d3d12->menu.enabled)
|
||||
#endif
|
||||
{
|
||||
D3D12RSSetViewports(d3d12->queue.cmd, 1, &d3d12->chain.viewport);
|
||||
D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &d3d12->chain.scissorRect);
|
||||
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->sprites.vbo_view);
|
||||
D3D12RSSetViewports(d3d12->queue.cmd, 1,
|
||||
&d3d12->chain.viewport);
|
||||
D3D12RSSetScissorRects(d3d12->queue.cmd, 1,
|
||||
&d3d12->chain.scissorRect);
|
||||
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1,
|
||||
&d3d12->sprites.vbo_view);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1544,10 +1848,14 @@ static bool d3d12_gfx_frame(
|
||||
{
|
||||
if (osd_params)
|
||||
{
|
||||
D3D12SetPipelineState(d3d12->queue.cmd, d3d12->sprites.pipe_blend);
|
||||
D3D12RSSetViewports(d3d12->queue.cmd, 1, &d3d12->chain.viewport);
|
||||
D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &d3d12->chain.scissorRect);
|
||||
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->sprites.vbo_view);
|
||||
D3D12SetPipelineState(d3d12->queue.cmd,
|
||||
d3d12->sprites.pipe_blend);
|
||||
D3D12RSSetViewports(d3d12->queue.cmd, 1,
|
||||
&d3d12->chain.viewport);
|
||||
D3D12RSSetScissorRects(d3d12->queue.cmd, 1,
|
||||
&d3d12->chain.scissorRect);
|
||||
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1,
|
||||
&d3d12->sprites.vbo_view);
|
||||
font_driver_render_msg(d3d12, stat_text,
|
||||
(const struct font_params*)osd_params, NULL);
|
||||
}
|
||||
@ -1557,17 +1865,21 @@ static bool d3d12_gfx_frame(
|
||||
{
|
||||
if (d3d12->overlays.fullscreen)
|
||||
{
|
||||
D3D12RSSetViewports(d3d12->queue.cmd, 1, &d3d12->chain.viewport);
|
||||
D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &d3d12->chain.scissorRect);
|
||||
D3D12RSSetViewports(d3d12->queue.cmd, 1,
|
||||
&d3d12->chain.viewport);
|
||||
D3D12RSSetScissorRects(d3d12->queue.cmd, 1,
|
||||
&d3d12->chain.scissorRect);
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D12RSSetViewports(d3d12->queue.cmd, 1, &d3d12->frame.viewport);
|
||||
D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &d3d12->frame.scissorRect);
|
||||
D3D12RSSetViewports(d3d12->queue.cmd, 1,
|
||||
&d3d12->frame.viewport);
|
||||
D3D12RSSetScissorRects(d3d12->queue.cmd, 1,
|
||||
&d3d12->frame.scissorRect);
|
||||
}
|
||||
|
||||
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->overlays.vbo_view);
|
||||
|
||||
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1,
|
||||
&d3d12->overlays.vbo_view);
|
||||
D3D12SetPipelineState(d3d12->queue.cmd, d3d12->sprites.pipe_blend);
|
||||
|
||||
D3D12SetGraphicsRootDescriptorTable(
|
||||
@ -1582,7 +1894,8 @@ static bool d3d12_gfx_frame(
|
||||
d3d12);
|
||||
|
||||
D3D12SetGraphicsRootDescriptorTable(
|
||||
d3d12->queue.cmd, ROOT_ID_TEXTURE_T, d3d12->overlays.textures[i].gpu_descriptor[0]);
|
||||
d3d12->queue.cmd, ROOT_ID_TEXTURE_T,
|
||||
d3d12->overlays.textures[i].gpu_descriptor[0]);
|
||||
D3D12DrawInstanced(d3d12->queue.cmd, 1, 1, i, 0);
|
||||
}
|
||||
}
|
||||
@ -1595,21 +1908,78 @@ static bool d3d12_gfx_frame(
|
||||
|
||||
if (msg && *msg)
|
||||
{
|
||||
D3D12SetPipelineState(d3d12->queue.cmd, d3d12->sprites.pipe_blend);
|
||||
D3D12RSSetViewports(d3d12->queue.cmd, 1, &d3d12->chain.viewport);
|
||||
D3D12RSSetScissorRects(d3d12->queue.cmd, 1, &d3d12->chain.scissorRect);
|
||||
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1, &d3d12->sprites.vbo_view);
|
||||
D3D12SetPipelineState(d3d12->queue.cmd,
|
||||
d3d12->sprites.pipe_blend);
|
||||
D3D12RSSetViewports(d3d12->queue.cmd, 1,
|
||||
&d3d12->chain.viewport);
|
||||
D3D12RSSetScissorRects(d3d12->queue.cmd, 1,
|
||||
&d3d12->chain.scissorRect);
|
||||
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1,
|
||||
&d3d12->sprites.vbo_view);
|
||||
|
||||
font_driver_render_msg(d3d12, msg, NULL, NULL);
|
||||
}
|
||||
d3d12->sprites.enabled = false;
|
||||
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
/* Copy over back buffer to swap chain render targets */
|
||||
if (d3d12->hdr.enable)
|
||||
{
|
||||
d3d12_resource_transition(
|
||||
d3d12->queue.cmd,
|
||||
d3d12->chain.renderTargets[d3d12->chain.frame_index],
|
||||
D3D12_RESOURCE_STATE_PRESENT,
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
|
||||
d3d12_resource_transition(
|
||||
d3d12->queue.cmd, d3d12->chain.back_buffer.handle,
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
D3D12SetPipelineState(d3d12->queue.cmd,
|
||||
d3d12->pipes[VIDEO_SHADER_STOCK_HDR]);
|
||||
|
||||
D3D12OMSetRenderTargets(
|
||||
d3d12->queue.cmd, 1,
|
||||
&d3d12->chain.desc_handles[d3d12->chain.frame_index],
|
||||
FALSE, NULL);
|
||||
D3D12ClearRenderTargetView(
|
||||
d3d12->queue.cmd,
|
||||
d3d12->chain.desc_handles[d3d12->chain.frame_index],
|
||||
d3d12->chain.clearcolor, 0, NULL);
|
||||
|
||||
D3D12SetGraphicsRootSignature(d3d12->queue.cmd,
|
||||
d3d12->desc.rootSignature);
|
||||
d3d12_set_texture(d3d12->queue.cmd, &d3d12->chain.back_buffer);
|
||||
d3d12_set_sampler(d3d12->queue.cmd,
|
||||
d3d12->samplers[RARCH_FILTER_UNSPEC][RARCH_WRAP_DEFAULT]);
|
||||
D3D12SetGraphicsRootConstantBufferView(
|
||||
d3d12->queue.cmd, ROOT_ID_UBO,
|
||||
d3d12->hdr.ubo_view.BufferLocation);
|
||||
D3D12IASetVertexBuffers(d3d12->queue.cmd, 0, 1,
|
||||
&d3d12->frame.vbo_view);
|
||||
|
||||
D3D12IASetPrimitiveTopology(d3d12->queue.cmd,
|
||||
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||
|
||||
D3D12RSSetViewports(d3d12->queue.cmd, 1,
|
||||
&d3d12->chain.viewport);
|
||||
D3D12RSSetScissorRects(d3d12->queue.cmd, 1,
|
||||
&d3d12->chain.scissorRect);
|
||||
|
||||
D3D12DrawInstanced(d3d12->queue.cmd, 4, 1, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
d3d12_resource_transition(
|
||||
d3d12->queue.cmd, d3d12->chain.renderTargets[d3d12->chain.frame_index],
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
|
||||
d3d12->queue.cmd,
|
||||
d3d12->chain.renderTargets[d3d12->chain.frame_index],
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
D3D12_RESOURCE_STATE_PRESENT);
|
||||
|
||||
D3D12CloseGraphicsCommandList(d3d12->queue.cmd);
|
||||
|
||||
D3D12ExecuteGraphicsCommandLists(d3d12->queue.handle, 1, &d3d12->queue.cmd);
|
||||
D3D12ExecuteGraphicsCommandLists(d3d12->queue.handle, 1,
|
||||
&d3d12->queue.cmd);
|
||||
|
||||
#if defined(_WIN32) && !defined(__WINRT__)
|
||||
win32_update_title();
|
||||
@ -1890,6 +2260,17 @@ static const video_poke_interface_t d3d12_poke_interface = {
|
||||
d3d12_gfx_get_current_shader,
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL, /* get_hw_render_interface */
|
||||
#ifdef HAVE_DXGI_HDR
|
||||
d3d12_set_hdr_max_nits,
|
||||
d3d12_set_hdr_paper_white_nits,
|
||||
d3d12_set_hdr_contrast,
|
||||
d3d12_set_hdr_expand_gamut,
|
||||
#else
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
#endif
|
||||
};
|
||||
|
||||
static void d3d12_gfx_get_poke_interface(void* data, const video_poke_interface_t** iface)
|
||||
|
@ -1831,7 +1831,11 @@ static const video_poke_interface_t d3d_poke_interface = {
|
||||
NULL, /* grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL /* get_hw_render_interface */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void d3d8_get_poke_interface(void *data,
|
||||
|
@ -1976,7 +1976,11 @@ static const video_poke_interface_t d3d9_poke_interface = {
|
||||
NULL, /* grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL /* get_hw_render_interface */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void d3d9_get_poke_interface(void *data,
|
||||
|
120
gfx/drivers/d3d_shaders/hdr_sm5.hlsl.h
Normal file
120
gfx/drivers/d3d_shaders/hdr_sm5.hlsl.h
Normal file
@ -0,0 +1,120 @@
|
||||
|
||||
#define SRC(...) #__VA_ARGS__
|
||||
SRC(
|
||||
struct UBO
|
||||
{
|
||||
float4x4 modelViewProj;
|
||||
float contrast; /* 2.0f; */
|
||||
float paperWhiteNits; /* 200.0f; */
|
||||
float maxNits; /* 1000.0f; */
|
||||
float expandGamut; /* 1.0f; */
|
||||
};
|
||||
uniform UBO global;
|
||||
|
||||
struct PSInput
|
||||
{
|
||||
float4 position : SV_POSITION;
|
||||
float2 texcoord : TEXCOORD0;
|
||||
float4 color : COLOR;
|
||||
};
|
||||
PSInput VSMain(float4 position : POSITION, float2 texcoord : TEXCOORD0, float4 color : COLOR)
|
||||
{
|
||||
PSInput result;
|
||||
result.position = mul(global.modelViewProj, position);
|
||||
result.texcoord = texcoord;
|
||||
result.color = color;
|
||||
return result;
|
||||
}
|
||||
uniform sampler s0;
|
||||
uniform Texture2D <float4> t0;
|
||||
|
||||
static const float kMaxNitsFor2084 = 10000.0f;
|
||||
static const float kEpsilon = 0.0001f;
|
||||
static const float kLumaChannelRatio = 0.25f;
|
||||
|
||||
static const float3x3 k709to2020 =
|
||||
{
|
||||
{ 0.6274040f, 0.3292820f, 0.0433136f },
|
||||
{ 0.0690970f, 0.9195400f, 0.0113612f },
|
||||
{ 0.0163916f, 0.0880132f, 0.8955950f }
|
||||
};
|
||||
|
||||
static const float3x3 kP3to2020 =
|
||||
{
|
||||
{ 0.753845f, 0.198593f, 0.047562f },
|
||||
{ 0.0457456f, 0.941777f, 0.0124772f },
|
||||
{ -0.00121055f, 0.0176041f, 0.983607f }
|
||||
};
|
||||
|
||||
/* START Converted from (Copyright (c) Microsoft Corporation - Licensed under the MIT License.) https://github.com/microsoft/Xbox-ATG-Samples/tree/master/Kits/ATGTK/HDR */
|
||||
static const float3x3 kExpanded709to2020 =
|
||||
{
|
||||
{ 0.6274040f, 0.3292820f, 0.0433136f },
|
||||
{ 0.0457456, 0.941777, 0.0124772 },
|
||||
{ -0.00121055, 0.0176041, 0.983607 }
|
||||
};
|
||||
|
||||
float3 LinearToST2084(float3 normalizedLinearValue)
|
||||
{
|
||||
float3 ST2084 = pow((0.8359375f + 18.8515625f * pow(abs(normalizedLinearValue), 0.1593017578f)) / (1.0f + 18.6875f * pow(abs(normalizedLinearValue), 0.1593017578f)), 78.84375f);
|
||||
return ST2084; /* Don't clamp between [0..1], so we can still perform operations on scene values higher than 10,000 nits */
|
||||
}
|
||||
/* END Converted from (Copyright (c) Microsoft Corporation - Licensed under the MIT License.) https://github.com/microsoft/Xbox-ATG-Samples/tree/master/Kits/ATGTK/HDR */
|
||||
|
||||
float3 SRGBToLinear(float3 color)
|
||||
{
|
||||
float3 scale = color / 12.92f;
|
||||
float3 gamma = pow(abs(color + 0.055f) / 1.055f, 2.4f);
|
||||
|
||||
return float3( color.x < 0.04045f ? scale.x : gamma.x,
|
||||
color.y < 0.04045f ? scale.y : gamma.y,
|
||||
color.z < 0.04045f ? scale.z : gamma.z);
|
||||
}
|
||||
|
||||
float4 Hdr(float4 sdr)
|
||||
{
|
||||
sdr.xyz = pow(abs(sdr.xyz), 2.2f / global.contrast); /* Display Gamma - needs to be determined by calibration screen but should be in the 0.8 - 1.4 range */
|
||||
|
||||
float luma = dot(sdr.xyz, float3(0.2126, 0.7152, 0.0722)); /* Rec BT.709 luma coefficients - https://en.wikipedia.org/wiki/Luma_(video) */
|
||||
|
||||
/* Inverse reinhard tonemap */
|
||||
float maxValue = (global.maxNits / global.paperWhiteNits) + kEpsilon;
|
||||
float elbow = maxValue / (maxValue - 1.0f); /* Convert (1.0 + epsilon) to infinite to range 1001 -> 1.0 */
|
||||
float offset = 1.0f - ((0.5f * elbow) / (elbow - 0.5f)); /* Convert 1001 to 1.0 to range 0.5 -> 1.0 */
|
||||
|
||||
float hdrLumaInvTonemap = offset + ((luma * elbow) / (elbow - luma));
|
||||
float sdrLumaInvTonemap = luma / ((1.0f + kEpsilon) - luma); /* Convert the srd < 0.5 to 0.0 -> 1.0 range */
|
||||
|
||||
float lumaInvTonemap = (luma > 0.5f) ? hdrLumaInvTonemap : sdrLumaInvTonemap;
|
||||
float3 perLuma = sdr.xyz / (luma + kEpsilon) * lumaInvTonemap;
|
||||
|
||||
float3 hdrInvTonemap = offset + ((sdr.xyz * elbow) / (elbow - sdr.xyz));
|
||||
float3 sdrInvTonemap = sdr.xyz / ((1.0f + kEpsilon) - sdr.xyz); /* Convert the srd < 0.5 to 0.0 -> 1.0 range */
|
||||
|
||||
float3 perChannel = float3(sdr.x > 0.5f ? hdrInvTonemap.x : sdrInvTonemap.x,
|
||||
sdr.y > 0.5f ? hdrInvTonemap.y : sdrInvTonemap.y,
|
||||
sdr.z > 0.5f ? hdrInvTonemap.z : sdrInvTonemap.z);
|
||||
|
||||
float3 hdr = lerp(perLuma, perChannel, kLumaChannelRatio);
|
||||
|
||||
/* Now convert into HDR10 */
|
||||
float3 rec2020 = mul(k709to2020, hdr);
|
||||
|
||||
if(global.expandGamut > 0.0f)
|
||||
{
|
||||
rec2020 = mul( kExpanded709to2020, hdr);
|
||||
}
|
||||
|
||||
float3 linearColour = rec2020 * (global.paperWhiteNits / kMaxNitsFor2084);
|
||||
float3 hdr10 = LinearToST2084(linearColour);
|
||||
|
||||
return float4(hdr10, sdr.w);
|
||||
}
|
||||
|
||||
float4 PSMain(PSInput input) : SV_TARGET
|
||||
{
|
||||
float4 sdr = input.color * t0.Sample(s0, input.texcoord);
|
||||
|
||||
return Hdr(sdr);
|
||||
};
|
||||
)
|
@ -600,7 +600,11 @@ static const video_poke_interface_t dispmanx_poke_interface = {
|
||||
NULL, /* grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL /* get_hw_render_interface */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void dispmanx_gfx_get_poke_interface(void *data,
|
||||
|
@ -956,7 +956,11 @@ static const video_poke_interface_t drm_poke_interface = {
|
||||
NULL, /* grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL /* get_hw_render_interface */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void drm_gfx_get_poke_interface(void *data,
|
||||
|
@ -1498,7 +1498,11 @@ static const video_poke_interface_t exynos_poke_interface = {
|
||||
NULL, /* grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL /* get_hw_render_interface */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void exynos_gfx_get_poke_interface(void *data,
|
||||
|
@ -386,6 +386,10 @@ static const video_poke_interface_t fpga_poke_interface = {
|
||||
#ifdef HAVE_MENU
|
||||
NULL,
|
||||
#endif
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void fpga_gfx_get_poke_interface(void *data,
|
||||
|
@ -724,7 +724,11 @@ static const video_poke_interface_t gdi_poke_interface = {
|
||||
NULL, /* grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL /* get_hw_render_interface */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void gdi_gfx_get_poke_interface(void *data,
|
||||
|
@ -4588,7 +4588,11 @@ static const video_poke_interface_t gl2_poke_interface = {
|
||||
NULL,
|
||||
gl2_get_current_shader,
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL /* get_hw_render_interface */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void gl2_get_poke_interface(void *data,
|
||||
|
@ -1448,7 +1448,11 @@ static const video_poke_interface_t gl1_poke_interface = {
|
||||
NULL, /* grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL /* get_hw_render_interface */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void gl1_gfx_get_poke_interface(void *data,
|
||||
|
@ -2287,6 +2287,10 @@ static const video_poke_interface_t gl_core_poke_interface = {
|
||||
gl_core_get_current_shader,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void gl_core_get_poke_interface(void *data,
|
||||
|
@ -1735,6 +1735,10 @@ static const video_poke_interface_t wiiu_poke_interface = {
|
||||
wiiu_gfx_get_current_shader,
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void wiiu_gfx_get_poke_interface(void *data,
|
||||
|
@ -1372,7 +1372,11 @@ static const video_poke_interface_t gx_poke_interface = {
|
||||
NULL, /* grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL /* get_hw_render_interface */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void gx_get_poke_interface(void *data,
|
||||
|
@ -399,19 +399,31 @@ static uint32_t metal_get_flags(void *data)
|
||||
}
|
||||
|
||||
static const video_poke_interface_t metal_poke_interface = {
|
||||
.get_flags = metal_get_flags,
|
||||
.load_texture = metal_load_texture,
|
||||
.unload_texture = metal_unload_texture,
|
||||
.set_video_mode = metal_set_video_mode,
|
||||
.get_refresh_rate = metal_get_refresh_rate,
|
||||
.set_filtering = metal_set_filtering,
|
||||
.set_aspect_ratio = metal_set_aspect_ratio,
|
||||
.apply_state_changes = metal_apply_state_changes,
|
||||
.set_texture_frame = metal_set_texture_frame,
|
||||
.set_texture_enable = metal_set_texture_enable,
|
||||
.set_osd_msg = font_driver_render_msg,
|
||||
.show_mouse = metal_show_mouse,
|
||||
.get_current_shader = metal_get_current_shader,
|
||||
metal_get_flags,
|
||||
metal_load_texture,
|
||||
metal_unload_texture,
|
||||
metal_set_video_mode,
|
||||
metal_get_refresh_rate,
|
||||
metal_set_filtering,
|
||||
NULL, /* get_video_output_size */
|
||||
NULL, /* get_video_output_prev */
|
||||
NULL, /* get_video_output_next */
|
||||
NULL, /* get_current_framebuffer */
|
||||
NULL, /* get_proc_address */
|
||||
metal_set_aspect_ratio,
|
||||
metal_apply_state_changes,
|
||||
metal_set_texture_frame,
|
||||
metal_set_texture_enable,
|
||||
font_driver_render_msg,
|
||||
metal_show_mouse,
|
||||
NULL, /* grab_mouse_toggle */
|
||||
metal_get_current_shader,
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void metal_get_poke_interface(void *data,
|
||||
|
@ -1123,7 +1123,11 @@ static const video_poke_interface_t omap_gfx_poke_interface = {
|
||||
NULL, /* grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL /* get_hw_render_interface */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void omap_gfx_get_poke_interface(void *data,
|
||||
|
@ -465,7 +465,11 @@ static const video_poke_interface_t ps2_poke_interface = {
|
||||
NULL, /* grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
ps2_get_hw_render_interface /* get_hw_render_interface */
|
||||
ps2_get_hw_render_interface, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void ps2_gfx_get_poke_interface(void *data,
|
||||
|
@ -802,7 +802,11 @@ static const video_poke_interface_t psp_poke_interface = {
|
||||
NULL, /* grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL /* get_hw_render_interface */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void psp_get_poke_interface(void *data,
|
||||
|
@ -720,7 +720,11 @@ static const video_poke_interface_t rsx_poke_interface = {
|
||||
NULL, /* grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL /* get_hw_render_interface */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void rsx_get_poke_interface(void* data,
|
||||
|
@ -1106,7 +1106,11 @@ static const video_poke_interface_t sdl_dingux_poke_interface = {
|
||||
NULL, /* sdl_grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL /* get_hw_render_interface */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void sdl_dingux_get_poke_interface(void *data, const video_poke_interface_t **iface)
|
||||
|
@ -547,7 +547,11 @@ static const video_poke_interface_t sdl_poke_interface = {
|
||||
sdl_grab_mouse_toggle,
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL /* get_hw_render_interface */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void sdl_get_poke_interface(void *data, const video_poke_interface_t **iface)
|
||||
|
@ -1393,7 +1393,11 @@ static const video_poke_interface_t sdl_rs90_poke_interface = {
|
||||
NULL, /* sdl_grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL /* get_hw_render_interface */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void sdl_rs90_get_poke_interface(void *data, const video_poke_interface_t **iface)
|
||||
|
@ -551,6 +551,10 @@ static const video_poke_interface_t sixel_poke_interface = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void sixel_gfx_get_poke_interface(void *data,
|
||||
|
@ -951,7 +951,11 @@ static const video_poke_interface_t sunxi_poke_interface = {
|
||||
NULL, /* grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL /* get_hw_render_interface */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void sunxi_gfx_get_poke_interface(void *data,
|
||||
|
@ -397,6 +397,10 @@ static const video_poke_interface_t switch_poke_interface = {
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void switch_get_poke_interface(void *data,
|
||||
|
@ -682,6 +682,10 @@ static const video_poke_interface_t switch_poke_interface = {
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void switch_get_poke_interface(void *data,
|
||||
|
@ -385,7 +385,11 @@ static const video_poke_interface_t vga_poke_interface = {
|
||||
NULL, /* grab_mouse_toggle */
|
||||
NULL, /* get_current_shader */
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL /* get_hw_render_interface */
|
||||
NULL, /* get_hw_render_interface */
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void vga_gfx_get_poke_interface(void *data,
|
||||
|
@ -824,7 +824,11 @@ static const video_poke_interface_t vita_poke_interface = {
|
||||
NULL,
|
||||
NULL,
|
||||
vita_get_current_sw_framebuffer,
|
||||
NULL
|
||||
NULL,
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void vita2d_gfx_get_poke_interface(void *data,
|
||||
|
@ -2638,6 +2638,10 @@ static const video_poke_interface_t vulkan_poke_interface = {
|
||||
vulkan_get_current_shader,
|
||||
vulkan_get_current_sw_framebuffer,
|
||||
vulkan_get_hw_render_interface,
|
||||
NULL, /* set_hdr_max_nits */
|
||||
NULL, /* set_hdr_paper_white_nits */
|
||||
NULL, /* set_hdr_contrast */
|
||||
NULL /* set_hdr_expand_gamut */
|
||||
};
|
||||
|
||||
static void vulkan_get_poke_interface(void *data,
|
||||
|
@ -366,6 +366,34 @@ static bool video_thread_handle_packet(
|
||||
/* Never reply on no command. Possible deadlock if
|
||||
* thread sends command right after frame update. */
|
||||
break;
|
||||
|
||||
case CMD_POKE_SET_HDR_MAX_NITS:
|
||||
if (thr->poke && thr->poke->set_hdr_max_nits)
|
||||
thr->poke->set_hdr_max_nits(thr->driver_data,
|
||||
pkt.data.hdr.max_nits);
|
||||
video_thread_reply(thr, &pkt);
|
||||
break;
|
||||
|
||||
case CMD_POKE_SET_HDR_PAPER_WHITE_NITS:
|
||||
if (thr->poke && thr->poke->set_hdr_paper_white_nits)
|
||||
thr->poke->set_hdr_paper_white_nits(thr->driver_data,
|
||||
pkt.data.hdr.paper_white_nits);
|
||||
video_thread_reply(thr, &pkt);
|
||||
break;
|
||||
|
||||
case CMD_POKE_SET_HDR_CONTRAST:
|
||||
if (thr->poke && thr->poke->set_hdr_contrast)
|
||||
thr->poke->set_hdr_contrast(thr->driver_data,
|
||||
pkt.data.hdr.contrast);
|
||||
video_thread_reply(thr, &pkt);
|
||||
break;
|
||||
|
||||
case CMD_POKE_SET_HDR_EXPAND_GAMUT:
|
||||
if (thr->poke && thr->poke->set_hdr_expand_gamut)
|
||||
thr->poke->set_hdr_expand_gamut(thr->driver_data,
|
||||
pkt.data.hdr.expand_gamut);
|
||||
video_thread_reply(thr, &pkt);
|
||||
break;
|
||||
default:
|
||||
video_thread_reply(thr, &pkt);
|
||||
break;
|
||||
@ -931,6 +959,58 @@ static void thread_set_filtering(void *data, unsigned idx, bool smooth, bool ctx
|
||||
video_thread_send_and_wait_user_to_thread(thr, &pkt);
|
||||
}
|
||||
|
||||
static void thread_set_hdr_max_nits(void *data, float max_nits)
|
||||
{
|
||||
thread_packet_t pkt;
|
||||
thread_video_t *thr = (thread_video_t*)data;
|
||||
|
||||
if (!thr)
|
||||
return;
|
||||
pkt.type = CMD_POKE_SET_HDR_MAX_NITS;
|
||||
pkt.data.hdr.max_nits = max_nits;
|
||||
|
||||
video_thread_send_and_wait_user_to_thread(thr, &pkt);
|
||||
}
|
||||
|
||||
static void thread_set_hdr_paper_white_nits(void *data, float paper_white_nits)
|
||||
{
|
||||
thread_packet_t pkt;
|
||||
thread_video_t *thr = (thread_video_t*)data;
|
||||
|
||||
if (!thr)
|
||||
return;
|
||||
pkt.type = CMD_POKE_SET_HDR_PAPER_WHITE_NITS;
|
||||
pkt.data.hdr.paper_white_nits = paper_white_nits;
|
||||
|
||||
video_thread_send_and_wait_user_to_thread(thr, &pkt);
|
||||
}
|
||||
|
||||
static void thread_set_hdr_contrast(void *data, float contrast)
|
||||
{
|
||||
thread_packet_t pkt;
|
||||
thread_video_t *thr = (thread_video_t*)data;
|
||||
|
||||
if (!thr)
|
||||
return;
|
||||
pkt.type = CMD_POKE_SET_HDR_CONTRAST;
|
||||
pkt.data.hdr.contrast = contrast;
|
||||
|
||||
video_thread_send_and_wait_user_to_thread(thr, &pkt);
|
||||
}
|
||||
|
||||
static void thread_set_hdr_expand_gamut(void *data, bool expand_gamut)
|
||||
{
|
||||
thread_packet_t pkt;
|
||||
thread_video_t *thr = (thread_video_t*)data;
|
||||
|
||||
if (!thr)
|
||||
return;
|
||||
pkt.type = CMD_POKE_SET_HDR_EXPAND_GAMUT;
|
||||
pkt.data.hdr.expand_gamut = expand_gamut;
|
||||
|
||||
video_thread_send_and_wait_user_to_thread(thr, &pkt);
|
||||
}
|
||||
|
||||
static void thread_get_video_output_size(void *data,
|
||||
unsigned *width, unsigned *height)
|
||||
{
|
||||
@ -1132,7 +1212,11 @@ static const video_poke_interface_t thread_poke = {
|
||||
|
||||
thread_get_current_shader,
|
||||
NULL, /* get_current_software_framebuffer */
|
||||
NULL /* get_hw_render_interface */
|
||||
NULL, /* get_hw_render_interface */
|
||||
thread_set_hdr_max_nits,
|
||||
thread_set_hdr_paper_white_nits,
|
||||
thread_set_hdr_contrast,
|
||||
thread_set_hdr_expand_gamut
|
||||
};
|
||||
|
||||
static void video_thread_get_poke_interface(
|
||||
|
@ -57,6 +57,11 @@ enum thread_cmd
|
||||
CMD_POKE_SHOW_MOUSE,
|
||||
CMD_POKE_GRAB_MOUSE_TOGGLE,
|
||||
|
||||
CMD_POKE_SET_HDR_MAX_NITS,
|
||||
CMD_POKE_SET_HDR_PAPER_WHITE_NITS,
|
||||
CMD_POKE_SET_HDR_CONTRAST,
|
||||
CMD_POKE_SET_HDR_EXPAND_GAMUT,
|
||||
|
||||
CMD_DUMMY = INT_MAX
|
||||
};
|
||||
|
||||
@ -150,6 +155,14 @@ struct thread_packet
|
||||
bool is_threaded;
|
||||
enum font_driver_render_api api;
|
||||
} font_init;
|
||||
|
||||
struct
|
||||
{
|
||||
float max_nits;
|
||||
float paper_white_nits;
|
||||
float contrast;
|
||||
bool expand_gamut;
|
||||
} hdr;
|
||||
} data;
|
||||
enum thread_cmd type;
|
||||
};
|
||||
|
@ -1072,6 +1072,10 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_DEFERRED_VIDEO_SCALING_SETTINGS_LIST,
|
||||
"deferred_video_scaling_settings_list"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_DEFERRED_VIDEO_HDR_SETTINGS_LIST,
|
||||
"deferred_video_hdr_settings_list"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_DEFERRED_VIDEO_SYNCHRONIZATION_SETTINGS_LIST,
|
||||
"deferred_video_synchronization_settings_list"
|
||||
@ -3356,6 +3360,10 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_VIDEO_SCALING_SETTINGS,
|
||||
"video_scaling_settings"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VIDEO_HDR_SETTINGS,
|
||||
"video_hdr_settings"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VIDEO_SYNCHRONIZATION_SETTINGS,
|
||||
"video_synchronization_settings"
|
||||
|
@ -1316,6 +1316,36 @@ int msg_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len)
|
||||
"Resolution of 0 uses the \n"
|
||||
"resolution of the environment.\n");
|
||||
break;
|
||||
case MENU_ENUM_LABEL_VIDEO_HDR_ENABLE:
|
||||
snprintf(s, len,
|
||||
"Enable HDR.\n"
|
||||
" \n"
|
||||
"If supported this enables hdr \n");
|
||||
break;
|
||||
case MENU_ENUM_LABEL_VIDEO_HDR_MAX_NITS:
|
||||
snprintf(s, len,
|
||||
"Max Nits\n"
|
||||
" \n"
|
||||
"Set the maximum no. nits the display can reproduce\n");
|
||||
break;
|
||||
case MENU_ENUM_LABEL_VIDEO_HDR_PAPER_WHITE_NITS:
|
||||
snprintf(s, len,
|
||||
"Paper White Nits\n"
|
||||
" \n"
|
||||
"Set the no. nits at which paper white should be\n");
|
||||
break;
|
||||
case MENU_ENUM_LABEL_VIDEO_HDR_CONTRAST:
|
||||
snprintf(s, len,
|
||||
"Contrast\n"
|
||||
" \n"
|
||||
"The constrast setting for HDR\n");
|
||||
break;
|
||||
case MENU_ENUM_LABEL_VIDEO_HDR_EXPAND_GAMUT:
|
||||
snprintf(s, len,
|
||||
"Expand Gamut\n"
|
||||
" \n"
|
||||
"Once converted to linear space should we use an expanded gamut to get to HDR10\n");
|
||||
break;
|
||||
case MENU_ENUM_LABEL_FASTFORWARD_RATIO:
|
||||
snprintf(s, len,
|
||||
"Fastforward ratio.\n"
|
||||
|
@ -1304,6 +1304,14 @@ MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_VIDEO_SCALING_SETTINGS,
|
||||
"Change video scaling settings."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_VIDEO_HDR_SETTINGS,
|
||||
"HDR"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_VIDEO_HDR_SETTINGS,
|
||||
"Change video hdr settings."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_VIDEO_SYNCHRONIZATION_SETTINGS,
|
||||
"Synchronization"
|
||||
@ -1748,6 +1756,49 @@ MSG_HASH(
|
||||
"Cut off a few pixels around the edges of the image customarily left blank by developers which sometimes also contain garbage pixels."
|
||||
)
|
||||
|
||||
/* Settings > Video > HDR */
|
||||
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_VIDEO_HDR_ENABLE,
|
||||
"Enable HDR"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_VIDEO_HDR_ENABLE,
|
||||
"Enable HDR if the display supports it"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_VIDEO_HDR_MAX_NITS,
|
||||
"Max Nits"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_VIDEO_HDR_MAX_NITS,
|
||||
""
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_VIDEO_HDR_PAPER_WHITE_NITS,
|
||||
"Paper White Nits"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_VIDEO_HDR_PAPER_WHITE_NITS,
|
||||
""
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_VIDEO_HDR_CONTRAST,
|
||||
"Contrast"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_VIDEO_HDR_CONTRAST,
|
||||
""
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_VIDEO_HDR_EXPAND_GAMUT,
|
||||
"Expand Gamut"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_VIDEO_HDR_EXPAND_GAMUT,
|
||||
""
|
||||
)
|
||||
|
||||
/* Settings > Video > Synchronization */
|
||||
|
||||
MSG_HASH(
|
||||
|
@ -167,6 +167,7 @@ GENERIC_DEFERRED_PUSH(deferred_push_video_windowed_mode_settings_list, DISPLA
|
||||
GENERIC_DEFERRED_PUSH(deferred_push_video_synchronization_settings_list, DISPLAYLIST_VIDEO_SYNCHRONIZATION_SETTINGS_LIST)
|
||||
GENERIC_DEFERRED_PUSH(deferred_push_video_output_settings_list, DISPLAYLIST_VIDEO_OUTPUT_SETTINGS_LIST)
|
||||
GENERIC_DEFERRED_PUSH(deferred_push_video_scaling_settings_list, DISPLAYLIST_VIDEO_SCALING_SETTINGS_LIST)
|
||||
GENERIC_DEFERRED_PUSH(deferred_push_video_hdr_settings_list, DISPLAYLIST_VIDEO_HDR_SETTINGS_LIST)
|
||||
GENERIC_DEFERRED_PUSH(deferred_push_crt_switchres_settings_list, DISPLAYLIST_CRT_SWITCHRES_SETTINGS_LIST)
|
||||
GENERIC_DEFERRED_PUSH(deferred_push_configuration_settings_list, DISPLAYLIST_CONFIGURATION_SETTINGS_LIST)
|
||||
GENERIC_DEFERRED_PUSH(deferred_push_saving_settings_list, DISPLAYLIST_SAVING_SETTINGS_LIST)
|
||||
@ -766,6 +767,7 @@ static int menu_cbs_init_bind_deferred_push_compare_label(
|
||||
{MENU_ENUM_LABEL_DEFERRED_VIDEO_SYNCHRONIZATION_SETTINGS_LIST, deferred_push_video_synchronization_settings_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_VIDEO_OUTPUT_SETTINGS_LIST, deferred_push_video_output_settings_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_VIDEO_SCALING_SETTINGS_LIST, deferred_push_video_scaling_settings_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_VIDEO_HDR_SETTINGS_LIST, deferred_push_video_hdr_settings_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_CRT_SWITCHRES_SETTINGS_LIST, deferred_push_crt_switchres_settings_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_AUDIO_SETTINGS_LIST, deferred_push_audio_settings_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_AUDIO_SYNCHRONIZATION_SETTINGS_LIST, deferred_push_audio_synchronization_settings_list},
|
||||
@ -1209,6 +1211,9 @@ static int menu_cbs_init_bind_deferred_push_compare_label(
|
||||
case MENU_ENUM_LABEL_DEFERRED_VIDEO_OUTPUT_SETTINGS_LIST:
|
||||
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_video_output_settings_list);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_DEFERRED_VIDEO_HDR_SETTINGS_LIST:
|
||||
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_video_hdr_settings_list);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_DEFERRED_VIDEO_SCALING_SETTINGS_LIST:
|
||||
BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_video_scaling_settings_list);
|
||||
break;
|
||||
|
@ -330,6 +330,8 @@ static enum msg_hash_enums action_ok_dl_to_enum(unsigned lbl)
|
||||
return MENU_ENUM_LABEL_DEFERRED_VIDEO_WINDOWED_MODE_SETTINGS_LIST;
|
||||
case ACTION_OK_DL_VIDEO_SCALING_SETTINGS_LIST:
|
||||
return MENU_ENUM_LABEL_DEFERRED_VIDEO_SCALING_SETTINGS_LIST;
|
||||
case ACTION_OK_DL_VIDEO_HDR_SETTINGS_LIST:
|
||||
return MENU_ENUM_LABEL_DEFERRED_VIDEO_HDR_SETTINGS_LIST;
|
||||
case ACTION_OK_DL_VIDEO_OUTPUT_SETTINGS_LIST:
|
||||
return MENU_ENUM_LABEL_DEFERRED_VIDEO_OUTPUT_SETTINGS_LIST;
|
||||
case ACTION_OK_DL_CRT_SWITCHRES_SETTINGS_LIST:
|
||||
@ -1458,6 +1460,7 @@ int generic_action_ok_displaylist_push(const char *path,
|
||||
case ACTION_OK_DL_CORE_SETTINGS_LIST:
|
||||
case ACTION_OK_DL_CORE_INFORMATION_LIST:
|
||||
case ACTION_OK_DL_VIDEO_SETTINGS_LIST:
|
||||
case ACTION_OK_DL_VIDEO_HDR_SETTINGS_LIST:
|
||||
case ACTION_OK_DL_VIDEO_SYNCHRONIZATION_SETTINGS_LIST:
|
||||
case ACTION_OK_DL_VIDEO_FULLSCREEN_MODE_SETTINGS_LIST:
|
||||
case ACTION_OK_DL_VIDEO_WINDOWED_MODE_SETTINGS_LIST:
|
||||
@ -5609,6 +5612,7 @@ DEFAULT_ACTION_OK_FUNC(action_ok_push_video_fullscreen_mode_settings_list, ACTIO
|
||||
DEFAULT_ACTION_OK_FUNC(action_ok_push_video_synchronization_settings_list, ACTION_OK_DL_VIDEO_SYNCHRONIZATION_SETTINGS_LIST)
|
||||
DEFAULT_ACTION_OK_FUNC(action_ok_push_video_windowed_mode_settings_list, ACTION_OK_DL_VIDEO_WINDOWED_MODE_SETTINGS_LIST)
|
||||
DEFAULT_ACTION_OK_FUNC(action_ok_push_video_scaling_settings_list, ACTION_OK_DL_VIDEO_SCALING_SETTINGS_LIST)
|
||||
DEFAULT_ACTION_OK_FUNC(action_ok_push_video_hdr_settings_list, ACTION_OK_DL_VIDEO_HDR_SETTINGS_LIST)
|
||||
DEFAULT_ACTION_OK_FUNC(action_ok_push_video_output_settings_list, ACTION_OK_DL_VIDEO_OUTPUT_SETTINGS_LIST)
|
||||
DEFAULT_ACTION_OK_FUNC(action_ok_push_configuration_settings_list, ACTION_OK_DL_CONFIGURATION_SETTINGS_LIST)
|
||||
DEFAULT_ACTION_OK_FUNC(action_ok_push_core_settings_list, ACTION_OK_DL_CORE_SETTINGS_LIST)
|
||||
@ -7688,6 +7692,7 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs,
|
||||
{MENU_ENUM_LABEL_VIDEO_FULLSCREEN_MODE_SETTINGS, action_ok_push_video_fullscreen_mode_settings_list},
|
||||
{MENU_ENUM_LABEL_VIDEO_WINDOWED_MODE_SETTINGS, action_ok_push_video_windowed_mode_settings_list},
|
||||
{MENU_ENUM_LABEL_VIDEO_SCALING_SETTINGS, action_ok_push_video_scaling_settings_list},
|
||||
{MENU_ENUM_LABEL_VIDEO_HDR_SETTINGS, action_ok_push_video_hdr_settings_list},
|
||||
{MENU_ENUM_LABEL_VIDEO_OUTPUT_SETTINGS, action_ok_push_video_output_settings_list},
|
||||
{MENU_ENUM_LABEL_CRT_SWITCHRES_SETTINGS, action_ok_push_crt_switchres_settings_list},
|
||||
{MENU_ENUM_LABEL_AUDIO_SETTINGS, action_ok_push_audio_settings_list},
|
||||
|
@ -203,6 +203,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_synchronization_settings_list,
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_fullscreen_mode_settings_list, MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN_MODE_SETTINGS)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_windowed_mode_settings_list, MENU_ENUM_SUBLABEL_VIDEO_WINDOWED_MODE_SETTINGS)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_scaling_settings_list, MENU_ENUM_SUBLABEL_VIDEO_SCALING_SETTINGS)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_hdr_settings_list, MENU_ENUM_SUBLABEL_VIDEO_HDR_SETTINGS)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_output_settings_list, MENU_ENUM_SUBLABEL_VIDEO_OUTPUT_SETTINGS)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_crt_switchres_settings_list, MENU_ENUM_SUBLABEL_CRT_SWITCHRES_SETTINGS)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_suspend_screensaver_enable, MENU_ENUM_SUBLABEL_SUSPEND_SCREENSAVER_ENABLE)
|
||||
@ -3878,6 +3879,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
case MENU_ENUM_LABEL_VIDEO_SCALING_SETTINGS:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_scaling_settings_list);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_VIDEO_HDR_SETTINGS:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_hdr_settings_list);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_VIDEO_OUTPUT_SETTINGS:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_output_settings_list);
|
||||
break;
|
||||
|
@ -589,6 +589,7 @@ DEFAULT_TITLE_MACRO(action_get_core_settings_list, MENU_ENUM_LABEL_
|
||||
DEFAULT_TITLE_MACRO(action_get_video_settings_list, MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS)
|
||||
DEFAULT_TITLE_MACRO(action_get_video_fullscreen_mode_settings_list, MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN_MODE_SETTINGS)
|
||||
DEFAULT_TITLE_MACRO(action_get_video_windowed_mode_settings_list, MENU_ENUM_LABEL_VALUE_VIDEO_WINDOWED_MODE_SETTINGS)
|
||||
DEFAULT_TITLE_MACRO(action_get_video_hdr_settings_list, MENU_ENUM_LABEL_VALUE_VIDEO_HDR_SETTINGS)
|
||||
DEFAULT_TITLE_MACRO(action_get_video_scaling_settings_list, MENU_ENUM_LABEL_VALUE_VIDEO_SCALING_SETTINGS)
|
||||
DEFAULT_TITLE_MACRO(action_get_video_output_settings_list, MENU_ENUM_LABEL_VALUE_VIDEO_OUTPUT_SETTINGS)
|
||||
DEFAULT_TITLE_MACRO(action_get_video_synchronization_settings_list, MENU_ENUM_LABEL_VALUE_VIDEO_SYNCHRONIZATION_SETTINGS)
|
||||
@ -1000,6 +1001,7 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs,
|
||||
{MENU_ENUM_LABEL_ONLINE_UPDATER, action_get_online_updater_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_RECORDING_SETTINGS_LIST, action_get_recording_settings_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_VIDEO_SCALING_SETTINGS_LIST, action_get_video_scaling_settings_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_VIDEO_HDR_SETTINGS_LIST, action_get_video_hdr_settings_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_VIDEO_OUTPUT_SETTINGS_LIST, action_get_video_output_settings_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_VIDEO_SYNCHRONIZATION_SETTINGS_LIST, action_get_video_synchronization_settings_list},
|
||||
{MENU_ENUM_LABEL_DEFERRED_INPUT_MENU_SETTINGS_LIST, action_get_input_menu_settings_list},
|
||||
|
@ -10383,6 +10383,7 @@ static void materialui_list_insert(
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_FULLSCREEN_MODE_SETTINGS)) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_WINDOWED_MODE_SETTINGS)) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_SCALING_SETTINGS)) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_HDR_SETTINGS)) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_AUDIO_SETTINGS)) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_AUDIO_OUTPUT_SETTINGS)) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_AUDIO_RESAMPLER_SETTINGS)) ||
|
||||
|
@ -107,6 +107,7 @@ enum
|
||||
ACTION_OK_DL_VIDEO_SYNCHRONIZATION_SETTINGS_LIST,
|
||||
ACTION_OK_DL_VIDEO_OUTPUT_SETTINGS_LIST,
|
||||
ACTION_OK_DL_VIDEO_SCALING_SETTINGS_LIST,
|
||||
ACTION_OK_DL_VIDEO_HDR_SETTINGS_LIST,
|
||||
ACTION_OK_DL_CRT_SWITCHRES_SETTINGS_LIST,
|
||||
ACTION_OK_DL_AUDIO_SETTINGS_LIST,
|
||||
ACTION_OK_DL_AUDIO_OUTPUT_SETTINGS_LIST,
|
||||
|
@ -6095,6 +6095,11 @@ unsigned menu_displaylist_build_list(
|
||||
MENU_ENUM_LABEL_VIDEO_SCALING_SETTINGS,
|
||||
PARSE_ACTION, false) == 0)
|
||||
count++;
|
||||
/* if (video_driver_supports_hdr()) */
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
|
||||
MENU_ENUM_LABEL_VIDEO_HDR_SETTINGS,
|
||||
PARSE_ACTION, false) == 0)
|
||||
count++;
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
|
||||
MENU_ENUM_LABEL_VIDEO_SYNCHRONIZATION_SETTINGS,
|
||||
PARSE_ACTION, false) == 0)
|
||||
@ -7917,6 +7922,37 @@ unsigned menu_displaylist_build_list(
|
||||
count++;
|
||||
}
|
||||
break;
|
||||
case DISPLAYLIST_VIDEO_HDR_SETTINGS_LIST:
|
||||
{
|
||||
if (video_driver_supports_hdr())
|
||||
{
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
|
||||
MENU_ENUM_LABEL_VIDEO_HDR_ENABLE,
|
||||
PARSE_ONLY_BOOL, false) == 0)
|
||||
count++;
|
||||
|
||||
/* if (settings->bools.video_hdr_enable) */
|
||||
{
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
|
||||
MENU_ENUM_LABEL_VIDEO_HDR_MAX_NITS,
|
||||
PARSE_ONLY_FLOAT, false) == 0)
|
||||
count++;
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
|
||||
MENU_ENUM_LABEL_VIDEO_HDR_PAPER_WHITE_NITS,
|
||||
PARSE_ONLY_FLOAT, false) == 0)
|
||||
count++;
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
|
||||
MENU_ENUM_LABEL_VIDEO_HDR_CONTRAST,
|
||||
PARSE_ONLY_FLOAT, false) == 0)
|
||||
count++;
|
||||
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
|
||||
MENU_ENUM_LABEL_VIDEO_HDR_EXPAND_GAMUT,
|
||||
PARSE_ONLY_BOOL, false) == 0)
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DISPLAYLIST_VIDEO_SCALING_SETTINGS_LIST:
|
||||
{
|
||||
#if defined(DINGUX)
|
||||
@ -11637,6 +11673,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
|
||||
case DISPLAYLIST_VIDEO_FULLSCREEN_MODE_SETTINGS_LIST:
|
||||
case DISPLAYLIST_VIDEO_WINDOWED_MODE_SETTINGS_LIST:
|
||||
case DISPLAYLIST_VIDEO_OUTPUT_SETTINGS_LIST:
|
||||
case DISPLAYLIST_VIDEO_HDR_SETTINGS_LIST:
|
||||
case DISPLAYLIST_VIDEO_SYNCHRONIZATION_SETTINGS_LIST:
|
||||
case DISPLAYLIST_VIDEO_SCALING_SETTINGS_LIST:
|
||||
case DISPLAYLIST_OPTIONS_DISK:
|
||||
|
@ -156,6 +156,7 @@ enum menu_displaylist_ctl_state
|
||||
DISPLAYLIST_VIDEO_SYNCHRONIZATION_SETTINGS_LIST,
|
||||
DISPLAYLIST_VIDEO_OUTPUT_SETTINGS_LIST,
|
||||
DISPLAYLIST_VIDEO_SCALING_SETTINGS_LIST,
|
||||
DISPLAYLIST_VIDEO_HDR_SETTINGS_LIST,
|
||||
DISPLAYLIST_CRT_SWITCHRES_SETTINGS_LIST,
|
||||
DISPLAYLIST_VIDEO_SETTINGS_LIST,
|
||||
DISPLAYLIST_CONFIGURATION_SETTINGS_LIST,
|
||||
|
@ -7711,6 +7711,51 @@ static void general_write_handler(rarch_setting_t *setting)
|
||||
rarch_cmd = CMD_EVENT_REINIT;
|
||||
}
|
||||
break;
|
||||
case MENU_ENUM_LABEL_VIDEO_HDR_ENABLE:
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
settings->modified = true;
|
||||
settings->bools.video_hdr_enable = *setting->value.target.boolean;
|
||||
|
||||
rarch_cmd = CMD_EVENT_REINIT;
|
||||
}
|
||||
break;
|
||||
case MENU_ENUM_LABEL_VIDEO_HDR_MAX_NITS:
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
settings->modified = true;
|
||||
settings->floats.video_hdr_max_nits = roundf(*setting->value.target.fraction);
|
||||
|
||||
video_driver_set_hdr_max_nits(settings->floats.video_hdr_max_nits);
|
||||
}
|
||||
break;
|
||||
case MENU_ENUM_LABEL_VIDEO_HDR_PAPER_WHITE_NITS:
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
settings->modified = true;
|
||||
settings->floats.video_hdr_paper_white_nits = roundf(*setting->value.target.fraction);
|
||||
|
||||
video_driver_set_hdr_paper_white_nits(settings->floats.video_hdr_paper_white_nits);
|
||||
}
|
||||
break;
|
||||
case MENU_ENUM_LABEL_VIDEO_HDR_CONTRAST:
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
settings->modified = true;
|
||||
settings->floats.video_hdr_contrast = *setting->value.target.fraction;
|
||||
|
||||
video_driver_set_hdr_contrast(settings->floats.video_hdr_contrast);
|
||||
}
|
||||
break;
|
||||
case MENU_ENUM_LABEL_VIDEO_HDR_EXPAND_GAMUT:
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
settings->modified = true;
|
||||
settings->bools.video_hdr_expand_gamut = *setting->value.target.boolean;;
|
||||
|
||||
video_driver_set_hdr_expand_gamut(settings->bools.video_hdr_expand_gamut);
|
||||
}
|
||||
break;
|
||||
case MENU_ENUM_LABEL_INPUT_MAX_USERS:
|
||||
command_event(CMD_EVENT_CONTROLLER_INIT, NULL);
|
||||
break;
|
||||
@ -11783,6 +11828,114 @@ static bool setting_append_list(
|
||||
SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_ADVANCED);
|
||||
|
||||
END_SUB_GROUP(list, list_info, parent_group);
|
||||
|
||||
if(video_driver_supports_hdr())
|
||||
{
|
||||
START_SUB_GROUP(list, list_info, "HDR", &group_info, &subgroup_info, parent_group);
|
||||
|
||||
CONFIG_ACTION(
|
||||
list, list_info,
|
||||
MENU_ENUM_LABEL_VIDEO_HDR_SETTINGS,
|
||||
MENU_ENUM_LABEL_VALUE_VIDEO_HDR_SETTINGS,
|
||||
&group_info,
|
||||
&subgroup_info,
|
||||
parent_group);
|
||||
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
&settings->bools.video_hdr_enable,
|
||||
MENU_ENUM_LABEL_VIDEO_HDR_ENABLE,
|
||||
MENU_ENUM_LABEL_VALUE_VIDEO_HDR_ENABLE,
|
||||
DEFAULT_VIDEO_HDR_ENABLE,
|
||||
MENU_ENUM_LABEL_VALUE_OFF,
|
||||
MENU_ENUM_LABEL_VALUE_ON,
|
||||
&group_info,
|
||||
&subgroup_info,
|
||||
parent_group,
|
||||
general_write_handler,
|
||||
general_read_handler,
|
||||
SD_FLAG_NONE);
|
||||
(*list)[list_info->index - 1].action_ok = setting_bool_action_left_with_refresh;
|
||||
(*list)[list_info->index - 1].action_left = setting_bool_action_left_with_refresh;
|
||||
(*list)[list_info->index - 1].action_right = setting_bool_action_right_with_refresh;
|
||||
MENU_SETTINGS_LIST_CURRENT_ADD_CMD(
|
||||
list,
|
||||
list_info,
|
||||
CMD_EVENT_VIDEO_APPLY_STATE_CHANGES);
|
||||
|
||||
/* if (settings->bools.video_hdr_enable) */
|
||||
{
|
||||
CONFIG_FLOAT(
|
||||
list, list_info,
|
||||
&settings->floats.video_hdr_max_nits,
|
||||
MENU_ENUM_LABEL_VIDEO_HDR_MAX_NITS,
|
||||
MENU_ENUM_LABEL_VALUE_VIDEO_HDR_MAX_NITS,
|
||||
DEFAULT_VIDEO_HDR_MAX_NITS,
|
||||
"%.1fx",
|
||||
&group_info,
|
||||
&subgroup_info,
|
||||
parent_group,
|
||||
general_write_handler,
|
||||
general_read_handler);
|
||||
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
|
||||
menu_settings_list_current_add_range(list, list_info, 0.0, 10000.0, 10.0, true, true);
|
||||
|
||||
CONFIG_FLOAT(
|
||||
list, list_info,
|
||||
&settings->floats.video_hdr_paper_white_nits,
|
||||
MENU_ENUM_LABEL_VIDEO_HDR_PAPER_WHITE_NITS,
|
||||
MENU_ENUM_LABEL_VALUE_VIDEO_HDR_PAPER_WHITE_NITS,
|
||||
DEFAULT_VIDEO_HDR_PAPER_WHITE_NITS,
|
||||
"%.1fx",
|
||||
&group_info,
|
||||
&subgroup_info,
|
||||
parent_group,
|
||||
general_write_handler,
|
||||
general_read_handler);
|
||||
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
|
||||
menu_settings_list_current_add_range(list, list_info, 0.0, 10000.0, 10.0, true, true);
|
||||
|
||||
CONFIG_FLOAT(
|
||||
list, list_info,
|
||||
&settings->floats.video_hdr_contrast,
|
||||
MENU_ENUM_LABEL_VIDEO_HDR_CONTRAST,
|
||||
MENU_ENUM_LABEL_VALUE_VIDEO_HDR_CONTRAST,
|
||||
DEFAULT_VIDEO_HDR_CONTRAST,
|
||||
"%.2fx",
|
||||
&group_info,
|
||||
&subgroup_info,
|
||||
parent_group,
|
||||
general_write_handler,
|
||||
general_read_handler);
|
||||
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
|
||||
menu_settings_list_current_add_range(list, list_info, 0.1, 3.0, 0.01, true, true);
|
||||
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
&settings->bools.video_hdr_expand_gamut,
|
||||
MENU_ENUM_LABEL_VIDEO_HDR_EXPAND_GAMUT,
|
||||
MENU_ENUM_LABEL_VALUE_VIDEO_HDR_EXPAND_GAMUT,
|
||||
DEFAULT_VIDEO_HDR_EXPAND_GAMUT,
|
||||
MENU_ENUM_LABEL_VALUE_OFF,
|
||||
MENU_ENUM_LABEL_VALUE_ON,
|
||||
&group_info,
|
||||
&subgroup_info,
|
||||
parent_group,
|
||||
general_write_handler,
|
||||
general_read_handler,
|
||||
SD_FLAG_NONE);
|
||||
(*list)[list_info->index - 1].action_ok = setting_bool_action_left_with_refresh;
|
||||
(*list)[list_info->index - 1].action_left = setting_bool_action_left_with_refresh;
|
||||
(*list)[list_info->index - 1].action_right = setting_bool_action_right_with_refresh;
|
||||
MENU_SETTINGS_LIST_CURRENT_ADD_CMD(
|
||||
list,
|
||||
list_info,
|
||||
CMD_EVENT_VIDEO_APPLY_STATE_CHANGES);
|
||||
}
|
||||
|
||||
END_SUB_GROUP(list, list_info, parent_group);
|
||||
}
|
||||
|
||||
START_SUB_GROUP(
|
||||
list,
|
||||
list_info,
|
||||
|
@ -1097,6 +1097,12 @@ enum msg_hash_enums
|
||||
MENU_LABEL(VIDEO_REFRESH_RATE_AUTO),
|
||||
MENU_LABEL(VIDEO_REFRESH_RATE_POLLED),
|
||||
|
||||
MENU_LABEL(VIDEO_HDR_ENABLE),
|
||||
MENU_LABEL(VIDEO_HDR_MAX_NITS),
|
||||
MENU_LABEL(VIDEO_HDR_PAPER_WHITE_NITS),
|
||||
MENU_LABEL(VIDEO_HDR_CONTRAST),
|
||||
MENU_LABEL(VIDEO_HDR_EXPAND_GAMUT),
|
||||
|
||||
MENU_LABEL(VIDEO_LAYOUT_ENABLE),
|
||||
MENU_LABEL(VIDEO_LAYOUT_PATH),
|
||||
MENU_LABEL(VIDEO_LAYOUT_SELECTED_VIEW),
|
||||
@ -1538,6 +1544,7 @@ enum msg_hash_enums
|
||||
MENU_ENUM_LABEL_DEFERRED_VIDEO_FULLSCREEN_MODE_SETTINGS_LIST,
|
||||
MENU_ENUM_LABEL_DEFERRED_VIDEO_OUTPUT_SETTINGS_LIST,
|
||||
MENU_ENUM_LABEL_DEFERRED_VIDEO_SYNCHRONIZATION_SETTINGS_LIST,
|
||||
MENU_ENUM_LABEL_DEFERRED_VIDEO_HDR_SETTINGS_LIST,
|
||||
MENU_ENUM_LABEL_DEFERRED_VIDEO_SCALING_SETTINGS_LIST,
|
||||
MENU_ENUM_LABEL_DEFERRED_CRT_SWITCHRES_SETTINGS_LIST,
|
||||
MENU_ENUM_LABEL_DEFERRED_CONFIGURATION_SETTINGS_LIST,
|
||||
@ -2345,6 +2352,7 @@ enum msg_hash_enums
|
||||
MENU_LABEL(VIDEO_OUTPUT_SETTINGS),
|
||||
MENU_LABEL(VIDEO_SYNCHRONIZATION_SETTINGS),
|
||||
MENU_LABEL(VIDEO_SCALING_SETTINGS),
|
||||
MENU_LABEL(VIDEO_HDR_SETTINGS),
|
||||
MENU_LABEL(CRT_SWITCHRES_SETTINGS),
|
||||
MENU_LABEL(AUDIO_SETTINGS),
|
||||
MENU_LABEL(AUDIO_RESAMPLER_SETTINGS),
|
||||
|
60
retroarch.c
60
retroarch.c
@ -27718,6 +27718,38 @@ void video_driver_set_filtering(unsigned index, bool smooth, bool ctx_scaling)
|
||||
index, smooth, ctx_scaling);
|
||||
}
|
||||
|
||||
void video_driver_set_hdr_max_nits(float max_nits)
|
||||
{
|
||||
struct rarch_state *p_rarch = &rarch_st;
|
||||
if (p_rarch->video_driver_poke && p_rarch->video_driver_poke->set_hdr_max_nits)
|
||||
p_rarch->video_driver_poke->set_hdr_max_nits(p_rarch->video_driver_data,
|
||||
max_nits);
|
||||
}
|
||||
|
||||
void video_driver_set_hdr_paper_white_nits(float paper_white_nits)
|
||||
{
|
||||
struct rarch_state *p_rarch = &rarch_st;
|
||||
if (p_rarch->video_driver_poke && p_rarch->video_driver_poke->set_hdr_paper_white_nits)
|
||||
p_rarch->video_driver_poke->set_hdr_paper_white_nits(p_rarch->video_driver_data,
|
||||
paper_white_nits);
|
||||
}
|
||||
|
||||
void video_driver_set_hdr_contrast(float contrast)
|
||||
{
|
||||
struct rarch_state *p_rarch = &rarch_st;
|
||||
if (p_rarch->video_driver_poke && p_rarch->video_driver_poke->set_hdr_contrast)
|
||||
p_rarch->video_driver_poke->set_hdr_contrast(p_rarch->video_driver_data,
|
||||
contrast);
|
||||
}
|
||||
|
||||
void video_driver_set_hdr_expand_gamut(bool expand_gamut)
|
||||
{
|
||||
struct rarch_state *p_rarch = &rarch_st;
|
||||
if (p_rarch->video_driver_poke && p_rarch->video_driver_poke->set_hdr_expand_gamut)
|
||||
p_rarch->video_driver_poke->set_hdr_expand_gamut(p_rarch->video_driver_data,
|
||||
expand_gamut);
|
||||
}
|
||||
|
||||
void video_driver_cached_frame_set(const void *data, unsigned width,
|
||||
unsigned height, size_t pitch)
|
||||
{
|
||||
@ -28068,6 +28100,32 @@ bool video_driver_supports_rgba(void)
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void video_driver_set_hdr_support(void)
|
||||
{
|
||||
struct rarch_state *p_rarch = &rarch_st;
|
||||
VIDEO_DRIVER_LOCK();
|
||||
p_rarch->video_driver_hdr_support = true;
|
||||
VIDEO_DRIVER_UNLOCK();
|
||||
}
|
||||
|
||||
void video_driver_unset_hdr_support(void)
|
||||
{
|
||||
struct rarch_state *p_rarch = &rarch_st;
|
||||
VIDEO_DRIVER_LOCK();
|
||||
p_rarch->video_driver_hdr_support = false;
|
||||
VIDEO_DRIVER_UNLOCK();
|
||||
}
|
||||
|
||||
bool video_driver_supports_hdr(void)
|
||||
{
|
||||
bool tmp;
|
||||
struct rarch_state *p_rarch = &rarch_st;
|
||||
VIDEO_DRIVER_LOCK();
|
||||
tmp = p_rarch->video_driver_hdr_support;
|
||||
VIDEO_DRIVER_UNLOCK();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool video_driver_get_next_video_out(void)
|
||||
{
|
||||
struct rarch_state *p_rarch = &rarch_st;
|
||||
@ -29152,6 +29210,7 @@ void video_driver_build_info(video_frame_info_t *video_info)
|
||||
video_info->height = p_rarch->video_driver_height;
|
||||
|
||||
video_info->use_rgba = p_rarch->video_driver_use_rgba;
|
||||
video_info->hdr_enable = settings->bools.video_hdr_enable;
|
||||
|
||||
video_info->libretro_running = false;
|
||||
video_info->msg_bgcolor_enable =
|
||||
@ -30527,6 +30586,7 @@ static void retroarch_deinit_drivers(
|
||||
video_display_server_destroy();
|
||||
|
||||
p_rarch->video_driver_use_rgba = false;
|
||||
p_rarch->video_driver_hdr_support = false;
|
||||
p_rarch->video_driver_active = false;
|
||||
p_rarch->video_driver_cache_context = false;
|
||||
p_rarch->video_driver_cache_context_ack = false;
|
||||
|
@ -283,6 +283,13 @@
|
||||
# The angle is <value> * 90 degrees counter-clockwise.
|
||||
# screen_orientation = 0
|
||||
|
||||
# HDR settings
|
||||
# video_hdr_enable = false
|
||||
# video_hdr_max_nits = 1000.0f
|
||||
# video_hdr_paper_white_nits = 200.0f
|
||||
# video_hdr_contrast = 1.0f
|
||||
# video_hdr_expand_gamut = true
|
||||
|
||||
#### Audio
|
||||
|
||||
# Enable audio.
|
||||
|
21
retroarch.h
21
retroarch.h
@ -799,6 +799,7 @@ void recording_driver_update_streaming_url(void);
|
||||
#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)
|
||||
|
||||
#if defined(_XBOX360)
|
||||
#define DEFAULT_SHADER_TYPE RARCH_SHADER_HLSL
|
||||
@ -1233,6 +1234,7 @@ typedef struct video_frame_info
|
||||
bool fullscreen;
|
||||
bool font_enable;
|
||||
bool use_rgba;
|
||||
bool hdr_support;
|
||||
bool libretro_running;
|
||||
bool xmb_shadows_enable;
|
||||
bool battery_level_enable;
|
||||
@ -1243,7 +1245,7 @@ typedef struct video_frame_info
|
||||
bool menu_screensaver_active;
|
||||
bool msg_bgcolor_enable;
|
||||
bool crt_switch_hires_menu;
|
||||
|
||||
bool hdr_enable;
|
||||
} video_frame_info_t;
|
||||
|
||||
typedef void (*update_window_title_cb)(void*);
|
||||
@ -1452,6 +1454,12 @@ typedef struct video_poke_interface
|
||||
struct retro_framebuffer *framebuffer);
|
||||
bool (*get_hw_render_interface)(void *data,
|
||||
const struct retro_hw_render_interface **iface);
|
||||
|
||||
/* hdr settings */
|
||||
void (*set_hdr_max_nits)(void *data, float max_nits);
|
||||
void (*set_hdr_paper_white_nits)(void *data, float paper_white_nits);
|
||||
void (*set_hdr_contrast)(void *data, float contrast);
|
||||
void (*set_hdr_expand_gamut)(void *data, bool expand_gamut);
|
||||
} video_poke_interface_t;
|
||||
|
||||
/* msg is for showing a message on the screen
|
||||
@ -1579,6 +1587,12 @@ void video_driver_unset_rgba(void);
|
||||
|
||||
bool video_driver_supports_rgba(void);
|
||||
|
||||
void video_driver_set_hdr_support(void);
|
||||
|
||||
void video_driver_unset_hdr_support(void);
|
||||
|
||||
bool video_driver_supports_hdr(void);
|
||||
|
||||
bool video_driver_get_next_video_out(void);
|
||||
|
||||
bool video_driver_get_prev_video_out(void);
|
||||
@ -1655,6 +1669,11 @@ void * video_driver_read_frame_raw(unsigned *width,
|
||||
|
||||
void video_driver_set_filtering(unsigned index, bool smooth, bool ctx_scaling);
|
||||
|
||||
void video_driver_set_hdr_max_nits(float max_nits);
|
||||
void video_driver_set_hdr_paper_white_nits(float paper_white_nits);
|
||||
void video_driver_set_hdr_contrast(float contrast);
|
||||
void video_driver_set_hdr_expand_gamut(bool expand_gamut);
|
||||
|
||||
const char *video_driver_get_ident(void);
|
||||
|
||||
void video_driver_set_viewport(unsigned width, unsigned height,
|
||||
|
@ -1844,6 +1844,11 @@ struct rarch_state
|
||||
* TODO: Refactor this better. */
|
||||
bool video_driver_use_rgba;
|
||||
|
||||
/* Graphics driver supports HDR displays
|
||||
* Currently only D3D11/D3D12 supports HDR displays and
|
||||
* whether we've enabled it */
|
||||
bool video_driver_hdr_support;
|
||||
|
||||
/* If set during context deinit, the driver should keep
|
||||
* graphics context alive to avoid having to reset all
|
||||
* context state. */
|
||||
|
@ -173,7 +173,7 @@ vector<string> derived_types_list =
|
||||
"IDXGIFactory1",
|
||||
"IDXGIAdapter1",
|
||||
"IDXGISurface1",
|
||||
"IDXGISwapChain3",
|
||||
"IDXGISwapChain4",
|
||||
"IDXGIOutput",
|
||||
"IDXGIDevice",
|
||||
};
|
||||
|
@ -1235,6 +1235,9 @@ QWidget *VideoPage::widget()
|
||||
CheckableSettingsGroup *savePosGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_VIDEO_WINDOW_CUSTOM_SIZE_ENABLE);
|
||||
#endif
|
||||
|
||||
SettingsGroup *hdrGroup = new SettingsGroup("HDR");
|
||||
QHBoxLayout *hdrLayout = new QHBoxLayout;
|
||||
|
||||
SettingsGroup *syncGroup = new SettingsGroup("Synchronization");
|
||||
CheckableSettingsGroup *vSyncGroup = new CheckableSettingsGroup(MENU_ENUM_LABEL_VIDEO_VSYNC);
|
||||
|
||||
@ -1307,6 +1310,12 @@ QWidget *VideoPage::widget()
|
||||
|
||||
windowedGroup->add(MENU_ENUM_LABEL_VIDEO_WINDOW_SHOW_DECORATIONS);
|
||||
|
||||
hdrGroup->add(MENU_ENUM_LABEL_VIDEO_HDR_ENABLE);
|
||||
hdrGroup->add(MENU_ENUM_LABEL_VIDEO_HDR_MAX_NITS);
|
||||
hdrGroup->add(MENU_ENUM_LABEL_VIDEO_HDR_PAPER_WHITE_NITS);
|
||||
hdrGroup->add(MENU_ENUM_LABEL_VIDEO_HDR_CONTRAST);
|
||||
hdrGroup->add(MENU_ENUM_LABEL_VIDEO_HDR_EXPAND_GAMUT);
|
||||
|
||||
vSyncGroup->add(MENU_ENUM_LABEL_VIDEO_SWAP_INTERVAL);
|
||||
vSyncGroup->add(MENU_ENUM_LABEL_VIDEO_ADAPTIVE_VSYNC);
|
||||
vSyncGroup->add(MENU_ENUM_LABEL_VIDEO_FRAME_DELAY);
|
||||
@ -1333,6 +1342,8 @@ QWidget *VideoPage::widget()
|
||||
miscGroup->add(MENU_ENUM_LABEL_VIDEO_CTX_SCALING);
|
||||
miscGroup->add(MENU_ENUM_LABEL_VIDEO_SHADER_DELAY);
|
||||
|
||||
hdrLayout->addWidget(hdrGroup);
|
||||
|
||||
syncMiscLayout->addWidget(syncGroup);
|
||||
syncMiscLayout->addWidget(miscGroup);
|
||||
|
||||
@ -1348,6 +1359,7 @@ QWidget *VideoPage::widget()
|
||||
|
||||
layout->addLayout(outputScalingLayout);
|
||||
layout->addLayout(modeLayout);
|
||||
layout->addLayout(hdrLayout);
|
||||
layout->addLayout(syncMiscLayout);
|
||||
layout->addWidget(filterGroup);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user