Skip to content

Commit

Permalink
Suppot for SPV_QCOM_image_processing2 (KhronosGroup#5582)
Browse files Browse the repository at this point in the history
  • Loading branch information
wooyoungqcom committed Feb 28, 2024
1 parent 0b027ba commit 9bd44d0
Show file tree
Hide file tree
Showing 4 changed files with 2,857 additions and 13 deletions.
47 changes: 46 additions & 1 deletion source/val/validate_image.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion source/val/validation_state.cpp
Expand Up @@ -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());
Expand Down
208 changes: 208 additions & 0 deletions test/val/val_extensions_test.cpp
Expand Up @@ -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
Expand Down

0 comments on commit 9bd44d0

Please sign in to comment.