From 3393694b44af242413229ca442e5cb2541c91036 Mon Sep 17 00:00:00 2001 From: IndecisiveTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Mon, 14 Jul 2025 00:05:20 +0300 Subject: [PATCH] renderer_vulkan: Respect provoking vertex setting --- .../renderer_vulkan/vk_graphics_pipeline.cpp | 6 +++++ .../renderer_vulkan/vk_graphics_pipeline.h | 24 ++++++++++--------- .../renderer_vulkan/vk_instance.cpp | 7 ++++++ src/video_core/renderer_vulkan/vk_instance.h | 6 +++++ .../renderer_vulkan/vk_pipeline_cache.cpp | 1 + 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 3596bb041..79fafb5b7 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -109,7 +109,13 @@ GraphicsPipeline::GraphicsPipeline( .patchControlPoints = is_rect_list ? 3U : (is_quad_list ? 4U : key.patch_control_points), }; + const vk::PipelineRasterizationProvokingVertexStateCreateInfoEXT provoking_vertex_state = { + .provokingVertexMode = key.provoking_vtx_last == Liverpool::ProvokingVtxLast::First + ? vk::ProvokingVertexModeEXT::eFirstVertex + : vk::ProvokingVertexModeEXT::eLastVertex}; + const vk::PipelineRasterizationStateCreateInfo raster_state = { + .pNext = instance.IsProvokingVertexSupported() ? &provoking_vertex_state : nullptr, .depthClampEnable = false, .rasterizerDiscardEnable = false, .polygonMode = LiverpoolToVK::PolygonMode(key.polygon_mode), diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h index ab67a52b4..30b73f698 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h @@ -33,22 +33,24 @@ using VertexInputs = boost::container::static_vector; struct GraphicsPipelineKey { std::array stage_hashes; + std::array vertex_buffer_formats; + u32 patch_control_points; u32 num_color_attachments; std::array color_formats; std::array color_buffers; - vk::Format depth_format; - vk::Format stencil_format; - - u32 num_samples; - u32 mrt_mask; - AmdGpu::PrimitiveType prim_type; - Liverpool::PolygonMode polygon_mode; - Liverpool::ClipSpace clip_space; - Liverpool::ColorBufferMask cb_shader_mask; std::array blend_controls; std::array write_masks; - std::array vertex_buffer_formats; - u32 patch_control_points; + Liverpool::ColorBufferMask cb_shader_mask; + u32 num_samples; + u32 mrt_mask; + vk::Format depth_format; + vk::Format stencil_format; + struct { + AmdGpu::PrimitiveType prim_type : 5; + Liverpool::PolygonMode polygon_mode : 2; + Liverpool::ClipSpace clip_space : 1; + Liverpool::ProvokingVtxLast provoking_vtx_last : 1; + }; bool operator==(const GraphicsPipelineKey& key) const noexcept { return std::memcmp(this, &key, sizeof(key)) == 0; diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index 85fc993a9..a00e9b2fd 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -274,6 +274,7 @@ bool Instance::CreateDevice() { list_restart = add_extension(VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME); fragment_shader_barycentric = add_extension(VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME); legacy_vertex_attributes = add_extension(VK_EXT_LEGACY_VERTEX_ATTRIBUTES_EXTENSION_NAME); + provoking_vertex = add_extension(VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME); shader_stencil_export = add_extension(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME); image_load_store_lod = add_extension(VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_EXTENSION_NAME); amd_gcn_shader = add_extension(VK_AMD_GCN_SHADER_EXTENSION_NAME); @@ -437,6 +438,9 @@ bool Instance::CreateDevice() { vk::PhysicalDeviceLegacyVertexAttributesFeaturesEXT{ .legacyVertexAttributes = true, }, + vk::PhysicalDeviceProvokingVertexFeaturesEXT{ + .provokingVertexLast = true, + }, vk::PhysicalDeviceVertexAttributeDivisorFeatures{ .vertexAttributeInstanceRateDivisor = true, }, @@ -502,6 +506,9 @@ bool Instance::CreateDevice() { if (!legacy_vertex_attributes) { device_chain.unlink(); } + if (!provoking_vertex) { + device_chain.unlink(); + } if (!shader_atomic_float2) { device_chain.unlink(); } diff --git a/src/video_core/renderer_vulkan/vk_instance.h b/src/video_core/renderer_vulkan/vk_instance.h index 830b1d5c2..19ab563e5 100644 --- a/src/video_core/renderer_vulkan/vk_instance.h +++ b/src/video_core/renderer_vulkan/vk_instance.h @@ -150,6 +150,11 @@ public: return legacy_vertex_attributes; } + /// Returns true when VK_EXT_provoking_vertex is supported. + bool IsProvokingVertexSupported() const { + return provoking_vertex; + } + /// Returns true when VK_AMD_shader_image_load_store_lod is supported. bool IsImageLoadStoreLodSupported() const { return image_load_store_lod; @@ -405,6 +410,7 @@ private: bool robustness2{}; bool list_restart{}; bool legacy_vertex_attributes{}; + bool provoking_vertex{}; bool shader_stencil_export{}; bool image_load_store_lod{}; bool amd_gcn_shader{}; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 8d12b74f3..06526477a 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -303,6 +303,7 @@ bool PipelineCache::RefreshGraphicsKey() { key.prim_type = regs.primitive_type; key.polygon_mode = regs.polygon_control.PolyMode(); key.clip_space = regs.clipper_control.clip_space; + key.provoking_vtx_last = regs.polygon_control.provoking_vtx_last; key.num_samples = regs.NumSamples(); const bool skip_cb_binding =