aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWooyoung Kim <wooykim@qti.qualcomm.com>2024-02-28 13:26:28 -0800
committerGitHub <noreply@github.com>2024-02-28 16:26:28 -0500
commit9bd44d028e8ca257dde9c24d5f67adabee3275ab (patch)
tree63a64e236fbc2320cfebd3e2cf5e026215f09e8c
parent0b027bafa54dba4e3f41c679ba0d45d6e514c4d5 (diff)
downloadspirv-tools-9bd44d028e8ca257dde9c24d5f67adabee3275ab.tar.gz
Suppot for SPV_QCOM_image_processing2 (#5582)
-rw-r--r--source/val/validate_image.cpp47
-rw-r--r--source/val/validation_state.cpp3
-rw-r--r--test/val/val_extensions_test.cpp208
-rw-r--r--test/val/val_image_test.cpp2612
4 files changed, 2857 insertions, 13 deletions
diff --git a/source/val/validate_image.cpp b/source/val/validate_image.cpp
index 543f345e..f62c3a26 100644
--- a/source/val/validate_image.cpp
+++ b/source/val/validate_image.cpp
@@ -982,6 +982,10 @@ bool IsAllowedSampledImageOperand(spv::Op opcode, ValidationState_t& _) {
case spv::Op::OpImageBoxFilterQCOM:
case spv::Op::OpImageBlockMatchSSDQCOM:
case spv::Op::OpImageBlockMatchSADQCOM:
+ case spv::Op::OpImageBlockMatchWindowSADQCOM:
+ case spv::Op::OpImageBlockMatchWindowSSDQCOM:
+ case spv::Op::OpImageBlockMatchGatherSADQCOM:
+ case spv::Op::OpImageBlockMatchGatherSSDQCOM:
return true;
case spv::Op::OpStore:
if (_.HasCapability(spv::Capability::BindlessTextureNV)) return true;
@@ -2168,7 +2172,7 @@ spv_result_t ValidateImageProcessingQCOMDecoration(ValidationState_t& _, int id,
int texture_id = ld_inst->GetOperandAs<int>(2); // variable to load
if (!_.HasDecoration(texture_id, decor)) {
return _.diag(SPV_ERROR_INVALID_DATA, ld_inst)
- << "Missing decoration WeightTextureQCOM/BlockMatchTextureQCOM";
+ << "Missing decoration " << _.SpvDecorationString(decor);
}
return SPV_SUCCESS;
@@ -2196,6 +2200,34 @@ spv_result_t ValidateImageProcessingQCOM(ValidationState_t& _,
_, ref_idx, spv::Decoration::BlockMatchTextureQCOM);
break;
}
+ case spv::Op::OpImageBlockMatchWindowSSDQCOM:
+ case spv::Op::OpImageBlockMatchWindowSADQCOM: {
+ int tgt_idx = inst->GetOperandAs<int>(2); // target
+ res = ValidateImageProcessingQCOMDecoration(
+ _, tgt_idx, spv::Decoration::BlockMatchTextureQCOM);
+ if (res != SPV_SUCCESS) break;
+ res = ValidateImageProcessingQCOMDecoration(
+ _, tgt_idx, spv::Decoration::BlockMatchSamplerQCOM);
+ if (res != SPV_SUCCESS) break;
+ int ref_idx = inst->GetOperandAs<int>(4); // reference
+ res = ValidateImageProcessingQCOMDecoration(
+ _, ref_idx, spv::Decoration::BlockMatchTextureQCOM);
+ if (res != SPV_SUCCESS) break;
+ res = ValidateImageProcessingQCOMDecoration(
+ _, ref_idx, spv::Decoration::BlockMatchSamplerQCOM);
+ break;
+ }
+ case spv::Op::OpImageBlockMatchGatherSSDQCOM:
+ case spv::Op::OpImageBlockMatchGatherSADQCOM: {
+ int tgt_idx = inst->GetOperandAs<int>(2); // target
+ res = ValidateImageProcessingQCOMDecoration(
+ _, tgt_idx, spv::Decoration::BlockMatchTextureQCOM);
+ if (res != SPV_SUCCESS) break;
+ int ref_idx = inst->GetOperandAs<int>(4); // reference
+ res = ValidateImageProcessingQCOMDecoration(
+ _, ref_idx, spv::Decoration::BlockMatchTextureQCOM);
+ break;
+ }
default:
break;
}
@@ -2326,6 +2358,10 @@ spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) {
case spv::Op::OpImageBoxFilterQCOM:
case spv::Op::OpImageBlockMatchSSDQCOM:
case spv::Op::OpImageBlockMatchSADQCOM:
+ case spv::Op::OpImageBlockMatchWindowSADQCOM:
+ case spv::Op::OpImageBlockMatchWindowSSDQCOM:
+ case spv::Op::OpImageBlockMatchGatherSADQCOM:
+ case spv::Op::OpImageBlockMatchGatherSSDQCOM:
return ValidateImageProcessingQCOM(_, inst);
default:
@@ -2378,6 +2414,10 @@ bool IsImageInstruction(const spv::Op opcode) {
case spv::Op::OpImageBoxFilterQCOM:
case spv::Op::OpImageBlockMatchSSDQCOM:
case spv::Op::OpImageBlockMatchSADQCOM:
+ case spv::Op::OpImageBlockMatchWindowSADQCOM:
+ case spv::Op::OpImageBlockMatchWindowSSDQCOM:
+ case spv::Op::OpImageBlockMatchGatherSADQCOM:
+ case spv::Op::OpImageBlockMatchGatherSSDQCOM:
return true;
default:
break;
@@ -2396,6 +2436,11 @@ spv_result_t ValidateQCOMImageProcessingTextureUsages(ValidationState_t& _,
case spv::Op::OpImageBlockMatchSSDQCOM:
case spv::Op::OpImageBlockMatchSADQCOM:
break;
+ case spv::Op::OpImageBlockMatchWindowSADQCOM:
+ case spv::Op::OpImageBlockMatchWindowSSDQCOM:
+ case spv::Op::OpImageBlockMatchGatherSADQCOM:
+ case spv::Op::OpImageBlockMatchGatherSSDQCOM:
+ break;
default:
for (size_t i = 0; i < inst->operands().size(); ++i) {
int id = inst->GetOperandAs<int>(i);
diff --git a/source/val/validation_state.cpp b/source/val/validation_state.cpp
index fa5ae3e0..89684993 100644
--- a/source/val/validation_state.cpp
+++ b/source/val/validation_state.cpp
@@ -615,7 +615,8 @@ void ValidationState_t::RegisterQCOMImageProcessingTextureConsumer(
uint32_t texture_id, const Instruction* consumer0,
const Instruction* consumer1) {
if (HasDecoration(texture_id, spv::Decoration::WeightTextureQCOM) ||
- HasDecoration(texture_id, spv::Decoration::BlockMatchTextureQCOM)) {
+ HasDecoration(texture_id, spv::Decoration::BlockMatchTextureQCOM) ||
+ HasDecoration(texture_id, spv::Decoration::BlockMatchSamplerQCOM)) {
qcom_image_processing_consumers_.insert(consumer0->id());
if (consumer1) {
qcom_image_processing_consumers_.insert(consumer1->id());
diff --git a/test/val/val_extensions_test.cpp b/test/val/val_extensions_test.cpp
index 0ab8c6e3..932bbee8 100644
--- a/test/val/val_extensions_test.cpp
+++ b/test/val/val_extensions_test.cpp
@@ -131,6 +131,214 @@ TEST_F(ValidateExtensionCapabilities, DeclCapabilityFailure) {
EXPECT_THAT(getDiagnosticString(), HasSubstr("SPV_KHR_device_group"));
}
+TEST_F(ValidateExtensionCapabilities,
+ DeclCapabilityFailureBlockMatchWIndowSAD) {
+ const std::string str = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %v_texcoord %fragColor %target_samp %ref_samp
+ OpExecutionMode %main OriginUpperLeft
+ OpSource GLSL 450
+ OpSourceExtension "GL_QCOM_image_processing"
+ OpSourceExtension "GL_QCOM_image_processing2"
+ OpName %main "main"
+ OpName %tgt_coords "tgt_coords"
+ OpName %v_texcoord "v_texcoord"
+ OpName %ref_coords "ref_coords"
+ OpName %blockSize "blockSize"
+ OpName %fragColor "fragColor"
+ OpName %target_samp "target_samp"
+ OpName %ref_samp "ref_samp"
+ OpDecorate %v_texcoord Location 0
+ OpDecorate %fragColor Location 0
+ OpDecorate %target_samp DescriptorSet 0
+ OpDecorate %target_samp Binding 4
+ OpDecorate %ref_samp DescriptorSet 0
+ OpDecorate %ref_samp Binding 5
+ OpDecorate %target_samp BlockMatchTextureQCOM
+ OpDecorate %target_samp BlockMatchSamplerQCOM
+ OpDecorate %ref_samp BlockMatchTextureQCOM
+ OpDecorate %ref_samp BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %v_texcoord = OpVariable %_ptr_Input_v4float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %uint_1 = OpConstant %uint 1
+ %uint_2 = OpConstant %uint 2
+ %uint_3 = OpConstant %uint 3
+ %uint_4 = OpConstant %uint 4
+ %39 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %fragColor = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %43 = OpTypeSampledImage %42
+%_ptr_UniformConstant_43 = OpTypePointer UniformConstant %43
+%target_samp = OpVariable %_ptr_UniformConstant_43 UniformConstant
+ %ref_samp = OpVariable %_ptr_UniformConstant_43 UniformConstant
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %tgt_coords = OpVariable %_ptr_Function_v2uint Function
+ %ref_coords = OpVariable %_ptr_Function_v2uint Function
+ %blockSize = OpVariable %_ptr_Function_v2uint Function
+ %16 = OpAccessChain %_ptr_Input_float %v_texcoord %uint_0
+ %17 = OpLoad %float %16
+ %18 = OpConvertFToU %uint %17
+ %20 = OpAccessChain %_ptr_Function_uint %tgt_coords %uint_0
+ OpStore %20 %18
+ %22 = OpAccessChain %_ptr_Input_float %v_texcoord %uint_1
+ %23 = OpLoad %float %22
+ %24 = OpConvertFToU %uint %23
+ %25 = OpAccessChain %_ptr_Function_uint %tgt_coords %uint_0
+ OpStore %25 %24
+ %28 = OpAccessChain %_ptr_Input_float %v_texcoord %uint_2
+ %29 = OpLoad %float %28
+ %30 = OpConvertFToU %uint %29
+ %31 = OpAccessChain %_ptr_Function_uint %ref_coords %uint_0
+ OpStore %31 %30
+ %33 = OpAccessChain %_ptr_Input_float %v_texcoord %uint_3
+ %34 = OpLoad %float %33
+ %35 = OpConvertFToU %uint %34
+ %36 = OpAccessChain %_ptr_Function_uint %ref_coords %uint_1
+ OpStore %36 %35
+ OpStore %blockSize %39
+ %46 = OpLoad %43 %target_samp
+ %47 = OpLoad %v2uint %tgt_coords
+ %49 = OpLoad %43 %ref_samp
+ %50 = OpLoad %v2uint %ref_coords
+ %51 = OpLoad %v2uint %blockSize
+ %52 = OpImageBlockMatchWindowSADQCOM %v4float %46 %47 %49 %50 %51
+ OpStore %fragColor %52
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_ERROR_MISSING_EXTENSION, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr("2nd operand of Decorate"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("requires one of these extensions"));
+ EXPECT_THAT(getDiagnosticString(), HasSubstr("SPV_QCOM_image_processing"));
+}
+
+TEST_F(ValidateExtensionCapabilities,
+ DeclCapabilityFailureBlockMatchWIndowSSD) {
+ const std::string str = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %v_texcoord %fragColor %tex2D_src1 %samp %tex2D_src2
+ OpExecutionMode %main OriginUpperLeft
+ OpSource GLSL 450
+ OpSourceExtension "GL_QCOM_image_processing"
+ OpSourceExtension "GL_QCOM_image_processing2"
+ OpName %main "main"
+ OpName %tgt_coords "tgt_coords"
+ OpName %v_texcoord "v_texcoord"
+ OpName %ref_coords "ref_coords"
+ OpName %blockSize "blockSize"
+ OpName %fragColor "fragColor"
+ OpName %tex2D_src1 "tex2D_src1"
+ OpName %samp "samp"
+ OpName %tex2D_src2 "tex2D_src2"
+ OpDecorate %v_texcoord Location 0
+ OpDecorate %fragColor Location 0
+ OpDecorate %tex2D_src1 DescriptorSet 0
+ OpDecorate %tex2D_src1 Binding 1
+ OpDecorate %samp DescriptorSet 0
+ OpDecorate %samp Binding 3
+ OpDecorate %tex2D_src2 DescriptorSet 0
+ OpDecorate %tex2D_src2 Binding 2
+ OpDecorate %tex2D_src1 BlockMatchTextureQCOM
+ OpDecorate %samp BlockMatchSamplerQCOM
+ OpDecorate %tex2D_src2 BlockMatchTextureQCOM
+ OpDecorate %samp BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %v_texcoord = OpVariable %_ptr_Input_v4float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %uint_1 = OpConstant %uint 1
+ %uint_2 = OpConstant %uint 2
+ %uint_3 = OpConstant %uint 3
+ %uint_4 = OpConstant %uint 4
+ %39 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %fragColor = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %tex2D_src1 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %samp = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %tex2D_src2 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %tgt_coords = OpVariable %_ptr_Function_v2uint Function
+ %ref_coords = OpVariable %_ptr_Function_v2uint Function
+ %blockSize = OpVariable %_ptr_Function_v2uint Function
+ %16 = OpAccessChain %_ptr_Input_float %v_texcoord %uint_0
+ %17 = OpLoad %float %16
+ %18 = OpConvertFToU %uint %17
+ %20 = OpAccessChain %_ptr_Function_uint %tgt_coords %uint_0
+ OpStore %20 %18
+ %22 = OpAccessChain %_ptr_Input_float %v_texcoord %uint_1
+ %23 = OpLoad %float %22
+ %24 = OpConvertFToU %uint %23
+ %25 = OpAccessChain %_ptr_Function_uint %tgt_coords %uint_0
+ OpStore %25 %24
+ %28 = OpAccessChain %_ptr_Input_float %v_texcoord %uint_2
+ %29 = OpLoad %float %28
+ %30 = OpConvertFToU %uint %29
+ %31 = OpAccessChain %_ptr_Function_uint %ref_coords %uint_0
+ OpStore %31 %30
+ %33 = OpAccessChain %_ptr_Input_float %v_texcoord %uint_3
+ %34 = OpLoad %float %33
+ %35 = OpConvertFToU %uint %34
+ %36 = OpAccessChain %_ptr_Function_uint %ref_coords %uint_1
+ OpStore %36 %35
+ OpStore %blockSize %39
+ %45 = OpLoad %42 %tex2D_src1
+ %49 = OpLoad %46 %samp
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %tgt_coords
+ %54 = OpLoad %42 %tex2D_src2
+ %55 = OpLoad %46 %samp
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %ref_coords
+ %58 = OpLoad %v2uint %blockSize
+ %59 = OpImageBlockMatchWindowSSDQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %fragColor %59
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_ERROR_MISSING_EXTENSION, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr("2nd operand of Decorate"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("requires one of these extensions"));
+ EXPECT_THAT(getDiagnosticString(), HasSubstr("SPV_QCOM_image_processing"));
+}
+
using ValidateAMDShaderBallotCapabilities = spvtest::ValidateBase<std::string>;
// Returns a vector of strings for the prefix of a SPIR-V assembly shader
diff --git a/test/val/val_image_test.cpp b/test/val/val_image_test.cpp
index 9a704098..35b76fc5 100644
--- a/test/val/val_image_test.cpp
+++ b/test/val/val_image_test.cpp
@@ -6733,7 +6733,8 @@ TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationA) {
CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
}
TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationB) {
@@ -6792,7 +6793,8 @@ TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationB) {
CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
}
TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationC) {
@@ -6844,7 +6846,8 @@ TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationC) {
CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
}
TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationD) {
@@ -6896,7 +6899,8 @@ TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationD) {
CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
}
TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationA) {
@@ -6955,7 +6959,8 @@ TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationA) {
CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
}
TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationB) {
@@ -7014,7 +7019,8 @@ TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationB) {
CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
}
TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationC) {
@@ -7066,7 +7072,8 @@ TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationC) {
CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
}
TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationD) {
@@ -7118,7 +7125,8 @@ TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationD) {
CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
}
TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedNoDecorationA) {
@@ -7177,7 +7185,8 @@ TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedNoDecorationA) {
CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration WeightTextureQCOM"));
}
TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedNoDecorationB) {
@@ -7230,10 +7239,11 @@ TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedNoDecorationB) {
CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
EXPECT_EQ(SPV_ERROR_INVALID_DATA,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
- EXPECT_THAT(getDiagnosticString(), HasSubstr("Missing decoration"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration WeightTextureQCOM"));
}
-TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseA) {
+TEST_F(ValidateImage, QCOMImageProcessingBlockMatchWindowSADInvalidUseA) {
std::string text = R"(
; SPIR-V
; Version: 1.0
@@ -7936,6 +7946,2586 @@ TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedInvalidUseB) {
HasSubstr("Illegal use of QCOM image processing decorated texture"));
}
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %5 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchWindowSADQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetIS) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %5 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchWindowSADQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorRefIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchWindowSADQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorRefIS) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchWindowSADQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetNIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchWindowSADQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetNIS) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchWindowSADQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorRefNIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchWindowSADQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorRefNIS) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchWindowSADQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %5 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchWindowSSDQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetIS) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %5 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchWindowSSDQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchWindowSSDQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefIS) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchWindowSSDQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetNIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchWindowSSDQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetNIS) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchWindowSSDQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefNIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchWindowSSDQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefNIS) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchWindowSSDQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADNoDecorTargetIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchGatherSADQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADNoDecorRefIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchGatherSADQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADNoDecorTargetNIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchGatherSADQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADNoDecorRefNIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchGatherSADQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDNoDecorTargetIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchGatherSSDQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDNoDecorRefIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchGatherSSDQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDNoDecorTargetNIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchGatherSSDQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDNoDecorRefNIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchGatherSSDQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage,
+ QCOMImageProcessing2BlockMatchWindowSADInvalidUseTargetI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %5 BlockMatchSamplerQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchWindowSADQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %5
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADInvalidUseRefI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %5 BlockMatchSamplerQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchWindowSADQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %6
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage,
+ QCOMImageProcessing2BlockMatchWindowSADInvalidUseTargetNI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %102 BlockMatchSamplerQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ OpDecorate %104 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchWindowSADQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %102
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADInvalidUseRefNI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %102 BlockMatchSamplerQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ OpDecorate %104 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchWindowSADQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %104
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage,
+ QCOMImageProcessing2BlockMatchWindowSSDInvalidUseTargetI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %5 BlockMatchSamplerQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchWindowSSDQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %5
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDInvalidUseRefI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %5 BlockMatchSamplerQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchWindowSSDQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %6
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage,
+ QCOMImageProcessing2BlockMatchWindowSSDInvalidUseTargetNI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %102 BlockMatchSamplerQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ OpDecorate %104 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchWindowSSDQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %102
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDInvalidUseRefNI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %102 BlockMatchSamplerQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ OpDecorate %104 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchWindowSSDQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %104
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage,
+ QCOMImageProcessing2BlockMatchGatherSADInvalidUseTargetI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchGatherSADQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %5
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADInvalidUseRefI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchGatherSADQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %6
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage,
+ QCOMImageProcessing2BlockMatchGatherSADInvalidUseTargetNI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchGatherSADQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %102
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADInvalidUseRefNI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchGatherSADQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %104
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage,
+ QCOMImageProcessing2BlockMatchGatherSSDInvalidUseTargetI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchGatherSSDQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %5
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDInvalidUseRefI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchGatherSSDQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %6
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage,
+ QCOMImageProcessing2BlockMatchGatherSSDInvalidUseTargetNI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchGatherSSDQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %102
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDInvalidUseRefNI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchGatherSSDQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %104
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
TEST_F(ValidateImage, ImageMSArray_ArrayedSampledTypeRequiresCapability) {
const std::string code = R"(
OpCapability Shader