diff options
| author | Robin Voetter <robin@voetter.nl> | 2025-03-18 22:31:57 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-18 22:31:57 +0100 |
| commit | 5105c3c7fa46969dc731b7447415436fd7572e87 (patch) | |
| tree | f3bdcc2b4f9193476cfc738a25b6d8869908999a /src/codegen/spirv | |
| parent | 074dd4d083b8ddefc370425568b61c890efe905d (diff) | |
| parent | ee06b2ce760d927b62726de1e2e3cb33b48d4932 (diff) | |
| download | zig-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.zig | 56 | ||||
| -rw-r--r-- | src/codegen/spirv/Module.zig | 29 |
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; |
