spirv-reader: float array layer conversion uses round-to-even

Vulkan requires round-to-nearest when converting from a float
coordinate to an integer array layer. It prefers round-to-nearest-even.
Use round-to-nearest-even, instad of relying on the rounding behaviour
of the i32(f32) overload.

Fixes: tint:1316
Change-Id: I43624e25e8ea27d3a6e04841a911bbb9418810d0
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/70343
Auto-Submit: David Neto <dneto@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
David Neto 2021-11-22 10:14:36 +00:00 committed by Tint LUCI CQ
parent 1bf5af25ad
commit c87dc10ce3
2 changed files with 34 additions and 27 deletions

View File

@ -5697,9 +5697,16 @@ ast::ExpressionList FunctionEmitter::MakeCoordinateOperandsForImageAccess(
result.push_back(prefix_swizzle_expr());
// Now get the array index.
const ast::Expression* array_index = create<ast::MemberAccessorExpression>(
Source{}, raw_coords.expr, Swizzle(num_axes));
// Convert it to a signed integer type, if needed
const ast::Expression* array_index =
builder_.MemberAccessor(raw_coords.expr, Swizzle(num_axes));
if (component_type->IsFloatScalar()) {
// When converting from a float array layer to integer, Vulkan requires
// round-to-nearest, with preference for round-to-nearest-even.
// But i32(f32) in WGSL has unspecified rounding mode, so we have to
// explicitly specify the rounding.
array_index = builder_.Call("round", array_index);
}
// Convert it to a signed integer type, if needed.
result.push_back(ToI32({component_type, array_index}).expr);
} else {
if (num_coords_supplied == num_coords_required && !is_proj) {

View File

@ -1607,7 +1607,7 @@ INSTANTIATE_TEST_SUITE_P(
R"([[group(0), binding(0)]] var x_10 : sampler;
[[group(2), binding(1)]] var x_20 : texture_2d_array<f32>;)",
"textureSample(x_20, x_10, coords123.xy, i32(coords123.z))"},
"textureSample(x_20, x_10, coords123.xy, i32(round(coords123.z)))"},
// OpImageSampleImplicitLod with ConstOffset
ImageAccessCase{
@ -1627,7 +1627,7 @@ INSTANTIATE_TEST_SUITE_P(
R"([[group(0), binding(0)]] var x_10 : sampler;
[[group(2), binding(1)]] var x_20 : texture_2d_array<f32>;)",
R"(textureSample(x_20, x_10, coords123.xy, i32(coords123.z), vec2<i32>(3, 4)))"},
R"(textureSample(x_20, x_10, coords123.xy, i32(round(coords123.z)), vec2<i32>(3, 4)))"},
// OpImageSampleImplicitLod with Bias
ImageAccessCase{"%float 2D 0 0 0 1 Unknown",
@ -1646,7 +1646,7 @@ INSTANTIATE_TEST_SUITE_P(
R"([[group(0), binding(0)]] var x_10 : sampler;
[[group(2), binding(1)]] var x_20 : texture_2d_array<f32>;)",
R"(textureSampleBias(x_20, x_10, coords123.xy, i32(coords123.z), 7.0))"},
R"(textureSampleBias(x_20, x_10, coords123.xy, i32(round(coords123.z)), 7.0))"},
// OpImageSampleImplicitLod with Bias and signed ConstOffset
ImageAccessCase{
@ -1679,7 +1679,7 @@ INSTANTIATE_TEST_SUITE_P(
R"([[group(0), binding(0)]] var x_10 : sampler;
[[group(2), binding(1)]] var x_20 : texture_2d_array<f32>;)",
R"(textureSampleBias(x_20, x_10, coords123.xy, i32(coords123.z), 7.0, vec2<i32>(3, 4))"}));
R"(textureSampleBias(x_20, x_10, coords123.xy, i32(round(coords123.z)), 7.0, vec2<i32>(3, 4))"}));
INSTANTIATE_TEST_SUITE_P(
// This test shows the use of a sampled image used with both regular
@ -1730,7 +1730,7 @@ INSTANTIATE_TEST_SUITE_P(
R"([[group(0), binding(0)]] var x_10 : sampler_comparison;
[[group(2), binding(1)]] var x_20 : texture_depth_2d_array;)",
R"(textureSampleCompare(x_20, x_10, coords123.xy, i32(coords123.z), 0.200000003))"},
R"(textureSampleCompare(x_20, x_10, coords123.xy, i32(round(coords123.z)), 0.200000003))"},
// ImageSampleDrefImplicitLod with ConstOffset
ImageAccessCase{
"%float 2D 0 0 0 1 Unknown",
@ -1749,7 +1749,7 @@ INSTANTIATE_TEST_SUITE_P(
R"([[group(0), binding(0)]] var x_10 : sampler_comparison;
[[group(2), binding(1)]] var x_20 : texture_depth_2d_array;)",
R"(textureSampleCompare(x_20, x_10, coords123.xy, i32(coords123.z), 0.200000003, vec2<i32>(3, 4)))"}));
R"(textureSampleCompare(x_20, x_10, coords123.xy, i32(round(coords123.z)), 0.200000003, vec2<i32>(3, 4)))"}));
INSTANTIATE_TEST_SUITE_P(
ImageSampleDrefExplicitLod,
@ -1775,7 +1775,7 @@ INSTANTIATE_TEST_SUITE_P(
R"([[group(0), binding(0)]] var x_10 : sampler_comparison;
[[group(2), binding(1)]] var x_20 : texture_depth_2d_array;)",
R"(textureSampleCompareLevel(x_20, x_10, coords123.xy, i32(coords123.z), 0.200000003))"},
R"(textureSampleCompareLevel(x_20, x_10, coords123.xy, i32(round(coords123.z)), 0.200000003))"},
// 2D, ConstOffset
ImageAccessCase{
"%float 2D 1 0 0 1 Unknown",
@ -1796,7 +1796,7 @@ INSTANTIATE_TEST_SUITE_P(
R"([[group(0), binding(0)]] var x_10 : sampler_comparison;
[[group(2), binding(1)]] var x_20 : texture_depth_2d_array;)",
R"(textureSampleCompareLevel(x_20, x_10, coords123.xy, i32(coords123.z), 0.200000003, vec2<i32>(3, 4)))"},
R"(textureSampleCompareLevel(x_20, x_10, coords123.xy, i32(round(coords123.z)), 0.200000003, vec2<i32>(3, 4)))"},
// Cube
ImageAccessCase{
"%float Cube 1 0 0 1 Unknown",
@ -1814,7 +1814,7 @@ INSTANTIATE_TEST_SUITE_P(
R"([[group(0), binding(0)]] var x_10 : sampler_comparison;
[[group(2), binding(1)]] var x_20 : texture_depth_cube_array;)",
R"(textureSampleCompareLevel(x_20, x_10, coords1234.xyz, i32(coords1234.w), 0.200000003))"}));
R"(textureSampleCompareLevel(x_20, x_10, coords1234.xyz, i32(round(coords1234.w)), 0.200000003))"}));
INSTANTIATE_TEST_SUITE_P(
ImageSampleExplicitLod_UsingLod,
@ -1838,7 +1838,7 @@ INSTANTIATE_TEST_SUITE_P(
R"([[group(0), binding(0)]] var x_10 : sampler;
[[group(2), binding(1)]] var x_20 : texture_2d_array<f32>;)",
R"(textureSampleLevel(x_20, x_10, coords123.xy, i32(coords123.z), 0.0))"},
R"(textureSampleLevel(x_20, x_10, coords123.xy, i32(round(coords123.z)), 0.0))"},
// OpImageSampleExplicitLod - using Lod and ConstOffset
ImageAccessCase{
@ -1872,7 +1872,7 @@ INSTANTIATE_TEST_SUITE_P(
R"([[group(0), binding(0)]] var x_10 : sampler;
[[group(2), binding(1)]] var x_20 : texture_2d_array<f32>;)",
R"(textureSampleLevel(x_20, x_10, coords123.xy, i32(coords123.z), 0.0, vec2<i32>(3, 4)))"}));
R"(textureSampleLevel(x_20, x_10, coords123.xy, i32(round(coords123.z)), 0.0, vec2<i32>(3, 4)))"}));
INSTANTIATE_TEST_SUITE_P(
ImageSampleExplicitLod_UsingGrad,
@ -1897,7 +1897,7 @@ INSTANTIATE_TEST_SUITE_P(
R"([[group(0), binding(0)]] var x_10 : sampler;
[[group(2), binding(1)]] var x_20 : texture_2d_array<f32>;)",
R"(textureSampleGrad(x_20, x_10, coords123.xy, i32(coords123.z), vf12, vf21))"},
R"(textureSampleGrad(x_20, x_10, coords123.xy, i32(round(coords123.z)), vf12, vf21))"},
// OpImageSampleExplicitLod - using Grad and ConstOffset
ImageAccessCase{
@ -1930,7 +1930,7 @@ INSTANTIATE_TEST_SUITE_P(
R"([[group(0), binding(0)]] var x_10 : sampler;
[[group(2), binding(1)]] var x_20 : texture_2d_array<f32>;)",
R"(textureSampleGrad(x_20, x_10, coords123.xy, i32(coords123.z), vf12, vf21, vec2<i32>(3, 4)))"},
R"(textureSampleGrad(x_20, x_10, coords123.xy, i32(round(coords123.z)), vf12, vf21, vec2<i32>(3, 4)))"},
// OpImageSampleExplicitLod arrayed - using Grad and unsigned
// ConstOffset
@ -1942,7 +1942,7 @@ INSTANTIATE_TEST_SUITE_P(
R"([[group(0), binding(0)]] var x_10 : sampler;
[[group(2), binding(1)]] var x_20 : texture_2d_array<f32>;)",
R"(textureSampleGrad(x_20, x_10, coords123.xy, i32(coords123.z), vf12, vf21, vec2<i32>(vec2<u32>(3u, 4u))))"}));
R"(textureSampleGrad(x_20, x_10, coords123.xy, i32(round(coords123.z)), vf12, vf21, vec2<i32>(vec2<u32>(3u, 4u))))"}));
// Test crbug.com/378:
// In WGSL, sampling from depth texture with explicit level of detail
@ -3088,17 +3088,17 @@ INSTANTIATE_TEST_SUITE_P(Good_1DArray,
"%result = OpImageSampleImplicitLod %v4float "
"%sampled_image %vf12",
"",
{"vf12.x", "i32(vf12.y)"}},
{"vf12.x", "i32(round(vf12.y))"}},
{"%float 1D 0 1 0 1 Unknown",
"%result = OpImageSampleImplicitLod %v4float "
"%sampled_image %vf123", // one excess arg
"",
{"vf123.x", "i32(vf123.y)"}},
{"vf123.x", "i32(round(vf123.y))"}},
{"%float 1D 0 1 0 1 Unknown",
"%result = OpImageSampleImplicitLod %v4float "
"%sampled_image %vf1234", // two excess args
"",
{"vf1234.x", "i32(vf1234.y)"}}}));
{"vf1234.x", "i32(round(vf1234.y))"}}}));
INSTANTIATE_TEST_SUITE_P(Good_2D,
SpvParserHandleTest_ImageCoordsTest,
@ -3126,12 +3126,12 @@ INSTANTIATE_TEST_SUITE_P(Good_2DArray,
"%result = OpImageSampleImplicitLod %v4float "
"%sampled_image %vf123",
"",
{"vf123.xy", "i32(vf123.z)"}},
{"vf123.xy", "i32(round(vf123.z))"}},
{"%float 2D 0 1 0 1 Unknown",
"%result = OpImageSampleImplicitLod %v4float "
"%sampled_image %vf1234", // one excess arg
"",
{"vf1234.xy", "i32(vf1234.z)"}}}));
{"vf1234.xy", "i32(round(vf1234.z))"}}}));
INSTANTIATE_TEST_SUITE_P(Good_3D,
SpvParserHandleTest_ImageCoordsTest,
@ -3175,7 +3175,7 @@ INSTANTIATE_TEST_SUITE_P(Good_CubeArray,
"%v4float "
"%sampled_image %vf1234",
"",
{"vf1234.xyz", "i32(vf1234.w)"}}}));
{"vf1234.xyz", "i32(round(vf1234.w))"}}}));
INSTANTIATE_TEST_SUITE_P(
PreserveFloatCoords_NonArrayed,
@ -3228,23 +3228,23 @@ INSTANTIATE_TEST_SUITE_P(
{"%float 2D 0 1 0 1 Unknown",
"%result = OpImageSampleImplicitLod %v4float %sampled_image %vf123",
"",
{"vf123.xy", "i32(vf123.z)"}},
{"vf123.xy", "i32(round(vf123.z))"}},
{"%float 2D 0 1 0 1 Unknown",
"%result = OpImageSampleExplicitLod %v4float %sampled_image %vf123 "
"Lod %f1",
"",
{"vf123.xy", "i32(vf123.z)"}},
{"vf123.xy", "i32(round(vf123.z))"}},
{"%float 2D 1 1 0 1 Unknown",
"%result = OpImageSampleDrefImplicitLod %float %sampled_image "
"%vf123 %depth",
"",
{"vf123.xy", "i32(vf123.z)"}},
{"vf123.xy", "i32(round(vf123.z))"}},
{"%float 2D 1 1 0 1 Unknown",
"%result = OpImageSampleDrefExplicitLod %float %sampled_image "
"%vf123 %depth Lod %float_0",
"",
{"vf123.xy", "i32(vf123.z)"}}}));
{"vf123.xy", "i32(round(vf123.z))"}}}));
INSTANTIATE_TEST_SUITE_P(
PreserveIntCoords_NonArrayed,