working on vertex implementation
This commit is contained in:
+2
-2
@@ -31,8 +31,8 @@
|
|||||||
.hash = "zmath-0.11.0-dev-wjwivdMsAwD-xaLj76YHUq3t9JDH-X16xuMTmnDzqbu2",
|
.hash = "zmath-0.11.0-dev-wjwivdMsAwD-xaLj76YHUq3t9JDH-X16xuMTmnDzqbu2",
|
||||||
},
|
},
|
||||||
.SPIRV_Interpreter = .{
|
.SPIRV_Interpreter = .{
|
||||||
.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#664ea9b92bf84bc97ec4a062c171562bf6628263",
|
.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#5b7380eea014dce11587597d44681640a3a3583b",
|
||||||
.hash = "SPIRV_Interpreter-0.0.1-ajmpn1qKBACshq_ncUUF-zXJzpdNLRzIAPcWRQL57W8l",
|
.hash = "SPIRV_Interpreter-0.0.1-ajmpnwaZBAA5PJz7wTcWkWPywJAJF672vYjuCZKO4t9j",
|
||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -482,7 +482,7 @@ pub fn draw(interface: *Interface, vertex_count: usize, instance_count: usize, f
|
|||||||
|
|
||||||
pub fn execute(context: *anyopaque, device: *ExecutionDevice) VkError!void {
|
pub fn execute(context: *anyopaque, device: *ExecutionDevice) VkError!void {
|
||||||
const impl: *Impl = @ptrCast(@alignCast(context));
|
const impl: *Impl = @ptrCast(@alignCast(context));
|
||||||
device.renderer.drawPrimitive(impl.vertex_count, impl.instance_count, impl.first_vertex, impl.first_instance);
|
try device.renderer.draw(impl.vertex_count, impl.instance_count, impl.first_vertex, impl.first_instance);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -58,10 +58,9 @@ pub fn map(interface: *Interface, offset: vk.DeviceSize, size: vk.DeviceSize) Vk
|
|||||||
if (offset >= self.data.len or (size != vk.WHOLE_SIZE and offset + size > self.data.len)) {
|
if (offset >= self.data.len or (size != vk.WHOLE_SIZE and offset + size > self.data.len)) {
|
||||||
return VkError.MemoryMapFailed;
|
return VkError.MemoryMapFailed;
|
||||||
}
|
}
|
||||||
interface.is_mapped = true;
|
|
||||||
return @ptrCast(&self.data[offset]);
|
return @ptrCast(&self.data[offset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unmap(interface: *Interface) void {
|
pub fn unmap(_: *Interface) void {
|
||||||
interface.is_mapped = false;
|
// no-op
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ pub fn init(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.compute)]);
|
self.renderer = .init(device, &self.pipeline_states[@intFromEnum(vk.PipelineBindPoint.graphics)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Self) void {
|
pub fn deinit(self: *Self) void {
|
||||||
|
|||||||
@@ -15,21 +15,12 @@ const SoftFramebuffer = @import("../SoftFramebuffer.zig");
|
|||||||
const SoftPipeline = @import("../SoftPipeline.zig");
|
const SoftPipeline = @import("../SoftPipeline.zig");
|
||||||
const SoftRenderPass = @import("../SoftRenderPass.zig");
|
const SoftRenderPass = @import("../SoftRenderPass.zig");
|
||||||
|
|
||||||
|
const vertex_dispatcher = @import("vertex_dispatcher.zig");
|
||||||
|
|
||||||
const VkError = base.VkError;
|
const VkError = base.VkError;
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
const VertexInputBindingState = struct {
|
|
||||||
input_rate: vk.VertexInputRate,
|
|
||||||
stride: usize,
|
|
||||||
};
|
|
||||||
|
|
||||||
const VertexInputAttributeState = struct {
|
|
||||||
format: vk.Format,
|
|
||||||
offset: usize,
|
|
||||||
binding: usize,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const VertexBuffer = struct {
|
pub const VertexBuffer = struct {
|
||||||
buffer: *const SoftBuffer,
|
buffer: *const SoftBuffer,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
@@ -39,20 +30,7 @@ pub const VertexBuffer = struct {
|
|||||||
pub const DynamicState = struct {
|
pub const DynamicState = struct {
|
||||||
viewport: vk.Viewport,
|
viewport: vk.Viewport,
|
||||||
scissor: vk.Rect2D,
|
scissor: vk.Rect2D,
|
||||||
|
|
||||||
line_width: f32,
|
line_width: f32,
|
||||||
cull_mode: vk.CullModeFlags,
|
|
||||||
front_face: vk.FrontFace,
|
|
||||||
primitive_topology: vk.PrimitiveTopology,
|
|
||||||
|
|
||||||
vertex_input_bindings: [lib.MAX_VERTEX_INPUT_BINDINGS]VertexInputBindingState,
|
|
||||||
vertex_input_attributes: [lib.MAX_VERTEX_INPUT_ATTRIBUTES]VertexInputAttributeState,
|
|
||||||
};
|
|
||||||
|
|
||||||
const Vertex = struct {
|
|
||||||
position: F32x4,
|
|
||||||
point_size: f32,
|
|
||||||
index: usize,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
device: *SoftDevice,
|
device: *SoftDevice,
|
||||||
@@ -72,23 +50,73 @@ pub fn init(device: *SoftDevice, state: *PipelineState) Self {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drawPrimitive(self: *Self, vertex_count: usize, instance_count: usize, first_vertex: usize, first_instance: usize) void {
|
pub fn draw(self: *Self, vertex_count: usize, instance_count: usize, first_vertex: usize, first_instance: usize) VkError!void {
|
||||||
const allocator = self.device.device_allocator.allocator();
|
_ = first_vertex;
|
||||||
|
_ = first_instance;
|
||||||
|
|
||||||
const vertices = self.fetchVertexInput(allocator, vertex_count, instance_count, first_vertex, first_instance);
|
self.inputAssemblyStage() catch |err| {
|
||||||
_ = vertices;
|
std.log.scoped(.@"Input assembly stage").err("catched a '{s}'", .{@errorName(err)});
|
||||||
|
if (@errorReturnTrace()) |trace| {
|
||||||
|
std.debug.dumpErrorReturnTrace(trace);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.vertexShaderStage(vertex_count, instance_count) catch |err| {
|
||||||
|
std.log.scoped(.@"Input assembly stage").err("catched a '{s}'", .{@errorName(err)});
|
||||||
|
if (@errorReturnTrace()) |trace| {
|
||||||
|
std.debug.dumpErrorReturnTrace(trace);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.primitiveAssemblyStage();
|
||||||
|
self.fragmentShaderStage();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Self) void {
|
pub fn deinit(self: *Self) void {
|
||||||
_ = self;
|
_ = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetchVertexInput(self: *const Self, allocator: std.mem.Allocator, vertex_count: usize, instance_count: usize, first_vertex: usize, first_instance: usize) []Vertex {
|
fn inputAssemblyStage(self: *Self) !void {
|
||||||
_ = self;
|
const pipeline = self.state.pipeline orelse return;
|
||||||
_ = allocator;
|
for ((pipeline.stages.getPtr(.vertex) orelse return).runtimes) |*rt| {
|
||||||
_ = vertex_count;
|
for (pipeline.interface.mode.graphics.input_assembly.attribute_description orelse return) |attribute| {
|
||||||
_ = instance_count;
|
const location_result = try rt.getResultByLocation(attribute.location, .input);
|
||||||
_ = first_vertex;
|
|
||||||
_ = first_instance;
|
const vertex_buffer = self.state.data.graphics.vertex_buffers[attribute.binding];
|
||||||
return undefined;
|
const buffer = vertex_buffer.buffer;
|
||||||
|
const buffer_memory_size = base.format.texelSize(attribute.format);
|
||||||
|
const buffer_memory = if (buffer.interface.memory) |memory| memory else return VkError.InvalidDeviceMemoryDrv;
|
||||||
|
const buffer_memory_map: []u8 = @as([*]u8, @ptrCast(@alignCast(try buffer_memory.map(buffer.interface.offset + attribute.offset, buffer_memory_size))))[0..buffer_memory_size];
|
||||||
|
|
||||||
|
try rt.writeInput(buffer_memory_map, location_result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vertexShaderStage(self: *Self, vertex_count: usize, instance_count: usize) !void {
|
||||||
|
const invocation_count = vertex_count * instance_count;
|
||||||
|
const pipeline = self.state.pipeline orelse return;
|
||||||
|
const batch_size = (pipeline.stages.getPtr(.vertex) orelse return).runtimes.len;
|
||||||
|
|
||||||
|
var wg: std.Io.Group = .init;
|
||||||
|
for (0..@min(batch_size, invocation_count)) |batch_id| {
|
||||||
|
const run_data: vertex_dispatcher.RunData = .{
|
||||||
|
.renderer = self,
|
||||||
|
.pipeline = pipeline,
|
||||||
|
.batch_id = batch_id,
|
||||||
|
.batch_size = batch_size,
|
||||||
|
.invocation_count = invocation_count,
|
||||||
|
};
|
||||||
|
|
||||||
|
wg.async(self.device.interface.io(), vertex_dispatcher.runWrapper, .{run_data});
|
||||||
|
}
|
||||||
|
wg.await(self.device.interface.io()) catch return VkError.DeviceLost;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn primitiveAssemblyStage(self: *Self) void {
|
||||||
|
_ = self;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fragmentShaderStage(self: *Self) void {
|
||||||
|
_ = self;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const spv = @import("spv");
|
||||||
|
|
||||||
|
const SpvRuntimeError = spv.Runtime.RuntimeError;
|
||||||
|
|
||||||
|
const Renderer = @import("Renderer.zig");
|
||||||
|
const SoftPipeline = @import("../SoftPipeline.zig");
|
||||||
|
|
||||||
|
pub const RunData = struct {
|
||||||
|
renderer: *Renderer,
|
||||||
|
pipeline: *SoftPipeline,
|
||||||
|
batch_id: usize,
|
||||||
|
batch_size: usize,
|
||||||
|
invocation_count: usize,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn runWrapper(data: RunData) void {
|
||||||
|
@call(.always_inline, run, .{data}) catch |err| {
|
||||||
|
std.log.scoped(.@"SPIR-V runtime").err("SPIR-V runtime catched a '{s}'", .{@errorName(err)});
|
||||||
|
if (@errorReturnTrace()) |trace| {
|
||||||
|
std.debug.dumpErrorReturnTrace(trace);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn run(data: RunData) !void {
|
||||||
|
const allocator = data.renderer.device.device_allocator.allocator();
|
||||||
|
|
||||||
|
const shader = data.pipeline.stages.getPtrAssertContains(.vertex);
|
||||||
|
const rt = &shader.runtimes[data.batch_id];
|
||||||
|
|
||||||
|
const entry = try rt.getEntryPointByName(shader.entry);
|
||||||
|
|
||||||
|
var invocation_index: usize = data.batch_id;
|
||||||
|
while (invocation_index < data.invocation_count) : (invocation_index += data.batch_size) {
|
||||||
|
rt.callEntryPoint(allocator, entry) catch |err| switch (err) {
|
||||||
|
// Some errors can be ignored
|
||||||
|
SpvRuntimeError.OutOfBounds,
|
||||||
|
SpvRuntimeError.Killed,
|
||||||
|
=> {},
|
||||||
|
else => return err,
|
||||||
|
};
|
||||||
|
|
||||||
|
var output: [4]f32 = undefined;
|
||||||
|
try rt.readBuiltIn(std.mem.asBytes(output[0..output.len]), .Position);
|
||||||
|
std.debug.print("Output: Vec4{any}\n", .{output});
|
||||||
|
}
|
||||||
|
}
|
||||||
+49
-1
@@ -16,6 +16,16 @@ owner: *Device,
|
|||||||
vtable: *const VTable,
|
vtable: *const VTable,
|
||||||
bind_point: vk.PipelineBindPoint,
|
bind_point: vk.PipelineBindPoint,
|
||||||
stages: vk.ShaderStageFlags,
|
stages: vk.ShaderStageFlags,
|
||||||
|
mode: union(enum) {
|
||||||
|
compute: struct {},
|
||||||
|
graphics: struct {
|
||||||
|
input_assembly: struct {
|
||||||
|
binding_description: ?[]vk.VertexInputBindingDescription,
|
||||||
|
attribute_description: ?[]vk.VertexInputAttributeDescription,
|
||||||
|
topology: vk.PrimitiveTopology,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
pub const VTable = struct {
|
pub const VTable = struct {
|
||||||
destroy: *const fn (*Self, std.mem.Allocator) void,
|
destroy: *const fn (*Self, std.mem.Allocator) void,
|
||||||
@@ -30,11 +40,11 @@ pub fn initCompute(device: *Device, allocator: std.mem.Allocator, cache: ?*Pipel
|
|||||||
.vtable = undefined,
|
.vtable = undefined,
|
||||||
.bind_point = .compute,
|
.bind_point = .compute,
|
||||||
.stages = info.stage.stage,
|
.stages = info.stage.stage,
|
||||||
|
.mode = .{ .compute = .{} },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn initGraphics(device: *Device, allocator: std.mem.Allocator, cache: ?*PipelineCache, info: *const vk.GraphicsPipelineCreateInfo) VkError!Self {
|
pub fn initGraphics(device: *Device, allocator: std.mem.Allocator, cache: ?*PipelineCache, info: *const vk.GraphicsPipelineCreateInfo) VkError!Self {
|
||||||
_ = allocator;
|
|
||||||
_ = cache;
|
_ = cache;
|
||||||
|
|
||||||
var stages: vk.ShaderStageFlags = .{};
|
var stages: vk.ShaderStageFlags = .{};
|
||||||
@@ -49,9 +59,47 @@ pub fn initGraphics(device: *Device, allocator: std.mem.Allocator, cache: ?*Pipe
|
|||||||
.vtable = undefined,
|
.vtable = undefined,
|
||||||
.bind_point = .graphics,
|
.bind_point = .graphics,
|
||||||
.stages = stages,
|
.stages = stages,
|
||||||
|
.mode = .{
|
||||||
|
.graphics = .{
|
||||||
|
.input_assembly = .{
|
||||||
|
.binding_description = blk: {
|
||||||
|
if (info.p_vertex_input_state) |vertex_input_state| {
|
||||||
|
if (vertex_input_state.p_vertex_binding_descriptions) |vertex_binding_descriptions| {
|
||||||
|
break :blk allocator.dupe(vk.VertexInputBindingDescription, vertex_binding_descriptions[0..vertex_input_state.vertex_binding_description_count]) catch return VkError.OutOfHostMemory;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return VkError.ValidationFailed;
|
||||||
|
}
|
||||||
|
break :blk null;
|
||||||
|
},
|
||||||
|
.attribute_description = blk: {
|
||||||
|
if (info.p_vertex_input_state) |vertex_input_state| {
|
||||||
|
if (vertex_input_state.p_vertex_attribute_descriptions) |vertex_attribute_descriptions| {
|
||||||
|
break :blk allocator.dupe(vk.VertexInputAttributeDescription, vertex_attribute_descriptions[0..vertex_input_state.vertex_attribute_description_count]) catch return VkError.OutOfHostMemory;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return VkError.ValidationFailed;
|
||||||
|
}
|
||||||
|
break :blk null;
|
||||||
|
},
|
||||||
|
.topology = if (info.p_input_assembly_state) |state| state.topology else return VkError.ValidationFailed,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void {
|
pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void {
|
||||||
|
switch (self.mode) {
|
||||||
|
.compute => {},
|
||||||
|
.graphics => |graphics| {
|
||||||
|
if (graphics.input_assembly.binding_description) |binding_description| {
|
||||||
|
allocator.free(binding_description);
|
||||||
|
}
|
||||||
|
if (graphics.input_assembly.attribute_description) |attribute_description| {
|
||||||
|
allocator.free(attribute_description);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
self.vtable.destroy(self, allocator);
|
self.vtable.destroy(self, allocator);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user