diff --git a/intern/ghost/intern/GHOST_ContextVK.cc b/intern/ghost/intern/GHOST_ContextVK.cc index 5455243fb6a..f02555ba023 100644 --- a/intern/ghost/intern/GHOST_ContextVK.cc +++ b/intern/ghost/intern/GHOST_ContextVK.cc @@ -25,8 +25,7 @@ #include "CLG_log.h" -#include - +#include #include #include #include @@ -34,6 +33,7 @@ #include #include #include +#include #include @@ -852,21 +852,19 @@ static bool selectSurfaceFormat(const VkPhysicalDevice physical_device, vector formats(format_count); vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &format_count, formats.data()); - for (const VkSurfaceFormatKHR &format : formats) { - if (format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR && - format.format == VK_FORMAT_R8G8B8A8_UNORM) - { - r_surfaceFormat = format; - return true; - } - } + array, 4> selection_order = { + make_pair(VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT, VK_FORMAT_R16G16B16A16_SFLOAT), + make_pair(VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, VK_FORMAT_R16G16B16A16_SFLOAT), + make_pair(VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, VK_FORMAT_R8G8B8A8_UNORM), + make_pair(VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, VK_FORMAT_B8G8R8A8_UNORM), + }; - for (const VkSurfaceFormatKHR &format : formats) { - if (format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR && - format.format == VK_FORMAT_B8G8R8A8_UNORM) - { - r_surfaceFormat = format; - return true; + for (pair &pair : selection_order) { + for (const VkSurfaceFormatKHR &format : formats) { + if (format.colorSpace == pair.first && format.format == pair.second) { + r_surfaceFormat = format; + return true; + } } } @@ -1053,7 +1051,7 @@ GHOST_TSuccess GHOST_ContextVK::recreateSwapchain() create_info.imageExtent = m_render_extent; create_info.imageArrayLayers = 1; create_info.imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; - create_info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; + create_info.preTransform = capabilities.currentTransform; create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; create_info.presentMode = present_mode; create_info.clipped = VK_TRUE; @@ -1207,6 +1205,7 @@ GHOST_TSuccess GHOST_ContextVK::initializeDrawingContext() requireExtension(extensions_available, extensions_enabled, VK_KHR_SURFACE_EXTENSION_NAME); requireExtension(extensions_available, extensions_enabled, native_surface_extension_name); required_device_extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + optional_device_extensions.push_back(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME); /* X11 doesn't use the correct swapchain offset, flipping can squash the first frames. */ const bool use_swapchain_maintenance1 = diff --git a/scripts/startup/bl_ui/space_userpref.py b/scripts/startup/bl_ui/space_userpref.py index feddd06fd69..ac1b1adb77b 100644 --- a/scripts/startup/bl_ui/space_userpref.py +++ b/scripts/startup/bl_ui/space_userpref.py @@ -2878,6 +2878,13 @@ class USERPREF_PT_experimental_prototypes(ExperimentalPanel, Panel): ({"property": "write_legacy_blend_file_format"}, ("/blender/blender/issues/129309", "#129309")), ), ) + import sys + if sys.platform == "linux": + self._draw_items( + context, ( + ({"property": "use_vulkan_hdr"}, ("/blender/blender/issues/140277", "#140277")), + ), + ) # Keep this as tweaks can be useful to restore. diff --git a/source/blender/gpu/vulkan/vk_common.cc b/source/blender/gpu/vulkan/vk_common.cc index 6771f4e7e83..3899ffb580f 100644 --- a/source/blender/gpu/vulkan/vk_common.cc +++ b/source/blender/gpu/vulkan/vk_common.cc @@ -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(); } diff --git a/source/blender/gpu/vulkan/vk_context.cc b/source/blender/gpu/vulkan/vk_context.cc index 19495d73e0b..d5f7754464f 100644 --- a/source/blender/gpu/vulkan/vk_context.cc +++ b/source/blender/gpu/vulkan/vk_context.cc @@ -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); diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 783a5b04dea..cc9ac7b8096 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -227,7 +227,8 @@ typedef struct UserDef_Experimental { char use_shader_node_previews; char use_bundle_and_closure_nodes; char use_socket_structure_type; - char _pad[5]; + char use_vulkan_hdr; + char _pad[4]; } UserDef_Experimental; #define USER_EXPERIMENTAL_TEST(userdef, member) \ diff --git a/source/blender/makesrna/intern/rna_userdef.cc b/source/blender/makesrna/intern/rna_userdef.cc index b1ba0930e35..1a46386bfef 100644 --- a/source/blender/makesrna/intern/rna_userdef.cc +++ b/source/blender/makesrna/intern/rna_userdef.cc @@ -7610,6 +7610,12 @@ static void rna_def_userdef_experimental(BlenderRNA *brna) "Recompute all ID usercounts before saving to a blendfile. Allows to " "work around invalid usercount handling in code that may lead to loss " "of data due to wrongly detected unused data-blocks"); + + prop = RNA_def_property(srna, "use_vulkan_hdr", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_ui_text( + prop, + "Vulkan HDR support Linux/Wayland", + "Enables HDR on Linux/Wayland on HDR capable setups. Requires a restart"); } static void rna_def_userdef_addon_collection(BlenderRNA *brna, PropertyRNA *cprop)