spirv-reader: support OpImageGather
Bug: tint:1336 Change-Id: I771b09e7568f1f022a316f2ba0bc72c03f735aa1 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/74800 Auto-Submit: David Neto <dneto@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: David Neto <dneto@google.com>
This commit is contained in:
parent
f09a23a3f7
commit
7d88368c56
|
@ -494,8 +494,9 @@ bool IsSampledImageAccess(SpvOp opcode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// @param opcode a SPIR-V opcode
|
// @param opcode a SPIR-V opcode
|
||||||
// @returns true if the given instruction is an image sampling operation.
|
// @returns true if the given instruction is an image sampling, gather,
|
||||||
bool IsImageSampling(SpvOp opcode) {
|
// or gather-compare operation.
|
||||||
|
bool IsImageSamplingOrGatherOrDrefGather(SpvOp opcode) {
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case SpvOpImageSampleImplicitLod:
|
case SpvOpImageSampleImplicitLod:
|
||||||
case SpvOpImageSampleExplicitLod:
|
case SpvOpImageSampleExplicitLod:
|
||||||
|
@ -506,6 +507,8 @@ bool IsImageSampling(SpvOp opcode) {
|
||||||
case SpvOpImageSampleProjExplicitLod:
|
case SpvOpImageSampleProjExplicitLod:
|
||||||
case SpvOpImageSampleProjDrefImplicitLod:
|
case SpvOpImageSampleProjDrefImplicitLod:
|
||||||
case SpvOpImageSampleProjDrefExplicitLod:
|
case SpvOpImageSampleProjDrefExplicitLod:
|
||||||
|
case SpvOpImageGather:
|
||||||
|
case SpvOpImageDrefGather:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -5247,6 +5250,7 @@ bool FunctionEmitter::EmitImageAccess(const spvtools::opt::Instruction& inst) {
|
||||||
}
|
}
|
||||||
params.push_back(GetImageExpression(inst));
|
params.push_back(GetImageExpression(inst));
|
||||||
|
|
||||||
|
// Form the sampler operand, if needed.
|
||||||
if (IsSampledImageAccess(opcode)) {
|
if (IsSampledImageAccess(opcode)) {
|
||||||
// Form the sampler operand.
|
// Form the sampler operand.
|
||||||
if (auto* sampler = GetSamplerExpression(inst)) {
|
if (auto* sampler = GetSamplerExpression(inst)) {
|
||||||
|
@ -5256,6 +5260,7 @@ bool FunctionEmitter::EmitImageAccess(const spvtools::opt::Instruction& inst) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find the texture type.
|
||||||
const Pointer* texture_ptr_type = parser_impl_.GetTypeForHandleVar(*image);
|
const Pointer* texture_ptr_type = parser_impl_.GetTypeForHandleVar(*image);
|
||||||
if (!texture_ptr_type) {
|
if (!texture_ptr_type) {
|
||||||
return Fail();
|
return Fail();
|
||||||
|
@ -5309,8 +5314,16 @@ bool FunctionEmitter::EmitImageAccess(const spvtools::opt::Instruction& inst) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SpvOpImageGather:
|
case SpvOpImageGather:
|
||||||
|
builtin_name = "textureGather";
|
||||||
|
if (!texture_type->Is<DepthTexture>()) {
|
||||||
|
// The explicit component is the *first* argument in WGSL.
|
||||||
|
params.insert(params.begin(), ToI32(MakeOperand(inst, arg_index)).expr);
|
||||||
|
}
|
||||||
|
// Skip over the component operand, even for depth textures.
|
||||||
|
arg_index++;
|
||||||
|
break;
|
||||||
case SpvOpImageDrefGather:
|
case SpvOpImageDrefGather:
|
||||||
return Fail() << " image gather is not yet supported";
|
return Fail() << " image dref gather is not yet supported";
|
||||||
case SpvOpImageFetch:
|
case SpvOpImageFetch:
|
||||||
case SpvOpImageRead:
|
case SpvOpImageRead:
|
||||||
// Read a single texel from a sampled or storage image.
|
// Read a single texel from a sampled or storage image.
|
||||||
|
@ -5407,8 +5420,9 @@ bool FunctionEmitter::EmitImageAccess(const spvtools::opt::Instruction& inst) {
|
||||||
}
|
}
|
||||||
if (arg_index < num_args &&
|
if (arg_index < num_args &&
|
||||||
(image_operands_mask & SpvImageOperandsConstOffsetMask)) {
|
(image_operands_mask & SpvImageOperandsConstOffsetMask)) {
|
||||||
if (!IsImageSampling(opcode)) {
|
if (!IsImageSamplingOrGatherOrDrefGather(opcode)) {
|
||||||
return Fail() << "ConstOffset is only permitted for sampling operations: "
|
return Fail() << "ConstOffset is only permitted for sampling, gather, or "
|
||||||
|
"depth-reference gather operations: "
|
||||||
<< inst.PrettyPrint();
|
<< inst.PrettyPrint();
|
||||||
}
|
}
|
||||||
switch (texture_type->dims) {
|
switch (texture_type->dims) {
|
||||||
|
|
|
@ -929,6 +929,7 @@ TEST_P(SpvParserHandleTest_RegisterHandleUsage_SampledImage, Variable) {
|
||||||
EXPECT_THAT(su.to_str(), Eq(GetParam().expected_sampler_usage));
|
EXPECT_THAT(su.to_str(), Eq(GetParam().expected_sampler_usage));
|
||||||
EXPECT_THAT(iu.to_str(), Eq(GetParam().expected_image_usage));
|
EXPECT_THAT(iu.to_str(), Eq(GetParam().expected_image_usage));
|
||||||
|
|
||||||
|
// TODO(dneto): remove this. crbug.com/tint/1336
|
||||||
if (inst.find("Gather") != std::string::npos) {
|
if (inst.find("Gather") != std::string::npos) {
|
||||||
// WGSL does not support Gather instructions yet.
|
// WGSL does not support Gather instructions yet.
|
||||||
// So don't emit them as part of a "passing" corpus.
|
// So don't emit them as part of a "passing" corpus.
|
||||||
|
@ -986,6 +987,7 @@ TEST_P(SpvParserHandleTest_RegisterHandleUsage_SampledImage, FunctionParam) {
|
||||||
EXPECT_THAT(su.to_str(), Eq(GetParam().expected_sampler_usage));
|
EXPECT_THAT(su.to_str(), Eq(GetParam().expected_sampler_usage));
|
||||||
EXPECT_THAT(iu.to_str(), Eq(GetParam().expected_image_usage));
|
EXPECT_THAT(iu.to_str(), Eq(GetParam().expected_image_usage));
|
||||||
|
|
||||||
|
// TODO(dneto): remove this. crbug.com/tint/1336
|
||||||
if (inst.find("Gather") != std::string::npos) {
|
if (inst.find("Gather") != std::string::npos) {
|
||||||
// WGSL does not support Gather instructions yet.
|
// WGSL does not support Gather instructions yet.
|
||||||
// So don't emit them as part of a "passing" corpus.
|
// So don't emit them as part of a "passing" corpus.
|
||||||
|
@ -1004,8 +1006,6 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
SpvParserHandleTest_RegisterHandleUsage_SampledImage,
|
SpvParserHandleTest_RegisterHandleUsage_SampledImage,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
|
|
||||||
// Test image gather even though WGSL doesn't support it yet.
|
|
||||||
|
|
||||||
// OpImageGather
|
// OpImageGather
|
||||||
UsageImageAccessCase{"%result = OpImageGather "
|
UsageImageAccessCase{"%result = OpImageGather "
|
||||||
"%v4float %sampled_image %coords %uint_1",
|
"%v4float %sampled_image %coords %uint_1",
|
||||||
|
@ -1565,24 +1565,170 @@ TEST_P(SpvParserHandleTest_RegisterHandleUsage_SampledImage,
|
||||||
DISABLED_FunctionParam) {}
|
DISABLED_FunctionParam) {}
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
DISABLED_ImageGather,
|
ImageGather,
|
||||||
SpvParserHandleTest_SampledImageAccessTest,
|
SpvParserHandleTest_SampledImageAccessTest,
|
||||||
::testing::ValuesIn(std::vector<ImageAccessCase>{
|
::testing::ValuesIn(std::vector<ImageAccessCase>{
|
||||||
// TODO(dneto): OpImageGather
|
// OpImageGather 2D
|
||||||
// TODO(dneto): OpImageGather with ConstOffset (signed and unsigned)
|
ImageAccessCase{"%float 2D 0 0 0 1 Unknown",
|
||||||
// TODO(dneto): OpImageGather with Offset (signed and unsigned)
|
"%result = OpImageGather "
|
||||||
// TODO(dneto): OpImageGather with Offsets (signed and unsigned)
|
"%v4float %sampled_image %coords12 %int_1",
|
||||||
}));
|
R"([[group(0), binding(0)]] var x_10 : sampler;
|
||||||
|
|
||||||
|
[[group(2), binding(1)]] var x_20 : texture_2d<f32>;)",
|
||||||
|
"textureGather(1, x_20, x_10, coords12)"},
|
||||||
|
// OpImageGather 2D ConstOffset signed
|
||||||
|
ImageAccessCase{
|
||||||
|
"%float 2D 0 0 0 1 Unknown",
|
||||||
|
"%result = OpImageGather "
|
||||||
|
"%v4float %sampled_image %coords12 %int_1 ConstOffset %offsets2d",
|
||||||
|
R"([[group(0), binding(0)]] var x_10 : sampler;
|
||||||
|
|
||||||
|
[[group(2), binding(1)]] var x_20 : texture_2d<f32>;)",
|
||||||
|
"textureGather(1, x_20, x_10, coords12, vec2<i32>(3, 4))"},
|
||||||
|
// OpImageGather 2D ConstOffset unsigned
|
||||||
|
ImageAccessCase{"%float 2D 0 0 0 1 Unknown",
|
||||||
|
"%result = OpImageGather "
|
||||||
|
"%v4float %sampled_image %coords12 %int_1 ConstOffset "
|
||||||
|
"%u_offsets2d",
|
||||||
|
R"([[group(0), binding(0)]] var x_10 : sampler;
|
||||||
|
|
||||||
|
[[group(2), binding(1)]] var x_20 : texture_2d<f32>;)",
|
||||||
|
"textureGather(1, x_20, x_10, coords12, "
|
||||||
|
"vec2<i32>(vec2<u32>(3u, 4u)))"},
|
||||||
|
// OpImageGather 2D Array
|
||||||
|
ImageAccessCase{"%float 2D 0 1 0 1 Unknown",
|
||||||
|
"%result = OpImageGather "
|
||||||
|
"%v4float %sampled_image %coords123 %int_1",
|
||||||
|
R"([[group(0), binding(0)]] var x_10 : sampler;
|
||||||
|
|
||||||
|
[[group(2), binding(1)]] var x_20 : texture_2d_array<f32>;)",
|
||||||
|
"textureGather(1, x_20, x_10, coords123.xy, "
|
||||||
|
"i32(round(coords123.z)))"},
|
||||||
|
// OpImageGather 2D Array ConstOffset signed
|
||||||
|
ImageAccessCase{
|
||||||
|
"%float 2D 0 1 0 1 Unknown",
|
||||||
|
"%result = OpImageGather "
|
||||||
|
"%v4float %sampled_image %coords123 %int_1 ConstOffset %offsets2d",
|
||||||
|
R"([[group(0), binding(0)]] var x_10 : sampler;
|
||||||
|
|
||||||
|
[[group(2), binding(1)]] var x_20 : texture_2d_array<f32>;)",
|
||||||
|
"textureGather(1, x_20, x_10, coords123.xy, "
|
||||||
|
"i32(round(coords123.z)), vec2<i32>(3, 4))"},
|
||||||
|
// OpImageGather 2D Array ConstOffset unsigned
|
||||||
|
ImageAccessCase{"%float 2D 0 1 0 1 Unknown",
|
||||||
|
"%result = OpImageGather "
|
||||||
|
"%v4float %sampled_image %coords123 %int_1 ConstOffset "
|
||||||
|
"%u_offsets2d",
|
||||||
|
R"([[group(0), binding(0)]] var x_10 : sampler;
|
||||||
|
|
||||||
|
[[group(2), binding(1)]] var x_20 : texture_2d_array<f32>;)",
|
||||||
|
"textureGather(1, x_20, x_10, coords123.xy, "
|
||||||
|
"i32(round(coords123.z)), "
|
||||||
|
"vec2<i32>(vec2<u32>(3u, 4u)))"},
|
||||||
|
// OpImageGather Cube
|
||||||
|
ImageAccessCase{"%float Cube 0 0 0 1 Unknown",
|
||||||
|
"%result = OpImageGather "
|
||||||
|
"%v4float %sampled_image %coords123 %int_1",
|
||||||
|
R"([[group(0), binding(0)]] var x_10 : sampler;
|
||||||
|
|
||||||
|
[[group(2), binding(1)]] var x_20 : texture_cube<f32>;)",
|
||||||
|
"textureGather(1, x_20, x_10, coords123)"},
|
||||||
|
// OpImageGather Cube Array
|
||||||
|
ImageAccessCase{"%float Cube 0 1 0 1 Unknown",
|
||||||
|
"%result = OpImageGather "
|
||||||
|
"%v4float %sampled_image %coords1234 %int_1",
|
||||||
|
R"([[group(0), binding(0)]] var x_10 : sampler;
|
||||||
|
|
||||||
|
[[group(2), binding(1)]] var x_20 : texture_cube_array<f32>;)",
|
||||||
|
"textureGather(1, x_20, x_10, coords1234.xyz, "
|
||||||
|
"i32(round(coords1234.w)))"},
|
||||||
|
// OpImageGather 2DDepth
|
||||||
|
ImageAccessCase{"%float 2D 1 0 0 1 Unknown",
|
||||||
|
"%result = OpImageGather "
|
||||||
|
"%v4float %sampled_image %coords12 %int_1",
|
||||||
|
R"([[group(0), binding(0)]] var x_10 : sampler;
|
||||||
|
|
||||||
|
[[group(2), binding(1)]] var x_20 : texture_depth_2d;)",
|
||||||
|
"textureGather(x_20, x_10, coords12)"},
|
||||||
|
// OpImageGather 2DDepth ConstOffset signed
|
||||||
|
ImageAccessCase{
|
||||||
|
"%float 2D 1 0 0 1 Unknown",
|
||||||
|
"%result = OpImageGather "
|
||||||
|
"%v4float %sampled_image %coords12 %int_1 ConstOffset %offsets2d",
|
||||||
|
R"([[group(0), binding(0)]] var x_10 : sampler;
|
||||||
|
|
||||||
|
[[group(2), binding(1)]] var x_20 : texture_depth_2d;)",
|
||||||
|
"textureGather(x_20, x_10, coords12, vec2<i32>(3, 4))"},
|
||||||
|
// OpImageGather 2DDepth ConstOffset unsigned
|
||||||
|
ImageAccessCase{"%float 2D 1 0 0 1 Unknown",
|
||||||
|
"%result = OpImageGather "
|
||||||
|
"%v4float %sampled_image %coords12 %int_1 ConstOffset "
|
||||||
|
"%u_offsets2d",
|
||||||
|
R"([[group(0), binding(0)]] var x_10 : sampler;
|
||||||
|
|
||||||
|
[[group(2), binding(1)]] var x_20 : texture_depth_2d;)",
|
||||||
|
"textureGather(x_20, x_10, coords12, "
|
||||||
|
"vec2<i32>(vec2<u32>(3u, 4u)))"},
|
||||||
|
// OpImageGather 2DDepth Array
|
||||||
|
ImageAccessCase{"%float 2D 1 1 0 1 Unknown",
|
||||||
|
"%result = OpImageGather "
|
||||||
|
"%v4float %sampled_image %coords123 %int_1",
|
||||||
|
R"([[group(0), binding(0)]] var x_10 : sampler;
|
||||||
|
|
||||||
|
[[group(2), binding(1)]] var x_20 : texture_depth_2d_array;)",
|
||||||
|
"textureGather(x_20, x_10, coords123.xy, "
|
||||||
|
"i32(round(coords123.z)))"},
|
||||||
|
// OpImageGather 2DDepth Array ConstOffset signed
|
||||||
|
ImageAccessCase{
|
||||||
|
"%float 2D 1 1 0 1 Unknown",
|
||||||
|
"%result = OpImageGather "
|
||||||
|
"%v4float %sampled_image %coords123 %int_1 ConstOffset %offsets2d",
|
||||||
|
R"([[group(0), binding(0)]] var x_10 : sampler;
|
||||||
|
|
||||||
|
[[group(2), binding(1)]] var x_20 : texture_depth_2d_array;)",
|
||||||
|
"textureGather(x_20, x_10, coords123.xy, "
|
||||||
|
"i32(round(coords123.z)), vec2<i32>(3, 4))"},
|
||||||
|
// OpImageGather 2DDepth Array ConstOffset unsigned
|
||||||
|
ImageAccessCase{"%float 2D 1 1 0 1 Unknown",
|
||||||
|
"%result = OpImageGather "
|
||||||
|
"%v4float %sampled_image %coords123 %int_1 ConstOffset "
|
||||||
|
"%u_offsets2d",
|
||||||
|
R"([[group(0), binding(0)]] var x_10 : sampler;
|
||||||
|
|
||||||
|
[[group(2), binding(1)]] var x_20 : texture_depth_2d_array;)",
|
||||||
|
"textureGather(x_20, x_10, coords123.xy, "
|
||||||
|
"i32(round(coords123.z)), "
|
||||||
|
"vec2<i32>(vec2<u32>(3u, 4u)))"},
|
||||||
|
// OpImageGather DepthCube
|
||||||
|
ImageAccessCase{"%float Cube 1 0 0 1 Unknown",
|
||||||
|
"%result = OpImageGather "
|
||||||
|
"%v4float %sampled_image %coords123 %int_1",
|
||||||
|
R"([[group(0), binding(0)]] var x_10 : sampler;
|
||||||
|
|
||||||
|
[[group(2), binding(1)]] var x_20 : texture_depth_cube;)",
|
||||||
|
"textureGather(x_20, x_10, coords123)"},
|
||||||
|
// OpImageGather DepthCube Array
|
||||||
|
ImageAccessCase{"%float Cube 1 1 0 1 Unknown",
|
||||||
|
"%result = OpImageGather "
|
||||||
|
"%v4float %sampled_image %coords1234 %int_1",
|
||||||
|
R"([[group(0), binding(0)]] var x_10 : sampler;
|
||||||
|
|
||||||
|
[[group(2), binding(1)]] var x_20 : texture_depth_cube_array;)",
|
||||||
|
"textureGather(x_20, x_10, coords1234.xyz, "
|
||||||
|
"i32(round(coords1234.w)))"}}));
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
DISABLED_ImageDrefGather,
|
ImageDrefGather,
|
||||||
SpvParserHandleTest_SampledImageAccessTest,
|
SpvParserHandleTest_SampledImageAccessTest,
|
||||||
::testing::ValuesIn(std::vector<ImageAccessCase>{
|
::testing::ValuesIn(std::vector<ImageAccessCase>{
|
||||||
// TODO(dneto): OpImageDrefGather
|
// TODO(dneto): OpImageDrefGather 2DDepth
|
||||||
// TODO(dneto): OpImageDrefGather with ConstOffset (signed and
|
// TODO(dneto): OpImageDrefGather 2DDepth ConstOffset signed
|
||||||
// unsigned)
|
// TODO(dneto): OpImageDrefGather 2DDepth ConstOffset unsigned
|
||||||
// TODO(dneto): OpImageDrefGather with Offset (signed and unsigned)
|
// TODO(dneto): OpImageDrefGather 2DDepth Array
|
||||||
// TODO(dneto): OpImageDrefGather with Offsets (signed and unsigned)
|
// TODO(dneto): OpImageDrefGather 2DDepth Array ConstOffset signed
|
||||||
|
// TODO(dneto): OpImageDrefGather 2DDepth Array ConstOffset unsigned
|
||||||
|
// TODO(dneto): OpImageDrefGather DepthCube
|
||||||
|
// TODO(dneto): OpImageDrefGather DepthCube Array
|
||||||
}));
|
}));
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
@ -3458,21 +3604,21 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
{"%uint 2D 0 0 0 1 Unknown",
|
{"%uint 2D 0 0 0 1 Unknown",
|
||||||
"%result = OpImageFetch %v4uint %sampled_image %vf12 ConstOffset "
|
"%result = OpImageFetch %v4uint %sampled_image %vf12 ConstOffset "
|
||||||
"%the_vu12",
|
"%the_vu12",
|
||||||
"ConstOffset is only permitted for sampling operations: ",
|
"ConstOffset is only permitted for sampling, gather, or "
|
||||||
|
"depth-reference gather operations: ",
|
||||||
{}},
|
{}},
|
||||||
// ImageRead
|
// ImageRead
|
||||||
{"%uint 2D 0 0 0 2 Rgba32ui",
|
{"%uint 2D 0 0 0 2 Rgba32ui",
|
||||||
"%result = OpImageRead %v4uint %im %vu12 ConstOffset %the_vu12",
|
"%result = OpImageRead %v4uint %im %vu12 ConstOffset %the_vu12",
|
||||||
"ConstOffset is only permitted for sampling operations: ",
|
"ConstOffset is only permitted for sampling, gather, or "
|
||||||
|
"depth-reference gather operations: ",
|
||||||
{}},
|
{}},
|
||||||
// ImageWrite
|
// ImageWrite
|
||||||
{"%uint 2D 0 0 0 2 Rgba32ui",
|
{"%uint 2D 0 0 0 2 Rgba32ui",
|
||||||
"OpImageWrite %im %vu12 %vu1234 ConstOffset %the_vu12",
|
"OpImageWrite %im %vu12 %vu1234 ConstOffset %the_vu12",
|
||||||
"ConstOffset is only permitted for sampling operations: ",
|
"ConstOffset is only permitted for sampling, gather, or "
|
||||||
{}}
|
"depth-reference gather operations: ",
|
||||||
// TODO(dneto): Gather
|
{}}}));
|
||||||
// TODO(dneto): DrefGather
|
|
||||||
}));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
ConstOffset_BadDim_Errors,
|
ConstOffset_BadDim_Errors,
|
||||||
|
|
Loading…
Reference in New Issue