Updated spirv-tools.

This commit is contained in:
Бранимир Караџић 2022-03-19 09:06:28 -07:00
parent bb86501886
commit 3cc0de3335
2 changed files with 105 additions and 115 deletions

View File

@ -1 +1 @@
"v2022.2-dev", "SPIRV-Tools v2022.2-dev 6bc813fb765b20ce28c8e6e8c5e6592e227dbf8c" "v2022.2-dev", "SPIRV-Tools v2022.2-dev 6a1809baa2ff1cb740db73cf23ad9df390a40ea3"

View File

@ -640,65 +640,64 @@ spv_result_t ValidateImageOperands(ValidationState_t& _,
return SPV_SUCCESS; return SPV_SUCCESS;
} }
// Checks some of the validation rules which are common to multiple opcodes. // Validate OpImage*Proj* instructions
spv_result_t ValidateImageCommon(ValidationState_t& _, const Instruction* inst, spv_result_t ValidateImageProj(ValidationState_t& _, const Instruction* inst,
const ImageTypeInfo& info) { const ImageTypeInfo& info) {
const SpvOp opcode = inst->opcode(); if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D &&
if (IsProj(opcode)) { info.dim != SpvDimRect) {
if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D && return _.diag(SPV_ERROR_INVALID_DATA, inst)
info.dim != SpvDimRect) { << "Expected Image 'Dim' parameter to be 1D, 2D, 3D or Rect";
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected Image 'Dim' parameter to be 1D, 2D, 3D or Rect";
}
if (info.multisampled != 0) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected Image 'MS' parameter to be 0";
}
if (info.arrayed != 0) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected Image 'arrayed' parameter to be 0";
}
} }
if (opcode == SpvOpImageRead || opcode == SpvOpImageSparseRead || if (info.multisampled != 0) {
opcode == SpvOpImageWrite) { return _.diag(SPV_ERROR_INVALID_DATA, inst)
if (info.sampled == 0) { << "Expected Image 'MS' parameter to be 0";
} else if (info.sampled == 2) { }
if (info.dim == SpvDim1D && !_.HasCapability(SpvCapabilityImage1D)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Capability Image1D is required to access storage image";
} else if (info.dim == SpvDimRect &&
!_.HasCapability(SpvCapabilityImageRect)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Capability ImageRect is required to access storage image";
} else if (info.dim == SpvDimBuffer &&
!_.HasCapability(SpvCapabilityImageBuffer)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Capability ImageBuffer is required to access storage image";
} else if (info.dim == SpvDimCube && info.arrayed == 1 &&
!_.HasCapability(SpvCapabilityImageCubeArray)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Capability ImageCubeArray is required to access "
<< "storage image";
}
if (info.multisampled == 1 && if (info.arrayed != 0) {
!_.HasCapability(SpvCapabilityImageMSArray)) { return _.diag(SPV_ERROR_INVALID_DATA, inst)
#if 0 << "Expected Image 'arrayed' parameter to be 0";
// TODO(atgoo@github.com) The description of this rule in the spec }
// is unclear and Glslang doesn't declare ImageMSArray. Need to clarify
// and reenable. return SPV_SUCCESS;
return _.diag(SPV_ERROR_INVALID_DATA, inst) }
<< "Capability ImageMSArray is required to access storage "
<< "image"; // Validate OpImage*Read and OpImage*Write instructions
#endif spv_result_t ValidateImageReadWrite(ValidationState_t& _,
} const Instruction* inst,
} else { const ImageTypeInfo& info) {
if (info.sampled == 2) {
if (info.dim == SpvDim1D && !_.HasCapability(SpvCapabilityImage1D)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst) return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected Image 'Sampled' parameter to be 0 or 2"; << "Capability Image1D is required to access storage image";
} else if (info.dim == SpvDimRect &&
!_.HasCapability(SpvCapabilityImageRect)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Capability ImageRect is required to access storage image";
} else if (info.dim == SpvDimBuffer &&
!_.HasCapability(SpvCapabilityImageBuffer)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Capability ImageBuffer is required to access storage image";
} else if (info.dim == SpvDimCube && info.arrayed == 1 &&
!_.HasCapability(SpvCapabilityImageCubeArray)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Capability ImageCubeArray is required to access "
<< "storage image";
} }
if (info.multisampled == 1 && !_.HasCapability(SpvCapabilityImageMSArray)) {
#if 0
// TODO(atgoo@github.com) The description of this rule in the spec
// is unclear and Glslang doesn't declare ImageMSArray. Need to clarify
// and reenable.
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Capability ImageMSArray is required to access storage "
<< "image";
#endif
}
} else if (info.sampled != 0) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected Image 'Sampled' parameter to be 0 or 2";
} }
return SPV_SUCCESS; return SPV_SUCCESS;
@ -813,7 +812,8 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
} }
} }
// Dim is checked elsewhere. // Universal checks on image type operands
// Dim and Format and Access Qualifier are checked elsewhere.
if (info.depth > 2) { if (info.depth > 2) {
return _.diag(SPV_ERROR_INVALID_DATA, inst) return _.diag(SPV_ERROR_INVALID_DATA, inst)
@ -825,47 +825,16 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
<< "Invalid Arrayed " << info.arrayed << " (must be 0 or 1)"; << "Invalid Arrayed " << info.arrayed << " (must be 0 or 1)";
} }
if (spvIsOpenCLEnv(target_env)) {
if ((info.arrayed == 1) && (info.dim != SpvDim1D) &&
(info.dim != SpvDim2D)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "In the OpenCL environment, Arrayed may only be set to 1 "
<< "when Dim is either 1D or 2D.";
}
}
if (info.multisampled > 1) { if (info.multisampled > 1) {
return _.diag(SPV_ERROR_INVALID_DATA, inst) return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Invalid MS " << info.multisampled << " (must be 0 or 1)"; << "Invalid MS " << info.multisampled << " (must be 0 or 1)";
} }
if (spvIsOpenCLEnv(target_env)) {
if (info.multisampled != 0) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "MS must be 0 in the OpenCL environment.";
}
}
if (info.sampled > 2) { if (info.sampled > 2) {
return _.diag(SPV_ERROR_INVALID_DATA, inst) return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Invalid Sampled " << info.sampled << " (must be 0, 1 or 2)"; << "Invalid Sampled " << info.sampled << " (must be 0, 1 or 2)";
} }
if (spvIsVulkanEnv(target_env)) {
if (info.sampled == 0) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< _.VkErrorID(4657)
<< "Sampled must be 1 or 2 in the Vulkan environment.";
}
}
if (spvIsOpenCLEnv(_.context()->target_env)) {
if (info.sampled != 0) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Sampled must be 0 in the OpenCL environment.";
}
}
if (info.dim == SpvDimSubpassData) { if (info.dim == SpvDimSubpassData) {
if (info.sampled != 2) { if (info.sampled != 2) {
return _.diag(SPV_ERROR_INVALID_DATA, inst) return _.diag(SPV_ERROR_INVALID_DATA, inst)
@ -876,19 +845,33 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
return _.diag(SPV_ERROR_INVALID_DATA, inst) return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Dim SubpassData requires format Unknown"; << "Dim SubpassData requires format Unknown";
} }
} else {
if (spvIsVulkanEnv(target_env)) { if (info.multisampled && (info.sampled == 2) &&
if (info.arrayed != 0) { !_.HasCapability(SpvCapabilityStorageImageMultisample)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst) return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< _.VkErrorID(6214) << "Capability StorageImageMultisample is required when using "
<< "Dim SubpassData requires Arrayed to be 0"; "multisampled storage image";
}
} }
} }
// Format and Access Qualifier are also checked elsewhere. if (spvIsOpenCLEnv(target_env)) {
if ((info.arrayed == 1) && (info.dim != SpvDim1D) &&
(info.dim != SpvDim2D)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "In the OpenCL environment, Arrayed may only be set to 1 "
<< "when Dim is either 1D or 2D.";
}
if (info.multisampled != 0) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "MS must be 0 in the OpenCL environment.";
}
if (info.sampled != 0) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Sampled must be 0 in the OpenCL environment.";
}
if (spvIsOpenCLEnv(_.context()->target_env)) {
if (info.access_qualifier == SpvAccessQualifierMax) { if (info.access_qualifier == SpvAccessQualifierMax) {
return _.diag(SPV_ERROR_INVALID_DATA, inst) return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "In the OpenCL environment, the optional Access Qualifier" << "In the OpenCL environment, the optional Access Qualifier"
@ -896,12 +879,16 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
} }
} }
if (info.multisampled && (info.sampled == 2) && if (spvIsVulkanEnv(target_env)) {
(info.dim != SpvDimSubpassData)) { if (info.sampled == 0) {
if (!_.HasCapability(SpvCapabilityStorageImageMultisample)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst) return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Capability StorageImageMultisample is required when using " << _.VkErrorID(4657)
"multisampled storage image"; << "Sampled must be 1 or 2 in the Vulkan environment.";
}
if (info.dim == SpvDimSubpassData && info.arrayed != 0) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< _.VkErrorID(6214) << "Dim SubpassData requires Arrayed to be 0";
} }
} }
@ -1213,7 +1200,9 @@ spv_result_t ValidateImageLod(ValidationState_t& _, const Instruction* inst) {
<< "Corrupt image type definition"; << "Corrupt image type definition";
} }
if (spv_result_t result = ValidateImageCommon(_, inst, info)) return result; if (IsProj(opcode)) {
if (spv_result_t result = ValidateImageProj(_, inst, info)) return result;
}
if (info.multisampled) { if (info.multisampled) {
// When using image operands, the Sample image operand is required if and // When using image operands, the Sample image operand is required if and
@ -1324,7 +1313,9 @@ spv_result_t ValidateImageDrefLod(ValidationState_t& _,
<< "Corrupt image type definition"; << "Corrupt image type definition";
} }
if (spv_result_t result = ValidateImageCommon(_, inst, info)) return result; if (IsProj(opcode)) {
if (spv_result_t result = ValidateImageProj(_, inst, info)) return result;
}
if (info.multisampled) { if (info.multisampled) {
// When using image operands, the Sample image operand is required if and // When using image operands, the Sample image operand is required if and
@ -1594,6 +1585,13 @@ spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) {
<< " to have 4 components"; << " to have 4 components";
} }
} }
const uint32_t mask = inst->words().size() <= 5 ? 0 : inst->word(5);
if (mask & SpvImageOperandsConstOffsetMask) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "ConstOffset image operand not allowed "
<< "in the OpenCL environment.";
}
} }
if (info.dim == SpvDimSubpassData) { if (info.dim == SpvDimSubpassData) {
@ -1619,7 +1617,8 @@ spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) {
} }
} }
if (spv_result_t result = ValidateImageCommon(_, inst, info)) return result; if (spv_result_t result = ValidateImageReadWrite(_, inst, info))
return result;
const uint32_t coord_type = _.GetOperandTypeId(inst, 3); const uint32_t coord_type = _.GetOperandTypeId(inst, 3);
if (!_.IsIntScalarOrVectorType(coord_type)) { if (!_.IsIntScalarOrVectorType(coord_type)) {
@ -1644,16 +1643,6 @@ spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) {
} }
} }
const uint32_t mask = inst->words().size() <= 5 ? 0 : inst->word(5);
if (mask & SpvImageOperandsConstOffsetMask) {
if (spvIsOpenCLEnv(_.context()->target_env)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "ConstOffset image operand not allowed "
<< "in the OpenCL environment.";
}
}
if (spv_result_t result = if (spv_result_t result =
ValidateImageOperands(_, inst, info, /* word_index = */ 6)) ValidateImageOperands(_, inst, info, /* word_index = */ 6))
return result; return result;
@ -1679,7 +1668,8 @@ spv_result_t ValidateImageWrite(ValidationState_t& _, const Instruction* inst) {
<< "Image 'Dim' cannot be SubpassData"; << "Image 'Dim' cannot be SubpassData";
} }
if (spv_result_t result = ValidateImageCommon(_, inst, info)) return result; if (spv_result_t result = ValidateImageReadWrite(_, inst, info))
return result;
const uint32_t coord_type = _.GetOperandTypeId(inst, 1); const uint32_t coord_type = _.GetOperandTypeId(inst, 1);
if (!_.IsIntScalarOrVectorType(coord_type)) { if (!_.IsIntScalarOrVectorType(coord_type)) {