From 3139f3cfdd844818ab42ebce1d430a1f524025d5 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Tue, 12 May 2026 03:01:04 +0200 Subject: [PATCH] drafting push constants --- src/Module.zig | 20 ++++++-------------- src/Runtime.zig | 11 +++++++++++ src/Value.zig | 15 ++++++++++++--- src/opcodes.zig | 3 ++- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/Module.zig b/src/Module.zig index 8353ca6..08be587 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -75,7 +75,6 @@ input_locations: [lib.SPIRV_MAX_INPUT_LOCATIONS]SpvWord, output_locations: [lib.SPIRV_MAX_OUTPUT_LOCATIONS]SpvWord, bindings: [lib.SPIRV_MAX_SET][lib.SPIRV_MAX_SET_BINDINGS]SpvWord, builtins: std.EnumMap(spv.SpvBuiltIn, SpvWord), -push_constants: []Value, pub fn init(allocator: std.mem.Allocator, source: []const SpvWord, options: ModuleOptions) ModuleError!Self { var self: Self = std.mem.zeroInit(Self, .{ @@ -198,12 +197,7 @@ fn findAccessChainToMember(self: *const Self, base_id: SpvWord, member_index: Sp return null; } -fn applyInterfaceDecoration( - self: *Self, - storage_class: spv.SpvStorageClass, - decoration: Result.Decoration, - id: SpvWord, -) ModuleError!void { +fn applyInterfaceDecoration(self: *Self, storage_class: spv.SpvStorageClass, decoration: Result.Decoration, id: SpvWord) ModuleError!void { switch (storage_class) { .Input => switch (decoration.rtype) { .BuiltIn => self.builtins.put( @@ -225,12 +219,7 @@ fn applyInterfaceDecoration( } } -fn applyStructMemberInterfaceDecorations( - self: *Self, - storage_class: spv.SpvStorageClass, - type_word: SpvWord, - id: SpvWord, -) ModuleError!void { +fn applyStructMemberInterfaceDecorations(self: *Self, storage_class: spv.SpvStorageClass, type_word: SpvWord, id: SpvWord) ModuleError!void { switch (storage_class) { .Input, .Output => {}, else => return, @@ -281,7 +270,10 @@ fn applyDecorations(self: *Self) ModuleError!void { try self.applyInterfaceDecoration(v.storage_class, decoration, @intCast(id)); switch (v.storage_class) { - .StorageBuffer, .Uniform, .UniformConstant => { + .StorageBuffer, + .Uniform, + .UniformConstant, + => { switch (decoration.rtype) { .Binding => binding = decoration.literal_1, .DescriptorSet => set = decoration.literal_1, diff --git a/src/Runtime.zig b/src/Runtime.zig index a573372..29b749e 100644 --- a/src/Runtime.zig +++ b/src/Runtime.zig @@ -240,6 +240,17 @@ fn pass(self: *Self, allocator: std.mem.Allocator, op_set: ?std.EnumSet(spv.SpvO } } +pub fn populatePushConstants(self: *Self, blob: []const u8) RuntimeError!void { + for (self.results) |*result| { + if (result.variant == null or std.meta.activeTag(result.variant.?) != .Variable) + continue; + const variable = &result.variant.?.Variable; + if (variable.storage_class != .PushConstant) + continue; + _ = try variable.value.writeConst(blob); + } +} + pub fn writeDescriptorSet(self: *const Self, input: []const u8, set: SpvWord, binding: SpvWord, descriptor_index: SpvWord) RuntimeError!void { if (set < lib.SPIRV_MAX_SET and binding < lib.SPIRV_MAX_SET_BINDINGS) { const value = &self.results[self.mod.bindings[set][binding]].variant.?.Variable.value; diff --git a/src/Value.zig b/src/Value.zig index ec30762..40237ac 100644 --- a/src/Value.zig +++ b/src/Value.zig @@ -143,9 +143,13 @@ pub const Value = union(Type) { pub fn init(allocator: std.mem.Allocator, results: []const Result, target_type: SpvWord, is_externally_visible: bool) RuntimeError!Self { const resolved = results[target_type].resolveTypeWordOrNull() orelse target_type; - const member_count = results[resolved].getMemberCounts(); + return initUnresolved(allocator, results, resolved, is_externally_visible); + } - return switch (results[resolved].variant.?) { + pub fn initUnresolved(allocator: std.mem.Allocator, results: []const Result, target_type: SpvWord, is_externally_visible: bool) RuntimeError!Self { + const member_count = results[target_type].getMemberCounts(); + + return switch (results[target_type].variant.?) { .Type => |t| switch (t) { .Void => .{ .Void = .{} }, .Bool => .{ .Bool = false }, @@ -233,12 +237,17 @@ pub const Value = union(Type) { }, .Image => .{ .Image = .{ - .type_word = resolved, + .type_word = target_type, .driver_image = undefined, }, }, .Sampler => RuntimeError.ToDo, .SampledImage => RuntimeError.ToDo, + .Pointer => .{ + .Pointer = .{ + .ptr = undefined, + }, + }, else => RuntimeError.InvalidSpirV, }, else => RuntimeError.InvalidSpirV, diff --git a/src/opcodes.zig b/src/opcodes.zig index b892af6..569fb46 100644 --- a/src/opcodes.zig +++ b/src/opcodes.zig @@ -1197,7 +1197,7 @@ fn setupAccessChain(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Runt .target = var_type, .base = base_id, .indexes = indexes, - .value = try Value.init(allocator, rt.results, var_type, false), + .value = try Value.initUnresolved(allocator, rt.results, var_type, false), }, }; } @@ -3267,6 +3267,7 @@ fn opVariable(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Runtime) R const externally_visible_data_storages = [_]spv.SpvStorageClass{ .Uniform, .StorageBuffer, + .PushConstant, }; const is_externally_visible = std.mem.containsAtLeastScalar(spv.SpvStorageClass, &externally_visible_data_storages, 1, storage_class);