base texture sampling
Test / build_and_test (push) Successful in 46s
Build / build (push) Successful in 1m15s

This commit is contained in:
2026-05-20 18:30:36 +02:00
parent 4d344e83d3
commit 800c867cdd
5 changed files with 236 additions and 31 deletions
+157 -22
View File
@@ -7,6 +7,7 @@ const Device = base.Device;
const Buffer = base.Buffer;
const BufferView = base.BufferView;
const ImageView = base.ImageView;
const Sampler = base.Sampler;
const SoftBuffer = @import("SoftBuffer.zig");
const SoftBufferView = @import("SoftBufferView.zig");
@@ -72,12 +73,18 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, layout: *base.
.storage_buffer,
.storage_buffer_dynamic,
=> @sizeOf(DescriptorBuffer),
.storage_image,
.input_attachment,
=> @sizeOf(DescriptorImage),
.storage_texel_buffer,
.uniform_texel_buffer,
=> @sizeOf(DescriptorTexel),
.combined_image_sampler,
=> @sizeOf(DescriptorTexture),
else => 0,
};
@@ -135,7 +142,22 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, layout: *base.
}
break :blk desc;
},
else => {},
.combined_image_sampler,
=> descriptor.* = blk: {
const desc: Descriptor = .{
.texture = local_allocator.alloc(DescriptorTexture, binding.array_size) catch return VkError.OutOfHostMemory,
};
for (desc.texture[0..]) |*d| {
d.* = .{
.sampler = null,
.view = null,
};
}
break :blk desc;
},
else => descriptor.* = .{ .unsupported = .{} },
}
}
@@ -153,33 +175,124 @@ pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void {
allocator.destroy(self);
}
fn descriptorLen(descriptor: Descriptor) usize {
return switch (descriptor) {
.buffer => |buffer| buffer.len,
.image => |image| image.len,
.texel_buffer => |texel_buffer| texel_buffer.len,
.texture => |texture| texture.len,
.unsupported => 0,
};
}
fn advanceToAvailableDescriptor(descriptors: []const Descriptor, binding: *usize, array_element: *usize) bool {
while (binding.* < descriptors.len) {
switch (descriptors[binding.*]) {
.unsupported => return true,
else => {},
}
const len = descriptorLen(descriptors[binding.*]);
if (array_element.* < len) return true;
if (array_element.* > len) return false;
binding.* += 1;
array_element.* = 0;
}
return false;
}
fn copyDescriptorRange(dst_desc: *Descriptor, dst_array_element: usize, src_desc: Descriptor, src_array_element: usize, descriptor_count: usize) bool {
switch (dst_desc.*) {
.buffer => |dst_buffer| {
const src_buffer = switch (src_desc) {
.buffer => |buffer| buffer,
else => return false,
};
@memcpy(
dst_buffer[dst_array_element .. dst_array_element + descriptor_count],
src_buffer[src_array_element .. src_array_element + descriptor_count],
);
},
.image => |dst_image| {
const src_image = switch (src_desc) {
.image => |image| image,
else => return false,
};
@memcpy(
dst_image[dst_array_element .. dst_array_element + descriptor_count],
src_image[src_array_element .. src_array_element + descriptor_count],
);
},
.texel_buffer => |dst_texel_buffer| {
const src_texel_buffer = switch (src_desc) {
.texel_buffer => |texel_buffer| texel_buffer,
else => return false,
};
@memcpy(
dst_texel_buffer[dst_array_element .. dst_array_element + descriptor_count],
src_texel_buffer[src_array_element .. src_array_element + descriptor_count],
);
},
.texture => |dst_texture| {
const src_texture = switch (src_desc) {
.texture => |texture| texture,
else => return false,
};
@memcpy(
dst_texture[dst_array_element .. dst_array_element + descriptor_count],
src_texture[src_array_element .. src_array_element + descriptor_count],
);
},
.unsupported => return false,
}
return true;
}
pub fn copy(interface: *Interface, src_interface: *const Interface, data: vk.CopyDescriptorSet) VkError!void {
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
const src: *const Self = @alignCast(@fieldParentPtr("interface", src_interface));
const dst_start = @min(@as(usize, @intCast(data.dst_binding)), self.descriptors.len);
const src_start = @min(@as(usize, @intCast(data.src_binding)), src.descriptors.len);
var dst_binding: usize = @intCast(data.dst_binding);
var src_binding: usize = @intCast(data.src_binding);
var dst_array_element: usize = @intCast(data.dst_array_element);
var src_array_element: usize = @intCast(data.src_array_element);
var descriptor_count: usize = @intCast(data.descriptor_count);
const descriptor_count: usize = @intCast(data.descriptor_count);
const dst_remaining = self.descriptors.len - dst_start;
const src_remaining = src.descriptors.len - src_start;
const copy_count = @min(descriptor_count, dst_remaining, src_remaining);
const dst_slice = self.descriptors[dst_start .. dst_start + copy_count];
const src_slice = src.descriptors[src_start .. src_start + copy_count];
for (dst_slice, src_slice) |*dst_desc, src_desc| {
switch (dst_desc.*) {
.buffer => |dst_buffer| @memcpy(dst_buffer[0..], src_desc.buffer[0..]),
.image => |dst_image| @memcpy(dst_image[0..], src_desc.image[0..]),
.texel_buffer => |dst_texel| @memcpy(dst_texel[0..], src_desc.texel_buffer[0..]),
else => {
dst_desc.* = .{ .unsupported = .{} };
base.unsupported("descriptor type for copy", .{});
},
while (descriptor_count > 0) {
if (!advanceToAvailableDescriptor(self.descriptors, &dst_binding, &dst_array_element) or
!advanceToAvailableDescriptor(src.descriptors, &src_binding, &src_array_element))
{
return;
}
const dst_desc = &self.descriptors[dst_binding];
const src_desc = src.descriptors[src_binding];
const dst_len = descriptorLen(dst_desc.*);
const src_len = descriptorLen(src_desc);
if (dst_len == 0 or src_len == 0) {
base.unsupported("descriptor type for copy", .{});
return;
}
const dst_remaining = dst_len - dst_array_element;
const src_remaining = src_len - src_array_element;
const copy_count = @min(descriptor_count, dst_remaining, src_remaining);
if (!copyDescriptorRange(dst_desc, dst_array_element, src_desc, src_array_element, copy_count)) {
base.unsupported("descriptor type for copy", .{});
return;
}
descriptor_count -= copy_count;
dst_array_element += copy_count;
src_array_element += copy_count;
}
}
@@ -207,6 +320,7 @@ pub fn write(interface: *Interface, write_data: vk.WriteDescriptorSet) VkError!v
}
}
},
.storage_image,
.input_attachment,
=> {
@@ -219,6 +333,7 @@ pub fn write(interface: *Interface, write_data: vk.WriteDescriptorSet) VkError!v
}
}
},
.storage_texel_buffer,
.uniform_texel_buffer,
=> {
@@ -231,6 +346,26 @@ pub fn write(interface: *Interface, write_data: vk.WriteDescriptorSet) VkError!v
}
}
},
.combined_image_sampler,
=> {
for (write_data.p_image_info, 0..write_data.descriptor_count) |image_info, i| {
const desc = &self.descriptors[write_data.dst_binding].texture[i];
desc.* = .{
.sampler = null,
.view = null,
};
if (image_info.image_view != .null_handle) {
const image_view = try NonDispatchable(ImageView).fromHandleObject(image_info.image_view);
desc.view = @as(*SoftImageView, @alignCast(@fieldParentPtr("interface", image_view)));
}
if (image_info.sampler != .null_handle) {
const sampler = try NonDispatchable(Sampler).fromHandleObject(image_info.sampler);
desc.sampler = @as(*SoftSampler, @alignCast(@fieldParentPtr("interface", sampler)));
}
}
},
else => {
self.descriptors[write_data.dst_binding] = .{ .unsupported = .{} };
base.unsupported("descriptor type {s} for writting", .{@tagName(write_data.descriptor_type)});