authorgravatar for alichraghi@proton.meAli Chraghi <alichraghi@proton.me> 2026-08-25 21:55:19+03:30
committergravatar for alichraghi@proton.meAli Chraghi <alichraghi@proton.me> 2026-08-26 08:13:06+03:30
log591b2a47f79fa07e87d3b625320135de8446a274
treefd3bdbf644552665d34841fd31774fa5c158acad
parent21575a44837861c0c9a7b2b42904afb0933995ea

spirv: emit descriptor arrays for uniform and storage buffers


1 files changed, 25 insertions(+), 13 deletions(-)

src/codegen/spirv/CodeGen.zig+25-13
......@@ -617,7 +617,8 @@ pub fn structType(
617617
618618/// Returns the layout-decorated variant of `ty` for use inside a Vulkan/OpenGL
619619/// interface block. Vulkan forbids nested Block decorations, so recursive calls
620/// always pass `false`.
620/// pass `false`, except through an array, whose elements are each a
621/// block of their own.
621622///
622623/// This is distinct from `resolveType` because SPIR-V forbids such decorations
623624/// on the pointee of a Function-scope variable.
......@@ -695,26 +696,30 @@ pub fn layoutType(cg: *CodeGen, ty: Type, is_block_root: bool) Error!Id {
695696 },
696697 .array => id: {
697698 const elem_ty = ty.childType(zcu);
698 const elem_ty_id = try cg.layoutType(elem_ty, false);
699 const elem_ty_id = try cg.layoutType(elem_ty, is_block_root);
699700 const total_len = std.math.cast(u32, ty.arrayLenIncludingSentinel(zcu)) orelse
700701 return cg.fail("array type of {} elements is too large", .{ty.arrayLenIncludingSentinel(zcu)});
701702 const id = try cg.arrayType(try cg.constInt(.u32, total_len), elem_ty_id);
702 if (elem_ty.hasRuntimeBits(zcu)) try cg.decorate(id, .{
703 .array_stride = .{ .array_stride = @intCast(elem_ty.abiSize(zcu)) },
704 });
703 if (!is_block_root and elem_ty.hasRuntimeBits(zcu)) {
704 try cg.decorate(id, .{
705 .array_stride = .{ .array_stride = @intCast(elem_ty.abiSize(zcu)) },
706 });
707 }
705708 break :id id;
706709 },
707710 .spirv => if (ty.isSpirvRuntimeArray(zcu)) id: {
708711 const elem_ty = ty.childType(zcu);
709 const elem_ty_id = try cg.layoutType(elem_ty, false);
712 const elem_ty_id = try cg.layoutType(elem_ty, is_block_root);
710713 const id = cg.allocId();
711714 try cg.sections.globals.emit(gpa, .OpTypeRuntimeArray, .{
712715 .id_result = id,
713716 .element_type = elem_ty_id,
714717 });
715 if (elem_ty.hasRuntimeBits(zcu)) try cg.decorate(id, .{
716 .array_stride = .{ .array_stride = @intCast(elem_ty.abiSize(zcu)) },
717 });
718 if (!is_block_root and elem_ty.hasRuntimeBits(zcu)) {
719 try cg.decorate(id, .{
720 .array_stride = .{ .array_stride = @intCast(elem_ty.abiSize(zcu)) },
721 });
722 }
718723 break :id id;
719724 } else return cg.resolveType(ty, .indirect),
720725 else => return cg.resolveType(ty, .indirect),
......@@ -955,11 +960,18 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
955960 switch (target.os.tag) {
956961 .vulkan, .opengl => {
957962 switch (storage_class) {
958 .uniform, .push_constant, .storage_buffer, .physical_storage_buffer => {
963 .uniform,
964 .push_constant,
965 .storage_buffer,
966 .physical_storage_buffer,
967 => {
959968 if (ty.hasRuntimeBits(zcu)) {
960 try cg.decorate(ptr_ty_id, .{
961 .array_stride = .{ .array_stride = @intCast(ty.abiSize(zcu)) },
962 });
969 if (!ty.isSpirvRuntimeArray(zcu)) {
970 try cg.decorate(
971 ptr_ty_id,
972 .{ .array_stride = .{ .array_stride = @intCast(ty.abiSize(zcu)) } },
973 );
974 }
963975 if (!cg.needsLayout(as, ty)) try cg.decorateLayout(ty, ty_id);
964976 }
965977 if (key.is_const and storage_class == .storage_buffer) {