diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp
index ace7edaa1..0a14b77d6 100644
--- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp
+++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp
@@ -929,6 +929,7 @@ void VulkanPipelineStateViewer::clearState()
ui->pipelineShadingRate->setText(tr("1x1"));
ui->shadingRateCombiners->setText(tr("Keep, Keep"));
+ ui->provokingVertex->setText(tr("First"));
ui->sampleCount->setText(lit("1"));
ui->sampleShading->setPixmap(tick);
@@ -2600,6 +2601,8 @@ void VulkanPipelineStateViewer::setState()
.arg(ToQStr(state.rasterizer.shadingRateCombiners.first, GraphicsAPI::Vulkan))
.arg(ToQStr(state.rasterizer.shadingRateCombiners.second, GraphicsAPI::Vulkan)));
+ ui->provokingVertex->setText(state.rasterizer.provokingVertexFirst ? tr("First") : tr("Last"));
+
if(state.currentPass.renderpass.multiviews.isEmpty())
{
ui->multiview->setText(tr("Disabled"));
diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui
index bde67c289..48d79433f 100644
--- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui
+++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui
@@ -2328,6 +2328,37 @@
-
+
+
+ Provoking Vertex:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ true
+
+
+
+ -
+
+
+
+ 12
+
+
+
+ First
+
+
+ Qt::AlignCenter
+
+
+ 4
+
+
+
+ -
Qt::Vertical
diff --git a/renderdoc/api/replay/vk_pipestate.h b/renderdoc/api/replay/vk_pipestate.h
index c44681d01..074f7489b 100644
--- a/renderdoc/api/replay/vk_pipestate.h
+++ b/renderdoc/api/replay/vk_pipestate.h
@@ -855,6 +855,8 @@ See :data:`conservativeRasterizationMode`
)");
float extraPrimitiveOverestimationSize = 0.0f;
+ DOCUMENT("Whether the provoking vertex is the first one (default behaviour).");
+ bool provokingVertexFirst = true;
DOCUMENT("Whether depth biasing is enabled.");
bool depthBiasEnable = false;
DOCUMENT("The fixed depth bias value to apply to z-values.");
diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h
index f3f9f82bc..2fb01aaa1 100644
--- a/renderdoc/driver/vulkan/vk_common.h
+++ b/renderdoc/driver/vulkan/vk_common.h
@@ -1211,6 +1211,8 @@ DECLARE_REFLECTION_STRUCT(VkPhysicalDevicePresentWaitFeaturesKHR);
DECLARE_REFLECTION_STRUCT(VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDevicePrivateDataFeatures);
+DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceProvokingVertexFeaturesEXT);
+DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceProvokingVertexPropertiesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceProperties2);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceProtectedMemoryFeatures);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceProtectedMemoryProperties);
@@ -1290,6 +1292,7 @@ DECLARE_REFLECTION_STRUCT(VkPipelineMultisampleStateCreateInfo);
DECLARE_REFLECTION_STRUCT(VkPipelineRasterizationConservativeStateCreateInfoEXT);
DECLARE_REFLECTION_STRUCT(VkPipelineRasterizationDepthClipStateCreateInfoEXT);
DECLARE_REFLECTION_STRUCT(VkPipelineRasterizationLineStateCreateInfoEXT);
+DECLARE_REFLECTION_STRUCT(VkPipelineRasterizationProvokingVertexStateCreateInfoEXT);
DECLARE_REFLECTION_STRUCT(VkPipelineRasterizationStateCreateInfo);
DECLARE_REFLECTION_STRUCT(VkPipelineRasterizationStateStreamCreateInfoEXT);
DECLARE_REFLECTION_STRUCT(VkPipelineRenderingCreateInfo);
@@ -1614,6 +1617,8 @@ DECLARE_DESERIALISE_TYPE(VkPhysicalDevicePresentWaitFeaturesKHR);
DECLARE_DESERIALISE_TYPE(VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDevicePrivateDataFeatures);
+DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceProvokingVertexFeaturesEXT);
+DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceProvokingVertexPropertiesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceProperties2);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceProtectedMemoryFeatures);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceProtectedMemoryProperties);
@@ -1693,6 +1698,7 @@ DECLARE_DESERIALISE_TYPE(VkPipelineMultisampleStateCreateInfo);
DECLARE_DESERIALISE_TYPE(VkPipelineRasterizationConservativeStateCreateInfoEXT);
DECLARE_DESERIALISE_TYPE(VkPipelineRasterizationDepthClipStateCreateInfoEXT);
DECLARE_DESERIALISE_TYPE(VkPipelineRasterizationLineStateCreateInfoEXT);
+DECLARE_DESERIALISE_TYPE(VkPipelineRasterizationProvokingVertexStateCreateInfoEXT);
DECLARE_DESERIALISE_TYPE(VkPipelineRasterizationStateCreateInfo);
DECLARE_DESERIALISE_TYPE(VkPipelineRasterizationStateStreamCreateInfoEXT);
DECLARE_DESERIALISE_TYPE(VkPipelineRenderingCreateInfo);
@@ -2054,6 +2060,7 @@ DECLARE_REFLECTION_ENUM(VkPresentGravityFlagBitsEXT);
DECLARE_REFLECTION_ENUM(VkPresentModeKHR);
DECLARE_REFLECTION_ENUM(VkPresentScalingFlagBitsEXT);
DECLARE_REFLECTION_ENUM(VkPrimitiveTopology);
+DECLARE_REFLECTION_ENUM(VkProvokingVertexModeEXT);
DECLARE_REFLECTION_ENUM(VkRenderingFlagBits);
DECLARE_REFLECTION_ENUM(VkQueryControlFlagBits);
DECLARE_REFLECTION_ENUM(VkQueryPipelineStatisticFlagBits);
diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp
index 6be08dbd4..5955c1910 100644
--- a/renderdoc/driver/vulkan/vk_core.cpp
+++ b/renderdoc/driver/vulkan/vk_core.cpp
@@ -1069,6 +1069,9 @@ static const VkExtensionProperties supportedExtensions[] = {
{
VK_EXT_PRIVATE_DATA_EXTENSION_NAME, VK_EXT_PRIVATE_DATA_SPEC_VERSION,
},
+ {
+ VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME, VK_EXT_PROVOKING_VERTEX_SPEC_VERSION,
+ },
{
VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME, VK_EXT_QUEUE_FAMILY_FOREIGN_SPEC_VERSION,
},
diff --git a/renderdoc/driver/vulkan/vk_hookset_defs.h b/renderdoc/driver/vulkan/vk_hookset_defs.h
index 8359bf8f0..5e44204b0 100644
--- a/renderdoc/driver/vulkan/vk_hookset_defs.h
+++ b/renderdoc/driver/vulkan/vk_hookset_defs.h
@@ -546,7 +546,8 @@
DeclExt(KHR_fragment_shading_rate); \
DeclExt(EXT_attachment_feedback_loop_layout); \
DeclExt(EXT_pageable_device_local_memory); \
- DeclExt(EXT_swapchain_maintenance1);
+ DeclExt(EXT_swapchain_maintenance1); \
+ DeclExt(EXT_provoking_vertex);
// for simplicity and since the check itself is platform agnostic,
// these aren't protected in platform defines
@@ -663,7 +664,8 @@
CheckExt(KHR_fragment_shading_rate, VKXX); \
CheckExt(EXT_attachment_feedback_loop_layout, VKXX); \
CheckExt(EXT_pageable_device_local_memory, VKXX); \
- CheckExt(EXT_swapchain_maintenance1, VKXX);
+ CheckExt(EXT_swapchain_maintenance1, VKXX); \
+ CheckExt(EXT_provoking_vertex, VKXX);
#define HookInitVulkanInstanceExts_PhysDev() \
HookInitExtension(KHR_surface, GetPhysicalDeviceSurfaceSupportKHR); \
diff --git a/renderdoc/driver/vulkan/vk_info.cpp b/renderdoc/driver/vulkan/vk_info.cpp
index da962f339..4f707eaef 100644
--- a/renderdoc/driver/vulkan/vk_info.cpp
+++ b/renderdoc/driver/vulkan/vk_info.cpp
@@ -1245,6 +1245,16 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan,
if(depthClipControl)
negativeOneToOne = depthClipControl->negativeOneToOne != VK_FALSE;
+ // VkPipelineRasterizationProvokingVertexStateCreateInfoEXT
+ provokingVertex = VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;
+
+ const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *provokeInfo =
+ (const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *)FindNextStruct(
+ pCreateInfo->pRasterizationState,
+ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT);
+ if(provokeInfo)
+ provokingVertex = provokeInfo->provokingVertexMode;
+
const VkPipelineLibraryCreateInfoKHR *libraryReference =
(const VkPipelineLibraryCreateInfoKHR *)FindNextStruct(
pCreateInfo, VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR);
@@ -1318,6 +1328,8 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan,
negativeOneToOne = pipeInfo.negativeOneToOne;
+ provokingVertex = pipeInfo.provokingVertex;
+
flags |= pipeInfo.flags;
}
diff --git a/renderdoc/driver/vulkan/vk_info.h b/renderdoc/driver/vulkan/vk_info.h
index 803a88180..acc4aa5ba 100644
--- a/renderdoc/driver/vulkan/vk_info.h
+++ b/renderdoc/driver/vulkan/vk_info.h
@@ -478,6 +478,9 @@ struct VulkanCreationInfo
// VkPipelineViewportDepthClipControlCreateInfoEXT
bool negativeOneToOne;
+
+ // VkPipelineRasterizationProvokingVertexStateCreateInfoEXT
+ VkProvokingVertexModeEXT provokingVertex;
};
std::unordered_map m_Pipeline;
diff --git a/renderdoc/driver/vulkan/vk_next_chains.cpp b/renderdoc/driver/vulkan/vk_next_chains.cpp
index 77e061b72..7b26507c1 100644
--- a/renderdoc/driver/vulkan/vk_next_chains.cpp
+++ b/renderdoc/driver/vulkan/vk_next_chains.cpp
@@ -376,6 +376,10 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
VkPhysicalDeviceProtectedMemoryFeatures); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES, \
VkPhysicalDeviceProtectedMemoryProperties); \
+ COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT, \
+ VkPhysicalDeviceProvokingVertexFeaturesEXT); \
+ COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT, \
+ VkPhysicalDeviceProvokingVertexPropertiesEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR, \
VkPhysicalDevicePushDescriptorPropertiesKHR); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT, \
@@ -490,8 +494,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
VkPipelineColorBlendStateCreateInfo); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT, \
VkPipelineColorWriteCreateInfoEXT); \
- COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT, \
- VkPipelineRasterizationDepthClipStateCreateInfoEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, \
VkPipelineDepthStencilStateCreateInfo); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT, \
@@ -511,8 +513,12 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
VkPipelineMultisampleStateCreateInfo); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT, \
VkPipelineRasterizationConservativeStateCreateInfoEXT); \
+ COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT, \
+ VkPipelineRasterizationDepthClipStateCreateInfoEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT, \
VkPipelineRasterizationLineStateCreateInfoEXT) \
+ COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT, \
+ VkPipelineRasterizationProvokingVertexStateCreateInfoEXT) \
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, \
VkPipelineRasterizationStateCreateInfo); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT, \
@@ -941,8 +947,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES_EXT: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_PROPERTIES_EXT: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_BARRIER_FEATURES_NV: \
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT: \
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_FEATURES_NV: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_PROPERTIES_NV: \
@@ -981,7 +985,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
case VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV: \
case VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_ENUM_STATE_CREATE_INFO_NV: \
case VK_STRUCTURE_TYPE_PIPELINE_PROPERTIES_IDENTIFIER_EXT: \
- case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT: \
case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD: \
case VK_STRUCTURE_TYPE_PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV: \
case VK_STRUCTURE_TYPE_PIPELINE_ROBUSTNESS_CREATE_INFO_EXT: \
diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp
index 2a4276c8a..f7b952261 100644
--- a/renderdoc/driver/vulkan/vk_replay.cpp
+++ b/renderdoc/driver/vulkan/vk_replay.cpp
@@ -1448,6 +1448,9 @@ void VulkanReplay::SavePipelineState(uint32_t eventId)
break;
}
+ ret.rasterizer.provokingVertexFirst =
+ p.provokingVertex == VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;
+
ret.rasterizer.depthBiasEnable = state.depthBiasEnable != VK_FALSE;
ret.rasterizer.depthBias = state.bias.depth;
ret.rasterizer.depthBiasClamp = state.bias.biasclamp;
diff --git a/renderdoc/driver/vulkan/vk_serialise.cpp b/renderdoc/driver/vulkan/vk_serialise.cpp
index 5ed9c1e48..1f559232c 100644
--- a/renderdoc/driver/vulkan/vk_serialise.cpp
+++ b/renderdoc/driver/vulkan/vk_serialise.cpp
@@ -800,6 +800,14 @@ SERIALISE_VK_HANDLES();
PNEXT_STRUCT(VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO, VkDevicePrivateDataCreateInfo) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO, VkPrivateDataSlotCreateInfo) \
\
+ /* VK_EXT_provoking_vertex */ \
+ PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT, \
+ VkPhysicalDeviceProvokingVertexFeaturesEXT) \
+ PNEXT_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT, \
+ VkPipelineRasterizationProvokingVertexStateCreateInfoEXT) \
+ PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT, \
+ VkPhysicalDeviceProvokingVertexPropertiesEXT) \
+ \
/* VK_EXT_rasterization_order_attachment_access */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT, \
VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT) \
@@ -1549,11 +1557,6 @@ SERIALISE_VK_HANDLES();
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES_EXT) \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_PROPERTIES_EXT) \
\
- /* VK_EXT_provoking_vertex */ \
- PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT) \
- PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT) \
- PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT) \
- \
/* VK_EXT_shader_module_identifier */ \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT) \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_PROPERTIES_EXT) \
@@ -7470,6 +7473,57 @@ void Deserialise(const VkPrivateDataSlotCreateInfo &el)
DeserialiseNext(el.pNext);
}
+template
+void DoSerialise(SerialiserType &ser, VkPhysicalDeviceProvokingVertexFeaturesEXT &el)
+{
+ RDCASSERT(ser.IsReading() ||
+ el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT);
+ SerialiseNext(ser, el.sType, el.pNext);
+
+ SERIALISE_MEMBER(provokingVertexLast);
+ SERIALISE_MEMBER(transformFeedbackPreservesProvokingVertex);
+}
+
+template <>
+void Deserialise(const VkPhysicalDeviceProvokingVertexFeaturesEXT &el)
+{
+ DeserialiseNext(el.pNext);
+}
+
+template
+void DoSerialise(SerialiserType &ser, VkPipelineRasterizationProvokingVertexStateCreateInfoEXT &el)
+{
+ RDCASSERT(ser.IsReading() ||
+ el.sType ==
+ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT);
+ SerialiseNext(ser, el.sType, el.pNext);
+
+ SERIALISE_MEMBER(provokingVertexMode);
+}
+
+template <>
+void Deserialise(const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT &el)
+{
+ DeserialiseNext(el.pNext);
+}
+
+template
+void DoSerialise(SerialiserType &ser, VkPhysicalDeviceProvokingVertexPropertiesEXT &el)
+{
+ RDCASSERT(ser.IsReading() ||
+ el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT);
+ SerialiseNext(ser, el.sType, el.pNext);
+
+ SERIALISE_MEMBER(provokingVertexModePerPipeline);
+ SERIALISE_MEMBER(transformFeedbackPreservesTriangleFanProvokingVertex);
+}
+
+template <>
+void Deserialise(const VkPhysicalDeviceProvokingVertexPropertiesEXT &el)
+{
+ DeserialiseNext(el.pNext);
+}
+
template
void DoSerialise(SerialiserType &ser,
VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT &el)
@@ -11419,6 +11473,8 @@ INSTANTIATE_SERIALISE_TYPE(VkPhysicalDevicePresentWaitFeaturesKHR);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDevicePrivateDataFeatures);
+INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceProvokingVertexFeaturesEXT);
+INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceProvokingVertexPropertiesEXT);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceProperties2);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceProtectedMemoryFeatures);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceProtectedMemoryProperties);
@@ -11498,6 +11554,7 @@ INSTANTIATE_SERIALISE_TYPE(VkPipelineMultisampleStateCreateInfo);
INSTANTIATE_SERIALISE_TYPE(VkPipelineRasterizationConservativeStateCreateInfoEXT);
INSTANTIATE_SERIALISE_TYPE(VkPipelineRasterizationDepthClipStateCreateInfoEXT);
INSTANTIATE_SERIALISE_TYPE(VkPipelineRasterizationLineStateCreateInfoEXT);
+INSTANTIATE_SERIALISE_TYPE(VkPipelineRasterizationProvokingVertexStateCreateInfoEXT);
INSTANTIATE_SERIALISE_TYPE(VkPipelineRasterizationStateCreateInfo);
INSTANTIATE_SERIALISE_TYPE(VkPipelineRasterizationStateStreamCreateInfoEXT);
INSTANTIATE_SERIALISE_TYPE(VkPipelineRenderingCreateInfo);
diff --git a/renderdoc/driver/vulkan/vk_shader_cache.cpp b/renderdoc/driver/vulkan/vk_shader_cache.cpp
index c1f9eb7e6..9d1c1a11a 100644
--- a/renderdoc/driver/vulkan/vk_shader_cache.cpp
+++ b/renderdoc/driver/vulkan/vk_shader_cache.cpp
@@ -990,6 +990,18 @@ void VulkanShaderCache::MakeGraphicsPipelineInfo(VkGraphicsPipelineCreateInfo &p
ret.pNext = &shadingRate;
}
+ static VkPipelineRasterizationProvokingVertexStateCreateInfoEXT provokeSetup = {
+ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT,
+ };
+
+ if(m_pDriver->GetExtensions(GetRecord(m_Device)).ext_EXT_provoking_vertex)
+ {
+ provokeSetup.provokingVertexMode = pipeInfo.provokingVertex;
+
+ provokeSetup.pNext = rs.pNext;
+ rs.pNext = &provokeSetup;
+ }
+
// never create derivatives
ret.flags &= ~VK_PIPELINE_CREATE_DERIVATIVE_BIT;
diff --git a/renderdoc/driver/vulkan/vk_stringise.cpp b/renderdoc/driver/vulkan/vk_stringise.cpp
index e85457a1c..d45155979 100644
--- a/renderdoc/driver/vulkan/vk_stringise.cpp
+++ b/renderdoc/driver/vulkan/vk_stringise.cpp
@@ -3111,6 +3111,17 @@ rdcstr DoStringise(const VkDeviceMemoryReportEventTypeEXT &el)
END_ENUM_STRINGISE();
}
+template <>
+rdcstr DoStringise(const VkProvokingVertexModeEXT &el)
+{
+ BEGIN_ENUM_STRINGISE(VkProvokingVertexModeEXT);
+ {
+ STRINGISE_ENUM(VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT)
+ STRINGISE_ENUM(VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT)
+ }
+ END_ENUM_STRINGISE();
+}
+
template <>
rdcstr DoStringise(const VkSemaphoreImportFlagBits &el)
{
diff --git a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp
index 185dc37a2..a1b49027f 100644
--- a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp
+++ b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp
@@ -3087,6 +3087,14 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
CHECK_PHYS_EXT_FEATURE(minLod);
}
END_PHYS_EXT_CHECK();
+
+ BEGIN_PHYS_EXT_CHECK(VkPhysicalDeviceProvokingVertexFeaturesEXT,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT);
+ {
+ CHECK_PHYS_EXT_FEATURE(provokingVertexLast);
+ CHECK_PHYS_EXT_FEATURE(transformFeedbackPreservesProvokingVertex);
+ }
+ END_PHYS_EXT_CHECK();
}
if(availFeatures.depthClamp)
diff --git a/renderdoc/replay/renderdoc_serialise.inl b/renderdoc/replay/renderdoc_serialise.inl
index 2deeaf6d8..d6ffc7329 100644
--- a/renderdoc/replay/renderdoc_serialise.inl
+++ b/renderdoc/replay/renderdoc_serialise.inl
@@ -2156,6 +2156,7 @@ void DoSerialise(SerialiserType &ser, VKPipe::Rasterizer &el)
SERIALISE_MEMBER(conservativeRasterization);
SERIALISE_MEMBER(extraPrimitiveOverestimationSize);
+ SERIALISE_MEMBER(provokingVertexFirst);
SERIALISE_MEMBER(depthBiasEnable);
SERIALISE_MEMBER(depthBias);
SERIALISE_MEMBER(depthBiasClamp);