diff --git a/docs/features.txt b/docs/features.txt index 7b76163cc13..01bdfb2683f 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -537,6 +537,7 @@ Khronos extensions that are not part of any Vulkan version: VK_EXT_pipeline_creation_feedback DONE (anv, radv) VK_EXT_post_depth_coverage DONE (anv/gfx10+, lvp, radv) VK_EXT_private_data DONE (anv, lvp, radv, tu, v3dv) + VK_EXT_provoking_vertex DONE (anv, lvp, radv, tu) VK_EXT_queue_family_foreign DONE (anv, radv) VK_EXT_robustness2 DONE (anv, radv, tu) VK_EXT_sample_locations DONE (anv, radv/gfx9-, tu/a650) diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c index fd7ea6df927..cef4215f474 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.c +++ b/src/freedreno/vulkan/tu_cmd_buffer.c @@ -3632,6 +3632,7 @@ tu6_draw_common(struct tu_cmd_buffer *cmd, tu_cs_emit_regs(cs, A6XX_PC_PRIMITIVE_CNTL_0( .primitive_restart = pipeline->ia.primitive_restart && indexed, + .provoking_vtx_last = pipeline->provoking_vertex_last, .tess_upper_left_domain_origin = pipeline->tess.upper_left_domain_origin)); diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c index d6b11d1152c..04801cb77bf 100644 --- a/src/freedreno/vulkan/tu_device.c +++ b/src/freedreno/vulkan/tu_device.c @@ -177,6 +177,7 @@ get_device_extensions(const struct tu_physical_device *device, .EXT_shader_stencil_export = true, .EXT_shader_viewport_index_layer = true, .EXT_vertex_attribute_divisor = true, + .EXT_provoking_vertex = true, #ifdef ANDROID .ANDROID_native_buffer = true, #endif @@ -734,6 +735,13 @@ tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, features->timelineSemaphore = true; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT: { + VkPhysicalDeviceProvokingVertexFeaturesEXT *features = + (VkPhysicalDeviceProvokingVertexFeaturesEXT *)ext; + features->provokingVertexLast = true; + features->transformFeedbackPreservesProvokingVertex = true; + break; + } default: break; @@ -1059,6 +1067,13 @@ tu_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, props->maxTimelineSemaphoreValueDifference = UINT64_MAX; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT: { + VkPhysicalDeviceProvokingVertexPropertiesEXT *properties = + (VkPhysicalDeviceProvokingVertexPropertiesEXT *)ext; + properties->provokingVertexModePerPipeline = true; + properties->transformFeedbackPreservesTriangleFanProvokingVertex = false; + break; + } default: break; } diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c index c005e169230..977c1c54440 100644 --- a/src/freedreno/vulkan/tu_pipeline.c +++ b/src/freedreno/vulkan/tu_pipeline.c @@ -2642,6 +2642,10 @@ tu_pipeline_builder_parse_rasterization(struct tu_pipeline_builder *builder, rast_info->depthBiasSlopeFactor); } + const struct VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *provoking_vtx_state = + vk_find_struct_const(rast_info->pNext, PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT); + pipeline->provoking_vertex_last = provoking_vtx_state && + provoking_vtx_state->provokingVertexMode == VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT; } static void diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h index dd339b27e67..2137d70deb3 100644 --- a/src/freedreno/vulkan/tu_private.h +++ b/src/freedreno/vulkan/tu_private.h @@ -1173,6 +1173,8 @@ struct tu_pipeline uint32_t local_size[3]; } compute; + bool provoking_vertex_last; + struct tu_lrz_pipeline lrz; void *executables_mem_ctx;