Tests for VK_EXT_vertex_input_dynamic_state

This CL expands the existing dEQP-VK.pipeline.extended_dynamic_state.*
tests to also include coverage for the vertex input pipeline state
being dynamic. The new vertex_input tests utilize the same
extended_dynamic_state test framework which verifies all combinations
of setting the dynamic state before and after the static pipeline
state works correctly.

New tests:

dEQP-VK.pipeline.extended_dynamic_state.*.vertex_input

Affects:

dEQP-VK.pipeline.extended_dynamic_state.*

Components: Vulkan

VK-GL-CTS issue: 2610

Change-Id: I669f60ddec743571d9e3eff1120f0112a829ecb7
(cherry picked from commit 92aa842b6fd13ba0fdfea9a0fe07577816815d31)
(cherry picked from commit 416ab7627b21e1938b88045f6d4a79b3c2fe8971)
diff --git a/android/cts/master/vk-master-2021-03-01.txt b/android/cts/master/vk-master-2021-03-01.txt
index c8f3ef5..63bed94 100644
--- a/android/cts/master/vk-master-2021-03-01.txt
+++ b/android/cts/master/vk-master-2021-03-01.txt
@@ -68406,6 +68406,7 @@
 dEQP-VK.pipeline.extended_dynamic_state.cmd_buffer_start.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_0_depthfail
 dEQP-VK.pipeline.extended_dynamic_state.cmd_buffer_start.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_1_pass
 dEQP-VK.pipeline.extended_dynamic_state.cmd_buffer_start.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_1_depthfail
+dEQP-VK.pipeline.extended_dynamic_state.cmd_buffer_start.vertex_input
 dEQP-VK.pipeline.extended_dynamic_state.before_draw.cull_none
 dEQP-VK.pipeline.extended_dynamic_state.before_draw.cull_back
 dEQP-VK.pipeline.extended_dynamic_state.before_draw.cull_front
@@ -69782,6 +69783,7 @@
 dEQP-VK.pipeline.extended_dynamic_state.before_draw.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_0_depthfail
 dEQP-VK.pipeline.extended_dynamic_state.before_draw.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_1_pass
 dEQP-VK.pipeline.extended_dynamic_state.before_draw.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_1_depthfail
+dEQP-VK.pipeline.extended_dynamic_state.before_draw.vertex_input
 dEQP-VK.pipeline.extended_dynamic_state.between_pipelines.cull_none
 dEQP-VK.pipeline.extended_dynamic_state.between_pipelines.cull_back
 dEQP-VK.pipeline.extended_dynamic_state.between_pipelines.cull_front
@@ -71158,6 +71160,7 @@
 dEQP-VK.pipeline.extended_dynamic_state.between_pipelines.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_0_depthfail
 dEQP-VK.pipeline.extended_dynamic_state.between_pipelines.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_1_pass
 dEQP-VK.pipeline.extended_dynamic_state.between_pipelines.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_1_depthfail
+dEQP-VK.pipeline.extended_dynamic_state.between_pipelines.vertex_input
 dEQP-VK.pipeline.extended_dynamic_state.after_pipelines.cull_none
 dEQP-VK.pipeline.extended_dynamic_state.after_pipelines.cull_back
 dEQP-VK.pipeline.extended_dynamic_state.after_pipelines.cull_front
@@ -72534,6 +72537,7 @@
 dEQP-VK.pipeline.extended_dynamic_state.after_pipelines.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_0_depthfail
 dEQP-VK.pipeline.extended_dynamic_state.after_pipelines.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_1_pass
 dEQP-VK.pipeline.extended_dynamic_state.after_pipelines.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_1_depthfail
+dEQP-VK.pipeline.extended_dynamic_state.after_pipelines.vertex_input
 dEQP-VK.pipeline.extended_dynamic_state.before_good_static.cull_none
 dEQP-VK.pipeline.extended_dynamic_state.before_good_static.cull_back
 dEQP-VK.pipeline.extended_dynamic_state.before_good_static.cull_front
@@ -73910,6 +73914,7 @@
 dEQP-VK.pipeline.extended_dynamic_state.before_good_static.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_0_depthfail
 dEQP-VK.pipeline.extended_dynamic_state.before_good_static.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_1_pass
 dEQP-VK.pipeline.extended_dynamic_state.before_good_static.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_1_depthfail
+dEQP-VK.pipeline.extended_dynamic_state.before_good_static.vertex_input
 dEQP-VK.pipeline.extended_dynamic_state.two_draws_dynamic.cull_none
 dEQP-VK.pipeline.extended_dynamic_state.two_draws_dynamic.cull_back
 dEQP-VK.pipeline.extended_dynamic_state.two_draws_dynamic.cull_front
@@ -75286,6 +75291,7 @@
 dEQP-VK.pipeline.extended_dynamic_state.two_draws_dynamic.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_0_depthfail
 dEQP-VK.pipeline.extended_dynamic_state.two_draws_dynamic.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_1_pass
 dEQP-VK.pipeline.extended_dynamic_state.two_draws_dynamic.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_1_depthfail
+dEQP-VK.pipeline.extended_dynamic_state.two_draws_dynamic.vertex_input
 dEQP-VK.pipeline.extended_dynamic_state.two_draws_static.cull_none
 dEQP-VK.pipeline.extended_dynamic_state.two_draws_static.cull_back
 dEQP-VK.pipeline.extended_dynamic_state.two_draws_static.cull_front
@@ -76659,6 +76665,7 @@
 dEQP-VK.pipeline.extended_dynamic_state.two_draws_static.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_0_depthfail
 dEQP-VK.pipeline.extended_dynamic_state.two_draws_static.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_1_pass
 dEQP-VK.pipeline.extended_dynamic_state.two_draws_static.stencil_state_face_both_dual_xt_dec_wrap_clear_0_ref_1_depthfail
+dEQP-VK.pipeline.extended_dynamic_state.two_draws_static.vertex_input
 dEQP-VK.pipeline.creation_cache_control.graphics_pipelines.single_pipeline_no_compile
 dEQP-VK.pipeline.creation_cache_control.graphics_pipelines.batch_pipelines_early_return
 dEQP-VK.pipeline.creation_cache_control.graphics_pipelines.duplicate_single_recreate_explicit_caching
diff --git a/android/cts/master/vk-master.txt b/android/cts/master/vk-master.txt
index 5f85994..d9d0443 100644
--- a/android/cts/master/vk-master.txt
+++ b/android/cts/master/vk-master.txt
Binary files differ
diff --git a/external/vulkancts/framework/vulkan/vkMandatoryFeatures.inl b/external/vulkancts/framework/vulkan/vkMandatoryFeatures.inl
index 0d33f42..63444dc 100644
--- a/external/vulkancts/framework/vulkan/vkMandatoryFeatures.inl
+++ b/external/vulkancts/framework/vulkan/vkMandatoryFeatures.inl
@@ -426,6 +426,16 @@
 		nextPtr  = &physicalDeviceVertexAttributeDivisorFeaturesEXT.pNext;
 	}
 
+	vk::VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT physicalDeviceVertexInputDynamicStateFeaturesEXT;
+	deMemset(&physicalDeviceVertexInputDynamicStateFeaturesEXT, 0, sizeof(physicalDeviceVertexInputDynamicStateFeaturesEXT));
+
+	if ( isExtensionSupported(deviceExtensions, RequiredExtension("VK_EXT_vertex_input_dynamic_state")) )
+	{
+		physicalDeviceVertexInputDynamicStateFeaturesEXT.sType = getStructureType<VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT>();
+		*nextPtr = &physicalDeviceVertexInputDynamicStateFeaturesEXT;
+		nextPtr  = &physicalDeviceVertexInputDynamicStateFeaturesEXT.pNext;
+	}
+
 	vk::VkPhysicalDeviceVulkan11Features physicalDeviceVulkan11Features;
 	deMemset(&physicalDeviceVulkan11Features, 0, sizeof(physicalDeviceVulkan11Features));
 
@@ -1595,6 +1605,15 @@
 		}
 	}
 
+	if ( isExtensionSupported(deviceExtensions, RequiredExtension("VK_EXT_vertex_input_dynamic_state")) )
+	{
+		if ( physicalDeviceVertexInputDynamicStateFeaturesEXT.vertexInputDynamicState == VK_FALSE )
+		{
+			log << tcu::TestLog::Message << "Mandatory feature vertexInputDynamicState not supported" << tcu::TestLog::EndMessage;
+			result = false;
+		}
+	}
+
 	return result;
 }
 
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineExtendedDynamicStateTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineExtendedDynamicStateTests.cpp
index bfab1b2..cb8271e 100644
--- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineExtendedDynamicStateTests.cpp
+++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineExtendedDynamicStateTests.cpp
@@ -103,13 +103,19 @@
 	// For the pipeline.
 
 	// Vertex attributes for VkPipelineVertexInputStateCreateInfo.
-	virtual std::vector<vk::VkVertexInputAttributeDescription>	getAttributeDescriptions()	const = 0;
+	virtual std::vector<vk::VkVertexInputAttributeDescription>	getAttributeDescriptions(deUint32 offset)	const = 0;
 
 	// Size of each vertex.
 	virtual size_t												getVertexDataSize()			const = 0;
 
 	// Array of bytes containing vertex data. .size() should match getVertexDataSize().
 	virtual std::vector<deUint8>								getVertexData()				const = 0;
+
+	// Offset to the coords data.
+	virtual size_t												getCoordsOffset()			const = 0;
+
+	// Offset to the padding data.
+	virtual size_t												getPaddingOffset()			const = 0;
 };
 
 // Vertices in buffers will have 2 components and a padding to properly test the stride.
@@ -140,10 +146,10 @@
 		return statements;
 	}
 
-	virtual std::vector<vk::VkVertexInputAttributeDescription> getAttributeDescriptions() const override
+	virtual std::vector<vk::VkVertexInputAttributeDescription> getAttributeDescriptions(deUint32 offset) const override
 	{
 		std::vector<vk::VkVertexInputAttributeDescription> descriptions;
-		descriptions.push_back(vk::makeVertexInputAttributeDescription(0u, 0u, vk::VK_FORMAT_R32G32_SFLOAT, 0u));
+		descriptions.push_back(vk::makeVertexInputAttributeDescription(0u, 0u, vk::VK_FORMAT_R32G32_SFLOAT, offset));
 		return descriptions;
 	}
 
@@ -161,6 +167,16 @@
 		deMemcpy(&vertexData[sizeof(coords)], &padding, sizeof(padding));
 		return vertexData;
 	}
+
+	virtual size_t getCoordsOffset() const override
+	{
+		return 0;
+	}
+
+	virtual size_t getPaddingOffset() const override
+	{
+		return sizeof coords;
+	}
 };
 
 class VertexWithExtraAttributes : public GeometryVertex
@@ -194,10 +210,10 @@
 		return statements;
 	}
 
-	virtual std::vector<vk::VkVertexInputAttributeDescription> getAttributeDescriptions() const override
+	virtual std::vector<vk::VkVertexInputAttributeDescription> getAttributeDescriptions(deUint32 offset) const override
 	{
 		std::vector<vk::VkVertexInputAttributeDescription> descriptions;
-		descriptions.push_back(vk::makeVertexInputAttributeDescription(0u, 0u, vk::VK_FORMAT_R32G32_SFLOAT, 0u));
+		descriptions.push_back(vk::makeVertexInputAttributeDescription(0u, 0u, vk::VK_FORMAT_R32G32_SFLOAT, offset));
 		descriptions.push_back(vk::makeVertexInputAttributeDescription(1u, 0u, vk::VK_FORMAT_R32G32_SFLOAT, static_cast<deUint32>(sizeof(coords) + sizeof(padding))));
 		return descriptions;
 	}
@@ -217,6 +233,16 @@
 		deMemcpy(&vertexData[sizeof(coords) + sizeof(padding)], &ones, sizeof(ones));
 		return vertexData;
 	}
+
+	virtual size_t getCoordsOffset() const override
+	{
+		return 0;
+	}
+
+	virtual size_t getPaddingOffset() const override
+	{
+		return sizeof coords;
+	}
 };
 
 constexpr auto kCoordsSize = static_cast<vk::VkDeviceSize>(sizeof(tcu::Vec2));
@@ -290,6 +316,7 @@
 using DepthBoundsTestEnableConfig	= BooleanFlagConfig;
 using StencilTestEnableConfig		= BooleanFlagConfig;
 using StencilOpConfig				= StaticAndDynamicPair<StencilOpVec>;	// At least one element.
+using VertexInputConfig				= StaticAndDynamicPair<deUint32>;
 
 const tcu::Vec4	kDefaultTriangleColor	(0.0f, 0.0f, 1.0f, 1.0f);	// Opaque blue.
 const tcu::Vec4	kDefaultClearColor		(0.0f, 0.0f, 0.0f, 1.0f);	// Opaque black.
@@ -443,6 +470,7 @@
 	DepthBoundsTestEnableConfig	depthBoundsTestEnableConfig;
 	StencilTestEnableConfig		stencilTestEnableConfig;
 	StencilOpConfig				stencilOpConfig;
+	VertexInputConfig			vertexInputConfig;
 
 	// Sane defaults.
 	TestConfig (SequenceOrdering ordering, VertexFactory vertexFactory_ = getVertexWithPadding)
@@ -475,6 +503,7 @@
 		, depthBoundsTestEnableConfig	(false)
 		, stencilTestEnableConfig		(false)
 		, stencilOpConfig				(StencilOpVec(1u, kDefaultStencilOpParams))
+		, vertexInputConfig				(static_cast<deUint32>(vertexFactory(tcu::Vec2(0.0f, 0.0f))->getCoordsOffset()))
 		, m_swappedValues				(false)
 	{
 	}
@@ -522,6 +551,7 @@
 		depthBoundsTestEnableConfig.swapValues();
 		stencilTestEnableConfig.swapValues();
 		stencilOpConfig.swapValues();
+		vertexInputConfig.swapValues();
 
 		m_swappedValues = !m_swappedValues;
 	}
@@ -674,8 +704,11 @@
 	const auto&	vki				= context.getInstanceInterface();
 	const auto	physicalDevice	= context.getPhysicalDevice();
 
-	// This is always required.
-	context.requireDeviceFunctionality("VK_EXT_extended_dynamic_state");
+	if (m_testConfig.vertexInputConfig.dynamicValue)
+		context.requireDeviceFunctionality("VK_EXT_vertex_input_dynamic_state");
+	else
+		// This is always required for the rest of the dynamic state tests.
+		context.requireDeviceFunctionality("VK_EXT_extended_dynamic_state");
 
 	// Check the number of viewports needed and the corresponding limits.
 	const auto&	viewportConfig	= m_testConfig.viewportConfig;
@@ -921,6 +954,29 @@
 		for (const auto& params : testConfig.stencilOpConfig.dynamicValue.get())
 			vkd.cmdSetStencilOpEXT(cmdBuffer, params.faceMask, params.failOp, params.passOp, params.depthFailOp, params.compareOp);
 	}
+
+	if (testConfig.vertexInputConfig.dynamicValue)
+	{
+		const vk::VkVertexInputBindingDescription2EXT vertexBinding =
+		{
+			vk::VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT,	//	VkStructureType		sType;
+			nullptr,														//	void*				pNext;
+			0u,																//	deUint32			binding;
+			static_cast<deUint32>(testConfig.strideConfig.staticValue),		//	deUint32			stride;
+			vk::VK_VERTEX_INPUT_RATE_VERTEX,								//	VkVertexInputRate	inputRate;
+			1u,																//	deUint32			divisor;
+		};
+		const vk::VkVertexInputAttributeDescription2EXT vertexAttribute =
+		{
+			vk::VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT,				//	VkStructureType	sType;
+			nullptr,																	//	void*			pNext;
+			0u,																			//	deUint32		location;
+			0u,																			//	deUint32		binding;
+			vk::VK_FORMAT_R32G32_SFLOAT,												//	VkFormat		format;
+			static_cast<deUint32>(testConfig.vertexInputConfig.dynamicValue.get()),		//	deUint32		offset;
+		};
+		vkd.cmdSetVertexInputEXT(cmdBuffer, 1, &vertexBinding, 1, &vertexAttribute);
+	}
 }
 
 // Bind the appropriate vertex buffer with a dynamic stride if the test configuration needs a dynamic stride.
@@ -1306,7 +1362,7 @@
 	// Input state.
 	DE_ASSERT(!vertexRawPtrs.empty());
 	const auto vertexBinding	= vk::makeVertexInputBindingDescription(0u, static_cast<deUint32>(m_testConfig.strideConfig.staticValue), vk::VK_VERTEX_INPUT_RATE_VERTEX);
-	const auto vertexAttributes	= vertexRawPtrs[0]->getAttributeDescriptions();
+	const auto vertexAttributes	= vertexRawPtrs[0]->getAttributeDescriptions(static_cast<deUint32>(m_testConfig.vertexInputConfig.staticValue));
 
 	const vk::VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
 	{
@@ -1473,6 +1529,7 @@
 	if (m_testConfig.depthBoundsTestEnableConfig.dynamicValue)	dynamicStates.push_back(vk::VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT);
 	if (m_testConfig.stencilTestEnableConfig.dynamicValue)		dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT);
 	if (m_testConfig.stencilOpConfig.dynamicValue)				dynamicStates.push_back(vk::VK_DYNAMIC_STATE_STENCIL_OP_EXT);
+	if (m_testConfig.vertexInputConfig.dynamicValue)			dynamicStates.push_back(vk::VK_DYNAMIC_STATE_VERTEX_INPUT_EXT);
 
 	const vk::VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
 	{
@@ -2498,6 +2555,18 @@
 			}
 		}
 
+		// Vertex input.
+		{
+			const auto	dummyVertex		= getVertexWithPadding(tcu::Vec2(0.0f, 0.0f));
+
+			TestConfig config(kOrdering);
+			config.vertexInputConfig.staticValue	= static_cast<deUint32>(dummyVertex->getPaddingOffset());
+			config.vertexInputConfig.dynamicValue	= static_cast<deUint32>(dummyVertex->getCoordsOffset());
+			config.strideConfig.staticValue			= kCoordsSize;
+			config.strideConfig.dynamicValue		= static_cast<vk::VkDeviceSize>(dummyVertex->getVertexDataSize());
+			orderingGroup->addChild(new ExtendedDynamicStateTest(testCtx, "vertex_input", "Dynamically set vertex input", config));
+		}
+
 		extendedDynamicStateGroup->addChild(orderingGroup.release());
 	}
 
diff --git a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrUtil.cpp b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrUtil.cpp
index 61127c8..ab4e049 100644
--- a/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrUtil.cpp
+++ b/external/vulkancts/modules/vulkan/ycbcr/vktYCbCrUtil.cpp
@@ -350,7 +350,7 @@
 					VK_QUEUE_FAMILY_IGNORED,
 					VK_QUEUE_FAMILY_IGNORED,
 					image,
-					{ aspect, 0u, 1u, arrayLayer, 1u }
+					{ (VkImageAspectFlags)aspect, 0u, 1u, arrayLayer, 1u }
 				};
 
 			vkd.cmdPipelineBarrier(*cmdBuffer,
@@ -379,7 +379,7 @@
 					VK_QUEUE_FAMILY_IGNORED,
 					VK_QUEUE_FAMILY_IGNORED,
 					image,
-					{ aspect, 0u, 1u, arrayLayer, 1u }
+					{ (VkImageAspectFlags)aspect, 0u, 1u, arrayLayer, 1u }
 				};
 
 			vkd.cmdPipelineBarrier(*cmdBuffer,
diff --git a/external/vulkancts/mustpass/master/vk-default.txt b/external/vulkancts/mustpass/master/vk-default.txt
index 862a5b2..375af35 100644
--- a/external/vulkancts/mustpass/master/vk-default.txt
+++ b/external/vulkancts/mustpass/master/vk-default.txt
Binary files differ
diff --git a/external/vulkancts/scripts/src/mandatory_features.txt b/external/vulkancts/scripts/src/mandatory_features.txt
index f39139d..68d3ced 100644
--- a/external/vulkancts/scripts/src/mandatory_features.txt
+++ b/external/vulkancts/scripts/src/mandatory_features.txt
@@ -129,3 +129,4 @@
 VkPhysicalDeviceRayTracingPipelineFeaturesKHR				FEATURES ( rayTracingPipeline rayTracingPipelineTraceRaysIndirect)	REQUIREMENTS ( VK_KHR_ray_tracing_pipeline )
 VkPhysicalDeviceRayTracingPipelineFeaturesKHR				FEATURES ( rayTraversalPrimitiveCulling )						REQUIREMENTS ( VK_KHR_ray_tracing_pipeline VK_KHR_ray_query )
 VkPhysicalDeviceRayQueryFeaturesKHR							FEATURES ( rayQuery )											REQUIREMENTS ( VK_KHR_ray_query )
+VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT			FEATURES ( vertexInputDynamicState )							REQUIREMENTS ( VK_EXT_vertex_input_dynamic_state  )