mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-22 19:50:05 +00:00
Validate OpenCL environment rules for OpTypeImage (#2606)
It is currently not possible to use an Image Format that is not Unknown without requiring a capability forbidden by the OpenCL environment. As such the validation of Image Format currently leans on capability validation entirely. Fixes #2592. Signed-off-by: Kevin Petit <kevin.petit@arm.com>
This commit is contained in:
parent
47741f0504
commit
9f035269d6
@ -718,6 +718,11 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
|
||||
<< "Expected Sampled Type to be a 32-bit int or float "
|
||||
"scalar type for Vulkan environment";
|
||||
}
|
||||
} else if (spvIsOpenCLEnv(_.context()->target_env)) {
|
||||
if (!_.IsVoidType(info.sampled_type)) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, inst)
|
||||
<< "Sampled Type must be OpTypeVoid in the OpenCL environment.";
|
||||
}
|
||||
} else {
|
||||
const SpvOp sampled_type_opcode = _.GetIdOpcode(info.sampled_type);
|
||||
if (sampled_type_opcode != SpvOpTypeVoid &&
|
||||
@ -741,16 +746,39 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
|
||||
<< "Invalid Arrayed " << info.arrayed << " (must be 0 or 1)";
|
||||
}
|
||||
|
||||
if (spvIsOpenCLEnv(_.context()->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) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, inst)
|
||||
<< "Invalid MS " << info.multisampled << " (must be 0 or 1)";
|
||||
}
|
||||
|
||||
if (spvIsOpenCLEnv(_.context()->target_env)) {
|
||||
if (info.multisampled != 0) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, inst)
|
||||
<< "MS must be 0 in the OpenCL environement.";
|
||||
}
|
||||
}
|
||||
|
||||
if (info.sampled > 2) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, inst)
|
||||
<< "Invalid Sampled " << info.sampled << " (must be 0, 1 or 2)";
|
||||
}
|
||||
|
||||
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.sampled != 2) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, inst)
|
||||
@ -763,7 +791,15 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
|
||||
}
|
||||
}
|
||||
|
||||
// Format and Access Qualifier are checked elsewhere.
|
||||
// Format and Access Qualifier are also checked elsewhere.
|
||||
|
||||
if (spvIsOpenCLEnv(_.context()->target_env)) {
|
||||
if (info.access_qualifier == SpvAccessQualifierMax) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, inst)
|
||||
<< "In the OpenCL environment, the optional Access Qualifier"
|
||||
<< " must be present.";
|
||||
}
|
||||
}
|
||||
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
@ -691,6 +691,12 @@ uint32_t ValidationState_t::GetBitWidth(uint32_t id) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ValidationState_t::IsVoidType(uint32_t id) const {
|
||||
const Instruction* inst = FindDef(id);
|
||||
assert(inst);
|
||||
return inst->opcode() == SpvOpTypeVoid;
|
||||
}
|
||||
|
||||
bool ValidationState_t::IsFloatScalarType(uint32_t id) const {
|
||||
const Instruction* inst = FindDef(id);
|
||||
assert(inst);
|
||||
|
@ -548,6 +548,7 @@ class ValidationState_t {
|
||||
|
||||
// Returns true iff |id| is a type corresponding to the name of the function.
|
||||
// Only works for types not for objects.
|
||||
bool IsVoidType(uint32_t id) const;
|
||||
bool IsFloatScalarType(uint32_t id) const;
|
||||
bool IsFloatVectorType(uint32_t id) const;
|
||||
bool IsFloatScalarOrVectorType(uint32_t id) const;
|
||||
|
@ -56,6 +56,97 @@ TEST_F(ValidateOpenCL, NonOpenCLMemoryModelBad) {
|
||||
"\n OpMemoryModel Physical32 GLSL450\n"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateOpenCL, NonVoidSampledTypeImageBad) {
|
||||
std::string spirv = R"(
|
||||
OpCapability Addresses
|
||||
OpCapability Kernel
|
||||
OpMemoryModel Physical32 OpenCL
|
||||
%1 = OpTypeInt 32 0
|
||||
%2 = OpTypeImage %1 2D 0 0 0 0 Unknown ReadOnly
|
||||
)";
|
||||
|
||||
CompileSuccessfully(spirv);
|
||||
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
|
||||
EXPECT_THAT(
|
||||
getDiagnosticString(),
|
||||
HasSubstr("Sampled Type must be OpTypeVoid in the OpenCL environment."
|
||||
"\n %2 = OpTypeImage %uint 2D 0 0 0 0 Unknown ReadOnly\n"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateOpenCL, NonZeroMSImageBad) {
|
||||
std::string spirv = R"(
|
||||
OpCapability Addresses
|
||||
OpCapability Kernel
|
||||
OpMemoryModel Physical32 OpenCL
|
||||
%1 = OpTypeVoid
|
||||
%2 = OpTypeImage %1 2D 0 0 1 0 Unknown ReadOnly
|
||||
)";
|
||||
|
||||
CompileSuccessfully(spirv);
|
||||
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
|
||||
EXPECT_THAT(
|
||||
getDiagnosticString(),
|
||||
HasSubstr("MS must be 0 in the OpenCL environement."
|
||||
"\n %2 = OpTypeImage %void 2D 0 0 1 0 Unknown ReadOnly\n"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateOpenCL, Non1D2DArrayedImageBad) {
|
||||
std::string spirv = R"(
|
||||
OpCapability Addresses
|
||||
OpCapability Kernel
|
||||
OpMemoryModel Physical32 OpenCL
|
||||
%1 = OpTypeVoid
|
||||
%2 = OpTypeImage %1 3D 0 1 0 0 Unknown ReadOnly
|
||||
)";
|
||||
|
||||
CompileSuccessfully(spirv);
|
||||
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
|
||||
EXPECT_THAT(
|
||||
getDiagnosticString(),
|
||||
HasSubstr("In the OpenCL environment, Arrayed may only be set to 1 "
|
||||
"when Dim is either 1D or 2D."
|
||||
"\n %2 = OpTypeImage %void 3D 0 1 0 0 Unknown ReadOnly\n"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateOpenCL, NonZeroSampledImageBad) {
|
||||
std::string spirv = R"(
|
||||
OpCapability Addresses
|
||||
OpCapability Kernel
|
||||
OpMemoryModel Physical32 OpenCL
|
||||
%1 = OpTypeVoid
|
||||
%2 = OpTypeImage %1 3D 0 0 0 1 Unknown ReadOnly
|
||||
)";
|
||||
|
||||
CompileSuccessfully(spirv);
|
||||
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
|
||||
EXPECT_THAT(
|
||||
getDiagnosticString(),
|
||||
HasSubstr("Sampled must be 0 in the OpenCL environment."
|
||||
"\n %2 = OpTypeImage %void 3D 0 0 0 1 Unknown ReadOnly\n"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateOpenCL, NoAccessQualifierImageBad) {
|
||||
std::string spirv = R"(
|
||||
OpCapability Addresses
|
||||
OpCapability Kernel
|
||||
OpMemoryModel Physical32 OpenCL
|
||||
%1 = OpTypeVoid
|
||||
%2 = OpTypeImage %1 3D 0 0 0 0 Unknown
|
||||
)";
|
||||
|
||||
CompileSuccessfully(spirv);
|
||||
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("In the OpenCL environment, the optional "
|
||||
"Access Qualifier must be present."
|
||||
"\n %2 = OpTypeImage %void 3D 0 0 0 0 Unknown\n"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace val
|
||||
} // namespace spvtools
|
||||
|
Loading…
Reference in New Issue
Block a user