mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-12-24 00:40:14 +00:00
Support SPV_KHR_fragment_shading_rate (#3943)
This commit is contained in:
parent
6fac705e76
commit
a1d38174b1
@ -176,12 +176,13 @@ typedef enum spv_operand_type_t {
|
||||
|
||||
// Set 5: Operands that are a single word bitmask.
|
||||
// Sometimes a set bit indicates the instruction requires still more operands.
|
||||
SPV_OPERAND_TYPE_IMAGE, // SPIR-V Sec 3.14
|
||||
SPV_OPERAND_TYPE_FP_FAST_MATH_MODE, // SPIR-V Sec 3.15
|
||||
SPV_OPERAND_TYPE_SELECTION_CONTROL, // SPIR-V Sec 3.22
|
||||
SPV_OPERAND_TYPE_LOOP_CONTROL, // SPIR-V Sec 3.23
|
||||
SPV_OPERAND_TYPE_FUNCTION_CONTROL, // SPIR-V Sec 3.24
|
||||
SPV_OPERAND_TYPE_MEMORY_ACCESS, // SPIR-V Sec 3.26
|
||||
SPV_OPERAND_TYPE_IMAGE, // SPIR-V Sec 3.14
|
||||
SPV_OPERAND_TYPE_FP_FAST_MATH_MODE, // SPIR-V Sec 3.15
|
||||
SPV_OPERAND_TYPE_SELECTION_CONTROL, // SPIR-V Sec 3.22
|
||||
SPV_OPERAND_TYPE_LOOP_CONTROL, // SPIR-V Sec 3.23
|
||||
SPV_OPERAND_TYPE_FUNCTION_CONTROL, // SPIR-V Sec 3.24
|
||||
SPV_OPERAND_TYPE_MEMORY_ACCESS, // SPIR-V Sec 3.26
|
||||
SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE, // SPIR-V Sec 3.FSR
|
||||
|
||||
// The remaining operand types are only used internally by the assembler.
|
||||
// There are two categories:
|
||||
|
@ -208,6 +208,8 @@ const char* spvOperandTypeStr(spv_operand_type_t type) {
|
||||
case SPV_OPERAND_TYPE_MEMORY_ACCESS:
|
||||
case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
|
||||
return "memory access";
|
||||
case SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE:
|
||||
return "shading rate";
|
||||
case SPV_OPERAND_TYPE_SCOPE_ID:
|
||||
return "scope ID";
|
||||
case SPV_OPERAND_TYPE_GROUP_OPERATION:
|
||||
@ -360,6 +362,7 @@ bool spvOperandIsConcreteMask(spv_operand_type_t type) {
|
||||
case SPV_OPERAND_TYPE_LOOP_CONTROL:
|
||||
case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
|
||||
case SPV_OPERAND_TYPE_MEMORY_ACCESS:
|
||||
case SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE:
|
||||
case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
|
||||
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
|
||||
return true;
|
||||
|
@ -1,4 +1,6 @@
|
||||
// Copyright (c) 2018 Google LLC.
|
||||
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights
|
||||
// reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -230,6 +232,12 @@ class BuiltInsValidator {
|
||||
spv_result_t ValidateComputeI32InputAtDefinition(const Decoration& decoration,
|
||||
const Instruction& inst);
|
||||
|
||||
spv_result_t ValidatePrimitiveShadingRateAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst);
|
||||
|
||||
spv_result_t ValidateShadingRateAtDefinition(const Decoration& decoration,
|
||||
const Instruction& inst);
|
||||
|
||||
// The following section contains functions which are called when id defined
|
||||
// by |referenced_inst| is
|
||||
// 1. referenced by |referenced_from_inst|
|
||||
@ -383,6 +391,16 @@ class BuiltInsValidator {
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst);
|
||||
|
||||
spv_result_t ValidatePrimitiveShadingRateAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst);
|
||||
|
||||
spv_result_t ValidateShadingRateAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst);
|
||||
|
||||
// Validates that |built_in_inst| is not (even indirectly) referenced from
|
||||
// within a function which can be called with |execution_model|.
|
||||
//
|
||||
@ -3314,6 +3332,142 @@ spv_result_t BuiltInsValidator::ValidateSMBuiltinsAtReference(
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidatePrimitiveShadingRateAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
if (spv_result_t error = ValidateI32(
|
||||
decoration, inst,
|
||||
[this, &inst,
|
||||
&decoration](const std::string& message) -> spv_result_t {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< _.VkErrorID(4486)
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " variable needs to be a 32-bit int scalar. "
|
||||
<< message;
|
||||
})) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
// Seed at reference checks with this built-in.
|
||||
return ValidatePrimitiveShadingRateAtReference(decoration, inst, inst, inst);
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidatePrimitiveShadingRateAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != SpvStorageClassMax &&
|
||||
storage_class != SpvStorageClassOutput) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< _.VkErrorID(4485) << "Vulkan spec allows BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " to be only used for variables with Output storage class. "
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
referenced_from_inst)
|
||||
<< " " << GetStorageClassDesc(referenced_from_inst);
|
||||
}
|
||||
|
||||
for (const SpvExecutionModel execution_model : execution_models_) {
|
||||
switch (execution_model) {
|
||||
case SpvExecutionModelVertex:
|
||||
case SpvExecutionModelGeometry:
|
||||
case SpvExecutionModelMeshNV:
|
||||
break;
|
||||
default: {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< _.VkErrorID(4484) << "Vulkan spec allows BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " to be used only with Vertex, Geometry, or MeshNV "
|
||||
"execution models. "
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
referenced_from_inst, execution_model);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (function_id_ == 0) {
|
||||
// Propagate this rule to all dependant ids in the global scope.
|
||||
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(
|
||||
std::bind(&BuiltInsValidator::ValidatePrimitiveShadingRateAtReference,
|
||||
this, decoration, built_in_inst, referenced_from_inst,
|
||||
std::placeholders::_1));
|
||||
}
|
||||
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidateShadingRateAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
if (spv_result_t error = ValidateI32(
|
||||
decoration, inst,
|
||||
[this, &inst,
|
||||
&decoration](const std::string& message) -> spv_result_t {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< _.VkErrorID(4492)
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " variable needs to be a 32-bit int scalar. "
|
||||
<< message;
|
||||
})) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
// Seed at reference checks with this built-in.
|
||||
return ValidateShadingRateAtReference(decoration, inst, inst, inst);
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidateShadingRateAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != SpvStorageClassMax &&
|
||||
storage_class != SpvStorageClassInput) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< _.VkErrorID(4491) << "Vulkan spec allows BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " to be only used for variables with Input storage class. "
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
referenced_from_inst)
|
||||
<< " " << GetStorageClassDesc(referenced_from_inst);
|
||||
}
|
||||
|
||||
for (const SpvExecutionModel execution_model : execution_models_) {
|
||||
if (execution_model != SpvExecutionModelFragment) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< _.VkErrorID(4490) << "Vulkan spec allows BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " to be used only with the Fragment execution model. "
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
referenced_from_inst, execution_model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (function_id_ == 0) {
|
||||
// Propagate this rule to all dependant ids in the global scope.
|
||||
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
|
||||
&BuiltInsValidator::ValidateShadingRateAtReference, this, decoration,
|
||||
built_in_inst, referenced_from_inst, std::placeholders::_1));
|
||||
}
|
||||
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
const SpvBuiltIn label = SpvBuiltIn(decoration.params()[0]);
|
||||
@ -3514,6 +3668,11 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
|
||||
case SpvBuiltInRayGeometryIndexKHR: {
|
||||
// No validation rules (for the moment).
|
||||
break;
|
||||
|
||||
case SpvBuiltInPrimitiveShadingRateKHR:
|
||||
return ValidatePrimitiveShadingRateAtDefinition(decoration, inst);
|
||||
case SpvBuiltInShadingRateKHR:
|
||||
return ValidateShadingRateAtDefinition(decoration, inst);
|
||||
}
|
||||
}
|
||||
return SPV_SUCCESS;
|
||||
|
@ -1,4 +1,6 @@
|
||||
// Copyright (c) 2018 Google LLC.
|
||||
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights
|
||||
// reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -3723,6 +3725,108 @@ OpDecorate %int0 BuiltIn Position
|
||||
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
PrimitiveShadingRateOutputSuccess,
|
||||
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||
Combine(Values("PrimitiveShadingRateKHR"), Values("Vertex", "Geometry"),
|
||||
Values("Output"), Values("%u32"),
|
||||
Values("OpCapability FragmentShadingRateKHR\n"),
|
||||
Values("OpExtension \"SPV_KHR_fragment_shading_rate\"\n"),
|
||||
Values(nullptr), Values(TestResult())));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
PrimitiveShadingRateMeshOutputSuccess,
|
||||
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||
Combine(Values("PrimitiveShadingRateKHR"), Values("MeshNV"),
|
||||
Values("Output"), Values("%u32"),
|
||||
Values("OpCapability FragmentShadingRateKHR\nOpCapability "
|
||||
"MeshShadingNV\n"),
|
||||
Values("OpExtension \"SPV_KHR_fragment_shading_rate\"\nOpExtension "
|
||||
"\"SPV_NV_mesh_shader\"\n"),
|
||||
Values(nullptr), Values(TestResult())));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
PrimitiveShadingRateInvalidExecutionModel,
|
||||
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||
Combine(
|
||||
Values("PrimitiveShadingRateKHR"), Values("Fragment"), Values("Output"),
|
||||
Values("%u32"), Values("OpCapability FragmentShadingRateKHR\n"),
|
||||
Values("OpExtension \"SPV_KHR_fragment_shading_rate\"\n"),
|
||||
Values("VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04484 "),
|
||||
Values(TestResult(
|
||||
SPV_ERROR_INVALID_DATA,
|
||||
"Vulkan spec allows BuiltIn PrimitiveShadingRateKHR to be used "
|
||||
"only with Vertex, Geometry, or MeshNV execution models."))));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
PrimitiveShadingRateInvalidStorageClass,
|
||||
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||
Combine(
|
||||
Values("PrimitiveShadingRateKHR"), Values("Vertex"), Values("Input"),
|
||||
Values("%u32"), Values("OpCapability FragmentShadingRateKHR\n"),
|
||||
Values("OpExtension \"SPV_KHR_fragment_shading_rate\"\n"),
|
||||
Values("VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04485 "),
|
||||
Values(TestResult(
|
||||
SPV_ERROR_INVALID_DATA,
|
||||
"Vulkan spec allows BuiltIn PrimitiveShadingRateKHR to be only "
|
||||
"used for variables with Output storage class."))));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
PrimitiveShadingRateInvalidType,
|
||||
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||
Combine(
|
||||
Values("PrimitiveShadingRateKHR"), Values("Vertex"), Values("Output"),
|
||||
Values("%f32"), Values("OpCapability FragmentShadingRateKHR\n"),
|
||||
Values("OpExtension \"SPV_KHR_fragment_shading_rate\"\n"),
|
||||
Values("VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04485 "),
|
||||
Values(TestResult(
|
||||
SPV_ERROR_INVALID_DATA,
|
||||
"According to the Vulkan spec BuiltIn PrimitiveShadingRateKHR "
|
||||
"variable needs to be a 32-bit int scalar."))));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
ShadingRateInputSuccess,
|
||||
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||
Combine(Values("ShadingRateKHR"), Values("Fragment"), Values("Input"),
|
||||
Values("%u32"), Values("OpCapability FragmentShadingRateKHR\n"),
|
||||
Values("OpExtension \"SPV_KHR_fragment_shading_rate\"\n"),
|
||||
Values(nullptr), Values(TestResult())));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
ShadingRateInvalidExecutionModel,
|
||||
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||
Combine(Values("ShadingRateKHR"), Values("Vertex"), Values("Input"),
|
||||
Values("%u32"), Values("OpCapability FragmentShadingRateKHR\n"),
|
||||
Values("OpExtension \"SPV_KHR_fragment_shading_rate\"\n"),
|
||||
Values("VUID-ShadingRateKHR-ShadingRateKHR-04490 "),
|
||||
Values(TestResult(
|
||||
SPV_ERROR_INVALID_DATA,
|
||||
"Vulkan spec allows BuiltIn ShadingRateKHR to be used "
|
||||
"only with the Fragment execution model."))));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
ShadingRateInvalidStorageClass,
|
||||
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||
Combine(Values("ShadingRateKHR"), Values("Fragment"), Values("Output"),
|
||||
Values("%u32"), Values("OpCapability FragmentShadingRateKHR\n"),
|
||||
Values("OpExtension \"SPV_KHR_fragment_shading_rate\"\n"),
|
||||
Values("VUID-ShadingRateKHR-ShadingRateKHR-04491 "),
|
||||
Values(TestResult(
|
||||
SPV_ERROR_INVALID_DATA,
|
||||
"Vulkan spec allows BuiltIn ShadingRateKHR to be only "
|
||||
"used for variables with Input storage class."))));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
ShadingRateInvalidType,
|
||||
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||
Combine(
|
||||
Values("ShadingRateKHR"), Values("Fragment"), Values("Input"),
|
||||
Values("%f32"), Values("OpCapability FragmentShadingRateKHR\n"),
|
||||
Values("OpExtension \"SPV_KHR_fragment_shading_rate\"\n"),
|
||||
Values("VUID-ShadingRateKHR-ShadingRateKHR-04492 "),
|
||||
Values(TestResult(SPV_ERROR_INVALID_DATA,
|
||||
"According to the Vulkan spec BuiltIn ShadingRateKHR "
|
||||
"variable needs to be a 32-bit int scalar."))));
|
||||
} // namespace
|
||||
} // namespace val
|
||||
} // namespace spvtools
|
||||
|
Loading…
Reference in New Issue
Block a user