adding some opcodes
This commit is contained in:
@@ -59,8 +59,9 @@
|
|||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
.SPIRV_Interpreter = .{
|
.SPIRV_Interpreter = .{
|
||||||
.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#ad013d23fcf287d7354a05251ad0140f5fb883f7",
|
//.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#1a48af468d345d8786cbb9b7d9f308f8832cbcd0",
|
||||||
.hash = "SPIRV_Interpreter-0.0.1-ajmpnwSPAwD5VW4PJc1fUX0Q7niFovZyIHfhM7jZ2kkB",
|
//.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);
|
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;
|
self.interface.submit() catch return;
|
||||||
defer self.interface.finish() catch {};
|
defer self.interface.finish() catch {};
|
||||||
|
|
||||||
for (self.commands.items) |command| {
|
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 {
|
pub fn begin(interface: *Interface, _: *const vk.CommandBufferBeginInfo) VkError!void {
|
||||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
// No-op
|
||||||
_ = self.command_allocator.reset(.free_all);
|
_ = interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn end(interface: *Interface) VkError!void {
|
pub fn end(interface: *Interface) VkError!void {
|
||||||
|
|||||||
@@ -13,17 +13,22 @@ const NonDispatchable = base.NonDispatchable;
|
|||||||
const Self = @This();
|
const Self = @This();
|
||||||
pub const Interface = base.DescriptorSet;
|
pub const Interface = base.DescriptorSet;
|
||||||
|
|
||||||
const Descriptor = union(enum) {
|
const DescriptorBuffer = struct {
|
||||||
buffer: struct {
|
|
||||||
object: ?*SoftBuffer,
|
object: ?*SoftBuffer,
|
||||||
offset: vk.DeviceSize,
|
offset: vk.DeviceSize,
|
||||||
size: vk.DeviceSize,
|
size: vk.DeviceSize,
|
||||||
},
|
};
|
||||||
|
|
||||||
|
const Descriptor = union(enum) {
|
||||||
|
buffer: []DescriptorBuffer,
|
||||||
image: struct {},
|
image: struct {},
|
||||||
};
|
};
|
||||||
|
|
||||||
interface: Interface,
|
interface: Interface,
|
||||||
|
|
||||||
|
/// Memory containing actual binding descriptors and their array
|
||||||
|
heap: []u8,
|
||||||
|
|
||||||
descriptors: []Descriptor,
|
descriptors: []Descriptor,
|
||||||
|
|
||||||
pub fn create(device: *base.Device, allocator: std.mem.Allocator, layout: *base.DescriptorSetLayout) VkError!*Self {
|
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,
|
.write = write,
|
||||||
};
|
};
|
||||||
|
|
||||||
const descriptors = allocator.alloc(Descriptor, layout.bindings.len) catch return VkError.OutOfHostMemory;
|
const heap_size = blk: {
|
||||||
errdefer allocator.free(descriptors);
|
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.* = .{
|
self.* = .{
|
||||||
.interface = interface,
|
.interface = interface,
|
||||||
|
.heap = heap,
|
||||||
.descriptors = descriptors,
|
.descriptors = descriptors,
|
||||||
};
|
};
|
||||||
return self;
|
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 {
|
pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void {
|
||||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
allocator.free(self.descriptors);
|
allocator.free(self.heap);
|
||||||
allocator.destroy(self);
|
allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,19 +98,17 @@ pub fn write(interface: *Interface, write_data: vk.WriteDescriptorSet) VkError!v
|
|||||||
switch (write_data.descriptor_type) {
|
switch (write_data.descriptor_type) {
|
||||||
.storage_buffer, .storage_buffer_dynamic => {
|
.storage_buffer, .storage_buffer_dynamic => {
|
||||||
for (write_data.p_buffer_info, 0..write_data.descriptor_count) |buffer_info, i| {
|
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.* = .{
|
desc.* = .{
|
||||||
.buffer = .{
|
|
||||||
.object = null,
|
.object = null,
|
||||||
.offset = buffer_info.offset,
|
.offset = buffer_info.offset,
|
||||||
.size = buffer_info.range,
|
.size = buffer_info.range,
|
||||||
},
|
|
||||||
};
|
};
|
||||||
if (buffer_info.buffer != .null_handle) {
|
if (buffer_info.buffer != .null_handle) {
|
||||||
const buffer = try NonDispatchable(Buffer).fromHandleObject(buffer_info.buffer);
|
const buffer = try NonDispatchable(Buffer).fromHandleObject(buffer_info.buffer);
|
||||||
desc.buffer.object = @as(*SoftBuffer, @alignCast(@fieldParentPtr("interface", buffer)));
|
desc.object = @as(*SoftBuffer, @alignCast(@fieldParentPtr("interface", buffer)));
|
||||||
if (desc.buffer.size == vk.WHOLE_SIZE) {
|
if (desc.size == vk.WHOLE_SIZE) {
|
||||||
desc.buffer.size = if (buffer.memory) |memory| memory.size - desc.buffer.offset else return VkError.InvalidDeviceMemoryDrv;
|
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| {
|
for (info.command_buffers.items) |command_buffer| {
|
||||||
const soft_command_buffer: *SoftCommandBuffer = @alignCast(@fieldParentPtr("interface", command_buffer));
|
const soft_command_buffer: *SoftCommandBuffer = @alignCast(@fieldParentPtr("interface", command_buffer));
|
||||||
soft_command_buffer.execute(&execution_device) catch |err| {
|
soft_command_buffer.execute(&execution_device);
|
||||||
base.errors.errorLoggerContext(err, "the software execution device");
|
|
||||||
if (@errorReturnTrace()) |trace| {
|
|
||||||
std.debug.dumpStackTrace(trace.*);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_fence) |fence| {
|
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),
|
.use_simd_vectors_specializations = !std.process.hasEnvVarConstant(lib.NO_SHADER_SIMD_ENV_NAME),
|
||||||
}) catch |err| switch (err) {
|
}) catch |err| switch (err) {
|
||||||
spv.Module.ModuleError.OutOfMemory => return VkError.OutOfHostMemory,
|
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),
|
.ref_count = std.atomic.Value(usize).init(1),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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 spv = @import("spv");
|
const spv = @import("spv");
|
||||||
|
const lib = @import("../lib.zig");
|
||||||
|
|
||||||
const PipelineState = @import("PipelineState.zig");
|
const PipelineState = @import("PipelineState.zig");
|
||||||
|
|
||||||
@@ -52,6 +53,22 @@ pub fn dispatch(self: *Self, group_count_x: u32, group_count_y: u32, group_count
|
|||||||
|
|
||||||
var wg: std.Thread.WaitGroup = .{};
|
var wg: std.Thread.WaitGroup = .{};
|
||||||
for (0..@min(self.batch_size, group_count)) |batch_id| {
|
for (0..@min(self.batch_size, group_count)) |batch_id| {
|
||||||
|
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, .{
|
self.device.workers.spawnWg(&wg, runWrapper, .{
|
||||||
RunData{
|
RunData{
|
||||||
.self = self,
|
.self = self,
|
||||||
@@ -65,6 +82,7 @@ pub fn dispatch(self: *Self, group_count_x: u32, group_count_y: u32, group_count
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
self.device.workers.waitAndWork(&wg);
|
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| {
|
bindings: for (set.?.descriptors[0..], 0..) |binding, binding_index| {
|
||||||
switch (binding) {
|
switch (binding) {
|
||||||
.buffer => |buffer_data| if (buffer_data.object) |buffer| {
|
.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 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];
|
const map: []u8 = @as([*]u8, @ptrCast(try memory.map(buffer_data.offset, buffer_data.size)))[0..buffer_data.size];
|
||||||
try rt.writeDescriptorSet(
|
try rt.writeDescriptorSet(
|
||||||
map,
|
map,
|
||||||
@as(u32, @intCast(set_index)),
|
@as(u32, @intCast(set_index)),
|
||||||
@as(u32, @intCast(binding_index)),
|
@as(u32, @intCast(binding_index)),
|
||||||
|
@as(u32, @intCast(descriptor_index)),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ pub const DRIVER_VERSION = vk.makeApiVersion(0, 0, 0, 1);
|
|||||||
pub const DEVICE_ID = 0x600DCAFE;
|
pub const DEVICE_ID = 0x600DCAFE;
|
||||||
|
|
||||||
pub const NO_SHADER_SIMD_ENV_NAME = "STROLL_SOFT_NO_SIMD";
|
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.
|
/// Generic system memory.
|
||||||
pub const MEMORY_TYPE_GENERIC_BIT = 0;
|
pub const MEMORY_TYPE_GENERIC_BIT = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user