Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix glsl backend errors regarding samplerCubeArrayShadow #5171

Merged
merged 11 commits into from
Feb 8, 2024

Conversation

cmrschwarz
Copy link
Contributor

@cmrschwarz cmrschwarz commented Jan 31, 2024

Connections
Offers a solution for #4455, and the related downstream issues ( see bevyengine/bevy#7320 )

Description
GL's textureLod does not support sampling from a cube depth texture with an explicit LOD.

This is made significantly worse by the fact that the only way to use wgsl's textureSampleCompare from
non uniform control flow is to use textureSampleCompareLevel, which forces us to specify an LOD (0).

This currently triggers a backend error that has been observed downstream multiple times,
e.g. breaking bevy's PBR pipeline for the GL backend, and therefore many Intel Graphics Cards.

This PR mostly solves this problem by changing the behavior for this case from a backend error to a
GL feature requirement on GL_EXT_texture_shadow_lod , as was previously suggested by @magcius .
Fortunately, this extension seems to be available on many of the affected devices.

The existing functionality around workaround_lod_array_shadow_as_grad is preserved, and preferred over requiring the extension where possible.

Some impossible cases still remain ( textureGrad still doesn't support samplerCubeArrayShadow), but those should be far less common.

Testing
A testcase showing the extension working was added in b2ea9fe.
A testcase around overriding the workaround if instructed was added in cd4108f.

Checklist

  • Run cargo fmt.
  • Run cargo clippy. If applicable, add:
    • --target wasm32-unknown-unknown
    • --target wasm32-unknown-emscripten
  • Run cargo xtask test to run tests.
  • Add change to CHANGELOG.md. See simple instructions inside file.

@cmrschwarz cmrschwarz requested a review from a team as a code owner January 31, 2024 09:30
@cmrschwarz cmrschwarz changed the title Texture shadow lod Fix glsl backend errors regarding samplerCubeArrayShadow Jan 31, 2024
Copy link
Member

@cwfitzgerald cwfitzgerald left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is all very cool!

I feel like this requires a wgpu downlevel flag, so users can know if GL_EXT_texture_shadow_lod is allowed and avoid a runtime crash.

@cmrschwarz
Copy link
Contributor Author

cmrschwarz commented Jan 31, 2024

Sure, I could do that.

But I don't fully understand yet why we would need / want that.
Where do you see the difference between this GL extension and others that we are already using (like GL_EXT_texture_cube_map_array) that would warrant a feature flag?

We don't have any alternatives to using the extension.
The logic in FeaturesManager makes sure that we only require it if absolutely necessary, just like with any other extensions we use.
So we could only throw a backend error again if a potential 'allow_gl_ext_texture_shadow_lod' feature flag was not set.

If we want users to be able to get better error messages (custom ones instead of what their driver ends up reporting for missing extensions), wouldn't that apply to all our used GL extensions, and be out of scope for this PR?

@magcius
Copy link
Contributor

magcius commented Feb 1, 2024

The downlevel flag would still be a good idea since there's one case we can't emulate even with EXT_texture_shadow_lod: samplerCubeArrayShadow on textureGrad.

@cmrschwarz
Copy link
Contributor Author

I kept the backend error that we had before this PR for that case @magcius .

What is the behavior you would like to see instead? (with / without the downlevel flag set)

naga/src/back/glsl/mod.rs Outdated Show resolved Hide resolved
naga/src/back/glsl/features.rs Outdated Show resolved Hide resolved
naga/src/back/glsl/features.rs Outdated Show resolved Hide resolved
@cmrschwarz
Copy link
Contributor Author

cmrschwarz commented Feb 2, 2024

Thank you for taking a look at this.
I'm glad to see that there's interest in merging this.

You're definitely right that the criteria for using the extension / workaround weren't quite perfect yet.
I updated the code to hopefully fix this, and replaced all the problematic cases with errors, as you suggested.
I would appreciate somebody taking the time to review this again.

There's a conversation to be had here about the exact GL / GLES version requirements of the sampling functions, which currently aren't enforced properly. This is especially problematic since we currently default to GLES 3.1, which lacks some of the features we're using here. While that's potentially out of scope for this PR, I would be willing to work on that.
In the process of fixing the criteria for the extension I already ended up creating the following table by scouring through the documentations.
I'm reproducing it here hoping it may be useful:

2DArray cube cubeArray 2DArrayShadow cubeShadow cubeArrayShadow workaround for lod 0
GL GLES GL GLES GL GLES GL GLES GL GLES GL GLES
texture 1.3 3.0 1.3 3.0 4.0 3.2 1.3 3.0 1.3 3.0 4.0 3.2
texture+bias 1.3 3.0 1.3 3.0 4.0 3.2 EXT EXT EXT EXT EXT EXT
textureLod 1.3 3.0 1.3 3.0 4.0 3.2 EXT EXT EXT EXT EXT EXT textureGrad
textureGrad 1.3 3.0 1.3 3.0 4.0 3.2 1.3 3.0 1.3 3.0 no no
textureGather 4.0 3.1 4.0 3.1 4.0 3.2 4.0 3.1 4.0 3.1 4.0 3.2
textureOffset 1.3 3.0 no no no no 4.3 EXT no no no no
textureOffset+bias 1.3 3.0 no no no no EXT EXT no no no no
textureLodOffset 1.3 3.0 no no no no EXT EXT no no no no textureGradOffset
textureGradOffset 1.3 3.0 no no no no 1.3 3.0 no no no no
textureGatherOffset 4.0 3.1 no no no no 4.0 3.0 no no no no

@teoxoy
Copy link
Member

teoxoy commented Feb 5, 2024

Thanks for sharing the table!

The only discrepancy I found was that texture, texture+bias and textureGrad with cube[Shadow] are available since GLES 1.3.

There's a conversation to be had here about the exact GL / GLES version requirements of the sampling functions, which currently aren't enforced properly.

The only restrictions from our base of GLSL 1.3 & GLSL ES 3.0 seem to be:

  • textureGather[Offset] available since 4.0 / 3.1
  • cubeArray[Shadow] available since 4.0 / 3.2

We seem to check for availability of textureGather[Offset] and we should.
For cube arrays, we have Features::CUBE_TEXTURES_ARRAY which will request the extension. An improvement would be to omit requesting the extension if we are on 3.2 already.

naga/src/back/glsl/mod.rs Outdated Show resolved Hide resolved
naga/src/back/glsl/mod.rs Outdated Show resolved Hide resolved
naga/src/back/glsl/mod.rs Outdated Show resolved Hide resolved
naga/src/back/glsl/features.rs Outdated Show resolved Hide resolved
@teoxoy
Copy link
Member

teoxoy commented Feb 5, 2024

glslangValidator v13.1.0 (released on 2023-10-13) added support for GL_EXT_texture_shadow_lod but CI seems to be on v11.8.0 (released on 2022-01-27).

@cwfitzgerald do you know how we could get v13.1.0 on CI?

@cwfitzgerald
Copy link
Member

Installing the vulkan sdk is a good way of getting an up to date copy of the glsl tooling

@teoxoy
Copy link
Member

teoxoy commented Feb 5, 2024

#5202 landed; @cmrschwarz could you rebase on top of it to see if the CI failure goes away?

naga/src/back/glsl/mod.rs Outdated Show resolved Hide resolved
@cmrschwarz
Copy link
Contributor Author

cmrschwarz commented Feb 8, 2024

We seem to check for availability of textureGather[Offset] and we should.

textureGather[Offset] before GL 4.0 / GLES 3.1 currently compiles without any errors / extensions used.

Demonstration test:

wgsl:

@group(0) @binding(0) var texture: texture_cube<f32>;
@group(0) @binding(1) var texture_sampler: sampler;

@fragment
fn main() -> @location(0) vec4<f32>  {
    return textureGather(0, texture, texture_sampler, vec3<f32>(0.0));
}

ron:

(
	glsl: (
        writer_flags: (""),
        version: Desktop(140),
		binding_map: {},
		zero_initialize_workgroup_memory: true,
	),
)

output:

#version 140 core
uniform samplerCube _group_0_binding_0_fs;

out vec4 _fs2p_location0;

void main() {
    vec4 _e4 = textureGather(_group_0_binding_0_fs, vec3(vec3(0.0)), vec3(0.0), vec3(0.0), 0);
    _fs2p_location0 = _e4;
    return;
}


An improvement would be to omit requesting the extension if we are on 3.2 already.

Things that currently require an extension for but don't have to:

  • any use of cubeArray / cubeArrayShadow in GL 4.0 / GLES 3.2
  • textureOffset on 2DArrayShadow in GL 4.3

The only restrictions from our base of GLSL 1.3 & GLSL ES 3.0 seem to be [...]

Maybe not too really relevant, but we currently don't seem to support GL 1.3, only GL 1.4. I assume that's intended.

@teoxoy
Copy link
Member

teoxoy commented Feb 8, 2024

We seem to check for availability of textureGather[Offset] and we should.

textureGather[Offset] before GL 4.0 / GLES 3.1 currently compiles without any errors / extensions used.

Right, I mistyped, should have been: "We don't seem to check for availability of textureGather[Offset] and we should.".

@cmrschwarz
Copy link
Contributor Author

Damn, sorry for all my mistakes on this.
35dbd9d should address the issues you pointed out.
Thank you for your patience with me @teoxoy .

Regarding thetextureGather situation, would you be fine with a separate PR regarding that?

naga/src/back/glsl/mod.rs Outdated Show resolved Hide resolved
@teoxoy
Copy link
Member

teoxoy commented Feb 8, 2024

No worries :)

Thanks for addressing all the feedback!

Regarding the textureGather situation, would you be fine with a separate PR regarding that?

Yeah, that sounds the best.

Copy link
Member

@teoxoy teoxoy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good stuff!

@teoxoy
Copy link
Member

teoxoy commented Feb 8, 2024

Ah, I forgot about the downlevel flag request. Would you be able to add a downlevel flag for the GL_EXT_texture_shadow_lod extension? We could do that in a follow-up PR as well.

The role of downlevel flags is letting users know what functionality is available before they use it. The presence of all dowlevel flags also signifies that the device implements the WebGPU API fully.

@cmrschwarz
Copy link
Contributor Author

Oh! When I initially submitted this, I wasn't too familiar with the library, so I was thinking Rust feature flag, not wgpu::DownlevelFlag.

My initial comments regarding this probably didn't make any sense at all 😅 . Sorry for my ignorance.

Since this comment thread is getting pretty long, and as the downlevel flag sort of addresses an issue that was present before this PR, I would prefer doing a follow up PR, if thats ok for you guys.

@teoxoy teoxoy dismissed cwfitzgerald’s stale review February 8, 2024 17:26

we will add the downlevel flag in a follow-up PR

@teoxoy teoxoy merged commit 2382c8e into gfx-rs:trunk Feb 8, 2024
27 checks passed
@billyb2
Copy link

billyb2 commented Feb 28, 2024

hey, would it be possible to cut a new release? Using this PR would be super useful for a personal project of mine. If not, no worries. Hope I'm not bugging yall :)

@cwfitzgerald cwfitzgerald added the PR: needs back-porting PR with a fix that needs to land on crates label Feb 29, 2024
cwfitzgerald pushed a commit to cwfitzgerald/wgpu that referenced this pull request Feb 29, 2024
* add GL_EXT_texture_shadow_lod feature detection

* allow more cases of cube depth texture sampling in glsl

* add test for sampling a cubemap array depth texture with lod

* add test for chosing GL_EXT_texture_shadow_lod over the grad workaround if instructed

* add changelog entry for GL_EXT_texture_shadow_lod

* fix criteria for requiring and using TEXTURE_SHADOW_LOD

* require gles 320 for textureSampling over cubeArrayShadow

* prevent false positives in TEXTURE_SHADOW_LOD in checks

* make workaround_lod_with_grad usecase selection less context dependant

* move 3d array texture error into the validator

* correct ImageSample logic errors
@cwfitzgerald
Copy link
Member

Just landed in 0.19.2 :)

@billyb2
Copy link

billyb2 commented Feb 29, 2024

Just landed in 0.19.2 :)

You guys are awesome

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants