authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2022-11-30 23:50:47+01:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-04-09 01:51:51+02:00
logf1229e0f00114e38001df8b57725de9c3e13a06d
treee178d7966954fdb1fe489474559c9e5757f460de
parentcaf8461af8df9a34abc5985042d98b8188575cd0
signaturelock-open Commit is signed but in an unrecognized format.

spirv: convert bools on load/store

Bools have a different immediate representation and memory representation - which means that they must be converted every time a bool is loaded from or stored into memory.

1 files changed, 34 insertions(+), 3 deletions(-)

src/codegen/spirv.zig+34-3
......@@ -1604,17 +1604,30 @@ pub const DeclGen = struct {
16041604
16051605 fn load(self: *DeclGen, ptr_ty: Type, ptr: IdRef) !IdRef {
16061606 const value_ty = ptr_ty.childType();
1607 const result_type_id = try self.resolveTypeId(value_ty);
1607 const direct_result_ty_ref = try self.resolveType(value_ty, .direct);
1608 const indirect_result_ty_ref = try self.resolveType(value_ty, .indirect);
16081609 const result_id = self.spv.allocId();
16091610 const access = spec.MemoryAccess.Extended{
16101611 .Volatile = ptr_ty.isVolatilePtr(),
16111612 };
16121613 try self.func.body.emit(self.spv.gpa, .OpLoad, .{
1613 .id_result_type = result_type_id,
1614 .id_result_type = self.typeId(indirect_result_ty_ref),
16141615 .id_result = result_id,
16151616 .pointer = ptr,
16161617 .memory_access = access,
16171618 });
1619 if (value_ty.zigTypeTag() == .Bool) {
1620 // Convert indirect bool to direct bool
1621 const zero_id = try self.constInt(indirect_result_ty_ref, 0);
1622 const casted_result_id = self.spv.allocId();
1623 try self.func.body.emit(self.spv.gpa, .OpINotEqual, .{
1624 .id_result_type = self.typeId(direct_result_ty_ref),
1625 .id_result = casted_result_id,
1626 .operand_1 = result_id,
1627 .operand_2 = zero_id,
1628 });
1629 return casted_result_id;
1630 }
16181631 return result_id;
16191632 }
16201633
......@@ -1628,12 +1641,30 @@ pub const DeclGen = struct {
16281641 }
16291642
16301643 fn store(self: *DeclGen, ptr_ty: Type, ptr: IdRef, value: IdRef) !void {
1644 const value_ty = ptr_ty.childType();
1645 const converted_value = switch (value_ty.zigTypeTag()) {
1646 .Bool => blk: {
1647 const indirect_bool_ty_ref = try self.resolveType(value_ty, .indirect);
1648 const result_id = self.spv.allocId();
1649 const zero = try self.constInt(indirect_bool_ty_ref, 0);
1650 const one = try self.constInt(indirect_bool_ty_ref, 1);
1651 try self.func.body.emit(self.spv.gpa, .OpSelect, .{
1652 .id_result_type = self.typeId(indirect_bool_ty_ref),
1653 .id_result = result_id,
1654 .condition = value,
1655 .object_1 = one,
1656 .object_2 = zero,
1657 });
1658 break :blk result_id;
1659 },
1660 else => value,
1661 };
16311662 const access = spec.MemoryAccess.Extended{
16321663 .Volatile = ptr_ty.isVolatilePtr(),
16331664 };
16341665 try self.func.body.emit(self.spv.gpa, .OpStore, .{
16351666 .pointer = ptr,
1636 .object = value,
1667 .object = converted_value,
16371668 .memory_access = access,
16381669 });
16391670 }