improving descriptor sets push to shaders
Test / build_and_test (push) Successful in 35s
Build / build (push) Successful in 1m16s

This commit is contained in:
2026-05-18 19:54:09 +02:00
parent 3c9a864240
commit 9e4221affb
9 changed files with 130 additions and 117 deletions
+2 -2
View File
@@ -31,8 +31,8 @@
.lazy = true, .lazy = true,
}, },
.SPIRV_Interpreter = .{ .SPIRV_Interpreter = .{
.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#a765246ee96bd2990471cab1d06468dab8ca5a90", .url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#b82d37e7b66a94b58464c972092e184e219e98d8",
.hash = "SPIRV_Interpreter-0.0.1-ajmpnwJJBQBf3lGA1o8VXvEotGeeajtQGgcrGeDVd21S", .hash = "SPIRV_Interpreter-0.0.1-ajmpnyI_BQACRyFzfq9PUcgOz7OqJP4qSoLfhJxj2XSY",
.lazy = true, .lazy = true,
}, },
//.SPIRV_Interpreter = .{ //.SPIRV_Interpreter = .{
+30 -6
View File
@@ -98,18 +98,42 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, layout: *base.
.uniform_buffer, .uniform_buffer,
.storage_buffer, .storage_buffer,
.storage_buffer_dynamic, .storage_buffer_dynamic,
=> descriptor.* = .{ => descriptor.* = blk: {
.buffer = local_allocator.alloc(DescriptorBuffer, binding.array_size) catch return VkError.OutOfHostMemory, const desc: Descriptor = .{
.buffer = local_allocator.alloc(DescriptorBuffer, binding.array_size) catch return VkError.OutOfHostMemory,
};
for (desc.buffer[0..]) |*d| {
d.* = .{
.object = null,
.offset = 0,
.size = 0,
};
}
break :blk desc;
}, },
.storage_image, .storage_image,
.input_attachment, .input_attachment,
=> descriptor.* = .{ => descriptor.* = blk: {
.image = local_allocator.alloc(DescriptorImage, binding.array_size) catch return VkError.OutOfHostMemory, const desc: Descriptor = .{
.image = local_allocator.alloc(DescriptorImage, binding.array_size) catch return VkError.OutOfHostMemory,
};
for (desc.image[0..]) |*d| {
d.* = .{ .object = null };
}
break :blk desc;
}, },
.storage_texel_buffer, .storage_texel_buffer,
.uniform_texel_buffer, .uniform_texel_buffer,
=> descriptor.* = .{ => descriptor.* = blk: {
.texel_buffer = local_allocator.alloc(DescriptorTexel, binding.array_size) catch return VkError.OutOfHostMemory, const desc: Descriptor = .{
.texel_buffer = local_allocator.alloc(DescriptorTexel, binding.array_size) catch return VkError.OutOfHostMemory,
};
for (desc.texel_buffer[0..]) |*d| {
d.* = .{ .object = null };
}
break :blk desc;
}, },
else => {}, else => {},
} }
+3 -48
View File
@@ -4,7 +4,8 @@ const base = @import("base");
const spv = @import("spv"); const spv = @import("spv");
const lib = @import("../lib.zig"); const lib = @import("../lib.zig");
const PipelineState = @import("Device.zig").PipelineState; const ExecutionDevice = @import("Device.zig");
const PipelineState = ExecutionDevice.PipelineState;
const SoftDevice = @import("../SoftDevice.zig"); const SoftDevice = @import("../SoftDevice.zig");
const SoftPipeline = @import("../SoftPipeline.zig"); const SoftPipeline = @import("../SoftPipeline.zig");
@@ -96,7 +97,7 @@ inline fn run(data: RunData) !void {
const entry = try rt.getEntryPointByName(shader.entry); const entry = try rt.getEntryPointByName(shader.entry);
try data.self.writeDescriptorSets(rt); try ExecutionDevice.writeDescriptorSets(data.self.state, rt);
var group_index: usize = data.batch_id; var group_index: usize = data.batch_id;
while (group_index < data.group_count) : (group_index += data.self.batch_size) { while (group_index < data.group_count) : (group_index += data.self.batch_size) {
@@ -165,52 +166,6 @@ inline fn dumpResultsTable(allocator: std.mem.Allocator, io: std.Io, rt: *spv.Ru
try rt.dumpResultsTable(allocator, &writer.interface); try rt.dumpResultsTable(allocator, &writer.interface);
} }
fn writeDescriptorSets(self: *Self, rt: *spv.Runtime) !void {
sets: for (self.state.sets[0..], 0..) |set, set_index| {
if (set == null)
continue :sets;
bindings: for (set.?.descriptors[0..], 0..) |binding, binding_index| {
switch (binding) {
.buffer => |buffer_data_array| for (buffer_data_array, 0..) |buffer_data, descriptor_index| {
if (buffer_data.object) |buffer| {
const map = buffer.mapAsSliceWithOffset(u8, buffer_data.offset, buffer_data.size) catch continue :bindings;
try rt.writeDescriptorSet(
map,
@as(u32, @intCast(set_index)),
@as(u32, @intCast(binding_index)),
@as(u32, @intCast(descriptor_index)),
);
}
},
.image => |image_data_array| for (image_data_array, 0..) |image_data, descriptor_index| {
if (image_data.object) |image_view| {
const addr: usize = @intFromPtr(image_view);
try rt.writeDescriptorSet(
std.mem.asBytes(&addr),
@as(u32, @intCast(set_index)),
@as(u32, @intCast(binding_index)),
@as(u32, @intCast(descriptor_index)),
);
}
},
.texel_buffer => |texel_data_array| for (texel_data_array, 0..) |texel_data, descriptor_index| {
if (texel_data.object) |buffer_view| {
const addr: usize = @intFromPtr(buffer_view);
try rt.writeDescriptorSet(
std.mem.asBytes(&addr),
@as(u32, @intCast(set_index)),
@as(u32, @intCast(binding_index)),
@as(u32, @intCast(descriptor_index)),
);
}
},
else => {},
}
}
}
}
fn setupWorkgroupBuiltins( fn setupWorkgroupBuiltins(
self: *Self, self: *Self,
rt: *spv.Runtime, rt: *spv.Runtime,
+47
View File
@@ -2,6 +2,7 @@ const std = @import("std");
const vk = @import("vulkan"); const vk = @import("vulkan");
const base = @import("base"); const base = @import("base");
const lib = @import("../lib.zig"); const lib = @import("../lib.zig");
const spv = @import("spv");
const SoftDescriptorSet = @import("../SoftDescriptorSet.zig"); const SoftDescriptorSet = @import("../SoftDescriptorSet.zig");
const SoftDevice = @import("../SoftDevice.zig"); const SoftDevice = @import("../SoftDevice.zig");
@@ -60,3 +61,49 @@ pub fn setup(self: *Self, device: *SoftDevice) void {
self.compute = .init(device, &self.pipeline_states[@intFromEnum(vk.PipelineBindPoint.compute)]); self.compute = .init(device, &self.pipeline_states[@intFromEnum(vk.PipelineBindPoint.compute)]);
self.renderer = .init(device, &self.pipeline_states[@intFromEnum(vk.PipelineBindPoint.graphics)]); self.renderer = .init(device, &self.pipeline_states[@intFromEnum(vk.PipelineBindPoint.graphics)]);
} }
pub fn writeDescriptorSets(state: *PipelineState, rt: *spv.Runtime) !void {
sets: for (state.sets[0..], 0..) |set, set_index| {
if (set == null)
continue :sets;
bindings: for (set.?.descriptors[0..], 0..) |binding, binding_index| {
switch (binding) {
.buffer => |buffer_data_array| for (buffer_data_array, 0..) |buffer_data, descriptor_index| {
if (buffer_data.object) |buffer| {
const map = buffer.mapAsSliceWithOffset(u8, buffer_data.offset, buffer_data.size) catch continue :bindings;
try rt.writeDescriptorSet(
map,
@as(u32, @intCast(set_index)),
@as(u32, @intCast(binding_index)),
@as(u32, @intCast(descriptor_index)),
);
}
},
.image => |image_data_array| for (image_data_array, 0..) |image_data, descriptor_index| {
if (image_data.object) |image_view| {
const addr: usize = @intFromPtr(image_view);
try rt.writeDescriptorSet(
std.mem.asBytes(&addr),
@as(u32, @intCast(set_index)),
@as(u32, @intCast(binding_index)),
@as(u32, @intCast(descriptor_index)),
);
}
},
.texel_buffer => |texel_data_array| for (texel_data_array, 0..) |texel_data, descriptor_index| {
if (texel_data.object) |buffer_view| {
const addr: usize = @intFromPtr(buffer_view);
try rt.writeDescriptorSet(
std.mem.asBytes(&addr),
@as(u32, @intCast(set_index)),
@as(u32, @intCast(binding_index)),
@as(u32, @intCast(descriptor_index)),
);
}
},
else => {},
}
}
}
}
+4 -38
View File
@@ -4,7 +4,8 @@ const base = @import("base");
const zm = base.zm; const zm = base.zm;
const spv = @import("spv"); const spv = @import("spv");
const PipelineState = @import("Device.zig").PipelineState; const ExecutionDevice = @import("Device.zig");
const PipelineState = ExecutionDevice.PipelineState;
const BoundedAllocator = @import("BoundedAllocator.zig"); const BoundedAllocator = @import("BoundedAllocator.zig");
const SoftBuffer = @import("../SoftBuffer.zig"); const SoftBuffer = @import("../SoftBuffer.zig");
@@ -182,11 +183,11 @@ fn drawCall(self: *Self, bounded_allocator: *BoundedAllocator, vertex_count: usi
const pipeline = self.state.pipeline orelse return VkError.InvalidPipelineDrv; const pipeline = self.state.pipeline orelse return VkError.InvalidPipelineDrv;
const vertex_shader = pipeline.stages.getPtrAssertContains(.vertex); const vertex_shader = pipeline.stages.getPtrAssertContains(.vertex);
for (vertex_shader.runtimes[0..]) |*runtime| { for (vertex_shader.runtimes[0..]) |*runtime| {
writeDescriptorSets(&draw_call, &runtime.rt) catch return VkError.Unknown; ExecutionDevice.writeDescriptorSets(self.state, &runtime.rt) catch return VkError.Unknown;
} }
const fragment_shader = pipeline.stages.getPtrAssertContains(.fragment); const fragment_shader = pipeline.stages.getPtrAssertContains(.fragment);
for (fragment_shader.runtimes[0..]) |*runtime| { for (fragment_shader.runtimes[0..]) |*runtime| {
writeDescriptorSets(&draw_call, &runtime.rt) catch return VkError.Unknown; ExecutionDevice.writeDescriptorSets(self.state, &runtime.rt) catch return VkError.Unknown;
} }
self.vertexShaderStage(allocator, &draw_call, vertex_count, instance_count, first_vertex, first_instance, indices) catch |err| { self.vertexShaderStage(allocator, &draw_call, vertex_count, instance_count, first_vertex, first_instance, indices) catch |err| {
@@ -307,38 +308,3 @@ fn resolveScissor(self: *Self, scissor_index: usize) VkError!vk.Rect2D {
return VkError.Unknown; return VkError.Unknown;
} }
fn writeDescriptorSets(draw_call: *DrawCall, rt: *spv.Runtime) !void {
sets: for (draw_call.renderer.state.sets[0..], 0..) |set, set_index| {
if (set == null)
continue :sets;
bindings: for (set.?.descriptors[0..], 0..) |binding, binding_index| {
switch (binding) {
.buffer => |buffer_data_array| for (buffer_data_array, 0..) |buffer_data, descriptor_index| {
if (buffer_data.object) |buffer| {
const map = buffer.mapAsSliceWithOffset(u8, buffer_data.offset, buffer_data.size) catch continue :bindings;
try rt.writeDescriptorSet(
map,
@as(u32, @intCast(set_index)),
@as(u32, @intCast(binding_index)),
@as(u32, @intCast(descriptor_index)),
);
}
},
.image => |image_data_array| for (image_data_array, 0..) |image_data, descriptor_index| {
if (image_data.object) |image_view| {
const addr: usize = @intFromPtr(image_view);
try rt.writeDescriptorSet(
std.mem.asBytes(&addr),
@as(u32, @intCast(set_index)),
@as(u32, @intCast(binding_index)),
@as(u32, @intCast(descriptor_index)),
);
}
},
else => {},
}
}
}
}
+8 -1
View File
@@ -649,7 +649,7 @@ pub fn writeFloat4(color: F32x4, map: []u8, dst_format: vk.Format) void {
.r8_snorm, .r8_snorm,
.r8_unorm, .r8_unorm,
.s8_uint, .s8_uint,
=> map[0] = @intFromFloat(@round(color[0] * 255.0)), => map[0] = @intFromFloat(@round(color[0] * std.math.maxInt(u8))),
.r16_sint, .r16_sint,
.r16_uint, .r16_uint,
@@ -692,6 +692,13 @@ pub fn writeFloat4(color: F32x4, map: []u8, dst_format: vk.Format) void {
.r32g32b32a32_sfloat => std.mem.bytesAsValue(F32x4, map).* = color, .r32g32b32a32_sfloat => std.mem.bytesAsValue(F32x4, map).* = color,
.r5g6b5_unorm_pack16 => {
const r: u5 = @intFromFloat(@round(color[0] * std.math.maxInt(u5)));
const g: u6 = @intFromFloat(@round(color[1] * std.math.maxInt(u6)));
const b: u5 = @intFromFloat(@round(color[2] * std.math.maxInt(u5)));
std.mem.bytesAsValue(u16, map[0..]).* = (@as(u16, r) << 11) | (@as(u16, g) << 5) | @as(u16, b);
},
else => base.unsupported("Blitter: write float to destination format {any}", .{dst_format}), else => base.unsupported("Blitter: write float to destination format {any}", .{dst_format}),
} }
} }
+11 -4
View File
@@ -4,7 +4,7 @@ const base = @import("base");
const zm = base.zm; const zm = base.zm;
const spv = @import("spv"); const spv = @import("spv");
const lib = @import("../lib.zig"); const VertexInterpolation = @import("rasterizer/common.zig").VertexInterpolation;
const Renderer = @import("Renderer.zig"); const Renderer = @import("Renderer.zig");
const SoftImage = @import("../SoftImage.zig"); const SoftImage = @import("../SoftImage.zig");
@@ -12,7 +12,13 @@ const SoftImage = @import("../SoftImage.zig");
const VkError = base.VkError; const VkError = base.VkError;
const SpvRuntimeError = spv.Runtime.RuntimeError; const SpvRuntimeError = spv.Runtime.RuntimeError;
pub fn shaderInvocation(allocator: std.mem.Allocator, draw_call: *Renderer.DrawCall, batch_id: usize, position: zm.F32x4, inputs: [spv.SPIRV_MAX_OUTPUT_LOCATIONS][]const u8) SpvRuntimeError!zm.F32x4 { pub fn shaderInvocation(
allocator: std.mem.Allocator,
draw_call: *Renderer.DrawCall,
batch_id: usize,
position: zm.F32x4,
inputs: [spv.SPIRV_MAX_OUTPUT_LOCATIONS]VertexInterpolation,
) SpvRuntimeError!zm.F32x4 {
const io = draw_call.renderer.device.interface.io(); const io = draw_call.renderer.device.interface.io();
_ = position; _ = position;
@@ -34,8 +40,9 @@ pub fn shaderInvocation(allocator: std.mem.Allocator, draw_call: *Renderer.DrawC
SpvRuntimeError.NotFound => continue, SpvRuntimeError.NotFound => continue,
else => return err, else => return err,
}; };
try rt.writeInput(inputs[location], result_word); try rt.writeInput(inputs[location].blob, result_word);
allocator.free(inputs[location]); if (inputs[location].free_responsability)
allocator.free(inputs[location].blob);
} }
rt.callEntryPoint(allocator, entry) catch |err| switch (err) { rt.callEntryPoint(allocator, entry) catch |err| switch (err) {
+15 -5
View File
@@ -17,6 +17,11 @@ pub const RenderTargetAccess = struct {
format: vk.Format, format: vk.Format,
}; };
pub const VertexInterpolation = struct {
blob: []const u8,
free_responsability: bool,
};
pub fn scissorContainsPixel(scissor: vk.Rect2D, x: i32, y: i32) bool { pub fn scissorContainsPixel(scissor: vk.Rect2D, x: i32, y: i32) bool {
const min_x: i64 = @as(i64, scissor.offset.x); const min_x: i64 = @as(i64, scissor.offset.x);
const min_y: i64 = @as(i64, scissor.offset.y); const min_y: i64 = @as(i64, scissor.offset.y);
@@ -41,8 +46,8 @@ pub fn interpolateVertexOutputs(
b0: f32, b0: f32,
b1: f32, b1: f32,
b2: f32, b2: f32,
) VkError![spv.SPIRV_MAX_OUTPUT_LOCATIONS][]u8 { ) VkError![spv.SPIRV_MAX_OUTPUT_LOCATIONS]VertexInterpolation {
var inputs: [spv.SPIRV_MAX_OUTPUT_LOCATIONS][]u8 = undefined; var inputs: [spv.SPIRV_MAX_OUTPUT_LOCATIONS]VertexInterpolation = undefined;
for (0..spv.SPIRV_MAX_OUTPUT_LOCATIONS) |location| { for (0..spv.SPIRV_MAX_OUTPUT_LOCATIONS) |location| {
const out0 = v0.outputs[location] orelse continue; const out0 = v0.outputs[location] orelse continue;
@@ -50,7 +55,7 @@ pub fn interpolateVertexOutputs(
const out2 = v2.outputs[location] orelse continue; const out2 = v2.outputs[location] orelse continue;
if (out0.interpolation_type == .flat or out0.blob.len == 0) { if (out0.interpolation_type == .flat or out0.blob.len == 0) {
inputs[location] = out0.blob; inputs[location] = .{ .blob = out0.blob, .free_responsability = false };
continue; continue;
} }
@@ -75,13 +80,18 @@ pub fn interpolateVertexOutputs(
if (byte_index < len) if (byte_index < len)
@memcpy(input[byte_index..], out0.blob[byte_index..len]); @memcpy(input[byte_index..], out0.blob[byte_index..len]);
inputs[location] = input; inputs[location] = .{ .blob = input, .free_responsability = true };
} }
return inputs; return inputs;
} }
pub fn interpolateLineOutputs(allocator: std.mem.Allocator, v0: *const Renderer.Vertex, v1: *const Renderer.Vertex, t: f32) VkError![spv.SPIRV_MAX_OUTPUT_LOCATIONS][]u8 { pub fn interpolateLineOutputs(
allocator: std.mem.Allocator,
v0: *const Renderer.Vertex,
v1: *const Renderer.Vertex,
t: f32,
) VkError![spv.SPIRV_MAX_OUTPUT_LOCATIONS]VertexInterpolation {
return interpolateVertexOutputs(allocator, v0, v1, v0, 1.0 - t, t, 0.0); return interpolateVertexOutputs(allocator, v0, v1, v0, 1.0 - t, t, 0.0);
} }
+10 -13
View File
@@ -65,10 +65,7 @@ pub fn load() VkError!void {
if (ref_count.load(.monotonic) != 0) if (ref_count.load(.monotonic) != 0)
return; return;
module = std.DynLib.open("libwayland-client.so.0") catch { module = std.DynLib.open("libwayland-client.so.0") catch return VkError.Unknown;
_ = ref_count.fetchSub(1, .monotonic);
return VkError.Unknown;
};
errdefer module.close(); errdefer module.close();
errdefer std.log.scoped(.WaylandClient).err("Could not open 'libwayland-client.so.0': {s}", .{std.c.dlerror() orelse "unknown error"}); errdefer std.log.scoped(.WaylandClient).err("Could not open 'libwayland-client.so.0': {s}", .{std.c.dlerror() orelse "unknown error"});
@@ -94,7 +91,7 @@ pub fn unload() void {
} }
} }
pub fn wl_registry_bind(registry: *wl_registry, name: u32, interface: *const wl_interface, version: u32) callconv(.c) ?*wl_proxy { pub fn wl_registry_bind(registry: *wl_registry, name: u32, interface: *const wl_interface, version: u32) ?*wl_proxy {
return wl_proxy_marshal_flags( return wl_proxy_marshal_flags(
@ptrCast(@alignCast(registry)), @ptrCast(@alignCast(registry)),
WL_REGISTRY_BIND, WL_REGISTRY_BIND,
@@ -108,7 +105,7 @@ pub fn wl_registry_bind(registry: *wl_registry, name: u32, interface: *const wl_
); );
} }
pub fn wl_display_get_registry(display: *wl_display) callconv(.c) ?*wl_registry { pub fn wl_display_get_registry(display: *wl_display) ?*wl_registry {
return @ptrCast(@alignCast(wl_proxy_marshal_flags( return @ptrCast(@alignCast(wl_proxy_marshal_flags(
@ptrCast(@alignCast(display)), @ptrCast(@alignCast(display)),
WL_DISPLAY_GET_REGISTRY, WL_DISPLAY_GET_REGISTRY,
@@ -119,7 +116,7 @@ pub fn wl_display_get_registry(display: *wl_display) callconv(.c) ?*wl_registry
))); )));
} }
pub fn wl_registry_add_listener(registry: *wl_registry, listener: *const wl_registry_listener, data: ?*anyopaque) callconv(.c) c_int { pub fn wl_registry_add_listener(registry: *wl_registry, listener: *const wl_registry_listener, data: ?*anyopaque) c_int {
return wl_proxy_add_listener(@ptrCast(@alignCast(registry)), @ptrCast(@alignCast(@constCast(listener))), data); return wl_proxy_add_listener(@ptrCast(@alignCast(registry)), @ptrCast(@alignCast(@constCast(listener))), data);
} }
@@ -136,7 +133,7 @@ pub fn wl_shm_create_pool(shm: *wl_shm, fd: i32, size: i32) callconv(.c) ?*wl_sh
))); )));
} }
pub fn wl_shm_pool_destroy(shm_pool: *wl_shm_pool) callconv(.c) void { pub fn wl_shm_pool_destroy(shm_pool: *wl_shm_pool) void {
_ = wl_proxy_marshal_flags( _ = wl_proxy_marshal_flags(
@ptrCast(@alignCast(shm_pool)), @ptrCast(@alignCast(shm_pool)),
WL_SHM_POOL_DESTROY, WL_SHM_POOL_DESTROY,
@@ -146,7 +143,7 @@ pub fn wl_shm_pool_destroy(shm_pool: *wl_shm_pool) callconv(.c) void {
); );
} }
pub fn wl_shm_pool_create_buffer(shm_pool: *wl_shm_pool, offset: i32, width: i32, height: i32, stride: i32, format: u32) callconv(.c) ?*wl_buffer { pub fn wl_shm_pool_create_buffer(shm_pool: *wl_shm_pool, offset: i32, width: i32, height: i32, stride: i32, format: u32) ?*wl_buffer {
return @ptrCast(@alignCast(wl_proxy_marshal_flags( return @ptrCast(@alignCast(wl_proxy_marshal_flags(
@ptrCast(@alignCast(shm_pool)), @ptrCast(@alignCast(shm_pool)),
WL_SHM_POOL_CREATE_BUFFER, WL_SHM_POOL_CREATE_BUFFER,
@@ -162,7 +159,7 @@ pub fn wl_shm_pool_create_buffer(shm_pool: *wl_shm_pool, offset: i32, width: i32
))); )));
} }
pub fn wl_buffer_destroy(buffer: *wl_buffer) callconv(.c) void { pub fn wl_buffer_destroy(buffer: *wl_buffer) void {
_ = wl_proxy_marshal_flags( _ = wl_proxy_marshal_flags(
@ptrCast(@alignCast(buffer)), @ptrCast(@alignCast(buffer)),
WL_BUFFER_DESTROY, WL_BUFFER_DESTROY,
@@ -172,7 +169,7 @@ pub fn wl_buffer_destroy(buffer: *wl_buffer) callconv(.c) void {
); );
} }
pub fn wl_surface_attach(surface: *wl_surface, buffer: *wl_buffer, x: i32, y: i32) callconv(.c) void { pub fn wl_surface_attach(surface: *wl_surface, buffer: *wl_buffer, x: i32, y: i32) void {
_ = wl_proxy_marshal_flags( _ = wl_proxy_marshal_flags(
@ptrCast(@alignCast(surface)), @ptrCast(@alignCast(surface)),
WL_SURFACE_ATTACH, WL_SURFACE_ATTACH,
@@ -185,7 +182,7 @@ pub fn wl_surface_attach(surface: *wl_surface, buffer: *wl_buffer, x: i32, y: i3
); );
} }
pub fn wl_surface_damage(surface: *wl_surface, x: i32, y: i32, width: i32, height: i32) callconv(.c) void { pub fn wl_surface_damage(surface: *wl_surface, x: i32, y: i32, width: i32, height: i32) void {
_ = wl_proxy_marshal_flags( _ = wl_proxy_marshal_flags(
@ptrCast(@alignCast(surface)), @ptrCast(@alignCast(surface)),
WL_SURFACE_DAMAGE, WL_SURFACE_DAMAGE,
@@ -199,7 +196,7 @@ pub fn wl_surface_damage(surface: *wl_surface, x: i32, y: i32, width: i32, heigh
); );
} }
pub fn wl_surface_commit(surface: *wl_surface) callconv(.c) void { pub fn wl_surface_commit(surface: *wl_surface) void {
_ = wl_proxy_marshal_flags( _ = wl_proxy_marshal_flags(
@ptrCast(@alignCast(surface)), @ptrCast(@alignCast(surface)),
WL_SURFACE_COMMIT, WL_SURFACE_COMMIT,