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

MSL: Fragment shader that discards unconditionally does not compile. #2435

Closed
squidbus opened this issue Jan 20, 2025 · 2 comments
Closed

MSL: Fragment shader that discards unconditionally does not compile. #2435

squidbus opened this issue Jan 20, 2025 · 2 comments

Comments

@squidbus
Copy link
Contributor

squidbus commented Jan 20, 2025

Ran into an interesting case with a emulator shader translator where it was outputting a shader that branches over its whole logic to a OpDemoteToHelperInvocation at the end.

The SPIR-V at the end looks like this:

       %2613 = OpLabel
               OpDemoteToHelperInvocation
               OpBranch %195
        %195 = OpLabel
               OpUnreachable
               OpFunctionEnd

When translated to MSL, the shader results in a main function with the following structure:

fragment main0_out main0(main0_in in [[stage_in]], ...)
{
    main0_out out = {};
    ...
    if (false)
    {
        ...
        return out;
    }
    discard_fragment();
}

This results in the following MSL compile error:

program_source:1199:1: error: control reaches end of non-void fragment function [-Werror,-Wmtl-shader-return-type]
}
^

Now, I am not sure whether this is actually how the shader was supposed to be translated from its original assembly to SPIR-V. I've looked into this further and the shader does in fact just block its logic behind an always-false condition and discard. I do believe the resulting SPIR-V is a valid shader with no errors from spirv-val, so I think cases like this where a shader discards unconditionally should produce valid MSL shaders. I believe adding a dummy return after the discard can fix the issue, see another case of this for reference: gfx-rs/wgpu#4458

@squidbus
Copy link
Contributor Author

I saw there's similar handling for blocks ending in Kill already and it just needs to be extended to Unreachable, so I added that here: #2436

@HansKristian-Work
Copy link
Contributor

       %2613 = OpLabel
               OpDemoteToHelperInvocation
               OpBranch %195
        %195 = OpLabel
               OpUnreachable
               OpFunctionEnd

It should be mentioned that this SPIR-V is broken, but we can paper over it.

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

No branches or pull requests

2 participants