adding some opcodes
This commit is contained in:
@@ -59,8 +59,9 @@
|
||||
.lazy = true,
|
||||
},
|
||||
.SPIRV_Interpreter = .{
|
||||
.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#ad013d23fcf287d7354a05251ad0140f5fb883f7",
|
||||
.hash = "SPIRV_Interpreter-0.0.1-ajmpnwSPAwD5VW4PJc1fUX0Q7niFovZyIHfhM7jZ2kkB",
|
||||
//.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#1a48af468d345d8786cbb9b7d9f308f8832cbcd0",
|
||||
//.hash = "SPIRV_Interpreter-0.0.1-ajmpn8CQAwD6-6jsLx5nODWFc4lAUvVTuZVVHop1X3-m",
|
||||
.path = "../SPIRV-Interpreter",
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -71,18 +71,24 @@ pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void {
|
||||
allocator.destroy(self);
|
||||
}
|
||||
|
||||
pub fn execute(self: *Self, device: *ExecutionDevice) VkError!void {
|
||||
pub fn execute(self: *Self, device: *ExecutionDevice) void {
|
||||
self.interface.submit() catch return;
|
||||
defer self.interface.finish() catch {};
|
||||
|
||||
for (self.commands.items) |command| {
|
||||
try command.vtable.execute(command.ptr, device);
|
||||
command.vtable.execute(command.ptr, device) catch |err| {
|
||||
base.errors.errorLoggerContext(err, "the software execution device");
|
||||
if (@errorReturnTrace()) |trace| {
|
||||
std.debug.dumpStackTrace(trace.*);
|
||||
}
|
||||
return; // Should we return or continue ? Maybe device lost ?
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn begin(interface: *Interface, _: *const vk.CommandBufferBeginInfo) VkError!void {
|
||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||
_ = self.command_allocator.reset(.free_all);
|
||||
// No-op
|
||||
_ = interface;
|
||||
}
|
||||
|
||||
pub fn end(interface: *Interface) VkError!void {
|
||||
|
||||
@@ -13,17 +13,22 @@ const NonDispatchable = base.NonDispatchable;
|
||||
const Self = @This();
|
||||
pub const Interface = base.DescriptorSet;
|
||||
|
||||
const DescriptorBuffer = struct {
|
||||
object: ?*SoftBuffer,
|
||||
offset: vk.DeviceSize,
|
||||
size: vk.DeviceSize,
|
||||
};
|
||||
|
||||
const Descriptor = union(enum) {
|
||||
buffer: struct {
|
||||
object: ?*SoftBuffer,
|
||||
offset: vk.DeviceSize,
|
||||
size: vk.DeviceSize,
|
||||
},
|
||||
buffer: []DescriptorBuffer,
|
||||
image: struct {},
|
||||
};
|
||||
|
||||
interface: Interface,
|
||||
|
||||
/// Memory containing actual binding descriptors and their array
|
||||
heap: []u8,
|
||||
|
||||
descriptors: []Descriptor,
|
||||
|
||||
pub fn create(device: *base.Device, allocator: std.mem.Allocator, layout: *base.DescriptorSetLayout) VkError!*Self {
|
||||
@@ -38,11 +43,38 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, layout: *base.
|
||||
.write = write,
|
||||
};
|
||||
|
||||
const descriptors = allocator.alloc(Descriptor, layout.bindings.len) catch return VkError.OutOfHostMemory;
|
||||
errdefer allocator.free(descriptors);
|
||||
const heap_size = blk: {
|
||||
var size: usize = layout.bindings.len * @sizeOf(Descriptor);
|
||||
for (layout.bindings) |binding| {
|
||||
const struct_size: usize = switch (binding.descriptor_type) {
|
||||
.storage_buffer, .storage_buffer_dynamic => @sizeOf(DescriptorBuffer),
|
||||
else => 0,
|
||||
};
|
||||
|
||||
size += binding.array_size * struct_size;
|
||||
}
|
||||
break :blk size;
|
||||
};
|
||||
|
||||
const heap = allocator.alloc(u8, heap_size) catch return VkError.OutOfHostMemory;
|
||||
errdefer allocator.free(heap);
|
||||
|
||||
var local_heap = std.heap.FixedBufferAllocator.init(heap);
|
||||
const local_allocator = local_heap.allocator();
|
||||
|
||||
const descriptors = local_allocator.alloc(Descriptor, layout.bindings.len) catch return VkError.OutOfHostMemory;
|
||||
for (descriptors, layout.bindings) |*descriptor, binding| {
|
||||
switch (binding.descriptor_type) {
|
||||
.storage_buffer, .storage_buffer_dynamic => descriptor.* = .{
|
||||
.buffer = local_allocator.alloc(DescriptorBuffer, binding.array_size) catch return VkError.OutOfHostMemory,
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
self.* = .{
|
||||
.interface = interface,
|
||||
.heap = heap,
|
||||
.descriptors = descriptors,
|
||||
};
|
||||
return self;
|
||||
@@ -56,7 +88,7 @@ pub fn copy(interface: *Interface, copy_data: vk.CopyDescriptorSet) VkError!void
|
||||
|
||||
pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void {
|
||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||
allocator.free(self.descriptors);
|
||||
allocator.free(self.heap);
|
||||
allocator.destroy(self);
|
||||
}
|
||||
|
||||
@@ -66,19 +98,17 @@ pub fn write(interface: *Interface, write_data: vk.WriteDescriptorSet) VkError!v
|
||||
switch (write_data.descriptor_type) {
|
||||
.storage_buffer, .storage_buffer_dynamic => {
|
||||
for (write_data.p_buffer_info, 0..write_data.descriptor_count) |buffer_info, i| {
|
||||
const desc = &self.descriptors[write_data.dst_binding + i];
|
||||
const desc = &self.descriptors[write_data.dst_binding].buffer[i];
|
||||
desc.* = .{
|
||||
.buffer = .{
|
||||
.object = null,
|
||||
.offset = buffer_info.offset,
|
||||
.size = buffer_info.range,
|
||||
},
|
||||
.object = null,
|
||||
.offset = buffer_info.offset,
|
||||
.size = buffer_info.range,
|
||||
};
|
||||
if (buffer_info.buffer != .null_handle) {
|
||||
const buffer = try NonDispatchable(Buffer).fromHandleObject(buffer_info.buffer);
|
||||
desc.buffer.object = @as(*SoftBuffer, @alignCast(@fieldParentPtr("interface", buffer)));
|
||||
if (desc.buffer.size == vk.WHOLE_SIZE) {
|
||||
desc.buffer.size = if (buffer.memory) |memory| memory.size - desc.buffer.offset else return VkError.InvalidDeviceMemoryDrv;
|
||||
desc.object = @as(*SoftBuffer, @alignCast(@fieldParentPtr("interface", buffer)));
|
||||
if (desc.size == vk.WHOLE_SIZE) {
|
||||
desc.size = if (buffer.memory) |memory| memory.size - desc.offset else return VkError.InvalidDeviceMemoryDrv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,12 +104,7 @@ fn taskRunner(self: *Self, info: Interface.SubmitInfo, p_fence: ?*base.Fence, ru
|
||||
|
||||
for (info.command_buffers.items) |command_buffer| {
|
||||
const soft_command_buffer: *SoftCommandBuffer = @alignCast(@fieldParentPtr("interface", command_buffer));
|
||||
soft_command_buffer.execute(&execution_device) catch |err| {
|
||||
base.errors.errorLoggerContext(err, "the software execution device");
|
||||
if (@errorReturnTrace()) |trace| {
|
||||
std.debug.dumpStackTrace(trace.*);
|
||||
}
|
||||
};
|
||||
soft_command_buffer.execute(&execution_device);
|
||||
}
|
||||
|
||||
if (p_fence) |fence| {
|
||||
|
||||
@@ -35,7 +35,13 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v
|
||||
.use_simd_vectors_specializations = !std.process.hasEnvVarConstant(lib.NO_SHADER_SIMD_ENV_NAME),
|
||||
}) catch |err| switch (err) {
|
||||
spv.Module.ModuleError.OutOfMemory => return VkError.OutOfHostMemory,
|
||||
else => return VkError.ValidationFailed,
|
||||
else => {
|
||||
std.log.scoped(.@"SPIR-V module").err("module creation catched a '{s}'", .{@errorName(err)});
|
||||
if (@errorReturnTrace()) |trace| {
|
||||
std.debug.dumpStackTrace(trace.*);
|
||||
}
|
||||
return VkError.ValidationFailed;
|
||||
},
|
||||
},
|
||||
.ref_count = std.atomic.Value(usize).init(1),
|
||||
};
|
||||
|
||||
@@ -2,6 +2,7 @@ const std = @import("std");
|
||||
const vk = @import("vulkan");
|
||||
const base = @import("base");
|
||||
const spv = @import("spv");
|
||||
const lib = @import("../lib.zig");
|
||||
|
||||
const PipelineState = @import("PipelineState.zig");
|
||||
|
||||
@@ -52,18 +53,35 @@ pub fn dispatch(self: *Self, group_count_x: u32, group_count_y: u32, group_count
|
||||
|
||||
var wg: std.Thread.WaitGroup = .{};
|
||||
for (0..@min(self.batch_size, group_count)) |batch_id| {
|
||||
self.device.workers.spawnWg(&wg, runWrapper, .{
|
||||
RunData{
|
||||
.self = self,
|
||||
.batch_id = batch_id,
|
||||
.group_count = group_count,
|
||||
.group_count_x = @as(usize, @intCast(group_count_x)),
|
||||
.group_count_y = @as(usize, @intCast(group_count_y)),
|
||||
.group_count_z = @as(usize, @intCast(group_count_z)),
|
||||
.invocations_per_workgroup = invocations_per_workgroup,
|
||||
.pipeline = pipeline,
|
||||
},
|
||||
});
|
||||
if (std.process.hasEnvVarConstant(lib.SINGLE_THREAD_COMPUTE_EXECUTION_ENV_NAME)) {
|
||||
@branchHint(.cold); // Should only be reached for debugging
|
||||
|
||||
runWrapper(
|
||||
RunData{
|
||||
.self = self,
|
||||
.batch_id = batch_id,
|
||||
.group_count = group_count,
|
||||
.group_count_x = @as(usize, @intCast(group_count_x)),
|
||||
.group_count_y = @as(usize, @intCast(group_count_y)),
|
||||
.group_count_z = @as(usize, @intCast(group_count_z)),
|
||||
.invocations_per_workgroup = invocations_per_workgroup,
|
||||
.pipeline = pipeline,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
self.device.workers.spawnWg(&wg, runWrapper, .{
|
||||
RunData{
|
||||
.self = self,
|
||||
.batch_id = batch_id,
|
||||
.group_count = group_count,
|
||||
.group_count_x = @as(usize, @intCast(group_count_x)),
|
||||
.group_count_y = @as(usize, @intCast(group_count_y)),
|
||||
.group_count_z = @as(usize, @intCast(group_count_z)),
|
||||
.invocations_per_workgroup = invocations_per_workgroup,
|
||||
.pipeline = pipeline,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
self.device.workers.waitAndWork(&wg);
|
||||
}
|
||||
@@ -135,14 +153,17 @@ fn writeDescriptorSets(self: *Self, rt: *spv.Runtime) !void {
|
||||
|
||||
bindings: for (set.?.descriptors[0..], 0..) |binding, binding_index| {
|
||||
switch (binding) {
|
||||
.buffer => |buffer_data| if (buffer_data.object) |buffer| {
|
||||
const memory = if (buffer.interface.memory) |memory| memory else continue :bindings;
|
||||
const map: []u8 = @as([*]u8, @ptrCast(try memory.map(buffer_data.offset, buffer_data.size)))[0..buffer_data.size];
|
||||
try rt.writeDescriptorSet(
|
||||
map,
|
||||
@as(u32, @intCast(set_index)),
|
||||
@as(u32, @intCast(binding_index)),
|
||||
);
|
||||
.buffer => |buffer_data_array| for (buffer_data_array, 0..) |buffer_data, descriptor_index| {
|
||||
if (buffer_data.object) |buffer| {
|
||||
const memory = if (buffer.interface.memory) |memory| memory else continue :bindings;
|
||||
const map: []u8 = @as([*]u8, @ptrCast(try memory.map(buffer_data.offset, buffer_data.size)))[0..buffer_data.size];
|
||||
try rt.writeDescriptorSet(
|
||||
map,
|
||||
@as(u32, @intCast(set_index)),
|
||||
@as(u32, @intCast(binding_index)),
|
||||
@as(u32, @intCast(descriptor_index)),
|
||||
);
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ pub const DRIVER_VERSION = vk.makeApiVersion(0, 0, 0, 1);
|
||||
pub const DEVICE_ID = 0x600DCAFE;
|
||||
|
||||
pub const NO_SHADER_SIMD_ENV_NAME = "STROLL_SOFT_NO_SIMD";
|
||||
pub const SINGLE_THREAD_COMPUTE_EXECUTION_ENV_NAME = "STROLL_SINGLE_THREAD_COMPUTE_EXECUTION";
|
||||
|
||||
/// Generic system memory.
|
||||
pub const MEMORY_TYPE_GENERIC_BIT = 0;
|
||||
|
||||
Reference in New Issue
Block a user