RetroArch/gfx/video_thread_wrapper.c

1451 lines
39 KiB
C
Raw Normal View History

/* RetroArch - A frontend for libretro.
2014-01-01 01:50:59 +01:00
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
2017-01-22 13:40:32 +01:00
* Copyright (C) 2011-2017 - Daniel De Matteis
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <math.h>
2016-09-06 00:56:00 +02:00
#include <compat/strl.h>
#include <features/features_cpu.h>
#include <string/stdstring.h>
2021-11-09 07:06:04 +01:00
#include "video_driver.h"
2015-09-05 20:03:27 +02:00
#include "video_thread_wrapper.h"
#include "font_driver.h"
2016-09-05 18:31:32 +02:00
2017-05-11 09:11:46 +02:00
#include "../retroarch.h"
2015-11-23 12:03:38 +01:00
#include "../verbosity.h"
2015-09-05 20:03:27 +02:00
static void *video_thread_init_never_call(const video_info_t *video,
input_driver_t **input, void **input_data)
{
(void)video;
(void)input;
(void)input_data;
RARCH_ERR("Sanity check fail! Threaded mustn't be reinit.\n");
abort();
return NULL;
}
/* thread -> user */
2016-05-10 03:14:23 +02:00
static void video_thread_reply(thread_video_t *thr, const thread_packet_t *pkt)
{
slock_lock(thr->lock);
2017-01-12 10:41:11 +01:00
thr->cmd_data = *pkt;
thr->reply_cmd = pkt->type;
2016-09-11 17:40:26 +02:00
thr->send_cmd = CMD_VIDEO_NONE;
scond_signal(thr->cond_cmd);
slock_unlock(thr->lock);
}
/* user -> thread */
2016-05-10 03:14:23 +02:00
static void video_thread_send_packet(thread_video_t *thr,
const thread_packet_t *pkt)
{
slock_lock(thr->lock);
2017-01-12 10:41:11 +01:00
thr->cmd_data = *pkt;
thr->send_cmd = pkt->type;
2016-09-11 17:40:26 +02:00
thr->reply_cmd = CMD_VIDEO_NONE;
scond_signal(thr->cond_thread);
slock_unlock(thr->lock);
}
/* user -> thread */
2016-05-10 03:14:23 +02:00
static void video_thread_wait_reply(thread_video_t *thr, thread_packet_t *pkt)
{
slock_lock(thr->lock);
while (pkt->type != thr->reply_cmd)
scond_wait(thr->cond_cmd, thr->lock);
2017-01-12 10:41:11 +01:00
*pkt = thr->cmd_data;
2016-09-11 17:40:26 +02:00
thr->cmd_data.type = CMD_VIDEO_NONE;
slock_unlock(thr->lock);
}
/* user -> thread */
2016-05-10 03:14:23 +02:00
static void video_thread_send_and_wait_user_to_thread(thread_video_t *thr, thread_packet_t *pkt)
{
2016-05-10 03:14:23 +02:00
video_thread_send_packet(thr, pkt);
video_thread_wait_reply(thr, pkt);
}
static void thread_update_driver_state(thread_video_t *thr)
{
#ifdef HAVE_MENU
if (thr->texture.frame_updated)
{
if (thr->driver_data && thr->poke && thr->poke->set_texture_frame)
thr->poke->set_texture_frame(thr->driver_data,
thr->texture.frame, thr->texture.rgb32,
thr->texture.width, thr->texture.height,
thr->texture.alpha);
thr->texture.frame_updated = false;
}
if (thr->driver_data && thr->poke && thr->poke->set_texture_enable)
2014-09-08 17:57:18 +02:00
thr->poke->set_texture_enable(thr->driver_data,
thr->texture.enable, thr->texture.full_screen);
#endif
#ifdef HAVE_OVERLAY
slock_lock(thr->alpha_lock);
if (thr->alpha_update)
{
if (thr->driver_data && thr->overlay && thr->overlay->set_alpha)
{
unsigned i;
for (i = 0; i < thr->alpha_mods; i++)
thr->overlay->set_alpha(thr->driver_data, i, thr->alpha_mod[i]);
}
thr->alpha_update = false;
}
slock_unlock(thr->alpha_lock);
#endif
if (thr->apply_state_changes)
{
if (thr->driver_data && thr->poke && thr->poke->apply_state_changes)
thr->poke->apply_state_changes(thr->driver_data);
thr->apply_state_changes = false;
}
}
2016-05-10 03:14:23 +02:00
/* returns true when video_thread_loop should quit */
static bool video_thread_handle_packet(
thread_video_t *thr,
const thread_packet_t *incoming)
2015-05-20 17:06:11 -03:00
{
thread_packet_t pkt = *incoming;
switch (pkt.type)
{
case CMD_INIT:
if (thr->driver && thr->driver->init)
{
thr->driver_data = thr->driver->init(&thr->info,
thr->input, thr->input_data);
if (thr->driver_data && thr->driver->viewport_info)
thr->driver->viewport_info(thr->driver_data, &thr->vp);
}
else
{
thr->driver_data = NULL;
}
2017-10-03 00:53:09 +02:00
pkt.data.b = (thr->driver_data != NULL);
2016-05-10 03:14:23 +02:00
video_thread_reply(thr, &pkt);
2015-05-20 17:06:11 -03:00
break;
case CMD_FREE:
if (thr->driver_data && thr->driver && thr->driver->free)
thr->driver->free(thr->driver_data);
2015-05-20 17:06:11 -03:00
thr->driver_data = NULL;
2016-05-10 03:14:23 +02:00
video_thread_reply(thr, &pkt);
2015-05-20 17:06:11 -03:00
return true;
case CMD_SET_ROTATION:
if (thr->driver_data && thr->driver && thr->driver->set_rotation)
2015-05-20 17:06:11 -03:00
thr->driver->set_rotation(thr->driver_data, pkt.data.i);
2016-05-10 03:14:23 +02:00
video_thread_reply(thr, &pkt);
2015-05-20 17:06:11 -03:00
break;
case CMD_READ_VIEWPORT:
if (thr->driver_data && thr->driver &&
thr->driver->viewport_info && thr->driver->read_viewport)
{
struct video_viewport vp = {0};
2015-05-20 17:06:11 -03:00
thr->driver->viewport_info(thr->driver_data, &vp);
if (!memcmp(&vp, &thr->read_vp, sizeof(vp)))
{
/* We can read safely
*
* read_viewport() in GL driver calls
* 'cached frame render' to be able to read from
* back buffer.
*
* This means frame() callback in threaded wrapper will
* be called from this thread, causing a timeout, and
* no frame to be rendered.
*
* To avoid this, set a flag so wrapper can see if
* it's called in this "special" way. */
thr->frame.within_thread = true;
pkt.data.b = thr->driver->read_viewport(thr->driver_data,
(uint8_t*)pkt.data.v, thr->is_idle);
thr->frame.within_thread = false;
}
else
{
/* Viewport dimensions changed right after main
* thread read the async value. Cannot read safely. */
pkt.data.b = false;
}
2015-05-20 17:06:11 -03:00
}
else
{
pkt.data.b = false;
}
2016-05-10 03:14:23 +02:00
video_thread_reply(thr, &pkt);
2015-05-20 17:06:11 -03:00
break;
case CMD_SET_SHADER:
if (thr->driver_data && thr->driver && thr->driver->set_shader)
pkt.data.b = thr->driver->set_shader(thr->driver_data,
pkt.data.set_shader.type, pkt.data.set_shader.path);
else
pkt.data.b = false;
2016-05-10 03:14:23 +02:00
video_thread_reply(thr, &pkt);
2015-05-20 17:06:11 -03:00
break;
case CMD_ALIVE:
if (thr->driver_data && thr->driver && thr->driver->alive)
pkt.data.b = thr->driver->alive(thr->driver_data);
else
pkt.data.b = false;
2016-05-10 03:14:23 +02:00
video_thread_reply(thr, &pkt);
2015-05-20 17:06:11 -03:00
break;
#ifdef HAVE_OVERLAY
case CMD_OVERLAY_ENABLE:
if (thr->driver_data && thr->overlay && thr->overlay->enable)
2015-05-20 17:06:11 -03:00
thr->overlay->enable(thr->driver_data, pkt.data.b);
2016-05-10 03:14:23 +02:00
video_thread_reply(thr, &pkt);
2015-05-20 17:06:11 -03:00
break;
case CMD_OVERLAY_LOAD:
2022-05-21 06:23:17 -03:00
{
unsigned tmp_alpha_mods = pkt.data.image.num;
2022-05-21 06:23:17 -03:00
if (thr->driver_data && thr->overlay && thr->overlay->load)
pkt.data.b = thr->overlay->load(thr->driver_data,
pkt.data.image.data, pkt.data.image.num);
else
pkt.data.b = false;
2020-09-11 16:48:18 +01:00
2022-05-21 06:23:17 -03:00
if (tmp_alpha_mods > 0)
{
2022-05-21 06:23:17 -03:00
float *tmp_alpha_mod = (float*)realloc(thr->alpha_mod,
tmp_alpha_mods * sizeof(float));
if (tmp_alpha_mod)
{
/* Avoid temporary garbage data. */
unsigned i;
for (i = 0; i < tmp_alpha_mods; i++)
tmp_alpha_mod[i] = 1.0f;
thr->alpha_mods = tmp_alpha_mods;
thr->alpha_mod = tmp_alpha_mod;
}
}
else
{
free(thr->alpha_mod);
thr->alpha_mods = 0;
thr->alpha_mod = NULL;
}
}
video_thread_reply(thr, &pkt);
2015-05-20 17:06:11 -03:00
break;
case CMD_OVERLAY_TEX_GEOM:
if (thr->driver_data && thr->overlay && thr->overlay->tex_geom)
2015-05-20 17:06:11 -03:00
thr->overlay->tex_geom(thr->driver_data,
pkt.data.rect.index,
pkt.data.rect.x,
pkt.data.rect.y,
pkt.data.rect.w,
pkt.data.rect.h);
2016-05-10 03:14:23 +02:00
video_thread_reply(thr, &pkt);
2015-05-20 17:06:11 -03:00
break;
case CMD_OVERLAY_VERTEX_GEOM:
if (thr->driver_data && thr->overlay && thr->overlay->vertex_geom)
2015-05-20 17:06:11 -03:00
thr->overlay->vertex_geom(thr->driver_data,
pkt.data.rect.index,
pkt.data.rect.x,
pkt.data.rect.y,
pkt.data.rect.w,
pkt.data.rect.h);
2016-05-10 03:14:23 +02:00
video_thread_reply(thr, &pkt);
2015-05-20 17:06:11 -03:00
break;
case CMD_OVERLAY_FULL_SCREEN:
if (thr->driver_data && thr->overlay && thr->overlay->full_screen)
thr->overlay->full_screen(thr->driver_data, pkt.data.b);
2016-05-10 03:14:23 +02:00
video_thread_reply(thr, &pkt);
2015-05-20 17:06:11 -03:00
break;
#endif
case CMD_POKE_SET_VIDEO_MODE:
if (thr->driver_data && thr->poke && thr->poke->set_video_mode)
2015-05-20 17:06:11 -03:00
thr->poke->set_video_mode(thr->driver_data,
pkt.data.new_mode.width,
pkt.data.new_mode.height,
pkt.data.new_mode.fullscreen);
2016-05-10 03:14:23 +02:00
video_thread_reply(thr, &pkt);
2015-05-20 17:06:11 -03:00
break;
2015-05-20 17:06:11 -03:00
case CMD_POKE_SET_FILTERING:
if (thr->driver_data && thr->poke && thr->poke->set_filtering)
2015-05-20 17:06:11 -03:00
thr->poke->set_filtering(thr->driver_data,
pkt.data.filtering.index,
pkt.data.filtering.smooth,
pkt.data.filtering.ctx_scaling);
2016-05-10 03:14:23 +02:00
video_thread_reply(thr, &pkt);
2015-05-20 17:06:11 -03:00
break;
case CMD_POKE_SET_ASPECT_RATIO:
if (thr->driver_data && thr->poke && thr->poke->set_aspect_ratio)
thr->poke->set_aspect_ratio(thr->driver_data, pkt.data.i);
2016-05-10 03:14:23 +02:00
video_thread_reply(thr, &pkt);
2015-05-20 17:06:11 -03:00
break;
case CMD_FONT_INIT:
if (pkt.data.font_init.method)
pkt.data.font_init.return_value = pkt.data.font_init.method(
pkt.data.font_init.font_driver,
pkt.data.font_init.font_handle,
pkt.data.font_init.video_data,
pkt.data.font_init.font_path,
pkt.data.font_init.font_size,
pkt.data.font_init.api,
pkt.data.font_init.is_threaded
);
2016-05-10 03:14:23 +02:00
video_thread_reply(thr, &pkt);
2015-05-20 17:06:11 -03:00
break;
case CMD_CUSTOM_COMMAND:
if (pkt.data.custom_command.method)
pkt.data.custom_command.return_value =
pkt.data.custom_command.method(pkt.data.custom_command.data);
2016-05-10 03:14:23 +02:00
video_thread_reply(thr, &pkt);
2015-05-20 17:06:11 -03:00
break;
case CMD_POKE_SHOW_MOUSE:
if (thr->driver_data && thr->poke && thr->poke->show_mouse)
thr->poke->show_mouse(thr->driver_data, pkt.data.b);
video_thread_reply(thr, &pkt);
break;
case CMD_POKE_GRAB_MOUSE_TOGGLE:
if (thr->driver_data && thr->poke && thr->poke->grab_mouse_toggle)
thr->poke->grab_mouse_toggle(thr->driver_data);
video_thread_reply(thr, &pkt);
break;
2016-09-11 17:40:26 +02:00
case CMD_VIDEO_NONE:
2015-05-20 17:06:11 -03:00
/* Never reply on no command. Possible deadlock if
* thread sends command right after frame update. */
break;
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 https://github.com/libretro/RetroArch/pull/12916/commits/c1b6c0bff2aa33cde035b43cb31ac7e78ff2a07a - 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
2021-09-03 06:15:25 +02:00
case CMD_POKE_SET_HDR_MAX_NITS:
if (thr->driver_data && thr->poke && thr->poke->set_hdr_max_nits)
thr->poke->set_hdr_max_nits(
thr->driver_data,
pkt.data.hdr.max_nits
);
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 https://github.com/libretro/RetroArch/pull/12916/commits/c1b6c0bff2aa33cde035b43cb31ac7e78ff2a07a - 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
2021-09-03 06:15:25 +02:00
video_thread_reply(thr, &pkt);
break;
case CMD_POKE_SET_HDR_PAPER_WHITE_NITS:
if (thr->driver_data &&
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
);
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 https://github.com/libretro/RetroArch/pull/12916/commits/c1b6c0bff2aa33cde035b43cb31ac7e78ff2a07a - 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
2021-09-03 06:15:25 +02:00
video_thread_reply(thr, &pkt);
break;
case CMD_POKE_SET_HDR_CONTRAST:
if (thr->driver_data && thr->poke && thr->poke->set_hdr_contrast)
thr->poke->set_hdr_contrast(
thr->driver_data,
pkt.data.hdr.contrast
);
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 https://github.com/libretro/RetroArch/pull/12916/commits/c1b6c0bff2aa33cde035b43cb31ac7e78ff2a07a - 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
2021-09-03 06:15:25 +02:00
video_thread_reply(thr, &pkt);
break;
case CMD_POKE_SET_HDR_EXPAND_GAMUT:
if (thr->driver_data && thr->poke && thr->poke->set_hdr_expand_gamut)
thr->poke->set_hdr_expand_gamut(
thr->driver_data,
pkt.data.hdr.expand_gamut
);
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 https://github.com/libretro/RetroArch/pull/12916/commits/c1b6c0bff2aa33cde035b43cb31ac7e78ff2a07a - 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
2021-09-03 06:15:25 +02:00
video_thread_reply(thr, &pkt);
break;
2015-05-20 17:06:11 -03:00
default:
2016-05-10 03:14:23 +02:00
video_thread_reply(thr, &pkt);
2015-05-20 17:06:11 -03:00
break;
}
return false;
}
2016-05-10 03:14:23 +02:00
static void video_thread_loop(void *data)
{
thread_packet_t pkt;
bool updated;
thread_video_t *thr = (thread_video_t*)data;
for (;;)
{
slock_lock(thr->lock);
2016-09-11 17:40:26 +02:00
while (thr->send_cmd == CMD_VIDEO_NONE && !thr->frame.updated)
scond_wait(thr->cond_thread, thr->lock);
updated = thr->frame.updated;
2014-09-08 17:57:18 +02:00
/* To avoid race condition where send_cmd is updated
2014-09-08 17:57:18 +02:00
* right after the switch is checked. */
pkt = thr->cmd_data;
slock_unlock(thr->lock);
2016-05-10 03:14:23 +02:00
if (video_thread_handle_packet(thr, &pkt))
2015-05-20 17:06:11 -03:00
return;
if (updated)
{
2015-09-29 17:35:28 +02:00
bool alive = false;
bool focus = false;
bool has_windowed = false;
struct video_viewport vp = {0};
slock_lock(thr->frame.lock);
thread_update_driver_state(thr);
if (thr->driver_data && thr->driver)
{
if (thr->driver->frame)
{
video_frame_info_t video_info;
bool ret;
/* TODO/FIXME - not thread-safe - should get
* rid of this */
video_driver_build_info(&video_info);
ret = thr->driver->frame(thr->driver_data,
thr->frame.buffer, thr->frame.width, thr->frame.height,
thr->frame.count, thr->frame.pitch,
*thr->frame.msg ? thr->frame.msg : NULL,
2017-01-18 17:41:27 +01:00
&video_info);
slock_unlock(thr->frame.lock);
if (ret)
{
if (thr->driver->alive)
alive = thr->driver->alive(thr->driver_data);
if (thr->driver->focus)
focus = thr->driver->focus(thr->driver_data);
if (thr->driver->has_windowed)
has_windowed = thr->driver->has_windowed(thr->driver_data);
}
}
else
slock_unlock(thr->frame.lock);
if (thr->driver->viewport_info)
thr->driver->viewport_info(thr->driver_data, &vp);
}
else
slock_unlock(thr->frame.lock);
slock_lock(thr->lock);
2015-09-29 17:35:28 +02:00
thr->alive = alive;
thr->focus = focus;
thr->has_windowed = has_windowed;
thr->vp = vp;
thr->frame.updated = false;
scond_signal(thr->cond_cmd);
slock_unlock(thr->lock);
}
}
}
2016-05-10 03:14:23 +02:00
static bool video_thread_alive(void *data)
{
2015-11-30 22:25:13 +01:00
bool ret;
thread_video_t *thr = (thread_video_t*)data;
if (!thr)
return false;
if (retroarch_ctl(RARCH_CTL_IS_PAUSED, NULL))
2013-02-16 11:44:15 +01:00
{
2020-08-18 16:51:00 +02:00
thread_packet_t pkt;
pkt.type = CMD_ALIVE;
2016-05-10 03:14:23 +02:00
video_thread_send_and_wait_user_to_thread(thr, &pkt);
return pkt.data.b;
2013-02-16 11:44:15 +01:00
}
slock_lock(thr->lock);
ret = thr->alive;
slock_unlock(thr->lock);
return ret;
}
2016-05-10 03:14:23 +02:00
static bool video_thread_focus(void *data)
{
bool ret;
thread_video_t *thr = (thread_video_t*)data;
if (!thr)
return false;
slock_lock(thr->lock);
ret = thr->focus;
slock_unlock(thr->lock);
return ret;
}
2016-05-10 03:14:23 +02:00
static bool video_thread_suppress_screensaver(void *data, bool enable)
2015-01-18 22:32:14 +01:00
{
bool ret;
thread_video_t *thr = (thread_video_t*)data;
if (!thr)
return false;
2015-01-18 22:32:14 +01:00
slock_lock(thr->lock);
ret = thr->suppress_screensaver;
slock_unlock(thr->lock);
return ret;
}
2016-05-10 03:14:23 +02:00
static bool video_thread_has_windowed(void *data)
{
bool ret;
thread_video_t *thr = (thread_video_t*)data;
if (!thr)
return false;
slock_lock(thr->lock);
ret = thr->has_windowed;
slock_unlock(thr->lock);
return ret;
}
2016-05-10 03:14:23 +02:00
static bool video_thread_frame(void *data, const void *frame_,
2015-08-03 23:01:07 +02:00
unsigned width, unsigned height, uint64_t frame_count,
2017-01-18 17:41:27 +01:00
unsigned pitch, const char *msg, video_frame_info_t *video_info)
{
thread_video_t *thr = (thread_video_t*)data;
if (!thr)
return false;
/* If called from within read_viewport, we're actually in the
2014-09-08 17:57:18 +02:00
* driver thread, so just render directly. */
if (thr->frame.within_thread)
{
thread_update_driver_state(thr);
if (thr->driver_data && thr->driver && thr->driver->frame)
2014-09-08 17:57:18 +02:00
return thr->driver->frame(thr->driver_data, frame_,
width, height, frame_count, pitch, msg, video_info);
return false;
}
slock_lock(thr->lock);
if (!thr->nonblock)
{
retro_time_t target_frame_time =
(retro_time_t)roundf(1000000 / video_info->refresh_rate);
retro_time_t target = thr->last_time + target_frame_time;
2014-09-08 17:57:18 +02:00
/* Ideally, use absolute time, but that is only a good idea on POSIX. */
while (thr->frame.updated)
{
2016-05-10 09:17:04 +02:00
retro_time_t current = cpu_features_get_time_usec();
2015-09-20 10:02:47 +02:00
retro_time_t delta = target - current;
if (delta <= 0)
break;
if (!scond_wait_timeout(thr->cond_cmd, thr->lock, delta))
break;
}
}
/* Drop frame if updated flag is still set, as thread is
2014-09-08 17:57:18 +02:00
* still working on last frame. */
if (!thr->frame.updated)
{
const uint8_t *src = (const uint8_t*)frame_;
uint8_t *dst = thr->frame.buffer;
unsigned copy_stride = width *
(thr->info.rgb32 ? sizeof(uint32_t) : sizeof(uint16_t));
if (src)
{
unsigned h;
for (h = 0; h < height; h++, src += pitch, dst += copy_stride)
memcpy(dst, src, copy_stride);
}
thr->frame.updated = true;
thr->frame.width = width;
thr->frame.height = height;
thr->frame.count = frame_count;
thr->frame.pitch = copy_stride;
if (msg)
strlcpy(thr->frame.msg, msg, sizeof(thr->frame.msg));
else
*thr->frame.msg = '\0';
2013-02-16 12:30:26 +01:00
scond_signal(thr->cond_thread);
#ifdef HAVE_MENU
if (thr->texture.enable)
{
do
{
scond_wait(thr->cond_cmd, thr->lock);
} while (thr->frame.updated);
}
#endif
thr->hit_count++;
}
else
thr->miss_count++;
slock_unlock(thr->lock);
2016-05-10 09:17:04 +02:00
thr->last_time = cpu_features_get_time_usec();
return true;
}
static void video_thread_set_nonblock_state(void *data, bool state,
bool adaptive_vsync_enabled,
unsigned swap_interval)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr)
thr->nonblock = state;
}
2017-01-16 18:02:28 +01:00
static bool video_thread_init(thread_video_t *thr,
const video_info_t info,
input_driver_t **input, void **input_data)
{
2020-08-18 16:51:00 +02:00
thread_packet_t pkt;
thr->lock = slock_new();
if (!thr->lock)
return false;
thr->alpha_lock = slock_new();
if (!thr->alpha_lock)
return false;
thr->frame.lock = slock_new();
if (!thr->frame.lock)
return false;
thr->cond_cmd = scond_new();
if (!thr->cond_cmd)
return false;
thr->cond_thread = scond_new();
if (!thr->cond_thread)
return false;
{
size_t max_size = info.input_scale * RARCH_SCALE_BASE;
max_size *= max_size;
max_size *= info.rgb32 ?
sizeof(uint32_t) : sizeof(uint16_t);
#ifdef _3DS
thr->frame.buffer = linearMemAlign(max_size, 0x80);
#else
thr->frame.buffer = (uint8_t*)malloc(max_size);
#endif
if (!thr->frame.buffer)
return false;
memset(thr->frame.buffer, 0x80, max_size);
}
thr->input = input;
thr->input_data = input_data;
2017-01-16 18:02:28 +01:00
thr->info = info;
thr->alive = true;
thr->focus = true;
thr->has_windowed = true;
2015-01-18 22:32:14 +01:00
thr->suppress_screensaver = true;
2016-05-10 09:17:04 +02:00
thr->last_time = cpu_features_get_time_usec();
2015-12-02 01:01:27 +01:00
thr->thread = sthread_create(video_thread_loop, thr);
if (!thr->thread)
return false;
pkt.type = CMD_INIT;
2016-05-10 03:14:23 +02:00
video_thread_send_and_wait_user_to_thread(thr, &pkt);
2013-02-16 12:30:26 +01:00
return pkt.data.b;
}
2016-05-10 03:14:23 +02:00
static bool video_thread_set_shader(void *data,
2014-09-08 17:57:18 +02:00
enum rarch_shader_type type, const char *path)
{
2020-08-18 16:51:00 +02:00
thread_packet_t pkt;
thread_video_t *thr = (thread_video_t*)data;
if (!thr)
return false;
2020-08-18 16:51:00 +02:00
pkt.type = CMD_SET_SHADER;
pkt.data.set_shader.type = type;
pkt.data.set_shader.path = path;
2016-05-10 03:14:23 +02:00
video_thread_send_and_wait_user_to_thread(thr, &pkt);
return pkt.data.b;
}
2016-05-10 03:14:23 +02:00
static void video_thread_set_viewport(void *data, unsigned width,
unsigned height, bool force_full, bool video_allow_rotate)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr && thr->driver_data && thr->driver && thr->driver->set_viewport)
{
slock_lock(thr->lock);
thr->driver->set_viewport(thr->driver_data, width, height,
force_full, video_allow_rotate);
slock_unlock(thr->lock);
}
}
2016-05-10 03:14:23 +02:00
static void video_thread_set_rotation(void *data, unsigned rotation)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr)
{
thread_packet_t pkt;
pkt.type = CMD_SET_ROTATION;
pkt.data.i = rotation;
2016-05-10 03:14:23 +02:00
video_thread_send_and_wait_user_to_thread(thr, &pkt);
}
}
/* This value is set async as stalling on the video driver for
2014-09-08 17:57:18 +02:00
* every query is too slow.
*
* This means this value might not be correct, so viewport
2014-09-08 17:57:18 +02:00
* reads are not supported for now. */
2016-05-10 03:14:23 +02:00
static void video_thread_viewport_info(void *data, struct video_viewport *vp)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr)
{
slock_lock(thr->lock);
*vp = thr->vp;
/* Explicitly mem-copied so we can use memcmp correctly later. */
memcpy(&thr->read_vp, &thr->vp, sizeof(thr->read_vp));
slock_unlock(thr->lock);
}
}
2020-08-18 16:51:00 +02:00
static bool video_thread_read_viewport(void *data,
uint8_t *buffer, bool is_idle)
{
2020-08-18 16:51:00 +02:00
thread_packet_t pkt;
thread_video_t *thr = (thread_video_t*)data;
if (!thr)
return false;
2020-08-18 16:51:00 +02:00
pkt.type = CMD_READ_VIEWPORT;
pkt.data.v = buffer;
thr->is_idle = is_idle;
2016-05-10 03:14:23 +02:00
video_thread_send_and_wait_user_to_thread(thr, &pkt);
return pkt.data.b;
}
2016-05-10 03:14:23 +02:00
static void video_thread_free(void *data)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr)
{
if (thr->thread)
{
thread_packet_t pkt;
pkt.type = CMD_FREE;
video_thread_send_and_wait_user_to_thread(thr, &pkt);
sthread_join(thr->thread);
}
2022-05-21 06:23:17 -03:00
else
{
/* If we don't have a thread,
we must call the driver's free function ourselves. */
if (thr->driver_data && thr->driver && thr->driver->free)
thr->driver->free(thr->driver_data);
}
free(thr->texture.frame);
2020-08-27 19:36:39 -07:00
#ifdef _3DS
linearFree(thr->frame.buffer);
2020-08-27 19:36:39 -07:00
#else
free(thr->frame.buffer);
2020-08-27 19:36:39 -07:00
#endif
free(thr->alpha_mod);
slock_free(thr->frame.lock);
slock_free(thr->alpha_lock);
slock_free(thr->lock);
scond_free(thr->cond_cmd);
scond_free(thr->cond_thread);
RARCH_LOG(
"Threaded video stats: Frames pushed: %u, Frames dropped: %u.\n",
thr->hit_count, thr->miss_count);
free(thr);
}
}
2013-02-16 11:44:15 +01:00
#ifdef HAVE_OVERLAY
static void thread_overlay_enable(void *data, bool state)
{
2013-02-16 12:05:15 +01:00
thread_video_t *thr = (thread_video_t*)data;
if (thr)
{
thread_packet_t pkt;
pkt.type = CMD_OVERLAY_ENABLE;
pkt.data.b = state;
2016-05-10 03:14:23 +02:00
video_thread_send_and_wait_user_to_thread(thr, &pkt);
}
2013-02-16 11:44:15 +01:00
}
2014-09-08 17:57:18 +02:00
static bool thread_overlay_load(void *data,
const void *image_data, unsigned num_images)
2013-02-16 11:44:15 +01:00
{
2020-08-18 16:51:00 +02:00
thread_packet_t pkt;
thread_video_t *thr = (thread_video_t*)data;
if (!thr)
return false;
2020-08-18 16:51:00 +02:00
pkt.type = CMD_OVERLAY_LOAD;
pkt.data.image.data = (const struct texture_image*)image_data;
2016-05-10 03:14:23 +02:00
pkt.data.image.num = num_images;
video_thread_send_and_wait_user_to_thread(thr, &pkt);
return pkt.data.b;
2013-02-16 11:44:15 +01:00
}
2014-09-08 17:57:18 +02:00
static void thread_overlay_tex_geom(void *data,
unsigned idx, float x, float y, float w, float h)
2013-02-16 11:44:15 +01:00
{
2013-02-16 12:05:15 +01:00
thread_video_t *thr = (thread_video_t*)data;
if (thr)
{
thread_packet_t pkt;
pkt.type = CMD_OVERLAY_TEX_GEOM;
pkt.data.rect.index = idx;
pkt.data.rect.x = x;
pkt.data.rect.y = y;
pkt.data.rect.w = w;
pkt.data.rect.h = h;
video_thread_send_and_wait_user_to_thread(thr, &pkt);
}
2013-02-16 11:44:15 +01:00
}
2014-09-08 17:57:18 +02:00
static void thread_overlay_vertex_geom(void *data,
unsigned idx, float x, float y, float w, float h)
2013-02-16 11:44:15 +01:00
{
2013-02-16 12:05:15 +01:00
thread_video_t *thr = (thread_video_t*)data;
if (thr)
{
thread_packet_t pkt;
pkt.type = CMD_OVERLAY_VERTEX_GEOM;
pkt.data.rect.index = idx;
pkt.data.rect.x = x;
pkt.data.rect.y = y;
pkt.data.rect.w = w;
pkt.data.rect.h = h;
video_thread_send_and_wait_user_to_thread(thr, &pkt);
}
2013-02-16 11:44:15 +01:00
}
static void thread_overlay_full_screen(void *data, bool enable)
{
2013-02-16 12:05:15 +01:00
thread_video_t *thr = (thread_video_t*)data;
if (thr)
{
thread_packet_t pkt;
pkt.type = CMD_OVERLAY_FULL_SCREEN;
pkt.data.b = enable;
2016-05-10 03:14:23 +02:00
video_thread_send_and_wait_user_to_thread(thr, &pkt);
}
2013-02-16 11:44:15 +01:00
}
2014-09-08 17:57:18 +02:00
/* We cannot wait for this to complete. Totally blocks the main thread. */
static void thread_overlay_set_alpha(void *data, unsigned idx, float mod)
2013-02-16 11:44:15 +01:00
{
2013-02-16 12:05:15 +01:00
thread_video_t *thr = (thread_video_t*)data;
if (thr)
{
slock_lock(thr->alpha_lock);
thr->alpha_mod[idx] = mod;
thr->alpha_update = true;
slock_unlock(thr->alpha_lock);
}
2013-02-16 11:44:15 +01:00
}
static const video_overlay_interface_t thread_overlay = {
thread_overlay_enable,
thread_overlay_load,
thread_overlay_tex_geom,
thread_overlay_vertex_geom,
thread_overlay_full_screen,
thread_overlay_set_alpha,
};
2016-05-10 03:14:23 +02:00
static void video_thread_get_overlay_interface(void *data,
2014-09-08 17:57:18 +02:00
const video_overlay_interface_t **iface)
2013-02-16 11:44:15 +01:00
{
2013-02-16 12:05:15 +01:00
thread_video_t *thr = (thread_video_t*)data;
if (thr && thr->driver_data &&
thr->driver && thr->driver->overlay_interface)
{
thr->driver->overlay_interface(thr->driver_data, &thr->overlay);
*iface = &thread_overlay;
}
else
*iface = NULL;
2013-02-16 11:44:15 +01:00
}
#endif
static void thread_set_video_mode(void *data,
unsigned width, unsigned height, bool video_fullscreen)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr)
{
thread_packet_t pkt;
pkt.type = CMD_POKE_SET_VIDEO_MODE;
pkt.data.new_mode.width = width;
pkt.data.new_mode.height = height;
pkt.data.new_mode.fullscreen = video_fullscreen;
2016-05-10 03:14:23 +02:00
video_thread_send_and_wait_user_to_thread(thr, &pkt);
}
}
static void thread_set_filtering(void *data,
unsigned idx, bool smooth, bool ctx_scaling)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr)
{
thread_packet_t pkt;
pkt.type = CMD_POKE_SET_FILTERING;
pkt.data.filtering.index = idx;
pkt.data.filtering.smooth = smooth;
2016-05-10 03:14:23 +02:00
video_thread_send_and_wait_user_to_thread(thr, &pkt);
}
}
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 https://github.com/libretro/RetroArch/pull/12916/commits/c1b6c0bff2aa33cde035b43cb31ac7e78ff2a07a - 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
2021-09-03 06:15:25 +02:00
static void thread_set_hdr_max_nits(void *data, float max_nits)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr)
{
thread_packet_t pkt;
pkt.type = CMD_POKE_SET_HDR_MAX_NITS;
pkt.data.hdr.max_nits = max_nits;
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 https://github.com/libretro/RetroArch/pull/12916/commits/c1b6c0bff2aa33cde035b43cb31ac7e78ff2a07a - 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
2021-09-03 06:15:25 +02:00
video_thread_send_and_wait_user_to_thread(thr, &pkt);
}
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 https://github.com/libretro/RetroArch/pull/12916/commits/c1b6c0bff2aa33cde035b43cb31ac7e78ff2a07a - 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
2021-09-03 06:15:25 +02:00
}
static void thread_set_hdr_paper_white_nits(void *data, float paper_white_nits)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr)
{
thread_packet_t pkt;
pkt.type = CMD_POKE_SET_HDR_PAPER_WHITE_NITS;
pkt.data.hdr.paper_white_nits = paper_white_nits;
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 https://github.com/libretro/RetroArch/pull/12916/commits/c1b6c0bff2aa33cde035b43cb31ac7e78ff2a07a - 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
2021-09-03 06:15:25 +02:00
video_thread_send_and_wait_user_to_thread(thr, &pkt);
}
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 https://github.com/libretro/RetroArch/pull/12916/commits/c1b6c0bff2aa33cde035b43cb31ac7e78ff2a07a - 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
2021-09-03 06:15:25 +02:00
}
static void thread_set_hdr_contrast(void *data, float contrast)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr)
{
thread_packet_t pkt;
pkt.type = CMD_POKE_SET_HDR_CONTRAST;
pkt.data.hdr.contrast = contrast;
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 https://github.com/libretro/RetroArch/pull/12916/commits/c1b6c0bff2aa33cde035b43cb31ac7e78ff2a07a - 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
2021-09-03 06:15:25 +02:00
video_thread_send_and_wait_user_to_thread(thr, &pkt);
}
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 https://github.com/libretro/RetroArch/pull/12916/commits/c1b6c0bff2aa33cde035b43cb31ac7e78ff2a07a - 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
2021-09-03 06:15:25 +02:00
}
static void thread_set_hdr_expand_gamut(void *data, bool expand_gamut)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr)
{
thread_packet_t pkt;
pkt.type = CMD_POKE_SET_HDR_EXPAND_GAMUT;
pkt.data.hdr.expand_gamut = expand_gamut;
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 https://github.com/libretro/RetroArch/pull/12916/commits/c1b6c0bff2aa33cde035b43cb31ac7e78ff2a07a - 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
2021-09-03 06:15:25 +02:00
video_thread_send_and_wait_user_to_thread(thr, &pkt);
}
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 https://github.com/libretro/RetroArch/pull/12916/commits/c1b6c0bff2aa33cde035b43cb31ac7e78ff2a07a - 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
2021-09-03 06:15:25 +02:00
}
static void thread_get_video_output_size(void *data,
unsigned *width, unsigned *height, char *desc, size_t desc_len)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr && thr->driver_data &&
thr->poke && thr->poke->get_video_output_size)
thr->poke->get_video_output_size(thr->driver_data,
width, height, desc, desc_len);
}
static void thread_get_video_output_prev(void *data)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr && thr->driver_data &&
thr->poke && thr->poke->get_video_output_prev)
thr->poke->get_video_output_prev(thr->driver_data);
}
static void thread_get_video_output_next(void *data)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr && thr->driver_data &&
thr->poke && thr->poke->get_video_output_next)
thr->poke->get_video_output_next(thr->driver_data);
}
static void thread_set_aspect_ratio(void *data, unsigned aspect_ratio_idx)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr)
{
thread_packet_t pkt;
pkt.type = CMD_POKE_SET_ASPECT_RATIO;
pkt.data.i = aspect_ratio_idx;
2016-05-10 03:14:23 +02:00
video_thread_send_and_wait_user_to_thread(thr, &pkt);
}
}
static void thread_set_texture_frame(void *data, const void *frame,
bool rgb32, unsigned width, unsigned height, float alpha)
{
thread_video_t *thr = (thread_video_t*)data;
size_t required = width * height *
(rgb32 ? sizeof(uint32_t) : sizeof(uint16_t));
if (!thr)
return;
slock_lock(thr->frame.lock);
2014-09-08 17:57:18 +02:00
if (!thr->texture.frame || required > thr->texture.frame_cap)
{
void *tmp_frame = realloc(thr->texture.frame, required);
if (!tmp_frame)
goto end;
thr->texture.frame = tmp_frame;
thr->texture.frame_cap = required;
}
memcpy(thr->texture.frame, frame, required);
thr->texture.rgb32 = rgb32;
thr->texture.width = width;
thr->texture.height = height;
thr->texture.alpha = alpha;
thr->texture.frame_updated = true;
end:
slock_unlock(thr->frame.lock);
}
static void thread_set_texture_enable(void *data, bool state, bool full_screen)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr)
{
slock_lock(thr->frame.lock);
thr->texture.enable = state;
thr->texture.full_screen = full_screen;
slock_unlock(thr->frame.lock);
}
}
static void thread_set_osd_msg(void *data,
const char *msg, const void *params, void *font)
{
thread_video_t *thr = (thread_video_t*)data;
/* TODO : find a way to determine if the calling
* thread is the driver thread or not. */
if (thr && thr->driver_data && thr->poke && thr->poke->set_osd_msg)
thr->poke->set_osd_msg(thr->driver_data, msg, params, font);
}
static void thread_show_mouse(void *data, bool state)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr)
{
thread_packet_t pkt;
pkt.type = CMD_POKE_SHOW_MOUSE;
pkt.data.b = state;
video_thread_send_and_wait_user_to_thread(thr, &pkt);
}
}
static void thread_grab_mouse_toggle(void *data)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr)
{
thread_packet_t pkt;
pkt.type = CMD_POKE_GRAB_MOUSE_TOGGLE;
video_thread_send_and_wait_user_to_thread(thr, &pkt);
}
}
static uintptr_t thread_load_texture(void *video_data, void *data,
bool threaded, enum texture_filter_type filter_type)
{
thread_video_t *thr = (thread_video_t*)video_data;
if (thr && thr->driver_data && thr->poke && thr->poke->load_texture)
return thr->poke->load_texture(thr->driver_data,
data, threaded, filter_type);
return 0;
}
static void thread_unload_texture(void *data,
bool threaded, uintptr_t id)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr && thr->driver_data && thr->poke && thr->poke->unload_texture)
thr->poke->unload_texture(thr->driver_data, threaded, id);
}
2013-03-10 19:39:37 +01:00
static void thread_apply_state_changes(void *data)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr)
{
slock_lock(thr->frame.lock);
thr->apply_state_changes = true;
slock_unlock(thr->frame.lock);
}
2013-03-10 19:39:37 +01:00
}
/* This is read-only state which should not
2014-09-08 17:57:18 +02:00
* have any kind of race condition. */
2015-01-19 21:24:08 +01:00
static struct video_shader *thread_get_current_shader(void *data)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr && thr->driver_data && thr->poke && thr->poke->get_current_shader)
return thr->poke->get_current_shader(thr->driver_data);
return NULL;
}
static uint32_t thread_get_flags(void *data)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr && thr->driver_data && thr->poke && thr->poke->get_flags)
return thr->poke->get_flags(thr->driver_data);
return 0;
}
static const video_poke_interface_t thread_poke = {
thread_get_flags,
thread_load_texture,
thread_unload_texture,
thread_set_video_mode,
NULL, /* get_refresh_rate */
thread_set_filtering,
thread_get_video_output_size,
thread_get_video_output_prev,
thread_get_video_output_next,
2015-04-25 02:35:06 +02:00
NULL, /* get_current_framebuffer */
NULL, /* get_proc_address */
thread_set_aspect_ratio,
2013-03-10 19:39:37 +01:00
thread_apply_state_changes,
thread_set_texture_frame,
thread_set_texture_enable,
2015-10-28 00:55:11 +01:00
thread_set_osd_msg,
thread_show_mouse,
thread_grab_mouse_toggle,
thread_get_current_shader,
NULL, /* get_current_software_framebuffer */
NULL, /* get_hw_render_interface */
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 https://github.com/libretro/RetroArch/pull/12916/commits/c1b6c0bff2aa33cde035b43cb31ac7e78ff2a07a - 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
2021-09-03 06:15:25 +02:00
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(void *data,
2014-09-08 17:57:18 +02:00
const video_poke_interface_t **iface)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr && thr->driver_data &&
thr->driver && thr->driver->poke_interface)
{
thr->driver->poke_interface(thr->driver_data, &thr->poke);
*iface = &thread_poke;
}
else
*iface = NULL;
}
#ifdef HAVE_GFX_WIDGETS
2020-02-17 01:43:40 +01:00
static bool video_thread_wrapper_gfx_widgets_enabled(void *data)
{
thread_video_t *thr = (thread_video_t*)data;
if (thr && thr->driver_data &&
thr->driver && thr->driver->gfx_widgets_enabled)
2020-02-17 01:43:40 +01:00
return thr->driver->gfx_widgets_enabled(thr->driver_data);
return false;
}
#endif
static const video_driver_t video_thread = {
2016-05-10 03:14:23 +02:00
video_thread_init_never_call, /* Should never be called directly. */
video_thread_frame,
video_thread_set_nonblock_state,
video_thread_alive,
video_thread_focus,
video_thread_suppress_screensaver,
video_thread_has_windowed,
video_thread_set_shader,
video_thread_free,
"Thread wrapper",
2016-05-10 03:14:23 +02:00
video_thread_set_viewport,
video_thread_set_rotation,
video_thread_viewport_info,
video_thread_read_viewport,
NULL, /* read_frame_raw */
#ifdef HAVE_OVERLAY
video_thread_get_overlay_interface,
2019-04-01 04:00:58 +01:00
#endif
#ifdef HAVE_VIDEO_LAYOUT
NULL, /* video_layout_render_interface */
#endif
2016-05-10 03:14:23 +02:00
video_thread_get_poke_interface,
NULL, /* wrap_type_to_enum */
#ifdef HAVE_GFX_WIDGETS
2020-02-17 01:43:40 +01:00
video_thread_wrapper_gfx_widgets_enabled
#endif
};
static void video_thread_set_callbacks(thread_video_t *thr,
const video_driver_t *drv)
{
thr->video_thread = video_thread;
thr->driver = drv;
2014-09-08 17:57:18 +02:00
if (drv)
{
/* Disable optional features if not present. */
if (!drv->read_viewport)
thr->video_thread.read_viewport = NULL;
if (!drv->set_viewport)
thr->video_thread.set_viewport = NULL;
if (!drv->set_rotation)
thr->video_thread.set_rotation = NULL;
if (!drv->set_shader)
thr->video_thread.set_shader = NULL;
#ifdef HAVE_OVERLAY
if (!drv->overlay_interface)
thr->video_thread.overlay_interface = NULL;
#endif
if (!drv->poke_interface)
thr->video_thread.poke_interface = NULL;
}
}
/**
2016-05-10 03:14:23 +02:00
* video_init_thread:
* @out_driver : Output video driver
* @out_data : Output video data
* @input : Input input driver
* @input_data : Input input data
* @driver : Input Video driver
* @info : Video info handle.
*
* Creates, initializes and starts a video driver in a new thread.
* Access to video driver will be mediated through this driver.
*
* Returns: true (1) if successful, otherwise false (0).
**/
bool video_init_thread(const video_driver_t **out_driver, void **out_data,
input_driver_t **input, void **input_data,
2017-01-16 18:02:28 +01:00
const video_driver_t *drv, const video_info_t info)
{
thread_video_t *thr = (thread_video_t*)calloc(1, sizeof(*thr));
if (!thr)
goto error;
2016-05-10 03:14:23 +02:00
video_thread_set_callbacks(thr, drv);
if (!video_thread_init(thr, info, input, input_data))
{
thr->video_thread.free(thr);
goto error;
}
*out_driver = &thr->video_thread;
*out_data = thr;
return true;
error:
*out_driver = NULL;
*out_data = NULL;
return false;
}
2016-05-10 03:14:23 +02:00
bool video_thread_font_init(const void **font_driver, void **font_handle,
void *data, const char *font_path, float video_font_size,
enum font_driver_render_api api, custom_font_command_method_t func,
bool is_threaded)
{
thread_packet_t pkt;
2021-11-09 07:06:04 +01:00
video_driver_state_t *video_st = video_state_get_ptr();
thread_video_t *thr = (thread_video_t*)video_st->data;
if (!thr)
return false;
pkt.type = CMD_FONT_INIT;
pkt.data.font_init.method = func;
pkt.data.font_init.font_driver = font_driver;
pkt.data.font_init.font_handle = font_handle;
pkt.data.font_init.video_data = data;
pkt.data.font_init.font_path = font_path;
pkt.data.font_init.font_size = video_font_size;
pkt.data.font_init.is_threaded = is_threaded;
pkt.data.font_init.api = api;
video_thread_send_and_wait_user_to_thread(thr, &pkt);
return pkt.data.font_init.return_value;
}
unsigned video_thread_texture_load(void *data, custom_command_method_t func)
{
2020-08-18 16:51:00 +02:00
thread_packet_t pkt;
2021-11-09 07:06:04 +01:00
video_driver_state_t *video_st = video_state_get_ptr();
thread_video_t *thr = (thread_video_t*)video_st->data;
if (!thr)
return 0;
2020-08-18 16:51:00 +02:00
pkt.type = CMD_CUSTOM_COMMAND;
pkt.data.custom_command.method = func;
pkt.data.custom_command.data = data;
video_thread_send_and_wait_user_to_thread(thr, &pkt);
return pkt.data.custom_command.return_value;
}