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 {...@@ -1254,6 +1254,7 @@ const NavGen = struct {
1254 }1254 }
12551255
1256 fn ptrType(self: *NavGen, child_ty: Type, storage_class: StorageClass, child_repr: Repr) !IdRef {1256 fn ptrType(self: *NavGen, child_ty: Type, storage_class: StorageClass, child_repr: Repr) !IdRef {
1257 const zcu = self.pt.zcu;
1257 const key = .{ child_ty.toIntern(), storage_class, child_repr };1258 const key = .{ child_ty.toIntern(), storage_class, child_repr };
1258 const entry = try self.ptr_types.getOrPut(self.gpa, key);1259 const entry = try self.ptr_types.getOrPut(self.gpa, key);
1259 if (entry.found_existing) {1260 if (entry.found_existing) {
...@@ -1276,6 +1277,17 @@ const NavGen = struct {...@@ -1276,6 +1277,17 @@ const NavGen = struct {
12761277
1277 const child_ty_id = try self.resolveType(child_ty, child_repr);1278 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
1279 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpTypePointer, .{1291 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpTypePointer, .{
1280 .id_result = result_id,1292 .id_result = result_id,
1281 .storage_class = storage_class,1293 .storage_class = storage_class,
...@@ -6426,9 +6438,8 @@ const NavGen = struct {...@@ -6426,9 +6438,8 @@ const NavGen = struct {
64266438
6427 .undef => return self.fail("assembly input with 'c' constraint cannot be undefined", .{}),6439 .undef => return self.fail("assembly input with 'c' constraint cannot be undefined", .{}),
64286440
6429 .int => {6441 .int => try as.value_map.put(as.gpa, name, .{ .constant = @intCast(val.toUnsignedInt(zcu)) }),
6430 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) }),
6431 },
64326443
6433 else => unreachable, // TODO6444 else => unreachable, // TODO
6434 }6445 }
...@@ -6510,7 +6521,7 @@ const NavGen = struct {...@@ -6510,7 +6521,7 @@ const NavGen = struct {
6510 .just_declared, .unresolved_forward_reference => unreachable,6521 .just_declared, .unresolved_forward_reference => unreachable,
6511 .ty => return self.fail("cannot return spir-v type as value from assembly", .{}),6522 .ty => return self.fail("cannot return spir-v type as value from assembly", .{}),
6512 .value => |ref| return ref,6523 .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", .{}),
6514 }6525 }
65156526
6516 // TODO: Multiple results6527 // TODO: Multiple results
src/codegen/spirv/Assembler.zig+26
...@@ -135,6 +135,9 @@ const AsmValue = union(enum) {...@@ -135,6 +135,9 @@ const AsmValue = union(enum) {
135 /// This is a pre-supplied constant integer value.135 /// This is a pre-supplied constant integer value.
136 constant: u32,136 constant: u32,
137137
138 /// This is a pre-supplied constant string value.
139 string: []const u8,
140
138 /// Retrieve the result-id of this AsmValue. Asserts that this AsmValue141 /// Retrieve the result-id of this AsmValue. Asserts that this AsmValue
139 /// is of a variant that allows the result to be obtained (not an unresolved142 /// is of a variant that allows the result to be obtained (not an unresolved
140 /// forward declaration, not in the process of being declared, etc).143 /// forward declaration, not in the process of being declared, etc).
...@@ -144,6 +147,7 @@ const AsmValue = union(enum) {...@@ -144,6 +147,7 @@ const AsmValue = union(enum) {
144 .unresolved_forward_reference,147 .unresolved_forward_reference,
145 // TODO: Lower this value as constant?148 // TODO: Lower this value as constant?
146 .constant,149 .constant,
150 .string,
147 => unreachable,151 => unreachable,
148 .value => |result| result,152 .value => |result| result,
149 .ty => |result| result,153 .ty => |result| result,
...@@ -645,6 +649,28 @@ fn parseBitEnum(self: *Assembler, kind: spec.OperandKind) !void {...@@ -645,6 +649,28 @@ fn parseBitEnum(self: *Assembler, kind: spec.OperandKind) !void {
645/// Also handles parsing any required extra operands.649/// Also handles parsing any required extra operands.
646fn parseValueEnum(self: *Assembler, kind: spec.OperandKind) !void {650fn parseValueEnum(self: *Assembler, kind: spec.OperandKind) !void {
647 const tok = self.currentToken();651 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
648 try self.expectToken(.value);674 try self.expectToken(.value);
649675
650 const text = self.tokenText(tok);676 const text = self.tokenText(tok);