rust-gpu icon indicating copy to clipboard operation
rust-gpu copied to clipboard

Closure capture acceleration structure fails spirv-val

Open molikto opened this issue 2 years ago • 2 comments

Expected Behaviour

spriv-val should not fail. Looks it's because the bug mentioned here https://github.com/EmbarkStudios/rust-gpu/pull/690#pullrequestreview-719958024 . I will try to make a PR to fix it

Example & Steps To Reproduce

This shader fails with spirv-val error

But either:

  1. move out of the closure
  2. remove the rayquery

Make it compile successfully.

// build-pass
// compile-flags: -Ctarget-feature=+RayTracingKHR,+RayQueryKHR,+ext:SPV_KHR_ray_tracing,+ext:SPV_KHR_ray_query

#[cfg(not(target_arch = "spirv"))]
use spirv_std::macros::spirv;
use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery};
use spirv_std::{glam::Vec3, ray_query};
use spirv_std::macros::spirv;
use spirv_std::ray_tracing::{AccelerationStructure, CommittedIntersection, RayFlags, RayQuery};
use spirv_std::{glam::Vec3, ray_query};

pub fn some_fun(mut c: impl FnMut() -> bool) {
    let mut i = 0;
    while i < 10 {
        if c() {
            return;
        }
        i += 1;
    }
}
#[spirv(intersection)]
pub fn voxels_gbuffer_is(
    #[spirv(storage_buffer, descriptor_set = 1, binding = 1)] vertices: &[u32],
    #[spirv(descriptor_set = 1, binding = 3)] acceleration_structure: &AccelerationStructure,
) {
    some_fun(|| {
        unsafe {
            ray_query!(let mut handle);
            handle.initialize(
                acceleration_structure,
                RayFlags::TERMINATE_ON_FIRST_HIT,
                0xFF,
                Vec3::new(0.0, 0.0, 0.0),
                0.0,
                Vec3::new(0.0, 0.0, 0.0),
                10000.0,
            );
            unsafe {
                // Indices of the triangle
                let ind = vertices.index_unchecked(0);
            };
            true
        }
    });
}


System Info

  • Rust: rustc 1.62.0-nightly (1f7fb6413 2022-04-10)
  • OS: Windows 10 Version 10.0.19044 Build 19044
  • GPU: RTX 3070 Ti
  • SPIR-V: SPIRV-Tools v2022.2-dev v2022.1-6-g45dd184c

Backtrace

Backtrace

error: error:0:0 - OpLoad Pointer <id> '58[%58]' is not a logical pointer.
         %61 = OpLoad %20 %58
  |
  = note: spirv-val failed

spirv:

; SPIR-V
; Version: 1.3
; Generator: Embark Studios Rust GPU Compiler Backend; 0
; Bound: 76
; Schema: 0
               OpCapability Int16
               OpCapability Int64
               OpCapability Int8
               OpCapability RayQueryKHR
               OpCapability RayTracingKHR
               OpCapability Shader
               OpExtension "SPV_EXT_descriptor_indexing"
               OpExtension "SPV_KHR_ray_query"
               OpExtension "SPV_KHR_ray_tracing"
               OpMemoryModel Logical Simple
               OpEntryPoint IntersectionNV %1 "main"
          %2 = OpString "C:\\Users\\molikto\\.cargo\\git\\checkouts\\rust-gpu-c5ec26e609830c67\\8609aab\\crates\\spirv-std\\src\\arch.rs"
          %3 = OpString "crates\\mocraft-client\\shader\\src\\lib.rs"
          %4 = OpString "C:\\Users\\molikto\\.cargo\\git\\checkouts\\rust-gpu-c5ec26e609830c67\\8609aab\\crates\\spirv-std\\src\\ray_tracing.rs"
          %5 = OpString "C:\\Users\\molikto\\.cargo\\git\\checkouts\\glam-rs-ce970401f3f26dcb\\ef12fa7\\src\\vec3.rs"
          %6 = OpString "C:\\Users\\molikto\\.cargo\\registry\\src\\github.com-1ecc6299db9ec823\\bitflags-1.3.2\\src\\lib.rs"
          %7 = OpString "C:\\Users\\molikto\\.cargo\\git\\checkouts\\glam-rs-ce970401f3f26dcb\\ef12fa7\\src\\core\\scalar\\vector.rs"
               OpName %__u32_ "&[u32]"
               OpMemberName %_closure_crates_mocraft_client_shader_src_lib_rs_30_14__47_6_ 0 "0"
               OpMemberName %_closure_crates_mocraft_client_shader_src_lib_rs_30_14__47_6_ 1 "1"
               OpMemberName %_closure_crates_mocraft_client_shader_src_lib_rs_30_14__47_6_ 2 "2"
               OpName %_closure_crates_mocraft_client_shader_src_lib_rs_30_14__47_6_ "[closure@crates\\mocraft-client\\shader\\src\\lib.rs:30:14: 47:6]"
               OpName %vertices "vertices"
               OpName %acceleration_structure "acceleration_structure"
               OpDecorate %_runtimearr_uint ArrayStride 4
               OpMemberDecorate %__u32_ 0 Offset 0
               OpMemberDecorate %__u32_ 1 Offset 4
               OpMemberDecorate %_closure_crates_mocraft_client_shader_src_lib_rs_30_14__47_6_ 0 Offset 0
               OpMemberDecorate %_closure_crates_mocraft_client_shader_src_lib_rs_30_14__47_6_ 1 Offset 4
               OpMemberDecorate %_closure_crates_mocraft_client_shader_src_lib_rs_30_14__47_6_ 2 Offset 8
               OpDecorate %_struct_13 Block
               OpMemberDecorate %_struct_13 0 Offset 0
               OpDecorate %vertices DescriptorSet 1
               OpDecorate %vertices Binding 1
               OpDecorate %acceleration_structure DescriptorSet 1
               OpDecorate %acceleration_structure Binding 3
       %uint = OpTypeInt 32 0
%_runtimearr_uint = OpTypeRuntimeArray %uint
%_ptr_StorageBuffer__runtimearr_uint = OpTypePointer StorageBuffer %_runtimearr_uint
     %__u32_ = OpTypeStruct %_ptr_StorageBuffer__runtimearr_uint %uint
     %uint_0 = OpConstant %uint 0
       %void = OpTypeVoid
         %18 = OpTypeRayQueryKHR
%_ptr_Function_18 = OpTypePointer Function %18
         %20 = OpTypeAccelerationStructureKHR
%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
      %float = OpTypeFloat 32
    %v3float = OpTypeVector %float 3
%_closure_crates_mocraft_client_shader_src_lib_rs_30_14__47_6_ = OpTypeStruct %_ptr_Function_18 %_ptr_UniformConstant_20 %__u32_
         %24 = OpTypeFunction %void
 %_struct_13 = OpTypeStruct %_runtimearr_uint
%_ptr_StorageBuffer__struct_13 = OpTypePointer StorageBuffer %_struct_13
   %vertices = OpVariable %_ptr_StorageBuffer__struct_13 StorageBuffer
%acceleration_structure = OpVariable %_ptr_UniformConstant_20 UniformConstant
       %bool = OpTypeBool
        %int = OpTypeInt 32 1
      %int_0 = OpConstant %int 0
     %int_10 = OpConstant %int 10
      %int_1 = OpConstant %int 1
    %float_0 = OpConstant %float 0
     %uint_4 = OpConstant %uint 4
   %uint_255 = OpConstant %uint 255
%float_10000 = OpConstant %float 10000
       %true = OpConstantTrue %bool
      %false = OpConstantFalse %bool
         %37 = OpUndef %_closure_crates_mocraft_client_shader_src_lib_rs_30_14__47_6_
          %1 = OpFunction %void None %24
         %38 = OpLabel
         %39 = OpVariable %_ptr_Function_18 Function
               OpLine %3 26 4
         %40 = OpAccessChain %_ptr_StorageBuffer__runtimearr_uint %vertices %uint_0
         %41 = OpArrayLength %uint %vertices 0
               OpLine %3 30 13
         %42 = OpCompositeInsert %_closure_crates_mocraft_client_shader_src_lib_rs_30_14__47_6_ %39 %37 0
               OpLine %3 30 13
         %43 = OpCompositeInsert %_closure_crates_mocraft_client_shader_src_lib_rs_30_14__47_6_ %acceleration_structure %42 1
               OpLine %3 30 13
         %44 = OpCompositeInsert %_closure_crates_mocraft_client_shader_src_lib_rs_30_14__47_6_ %40 %43 2 0
         %45 = OpCompositeInsert %_closure_crates_mocraft_client_shader_src_lib_rs_30_14__47_6_ %41 %44 2 1
               OpLine %3 17 4
               OpBranch %46
         %46 = OpLabel
               OpBranch %47
         %47 = OpLabel
         %48 = OpPhi %int %int_0 %46 %49 %50
         %51 = OpPhi %bool %true %46 %52 %50
               OpLoopMerge %53 %50 None
               OpBranchConditional %51 %54 %53
         %54 = OpLabel
               OpLine %3 17 10
         %55 = OpSLessThan %bool %48 %int_10
               OpLine %3 17 10
               OpSelectionMerge %56 None
               OpBranchConditional %55 %57 %58
         %57 = OpLabel
               OpLine %3 32 12
         %59 = OpCompositeExtract %_ptr_Function_18 %45 0
               OpLine %3 33 16
         %60 = OpCompositeExtract %_ptr_UniformConstant_20 %45 1
               OpLine %7 745 8
         %61 = OpCompositeConstruct %v3float %float_0 %float_0 %float_0
               OpLine %7 745 8
         %62 = OpCompositeConstruct %v3float %float_0 %float_0 %float_0
               OpLine %4 246 8
         %63 = OpLoad %20 %60
               OpRayQueryInitializeKHR %59 %63 %uint_4 %uint_255 %61 %float_0 %62 %float_10000
               OpLine %3 18 11
               OpSelectionMerge %64 None
               OpBranchConditional %true %65 %66
         %65 = OpLabel
               OpLine %3 23 0
               OpBranch %64
         %66 = OpLabel
               OpLine %3 21 8
         %67 = OpIAdd %int %48 %int_1
               OpLine %3 17 4
               OpBranch %64
         %64 = OpLabel
         %68 = OpPhi %int %48 %65 %67 %66
         %69 = OpPhi %bool %true %65 %false %66
         %70 = OpPhi %bool %false %65 %true %66
               OpBranch %56
         %58 = OpLabel
               OpLine %3 23 0
               OpBranch %56
         %56 = OpLabel
         %49 = OpPhi %int %68 %64 %48 %58
         %71 = OpPhi %bool %69 %64 %true %58
         %72 = OpPhi %bool %70 %64 %false %58
               OpSelectionMerge %73 None
               OpBranchConditional %71 %74 %75
         %74 = OpLabel
               OpLine %3 48 1
               OpReturn
         %75 = OpLabel
               OpBranch %73
         %73 = OpLabel
         %52 = OpPhi %bool %72 %75
               OpBranch %50
         %50 = OpLabel
               OpBranch %47
         %53 = OpLabel
               OpUnreachable
               OpFunctionEnd

molikto avatar May 16 '22 06:05 molikto

This is the relevant error:

error: OpLoad Pointer <id> '58[%58]' is not a logical pointer.
           %61 = OpLoad %21 %58

oisyn avatar Mar 29 '23 13:03 oisyn

FWIW I've hit this with nested closures, here's the smallest repro I could get (tested on b2e5eb7):

#![cfg_attr(target_arch = "spirv", no_std)]
use spirv_std::{glam::UVec3, spirv};

pub fn inner(i: u32, callback: impl Fn()) {
    callback()
}

pub fn outer(callback: impl Fn()) {
    callback();
}

#[spirv(compute(threads(1, 1, 1)))]
pub fn compute(
    #[spirv(global_invocation_id)] id: UVec3,
    #[spirv(storage_buffer, descriptor_set = 0, binding = 0)] buffer: &[u32],
) {
    outer(|| {
        inner(id.x, || {
            buffer[0];
        })
    });
}
error: OpLoad Pointer <id> '30[%30]' is not a logical pointer.                                                                                                                                                                                                                    
         %31 = OpLoad %uint %30

kevinboulain avatar Jun 15 '23 17:06 kevinboulain