diff --git a/source/validate_builtins.cpp b/source/validate_builtins.cpp index f1d19ec7a..1f6da0dc9 100644 --- a/source/validate_builtins.cpp +++ b/source/validate_builtins.cpp @@ -2141,15 +2141,20 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference( if (storage_class == SpvStorageClassInput) { assert(function_id_ == 0); - id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( - &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, - "Vulkan spec doesn't allow BuiltIn Layer and " - "ViewportIndex to be " - "used for variables with Input storage class if " - "execution model is " - "Geometry.", - SpvExecutionModelGeometry, decoration, built_in_inst, - referenced_from_inst, std::placeholders::_1)); + for (const auto em : + {SpvExecutionModelVertex, SpvExecutionModelTessellationEvaluation, + SpvExecutionModelGeometry}) { + id_to_at_reference_checks_[referenced_from_inst.id()].push_back( + std::bind(&BuiltInsValidator::ValidateNotCalledWithExecutionModel, + this, + "Vulkan spec doesn't allow BuiltIn Layer and " + "ViewportIndex to be " + "used for variables with Input storage class if " + "execution model is Vertex, TessellationEvaluation, or " + "Geometry.", + em, decoration, built_in_inst, referenced_from_inst, + std::placeholders::_1)); + } } if (storage_class == SpvStorageClassOutput) { @@ -2171,15 +2176,25 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference( case SpvExecutionModelFragment: { // Ok. break; + case SpvExecutionModelVertex: + case SpvExecutionModelTessellationEvaluation: + if (!_.HasCapability(SpvCapabilityShaderViewportIndexLayerEXT)) { + return _.diag(SPV_ERROR_INVALID_DATA) + << "Using BuiltIn " + << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, + decoration.params()[0]) + << " in Vertex or Tessellation execution model requires " + "the ShaderViewportIndexLayerEXT capability."; + } + break; } - default: { return _.diag(SPV_ERROR_INVALID_DATA) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0]) - << " to be used only with Fragment or Geometry execution " - "models. " + << " to be used only with Vertex, TessellationEvaluation, " + "Geometry, or Fragment execution models. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); } diff --git a/test/val/val_builtins_test.cpp b/test/val/val_builtins_test.cpp index c2e1041fe..18df5ef17 100644 --- a/test/val/val_builtins_test.cpp +++ b/test/val/val_builtins_test.cpp @@ -744,14 +744,23 @@ INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P( LayerAndViewportIndexInvalidExecutionModel, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, - Combine( - Values("Layer", "ViewportIndex"), - Values("Vertex", "GLCompute", "TessellationControl", - "TessellationEvaluation"), - Values("Input"), Values("%u32"), - Values(TestResult( - SPV_ERROR_INVALID_DATA, - "to be used only with Fragment or Geometry execution models"))), ); + Combine(Values("Layer", "ViewportIndex"), + Values("TessellationControl", "GLCompute"), Values("Input"), + Values("%u32"), + Values(TestResult( + SPV_ERROR_INVALID_DATA, + "to be used only with Vertex, TessellationEvaluation, " + "Geometry, or Fragment execution models"))), ); + +INSTANTIATE_TEST_CASE_P( + LayerAndViewportIndexExecutionModelEnabledByCapability, + ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, + Combine(Values("Layer", "ViewportIndex"), + Values("Vertex", "TessellationEvaluation"), Values("Output"), + Values("%u32"), + Values(TestResult( + SPV_ERROR_INVALID_DATA, + "requires the ShaderViewportIndexLayerEXT capability"))), ); INSTANTIATE_TEST_CASE_P( LayerAndViewportIndexFragmentNotInput, @@ -767,11 +776,13 @@ INSTANTIATE_TEST_CASE_P( LayerAndViewportIndexGeometryNotOutput, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, Combine( - Values("Layer", "ViewportIndex"), Values("Geometry"), Values("Input"), + Values("Layer", "ViewportIndex"), + Values("Vertex", "TessellationEvaluation", "Geometry"), Values("Input"), Values("%u32"), Values(TestResult(SPV_ERROR_INVALID_DATA, - "Input storage class if execution model is Geometry", - "which is called with execution model Geometry"))), ); + "Input storage class if execution model is Vertex, " + "TessellationEvaluation, or Geometry", + "which is called with execution model"))), ); INSTANTIATE_TEST_CASE_P( LayerAndViewportIndexNotIntScalar,