vulkano-rs / vulkano

Safe and rich Rust wrapper around the Vulkan API
Apache License 2.0
4.45k stars 435 forks source link

textureGather from sampler2DShadow can't bind a sampler with compare operation #2544

Open YangZhiYU0421 opened 1 month ago

YangZhiYU0421 commented 1 month ago

Panic at validate_draw function.

thread 'main' panicked at src/examples/sampler_2d_shadow_binding.rs:379:55:
called `Result::unwrap()` on an `Err` value: the currently bound pipeline accesses the sampler bound to descriptor set 0, binding 0, descriptor index 0, in a way that requires a sampler without a compare operation, but the sampler currently bound to that descriptor has a compare operation

It happened when I try to bind a sampler which compare = Some(Less). Following the backtrace of panic, I found entry_point_info has a flag in descriptor requirements sampler_compare = false , that conflict a sampler with compare operator. Maybe the Texel gather from shadow texture should need a compare operator. Here has some decription about gather from shadow: The 4 return values for shadow samplers are the [result of the comparison] for each texel location (https://www.khronos.org/opengl/wiki/Depth_Compare).

EntryPointInfo {
...
descriptors: {
                Some(
                    0x0,
                ): DescriptorRequirements {
                    memory_read: FRAGMENT,
                    memory_write: empty(),
                    sampler_compare: false,
                    sampler_no_unnormalized_coordinates: true,
                    sampler_no_ycbcr_conversion: true,
                    sampler_with_images: {},
                    storage_image_atomic: false,
                },
            },

My fragment shader:

 #version 450
layout(location = 0) in vec2 tex_coord;
layout(location = 0) out vec4 f_color;
layout(set = 0, binding = 0) uniform sampler2DShadow src_image;
void main() {
    vec4 color = textureGather(src_image, tex_coord, 0.5);
    f_color = vec4(color.x, color.y, color.z, 1.0);
}

Maybe the shader reflect need add sampler_compare = true for ImageGatherDref branch.

vukano/src/shader/reflect.rs: 340:
                    Instruction::ImageDrefGather { sampled_image, .. }
                    | Instruction::ImageSparseDrefGather { sampled_image, .. } => {
                        if let Some(desc_reqs) = desc_reqs(
                            self.instruction_chain([inst_sampled_image, inst_load], sampled_image),
                        ) {
                            desc_reqs.memory_read = stage.into();
                            desc_reqs.sampler_no_unnormalized_coordinates = true;
                            desc_reqs.sampler_no_ycbcr_conversion = true;
                            // desc_reqs.sampler_compare = true;  ? // Add here ?
                        }
                    }