OpDecorate with Block/BufferBlock isn't working properly
Context
I'm working on a basic compiler for converting Rust functions to SPIR-V using proc macros and rspirv (to achieve similar functionality as CUDA)
Error
When compiling buffers to parameters I'm having an issue where the correlating OpTypeStruct (this: %_struct_5 = OpTypeStruct %_runtimearr_float) doesn't actually get decorated with Block despite marking aforementioned type with Block using rspirv.
Code Snippet
This is from withing a struct that uses a handful of hashmaps to store and access variable ids and type ids:
// get word of the type of the elements in the runtime arr
let base_word = self.types.get(arr_ty).ok_or(anyhow!(
"failed to retrieve base type of runtime arr: {:?}",
arr_ty
))?;
// create runtime arr type (pretty simple)
let runtime_ty = self.spirv_builder.type_runtime_array(*base_word);
// create a struct type
let struct_ty = self.spirv_builder.type_struct(vec![runtime_ty]);
self.spirv_builder.decorate(
struct_ty,
rspirv::spirv::Decoration::Block,
vec![],
);
let lit_0 = self.literals
.get(&MimirLit::Int32(0))
.ok_or(anyhow!("Failed to find literal 0 for struct decoration"))?;
self.spirv_builder.member_decorate(
struct_ty,
*lit_0,
rspirv::spirv::Decoration::Offset,
vec![rspirv::dr::Operand::LiteralBit32(0)]
);
SPIR-V
Outputted SPIR-V for my compiler:
saxpy.spirv.txt
Because the SPIR-V contains %_runtimearr_float = OpTypeRuntimeArray %float and
%_struct_5 = OpTypeStruct %_runtimearr_float the code for generating buffers is being called but the types are not being decorated properly.
Thank you in advance for any help, thank you!
Hi,
which version you are using? Unfortunately I'm unable to open the file, reports an error when trying to download. I put together a small program with rspirv:0.12.0 which outputs the decoration just fine:
use rspirv::binary::{Assemble, Disassemble};
use rspirv::spirv;
fn main() {
let mut b = rspirv::dr::Builder::new();
b.set_version(1, 0);
b.capability(spirv::Capability::Shader);
b.memory_model(spirv::AddressingModel::Logical, spirv::MemoryModel::GLSL450);
let ty_f32 = b.type_float(32);
let runtime_ty = b.type_runtime_array(ty_f32);
let struct_ty = b.type_struct(vec![runtime_ty]);
b.decorate(struct_ty, rspirv::spirv::Decoration::Block, vec![]);
b.member_decorate(
struct_ty,
0, // note: this should be an immediate value not an id
rspirv::spirv::Decoration::Offset,
vec![rspirv::dr::Operand::LiteralBit32(0)],
);
let module = b.module();
let code = module.assemble();
let mut loader = rspirv::dr::Loader::new();
rspirv::binary::parse_words(&code, &mut loader).unwrap();
let module = loader.module();
println!("{}", module.disassemble());
}
; SPIR-V
; Version: 1.0
; Generator: rspirv
; Bound: 4
OpCapability Shader
OpMemoryModel Logical GLSL450
OpDecorate %3 Block
OpMemberDecorate %3 0 Offset 0
%1 = OpTypeFloat 32
%2 = OpTypeRuntimeArray %1
%3 = OpTypeStruct %2
I'm using rspirv: 0.12.0 as well, the outputted SPIR-V is as below, I'm unsure what could be causing this. I might have to line by line debug my compiler once I'm out of school.
Outputted SPIR_V:
; SPIR-V
; Version: 1.2
; Generator: Google rspirv; 0
; Bound: 64
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %35 "main" %gl_WorkGroupID %gl_LocalInvocationID
OpSource Unknown 1
OpName %x "x"
OpName %y "y"
OpName %idx "idx"
OpName %idx "idx"
OpDecorate %20 SpecId 0
OpDecorate %21 SpecId 1
OpDecorate %22 SpecId 2
OpDecorate %gl_WorkGroupID BuiltIn WorkgroupId
OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize
OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
OpDecorate %x Binding 0
OpDecorate %x DescriptorSet 0
OpDecorate %y Binding 1
OpDecorate %y DescriptorSet 0
%void = OpTypeVoid
%uint = OpTypeInt 32 0
%v3uint = OpTypeVector %uint 3
%float = OpTypeFloat 32
%int = OpTypeInt 32 1
%_runtimearr_float = OpTypeRuntimeArray %float
%_struct_8 = OpTypeStruct %_runtimearr_float
%_ptr_Function_float = OpTypePointer Function %float
%_ptr_Function_int = OpTypePointer Function %int
%_ptr_PushConstant_int = OpTypePointer PushConstant %int
%_ptr_PushConstant_float = OpTypePointer PushConstant %float
%_ptr_Input_v3uint = OpTypePointer Input %v3uint
%_ptr_Function_uint = OpTypePointer Function %uint
%_ptr_Uniform_float = OpTypePointer Uniform %float
%_ptr_Uniform__struct_8 = OpTypePointer Uniform %_struct_8
%bool = OpTypeBool
%_ptr_Function_bool = OpTypePointer Function %bool
%19 = OpTypeFunction %void
%20 = OpSpecConstant %uint 1
%21 = OpSpecConstant %uint 1
%22 = OpSpecConstant %uint 1
%_ptr_Input_uint = OpTypePointer Input %uint
%gl_WorkGroupID = OpVariable %_ptr_Input_v3uint Input
%gl_WorkGroupSize = OpSpecConstantComposite %v3uint %20 %21 %22
%gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
%int_2 = OpConstant %int 2
%int_1 = OpConstant %int 1
%int_0 = OpConstant %int 0
%x = OpVariable %_ptr_Uniform__struct_8 Uniform
%y = OpVariable %_ptr_Uniform__struct_8 Uniform
%_struct_32 = OpTypeStruct %int %float
%_ptr_PushConstant__struct_32 = OpTypePointer PushConstant %_struct_32
%34 = OpVariable %_ptr_PushConstant__struct_32 PushConstant
%int_1_0 = OpConstant %int 1
%35 = OpFunction %void None %19
%36 = OpLabel
%idx = OpVariable %_ptr_Function_uint Function
%39 = OpAccessChain %_ptr_Input_uint %gl_WorkGroupID %int_0
%40 = OpLoad %uint %39
%41 = OpCompositeExtract %uint %gl_WorkGroupSize 0
%42 = OpIMul %uint %40 %41
%43 = OpAccessChain %_ptr_Input_uint %gl_LocalInvocationID %int_0
%44 = OpLoad %uint %43
%45 = OpIAdd %uint %42 %44
OpStore %idx %45
%46 = OpLoad %uint %idx
%47 = OpAccessChain %_ptr_PushConstant_int %34 %int_0
%48 = OpLoad %int %47
%49 = OpULessThan %bool %46 %48
OpSelectionMerge %50 None
OpBranchConditional %49 %51 %50
%51 = OpLabel
%52 = OpLoad %uint %idx
%53 = OpAccessChain %_ptr_Uniform_float %y %int_0 %52
%54 = OpAccessChain %_ptr_PushConstant_float %34 %int_1_0
%55 = OpLoad %float %54
%56 = OpLoad %uint %idx
%57 = OpAccessChain %_ptr_Uniform_float %x %int_0 %56
%58 = OpLoad %float %57
%59 = OpFMul %float %55 %58
%60 = OpLoad %uint %idx
%61 = OpAccessChain %_ptr_Uniform_float %y %int_0 %60
%62 = OpLoad %float %61
%63 = OpFAdd %float %59 %62
OpStore %53 %63
OpBranch %50
%50 = OpLabel
OpReturn
OpFunctionEnd