authorgravatar for alichraghi@proton.meAli Chraghi <alichraghi@proton.me> 2025-02-15 08:37:22+03:30
committergravatar for alichraghi@proton.meAli Chraghi <alichraghi@proton.me> 2025-02-18 18:08:51+03:30
log787208293960a02fbaf175a442d911c426a205cd
tree917bd1ad111065e548971ffec88e2b6b5ac2f6c6
parentd5e1cb3ea2cdd85bc2a9ca002d69d121a94f721c
signaturelock-open Commit is signed but in an unrecognized format.

spirv: extend supported `c` constraint values


2 files changed, 41 insertions(+), 4 deletions(-)

src/codegen/spirv.zig+15-4
......@@ -1254,6 +1254,7 @@ const NavGen = struct {
12541254 }
12551255
12561256 fn ptrType(self: *NavGen, child_ty: Type, storage_class: StorageClass, child_repr: Repr) !IdRef {
1257 const zcu = self.pt.zcu;
12571258 const key = .{ child_ty.toIntern(), storage_class, child_repr };
12581259 const entry = try self.ptr_types.getOrPut(self.gpa, key);
12591260 if (entry.found_existing) {
......@@ -1276,6 +1277,17 @@ const NavGen = struct {
12761277
12771278 const child_ty_id = try self.resolveType(child_ty, child_repr);
12781279
1280 if (self.spv.hasFeature(.shader)) {
1281 if (child_ty.zigTypeTag(zcu) == .@"struct") {
1282 switch (storage_class) {
1283 .Uniform, .PushConstant => try self.spv.decorate(child_ty_id, .Block),
1284 else => {},
1285 }
1286 }
1287
1288 try self.spv.decorate(result_id, .{ .ArrayStride = .{ .array_stride = @intCast(child_ty.abiSize(zcu)) } });
1289 }
1290
12791291 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpTypePointer, .{
12801292 .id_result = result_id,
12811293 .storage_class = storage_class,
......@@ -6426,9 +6438,8 @@ const NavGen = struct {
64266438
64276439 .undef => return self.fail("assembly input with 'c' constraint cannot be undefined", .{}),
64286440
6429 .int => {
6430 try as.value_map.put(as.gpa, name, .{ .constant = @intCast(val.toUnsignedInt(zcu)) });
6431 },
6441 .int => try as.value_map.put(as.gpa, name, .{ .constant = @intCast(val.toUnsignedInt(zcu)) }),
6442 .enum_literal => |str| try as.value_map.put(as.gpa, name, .{ .string = str.toSlice(ip) }),
64326443
64336444 else => unreachable, // TODO
64346445 }
......@@ -6510,7 +6521,7 @@ const NavGen = struct {
65106521 .just_declared, .unresolved_forward_reference => unreachable,
65116522 .ty => return self.fail("cannot return spir-v type as value from assembly", .{}),
65126523 .value => |ref| return ref,
6513 .constant => return self.fail("cannot return constant from assembly", .{}),
6524 .constant, .string => return self.fail("cannot return constant from assembly", .{}),
65146525 }
65156526
65166527 // TODO: Multiple results
src/codegen/spirv/Assembler.zig+26
......@@ -135,6 +135,9 @@ const AsmValue = union(enum) {
135135 /// This is a pre-supplied constant integer value.
136136 constant: u32,
137137
138 /// This is a pre-supplied constant string value.
139 string: []const u8,
140
138141 /// Retrieve the result-id of this AsmValue. Asserts that this AsmValue
139142 /// is of a variant that allows the result to be obtained (not an unresolved
140143 /// forward declaration, not in the process of being declared, etc).
......@@ -144,6 +147,7 @@ const AsmValue = union(enum) {
144147 .unresolved_forward_reference,
145148 // TODO: Lower this value as constant?
146149 .constant,
150 .string,
147151 => unreachable,
148152 .value => |result| result,
149153 .ty => |result| result,
......@@ -645,6 +649,28 @@ fn parseBitEnum(self: *Assembler, kind: spec.OperandKind) !void {
645649/// Also handles parsing any required extra operands.
646650fn parseValueEnum(self: *Assembler, kind: spec.OperandKind) !void {
647651 const tok = self.currentToken();
652 if (self.eatToken(.placeholder)) {
653 const name = self.tokenText(tok)[1..];
654 const value = self.value_map.get(name) orelse {
655 return self.fail(tok.start, "invalid placeholder '${s}'", .{name});
656 };
657 switch (value) {
658 .constant => |literal32| {
659 try self.inst.operands.append(self.gpa, .{ .value = literal32 });
660 },
661 .string => |str| {
662 const enumerant = for (kind.enumerants()) |enumerant| {
663 if (std.mem.eql(u8, enumerant.name, str)) break enumerant;
664 } else {
665 return self.fail(tok.start, "'{s}' is not a valid value for enumeration {s}", .{ str, @tagName(kind) });
666 };
667 try self.inst.operands.append(self.gpa, .{ .value = enumerant.value });
668 },
669 else => return self.fail(tok.start, "value '{s}' cannot be used as placeholder", .{name}),
670 }
671 return;
672 }
673
648674 try self.expectToken(.value);
649675
650676 const text = self.tokenText(tok);