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

image attribute has no arguments in storage_class.rs #386

Closed
adrianisuru opened this issue Jan 20, 2021 · 6 comments · Fixed by #461
Closed

image attribute has no arguments in storage_class.rs #386

adrianisuru opened this issue Jan 20, 2021 · 6 comments · Fixed by #461
Labels
t: bug Something isn't working

Comments

@adrianisuru
Copy link
Contributor

My goal is to recreate the shader below in rust.

// https://vulkano.rs/guide/mandelbrot
#version 450

 layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;

 layout(set = 0, binding = 0, rgba8) uniform writeonly image2D img;

 void main() {
     vec2 norm_coordinates = (gl_GlobalInvocationID.xy + vec2(0.5)) / vec2(imageSize(img));

     vec2 c = (norm_coordinates - vec2(0.5)) * 2.0 - vec2(1.0, 0.0);

     vec2 z = vec2(0.0, 0.0);
     float i;
     for (i = 0.0; i < 1.0; i += 0.005) {
         z = vec2(
         z.x * z.x - z.y * z.y + c.x,
         z.y * z.x + z.x * z.y + c.y
         );

         if (length(z) > 4.0) {
             break;
         }
     }

     vec4 to_write = vec4(vec3(i), 1.0);
     imageStore(img, ivec2(gl_GlobalInvocationID.xy), to_write);
}

Here is the code I have so far.

#![cfg_attr(
target_arch = "spirv",
no_std,
feature(register_attr),
register_attr(spirv)
)]

extern crate spirv_std;

#[cfg(not(target_arch = "spirv"))]
#[macro_use]
pub extern crate spirv_std_macros;

use spirv_std::storage_class::{Input, Image};
use spirv_std::glam::{Vec2, Vec3, Vec4};

const BAILOUT: i32 = 200;

#[allow(unused_attributes)]
#[spirv(gl_compute(local_size_x = 8, local_size_y = 8, local_size_z = 1))]
pub fn main(
    #[spirv(global_invocation_id)] gid: Input<Vec3>,
    #[spirv(image(dim="Dim2D", depth=1, arrayed=0, multisampled=0, sampled=0, image_format="Rgba8", access_qualifier="WriteOnly"))] img: &mut Image<Vec4>
) {
    let gid = gid.load();
    let norm_coordinates = (gid.truncate() + Vec2::new(0.5, 0. )) / Vec2::new(1024., 1024.);
    let  c = (norm_coordinates - Vec2::new(0.5, 0.))*2. - Vec2::new(1., 0.);
    let mut z = Vec2::zero();
    let mut i = 0i32;
    while i < BAILOUT {
        z = Vec2::new(z.x*z.x - z.y*z.y + c.x, 2.*z.x*z.y + c.y);
        if z.length() > 4. {
            break;
        }
        i = i + 1;
    };
    let to_write = Vec4::new(i as f32, 0., 0., 1.);
    img.store(to_write);
}

Through trial and error I found that the image macro requires many arguments.

#[spirv(image(dim="Dim2D", depth=1, arrayed=0, multisampled=0, sampled=0, image_format="Rgba8", access_qualifier="WriteOnly"))]

When I compile this shader with my build script, I get an error.

use spirv_builder::SpirvBuilder;
use std::error::Error;
use std::boxed::Box;
fn main() -> Result<(), Box<dyn Error>> {
    SpirvBuilder::new("shader")
        .spirv_version(1, 0)
        .build()?;
    Ok(())
}
$ cargo build
.
.
.
 error: image attribute must have arguments
     --> /home/adrianisuru/.cargo/git/checkouts/rust-gpu-e0a37a82a46176e6/1454fe3/crates/spirv-std/src/storage_class.rs:128:13
      |
  128 |     #[spirv(image)] writeable storage_class Image;
      |             ^^^^^
.
.
.

It seems this error occurs because in storage_class.rs, image has no arguments. Is it that image always requires many arguments or does the error in storage_class.rs occur for some other reason, say, something I've done incorrectly in my code?

Any help is appreciated.

@adrianisuru adrianisuru added the t: bug Something isn't working label Jan 20, 2021
@khyperia
Copy link
Contributor

Oh fun, didn't notice there was a storage class called image, no idea what the heck that does.

What you want here is, roughly (doing this off the top of my head):

use spirv_std::{storage_class::UniformConstant, textures::Image2d};
pub fn main(
    #[spirv(global_invocation_id)] gid: Input<Vec3>,
    mut img: UniformConstant<Image2d>
) {
...
}

However, we have no support for OpImageWrite yet, so the shader can't be translated right now. Not sure if there may be other unimplemented things, too.

@XAMPPRocky
Copy link
Member

Oh fun, didn't notice there was a storage class called image, no idea what the heck that does.

According to the spec, it's just for storing image memory.

@khyperia
Copy link
Contributor

Yeah, I saw that, but like... what does "image memory" mean? clearly not storing an image, because that's UniformConstant? aaa

@adrianisuru
Copy link
Contributor Author

Thanks. I guess then what I want to draw attention to is this:

#[spirv(image)] writeable storage_class Image;

In storage_class.rs the image macro is used without any arguments, but in symbols.rs there is code to check for, and error, when the image macro has no arguments.
.span_err(attr.span(), "image attribute must have arguments");

It seems inconsistent.

@khyperia
Copy link
Contributor

yeah, it's because there's a name collision we didn't notice before, the no-argument one is defined here. we need to rename one of them.

@XAMPPRocky
Copy link
Member

FWIW I think it would make sense to rename the Image type (not storage class) to #[spirv(image_type)] as the attribute, as that would keep the storage classes consistent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
t: bug Something isn't working
Projects
None yet
3 participants