Vulkan: HDR support for Wayland

This change enables HDR support for wayland as an experimental feature.
It supports both non-linear extended sRGB and un-clamped sRGB.

Windows isn't supported as the HDR settings are not accessible via an
API and would require similar settings that games use to configure the
monitor. Adding those sliders isn't what we would like to add.

Vulkan (working group) is working on new extensions that might change
the shortcomings. It isn't clear yet what the extension will do and what
the impact is for applications that want to use it. When the extension
is out we should review at the situation again.

Pull Request: https://projects.blender.org/blender/blender/pulls/133159
This commit is contained in:
Jeroen Bakker
2025-06-24 11:51:14 +02:00
parent f94ec130c3
commit e63a20fee1
6 changed files with 54 additions and 31 deletions

View File

@@ -120,6 +120,9 @@ eGPUTextureFormat to_gpu_format(const VkFormat format)
case VK_FORMAT_B8G8R8A8_UNORM:
return GPU_RGBA8;
case VK_FORMAT_R16G16B16A16_SFLOAT:
return GPU_RGBA16F;
default:
BLI_assert_unreachable();
}

View File

@@ -6,8 +6,12 @@
* \ingroup gpu
*/
#include "DNA_userdef_types.h"
#include "GPU_debug.hh"
#include "gpu_capabilities_private.hh"
#include "vk_backend.hh"
#include "vk_context.hh"
#include "vk_debug.hh"
@@ -94,6 +98,11 @@ void VKContext::sync_backbuffer(bool cycle_resource_pool)
swap_chain_format_ = swap_chain_data.surface_format;
vk_extent_ = swap_chain_data.extent;
GCaps.hdr_viewport_support = U.experimental.use_vulkan_hdr &&
(swap_chain_format_.format == VK_FORMAT_R16G16B16A16_SFLOAT) &&
ELEM(swap_chain_format_.colorSpace,
VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT,
VK_COLOR_SPACE_SRGB_NONLINEAR_KHR);
}
}
}
@@ -366,11 +375,17 @@ void VKContext::swap_buffers_post_callback()
void VKContext::swap_buffers_pre_handler(const GHOST_VulkanSwapChainData &swap_chain_data)
{
GPU_debug_group_begin("BackBuffer.Blit");
VKFrameBuffer &framebuffer = *unwrap(active_fb);
VKTexture *color_attachment = unwrap(unwrap(framebuffer.color_tex(0)));
VKDevice &device = VKBackend::get().device;
device.resources.add_image(swap_chain_data.image, 1, "SwapchainImage");
render_graph::VKRenderGraph &render_graph = this->render_graph();
framebuffer.rendering_end(*this);
GPU_debug_group_begin("BackBuffer.Blit");
render_graph::VKBlitImageNode::CreateInfo blit_image = {};
blit_image.src_image = color_attachment->vk_image_handle();
blit_image.dst_image = swap_chain_data.image;
@@ -391,25 +406,17 @@ void VKContext::swap_buffers_pre_handler(const GHOST_VulkanSwapChainData &swap_c
region.dstSubresource.baseArrayLayer = 0;
region.dstSubresource.layerCount = 1;
/* Swap chain commands are CPU synchronized at this moment, allowing to temporary add the swap
* chain image as device resources. When we move towards GPU swap chain synchronization we need
* to keep track of the swap chain image between frames. */
VKDevice &device = VKBackend::get().device;
device.resources.add_image(swap_chain_data.image, 1, "SwapchainImage");
framebuffer.rendering_end(*this);
flush_render_graph(RenderGraphFlushFlags::RENEW_RENDER_GRAPH);
render_graph::VKRenderGraph &render_graph = this->render_graph();
render_graph.add_node(blit_image);
GPU_debug_group_end();
render_graph::VKSynchronizationNode::CreateInfo synchronization = {};
synchronization.vk_image = swap_chain_data.image;
synchronization.vk_image_layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
synchronization.vk_image_aspect = VK_IMAGE_ASPECT_COLOR_BIT;
render_graph.add_node(synchronization);
GPU_debug_group_end();
flush_render_graph(RenderGraphFlushFlags::SUBMIT | RenderGraphFlushFlags::RENEW_RENDER_GRAPH,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
swap_chain_data.acquire_semaphore,
swap_chain_data.present_semaphore,
swap_chain_data.submission_fence);