Skip to content

Commit f877466

Browse files
authored
SPV_QCOM_image_processing3 (KhronosGroup#6672)
Validation support for SPV_QCOM_image_processing3
1 parent b707790 commit f877466

3 files changed

Lines changed: 228 additions & 8 deletions

File tree

include/spirv-tools/libspirv.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,8 +1017,8 @@ SPIRV_TOOLS_EXPORT spv_result_t spvBinaryParse(
10171017
// The optimizer interface.
10181018

10191019
// A pointer to a function that accepts a log message from an optimizer.
1020-
typedef void (*spv_message_consumer)(
1021-
spv_message_level_t, const char*, const spv_position_t*, const char*);
1020+
typedef void (*spv_message_consumer)(spv_message_level_t, const char*,
1021+
const spv_position_t*, const char*);
10221022

10231023
// Creates and returns an optimizer object. This object must be passed to
10241024
// optimizer APIs below and is valid until passed to spvOptimizerDestroy.

source/val/validate_image.cpp

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,8 @@ spv_result_t ValidateImageOperands(ValidationState_t& _,
637637
if (opcode != spv::Op::OpImageGather &&
638638
opcode != spv::Op::OpImageDrefGather &&
639639
opcode != spv::Op::OpImageSparseGather &&
640-
opcode != spv::Op::OpImageSparseDrefGather) {
640+
opcode != spv::Op::OpImageSparseDrefGather &&
641+
opcode != spv::Op::OpImageGatherQCOM) {
641642
return _.diag(SPV_ERROR_INVALID_DATA, inst)
642643
<< _.VkErrorID(10213)
643644
<< "Image Operand Offset can only be used with "
@@ -652,7 +653,8 @@ spv_result_t ValidateImageOperands(ValidationState_t& _,
652653
if (opcode != spv::Op::OpImageGather &&
653654
opcode != spv::Op::OpImageDrefGather &&
654655
opcode != spv::Op::OpImageSparseGather &&
655-
opcode != spv::Op::OpImageSparseDrefGather) {
656+
opcode != spv::Op::OpImageSparseDrefGather &&
657+
opcode != spv::Op::OpImageGatherQCOM) {
656658
return _.diag(SPV_ERROR_INVALID_DATA, inst)
657659
<< "Image Operand ConstOffsets can only be used with "
658660
"OpImageGather and OpImageDrefGather";
@@ -908,7 +910,9 @@ bool IsSparse(spv::Op opcode) {
908910
return true;
909911
}
910912

911-
default: { return false; }
913+
default: {
914+
return false;
915+
}
912916
}
913917

914918
return false;
@@ -1192,6 +1196,7 @@ bool IsAllowedSampledImageOperand(spv::Op opcode, ValidationState_t& _) {
11921196
case spv::Op::OpImageBlockMatchWindowSSDQCOM:
11931197
case spv::Op::OpImageBlockMatchGatherSADQCOM:
11941198
case spv::Op::OpImageBlockMatchGatherSSDQCOM:
1199+
case spv::Op::OpImageGatherQCOM:
11951200
case spv::Op::OpImageSampleFootprintNV:
11961201
return true;
11971202
case spv::Op::OpStore:
@@ -1218,6 +1223,7 @@ spv_result_t ValidateImageCoordinate(ValidationState_t& _,
12181223
opcode == spv::Op::OpImageSampleProjDrefImplicitLod ||
12191224
opcode == spv::Op::OpImageSampleProjDrefExplicitLod ||
12201225
opcode == spv::Op::OpImageGather ||
1226+
opcode == spv::Op::OpImageGatherQCOM ||
12211227
opcode == spv::Op::OpImageDrefGather ||
12221228
opcode == spv::Op::OpImageQueryLod ||
12231229
opcode == spv::Op::OpImageSparseSampleImplicitLod ||
@@ -1846,8 +1852,10 @@ spv_result_t ValidateImageGather(ValidationState_t& _,
18461852
ValidateImageCoordinate(_, inst, info, /* word_index = */ 3))
18471853
return result;
18481854

1855+
unsigned n_additional_operands = 0;
18491856
if (opcode == spv::Op::OpImageGather ||
1850-
opcode == spv::Op::OpImageSparseGather) {
1857+
opcode == spv::Op::OpImageSparseGather ||
1858+
opcode == spv::Op::OpImageGatherQCOM) {
18511859
const uint32_t component = inst->GetOperandAs<uint32_t>(4);
18521860
const uint32_t component_index_type = _.GetTypeId(component);
18531861
if (!_.IsIntScalarType(component_index_type, 32)) {
@@ -1862,14 +1870,53 @@ spv_result_t ValidateImageGather(ValidationState_t& _,
18621870
"environment";
18631871
}
18641872
}
1873+
if (opcode == spv::Op::OpImageGatherQCOM) {
1874+
const uint32_t mode = inst->GetOperandAs<uint32_t>(5);
1875+
const uint32_t mode_index_type = _.GetTypeId(mode);
1876+
if (!_.IsIntScalarType(mode_index_type) ||
1877+
_.GetBitWidth(mode_index_type) != 32) {
1878+
return _.diag(SPV_ERROR_INVALID_DATA, inst)
1879+
<< "Expected Mode to be 32-bit int scalar";
1880+
}
1881+
const spv::Op modeOpc = _.GetIdOpcode(mode);
1882+
if (spvOpcodeIsConstant(modeOpc) && !spvOpcodeIsSpecConstant(modeOpc)) {
1883+
uint64_t m_val = -1;
1884+
if (_.EvalConstantValUint64(mode, &m_val)) {
1885+
if (m_val == 0) {
1886+
if (!_.HasCapability(spv::Capability::ImageGatherLinearQCOM)) {
1887+
return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
1888+
<< "Mode GatherModesGather4x1QCOM (== 0) requires "
1889+
"capability ImageGatherLinearQCOM.";
1890+
}
1891+
} else if (m_val < 4) {
1892+
if (!_.HasCapability(
1893+
spv::Capability::ImageGatherExtendedModesQCOM)) {
1894+
return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
1895+
<< "Mode GatherModesGatherDQCOM (== "
1896+
"1)/GatherModesGatherH2QCOM (== 2"
1897+
")/GatherModesGatherV2QCOM (== 3)"
1898+
" requires capability ImageGatherExtendedModesQCOM.";
1899+
}
1900+
} else {
1901+
return _.diag(SPV_ERROR_INVALID_DATA, inst)
1902+
<< "GatherModesGather4x1QCOM (== 0)/"
1903+
"GatherModesGatherDQCOM (== 1)/"
1904+
"GatherModesGatherH2QCOM (== 2)/"
1905+
"GatherModesGatherV2QCOM (== 3) "
1906+
"are the only supported modes.";
1907+
}
1908+
}
1909+
}
1910+
n_additional_operands += 1;
1911+
}
18651912
} else {
18661913
assert(opcode == spv::Op::OpImageDrefGather ||
18671914
opcode == spv::Op::OpImageSparseDrefGather);
18681915
if (spv_result_t result = ValidateImageDref(_, inst, info)) return result;
18691916
}
18701917

1871-
if (spv_result_t result =
1872-
ValidateImageOperands(_, inst, info, /* word_index = */ 7))
1918+
if (spv_result_t result = ValidateImageOperands(
1919+
_, inst, info, /* word_index = */ (7 + n_additional_operands)))
18731920
return result;
18741921

18751922
return SPV_SUCCESS;
@@ -2682,6 +2729,7 @@ spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) {
26822729
case spv::Op::OpImageDrefGather:
26832730
case spv::Op::OpImageSparseGather:
26842731
case spv::Op::OpImageSparseDrefGather:
2732+
case spv::Op::OpImageGatherQCOM:
26852733
return ValidateImageGather(_, inst);
26862734

26872735
case spv::Op::OpImageRead:
@@ -2787,6 +2835,7 @@ bool IsImageInstruction(const spv::Op opcode) {
27872835
case spv::Op::OpImageBlockMatchWindowSSDQCOM:
27882836
case spv::Op::OpImageBlockMatchGatherSADQCOM:
27892837
case spv::Op::OpImageBlockMatchGatherSSDQCOM:
2838+
case spv::Op::OpImageGatherQCOM:
27902839
return true;
27912840
default:
27922841
break;

test/val/val_image_test.cpp

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11123,6 +11123,177 @@ TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDInvalidUseRefNI) {
1112311123
HasSubstr("Illegal use of QCOM image processing decorated texture"));
1112411124
}
1112511125

11126+
TEST_F(ValidateImage, QCOMImageProcessing3ImageGatherQCOMCapabilityCheck1) {
11127+
const std::string body = R"(
11128+
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
11129+
%sampler = OpLoad %type_sampler %uniform_sampler
11130+
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
11131+
%res1 = OpImageGatherQCOM %f32vec4 %simg %f32vec2_hh %u32_1 %u32_0
11132+
)";
11133+
11134+
const std::string extra = R"(
11135+
OpCapability ImageGatherExtendedModesQCOM
11136+
OpExtension "SPV_QCOM_image_processing3"
11137+
)";
11138+
11139+
CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
11140+
ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY,
11141+
ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
11142+
EXPECT_THAT(getDiagnosticString(),
11143+
HasSubstr("Mode GatherModesGather4x1QCOM (== 0) requires "
11144+
"capability ImageGatherLinearQCOM."));
11145+
}
11146+
11147+
TEST_F(ValidateImage, QCOMImageProcessing3ImageGatherQCOMCapabilityCheck2) {
11148+
const std::string body = R"(
11149+
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
11150+
%sampler = OpLoad %type_sampler %uniform_sampler
11151+
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
11152+
%res1 = OpImageGatherQCOM %f32vec4 %simg %f32vec2_hh %u32_1 %u32_1
11153+
)";
11154+
11155+
const std::string extra = R"(
11156+
OpCapability ImageGatherLinearQCOM
11157+
OpExtension "SPV_QCOM_image_processing3"
11158+
)";
11159+
11160+
CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
11161+
ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY,
11162+
ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
11163+
EXPECT_THAT(
11164+
getDiagnosticString(),
11165+
HasSubstr("Mode GatherModesGatherDQCOM (== 1)/GatherModesGatherH2QCOM "
11166+
"(== 2)/GatherModesGatherV2QCOM (== 3) requires capability "
11167+
"ImageGatherExtendedModesQCOM."));
11168+
}
11169+
11170+
TEST_F(ValidateImage, QCOMImageProcessing3ImageGatherQCOMCapabilityCheck3) {
11171+
const std::string body = R"(
11172+
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
11173+
%sampler = OpLoad %type_sampler %uniform_sampler
11174+
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
11175+
%res1 = OpImageGatherQCOM %f32vec4 %simg %f32vec2_hh %u32_1 %u32_2
11176+
)";
11177+
11178+
const std::string extra = R"(
11179+
OpCapability ImageGatherLinearQCOM
11180+
OpExtension "SPV_QCOM_image_processing3"
11181+
)";
11182+
11183+
CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
11184+
ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY,
11185+
ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
11186+
EXPECT_THAT(
11187+
getDiagnosticString(),
11188+
HasSubstr("Mode GatherModesGatherDQCOM (== 1)/GatherModesGatherH2QCOM "
11189+
"(== 2)/GatherModesGatherV2QCOM (== 3) requires capability "
11190+
"ImageGatherExtendedModesQCOM."));
11191+
}
11192+
11193+
TEST_F(ValidateImage, QCOMImageProcessing3ImageGatherQCOMCapabilityCheck4) {
11194+
const std::string body = R"(
11195+
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
11196+
%sampler = OpLoad %type_sampler %uniform_sampler
11197+
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
11198+
%res1 = OpImageGatherQCOM %f32vec4 %simg %f32vec2_hh %u32_1 %u32_3
11199+
)";
11200+
11201+
const std::string extra = R"(
11202+
OpCapability ImageGatherLinearQCOM
11203+
OpExtension "SPV_QCOM_image_processing3"
11204+
)";
11205+
11206+
CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
11207+
ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY,
11208+
ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
11209+
EXPECT_THAT(
11210+
getDiagnosticString(),
11211+
HasSubstr("Mode GatherModesGatherDQCOM (== 1)/GatherModesGatherH2QCOM "
11212+
"(== 2)/GatherModesGatherV2QCOM (== 3) requires capability "
11213+
"ImageGatherExtendedModesQCOM."));
11214+
}
11215+
11216+
TEST_F(ValidateImage, QCOMImageProcessing3ImageGatherQCOMCapabilityCheck5) {
11217+
const std::string body = R"(
11218+
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
11219+
%sampler = OpLoad %type_sampler %uniform_sampler
11220+
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
11221+
%res1 = OpImageGatherQCOM %f32vec4 %simg %f32vec2_hh %u32_1 %u32_4
11222+
)";
11223+
11224+
const std::string extra = R"(
11225+
OpCapability ImageGatherLinearQCOM
11226+
OpCapability ImageGatherExtendedModesQCOM
11227+
OpExtension "SPV_QCOM_image_processing3"
11228+
)";
11229+
11230+
CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
11231+
ASSERT_EQ(SPV_ERROR_INVALID_DATA,
11232+
ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
11233+
EXPECT_THAT(
11234+
getDiagnosticString(),
11235+
HasSubstr("GatherModesGather4x1QCOM (== 0)/GatherModesGatherDQCOM (== "
11236+
"1)/GatherModesGatherH2QCOM (== 2)/GatherModesGatherV2QCOM (== "
11237+
"3) are the only supported modes."));
11238+
}
11239+
11240+
TEST_F(ValidateImage, QCOMImageProcessing3ImageGatherQCOMReturnType) {
11241+
const std::string body = R"(
11242+
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
11243+
%sampler = OpLoad %type_sampler %uniform_sampler
11244+
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
11245+
%res1 = OpImageGatherQCOM %f32 %simg %f32vec2_hh %u32_1 %u32_0
11246+
)";
11247+
11248+
const std::string extra = R"(
11249+
OpCapability ImageGatherLinearQCOM
11250+
OpExtension "SPV_QCOM_image_processing3"
11251+
)";
11252+
11253+
CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
11254+
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
11255+
EXPECT_THAT(getDiagnosticString(),
11256+
HasSubstr("Expected Result Type to be int or float vector type"));
11257+
}
11258+
11259+
TEST_F(ValidateImage, QCOMImageProcessing3ImageGatherQCOMModeIndexType1) {
11260+
const std::string body = R"(
11261+
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
11262+
%sampler = OpLoad %type_sampler %uniform_sampler
11263+
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
11264+
%res1 = OpImageGatherQCOM %f32vec4 %simg %f32vec2_hh %u32_1 %f32_1
11265+
)";
11266+
11267+
const std::string extra = R"(
11268+
OpCapability ImageGatherExtendedModesQCOM
11269+
OpExtension "SPV_QCOM_image_processing3"
11270+
)";
11271+
11272+
CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
11273+
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
11274+
EXPECT_THAT(getDiagnosticString(),
11275+
HasSubstr("Expected Mode to be 32-bit int scalar"));
11276+
}
11277+
11278+
TEST_F(ValidateImage, QCOMImageProcessing3ImageGatherQCOMModeIndexType2) {
11279+
const std::string body = R"(
11280+
%img = OpLoad %type_image_f32_2d_0001 %uniform_image_f32_2d_0001
11281+
%sampler = OpLoad %type_sampler %uniform_sampler
11282+
%simg = OpSampledImage %type_sampled_image_f32_2d_0001 %img %sampler
11283+
%res1 = OpImageGatherQCOM %f32vec4 %simg %f32vec2_hh %u32_1 %u16_0
11284+
)";
11285+
11286+
const std::string extra = R"(
11287+
OpCapability ImageGatherExtendedModesQCOM
11288+
OpExtension "SPV_QCOM_image_processing3"
11289+
)";
11290+
11291+
CompileSuccessfully(GenerateShaderCode(body, extra).c_str());
11292+
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
11293+
EXPECT_THAT(getDiagnosticString(),
11294+
HasSubstr("Expected Mode to be 32-bit int scalar"));
11295+
}
11296+
1112611297
TEST_F(ValidateImage, ImageMSArray_ArrayedSampledTypeRequiresCapability) {
1112711298
const std::string code = R"(
1112811299
OpCapability Shader

0 commit comments

Comments
 (0)