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) {
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);
}

View File

@ -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,