GLSL: workaround texture sampling with offset on depth arrays.
When calling textureSample() or textureSampleCompare() on a texture_depth_2d_array with an offset, use GLSL's
textureGradOffset() instead of textureOffset(), and explicitly
pass dFdx and dFdy of the texture coords parameter as the gradients.
Bug: 42240302
Change-Id: I8b18d832f62924b2c7d6d63c39a29e9e18ae6cbc
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/198117
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: Stephen White <senorblanco@chromium.org>
diff --git a/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc b/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc
index 4ee3b91..f4256d8 100644
--- a/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc
+++ b/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc
@@ -1480,6 +1480,7 @@
uint32_t glsl_ret_width = 4u;
bool append_depth_ref_to_coords = true;
bool is_depth = texture_type->Is<core::type::DepthTexture>();
+ bool is_array = IsTextureArray(texture_type->Dim());
switch (builtin->Fn()) {
case wgsl::BuiltinFn::kTextureSample:
@@ -1522,7 +1523,14 @@
TINT_ICE() << "Unhandled texture builtin '" << std::string(builtin->str()) << "'";
}
+ bool supplyDerivativesAsGradients = false;
if (builtin->Signature().IndexOf(core::ParameterUsage::kOffset) >= 0) {
+ if ((builtin->Fn() == wgsl::BuiltinFn::kTextureSample ||
+ builtin->Fn() == wgsl::BuiltinFn::kTextureSampleCompare) &&
+ is_depth && is_array) {
+ out << "Grad";
+ supplyDerivativesAsGradients = true;
+ }
out << "Offset";
}
@@ -1560,6 +1568,14 @@
emit_expr_as_signed(param_coords);
+ if (supplyDerivativesAsGradients) {
+ auto* coords = arg(Usage::kCoords);
+ out << ", dFdx(";
+ EmitExpression(out, coords);
+ out << "), dFdy(";
+ EmitExpression(out, coords);
+ out << ")";
+ }
for (auto usage : {Usage::kLevel, Usage::kDdx, Usage::kDdy, Usage::kSampleIndex}) {
if (auto* e = arg(usage)) {
out << ", ";
diff --git a/src/tint/lang/glsl/writer/ast_printer/builtin_texture_test.cc b/src/tint/lang/glsl/writer/ast_printer/builtin_texture_test.cc
index b384c75..c8f158b 100644
--- a/src/tint/lang/glsl/writer/ast_printer/builtin_texture_test.cc
+++ b/src/tint/lang/glsl/writer/ast_printer/builtin_texture_test.cc
@@ -154,7 +154,7 @@
case ValidTextureOverload::kSampleDepth2dArrayF32:
return R"(texture(Texture_Sampler, vec4(1.0f, 2.0f, float(3), 0.0f));)";
case ValidTextureOverload::kSampleDepth2dArrayOffsetF32:
- return R"(textureOffset(Texture_Sampler, vec4(1.0f, 2.0f, float(3), 0.0f), ivec2(4, 5));)";
+ return R"(textureGradOffset(Texture_Sampler, vec4(1.0f, 2.0f, float(3), 0.0f), dFdx(vec2(1.0f, 2.0f)), dFdy(vec2(1.0f, 2.0f)), ivec2(4, 5));)";
case ValidTextureOverload::kSampleDepthCubeF32:
return R"(texture(Texture_Sampler, vec4(1.0f, 2.0f, 3.0f, 0.0f));)";
case ValidTextureOverload::kSampleDepthCubeArrayF32:
@@ -226,7 +226,7 @@
case ValidTextureOverload::kSampleCompareDepth2dArrayF32:
return R"(texture(Texture_Sampler, vec4(1.0f, 2.0f, float(4), 3.0f));)";
case ValidTextureOverload::kSampleCompareDepth2dArrayOffsetF32:
- return R"(textureOffset(Texture_Sampler, vec4(1.0f, 2.0f, float(4u), 3.0f), ivec2(5, 6));)";
+ return R"(textureGradOffset(Texture_Sampler, vec4(1.0f, 2.0f, float(4u), 3.0f), dFdx(vec2(1.0f, 2.0f)), dFdy(vec2(1.0f, 2.0f)), ivec2(5, 6));)";
case ValidTextureOverload::kSampleCompareDepthCubeF32:
return R"(texture(Texture_Sampler, vec4(1.0f, 2.0f, 3.0f, 4.0f));)";
case ValidTextureOverload::kSampleCompareDepthCubeArrayF32:
diff --git a/test/tint/builtins/gen/literal/textureSample/4703d0.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureSample/4703d0.wgsl.expected.glsl
index 2c7c454..82e522b 100644
--- a/test/tint/builtins/gen/literal/textureSample/4703d0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureSample/4703d0.wgsl.expected.glsl
@@ -1,5 +1,3 @@
-SKIP: FAILED
-
#version 310 es
precision highp float;
precision highp int;
@@ -11,7 +9,7 @@
uniform highp sampler2DArrayShadow arg_0_arg_1;
float textureSample_4703d0() {
- float res = textureOffset(arg_0_arg_1, vec4(vec3(vec2(1.0f), float(1u)), 0.0f), ivec2(1));
+ float res = textureGradOffset(arg_0_arg_1, vec4(vec3(vec2(1.0f), float(1u)), 0.0f), dFdx(vec2(1.0f)), dFdy(vec2(1.0f)), ivec2(1));
return res;
}
@@ -23,12 +21,3 @@
fragment_main();
return;
}
-error: Error parsing GLSL shader:
-ERROR: 0:12: 'sampler' : TextureOffset does not support sampler2DArrayShadow : ES Profile
-ERROR: 0:12: '' : compilation terminated
-ERROR: 2 compilation errors. No code generated.
-
-
-
-
-tint executable returned error: exit status 1
diff --git a/test/tint/builtins/gen/literal/textureSample/60bf45.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureSample/60bf45.wgsl.expected.glsl
index 53b2428..a67ca71 100644
--- a/test/tint/builtins/gen/literal/textureSample/60bf45.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureSample/60bf45.wgsl.expected.glsl
@@ -1,5 +1,3 @@
-SKIP: FAILED
-
#version 310 es
precision highp float;
precision highp int;
@@ -11,7 +9,7 @@
uniform highp sampler2DArrayShadow arg_0_arg_1;
float textureSample_60bf45() {
- float res = textureOffset(arg_0_arg_1, vec4(vec3(vec2(1.0f), float(1)), 0.0f), ivec2(1));
+ float res = textureGradOffset(arg_0_arg_1, vec4(vec3(vec2(1.0f), float(1)), 0.0f), dFdx(vec2(1.0f)), dFdy(vec2(1.0f)), ivec2(1));
return res;
}
@@ -23,12 +21,3 @@
fragment_main();
return;
}
-error: Error parsing GLSL shader:
-ERROR: 0:12: 'sampler' : TextureOffset does not support sampler2DArrayShadow : ES Profile
-ERROR: 0:12: '' : compilation terminated
-ERROR: 2 compilation errors. No code generated.
-
-
-
-
-tint executable returned error: exit status 1
diff --git a/test/tint/builtins/gen/literal/textureSampleCompare/7b5025.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureSampleCompare/7b5025.wgsl.expected.glsl
index f009aa4..a439863 100644
--- a/test/tint/builtins/gen/literal/textureSampleCompare/7b5025.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureSampleCompare/7b5025.wgsl.expected.glsl
@@ -1,5 +1,3 @@
-SKIP: FAILED
-
#version 310 es
precision highp float;
precision highp int;
@@ -11,7 +9,7 @@
uniform highp sampler2DArrayShadow arg_0_arg_1;
float textureSampleCompare_7b5025() {
- float res = textureOffset(arg_0_arg_1, vec4(vec3(vec2(1.0f), float(1u)), 1.0f), ivec2(1));
+ float res = textureGradOffset(arg_0_arg_1, vec4(vec3(vec2(1.0f), float(1u)), 1.0f), dFdx(vec2(1.0f)), dFdy(vec2(1.0f)), ivec2(1));
return res;
}
@@ -23,12 +21,3 @@
fragment_main();
return;
}
-error: Error parsing GLSL shader:
-ERROR: 0:12: 'sampler' : TextureOffset does not support sampler2DArrayShadow : ES Profile
-ERROR: 0:12: '' : compilation terminated
-ERROR: 2 compilation errors. No code generated.
-
-
-
-
-tint executable returned error: exit status 1
diff --git a/test/tint/builtins/gen/literal/textureSampleCompare/af1051.wgsl.expected.glsl b/test/tint/builtins/gen/literal/textureSampleCompare/af1051.wgsl.expected.glsl
index 28b6b19..e1d4652 100644
--- a/test/tint/builtins/gen/literal/textureSampleCompare/af1051.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/textureSampleCompare/af1051.wgsl.expected.glsl
@@ -1,5 +1,3 @@
-SKIP: FAILED
-
#version 310 es
precision highp float;
precision highp int;
@@ -11,7 +9,7 @@
uniform highp sampler2DArrayShadow arg_0_arg_1;
float textureSampleCompare_af1051() {
- float res = textureOffset(arg_0_arg_1, vec4(vec3(vec2(1.0f), float(1)), 1.0f), ivec2(1));
+ float res = textureGradOffset(arg_0_arg_1, vec4(vec3(vec2(1.0f), float(1)), 1.0f), dFdx(vec2(1.0f)), dFdy(vec2(1.0f)), ivec2(1));
return res;
}
@@ -23,12 +21,3 @@
fragment_main();
return;
}
-error: Error parsing GLSL shader:
-ERROR: 0:12: 'sampler' : TextureOffset does not support sampler2DArrayShadow : ES Profile
-ERROR: 0:12: '' : compilation terminated
-ERROR: 2 compilation errors. No code generated.
-
-
-
-
-tint executable returned error: exit status 1
diff --git a/test/tint/builtins/gen/var/textureSample/4703d0.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureSample/4703d0.wgsl.expected.glsl
index f9c5dc3..19abef6 100644
--- a/test/tint/builtins/gen/var/textureSample/4703d0.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureSample/4703d0.wgsl.expected.glsl
@@ -1,5 +1,3 @@
-SKIP: FAILED
-
#version 310 es
precision highp float;
precision highp int;
@@ -13,7 +11,7 @@
float textureSample_4703d0() {
vec2 arg_2 = vec2(1.0f);
uint arg_3 = 1u;
- float res = textureOffset(arg_0_arg_1, vec4(vec3(arg_2, float(arg_3)), 0.0f), ivec2(1));
+ float res = textureGradOffset(arg_0_arg_1, vec4(vec3(arg_2, float(arg_3)), 0.0f), dFdx(arg_2), dFdy(arg_2), ivec2(1));
return res;
}
@@ -25,12 +23,3 @@
fragment_main();
return;
}
-error: Error parsing GLSL shader:
-ERROR: 0:14: 'sampler' : TextureOffset does not support sampler2DArrayShadow : ES Profile
-ERROR: 0:14: '' : compilation terminated
-ERROR: 2 compilation errors. No code generated.
-
-
-
-
-tint executable returned error: exit status 1
diff --git a/test/tint/builtins/gen/var/textureSample/60bf45.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureSample/60bf45.wgsl.expected.glsl
index b3e933f..8dce77b 100644
--- a/test/tint/builtins/gen/var/textureSample/60bf45.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureSample/60bf45.wgsl.expected.glsl
@@ -1,5 +1,3 @@
-SKIP: FAILED
-
#version 310 es
precision highp float;
precision highp int;
@@ -13,7 +11,7 @@
float textureSample_60bf45() {
vec2 arg_2 = vec2(1.0f);
int arg_3 = 1;
- float res = textureOffset(arg_0_arg_1, vec4(vec3(arg_2, float(arg_3)), 0.0f), ivec2(1));
+ float res = textureGradOffset(arg_0_arg_1, vec4(vec3(arg_2, float(arg_3)), 0.0f), dFdx(arg_2), dFdy(arg_2), ivec2(1));
return res;
}
@@ -25,12 +23,3 @@
fragment_main();
return;
}
-error: Error parsing GLSL shader:
-ERROR: 0:14: 'sampler' : TextureOffset does not support sampler2DArrayShadow : ES Profile
-ERROR: 0:14: '' : compilation terminated
-ERROR: 2 compilation errors. No code generated.
-
-
-
-
-tint executable returned error: exit status 1
diff --git a/test/tint/builtins/gen/var/textureSampleCompare/7b5025.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureSampleCompare/7b5025.wgsl.expected.glsl
index 2dbab2a..0b00a71c1 100644
--- a/test/tint/builtins/gen/var/textureSampleCompare/7b5025.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureSampleCompare/7b5025.wgsl.expected.glsl
@@ -1,5 +1,3 @@
-SKIP: FAILED
-
#version 310 es
precision highp float;
precision highp int;
@@ -14,7 +12,7 @@
vec2 arg_2 = vec2(1.0f);
uint arg_3 = 1u;
float arg_4 = 1.0f;
- float res = textureOffset(arg_0_arg_1, vec4(vec3(arg_2, float(arg_3)), arg_4), ivec2(1));
+ float res = textureGradOffset(arg_0_arg_1, vec4(vec3(arg_2, float(arg_3)), arg_4), dFdx(arg_2), dFdy(arg_2), ivec2(1));
return res;
}
@@ -26,12 +24,3 @@
fragment_main();
return;
}
-error: Error parsing GLSL shader:
-ERROR: 0:15: 'sampler' : TextureOffset does not support sampler2DArrayShadow : ES Profile
-ERROR: 0:15: '' : compilation terminated
-ERROR: 2 compilation errors. No code generated.
-
-
-
-
-tint executable returned error: exit status 1
diff --git a/test/tint/builtins/gen/var/textureSampleCompare/af1051.wgsl.expected.glsl b/test/tint/builtins/gen/var/textureSampleCompare/af1051.wgsl.expected.glsl
index 395423e..fede927 100644
--- a/test/tint/builtins/gen/var/textureSampleCompare/af1051.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/textureSampleCompare/af1051.wgsl.expected.glsl
@@ -1,5 +1,3 @@
-SKIP: FAILED
-
#version 310 es
precision highp float;
precision highp int;
@@ -14,7 +12,7 @@
vec2 arg_2 = vec2(1.0f);
int arg_3 = 1;
float arg_4 = 1.0f;
- float res = textureOffset(arg_0_arg_1, vec4(vec3(arg_2, float(arg_3)), arg_4), ivec2(1));
+ float res = textureGradOffset(arg_0_arg_1, vec4(vec3(arg_2, float(arg_3)), arg_4), dFdx(arg_2), dFdy(arg_2), ivec2(1));
return res;
}
@@ -26,12 +24,3 @@
fragment_main();
return;
}
-error: Error parsing GLSL shader:
-ERROR: 0:15: 'sampler' : TextureOffset does not support sampler2DArrayShadow : ES Profile
-ERROR: 0:15: '' : compilation terminated
-ERROR: 2 compilation errors. No code generated.
-
-
-
-
-tint executable returned error: exit status 1
diff --git a/test/tint/unittest/reader/spirv/ImageSampleDrefImplicitLod_SpvParserHandleTest_SampledImageAccessTest_Variable_3.spvasm.expected.glsl b/test/tint/unittest/reader/spirv/ImageSampleDrefImplicitLod_SpvParserHandleTest_SampledImageAccessTest_Variable_3.spvasm.expected.glsl
deleted file mode 100644
index 195d058..0000000
--- a/test/tint/unittest/reader/spirv/ImageSampleDrefImplicitLod_SpvParserHandleTest_SampledImageAccessTest_Variable_3.spvasm.expected.glsl
+++ /dev/null
@@ -1,51 +0,0 @@
-SKIP: FAILED
-
-#version 310 es
-precision highp float;
-precision highp int;
-
-int tint_ftoi(float v) {
- return ((v <= 2147483520.0f) ? ((v < -2147483648.0f) ? (-2147483647 - 1) : int(v)) : 2147483647);
-}
-
-uniform highp sampler2DArrayShadow x_20_x_10;
-
-void main_1() {
- float f1 = 1.0f;
- vec2 vf12 = vec2(1.0f, 2.0f);
- vec2 vf21 = vec2(2.0f, 1.0f);
- vec3 vf123 = vec3(1.0f, 2.0f, 3.0f);
- vec4 vf1234 = vec4(1.0f, 2.0f, 3.0f, 4.0f);
- int i1 = 1;
- ivec2 vi12 = ivec2(1, 2);
- ivec3 vi123 = ivec3(1, 2, 3);
- ivec4 vi1234 = ivec4(1, 2, 3, 4);
- uint u1 = 1u;
- uvec2 vu12 = uvec2(1u, 2u);
- uvec3 vu123 = uvec3(1u, 2u, 3u);
- uvec4 vu1234 = uvec4(1u, 2u, 3u, 4u);
- float coords1 = 1.0f;
- vec2 coords12 = vf12;
- vec3 coords123 = vf123;
- vec4 coords1234 = vf1234;
- float x_79 = textureOffset(x_20_x_10, vec4(vec3(coords123.xy, float(tint_ftoi(round(coords123.z)))), 0.20000000298023223877f), ivec2(3, 4));
- return;
-}
-
-void tint_symbol() {
- main_1();
-}
-
-void main() {
- tint_symbol();
- return;
-}
-error: Error parsing GLSL shader:
-ERROR: 0:29: 'sampler' : TextureOffset does not support sampler2DArrayShadow : ES Profile
-ERROR: 0:29: '' : compilation terminated
-ERROR: 2 compilation errors. No code generated.
-
-
-
-
-tint executable returned error: exit status 1