-
Notifications
You must be signed in to change notification settings - Fork 75
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Compiletest
// build-pass
// compile-flags: -C llvm-args=--disassemble
use spirv_std::glam::*;
use spirv_std::spirv;
#[spirv(compute(threads(32)))]
pub fn main(
#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] input: &UVec4,
#[spirv(descriptor_set = 0, binding = 1, storage_buffer)] output: &mut [u32],
) {
// works
// output[0] = input.x;
// fails
output[0] = input[0];
// works
// output[0] = unsafe { spirv_std::arch::vector_extract_dynamic(*input, 0) };
}
Error
error: error:0:0 - Using pointers with OpPhi requires capability VariablePointers or VariablePointersStorageBuffer
%37 = OpPhi %_ptr_StorageBuffer_uint %33 %29 %34 %30 %35 %31 %36 %32
Full logs and disassembly
; SPIR-V
; Version: 1.5
; Generator: rspirv
; Bound: 44
OpCapability Shader
OpCapability VulkanMemoryModel
OpMemoryModel Logical Vulkan
OpEntryPoint GLCompute %1 "main" %2 %3
OpExecutionMode %1 LocalSize 32 1 1
%4 = OpString "/home/firestar99/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/glam-0.30.5/src/u32/uvec4.rs"
%5 = OpString "$DIR/minify.rs"
OpSource Unknown 0 %4 "<removed>"
OpSource Unknown 0 %5 "<removed>"
OpName %2 "input"
OpName %3 "output"
OpDecorate %6 Block
OpMemberDecorate %6 0 Offset 0
OpDecorate %7 ArrayStride 4
OpDecorate %8 Block
OpMemberDecorate %8 0 Offset 0
OpDecorate %2 NonWritable
OpDecorate %2 Binding 0
OpDecorate %2 DescriptorSet 0
OpDecorate %3 Binding 1
OpDecorate %3 DescriptorSet 0
%9 = OpTypeInt 32 0
%10 = OpTypeVector %9 4
%6 = OpTypeStruct %10
%11 = OpTypePointer StorageBuffer %6
%7 = OpTypeRuntimeArray %9
%8 = OpTypeStruct %7
%12 = OpTypePointer StorageBuffer %8
%13 = OpTypeVoid
%14 = OpTypeFunction %13
%15 = OpTypePointer StorageBuffer %10
%2 = OpVariable %11 StorageBuffer
%16 = OpConstant %9 0
%17 = OpTypePointer StorageBuffer %7
%3 = OpVariable %12 StorageBuffer
%18 = OpTypePointer StorageBuffer %9
%19 = OpConstant %9 1
%20 = OpConstant %9 2
%21 = OpConstant %9 3
%22 = OpTypeBool
%1 = OpFunction %13 None %14
%23 = OpLabel
OpLine %5 9 4
%24 = OpInBoundsAccessChain %15 %2 %16
OpLine %5 10 4
%25 = OpInBoundsAccessChain %17 %3 %16
%26 = OpArrayLength %9 %3 0
OpNoLine
OpSelectionMerge %27 None
OpSwitch %16 %28 0 %29 1 %30 2 %31 3 %32
%28 = OpLabel
OpReturn
%29 = OpLabel
OpLine %4 2910 17
%33 = OpInBoundsAccessChain %18 %24 %16
OpNoLine
OpBranch %27
%30 = OpLabel
OpLine %4 2911 17
%34 = OpInBoundsAccessChain %18 %24 %19
OpNoLine
OpBranch %27
%31 = OpLabel
OpLine %4 2912 17
%35 = OpInBoundsAccessChain %18 %24 %20
OpNoLine
OpBranch %27
%32 = OpLabel
OpLine %4 2913 17
%36 = OpInBoundsAccessChain %18 %24 %21
OpNoLine
OpBranch %27
%27 = OpLabel
%37 = OpPhi %18 %33 %29 %34 %30 %35 %31 %36 %32
OpLine %5 15 16
%38 = OpLoad %9 %37
OpLine %5 15 4
%39 = OpULessThan %22 %16 %26
OpNoLine
OpSelectionMerge %40 None
OpBranchConditional %39 %41 %42
%41 = OpLabel
OpBranch %40
%42 = OpLabel
OpReturn
%40 = OpLabel
OpLine %5 15 4
%43 = OpInBoundsAccessChain %18 %25 %16
OpStore %43 %38
OpNoLine
OpReturn
OpFunctionEnd
error: error:0:0 - Using pointers with OpPhi requires capability VariablePointers or VariablePointersStorageBuffer
%37 = OpPhi %_ptr_StorageBuffer_uint %33 %29 %34 %30 %35 %31 %36 %32
|
= note: spirv-val failed
= note: module `$TEST_BUILD_DIR/arch/shared/minify.vulkan1.2`
error: aborting due to 1 previous error
Notes
- was messing around with shared memory to test Erase explicit layout decorations (
Offset
/ArrayStride
) when disallowed by Vulkan. #379, there is no actual practical usecase for this - has nothing to do with shared memory itself
- structurization bug so @eddyb?
- I don't need this to be fixed anytime soon, feel free to delay it until "qptr will fix"
Analysis
- The assembly looks very much like this function:
impl Index<usize> for UVec4 {
type Output = u32;
#[inline]
fn index(&self, index: usize) -> &Self::Output {
match index {
0 => &self.x,
1 => &self.y,
2 => &self.z,
3 => &self.w,
_ => panic!("index out of bounds"),
}
}
}
- The function is inlined, but the returned
&u32
is still forwarded as a pointer - The
OpPhi
is after the switch, merging the different branches all returning the&u32
- The deref to
u32
only happens afterwards
System Info
rust-gpu main dbf3737
More compiletests
vec
// build-pass
use spirv_std::arch::workgroup_memory_barrier_with_group_sync;
use spirv_std::glam::*;
use spirv_std::spirv;
#[spirv(compute(threads(32)))]
pub fn main(
#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] input: &UVec4,
#[spirv(descriptor_set = 0, binding = 1, storage_buffer)] output: &mut [u32],
#[spirv(workgroup)] shared: &mut UVec4,
#[spirv(local_invocation_index)] inv_id: UVec3,
) {
unsafe {
// copy from input to shared
if (inv_id.x == 0) {
*shared = *input;
}
workgroup_memory_barrier_with_group_sync();
// accumulate random values
let mut accum = 0;
for i in 0..inv_id.x {
accum += shared[i as usize % 4];
}
// write out
output[inv_id.x as usize] = accum;
}
}
BigStruct
// build-pass
use spirv_std::arch::workgroup_memory_barrier_with_group_sync;
use spirv_std::glam::*;
use spirv_std::spirv;
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct MyStruct {
pub a: Nested,
pub b: Mat4,
pub c: UVec2,
}
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct Nested(pub f32);
#[spirv(compute(threads(32)))]
pub fn main(
#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] input: &MyStruct,
#[spirv(descriptor_set = 0, binding = 1, storage_buffer)] output: &mut [MyStruct],
#[spirv(workgroup)] shared: &mut MyStruct,
#[spirv(local_invocation_index)] inv_id: UVec3,
) {
unsafe {
// copy from input to shared
if (inv_id.x == 0) {
*shared = *input;
}
workgroup_memory_barrier_with_group_sync();
// accumulate random values
let mut accum = 0.;
accum += shared.a.0;
accum += shared.c.x as f32;
for axis_id in 0..4 {
let axis = [shared.b.x_axis, shared.b.y_axis, shared.b.z_axis, shared.b.w_axis][axis_id];
accum += axis[inv_id.x as usize % 4];
}
// write out
output[inv_id.x as usize].a.0 = accum;
}
}
nazar-pc
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working