Skip to content

[naga] Float literals do not round trip #7589

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

Open
LegNeato opened this issue Apr 21, 2025 · 2 comments
Open

[naga] Float literals do not round trip #7589

LegNeato opened this issue Apr 21, 2025 · 2 comments
Labels
area: naga back-end Outputs of naga shader conversion naga Shader Translator type: enhancement New feature or request

Comments

@LegNeato
Copy link
Contributor

LegNeato commented Apr 21, 2025

Description
When you have a float literal in a shader, the AST gets Literal::F32(value) or Literal::F64(value). The value is a rust float, which leads to precision issues when one roundtrips between shader languages.

Repro steps
This likely affects all inputs, but here is a repo:

void main() {
    double d = 1.2;
}

And inspect the AST.

Expected vs observed behavior
Expected: 1.2
Observed: 1.2000000476837158

Possible Solution
Happy to put up a PR so the literals also have (or instead of?) a String representation Literal::F64(num, s) if that is an agreeable fix.

Platform
naga 25.0.1

@cwfitzgerald
Copy link
Member

Do they need to round trip, if the literal would end up rounding to the observed value anyway?

@LegNeato
Copy link
Contributor Author

LegNeato commented Apr 22, 2025

Hmmm, that's an interesting question. I am doing source to source translation meant to be read by a human, so I would prefer to keep the input so my backend can choose what to do to make the output as semantically close to the input. For example, this test fails:

    fn test_as_expression_float_to_uint() {
        let glsl = r#"
            void main() {
                float f = 1.2;
                uint u = uint(f);
            }
        "#;

        let rust = r#"
            #[spirv(fragment)]
            pub fn main() {
                let f: f32 = 1.2;
                let u: u32;
                u = f as u32;
            }
        "#;

        assert_correct_translation(ShaderStage::Fragment, glsl, rust);
    }

The rust code instead becomes

let f: f32 = 1.2000000476837158;

So I see a semantic difference between "I wrote float f = 1.2;" and "I wrote float f = 1.2000000476837158" even though the calculation/value may still be correct.

@cwfitzgerald cwfitzgerald added type: enhancement New feature or request area: api Issues related to API surface area: naga back-end Outputs of naga shader conversion naga Shader Translator and removed area: api Issues related to API surface labels Apr 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: naga back-end Outputs of naga shader conversion naga Shader Translator type: enhancement New feature or request
Projects
Status: Todo
Development

No branches or pull requests

2 participants