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 {...@@ -1604,17 +1604,30 @@ pub const DeclGen = struct {
16041604
1605 fn load(self: *DeclGen, ptr_ty: Type, ptr: IdRef) !IdRef {1605 fn load(self: *DeclGen, ptr_ty: Type, ptr: IdRef) !IdRef {
1606 const value_ty = ptr_ty.childType();1606 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);
1608 const result_id = self.spv.allocId();1609 const result_id = self.spv.allocId();
1609 const access = spec.MemoryAccess.Extended{1610 const access = spec.MemoryAccess.Extended{
1610 .Volatile = ptr_ty.isVolatilePtr(),1611 .Volatile = ptr_ty.isVolatilePtr(),
1611 };1612 };
1612 try self.func.body.emit(self.spv.gpa, .OpLoad, .{1613 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),
1614 .id_result = result_id,1615 .id_result = result_id,
1615 .pointer = ptr,1616 .pointer = ptr,
1616 .memory_access = access,1617 .memory_access = access,
1617 });1618 });
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 }
1618 return result_id;1631 return result_id;
1619 }1632 }
16201633
...@@ -1628,12 +1641,30 @@ pub const DeclGen = struct {...@@ -1628,12 +1641,30 @@ pub const DeclGen = struct {
1628 }1641 }
16291642
1630 fn store(self: *DeclGen, ptr_ty: Type, ptr: IdRef, value: IdRef) !void {1643 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 };
1631 const access = spec.MemoryAccess.Extended{1662 const access = spec.MemoryAccess.Extended{
1632 .Volatile = ptr_ty.isVolatilePtr(),1663 .Volatile = ptr_ty.isVolatilePtr(),
1633 };1664 };
1634 try self.func.body.emit(self.spv.gpa, .OpStore, .{1665 try self.func.body.emit(self.spv.gpa, .OpStore, .{
1635 .pointer = ptr,1666 .pointer = ptr,
1636 .object = value,1667 .object = converted_value,
1637 .memory_access = access,1668 .memory_access = access,
1638 });1669 });
1639 }1670 }