diff options
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_blit_screen.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_swapchain.cpp | 24 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_swapchain.h | 6 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_device.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_device.h | 6 |
5 files changed, 37 insertions, 11 deletions
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp index cb0580182..888bc7392 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp | |||
| @@ -358,7 +358,7 @@ void VKBlitScreen::CreateDescriptorPool() { | |||
| 358 | void VKBlitScreen::CreateRenderPass() { | 358 | void VKBlitScreen::CreateRenderPass() { |
| 359 | const VkAttachmentDescription color_attachment{ | 359 | const VkAttachmentDescription color_attachment{ |
| 360 | .flags = 0, | 360 | .flags = 0, |
| 361 | .format = swapchain.GetImageFormat(), | 361 | .format = swapchain.GetImageViewFormat(), |
| 362 | .samples = VK_SAMPLE_COUNT_1_BIT, | 362 | .samples = VK_SAMPLE_COUNT_1_BIT, |
| 363 | .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, | 363 | .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, |
| 364 | .storeOp = VK_ATTACHMENT_STORE_OP_STORE, | 364 | .storeOp = VK_ATTACHMENT_STORE_OP_STORE, |
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index 71b12efe8..aadf03cb0 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp | |||
| @@ -20,16 +20,15 @@ namespace Vulkan { | |||
| 20 | 20 | ||
| 21 | namespace { | 21 | namespace { |
| 22 | 22 | ||
| 23 | VkSurfaceFormatKHR ChooseSwapSurfaceFormat(vk::Span<VkSurfaceFormatKHR> formats, bool srgb) { | 23 | VkSurfaceFormatKHR ChooseSwapSurfaceFormat(vk::Span<VkSurfaceFormatKHR> formats) { |
| 24 | if (formats.size() == 1 && formats[0].format == VK_FORMAT_UNDEFINED) { | 24 | if (formats.size() == 1 && formats[0].format == VK_FORMAT_UNDEFINED) { |
| 25 | VkSurfaceFormatKHR format; | 25 | VkSurfaceFormatKHR format; |
| 26 | format.format = VK_FORMAT_B8G8R8A8_UNORM; | 26 | format.format = VK_FORMAT_B8G8R8A8_UNORM; |
| 27 | format.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; | 27 | format.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; |
| 28 | return format; | 28 | return format; |
| 29 | } | 29 | } |
| 30 | const auto& found = std::find_if(formats.begin(), formats.end(), [srgb](const auto& format) { | 30 | const auto& found = std::find_if(formats.begin(), formats.end(), [](const auto& format) { |
| 31 | const auto request_format = srgb ? VK_FORMAT_B8G8R8A8_SRGB : VK_FORMAT_B8G8R8A8_UNORM; | 31 | return format.format == VK_FORMAT_B8G8R8A8_UNORM && |
| 32 | return format.format == request_format && | ||
| 33 | format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; | 32 | format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; |
| 34 | }); | 33 | }); |
| 35 | return found != formats.end() ? *found : formats[0]; | 34 | return found != formats.end() ? *found : formats[0]; |
| @@ -143,7 +142,7 @@ void VKSwapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, | |||
| 143 | const auto formats{physical_device.GetSurfaceFormatsKHR(surface)}; | 142 | const auto formats{physical_device.GetSurfaceFormatsKHR(surface)}; |
| 144 | const auto present_modes{physical_device.GetSurfacePresentModesKHR(surface)}; | 143 | const auto present_modes{physical_device.GetSurfacePresentModesKHR(surface)}; |
| 145 | 144 | ||
| 146 | const VkSurfaceFormatKHR surface_format{ChooseSwapSurfaceFormat(formats, srgb)}; | 145 | const VkSurfaceFormatKHR surface_format{ChooseSwapSurfaceFormat(formats)}; |
| 147 | const VkPresentModeKHR present_mode{ChooseSwapPresentMode(present_modes)}; | 146 | const VkPresentModeKHR present_mode{ChooseSwapPresentMode(present_modes)}; |
| 148 | 147 | ||
| 149 | u32 requested_image_count{capabilities.minImageCount + 1}; | 148 | u32 requested_image_count{capabilities.minImageCount + 1}; |
| @@ -178,6 +177,17 @@ void VKSwapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, | |||
| 178 | swapchain_ci.queueFamilyIndexCount = static_cast<u32>(queue_indices.size()); | 177 | swapchain_ci.queueFamilyIndexCount = static_cast<u32>(queue_indices.size()); |
| 179 | swapchain_ci.pQueueFamilyIndices = queue_indices.data(); | 178 | swapchain_ci.pQueueFamilyIndices = queue_indices.data(); |
| 180 | } | 179 | } |
| 180 | static constexpr std::array view_formats{VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_SRGB}; | ||
| 181 | VkImageFormatListCreateInfo format_list{ | ||
| 182 | .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR, | ||
| 183 | .pNext = nullptr, | ||
| 184 | .viewFormatCount = static_cast<u32>(view_formats.size()), | ||
| 185 | .pViewFormats = view_formats.data(), | ||
| 186 | }; | ||
| 187 | if (device.IsKhrSwapchainMutableFormatEnabled()) { | ||
| 188 | format_list.pNext = std::exchange(swapchain_ci.pNext, &format_list); | ||
| 189 | swapchain_ci.flags |= VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR; | ||
| 190 | } | ||
| 181 | // Request the size again to reduce the possibility of a TOCTOU race condition. | 191 | // Request the size again to reduce the possibility of a TOCTOU race condition. |
| 182 | const auto updated_capabilities = physical_device.GetSurfaceCapabilitiesKHR(surface); | 192 | const auto updated_capabilities = physical_device.GetSurfaceCapabilitiesKHR(surface); |
| 183 | swapchain_ci.imageExtent = ChooseSwapExtent(updated_capabilities, width, height); | 193 | swapchain_ci.imageExtent = ChooseSwapExtent(updated_capabilities, width, height); |
| @@ -189,7 +199,7 @@ void VKSwapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, | |||
| 189 | 199 | ||
| 190 | images = swapchain.GetImages(); | 200 | images = swapchain.GetImages(); |
| 191 | image_count = static_cast<u32>(images.size()); | 201 | image_count = static_cast<u32>(images.size()); |
| 192 | image_format = surface_format.format; | 202 | image_view_format = srgb ? VK_FORMAT_B8G8R8A8_SRGB : VK_FORMAT_B8G8R8A8_UNORM; |
| 193 | } | 203 | } |
| 194 | 204 | ||
| 195 | void VKSwapchain::CreateSemaphores() { | 205 | void VKSwapchain::CreateSemaphores() { |
| @@ -205,7 +215,7 @@ void VKSwapchain::CreateImageViews() { | |||
| 205 | .flags = 0, | 215 | .flags = 0, |
| 206 | .image = {}, | 216 | .image = {}, |
| 207 | .viewType = VK_IMAGE_VIEW_TYPE_2D, | 217 | .viewType = VK_IMAGE_VIEW_TYPE_2D, |
| 208 | .format = image_format, | 218 | .format = image_view_format, |
| 209 | .components = | 219 | .components = |
| 210 | { | 220 | { |
| 211 | .r = VK_COMPONENT_SWIZZLE_IDENTITY, | 221 | .r = VK_COMPONENT_SWIZZLE_IDENTITY, |
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.h b/src/video_core/renderer_vulkan/vk_swapchain.h index bbc8f07a8..5bce41e21 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.h +++ b/src/video_core/renderer_vulkan/vk_swapchain.h | |||
| @@ -68,8 +68,8 @@ public: | |||
| 68 | return *image_views[index]; | 68 | return *image_views[index]; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | VkFormat GetImageFormat() const { | 71 | VkFormat GetImageViewFormat() const { |
| 72 | return image_format; | 72 | return image_view_format; |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | VkSemaphore CurrentPresentSemaphore() const { | 75 | VkSemaphore CurrentPresentSemaphore() const { |
| @@ -100,7 +100,7 @@ private: | |||
| 100 | u32 image_index{}; | 100 | u32 image_index{}; |
| 101 | u32 frame_index{}; | 101 | u32 frame_index{}; |
| 102 | 102 | ||
| 103 | VkFormat image_format{}; | 103 | VkFormat image_view_format{}; |
| 104 | VkExtent2D extent{}; | 104 | VkExtent2D extent{}; |
| 105 | 105 | ||
| 106 | bool current_srgb{}; | 106 | bool current_srgb{}; |
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 86ca4be54..24821c1a3 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp | |||
| @@ -839,6 +839,8 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 839 | bool has_khr_shader_float16_int8{}; | 839 | bool has_khr_shader_float16_int8{}; |
| 840 | bool has_khr_workgroup_memory_explicit_layout{}; | 840 | bool has_khr_workgroup_memory_explicit_layout{}; |
| 841 | bool has_khr_pipeline_executable_properties{}; | 841 | bool has_khr_pipeline_executable_properties{}; |
| 842 | bool has_khr_image_format_list{}; | ||
| 843 | bool has_khr_swapchain_mutable_format{}; | ||
| 842 | bool has_ext_subgroup_size_control{}; | 844 | bool has_ext_subgroup_size_control{}; |
| 843 | bool has_ext_transform_feedback{}; | 845 | bool has_ext_transform_feedback{}; |
| 844 | bool has_ext_custom_border_color{}; | 846 | bool has_ext_custom_border_color{}; |
| @@ -888,6 +890,9 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 888 | test(has_ext_shader_atomic_int64, VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME, false); | 890 | test(has_ext_shader_atomic_int64, VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME, false); |
| 889 | test(has_khr_workgroup_memory_explicit_layout, | 891 | test(has_khr_workgroup_memory_explicit_layout, |
| 890 | VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME, false); | 892 | VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME, false); |
| 893 | test(has_khr_image_format_list, VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME, false); | ||
| 894 | test(has_khr_swapchain_mutable_format, VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME, | ||
| 895 | false); | ||
| 891 | test(has_ext_line_rasterization, VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, false); | 896 | test(has_ext_line_rasterization, VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, false); |
| 892 | if (Settings::values.enable_nsight_aftermath) { | 897 | if (Settings::values.enable_nsight_aftermath) { |
| 893 | test(nv_device_diagnostics_config, VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME, | 898 | test(nv_device_diagnostics_config, VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME, |
| @@ -1066,6 +1071,11 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 1066 | khr_pipeline_executable_properties = true; | 1071 | khr_pipeline_executable_properties = true; |
| 1067 | } | 1072 | } |
| 1068 | } | 1073 | } |
| 1074 | if (has_khr_image_format_list && has_khr_swapchain_mutable_format) { | ||
| 1075 | extensions.push_back(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME); | ||
| 1076 | extensions.push_back(VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME); | ||
| 1077 | khr_swapchain_mutable_format = true; | ||
| 1078 | } | ||
| 1069 | if (khr_push_descriptor) { | 1079 | if (khr_push_descriptor) { |
| 1070 | VkPhysicalDevicePushDescriptorPropertiesKHR push_descriptor; | 1080 | VkPhysicalDevicePushDescriptorPropertiesKHR push_descriptor; |
| 1071 | push_descriptor.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR; | 1081 | push_descriptor.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR; |
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 234d74129..5599c38c5 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h | |||
| @@ -224,6 +224,11 @@ public: | |||
| 224 | return khr_pipeline_executable_properties; | 224 | return khr_pipeline_executable_properties; |
| 225 | } | 225 | } |
| 226 | 226 | ||
| 227 | /// Returns true if VK_KHR_swapchain_mutable_format is enabled. | ||
| 228 | bool IsKhrSwapchainMutableFormatEnabled() const { | ||
| 229 | return khr_swapchain_mutable_format; | ||
| 230 | } | ||
| 231 | |||
| 227 | /// Returns true if the device supports VK_KHR_workgroup_memory_explicit_layout. | 232 | /// Returns true if the device supports VK_KHR_workgroup_memory_explicit_layout. |
| 228 | bool IsKhrWorkgroupMemoryExplicitLayoutSupported() const { | 233 | bool IsKhrWorkgroupMemoryExplicitLayoutSupported() const { |
| 229 | return khr_workgroup_memory_explicit_layout; | 234 | return khr_workgroup_memory_explicit_layout; |
| @@ -390,6 +395,7 @@ private: | |||
| 390 | bool khr_workgroup_memory_explicit_layout{}; ///< Support for explicit workgroup layouts. | 395 | bool khr_workgroup_memory_explicit_layout{}; ///< Support for explicit workgroup layouts. |
| 391 | bool khr_push_descriptor{}; ///< Support for VK_KHR_push_descritor. | 396 | bool khr_push_descriptor{}; ///< Support for VK_KHR_push_descritor. |
| 392 | bool khr_pipeline_executable_properties{}; ///< Support for executable properties. | 397 | bool khr_pipeline_executable_properties{}; ///< Support for executable properties. |
| 398 | bool khr_swapchain_mutable_format{}; ///< Support for VK_KHR_swapchain_mutable_format. | ||
| 393 | bool ext_index_type_uint8{}; ///< Support for VK_EXT_index_type_uint8. | 399 | bool ext_index_type_uint8{}; ///< Support for VK_EXT_index_type_uint8. |
| 394 | bool ext_sampler_filter_minmax{}; ///< Support for VK_EXT_sampler_filter_minmax. | 400 | bool ext_sampler_filter_minmax{}; ///< Support for VK_EXT_sampler_filter_minmax. |
| 395 | bool ext_depth_range_unrestricted{}; ///< Support for VK_EXT_depth_range_unrestricted. | 401 | bool ext_depth_range_unrestricted{}; ///< Support for VK_EXT_depth_range_unrestricted. |