mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-10-18 11:10:05 +00:00
Update sampled image validation (#5789)
Fixes #5781 * Requires all image operands to match except for depth between operand and result
This commit is contained in:
parent
07f49ce65d
commit
e9915cea8d
@ -1005,7 +1005,8 @@ bool IsAllowedSampledImageOperand(spv::Op opcode, ValidationState_t& _) {
|
||||
|
||||
spv_result_t ValidateSampledImage(ValidationState_t& _,
|
||||
const Instruction* inst) {
|
||||
if (_.GetIdOpcode(inst->type_id()) != spv::Op::OpTypeSampledImage) {
|
||||
auto type_inst = _.FindDef(inst->type_id());
|
||||
if (type_inst->opcode() != spv::Op::OpTypeSampledImage) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, inst)
|
||||
<< "Expected Result Type to be OpTypeSampledImage.";
|
||||
}
|
||||
@ -1022,8 +1023,25 @@ spv_result_t ValidateSampledImage(ValidationState_t& _,
|
||||
<< "Corrupt image type definition";
|
||||
}
|
||||
|
||||
// TODO(atgoo@github.com) Check compatibility of result type and received
|
||||
// image.
|
||||
// Image operands must match except for depth.
|
||||
auto sampled_image_id = type_inst->GetOperandAs<uint32_t>(1);
|
||||
if (sampled_image_id != image_type) {
|
||||
ImageTypeInfo sampled_info;
|
||||
if (!GetImageTypeInfo(_, sampled_image_id, &sampled_info)) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, inst)
|
||||
<< "Corrupt image type definition";
|
||||
}
|
||||
if (info.sampled_type != sampled_info.sampled_type ||
|
||||
info.dim != sampled_info.dim || info.arrayed != sampled_info.arrayed ||
|
||||
info.multisampled != sampled_info.multisampled ||
|
||||
info.sampled != sampled_info.sampled ||
|
||||
info.format != sampled_info.format ||
|
||||
info.access_qualifier != sampled_info.access_qualifier) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, inst)
|
||||
<< "Image operands must match result image operands except for "
|
||||
"depth";
|
||||
}
|
||||
}
|
||||
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
if (info.sampled != 1) {
|
||||
|
@ -4451,7 +4451,7 @@ TEST_F(ValidateImage, QuerySizeNotImage) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
|
||||
%res1 = OpImageQuerySize %u32vec2 %sampler
|
||||
)";
|
||||
|
||||
@ -4465,7 +4465,7 @@ TEST_F(ValidateImage, QuerySizeSampledImageDirectly) {
|
||||
const std::string body = R"(
|
||||
%img = OpLoad %type_image_f32_2d_0011 %uniform_image_f32_2d_0011
|
||||
%sampler = OpLoad %type_sampler %uniform_sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
|
||||
%simg = OpSampledImage %type_sampled_image_f32_2d_0011 %img %sampler
|
||||
%res1 = OpImageQuerySize %u32vec2 %simg
|
||||
)";
|
||||
|
||||
@ -10647,6 +10647,231 @@ TEST_F(ValidateImage, ImageMSArray_ArrayedTypeDoesNotRequireCapability) {
|
||||
EXPECT_THAT(getDiagnosticString(), Eq(""));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SampledImageTypeDepthMismatch) {
|
||||
const std::string code = R"(
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %main "main"
|
||||
OpExecutionMode %main LocalSize 1 1 1
|
||||
OpDecorate %im_var DescriptorSet 0
|
||||
OpDecorate %im_var Binding 0
|
||||
OpDecorate %s_var DescriptorSet 1
|
||||
OpDecorate %s_var Binding 0
|
||||
%void = OpTypeVoid
|
||||
%float = OpTypeFloat 32
|
||||
%im1_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
|
||||
%im2_ty = OpTypeImage %float 2D 1 0 0 1 Unknown
|
||||
%s_ty = OpTypeSampler
|
||||
%s_im_ty = OpTypeSampledImage %im2_ty
|
||||
%ptr_im = OpTypePointer UniformConstant %im1_ty
|
||||
%ptr_s = OpTypePointer UniformConstant %s_ty
|
||||
%im_var = OpVariable %ptr_im UniformConstant
|
||||
%s_var = OpVariable %ptr_s UniformConstant
|
||||
%void_fn = OpTypeFunction %void
|
||||
%main = OpFunction %void None %void_fn
|
||||
%entry = OpLabel
|
||||
%im_ld = OpLoad %im1_ty %im_var
|
||||
%s_ld = OpLoad %s_ty %s_var
|
||||
%sampled_image = OpSampledImage %s_im_ty %im_ld %s_ld
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const spv_target_env env = SPV_ENV_VULKAN_1_0;
|
||||
CompileSuccessfully(code, env);
|
||||
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(env));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SampledImageTypeArrayedMismatch) {
|
||||
const std::string code = R"(
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %main "main"
|
||||
OpExecutionMode %main LocalSize 1 1 1
|
||||
OpDecorate %im_var DescriptorSet 0
|
||||
OpDecorate %im_var Binding 0
|
||||
OpDecorate %s_var DescriptorSet 1
|
||||
OpDecorate %s_var Binding 0
|
||||
%void = OpTypeVoid
|
||||
%float = OpTypeFloat 32
|
||||
%im1_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
|
||||
%im2_ty = OpTypeImage %float 2D 0 1 0 1 Unknown
|
||||
%s_ty = OpTypeSampler
|
||||
%s_im_ty = OpTypeSampledImage %im2_ty
|
||||
%ptr_im = OpTypePointer UniformConstant %im1_ty
|
||||
%ptr_s = OpTypePointer UniformConstant %s_ty
|
||||
%im_var = OpVariable %ptr_im UniformConstant
|
||||
%s_var = OpVariable %ptr_s UniformConstant
|
||||
%void_fn = OpTypeFunction %void
|
||||
%main = OpFunction %void None %void_fn
|
||||
%entry = OpLabel
|
||||
%im_ld = OpLoad %im1_ty %im_var
|
||||
%s_ld = OpLoad %s_ty %s_var
|
||||
%sampled_image = OpSampledImage %s_im_ty %im_ld %s_ld
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const spv_target_env env = SPV_ENV_VULKAN_1_0;
|
||||
CompileSuccessfully(code, env);
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
|
||||
EXPECT_THAT(
|
||||
getDiagnosticString(),
|
||||
HasSubstr(
|
||||
"Image operands must match result image operands except for depth"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SampledImageTypeMultisampledMismatch) {
|
||||
const std::string code = R"(
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %main "main"
|
||||
OpExecutionMode %main LocalSize 1 1 1
|
||||
OpDecorate %im_var DescriptorSet 0
|
||||
OpDecorate %im_var Binding 0
|
||||
OpDecorate %s_var DescriptorSet 1
|
||||
OpDecorate %s_var Binding 0
|
||||
%void = OpTypeVoid
|
||||
%float = OpTypeFloat 32
|
||||
%im1_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
|
||||
%im2_ty = OpTypeImage %float 2D 0 0 1 1 Unknown
|
||||
%s_ty = OpTypeSampler
|
||||
%s_im_ty = OpTypeSampledImage %im2_ty
|
||||
%ptr_im = OpTypePointer UniformConstant %im1_ty
|
||||
%ptr_s = OpTypePointer UniformConstant %s_ty
|
||||
%im_var = OpVariable %ptr_im UniformConstant
|
||||
%s_var = OpVariable %ptr_s UniformConstant
|
||||
%void_fn = OpTypeFunction %void
|
||||
%main = OpFunction %void None %void_fn
|
||||
%entry = OpLabel
|
||||
%im_ld = OpLoad %im1_ty %im_var
|
||||
%s_ld = OpLoad %s_ty %s_var
|
||||
%sampled_image = OpSampledImage %s_im_ty %im_ld %s_ld
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const spv_target_env env = SPV_ENV_VULKAN_1_0;
|
||||
CompileSuccessfully(code, env);
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
|
||||
EXPECT_THAT(
|
||||
getDiagnosticString(),
|
||||
HasSubstr(
|
||||
"Image operands must match result image operands except for depth"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SampledImageTypeSampledMismatch) {
|
||||
const std::string code = R"(
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %main "main"
|
||||
OpExecutionMode %main LocalSize 1 1 1
|
||||
OpDecorate %im_var DescriptorSet 0
|
||||
OpDecorate %im_var Binding 0
|
||||
OpDecorate %s_var DescriptorSet 1
|
||||
OpDecorate %s_var Binding 0
|
||||
%void = OpTypeVoid
|
||||
%float = OpTypeFloat 32
|
||||
%im1_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
|
||||
%im2_ty = OpTypeImage %float 2D 0 0 0 0 Unknown
|
||||
%s_ty = OpTypeSampler
|
||||
%s_im_ty = OpTypeSampledImage %im2_ty
|
||||
%ptr_im = OpTypePointer UniformConstant %im1_ty
|
||||
%ptr_s = OpTypePointer UniformConstant %s_ty
|
||||
%im_var = OpVariable %ptr_im UniformConstant
|
||||
%s_var = OpVariable %ptr_s UniformConstant
|
||||
%void_fn = OpTypeFunction %void
|
||||
%main = OpFunction %void None %void_fn
|
||||
%entry = OpLabel
|
||||
%im_ld = OpLoad %im1_ty %im_var
|
||||
%s_ld = OpLoad %s_ty %s_var
|
||||
%sampled_image = OpSampledImage %s_im_ty %im_ld %s_ld
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const spv_target_env env = SPV_ENV_UNIVERSAL_1_0;
|
||||
CompileSuccessfully(code, env);
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
|
||||
EXPECT_THAT(
|
||||
getDiagnosticString(),
|
||||
HasSubstr(
|
||||
"Image operands must match result image operands except for depth"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SampledImageTypeFormatMismatch) {
|
||||
const std::string code = R"(
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %main "main"
|
||||
OpExecutionMode %main LocalSize 1 1 1
|
||||
OpDecorate %im_var DescriptorSet 0
|
||||
OpDecorate %im_var Binding 0
|
||||
OpDecorate %s_var DescriptorSet 1
|
||||
OpDecorate %s_var Binding 0
|
||||
%void = OpTypeVoid
|
||||
%float = OpTypeFloat 32
|
||||
%im1_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
|
||||
%im2_ty = OpTypeImage %float 2D 0 0 0 1 R32f
|
||||
%s_ty = OpTypeSampler
|
||||
%s_im_ty = OpTypeSampledImage %im2_ty
|
||||
%ptr_im = OpTypePointer UniformConstant %im1_ty
|
||||
%ptr_s = OpTypePointer UniformConstant %s_ty
|
||||
%im_var = OpVariable %ptr_im UniformConstant
|
||||
%s_var = OpVariable %ptr_s UniformConstant
|
||||
%void_fn = OpTypeFunction %void
|
||||
%main = OpFunction %void None %void_fn
|
||||
%entry = OpLabel
|
||||
%im_ld = OpLoad %im1_ty %im_var
|
||||
%s_ld = OpLoad %s_ty %s_var
|
||||
%sampled_image = OpSampledImage %s_im_ty %im_ld %s_ld
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const spv_target_env env = SPV_ENV_UNIVERSAL_1_0;
|
||||
CompileSuccessfully(code, env);
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
|
||||
EXPECT_THAT(
|
||||
getDiagnosticString(),
|
||||
HasSubstr(
|
||||
"Image operands must match result image operands except for depth"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateImage, SampledImageTypeAccessQualifierMismatch) {
|
||||
const std::string code = R"(
|
||||
OpCapability Kernel
|
||||
OpCapability Linkage
|
||||
OpMemoryModel Logical OpenCL
|
||||
%void = OpTypeVoid
|
||||
%float = OpTypeFloat 32
|
||||
%im1_ty = OpTypeImage %float 2D 0 0 0 0 Unknown ReadWrite
|
||||
%im2_ty = OpTypeImage %float 2D 0 0 0 0 Unknown ReadOnly
|
||||
%s_ty = OpTypeSampler
|
||||
%s_im_ty = OpTypeSampledImage %im2_ty
|
||||
%ptr_im = OpTypePointer UniformConstant %im1_ty
|
||||
%ptr_s = OpTypePointer UniformConstant %s_ty
|
||||
%im_var = OpVariable %ptr_im UniformConstant
|
||||
%s_var = OpVariable %ptr_s UniformConstant
|
||||
%void_fn = OpTypeFunction %void
|
||||
%main = OpFunction %void None %void_fn
|
||||
%entry = OpLabel
|
||||
%im_ld = OpLoad %im1_ty %im_var
|
||||
%s_ld = OpLoad %s_ty %s_var
|
||||
%sampled_image = OpSampledImage %s_im_ty %im_ld %s_ld
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const spv_target_env env = SPV_ENV_UNIVERSAL_1_0;
|
||||
CompileSuccessfully(code, env);
|
||||
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
|
||||
EXPECT_THAT(
|
||||
getDiagnosticString(),
|
||||
HasSubstr(
|
||||
"Image operands must match result image operands except for depth"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace val
|
||||
} // namespace spvtools
|
||||
|
Loading…
Reference in New Issue
Block a user