Skip to content
This repository has been archived by the owner on Jan 29, 2025. It is now read-only.

Commit

Permalink
Support buffer resource arrays in IR, wgsl-in, and spv-out
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark committed Mar 16, 2023
1 parent a3787be commit 8e13d58
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 7 deletions.
5 changes: 2 additions & 3 deletions src/back/spv/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,8 @@ impl<'w> BlockContext<'w> {
fn is_intermediate(&self, expr_handle: Handle<crate::Expression>) -> bool {
match self.ir_function.expressions[expr_handle] {
crate::Expression::GlobalVariable(handle) => {
let ty = self.ir_module.global_variables[handle].ty;
match self.ir_module.types[ty].inner {
crate::TypeInner::BindingArray { .. } => false,
match self.ir_module.global_variables[handle].space {
crate::AddressSpace::Handle => false,
_ => true,
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/back/spv/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ pub fn global_needs_wrapper(ir_module: &crate::Module, var: &crate::GlobalVariab
},
None => false,
},
// if it's not a structure, let's wrap it to be able to put "Block"
crate::TypeInner::BindingArray { .. } => false,
// if it's not a structure or a binding array, let's wrap it to be able to put "Block"
_ => true,
}
}
8 changes: 7 additions & 1 deletion src/back/spv/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1613,7 +1613,13 @@ impl Writer {
// a runtime-sized array. In this case, we need to decorate it with
// Block.
if let crate::AddressSpace::Storage { .. } = global_variable.space {
self.decorate(inner_type_id, Decoration::Block, &[]);
let decorated_id = match ir_module.types[global_variable.ty].inner {
crate::TypeInner::BindingArray { base, .. } => {
self.get_type_id(LookupType::Handle(base))
}
_ => inner_type_id,
};
self.decorate(decorated_id, Decoration::Block, &[]);
}
if substitute_inner_type_lookup.is_some() {
inner_type_id
Expand Down
4 changes: 3 additions & 1 deletion src/proc/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,9 @@ impl crate::TypeInner {
match *base_inner {
Ti::Vector { size, .. } => size as _,
Ti::Matrix { columns, .. } => columns as _,
Ti::Array { size, .. } => return size.to_indexable_length(module),
Ti::Array { size, .. } | Ti::BindingArray { size, .. } => {
return size.to_indexable_length(module)
}
_ => return Err(IndexableLengthError::TypeNotIndexable),
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/proc/typifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ impl<'a> ResolveContext<'a> {
width,
space,
},
Ti::BindingArray { base, .. } => Ti::Pointer { base, space },
ref other => {
log::error!("Access sub-type {:?}", other);
return Err(ResolveError::InvalidSubAccess {
Expand Down Expand Up @@ -401,6 +402,7 @@ impl<'a> ResolveContext<'a> {
space,
}
}
Ti::BindingArray { base, .. } => Ti::Pointer { base, space },
ref other => {
log::error!("Access index sub-type {:?}", other);
return Err(ResolveError::InvalidSubAccess {
Expand Down
7 changes: 6 additions & 1 deletion src/valid/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,12 @@ impl super::Validator {
self.require_type_capability(Capabilities::RAY_QUERY)?;
TypeInfo::new(TypeFlags::DATA | TypeFlags::SIZED, Alignment::ONE)
}
Ti::BindingArray { .. } => TypeInfo::new(TypeFlags::empty(), Alignment::ONE),
Ti::BindingArray { base, size: _ } => {
if base >= handle {
return Err(TypeError::UnresolvedBase(base));
}
self.types[base.index()].clone()
}
})
}
}
14 changes: 14 additions & 0 deletions tests/in/binding-buffer-arrays.param.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
(
god_mode: true,
spv: (
version: (1, 1),
binding_map: {
(group: 0, binding: 0): (binding_array_size: Some(10)),
},
),
bounds_check_policies: (
index: ReadZeroSkipWrite,
buffer: ReadZeroSkipWrite,
image: ReadZeroSkipWrite,
)
)
27 changes: 27 additions & 0 deletions tests/in/binding-buffer-arrays.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
struct UniformIndex {
index: u32
};

struct Foo { x: u32 }
@group(0) @binding(0)
var<storage, read> storage_array: binding_array<Foo, 5>;
@group(0) @binding(10)
var<uniform> uni: UniformIndex;

struct FragmentIn {
@location(0) index: u32,
};

@fragment
fn main(fragment_in: FragmentIn) -> @location(0) u32 {
let uniform_index = uni.index;
let non_uniform_index = fragment_in.index;

var u1 = 0u;

u1 += storage_array[0].x;
u1 += storage_array[uniform_index].x;
u1 += storage_array[non_uniform_index].x;

return u1;
}
103 changes: 103 additions & 0 deletions tests/out/spv/binding-buffer-arrays.spvasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
; SPIR-V
; Version: 1.1
; Generator: rspirv
; Bound: 66
OpCapability Shader
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %29 "main" %24 %27
OpExecutionMode %29 OriginUpperLeft
OpMemberDecorate %8 0 Offset 0
OpMemberDecorate %9 0 Offset 0
OpMemberDecorate %11 0 Offset 0
OpDecorate %12 NonWritable
OpDecorate %12 DescriptorSet 0
OpDecorate %12 Binding 0
OpDecorate %9 Block
OpDecorate %16 DescriptorSet 0
OpDecorate %16 Binding 10
OpDecorate %17 Block
OpMemberDecorate %17 0 Offset 0
OpDecorate %24 Location 0
OpDecorate %24 Flat
OpDecorate %27 Location 0
OpDecorate %27 Flat
%2 = OpTypeVoid
%4 = OpTypeInt 32 1
%3 = OpConstant %4 5
%6 = OpTypeInt 32 0
%5 = OpConstant %6 0
%7 = OpConstant %4 0
%8 = OpTypeStruct %6
%9 = OpTypeStruct %6
%10 = OpTypeArray %9 %3
%11 = OpTypeStruct %6
%15 = OpConstant %6 10
%14 = OpTypeArray %9 %15
%13 = OpTypePointer UniformConstant %14
%12 = OpVariable %13 StorageBuffer
%17 = OpTypeStruct %8
%18 = OpTypePointer Uniform %17
%16 = OpVariable %18 Uniform
%20 = OpTypePointer Function %6
%21 = OpConstantNull %6
%25 = OpTypePointer Input %6
%24 = OpVariable %25 Input
%28 = OpTypePointer Output %6
%27 = OpVariable %28 Output
%30 = OpTypeFunction %2
%31 = OpTypePointer Uniform %8
%33 = OpTypePointer StorageBuffer %10
%35 = OpTypePointer Uniform %6
%39 = OpTypePointer StorageBuffer %9
%40 = OpTypePointer StorageBuffer %6
%45 = OpConstant %6 5
%47 = OpTypeBool
%49 = OpConstantNull %6
%58 = OpConstantNull %6
%29 = OpFunction %2 None %30
%22 = OpLabel
%19 = OpVariable %20 Function %21
%26 = OpLoad %6 %24
%23 = OpCompositeConstruct %11 %26
%32 = OpAccessChain %31 %16 %5
OpBranch %34
%34 = OpLabel
%36 = OpAccessChain %35 %32 %5
%37 = OpLoad %6 %36
%38 = OpCompositeExtract %6 %23 0
OpStore %19 %5
%41 = OpAccessChain %40 %12 %5 %5
%42 = OpLoad %6 %41
%43 = OpLoad %6 %19
%44 = OpIAdd %6 %43 %42
OpStore %19 %44
%46 = OpULessThan %47 %37 %45
OpSelectionMerge %50 None
OpBranchConditional %46 %51 %50
%51 = OpLabel
%48 = OpAccessChain %40 %12 %37 %5
%52 = OpLoad %6 %48
OpBranch %50
%50 = OpLabel
%53 = OpPhi %6 %49 %34 %52 %51
%54 = OpLoad %6 %19
%55 = OpIAdd %6 %54 %53
OpStore %19 %55
%56 = OpULessThan %47 %38 %45
OpSelectionMerge %59 None
OpBranchConditional %56 %60 %59
%60 = OpLabel
%57 = OpAccessChain %40 %12 %38 %5
%61 = OpLoad %6 %57
OpBranch %59
%59 = OpLabel
%62 = OpPhi %6 %58 %50 %61 %60
%63 = OpLoad %6 %19
%64 = OpIAdd %6 %63 %62
OpStore %19 %64
%65 = OpLoad %6 %19
OpStore %27 %65
OpReturn
OpFunctionEnd
4 changes: 4 additions & 0 deletions tests/snapshots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,10 @@ fn convert_wgsl() {
"binding-arrays",
Targets::WGSL | Targets::HLSL | Targets::METAL | Targets::SPIRV,
),
(
"binding-buffer-arrays",
Targets::SPIRV, //TODO: more backends, eventually merge into "binding-arrays"
),
("multiview", Targets::SPIRV | Targets::GLSL | Targets::WGSL),
("multiview_webgl", Targets::GLSL),
(
Expand Down

0 comments on commit 8e13d58

Please sign in to comment.