| ... | ... | @@ -617,7 +617,8 @@ pub fn structType( |
| 617 | 617 | |
| 618 | 618 | /// Returns the layout-decorated variant of `ty` for use inside a Vulkan/OpenGL |
| 619 | 619 | /// 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. |
| 621 | 622 | /// |
| 622 | 623 | /// This is distinct from `resolveType` because SPIR-V forbids such decorations |
| 623 | 624 | /// 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 { |
| 695 | 696 | }, |
| 696 | 697 | .array => id: { |
| 697 | 698 | 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); |
| 699 | 700 | const total_len = std.math.cast(u32, ty.arrayLenIncludingSentinel(zcu)) orelse |
| 700 | 701 | return cg.fail("array type of {} elements is too large", .{ty.arrayLenIncludingSentinel(zcu)}); |
| 701 | 702 | 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 | } |
| 705 | 708 | break :id id; |
| 706 | 709 | }, |
| 707 | 710 | .spirv => if (ty.isSpirvRuntimeArray(zcu)) id: { |
| 708 | 711 | 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); |
| 710 | 713 | const id = cg.allocId(); |
| 711 | 714 | try cg.sections.globals.emit(gpa, .OpTypeRuntimeArray, .{ |
| 712 | 715 | .id_result = id, |
| 713 | 716 | .element_type = elem_ty_id, |
| 714 | 717 | }); |
| 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 | } |
| 718 | 723 | break :id id; |
| 719 | 724 | } else return cg.resolveType(ty, .indirect), |
| 720 | 725 | else => return cg.resolveType(ty, .indirect), |
| ... | ... | @@ -955,11 +960,18 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void { |
| 955 | 960 | switch (target.os.tag) { |
| 956 | 961 | .vulkan, .opengl => { |
| 957 | 962 | 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 | => { |
| 959 | 968 | 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 | } |
| 963 | 975 | if (!cg.needsLayout(as, ty)) try cg.decorateLayout(ty, ty_id); |
| 964 | 976 | } |
| 965 | 977 | if (key.is_const and storage_class == .storage_buffer) { |