vulkano icon indicating copy to clipboard operation
vulkano copied to clipboard

Incorrect data in output buffer when output buffer type is boolean

Open croraf opened this issue 5 years ago • 2 comments

Template

If you dont understand something just leave it. If you can provide more detailed information than the template allows for, please ignore the template and present all of your findings.

  • Version of vulkano: 0.17
  • OS: Ubuntu 19.10
  • GPU (the selected PhysicalDevice): TODO
  • GPU Driver: TODO
  • Upload of a reasonably minimal complete main.rs file that demonstrates the issue: TODO
    ...
    let data_in_iter = (0..2048).map(|i| (i, i));
    let data_in_buffer =
        CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), false, data_in_iter)
            .expect("failed to create buffer");

    let data_out_iter = (0..2048).map(|_| -1);
    let data_out_buffer =
        CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), false, data_out_iter)
            .expect("failed to create buffer");

    let compute_pipeline = Arc::new({
        mod cs {
            vulkano_shaders::shader! {
                ty: "compute",
                src:
                "
                    #version 450
                    
                    layout(local_size_x = 1024, local_size_y = 1, local_size_z = 1) in;
                    
                    layout(set = 0, binding = 0) buffer DataIn {
                        uvec2 data[];
                    } buf_in;
    
                    layout(set = 0, binding = 1) buffer DataOut {
                        uint data[];
                    } buf_out;
                    
                    void main() {
                        uint idx = gl_GlobalInvocationID.x;
                        buf_out.data[idx] = buf_in.data[idx].x + buf_in.data[idx].y < 2048 ? 0 : 1;
                    }
                "
            }
        }
        let shader = cs::Shader::load(device.clone()).expect("failed to create shader module");
        ComputePipeline::new(device.clone(), &shader.main_entry_point(), &())
            .expect("failed to create compute pipeline")
    });

    let layout = compute_pipeline.layout().descriptor_set_layout(0).unwrap();
    let set = Arc::new(
        PersistentDescriptorSet::start(layout.clone())
            .add_buffer(data_in_buffer.clone())
            .unwrap()
            .add_buffer(data_out_buffer.clone())
            .unwrap()
            .build()
            .unwrap(),
    );

    let command_buffer =
        AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
            .unwrap()
            .dispatch([2, 1, 1], compute_pipeline.clone(), set.clone(), ())
            .unwrap()
            .build()
            .unwrap();

Issue

The above code works OK, giving first 1024 elements 0 and last 1024 1.

But when I want to use output buffer as boolean:

    let data_out_iter = (0..2048).map(|_| true); // fill output buffer with all trues
    ...
         layout(set = 0, binding = 1) buffer DataOut {
               bool data[];
         } buf_out;
                    
         void main() {
              uint idx = gl_GlobalInvocationID.x;
              buf_out.data[idx] = buf_in.data[idx].x + buf_in.data[idx].y < 2048;
        }
   ...

the output buffer comes out as:

true
false
false
false
true
false
false
false
true
false
....

croraf avatar Mar 07 '20 18:03 croraf

Is this related to: https://github.com/vulkano-rs/vulkano/issues/781 ?

croraf avatar Mar 07 '20 21:03 croraf

This fucked me over earlier. That was on an input buffer in a graphics pipeline though. rust u32 -> glsl bool image rust bool -> glsl bool image

HookedBehemoth avatar Feb 02 '22 12:02 HookedBehemoth

This is normal shader behaviour, not related to Vulkano or Vulkan. The GLSL shader compiler generates this SPIR-V code for the buf_out variable:

                %uint = OpTypeInt 32 0
    %_runtimearr_uint = OpTypeRuntimeArray %uint
             %DataOut = OpTypeStruct %_runtimearr_uint
%_ptr_Uniform_DataOut = OpTypePointer Uniform %DataOut
             %buf_out = OpVariable %_ptr_Uniform_DataOut Uniform

It generates a runtime array with 32-bit integer elements, not boolean elements (OpTypeBool). So Vulkano can't fix this, it's simply how the shader compiler works.

Rua avatar Dec 28 '22 18:12 Rua