From 6430fc29a910d0d30db1ce6aaa05bf776b112623 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 18 Dec 2021 05:47:48 +0100 Subject: [PATCH 1/3] Vulkan: Implement VK_EXT_primitive_topology_list_restart --- externals/Vulkan-Headers | 2 +- .../renderer_vulkan/vk_graphics_pipeline.cpp | 4 +-- .../vulkan_common/vulkan_device.cpp | 28 +++++++++++++++++++ src/video_core/vulkan_common/vulkan_device.h | 10 +++++++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/externals/Vulkan-Headers b/externals/Vulkan-Headers index 07c4a37bcf..e005e1f817 160000 --- a/externals/Vulkan-Headers +++ b/externals/Vulkan-Headers @@ -1 +1 @@ -Subproject commit 07c4a37bcf41ea50aef6e98236abdfe8089fb4c6 +Subproject commit e005e1f8175d006adc3676b40ac3dd2212961a68 diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 616a7b457b..0c175c557f 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -605,7 +605,8 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .flags = 0, .topology = input_assembly_topology, .primitiveRestartEnable = key.state.primitive_restart_enable != 0 && - SupportsPrimitiveRestart(input_assembly_topology), + (device.IsExtPrimitiveTopologyListRestartSupported() || + SupportsPrimitiveRestart(input_assembly_topology)), }; const VkPipelineTessellationStateCreateInfo tessellation_ci{ .sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, @@ -613,7 +614,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .flags = 0, .patchControlPoints = key.state.patch_control_points_minus_one.Value() + 1, }; - std::array swizzles; std::ranges::transform(key.state.viewport_swizzles, swizzles.begin(), UnpackViewportSwizzle); const VkPipelineViewportSwizzleStateCreateInfoNV swizzle_ci{ diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 7bf5b6578b..38410eee45 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -433,6 +433,19 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR LOG_INFO(Render_Vulkan, "Device doesn't support uint8 indexes"); } + VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT primitive_topology_list_restart; + if (is_topology_list_restart_supported || is_patch_list_restart_supported) { + primitive_topology_list_restart = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT, + .pNext = nullptr, + .primitiveTopologyListRestart = is_topology_list_restart_supported, + .primitiveTopologyPatchListRestart = is_patch_list_restart_supported, + }; + SetNext(next, primitive_topology_list_restart); + } else { + LOG_INFO(Render_Vulkan, "Device doesn't support list topology primitive restart"); + } + VkPhysicalDeviceTransformFeedbackFeaturesEXT transform_feedback; if (ext_transform_feedback) { transform_feedback = { @@ -891,6 +904,7 @@ std::vector Device::LoadExtensions(bool requires_surface) { bool has_ext_provoking_vertex{}; bool has_ext_vertex_input_dynamic_state{}; bool has_ext_line_rasterization{}; + bool has_ext_primitive_topology_list_restart{}; for (const std::string& extension : supported_extensions) { const auto test = [&](std::optional> status, const char* name, bool push) { @@ -915,6 +929,8 @@ std::vector Device::LoadExtensions(bool requires_surface) { test(has_khr_shader_float16_int8, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, false); test(ext_depth_range_unrestricted, VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, true); test(ext_index_type_uint8, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, true); + test(has_ext_primitive_topology_list_restart, + VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME, true); test(ext_sampler_filter_minmax, VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME, true); test(ext_shader_viewport_index_layer, VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, true); @@ -1128,6 +1144,18 @@ std::vector Device::LoadExtensions(bool requires_surface) { max_push_descriptors = push_descriptor.maxPushDescriptors; } + if (has_ext_primitive_topology_list_restart) { + VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT primitive_topology_list_restart{}; + primitive_topology_list_restart.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT; + primitive_topology_list_restart.pNext = nullptr; + physical_properties.pNext = &primitive_topology_list_restart; + physical.GetProperties2KHR(physical_properties); + is_topology_list_restart_supported = + primitive_topology_list_restart.primitiveTopologyListRestart; + is_patch_list_restart_supported = + primitive_topology_list_restart.primitiveTopologyPatchListRestart; + } return extensions; } diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 10653ac6b9..ed7782d421 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -243,6 +243,11 @@ public: return ext_index_type_uint8; } + /// Returns true if the device supports VK_EXT_primitive_topology_list_restart. + bool IsExtPrimitiveTopologyListRestartSupported() const { + return ext_primitive_topology_list_restart; + } + /// Returns true if the device supports VK_EXT_sampler_filter_minmax. bool IsExtSamplerFilterMinmaxSupported() const { return ext_sampler_filter_minmax; @@ -401,6 +406,9 @@ private: bool is_shader_int16_supported{}; ///< Support for int16. bool is_shader_storage_image_multisample{}; ///< Support for image operations on MSAA images. bool is_blit_depth_stencil_supported{}; ///< Support for blitting from and to depth stencil. + bool is_topology_list_restart_supported{}; ///< Support for primitive restart with list + ///< topologies. + bool is_patch_list_restart_supported{}; ///< Support for primitive restart with list patch. bool nv_viewport_swizzle{}; ///< Support for VK_NV_viewport_swizzle. bool nv_viewport_array2{}; ///< Support for VK_NV_viewport_array2. bool nv_geometry_shader_passthrough{}; ///< Support for VK_NV_geometry_shader_passthrough. @@ -411,6 +419,8 @@ private: bool khr_pipeline_executable_properties{}; ///< Support for executable properties. bool khr_swapchain_mutable_format{}; ///< Support for VK_KHR_swapchain_mutable_format. bool ext_index_type_uint8{}; ///< Support for VK_EXT_index_type_uint8. + bool ext_primitive_topology_list_restart{}; ///< Support for + ///< VK_EXT_primitive_topology_list_restart. bool ext_sampler_filter_minmax{}; ///< Support for VK_EXT_sampler_filter_minmax. bool ext_depth_range_unrestricted{}; ///< Support for VK_EXT_depth_range_unrestricted. bool ext_shader_viewport_index_layer{}; ///< Support for VK_EXT_shader_viewport_index_layer. From 14d2c77f910aad77b408eef130d8212430e7202a Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 18 Dec 2021 06:52:28 +0100 Subject: [PATCH 2/3] Vulkan: implement Logical Operations. --- src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | 4 ++-- src/video_core/vulkan_common/vulkan_device.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 0c175c557f..7fe735e756 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -748,8 +748,8 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, .pNext = nullptr, .flags = 0, - .logicOpEnable = VK_FALSE, - .logicOp = VK_LOGIC_OP_COPY, + .logicOpEnable = key.state.logic_op_enable != 0, + .logicOp = static_cast(key.state.logic_op.Value()), .attachmentCount = static_cast(cb_attachments.size()), .pAttachments = cb_attachments.data(), .blendConstants = {}, diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 38410eee45..2413e72ba9 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -271,7 +271,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR .tessellationShader = true, .sampleRateShading = true, .dualSrcBlend = true, - .logicOp = false, + .logicOp = true, .multiDrawIndirect = false, .drawIndirectFirstInstance = false, .depthClamp = true, From 6c00151d17050861e76677c219296fb35bf76214 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 18 Dec 2021 07:03:13 +0100 Subject: [PATCH 3/3] Vulkan: Fix the checks for primitive restart extension. --- .../renderer_vulkan/vk_graphics_pipeline.cpp | 7 ++++-- .../vulkan_common/vulkan_device.cpp | 25 ++++++++++--------- src/video_core/vulkan_common/vulkan_device.h | 17 +++++++------ 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 7fe735e756..d514b71d09 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -605,8 +605,11 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .flags = 0, .topology = input_assembly_topology, .primitiveRestartEnable = key.state.primitive_restart_enable != 0 && - (device.IsExtPrimitiveTopologyListRestartSupported() || - SupportsPrimitiveRestart(input_assembly_topology)), + ((input_assembly_topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST && + device.IsTopologyListPrimitiveRestartSupported()) || + SupportsPrimitiveRestart(input_assembly_topology) || + (input_assembly_topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST && + device.IsPatchListPrimitiveRestartSupported())), }; const VkPipelineTessellationStateCreateInfo tessellation_ci{ .sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 2413e72ba9..9862b815b9 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -1129,6 +1129,19 @@ std::vector Device::LoadExtensions(bool requires_surface) { khr_pipeline_executable_properties = true; } } + if (has_ext_primitive_topology_list_restart) { + VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT primitive_topology_list_restart{}; + primitive_topology_list_restart.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT; + primitive_topology_list_restart.pNext = nullptr; + features.pNext = &primitive_topology_list_restart; + physical.GetFeatures2KHR(features); + + is_topology_list_restart_supported = + primitive_topology_list_restart.primitiveTopologyListRestart; + is_patch_list_restart_supported = + primitive_topology_list_restart.primitiveTopologyPatchListRestart; + } if (has_khr_image_format_list && has_khr_swapchain_mutable_format) { extensions.push_back(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME); extensions.push_back(VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME); @@ -1144,18 +1157,6 @@ std::vector Device::LoadExtensions(bool requires_surface) { max_push_descriptors = push_descriptor.maxPushDescriptors; } - if (has_ext_primitive_topology_list_restart) { - VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT primitive_topology_list_restart{}; - primitive_topology_list_restart.sType = - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT; - primitive_topology_list_restart.pNext = nullptr; - physical_properties.pNext = &primitive_topology_list_restart; - physical.GetProperties2KHR(physical_properties); - is_topology_list_restart_supported = - primitive_topology_list_restart.primitiveTopologyListRestart; - is_patch_list_restart_supported = - primitive_topology_list_restart.primitiveTopologyPatchListRestart; - } return extensions; } diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index ed7782d421..4c9d86aad1 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -238,14 +238,19 @@ public: return khr_workgroup_memory_explicit_layout; } - /// Returns true if the device supports VK_EXT_index_type_uint8. - bool IsExtIndexTypeUint8Supported() const { - return ext_index_type_uint8; + /// Returns true if the device supports VK_EXT_primitive_topology_list_restart. + bool IsTopologyListPrimitiveRestartSupported() const { + return is_topology_list_restart_supported; } /// Returns true if the device supports VK_EXT_primitive_topology_list_restart. - bool IsExtPrimitiveTopologyListRestartSupported() const { - return ext_primitive_topology_list_restart; + bool IsPatchListPrimitiveRestartSupported() const { + return is_patch_list_restart_supported; + } + + /// Returns true if the device supports VK_EXT_index_type_uint8. + bool IsExtIndexTypeUint8Supported() const { + return ext_index_type_uint8; } /// Returns true if the device supports VK_EXT_sampler_filter_minmax. @@ -419,8 +424,6 @@ private: bool khr_pipeline_executable_properties{}; ///< Support for executable properties. bool khr_swapchain_mutable_format{}; ///< Support for VK_KHR_swapchain_mutable_format. bool ext_index_type_uint8{}; ///< Support for VK_EXT_index_type_uint8. - bool ext_primitive_topology_list_restart{}; ///< Support for - ///< VK_EXT_primitive_topology_list_restart. bool ext_sampler_filter_minmax{}; ///< Support for VK_EXT_sampler_filter_minmax. bool ext_depth_range_unrestricted{}; ///< Support for VK_EXT_depth_range_unrestricted. bool ext_shader_viewport_index_layer{}; ///< Support for VK_EXT_shader_viewport_index_layer.