tests: Add test for graphics pipelines with tessellation
diff --git a/layers/vk_validation_error_database.txt b/layers/vk_validation_error_database.txt
index 62ca158..1fac4ff 100644
--- a/layers/vk_validation_error_database.txt
+++ b/layers/vk_validation_error_database.txt
@@ -504,9 +504,9 @@
VALIDATION_ERROR_00531~^~N~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'The stage member of each element of pStages must be unique' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
VALIDATION_ERROR_00532~^~Y~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'The stage member of one element of pStages must be VK_SHADER_STAGE_VERTEX_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
VALIDATION_ERROR_00533~^~Y~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'The stage member of any given element of pStages must not be VK_SHADER_STAGE_COMPUTE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
-VALIDATION_ERROR_00534~^~Y~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a tessellation control shader stage, it must include a tessellation evaluation shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
-VALIDATION_ERROR_00535~^~Y~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a tessellation evaluation shader stage, it must include a tessellation control shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
-VALIDATION_ERROR_00536~^~Y~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a tessellation control shader stage and a tessellation evaluation shader stage, pTessellationState must be a pointer to a valid VkPipelineTessellationStateCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00534~^~Y~^~CreatePipelineTessErrors~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a tessellation control shader stage, it must include a tessellation evaluation shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00535~^~Y~^~CreatePipelineTessErrors~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a tessellation evaluation shader stage, it must include a tessellation control shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00536~^~Y~^~CreatePipelineTessErrors~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a tessellation control shader stage and a tessellation evaluation shader stage, pTessellationState must be a pointer to a valid VkPipelineTessellationStateCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
VALIDATION_ERROR_00537~^~N~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes tessellation shader stages, the shader code of at least one stage must contain an OpExecutionMode instruction that specifies the type of subdivision in the pipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
VALIDATION_ERROR_00538~^~N~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'sType must be VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~implicit, TBD in parameter validation layer.
VALIDATION_ERROR_00539~^~N~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~implicit, TBD in parameter validation layer.
@@ -1371,8 +1371,8 @@
VALIDATION_ERROR_01423~^~Y~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkCmdBindVertexBuffers)~^~implicit
VALIDATION_ERROR_01424~^~N~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'bindingCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkCmdBindVertexBuffers)~^~implicit
VALIDATION_ERROR_01425~^~Y~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'Both of commandBuffer, and the elements of pBuffers must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#vkCmdBindVertexBuffers)~^~implicit
-VALIDATION_ERROR_01426~^~Y~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '21.8. Tessellation Pipeline State' which states 'patchControlPoints must be greater than zero and less than or equal to VkPhysicalDeviceLimits::maxTessellationPatchSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineTessellationStateCreateInfo)~^~
-VALIDATION_ERROR_01427~^~Y~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '21.8. Tessellation Pipeline State' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineTessellationStateCreateInfo)~^~implicit, TBD in parameter validation layer.
+VALIDATION_ERROR_01426~^~Y~^~CreatePipelineTessErrors~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '21.8. Tessellation Pipeline State' which states 'patchControlPoints must be greater than zero and less than or equal to VkPhysicalDeviceLimits::maxTessellationPatchSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineTessellationStateCreateInfo)~^~
+VALIDATION_ERROR_01427~^~Y~^~CreatePipelineTessErrors~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '21.8. Tessellation Pipeline State' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineTessellationStateCreateInfo)~^~implicit, TBD in parameter validation layer.
VALIDATION_ERROR_01428~^~N~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '21.8. Tessellation Pipeline State' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineTessellationStateCreateInfo)~^~implicit, TBD in parameter validation layer.
VALIDATION_ERROR_01429~^~N~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '21.8. Tessellation Pipeline State' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineTessellationStateCreateInfo)~^~implicit, TBD in parameter validation layer.
VALIDATION_ERROR_01430~^~Y~^~PSOViewportScissorCountTests~^~vkCmdSetViewportWScalingNV~^~For more information refer to Vulkan Spec Section '23.7. Controlling the Viewport' which states 'If the multiple viewports feature is not enabled, viewportCount must be 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineViewportStateCreateInfo)~^~
@@ -1958,8 +1958,8 @@
VALIDATION_ERROR_02096~^~N~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes tessellation shader stages, and the shader code of both stages contain an OpExecutionMode instruction that specifies the type of subdivision in the pipeline, they must both specify the same subdivision mode' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
VALIDATION_ERROR_02097~^~N~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes tessellation shader stages, the shader code of at least one stage must contain an OpExecutionMode instruction that specifies the output patch size in the pipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
VALIDATION_ERROR_02098~^~N~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes tessellation shader stages, and the shader code of both contain an OpExecutionMode instruction that specifies the out patch size in the pipeline, they must both specify the same patch size' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
-VALIDATION_ERROR_02099~^~Y~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes tessellation shader stages, the topology member of pInputAssembly must be VK_PRIMITIVE_TOPOLOGY_PATCH_LIST' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
-VALIDATION_ERROR_02100~^~Y~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If the topology member of pInputAssembly is VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, pStages must include tessellation shader stages' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02099~^~Y~^~CreatePipelineTessErrors~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes tessellation shader stages, the topology member of pInputAssembly must be VK_PRIMITIVE_TOPOLOGY_PATCH_LIST' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02100~^~Y~^~CreatePipelineTessErrors~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If the topology member of pInputAssembly is VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, pStages must include tessellation shader stages' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
VALIDATION_ERROR_02101~^~N~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a geometry shader stage, and does not include any tessellation shader stages, its shader code must contain an OpExecutionMode instruction that specifies an input primitive type that is compatible with the primitive topology specified in pInputAssembly' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
VALIDATION_ERROR_02102~^~N~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a geometry shader stage, and also includes tessellation shader stages, its shader code must contain an OpExecutionMode instruction that specifies an input primitive type that is compatible with the primitive topology that is output by the tessellation stages' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
VALIDATION_ERROR_02103~^~N~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a fragment shader stage and a geometry shader stage, and the fragment shader code reads from an input variable that is decorated with PrimitiveID, then the geometry shader code must write to a matching output variable, decorated with PrimitiveID, in all execution paths' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html#VkPipelineCreateFlagBits)~^~
diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp
index 6dc47ee..ac32f99 100644
--- a/tests/layer_validation_tests.cpp
+++ b/tests/layer_validation_tests.cpp
@@ -15517,6 +15517,140 @@
m_errorMonitor->VerifyFound();
}
+TEST_F(VkLayerTest, CreatePipelineTessErrors) {
+ TEST_DESCRIPTION("Test various errors when creating a graphics pipeline with tessellation stages active.");
+
+ ASSERT_NO_FATAL_FAILURE(Init());
+ ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+ if (!m_device->phy().features().tessellationShader) {
+ printf(" Device does not support tessellation shaders; skipped.\n");
+ return;
+ }
+
+ char const *vsSource =
+ "#version 450\n"
+ "void main(){}\n";
+ char const *tcsSource =
+ "#version 450\n"
+ "layout(vertices=3) out;\n"
+ "void main(){\n"
+ " gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
+ " gl_TessLevelInner[0] = 1;\n"
+ "}\n";
+ char const *tesSource =
+ "#version 450\n"
+ "layout(triangles, equal_spacing, cw) in;\n"
+ "out gl_PerVertex { vec4 gl_Position; };\n"
+ "void main(){\n"
+ " gl_Position.xyz = gl_TessCoord;\n"
+ " gl_Position.w = 0;\n"
+ "}\n";
+ char const *fsSource =
+ "#version 450\n"
+ "layout(location=0) out vec4 color;\n"
+ "void main(){\n"
+ " color = vec4(1);\n"
+ "}\n";
+
+ VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+ VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
+ VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
+ VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+ VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
+ VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
+
+ VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
+
+ VkDescriptorSetObj descriptorSet(m_device);
+ descriptorSet.AppendDummy();
+ descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
+
+ {
+ VkPipelineObj pipe(m_device);
+ VkPipelineInputAssemblyStateCreateInfo iasci_bad = iasci;
+ iasci_bad.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; // otherwise we get a failure about invalid topology
+ pipe.SetInputAssembly(&iasci_bad);
+ pipe.AddColorAttachment();
+ pipe.AddShader(&vs);
+ pipe.AddShader(&fs);
+
+ // Pass a tess control shader without a tess eval shader
+ pipe.AddShader(&tcs);
+ m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_00534);
+ pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+ m_errorMonitor->VerifyFound();
+ }
+
+ {
+ VkPipelineObj pipe(m_device);
+ VkPipelineInputAssemblyStateCreateInfo iasci_bad = iasci;
+ iasci_bad.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; // otherwise we get a failure about invalid topology
+ pipe.SetInputAssembly(&iasci_bad);
+ pipe.AddColorAttachment();
+ pipe.AddShader(&vs);
+ pipe.AddShader(&fs);
+
+ // Pass a tess eval shader without a tess control shader
+ pipe.AddShader(&tes);
+ m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_00535);
+ pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+ m_errorMonitor->VerifyFound();
+ }
+
+ {
+ VkPipelineObj pipe(m_device);
+ pipe.SetInputAssembly(&iasci);
+ pipe.AddColorAttachment();
+ pipe.AddShader(&vs);
+ pipe.AddShader(&fs);
+
+ // Pass patch topology without tessellation shaders
+ m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_02100);
+ pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+ m_errorMonitor->VerifyFound();
+
+ pipe.AddShader(&tcs);
+ pipe.AddShader(&tes);
+ // Pass a NULL pTessellationState (with active tessellation shader stages)
+ m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_00536);
+ pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+ m_errorMonitor->VerifyFound();
+
+ // Pass an invalid pTessellationState (bad sType)
+ VkPipelineTessellationStateCreateInfo tsci_bad = tsci;
+ tsci_bad.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ pipe.SetTessellation(&tsci_bad);
+ m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01427);
+ pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+ m_errorMonitor->VerifyFound();
+ // Pass out-of-range patchControlPoints
+ tsci_bad = tsci;
+ tsci_bad.patchControlPoints = 0;
+ pipe.SetTessellation(&tsci);
+ pipe.SetTessellation(&tsci_bad);
+ m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01426);
+ pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+ m_errorMonitor->VerifyFound();
+ tsci_bad.patchControlPoints = m_device->props.limits.maxTessellationPatchSize + 1;
+ pipe.SetTessellation(&tsci_bad);
+ m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01426);
+ pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+ m_errorMonitor->VerifyFound();
+ pipe.SetTessellation(&tsci);
+
+ // Pass an invalid primitive topology
+ VkPipelineInputAssemblyStateCreateInfo iasci_bad = iasci;
+ iasci_bad.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+ pipe.SetInputAssembly(&iasci_bad);
+ m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_02099);
+ pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+ m_errorMonitor->VerifyFound();
+ pipe.SetInputAssembly(&iasci);
+ }
+}
+
TEST_F(VkLayerTest, CreatePipelineAttribBindingConflict) {
TEST_DESCRIPTION(
"Test that an error is produced for a vertex attribute setup where multiple "