aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/spirv
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2025-03-18 22:31:57 +0100
committerGitHub <noreply@github.com>2025-03-18 22:31:57 +0100
commit5105c3c7fa46969dc731b7447415436fd7572e87 (patch)
treef3bdcc2b4f9193476cfc738a25b6d8869908999a /src/codegen/spirv
parent074dd4d083b8ddefc370425568b61c890efe905d (diff)
parentee06b2ce760d927b62726de1e2e3cb33b48d4932 (diff)
downloadzig-5105c3c7fa46969dc731b7447415436fd7572e87.tar.gz
zig-5105c3c7fa46969dc731b7447415436fd7572e87.zip
Merge pull request #23158 from alichraghi/ali_spirv
spirv: miscellaneous stuff #2
Diffstat (limited to 'src/codegen/spirv')
-rw-r--r--src/codegen/spirv/Assembler.zig56
-rw-r--r--src/codegen/spirv/Module.zig29
2 files changed, 67 insertions, 18 deletions
diff --git a/src/codegen/spirv/Assembler.zig b/src/codegen/spirv/Assembler.zig
index 25a5481fb5..264613b240 100644
--- a/src/codegen/spirv/Assembler.zig
+++ b/src/codegen/spirv/Assembler.zig
@@ -368,6 +368,40 @@ fn processTypeInstruction(self: *Assembler) !AsmValue {
});
break :blk result_id;
},
+ .OpTypeStruct => blk: {
+ const ids = try self.gpa.alloc(IdRef, operands[1..].len);
+ defer self.gpa.free(ids);
+ for (operands[1..], ids) |op, *id| id.* = try self.resolveRefId(op.ref_id);
+ const result_id = self.spv.allocId();
+ try self.spv.structType(result_id, ids, null);
+ break :blk result_id;
+ },
+ .OpTypeImage => blk: {
+ const sampled_type = try self.resolveRefId(operands[1].ref_id);
+ const result_id = self.spv.allocId();
+ try section.emit(self.gpa, .OpTypeImage, .{
+ .id_result = result_id,
+ .sampled_type = sampled_type,
+ .dim = @enumFromInt(operands[2].value),
+ .depth = operands[3].literal32,
+ .arrayed = operands[4].literal32,
+ .ms = operands[5].literal32,
+ .sampled = operands[6].literal32,
+ .image_format = @enumFromInt(operands[7].value),
+ });
+ break :blk result_id;
+ },
+ .OpTypeSampler => blk: {
+ const result_id = self.spv.allocId();
+ try section.emit(self.gpa, .OpTypeSampler, .{ .id_result = result_id });
+ break :blk result_id;
+ },
+ .OpTypeSampledImage => blk: {
+ const image_type = try self.resolveRefId(operands[1].ref_id);
+ const result_id = self.spv.allocId();
+ try section.emit(self.gpa, .OpTypeSampledImage, .{ .id_result = result_id, .image_type = image_type });
+ break :blk result_id;
+ },
.OpTypeFunction => blk: {
const param_operands = operands[2..];
const return_type = try self.resolveRefId(operands[1].ref_id);
@@ -406,18 +440,18 @@ fn processGenericInstruction(self: *Assembler) !?AsmValue {
else => switch (self.inst.opcode) {
.OpEntryPoint => unreachable,
.OpExecutionMode, .OpExecutionModeId => &self.spv.sections.execution_modes,
- .OpVariable => switch (@as(spec.StorageClass, @enumFromInt(operands[2].value))) {
- .Function => &self.func.prologue,
- .Input, .Output => section: {
- maybe_spv_decl_index = try self.spv.allocDecl(.global);
- try self.func.decl_deps.put(self.spv.gpa, maybe_spv_decl_index.?, {});
- // TODO: In theory this can be non-empty if there is an initializer which depends on another global...
- try self.spv.declareDeclDeps(maybe_spv_decl_index.?, &.{});
+ .OpVariable => section: {
+ const storage_class: spec.StorageClass = @enumFromInt(operands[2].value);
+ if (storage_class == .Function) break :section &self.func.prologue;
+ maybe_spv_decl_index = try self.spv.allocDecl(.global);
+ if (self.spv.version.minor < 4 and storage_class != .Input and storage_class != .Output) {
+ // Before version 1.4, the interface’s storage classes are limited to the Input and Output
break :section &self.spv.sections.types_globals_constants;
- },
- // These don't need to be marked in the dependency system.
- // Probably we should add them anyway, then filter out PushConstant globals.
- else => &self.spv.sections.types_globals_constants,
+ }
+ try self.func.decl_deps.put(self.spv.gpa, maybe_spv_decl_index.?, {});
+ // TODO: In theory this can be non-empty if there is an initializer which depends on another global...
+ try self.spv.declareDeclDeps(maybe_spv_decl_index.?, &.{});
+ break :section &self.spv.sections.types_globals_constants;
},
// Default case - to be worked out further.
else => &self.func.body,
diff --git a/src/codegen/spirv/Module.zig b/src/codegen/spirv/Module.zig
index 5ed1e2df1a..1aa082f6bc 100644
--- a/src/codegen/spirv/Module.zig
+++ b/src/codegen/spirv/Module.zig
@@ -333,8 +333,6 @@ pub fn finalize(self: *Module, a: Allocator) ![]Word {
// Versions
.v1_0, .v1_1, .v1_2, .v1_3, .v1_4, .v1_5, .v1_6 => {},
// Features with no dependencies
- .int8 => try self.addCapability(.Int8),
- .int16 => try self.addCapability(.Int16),
.int64 => try self.addCapability(.Int64),
.float16 => try self.addCapability(.Float16),
.float64 => try self.addCapability(.Float64),
@@ -343,21 +341,27 @@ pub fn finalize(self: *Module, a: Allocator) ![]Word {
try self.addExtension("SPV_KHR_16bit_storage");
try self.addCapability(.StoragePushConstant16);
},
- .addresses => if (self.hasFeature(.shader)) {
- try self.addExtension("SPV_KHR_physical_storage_buffer");
- try self.addCapability(.PhysicalStorageBufferAddresses);
- } else {
- try self.addCapability(.Addresses);
+ .arbitrary_precision_integers => {
+ try self.addExtension("SPV_INTEL_arbitrary_precision_integers");
+ try self.addCapability(.ArbitraryPrecisionIntegersINTEL);
},
+ .addresses => try self.addCapability(.Addresses),
// Kernel
.kernel => try self.addCapability(.Kernel),
.generic_pointer => try self.addCapability(.GenericPointer),
.vector16 => try self.addCapability(.Vector16),
// Shader
.shader => try self.addCapability(.Shader),
+ .physical_storage_buffer => {
+ try self.addExtension("SPV_KHR_physical_storage_buffer");
+ try self.addCapability(.PhysicalStorageBufferAddresses);
+ },
}
}
}
+ // These are well supported
+ try self.addCapability(.Int8);
+ try self.addCapability(.Int16);
// Emit memory model
const addressing_model: spec.AddressingModel = blk: {
@@ -610,6 +614,17 @@ pub fn functionType(self: *Module, return_ty_id: IdRef, param_type_ids: []const
return result_id;
}
+pub fn constant(self: *Module, result_ty_id: IdRef, value: spec.LiteralContextDependentNumber) !IdRef {
+ const result_id = self.allocId();
+ const section = &self.sections.types_globals_constants;
+ try section.emit(self.gpa, .OpConstant, .{
+ .id_result_type = result_ty_id,
+ .id_result = result_id,
+ .value = value,
+ });
+ return result_id;
+}
+
pub fn constBool(self: *Module, value: bool) !IdRef {
if (self.cache.bool_const[@intFromBool(value)]) |b| return b;