Browse Source

Merge pull request #7599 from FernandoS27/primrestart-vulkan

Vulkan: Fix Primitive Restart and implement Logical Operations
bunnei 4 years ago
parent
commit
36df305b13

+ 1 - 1
externals/Vulkan-Headers

@@ -1 +1 @@
-Subproject commit 07c4a37bcf41ea50aef6e98236abdfe8089fb4c6
+Subproject commit e005e1f8175d006adc3676b40ac3dd2212961a68

+ 7 - 4
src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp

@@ -605,7 +605,11 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
         .flags = 0,
         .topology = input_assembly_topology,
         .primitiveRestartEnable = key.state.primitive_restart_enable != 0 &&
-                                  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,
@@ -613,7 +617,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
         .flags = 0,
         .patchControlPoints = key.state.patch_control_points_minus_one.Value() + 1,
     };
-
     std::array<VkViewportSwizzleNV, Maxwell::NumViewports> swizzles;
     std::ranges::transform(key.state.viewport_swizzles, swizzles.begin(), UnpackViewportSwizzle);
     const VkPipelineViewportSwizzleStateCreateInfoNV swizzle_ci{
@@ -748,8 +751,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<VkLogicOp>(key.state.logic_op.Value()),
         .attachmentCount = static_cast<u32>(cb_attachments.size()),
         .pAttachments = cb_attachments.data(),
         .blendConstants = {},

+ 30 - 1
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,
@@ -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<const char*> 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<std::reference_wrapper<bool>> status, const char* name,
                               bool push) {
@@ -915,6 +929,8 @@ std::vector<const char*> 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);
@@ -1113,6 +1129,19 @@ std::vector<const char*> 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);

+ 13 - 0
src/video_core/vulkan_common/vulkan_device.h

@@ -238,6 +238,16 @@ public:
         return khr_workgroup_memory_explicit_layout;
     }
 
+    /// 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 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;
@@ -401,6 +411,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.