mirror of
https://gitee.com/openharmony/third_party_spirv-tools
synced 2024-11-23 07:20:28 +00:00
spirv-val: Add Vulkan EXT builtins (#4115)
This commit is contained in:
parent
1bd539b9bf
commit
f37547c73a
@ -120,7 +120,7 @@ typedef enum VUIDError_ {
|
|||||||
VUIDErrorMax,
|
VUIDErrorMax,
|
||||||
} VUIDError;
|
} VUIDError;
|
||||||
|
|
||||||
const static uint32_t NumVUIDBuiltins = 29;
|
const static uint32_t NumVUIDBuiltins = 33;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SpvBuiltIn builtIn;
|
SpvBuiltIn builtIn;
|
||||||
@ -158,6 +158,10 @@ std::array<BuiltinVUIDMapping, NumVUIDBuiltins> builtinVUIDInfo = {{
|
|||||||
{SpvBuiltInWorldRayOriginKHR, {4431, 4432, 4433}},
|
{SpvBuiltInWorldRayOriginKHR, {4431, 4432, 4433}},
|
||||||
{SpvBuiltInLaunchIdKHR, {4266, 4267, 4268}},
|
{SpvBuiltInLaunchIdKHR, {4266, 4267, 4268}},
|
||||||
{SpvBuiltInLaunchSizeKHR, {4269, 4270, 4271}},
|
{SpvBuiltInLaunchSizeKHR, {4269, 4270, 4271}},
|
||||||
|
{SpvBuiltInFragInvocationCountEXT, {4217, 4218, 4219}},
|
||||||
|
{SpvBuiltInFragSizeEXT, {4220, 4221, 4222}},
|
||||||
|
{SpvBuiltInFragStencilRefEXT, {4223, 4224, 4225}},
|
||||||
|
{SpvBuiltInFullyCoveredEXT, {4232, 4233, 4234}},
|
||||||
// clang-format off
|
// clang-format off
|
||||||
} };
|
} };
|
||||||
|
|
||||||
@ -314,6 +318,14 @@ class BuiltInsValidator {
|
|||||||
const Instruction& inst);
|
const Instruction& inst);
|
||||||
spv_result_t ValidateDeviceIndexAtDefinition(const Decoration& decoration,
|
spv_result_t ValidateDeviceIndexAtDefinition(const Decoration& decoration,
|
||||||
const Instruction& inst);
|
const Instruction& inst);
|
||||||
|
spv_result_t ValidateFragInvocationCountAtDefinition(const Decoration& decoration,
|
||||||
|
const Instruction& inst);
|
||||||
|
spv_result_t ValidateFragSizeAtDefinition(const Decoration& decoration,
|
||||||
|
const Instruction& inst);
|
||||||
|
spv_result_t ValidateFragStencilRefAtDefinition(const Decoration& decoration,
|
||||||
|
const Instruction& inst);
|
||||||
|
spv_result_t ValidateFullyCoveredAtDefinition(const Decoration& decoration,
|
||||||
|
const Instruction& inst);
|
||||||
// Used for GlobalInvocationId, LocalInvocationId, NumWorkgroups, WorkgroupId.
|
// Used for GlobalInvocationId, LocalInvocationId, NumWorkgroups, WorkgroupId.
|
||||||
spv_result_t ValidateComputeShaderI32Vec3InputAtDefinition(
|
spv_result_t ValidateComputeShaderI32Vec3InputAtDefinition(
|
||||||
const Decoration& decoration, const Instruction& inst);
|
const Decoration& decoration, const Instruction& inst);
|
||||||
@ -472,6 +484,26 @@ class BuiltInsValidator {
|
|||||||
const Instruction& referenced_inst,
|
const Instruction& referenced_inst,
|
||||||
const Instruction& referenced_from_inst);
|
const Instruction& referenced_from_inst);
|
||||||
|
|
||||||
|
spv_result_t ValidateFragInvocationCountAtReference(
|
||||||
|
const Decoration& decoration, const Instruction& built_in_inst,
|
||||||
|
const Instruction& referenced_inst,
|
||||||
|
const Instruction& referenced_from_inst);
|
||||||
|
|
||||||
|
spv_result_t ValidateFragSizeAtReference(
|
||||||
|
const Decoration& decoration, const Instruction& built_in_inst,
|
||||||
|
const Instruction& referenced_inst,
|
||||||
|
const Instruction& referenced_from_inst);
|
||||||
|
|
||||||
|
spv_result_t ValidateFragStencilRefAtReference(
|
||||||
|
const Decoration& decoration, const Instruction& built_in_inst,
|
||||||
|
const Instruction& referenced_inst,
|
||||||
|
const Instruction& referenced_from_inst);
|
||||||
|
|
||||||
|
spv_result_t ValidateFullyCoveredAtReference(
|
||||||
|
const Decoration& decoration, const Instruction& built_in_inst,
|
||||||
|
const Instruction& referenced_inst,
|
||||||
|
const Instruction& referenced_from_inst);
|
||||||
|
|
||||||
// Used for GlobalInvocationId, LocalInvocationId, NumWorkgroups, WorkgroupId.
|
// Used for GlobalInvocationId, LocalInvocationId, NumWorkgroups, WorkgroupId.
|
||||||
spv_result_t ValidateComputeShaderI32Vec3InputAtReference(
|
spv_result_t ValidateComputeShaderI32Vec3InputAtReference(
|
||||||
const Decoration& decoration, const Instruction& built_in_inst,
|
const Decoration& decoration, const Instruction& built_in_inst,
|
||||||
@ -525,6 +557,9 @@ class BuiltInsValidator {
|
|||||||
spv_result_t ValidateBool(
|
spv_result_t ValidateBool(
|
||||||
const Decoration& decoration, const Instruction& inst,
|
const Decoration& decoration, const Instruction& inst,
|
||||||
const std::function<spv_result_t(const std::string& message)>& diag);
|
const std::function<spv_result_t(const std::string& message)>& diag);
|
||||||
|
spv_result_t ValidateI(
|
||||||
|
const Decoration& decoration, const Instruction& inst,
|
||||||
|
const std::function<spv_result_t(const std::string& message)>& diag);
|
||||||
spv_result_t ValidateI32(
|
spv_result_t ValidateI32(
|
||||||
const Decoration& decoration, const Instruction& inst,
|
const Decoration& decoration, const Instruction& inst,
|
||||||
const std::function<spv_result_t(const std::string& message)>& diag);
|
const std::function<spv_result_t(const std::string& message)>& diag);
|
||||||
@ -717,6 +752,22 @@ spv_result_t BuiltInsValidator::ValidateBool(
|
|||||||
return SPV_SUCCESS;
|
return SPV_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spv_result_t BuiltInsValidator::ValidateI(
|
||||||
|
const Decoration& decoration, const Instruction& inst,
|
||||||
|
const std::function<spv_result_t(const std::string& message)>& diag) {
|
||||||
|
uint32_t underlying_type = 0;
|
||||||
|
if (spv_result_t error =
|
||||||
|
GetUnderlyingType(_, decoration, inst, &underlying_type)) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_.IsIntScalarType(underlying_type)) {
|
||||||
|
return diag(GetDefinitionDesc(decoration, inst) + " is not an int scalar.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return SPV_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
spv_result_t BuiltInsValidator::ValidateI32(
|
spv_result_t BuiltInsValidator::ValidateI32(
|
||||||
const Decoration& decoration, const Instruction& inst,
|
const Decoration& decoration, const Instruction& inst,
|
||||||
const std::function<spv_result_t(const std::string& message)>& diag) {
|
const std::function<spv_result_t(const std::string& message)>& diag) {
|
||||||
@ -3296,6 +3347,287 @@ spv_result_t BuiltInsValidator::ValidateDeviceIndexAtReference(
|
|||||||
return SPV_SUCCESS;
|
return SPV_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtDefinition(const Decoration& decoration,
|
||||||
|
const Instruction& inst) {
|
||||||
|
|
||||||
|
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||||
|
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
|
||||||
|
if (spv_result_t error = ValidateI32(
|
||||||
|
decoration, inst,
|
||||||
|
[this, &inst, &builtin](const std::string& message) -> spv_result_t {
|
||||||
|
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType);
|
||||||
|
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||||
|
<< _.VkErrorID(vuid) << "According to the "
|
||||||
|
<< spvLogStringForEnv(_.context()->target_env)
|
||||||
|
<< " spec BuiltIn "
|
||||||
|
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||||
|
builtin)
|
||||||
|
<< " variable needs to be a 32-bit int scalar. "
|
||||||
|
<< message;
|
||||||
|
})) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValidateFragInvocationCountAtReference(decoration, inst, inst, inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtReference(
|
||||||
|
const Decoration& decoration, const Instruction& built_in_inst,
|
||||||
|
const Instruction& referenced_inst,
|
||||||
|
const Instruction& referenced_from_inst) {
|
||||||
|
|
||||||
|
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||||
|
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
|
||||||
|
const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||||
|
if (storage_class != SpvStorageClassMax &&
|
||||||
|
storage_class != SpvStorageClassInput) {
|
||||||
|
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass);
|
||||||
|
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||||
|
<< _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env)
|
||||||
|
<< " spec allows BuiltIn "
|
||||||
|
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
|
||||||
|
<< " 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) {
|
||||||
|
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel);
|
||||||
|
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||||
|
<< _.VkErrorID(vuid)
|
||||||
|
<< spvLogStringForEnv(_.context()->target_env)
|
||||||
|
<< " spec allows BuiltIn "
|
||||||
|
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
|
||||||
|
<< " to be used only with 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::ValidateFragInvocationCountAtReference, this, decoration,
|
||||||
|
built_in_inst, referenced_from_inst, std::placeholders::_1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return SPV_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
spv_result_t BuiltInsValidator::ValidateFragSizeAtDefinition(const Decoration& decoration,
|
||||||
|
const Instruction& inst) {
|
||||||
|
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||||
|
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
|
||||||
|
if (spv_result_t error = ValidateI32Vec(
|
||||||
|
decoration, inst, 2,
|
||||||
|
[this, &inst, &builtin](const std::string& message) -> spv_result_t {
|
||||||
|
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType);
|
||||||
|
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||||
|
<< _.VkErrorID(vuid) << "According to the "
|
||||||
|
<< spvLogStringForEnv(_.context()->target_env)
|
||||||
|
<< " spec BuiltIn "
|
||||||
|
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||||
|
builtin)
|
||||||
|
<< " variable needs to be a 2-component 32-bit int vector. "
|
||||||
|
<< message;
|
||||||
|
})) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValidateFragSizeAtReference(decoration, inst, inst, inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
spv_result_t BuiltInsValidator::ValidateFragSizeAtReference(
|
||||||
|
const Decoration& decoration, const Instruction& built_in_inst,
|
||||||
|
const Instruction& referenced_inst,
|
||||||
|
const Instruction& referenced_from_inst) {
|
||||||
|
|
||||||
|
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||||
|
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
|
||||||
|
const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||||
|
if (storage_class != SpvStorageClassMax &&
|
||||||
|
storage_class != SpvStorageClassInput) {
|
||||||
|
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass);
|
||||||
|
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||||
|
<< _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env)
|
||||||
|
<< " spec allows BuiltIn "
|
||||||
|
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
|
||||||
|
<< " 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) {
|
||||||
|
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel);
|
||||||
|
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||||
|
<< _.VkErrorID(vuid)
|
||||||
|
<< spvLogStringForEnv(_.context()->target_env)
|
||||||
|
<< " spec allows BuiltIn "
|
||||||
|
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
|
||||||
|
<< " to be used only with 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::ValidateFragSizeAtReference, this, decoration,
|
||||||
|
built_in_inst, referenced_from_inst, std::placeholders::_1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return SPV_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
spv_result_t BuiltInsValidator::ValidateFragStencilRefAtDefinition(const Decoration& decoration,
|
||||||
|
const Instruction& inst) {
|
||||||
|
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||||
|
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
|
||||||
|
if (spv_result_t error = ValidateI(
|
||||||
|
decoration, inst,
|
||||||
|
[this, &inst, &builtin](const std::string& message) -> spv_result_t {
|
||||||
|
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType);
|
||||||
|
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||||
|
<< _.VkErrorID(vuid) << "According to the "
|
||||||
|
<< spvLogStringForEnv(_.context()->target_env)
|
||||||
|
<< " spec BuiltIn "
|
||||||
|
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||||
|
builtin)
|
||||||
|
<< " variable needs to be a int scalar. "
|
||||||
|
<< message;
|
||||||
|
})) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValidateFragStencilRefAtReference(decoration, inst, inst, inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
spv_result_t BuiltInsValidator::ValidateFragStencilRefAtReference(
|
||||||
|
const Decoration& decoration, const Instruction& built_in_inst,
|
||||||
|
const Instruction& referenced_inst,
|
||||||
|
const Instruction& referenced_from_inst) {
|
||||||
|
|
||||||
|
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||||
|
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
|
||||||
|
const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||||
|
if (storage_class != SpvStorageClassMax &&
|
||||||
|
storage_class != SpvStorageClassOutput) {
|
||||||
|
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass);
|
||||||
|
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||||
|
<< _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env)
|
||||||
|
<< " spec allows BuiltIn "
|
||||||
|
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
|
||||||
|
<< " 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_) {
|
||||||
|
if (execution_model != SpvExecutionModelFragment) {
|
||||||
|
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel);
|
||||||
|
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||||
|
<< _.VkErrorID(vuid)
|
||||||
|
<< spvLogStringForEnv(_.context()->target_env)
|
||||||
|
<< " spec allows BuiltIn "
|
||||||
|
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
|
||||||
|
<< " to be used only with 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::ValidateFragStencilRefAtReference, this, decoration,
|
||||||
|
built_in_inst, referenced_from_inst, std::placeholders::_1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return SPV_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
spv_result_t BuiltInsValidator::ValidateFullyCoveredAtDefinition(const Decoration& decoration,
|
||||||
|
const Instruction& inst) {
|
||||||
|
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||||
|
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
|
||||||
|
if (spv_result_t error = ValidateBool(
|
||||||
|
decoration, inst,
|
||||||
|
[this, &inst, &builtin](const std::string& message) -> spv_result_t {
|
||||||
|
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType);
|
||||||
|
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||||
|
<< _.VkErrorID(vuid) << "According to the "
|
||||||
|
<< spvLogStringForEnv(_.context()->target_env)
|
||||||
|
<< " spec BuiltIn "
|
||||||
|
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||||
|
builtin)
|
||||||
|
<< " variable needs to be a bool scalar. "
|
||||||
|
<< message;
|
||||||
|
})) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValidateFullyCoveredAtReference(decoration, inst, inst, inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
spv_result_t BuiltInsValidator::ValidateFullyCoveredAtReference(
|
||||||
|
const Decoration& decoration, const Instruction& built_in_inst,
|
||||||
|
const Instruction& referenced_inst,
|
||||||
|
const Instruction& referenced_from_inst) {
|
||||||
|
|
||||||
|
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||||
|
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
|
||||||
|
const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||||
|
if (storage_class != SpvStorageClassMax &&
|
||||||
|
storage_class != SpvStorageClassInput) {
|
||||||
|
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass);
|
||||||
|
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||||
|
<< _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env)
|
||||||
|
<< " spec allows BuiltIn "
|
||||||
|
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
|
||||||
|
<< " 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) {
|
||||||
|
uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel);
|
||||||
|
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||||
|
<< _.VkErrorID(vuid)
|
||||||
|
<< spvLogStringForEnv(_.context()->target_env)
|
||||||
|
<< " spec allows BuiltIn "
|
||||||
|
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
|
||||||
|
<< " to be used only with 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::ValidateFullyCoveredAtReference, this, decoration,
|
||||||
|
built_in_inst, referenced_from_inst, std::placeholders::_1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return SPV_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
spv_result_t BuiltInsValidator::ValidateSMBuiltinsAtDefinition(
|
spv_result_t BuiltInsValidator::ValidateSMBuiltinsAtDefinition(
|
||||||
const Decoration& decoration, const Instruction& inst) {
|
const Decoration& decoration, const Instruction& inst) {
|
||||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||||
@ -3793,6 +4125,20 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
|
|||||||
case SpvBuiltInDeviceIndex: {
|
case SpvBuiltInDeviceIndex: {
|
||||||
return ValidateDeviceIndexAtDefinition(decoration, inst);
|
return ValidateDeviceIndexAtDefinition(decoration, inst);
|
||||||
}
|
}
|
||||||
|
case SpvBuiltInFragInvocationCountEXT: {
|
||||||
|
// alias SpvBuiltInInvocationsPerPixelNV
|
||||||
|
return ValidateFragInvocationCountAtDefinition(decoration, inst);
|
||||||
|
}
|
||||||
|
case SpvBuiltInFragSizeEXT: {
|
||||||
|
// alias SpvBuiltInFragmentSizeNV
|
||||||
|
return ValidateFragSizeAtDefinition(decoration, inst);
|
||||||
|
}
|
||||||
|
case SpvBuiltInFragStencilRefEXT: {
|
||||||
|
return ValidateFragStencilRefAtDefinition(decoration, inst);
|
||||||
|
}
|
||||||
|
case SpvBuiltInFullyCoveredEXT:{
|
||||||
|
return ValidateFullyCoveredAtDefinition(decoration, inst);
|
||||||
|
}
|
||||||
// Ray tracing builtins
|
// Ray tracing builtins
|
||||||
case SpvBuiltInHitKindKHR: // alias SpvBuiltInHitKindNV
|
case SpvBuiltInHitKindKHR: // alias SpvBuiltInHitKindNV
|
||||||
case SpvBuiltInHitTNV: // NOT present in KHR
|
case SpvBuiltInHitTNV: // NOT present in KHR
|
||||||
@ -3828,13 +4174,11 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
|
|||||||
case SpvBuiltInBaryCoordSmoothCentroidAMD:
|
case SpvBuiltInBaryCoordSmoothCentroidAMD:
|
||||||
case SpvBuiltInBaryCoordSmoothSampleAMD:
|
case SpvBuiltInBaryCoordSmoothSampleAMD:
|
||||||
case SpvBuiltInBaryCoordPullModelAMD:
|
case SpvBuiltInBaryCoordPullModelAMD:
|
||||||
case SpvBuiltInFragStencilRefEXT:
|
|
||||||
case SpvBuiltInViewportMaskNV:
|
case SpvBuiltInViewportMaskNV:
|
||||||
case SpvBuiltInSecondaryPositionNV:
|
case SpvBuiltInSecondaryPositionNV:
|
||||||
case SpvBuiltInSecondaryViewportMaskNV:
|
case SpvBuiltInSecondaryViewportMaskNV:
|
||||||
case SpvBuiltInPositionPerViewNV:
|
case SpvBuiltInPositionPerViewNV:
|
||||||
case SpvBuiltInViewportMaskPerViewNV:
|
case SpvBuiltInViewportMaskPerViewNV:
|
||||||
case SpvBuiltInFullyCoveredEXT:
|
|
||||||
case SpvBuiltInMax:
|
case SpvBuiltInMax:
|
||||||
case SpvBuiltInTaskCountNV:
|
case SpvBuiltInTaskCountNV:
|
||||||
case SpvBuiltInPrimitiveCountNV:
|
case SpvBuiltInPrimitiveCountNV:
|
||||||
@ -3846,9 +4190,6 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
|
|||||||
case SpvBuiltInMeshViewIndicesNV:
|
case SpvBuiltInMeshViewIndicesNV:
|
||||||
case SpvBuiltInBaryCoordNV:
|
case SpvBuiltInBaryCoordNV:
|
||||||
case SpvBuiltInBaryCoordNoPerspNV:
|
case SpvBuiltInBaryCoordNoPerspNV:
|
||||||
case SpvBuiltInFragmentSizeNV: // alias SpvBuiltInFragSizeEXT
|
|
||||||
case SpvBuiltInInvocationsPerPixelNV: // alias
|
|
||||||
// SpvBuiltInFragInvocationCountEXT
|
|
||||||
// No validation rules (for the moment).
|
// No validation rules (for the moment).
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1340,12 +1340,36 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
|
|||||||
return VUID_WRAP(VUID-FragDepth-FragDepth-04215);
|
return VUID_WRAP(VUID-FragDepth-FragDepth-04215);
|
||||||
case 4216:
|
case 4216:
|
||||||
return VUID_WRAP(VUID-FragDepth-FragDepth-04216);
|
return VUID_WRAP(VUID-FragDepth-FragDepth-04216);
|
||||||
|
case 4217:
|
||||||
|
return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04217);
|
||||||
|
case 4218:
|
||||||
|
return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04218);
|
||||||
|
case 4219:
|
||||||
|
return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04219);
|
||||||
|
case 4220:
|
||||||
|
return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04220);
|
||||||
|
case 4221:
|
||||||
|
return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04221);
|
||||||
|
case 4222:
|
||||||
|
return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04222);
|
||||||
|
case 4223:
|
||||||
|
return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04223);
|
||||||
|
case 4224:
|
||||||
|
return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04224);
|
||||||
|
case 4225:
|
||||||
|
return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04225);
|
||||||
case 4229:
|
case 4229:
|
||||||
return VUID_WRAP(VUID-FrontFacing-FrontFacing-04229);
|
return VUID_WRAP(VUID-FrontFacing-FrontFacing-04229);
|
||||||
case 4230:
|
case 4230:
|
||||||
return VUID_WRAP(VUID-FrontFacing-FrontFacing-04230);
|
return VUID_WRAP(VUID-FrontFacing-FrontFacing-04230);
|
||||||
case 4231:
|
case 4231:
|
||||||
return VUID_WRAP(VUID-FrontFacing-FrontFacing-04231);
|
return VUID_WRAP(VUID-FrontFacing-FrontFacing-04231);
|
||||||
|
case 4232:
|
||||||
|
return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04232);
|
||||||
|
case 4233:
|
||||||
|
return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04233);
|
||||||
|
case 4234:
|
||||||
|
return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04234);
|
||||||
case 4236:
|
case 4236:
|
||||||
return VUID_WRAP(VUID-GlobalInvocationId-GlobalInvocationId-04236);
|
return VUID_WRAP(VUID-GlobalInvocationId-GlobalInvocationId-04236);
|
||||||
case 4237:
|
case 4237:
|
||||||
|
@ -3941,6 +3941,184 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
Values(TestResult(SPV_ERROR_INVALID_DATA,
|
Values(TestResult(SPV_ERROR_INVALID_DATA,
|
||||||
"According to the Vulkan spec BuiltIn ShadingRateKHR "
|
"According to the Vulkan spec BuiltIn ShadingRateKHR "
|
||||||
"variable needs to be a 32-bit int scalar."))));
|
"variable needs to be a 32-bit int scalar."))));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
FragInvocationCountInputSuccess,
|
||||||
|
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||||
|
Combine(Values("FragInvocationCountEXT"), Values("Fragment"),
|
||||||
|
Values("Input"), Values("%u32"),
|
||||||
|
Values("OpCapability FragmentDensityEXT\n"),
|
||||||
|
Values("OpExtension \"SPV_EXT_fragment_invocation_density\"\n"),
|
||||||
|
Values(nullptr), Values(TestResult())));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
FragInvocationCountInvalidExecutionModel,
|
||||||
|
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||||
|
Combine(
|
||||||
|
Values("FragInvocationCountEXT"), Values("Vertex"), Values("Input"),
|
||||||
|
Values("%u32"), Values("OpCapability FragmentDensityEXT\n"),
|
||||||
|
Values("OpExtension \"SPV_EXT_fragment_invocation_density\"\n"),
|
||||||
|
Values("VUID-FragInvocationCountEXT-FragInvocationCountEXT-04217"),
|
||||||
|
Values(TestResult(SPV_ERROR_INVALID_DATA,
|
||||||
|
"Vulkan spec allows BuiltIn FragInvocationCountEXT "
|
||||||
|
"to be used only with Fragment execution model."))));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
FragInvocationCountInvalidStorageClass,
|
||||||
|
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||||
|
Combine(Values("FragInvocationCountEXT"), Values("Fragment"),
|
||||||
|
Values("Output"), Values("%u32"),
|
||||||
|
Values("OpCapability FragmentDensityEXT\n"),
|
||||||
|
Values("OpExtension \"SPV_EXT_fragment_invocation_density\"\n"),
|
||||||
|
Values("VUID-FragInvocationCountEXT-FragInvocationCountEXT-04218"),
|
||||||
|
Values(TestResult(
|
||||||
|
SPV_ERROR_INVALID_DATA,
|
||||||
|
"Vulkan spec allows BuiltIn FragInvocationCountEXT to be only "
|
||||||
|
"used for variables with Input storage class."))));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
FragInvocationCountInvalidType,
|
||||||
|
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||||
|
Combine(Values("FragInvocationCountEXT"), Values("Fragment"),
|
||||||
|
Values("Input"), Values("%f32"),
|
||||||
|
Values("OpCapability FragmentDensityEXT\n"),
|
||||||
|
Values("OpExtension \"SPV_EXT_fragment_invocation_density\"\n"),
|
||||||
|
Values("VUID-FragInvocationCountEXT-FragInvocationCountEXT-04219"),
|
||||||
|
Values(TestResult(
|
||||||
|
SPV_ERROR_INVALID_DATA,
|
||||||
|
"According to the Vulkan spec BuiltIn FragInvocationCountEXT "
|
||||||
|
"variable needs to be a 32-bit int scalar."))));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
FragSizeInputSuccess,
|
||||||
|
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||||
|
Combine(Values("FragSizeEXT"), Values("Fragment"), Values("Input"),
|
||||||
|
Values("%u32vec2"), Values("OpCapability FragmentDensityEXT\n"),
|
||||||
|
Values("OpExtension \"SPV_EXT_fragment_invocation_density\"\n"),
|
||||||
|
Values(nullptr), Values(TestResult())));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
FragSizeInvalidExecutionModel,
|
||||||
|
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||||
|
Combine(Values("FragSizeEXT"), Values("Vertex"), Values("Input"),
|
||||||
|
Values("%u32vec2"), Values("OpCapability FragmentDensityEXT\n"),
|
||||||
|
Values("OpExtension \"SPV_EXT_fragment_invocation_density\"\n"),
|
||||||
|
Values("VUID-FragSizeEXT-FragSizeEXT-04220"),
|
||||||
|
Values(TestResult(SPV_ERROR_INVALID_DATA,
|
||||||
|
"Vulkan spec allows BuiltIn FragSizeEXT to be "
|
||||||
|
"used only with Fragment execution model."))));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
FragSizeInvalidStorageClass,
|
||||||
|
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||||
|
Combine(
|
||||||
|
Values("FragSizeEXT"), Values("Fragment"), Values("Output"),
|
||||||
|
Values("%u32vec2"), Values("OpCapability FragmentDensityEXT\n"),
|
||||||
|
Values("OpExtension \"SPV_EXT_fragment_invocation_density\"\n"),
|
||||||
|
Values("VUID-FragSizeEXT-FragSizeEXT-04221"),
|
||||||
|
Values(TestResult(SPV_ERROR_INVALID_DATA,
|
||||||
|
"Vulkan spec allows BuiltIn FragSizeEXT to be only "
|
||||||
|
"used for variables with Input storage class."))));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
FragSizeInvalidType,
|
||||||
|
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||||
|
Combine(Values("FragSizeEXT"), Values("Fragment"), Values("Input"),
|
||||||
|
Values("%u32vec3"), Values("OpCapability FragmentDensityEXT\n"),
|
||||||
|
Values("OpExtension \"SPV_EXT_fragment_invocation_density\"\n"),
|
||||||
|
Values("VUID-FragSizeEXT-FragSizeEXT-04222"),
|
||||||
|
Values(TestResult(
|
||||||
|
SPV_ERROR_INVALID_DATA,
|
||||||
|
"According to the Vulkan spec BuiltIn FragSizeEXT variable "
|
||||||
|
"needs to be a 2-component 32-bit int vector."))));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
FragStencilRefOutputSuccess,
|
||||||
|
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||||
|
Combine(Values("FragStencilRefEXT"), Values("Fragment"), Values("Output"),
|
||||||
|
Values("%u32", "%u64"), Values("OpCapability StencilExportEXT\n"),
|
||||||
|
Values("OpExtension \"SPV_EXT_shader_stencil_export\"\n"),
|
||||||
|
Values(nullptr), Values(TestResult())));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
FragStencilRefInvalidExecutionModel,
|
||||||
|
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||||
|
Combine(Values("FragStencilRefEXT"), Values("Vertex"), Values("Output"),
|
||||||
|
Values("%u32", "%u64"), Values("OpCapability StencilExportEXT\n"),
|
||||||
|
Values("OpExtension \"SPV_EXT_shader_stencil_export\"\n"),
|
||||||
|
Values("VUID-FragStencilRefEXT-FragStencilRefEXT-04223"),
|
||||||
|
Values(TestResult(SPV_ERROR_INVALID_DATA,
|
||||||
|
"Vulkan spec allows BuiltIn FragStencilRefEXT to "
|
||||||
|
"be used only with Fragment execution model."))));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
FragStencilRefInvalidStorageClass,
|
||||||
|
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||||
|
Combine(Values("FragStencilRefEXT"), Values("Fragment"), Values("Input"),
|
||||||
|
Values("%u32", "%u64"), Values("OpCapability StencilExportEXT\n"),
|
||||||
|
Values("OpExtension \"SPV_EXT_shader_stencil_export\"\n"),
|
||||||
|
Values("VUID-FragStencilRefEXT-FragStencilRefEXT-04224"),
|
||||||
|
Values(TestResult(
|
||||||
|
SPV_ERROR_INVALID_DATA,
|
||||||
|
"Vulkan spec allows BuiltIn FragStencilRefEXT to be only used "
|
||||||
|
"for variables with Output storage class."))));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
FragStencilRefInvalidType,
|
||||||
|
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||||
|
Combine(Values("FragStencilRefEXT"), Values("Fragment"), Values("Output"),
|
||||||
|
Values("%f32", "%f64", "%u32vec2"),
|
||||||
|
Values("OpCapability StencilExportEXT\n"),
|
||||||
|
Values("OpExtension \"SPV_EXT_shader_stencil_export\"\n"),
|
||||||
|
Values("VUID-FragStencilRefEXT-FragStencilRefEXT-04225"),
|
||||||
|
Values(TestResult(
|
||||||
|
SPV_ERROR_INVALID_DATA,
|
||||||
|
"According to the Vulkan spec BuiltIn FragStencilRefEXT "
|
||||||
|
"variable needs to be a int scalar."))));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
FullyCoveredEXTInputSuccess,
|
||||||
|
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||||
|
Combine(Values("FullyCoveredEXT"), Values("Fragment"), Values("Input"),
|
||||||
|
Values("%bool"), Values("OpCapability FragmentFullyCoveredEXT\n"),
|
||||||
|
Values("OpExtension \"SPV_EXT_fragment_fully_covered\"\n"),
|
||||||
|
Values(nullptr), Values(TestResult())));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
FullyCoveredEXTInvalidExecutionModel,
|
||||||
|
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||||
|
Combine(Values("FullyCoveredEXT"), Values("Vertex"), Values("Input"),
|
||||||
|
Values("%bool"), Values("OpCapability FragmentFullyCoveredEXT\n"),
|
||||||
|
Values("OpExtension \"SPV_EXT_fragment_fully_covered\"\n"),
|
||||||
|
Values("VUID-FullyCoveredEXT-FullyCoveredEXT-04232"),
|
||||||
|
Values(TestResult(SPV_ERROR_INVALID_DATA,
|
||||||
|
"Vulkan spec allows BuiltIn FullyCoveredEXT to "
|
||||||
|
"be used only with Fragment execution model."))));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
FullyCoveredEXTInvalidStorageClass,
|
||||||
|
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||||
|
Combine(Values("FullyCoveredEXT"), Values("Fragment"), Values("Output"),
|
||||||
|
Values("%bool"), Values("OpCapability FragmentFullyCoveredEXT\n"),
|
||||||
|
Values("OpExtension \"SPV_EXT_fragment_fully_covered\"\n"),
|
||||||
|
Values("VUID-FullyCoveredEXT-FullyCoveredEXT-04233"),
|
||||||
|
Values(TestResult(
|
||||||
|
SPV_ERROR_INVALID_DATA,
|
||||||
|
"Vulkan spec allows BuiltIn FullyCoveredEXT to be only used "
|
||||||
|
"for variables with Input storage class."))));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
FullyCoveredEXTInvalidType,
|
||||||
|
ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
|
||||||
|
Combine(Values("FullyCoveredEXT"), Values("Fragment"), Values("Input"),
|
||||||
|
Values("%f32"), Values("OpCapability FragmentFullyCoveredEXT\n"),
|
||||||
|
Values("OpExtension \"SPV_EXT_fragment_fully_covered\"\n"),
|
||||||
|
Values("VUID-FullyCoveredEXT-FullyCoveredEXT-04234"),
|
||||||
|
Values(TestResult(
|
||||||
|
SPV_ERROR_INVALID_DATA,
|
||||||
|
"According to the Vulkan spec BuiltIn FullyCoveredEXT variable "
|
||||||
|
"needs to be a bool scalar."))));
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace val
|
} // namespace val
|
||||||
} // namespace spvtools
|
} // namespace spvtools
|
||||||
|
Loading…
Reference in New Issue
Block a user