gfx-rs / metal-rs

Rust bindings for Metal
Apache License 2.0
573 stars 112 forks source link

fatal assert when calling ArgumentDescriptor::set_access #199

Closed aclysma closed 3 years ago

aclysma commented 3 years ago

I'm getting a very strange assertion with this program:

fn main() {
    let argument_descriptor = rafx::api::metal_rs::ArgumentDescriptor::new();
    println!("settings access");
    argument_descriptor.set_access(rafx::api::metal_rs::MTLArgumentAccess::ReadWrite);
    println!("has set access");

    let argument_descriptor = rafx::api::metal_rs::ArgumentDescriptor::new();
    println!("settings access");
    argument_descriptor.set_access(rafx::api::metal_rs::MTLArgumentAccess::ReadWrite);
    println!("has set access");

It prints

settings access
has set access
settings access
validateMTLArgumentAccess:27: failed assertion `access (4294967297) is not a valid MTLArgumentAccess.'

The bizarre thing is that I cannot reproduce this with an "empty" project. If I take the exact code and all the same dependencies and move them to another project, it works fine. The only difference I can think of at this point is the one that fails is an example of another crate and the in-theory identical project that doesn't crash links that same crate as a downstream binary.

The only thing I can think of that would cause a crash like this would be incorrect bindings or something happening before main() that causes undefined behavior. I use static variables and things like lazy_static extremely sparingly. The app runs fine if I use my vulkan backend instead of the metal backend and all other metal bindings seem to work. (The original project that is crashing calls quite a few metal APIs before reaching this point).

The only thing I saw that looks suspicious is that MTLArgumentAccess is repr(u32) and the docs point out that this is Uint, which would actually be u64 on most systems (i.e. usize)

I tried to find examples of this function actually being used but was unable to get the gfx-hal examples to call it and didn't see it used in the examples of this crate.

Just posting here hoping that someone has an idea!

kvark commented 3 years ago

I believe you fully identified and explained what's going on. We are sending 32bits of data, getting the higher 32 bits as garbage. Fix is coming is #200

aclysma commented 3 years ago

Made these repr(usize) locally and it fixed the problem, thanks for looking at it so quickly!