| ... | ... | @@ -169,12 +169,10 @@ pub const Object = struct { |
| 169 | 169 | /// via the usual `intern_map` mechanism. |
| 170 | 170 | ptr_types: PtrTypeMap = .{}, |
| 171 | 171 | |
| 172 | | /// For test declarations for Vulkan, we have to add a push constant with a pointer to a |
| 173 | | /// buffer that we can use. We only need to generate this once, this holds the link information |
| 172 | /// For test declarations for Vulkan, we have to add a buffer. |
| 173 | /// We only need to generate this once, this holds the link information |
| 174 | 174 | /// related to that. |
| 175 | | error_push_constant: ?struct { |
| 176 | | push_constant_ptr: SpvModule.Decl.Index, |
| 177 | | } = null, |
| 175 | error_buffer: ?SpvModule.Decl.Index = null, |
| 178 | 176 | |
| 179 | 177 | pub fn init(gpa: Allocator, target: std.Target) Object { |
| 180 | 178 | return .{ |
| ... | ... | @@ -1739,15 +1737,34 @@ const NavGen = struct { |
| 1739 | 1737 | fn spvStorageClass(self: *NavGen, as: std.builtin.AddressSpace) StorageClass { |
| 1740 | 1738 | return switch (as) { |
| 1741 | 1739 | .generic => if (self.spv.hasFeature(.generic_pointer)) .Generic else .Function, |
| 1740 | .global => { |
| 1741 | if (self.spv.hasFeature(.kernel)) return .CrossWorkgroup; |
| 1742 | return .StorageBuffer; |
| 1743 | }, |
| 1744 | .push_constant => { |
| 1745 | assert(self.spv.hasFeature(.shader)); |
| 1746 | return .PushConstant; |
| 1747 | }, |
| 1748 | .output => { |
| 1749 | assert(self.spv.hasFeature(.shader)); |
| 1750 | return .Output; |
| 1751 | }, |
| 1752 | .uniform => { |
| 1753 | assert(self.spv.hasFeature(.shader)); |
| 1754 | return .Uniform; |
| 1755 | }, |
| 1756 | .storage_buffer => { |
| 1757 | assert(self.spv.hasFeature(.shader)); |
| 1758 | return .StorageBuffer; |
| 1759 | }, |
| 1760 | .physical_storage_buffer => { |
| 1761 | assert(self.spv.hasFeature(.physical_storage_buffer)); |
| 1762 | return .PhysicalStorageBuffer; |
| 1763 | }, |
| 1764 | .constant => .UniformConstant, |
| 1742 | 1765 | .shared => .Workgroup, |
| 1743 | 1766 | .local => .Function, |
| 1744 | | .global => if (self.spv.hasFeature(.shader)) .PhysicalStorageBuffer else .CrossWorkgroup, |
| 1745 | | .constant => .UniformConstant, |
| 1746 | | .push_constant => .PushConstant, |
| 1747 | 1767 | .input => .Input, |
| 1748 | | .output => .Output, |
| 1749 | | .uniform => .Uniform, |
| 1750 | | .storage_buffer => .StorageBuffer, |
| 1751 | 1768 | .gs, |
| 1752 | 1769 | .fs, |
| 1753 | 1770 | .ss, |
| ... | ... | @@ -2713,38 +2730,32 @@ const NavGen = struct { |
| 2713 | 2730 | }); |
| 2714 | 2731 | }, |
| 2715 | 2732 | .vulkan, .opengl => { |
| 2716 | | const ptr_ptr_anyerror_ty_id = self.spv.allocId(); |
| 2717 | | try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpTypePointer, .{ |
| 2718 | | .id_result = ptr_ptr_anyerror_ty_id, |
| 2719 | | .storage_class = .PushConstant, |
| 2720 | | .type = ptr_anyerror_ty_id, |
| 2721 | | }); |
| 2722 | | |
| 2723 | | if (self.object.error_push_constant == null) { |
| 2733 | if (self.object.error_buffer == null) { |
| 2724 | 2734 | const spv_err_decl_index = try self.spv.allocDecl(.global); |
| 2725 | 2735 | try self.spv.declareDeclDeps(spv_err_decl_index, &.{}); |
| 2726 | 2736 | |
| 2727 | | const push_constant_struct_ty_id = self.spv.allocId(); |
| 2728 | | try self.spv.structType(push_constant_struct_ty_id, &.{ptr_anyerror_ty_id}, &.{"error_out_ptr"}); |
| 2729 | | try self.spv.decorate(push_constant_struct_ty_id, .Block); |
| 2730 | | try self.spv.decorateMember(push_constant_struct_ty_id, 0, .{ .Offset = .{ .byte_offset = 0 } }); |
| 2737 | const buffer_struct_ty_id = self.spv.allocId(); |
| 2738 | try self.spv.structType(buffer_struct_ty_id, &.{anyerror_ty_id}, &.{"error_out"}); |
| 2739 | try self.spv.decorate(buffer_struct_ty_id, .Block); |
| 2740 | try self.spv.decorateMember(buffer_struct_ty_id, 0, .{ .Offset = .{ .byte_offset = 0 } }); |
| 2731 | 2741 | |
| 2732 | | const ptr_push_constant_struct_ty_id = self.spv.allocId(); |
| 2742 | const ptr_buffer_struct_ty_id = self.spv.allocId(); |
| 2733 | 2743 | try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpTypePointer, .{ |
| 2734 | | .id_result = ptr_push_constant_struct_ty_id, |
| 2735 | | .storage_class = .PushConstant, |
| 2736 | | .type = push_constant_struct_ty_id, |
| 2744 | .id_result = ptr_buffer_struct_ty_id, |
| 2745 | .storage_class = self.spvStorageClass(.global), |
| 2746 | .type = buffer_struct_ty_id, |
| 2737 | 2747 | }); |
| 2738 | 2748 | |
| 2749 | const buffer_struct_id = self.spv.declPtr(spv_err_decl_index).result_id; |
| 2739 | 2750 | try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpVariable, .{ |
| 2740 | | .id_result_type = ptr_push_constant_struct_ty_id, |
| 2741 | | .id_result = self.spv.declPtr(spv_err_decl_index).result_id, |
| 2742 | | .storage_class = .PushConstant, |
| 2751 | .id_result_type = ptr_buffer_struct_ty_id, |
| 2752 | .id_result = buffer_struct_id, |
| 2753 | .storage_class = self.spvStorageClass(.global), |
| 2743 | 2754 | }); |
| 2755 | try self.spv.decorate(buffer_struct_id, .{ .DescriptorSet = .{ .descriptor_set = 0 } }); |
| 2756 | try self.spv.decorate(buffer_struct_id, .{ .Binding = .{ .binding_point = 0 } }); |
| 2744 | 2757 | |
| 2745 | | self.object.error_push_constant = .{ |
| 2746 | | .push_constant_ptr = spv_err_decl_index, |
| 2747 | | }; |
| 2758 | self.object.error_buffer = spv_err_decl_index; |
| 2748 | 2759 | } |
| 2749 | 2760 | |
| 2750 | 2761 | try self.spv.sections.execution_modes.emit(self.spv.gpa, .OpExecutionMode, .{ |
| ... | ... | @@ -2767,24 +2778,16 @@ const NavGen = struct { |
| 2767 | 2778 | .id_result = self.spv.allocId(), |
| 2768 | 2779 | }); |
| 2769 | 2780 | |
| 2770 | | const spv_err_decl_index = self.object.error_push_constant.?.push_constant_ptr; |
| 2771 | | const push_constant_id = self.spv.declPtr(spv_err_decl_index).result_id; |
| 2781 | const spv_err_decl_index = self.object.error_buffer.?; |
| 2782 | const buffer_id = self.spv.declPtr(spv_err_decl_index).result_id; |
| 2772 | 2783 | try decl_deps.append(spv_err_decl_index); |
| 2773 | 2784 | |
| 2774 | 2785 | const zero_id = try self.constInt(Type.u32, 0); |
| 2775 | | // We cannot use OpInBoundsAccessChain to dereference cross-storage class, so we have to use |
| 2776 | | // a load. |
| 2777 | | const tmp = self.spv.allocId(); |
| 2778 | 2786 | try section.emit(self.spv.gpa, .OpInBoundsAccessChain, .{ |
| 2779 | | .id_result_type = ptr_ptr_anyerror_ty_id, |
| 2780 | | .id_result = tmp, |
| 2781 | | .base = push_constant_id, |
| 2782 | | .indexes = &.{zero_id}, |
| 2783 | | }); |
| 2784 | | try section.emit(self.spv.gpa, .OpLoad, .{ |
| 2785 | 2787 | .id_result_type = ptr_anyerror_ty_id, |
| 2786 | 2788 | .id_result = p_error_id, |
| 2787 | | .pointer = tmp, |
| 2789 | .base = buffer_id, |
| 2790 | .indexes = &.{zero_id}, |
| 2788 | 2791 | }); |
| 2789 | 2792 | }, |
| 2790 | 2793 | else => unreachable, |
| ... | ... | @@ -4562,7 +4565,8 @@ const NavGen = struct { |
| 4562 | 4565 | const field_int_id = blk: { |
| 4563 | 4566 | if (field_ty.isPtrAtRuntime(zcu)) { |
| 4564 | 4567 | assert(self.spv.hasFeature(.addresses) or |
| 4565 | | (self.spv.hasFeature(.physical_storage_buffer) and field_ty.ptrAddressSpace(zcu) == .storage_buffer)); |
| 4568 | (self.spv.hasFeature(.physical_storage_buffer) and |
| 4569 | field_ty.ptrAddressSpace(zcu) == .storage_buffer)); |
| 4566 | 4570 | break :blk try self.intFromPtr(field_id); |
| 4567 | 4571 | } |
| 4568 | 4572 | break :blk try self.bitCast(field_int_ty, field_ty, field_id); |
| ... | ... | @@ -4969,13 +4973,16 @@ const NavGen = struct { |
| 4969 | 4973 | if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { |
| 4970 | 4974 | const pl_ptr_ty_id = try self.ptrType(layout.payload_ty, .Function, .indirect); |
| 4971 | 4975 | const pl_ptr_id = try self.accessChain(pl_ptr_ty_id, tmp_id, &.{layout.payload_index}); |
| 4972 | | const active_pl_ptr_ty_id = try self.ptrType(payload_ty, .Function, .indirect); |
| 4973 | | const active_pl_ptr_id = self.spv.allocId(); |
| 4974 | | try self.func.body.emit(self.spv.gpa, .OpBitcast, .{ |
| 4975 | | .id_result_type = active_pl_ptr_ty_id, |
| 4976 | | .id_result = active_pl_ptr_id, |
| 4977 | | .operand = pl_ptr_id, |
| 4978 | | }); |
| 4976 | const active_pl_ptr_id = if (!layout.payload_ty.eql(payload_ty, zcu)) blk: { |
| 4977 | const active_pl_ptr_ty_id = try self.ptrType(payload_ty, .Function, .indirect); |
| 4978 | const active_pl_ptr_id = self.spv.allocId(); |
| 4979 | try self.func.body.emit(self.spv.gpa, .OpBitcast, .{ |
| 4980 | .id_result_type = active_pl_ptr_ty_id, |
| 4981 | .id_result = active_pl_ptr_id, |
| 4982 | .operand = pl_ptr_id, |
| 4983 | }); |
| 4984 | break :blk active_pl_ptr_id; |
| 4985 | } else pl_ptr_id; |
| 4979 | 4986 | |
| 4980 | 4987 | try self.store(payload_ty, active_pl_ptr_id, payload.?, .{}); |
| 4981 | 4988 | } else { |