Skip to content

Commit

Permalink
GLSL: fix shadow samplers, and textures generally.
Browse files Browse the repository at this point in the history
1) Append "Shadow" to samplers representing depth textures.
2) Sampling a depth texture returns f32, not vec4<f32>
3) Sampling a depth texture requires a Dref parameter, so we must
   generate one if none is provided.
4) GLSL requires Dref to be appended to the texture coordinates vector,
   *unless* it's a samplerCubeArrayShadow, since this would require vec5.
   In that case, it's passed as a separate parameter.
5) GLSL's textureGather() with a depth sampler always requires a refZ
   parameter, so provide zero to emulate WGSL's compare-less textureGather().
6) texelFetch() does not support depth textures, so this will have to be
   validated out.
7) textureOffset() does not support sampler2DArrayShadow in GLES, so this will
   have to be validated out.

Bug: tint:1298
Change-Id: Idaebe89cac6c1ec97c50a361b1d3aa3b84fb6c12
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/78760
Reviewed-by: Ben Clayton <[email protected]>
Kokoro: Kokoro <[email protected]>
Commit-Queue: Stephen White <[email protected]>
  • Loading branch information
SenorBlanco authored and Tint LUCI CQ committed Feb 2, 2022
1 parent b68e8aa commit d4d7153
Show file tree
Hide file tree
Showing 87 changed files with 434 additions and 1,077 deletions.
71 changes: 61 additions & 10 deletions src/writer/glsl/generator_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1229,11 +1229,15 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
}

uint32_t glsl_ret_width = 4u;
bool is_depth = texture_type->Is<sem::DepthTexture>();

switch (intrinsic->Type()) {
case sem::IntrinsicType::kTextureSample:
case sem::IntrinsicType::kTextureSampleBias:
out << "texture";
if (is_depth) {
glsl_ret_width = 1u;
}
break;
case sem::IntrinsicType::kTextureSampleLevel:
out << "textureLod";
Expand Down Expand Up @@ -1283,19 +1287,51 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,

if (auto* array_index = arg(Usage::kArrayIndex)) {
// Array index needs to be appended to the coordinates.
auto* packed = AppendVector(&builder_, param_coords, array_index);
if (!EmitExpression(out, packed->Declaration())) {
return false;
}
} else {
if (!EmitExpression(out, param_coords)) {
return false;
param_coords =
AppendVector(&builder_, param_coords, array_index)->Declaration();
}
bool is_cube_array = texture_type->dim() == ast::TextureDimension::kCubeArray;

// GLSL requires Dref to be appended to the coordinates, *unless* it's
// samplerCubeArrayShadow, in which case it will be handled as a separate
// parameter [1].
if (is_depth && !is_cube_array) {
if (auto* depth_ref = arg(Usage::kDepthRef)) {
param_coords =
AppendVector(&builder_, param_coords, depth_ref)->Declaration();
} else if (intrinsic->Type() == sem::IntrinsicType::kTextureSample) {
// Sampling a depth texture in GLSL always requires a depth reference, so
// append zero here.
auto* f32 = builder_.create<sem::F32>();
auto* zero = builder_.Expr(0.0f);
auto* stmt = builder_.Sem().Get(param_coords)->Stmt();
auto* sem_zero =
builder_.create<sem::Expression>(zero, f32, stmt, sem::Constant{});
builder_.Sem().Add(zero, sem_zero);
param_coords = AppendVector(&builder_, param_coords, zero)->Declaration();
}
}

if (!EmitExpression(out, param_coords)) {
return false;
}

for (auto usage : {Usage::kLevel, Usage::kDdx, Usage::kDdy,
Usage::kSampleIndex, Usage::kValue}) {
if (auto* e = arg(usage)) {
out << ", ";
if (!EmitExpression(out, e)) {
return false;
}
}
}

for (auto usage : {Usage::kDepthRef, Usage::kLevel, Usage::kDdx, Usage::kDdy,
Usage::kSampleIndex, Usage::kOffset, Usage::kBias,
Usage::kComponent, Usage::kValue}) {
// GLSL's textureGather always requires a refZ parameter.
if (is_depth && intrinsic->Type() == sem::IntrinsicType::kTextureGather) {
out << ", 0.0";
}

for (auto usage : {Usage::kOffset, Usage::kComponent, Usage::kBias}) {
if (auto* e = arg(usage)) {
out << ", ";
if (!EmitExpression(out, e)) {
Expand All @@ -1304,6 +1340,18 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& out,
}
}

// [1] samplerCubeArrayShadow requires a separate depthRef parameter
if (is_depth && is_cube_array) {
if (auto* e = arg(Usage::kDepthRef)) {
out << ", ";
if (!EmitExpression(out, e)) {
return false;
}
} else if (intrinsic->Type() == sem::IntrinsicType::kTextureSample) {
out << ", 0.0f";
}
}

out << ")";

if (intrinsic->ReturnType()->Is<sem::Void>()) {
Expand Down Expand Up @@ -2377,6 +2425,9 @@ bool GeneratorImpl::EmitType(std::ostream& out,
<< "unexpected TextureDimension " << tex->dim();
return false;
}
if (tex->Is<sem::DepthTexture>()) {
out << "Shadow";
}
} else if (type->Is<sem::U32>()) {
out << "uint";
} else if (auto* vec = type->As<sem::Vector>()) {
Expand Down
50 changes: 25 additions & 25 deletions src/writer/glsl/generator_impl_intrinsic_texture_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,27 +76,27 @@ ExpectedResult expected_texture_overload(
case ValidTextureOverload::kGatherCubeArrayF32:
return R"(textureGather(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(4)), 0))";
case ValidTextureOverload::kGatherDepth2dF32:
return R"(textureGather(tint_symbol_sampler, vec2(1.0f, 2.0f)))";
return R"(textureGather(tint_symbol_sampler, vec2(1.0f, 2.0f), 0.0))";
case ValidTextureOverload::kGatherDepth2dOffsetF32:
return R"(textureGatherOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), ivec2(3, 4)))";
return R"(textureGatherOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), 0.0, ivec2(3, 4))";
case ValidTextureOverload::kGatherDepth2dArrayF32:
return R"(textureGather(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3))))";
return R"(textureGather(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), 0.0))";
case ValidTextureOverload::kGatherDepth2dArrayOffsetF32:
return R"(textureGatherOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), ivec2(4, 5)))";
return R"(textureGatherOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), 0.0, ivec2(4, 5)))";
case ValidTextureOverload::kGatherDepthCubeF32:
return R"(textureGather(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f)))";
return R"(textureGather(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), 0.0))";
case ValidTextureOverload::kGatherDepthCubeArrayF32:
return R"(textureGather(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(4))))";
return R"(textureGather(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(4)), 0.0))";
case ValidTextureOverload::kGatherCompareDepth2dF32:
return R"(textureGather(tint_symbol_sampler, vec2(1.0f, 2.0f), 3.0f))";
return R"(textureGather(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f))";
case ValidTextureOverload::kGatherCompareDepth2dOffsetF32:
return R"(textureGatherOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5)))";
return R"(textureGatherOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), ivec2(4, 5)))";
case ValidTextureOverload::kGatherCompareDepth2dArrayF32:
return R"(textureGather(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), 4.0f))";
return R"(textureGather(tint_symbol_sampler, vec4(1.0f, 2.0f, float(3), 4.0f)))";
case ValidTextureOverload::kGatherCompareDepth2dArrayOffsetF32:
return R"(textureGatherOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), 4.0f, ivec2(5, 6)))";
return R"(textureGatherOffset(tint_symbol_sampler, vec4(1.0f, 2.0f, float(3), 4.0f), ivec2(5, 6)))";
case ValidTextureOverload::kGatherCompareDepthCubeF32:
return R"(textureGather(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), 4.0f))";
return R"(textureGather(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, 4.0f)))";
case ValidTextureOverload::kGatherCompareDepthCubeArrayF32:
return R"(textureGather(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f))";
case ValidTextureOverload::kNumLayers2dArray:
Expand Down Expand Up @@ -136,17 +136,17 @@ ExpectedResult expected_texture_overload(
case ValidTextureOverload::kSampleCubeArrayF32:
return R"(texture(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(4)));)";
case ValidTextureOverload::kSampleDepth2dF32:
return R"(texture(tint_symbol_sampler, vec2(1.0f, 2.0f)).x;)";
return R"(texture(tint_symbol_sampler, vec3(1.0f, 2.0f, 0.0f));)";
case ValidTextureOverload::kSampleDepth2dOffsetF32:
return R"(textureOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), ivec2(3, 4)).x;)";
return R"(textureOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, 0.0f), ivec2(3, 4));)";
case ValidTextureOverload::kSampleDepth2dArrayF32:
return R"(texture(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3))).x;)";
return R"(texture(tint_symbol_sampler, vec4(1.0f, 2.0f, float(3), 0.0f));)";
case ValidTextureOverload::kSampleDepth2dArrayOffsetF32:
return R"(textureOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, float(3)), ivec2(4, 5)).x;)";
return R"(textureOffset(tint_symbol_sampler, vec4(1.0f, 2.0f, float(3), 0.0f), ivec2(4, 5));)";
case ValidTextureOverload::kSampleDepthCubeF32:
return R"(texture(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f)).x;)";
return R"(texture(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, 0.0f));)";
case ValidTextureOverload::kSampleDepthCubeArrayF32:
return R"(texture(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(4))).x;)";
return R"(texture(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(4)), 0.0f);)";
case ValidTextureOverload::kSampleBias2dF32:
return R"(texture(tint_symbol_sampler, vec2(1.0f, 2.0f), 3.0f);)";
case ValidTextureOverload::kSampleBias2dOffsetF32:
Expand Down Expand Up @@ -208,23 +208,23 @@ ExpectedResult expected_texture_overload(
case ValidTextureOverload::kSampleGradCubeArrayF32:
return R"(textureGrad(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(4)), vec3(5.0f, 6.0f, 7.0f), vec3(8.0f, 9.0f, 10.0f));)";
case ValidTextureOverload::kSampleCompareDepth2dF32:
return R"(texture(tint_symbol_sampler, vec2(1.0f, 2.0f), 3.0f);)";
return R"(texture(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f));)";
case ValidTextureOverload::kSampleCompareDepth2dOffsetF32:
return R"(textureOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
return R"(textureOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), ivec2(4, 5));)";
case ValidTextureOverload::kSampleCompareDepth2dArrayF32:
return R"(texture(tint_symbol_sampler, vec3(1.0f, 2.0f, float(4)), 3.0f);)";
return R"(texture(tint_symbol_sampler, vec4(1.0f, 2.0f, float(4), 3.0f));)";
case ValidTextureOverload::kSampleCompareDepth2dArrayOffsetF32:
return R"(textureOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, float(4)), 3.0f, ivec2(5, 6));)";
return R"(textureOffset(tint_symbol_sampler, vec4(1.0f, 2.0f, float(4), 3.0f), ivec2(5, 6));)";
case ValidTextureOverload::kSampleCompareDepthCubeF32:
return R"(texture(tint_symbol_sampler, vec3(1.0f, 2.0f, 3.0f), 4.0f);)";
return R"(texture(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, 4.0f));)";
case ValidTextureOverload::kSampleCompareDepthCubeArrayF32:
return R"(texture(tint_symbol_sampler, vec4(1.0f, 2.0f, 3.0f, float(4)), 5.0f);)";
case ValidTextureOverload::kSampleCompareLevelDepth2dF32:
return R"(texture(tint_symbol_sampler, vec2(1.0f, 2.0f), 3.0f);)";
return R"(yyytexture(tint_symbol_sampler, vec2(1.0f, 2.0f), 3.0f);)";
case ValidTextureOverload::kSampleCompareLevelDepth2dOffsetF32:
return R"(textureOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
return R"(yyytextureOffset(tint_symbol_sampler, vec2(1.0f, 2.0f), 3.0f, ivec2(4, 5));)";
case ValidTextureOverload::kSampleCompareLevelDepth2dArrayF32:
return R"(texture(tint_symbol_sampler, vec3(1.0f, 2.0f, float(4)), 3.0f);)";
return R"(texture(tint_symbol_sampler, vec4(1.0f, 2.0f, float(4)), 3.0f);)";
case ValidTextureOverload::kSampleCompareLevelDepth2dArrayOffsetF32:
return R"(textureOffset(tint_symbol_sampler, vec3(1.0f, 2.0f, float(4)), 3.0f, ivec2(5, 6));)";
case ValidTextureOverload::kSampleCompareLevelDepthCubeF32:
Expand Down
15 changes: 8 additions & 7 deletions src/writer/glsl/generator_impl_type_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -330,13 +330,14 @@ TEST_P(GlslDepthTexturesTest, Emit) {
INSTANTIATE_TEST_SUITE_P(
GlslGeneratorImplTest_Type,
GlslDepthTexturesTest,
testing::Values(
GlslDepthTextureData{ast::TextureDimension::k2d, "sampler2D tex;"},
GlslDepthTextureData{ast::TextureDimension::k2dArray,
"sampler2DArray tex;"},
GlslDepthTextureData{ast::TextureDimension::kCube, "samplerCube tex;"},
GlslDepthTextureData{ast::TextureDimension::kCubeArray,
"samplerCubeArray tex;"}));
testing::Values(GlslDepthTextureData{ast::TextureDimension::k2d,
"sampler2DShadow tex;"},
GlslDepthTextureData{ast::TextureDimension::k2dArray,
"sampler2DArrayShadow tex;"},
GlslDepthTextureData{ast::TextureDimension::kCube,
"samplerCubeShadow tex;"},
GlslDepthTextureData{ast::TextureDimension::kCubeArray,
"samplerCubeArrayShadow tex;"}));

using GlslDepthMultisampledTexturesTest = TestHelper;
TEST_F(GlslDepthMultisampledTexturesTest, Emit) {
Expand Down
64 changes: 0 additions & 64 deletions test/benchmark/shadow-fragment.wgsl.expected.glsl

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ struct ShadowProperties {
layout(binding = 7) buffer LightShadows_1 {
ShadowProperties properties[];
} shadow;
uniform highp sampler2D shadowTexture_1;
uniform highp sampler2D shadowTexture_shadowSampler;
uniform highp sampler2DShadow shadowTexture_1;
uniform highp sampler2DShadow shadowTexture_shadowSampler;

float dirLightVisibility(vec3 worldPos) {
int shadowIndex = lightShadowTable.light[0u];
Expand All @@ -124,7 +124,7 @@ float dirLightVisibility(vec3 worldPos) {
float visibility = 0.0f;
{
for(uint i = 0u; (i < shadowSampleCount); i = (i + 1u)) {
visibility = (visibility + texture(shadowTexture_shadowSampler, clamp((viewportPos + (shadowSampleOffsets[i] * texelSize)), clampRect.xy, clampRect.zw), (shadowPos.z - 0.003f)));
visibility = (visibility + texture(shadowTexture_shadowSampler, vec3(clamp((viewportPos + (shadowSampleOffsets[i] * texelSize)), clampRect.xy, clampRect.zw), (shadowPos.z - 0.003f))));
}
}
return (visibility / float(shadowSampleCount));
Expand Down Expand Up @@ -169,7 +169,7 @@ float pointLightVisibility(uint lightIndex, vec3 worldPos, vec3 pointToLight) {
float visibility = 0.0f;
{
for(uint i = 0u; (i < shadowSampleCount); i = (i + 1u)) {
visibility = (visibility + texture(shadowTexture_shadowSampler, clamp((viewportPos + (shadowSampleOffsets[i] * texelSize)), clampRect.xy, clampRect.zw), (shadowPos.z - 0.01f)));
visibility = (visibility + texture(shadowTexture_shadowSampler, vec3(clamp((viewportPos + (shadowSampleOffsets[i] * texelSize)), clampRect.xy, clampRect.zw), (shadowPos.z - 0.01f))));
}
}
return (visibility / float(shadowSampleCount));
Expand Down
9 changes: 4 additions & 5 deletions test/bug/chromium/1290107.wgsl.expected.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,21 @@ struct S {
layout(binding = 0) buffer arr_block_1 {
S inner[];
} arr;
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void tint_symbol() {
uint tint_symbol_2 = 0u;
arr.inner.GetDimensions(tint_symbol_2);
uint tint_symbol_3 = (tint_symbol_2 / 4u);
uint len = tint_symbol_3;
return;
}

layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void main() {
tint_symbol();
return;
}

Error parsing GLSL shader:
ERROR: 0:14: '.' : cannot apply to an array: GetDimensions
ERROR: 0:14: '' : compilation terminated
ERROR: 0:13: '.' : cannot apply to an array: GetDimensions
ERROR: 0:13: '' : compilation terminated
ERROR: 2 compilation errors. No code generated.


Expand Down
11 changes: 10 additions & 1 deletion test/bug/tint/827.wgsl.expected.glsl
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
SKIP: FAILED

#version 310 es
precision mediump float;

const uint width = 128u;
layout(binding = 1) buffer Result_1 {
float values[];
} result;
uniform highp sampler2D tex_1;
uniform highp sampler2DShadow tex_1;
void tint_symbol(uvec3 GlobalInvocationId) {
result.values[((GlobalInvocationId.y * width) + GlobalInvocationId.x)] = texelFetch(tex_1, ivec2(int(GlobalInvocationId.x), int(GlobalInvocationId.y)), 0).x;
}
Expand All @@ -15,3 +17,10 @@ void main() {
tint_symbol(gl_GlobalInvocationID);
return;
}
Error parsing GLSL shader:
ERROR: 0:10: 'texelFetch' : no matching overloaded function found
ERROR: 0:10: '' : compilation terminated
ERROR: 2 compilation errors. No code generated.



4 changes: 2 additions & 2 deletions test/bug/tint/978.wgsl.expected.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ struct FragmentOutput {
vec4 color;
};

uniform highp sampler2D depthMap_texSampler;
uniform highp sampler2DShadow depthMap_texSampler;

FragmentOutput tint_symbol(FragmentInput fIn) {
float tint_symbol_1 = texture(depthMap_texSampler, fIn.vUv).x;
float tint_symbol_1 = texture(depthMap_texSampler, vec3(fIn.vUv, 0.0f));
vec3 color = vec3(tint_symbol_1, tint_symbol_1, tint_symbol_1);
FragmentOutput fOut = FragmentOutput(vec4(0.0f, 0.0f, 0.0f, 0.0f));
fOut.color = vec4(color, 1.0f);
Expand Down
Loading

0 comments on commit d4d7153

Please sign in to comment.