Allow ViewportIndex & Layer to be used in VS/DS with extension

SPV_EXT_shader_viewport_index_layer enables using ViewportIndex
and Layer in vertex and tessellation shaders.

Also, as per the Vulkan spec:

> The ViewportIndex decoration must be used only within vertex,
> tessellation evaluation, geometry, and fragment shaders.

> In a vertex, tessellation evaluation, or geometry shader, any
> variable decorated with ViewportIndex must be declared using
> the Output storage class.

> In a fragment shader, any variable decorated with ViewportIndex
> must be declared using the Input storage class.

Similarly for Layer.
This commit is contained in:
Lei Zhang 2018-05-16 13:16:27 -04:00 committed by GitHub
parent 9b1a938ea1
commit b09e3ce842
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 23 deletions

View File

@ -2141,15 +2141,20 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference(
if (storage_class == SpvStorageClassInput) { if (storage_class == SpvStorageClassInput) {
assert(function_id_ == 0); assert(function_id_ == 0);
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( for (const auto em :
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, {SpvExecutionModelVertex, SpvExecutionModelTessellationEvaluation,
"Vulkan spec doesn't allow BuiltIn Layer and " SpvExecutionModelGeometry}) {
"ViewportIndex to be " id_to_at_reference_checks_[referenced_from_inst.id()].push_back(
"used for variables with Input storage class if " std::bind(&BuiltInsValidator::ValidateNotCalledWithExecutionModel,
"execution model is " this,
"Geometry.", "Vulkan spec doesn't allow BuiltIn Layer and "
SpvExecutionModelGeometry, decoration, built_in_inst, "ViewportIndex to be "
referenced_from_inst, std::placeholders::_1)); "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) { if (storage_class == SpvStorageClassOutput) {
@ -2171,15 +2176,25 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference(
case SpvExecutionModelFragment: { case SpvExecutionModelFragment: {
// Ok. // Ok.
break; 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: { default: {
return _.diag(SPV_ERROR_INVALID_DATA) return _.diag(SPV_ERROR_INVALID_DATA)
<< "Vulkan spec allows BuiltIn " << "Vulkan spec allows BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
decoration.params()[0]) decoration.params()[0])
<< " to be used only with Fragment or Geometry execution " << " to be used only with Vertex, TessellationEvaluation, "
"models. " "Geometry, or Fragment execution models. "
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst, << GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst, execution_model); referenced_from_inst, execution_model);
} }

View File

@ -744,14 +744,23 @@ INSTANTIATE_TEST_CASE_P(
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
LayerAndViewportIndexInvalidExecutionModel, LayerAndViewportIndexInvalidExecutionModel,
ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
Combine( Combine(Values("Layer", "ViewportIndex"),
Values("Layer", "ViewportIndex"), Values("TessellationControl", "GLCompute"), Values("Input"),
Values("Vertex", "GLCompute", "TessellationControl", Values("%u32"),
"TessellationEvaluation"), Values(TestResult(
Values("Input"), Values("%u32"), SPV_ERROR_INVALID_DATA,
Values(TestResult( "to be used only with Vertex, TessellationEvaluation, "
SPV_ERROR_INVALID_DATA, "Geometry, or Fragment execution models"))), );
"to be used only with Fragment or Geometry 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( INSTANTIATE_TEST_CASE_P(
LayerAndViewportIndexFragmentNotInput, LayerAndViewportIndexFragmentNotInput,
@ -767,11 +776,13 @@ INSTANTIATE_TEST_CASE_P(
LayerAndViewportIndexGeometryNotOutput, LayerAndViewportIndexGeometryNotOutput,
ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
Combine( Combine(
Values("Layer", "ViewportIndex"), Values("Geometry"), Values("Input"), Values("Layer", "ViewportIndex"),
Values("Vertex", "TessellationEvaluation", "Geometry"), Values("Input"),
Values("%u32"), Values("%u32"),
Values(TestResult(SPV_ERROR_INVALID_DATA, Values(TestResult(SPV_ERROR_INVALID_DATA,
"Input storage class if execution model is Geometry", "Input storage class if execution model is Vertex, "
"which is called with execution model Geometry"))), ); "TessellationEvaluation, or Geometry",
"which is called with execution model"))), );
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
LayerAndViewportIndexNotIntScalar, LayerAndViewportIndexNotIntScalar,