adding descriptor sets injections to graphics stages
This commit is contained in:
+2
-2
@@ -31,8 +31,8 @@
|
|||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
.SPIRV_Interpreter = .{
|
.SPIRV_Interpreter = .{
|
||||||
.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#dc80a6a3484667058194dc0540c2a15ba76ce2d9",
|
.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#236c6496ff567083ecd8084c792f02886b9c501a",
|
||||||
.hash = "SPIRV_Interpreter-0.0.1-ajmpnwNEBQA6scXu7V71PS-UV6wZtRut9vDh3PxrtW53",
|
.hash = "SPIRV_Interpreter-0.0.1-ajmpn8pFBQCz_zQmSQ3OY_qRDfAanQDtvoNKTxxEEvpH",
|
||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
//.SPIRV_Interpreter = .{
|
//.SPIRV_Interpreter = .{
|
||||||
|
|||||||
@@ -98,18 +98,28 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, layout: *base.
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy(interface: *Interface, copy_data: vk.CopyDescriptorSet) VkError!void {
|
|
||||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
|
||||||
_ = self;
|
|
||||||
_ = copy_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
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.heap);
|
allocator.free(self.heap);
|
||||||
allocator.destroy(self);
|
allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
for (self.descriptors[data.dst_binding..(data.dst_binding + data.descriptor_count)], src.descriptors[data.src_binding..(data.src_binding + data.descriptor_count)]) |*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..]),
|
||||||
|
else => {
|
||||||
|
dst_desc.* = .{ .unsupported = .{} };
|
||||||
|
base.unsupported("descriptor type for copy", .{});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn write(interface: *Interface, write_data: vk.WriteDescriptorSet) VkError!void {
|
pub fn write(interface: *Interface, write_data: vk.WriteDescriptorSet) VkError!void {
|
||||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
|
|
||||||
|
|||||||
@@ -174,8 +174,7 @@ fn writeDescriptorSets(self: *Self, rt: *spv.Runtime) !void {
|
|||||||
switch (binding) {
|
switch (binding) {
|
||||||
.buffer => |buffer_data_array| for (buffer_data_array, 0..) |buffer_data, descriptor_index| {
|
.buffer => |buffer_data_array| for (buffer_data_array, 0..) |buffer_data, descriptor_index| {
|
||||||
if (buffer_data.object) |buffer| {
|
if (buffer_data.object) |buffer| {
|
||||||
const memory = if (buffer.interface.memory) |memory| memory else continue :bindings;
|
const map = buffer.mapAsSliceWithOffset(u8, buffer_data.offset, buffer_data.size) catch continue :bindings;
|
||||||
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)),
|
||||||
|
|||||||
@@ -179,6 +179,16 @@ fn drawCall(self: *Self, bounded_allocator: *BoundedAllocator, vertex_count: usi
|
|||||||
logger.debug(fmt, args);
|
logger.debug(fmt, args);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const pipeline = self.state.pipeline orelse return VkError.InvalidPipelineDrv;
|
||||||
|
const vertex_shader = pipeline.stages.getPtrAssertContains(.vertex);
|
||||||
|
for (vertex_shader.runtimes[0..]) |*runtime| {
|
||||||
|
writeDescriptorSets(&draw_call, &runtime.rt) catch return VkError.Unknown;
|
||||||
|
}
|
||||||
|
const fragment_shader = pipeline.stages.getPtrAssertContains(.fragment);
|
||||||
|
for (fragment_shader.runtimes[0..]) |*runtime| {
|
||||||
|
writeDescriptorSets(&draw_call, &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| {
|
||||||
std.log.scoped(.@"Vertex stage").err("catched a '{s}'", .{@errorName(err)});
|
std.log.scoped(.@"Vertex stage").err("catched a '{s}'", .{@errorName(err)});
|
||||||
if (@errorReturnTrace()) |trace| {
|
if (@errorReturnTrace()) |trace| {
|
||||||
@@ -297,3 +307,38 @@ 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 => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -48,5 +48,8 @@ pub fn shaderInvocation(allocator: std.mem.Allocator, draw_call: *Renderer.DrawC
|
|||||||
|
|
||||||
var color = zm.f32x4s(0.0);
|
var color = zm.f32x4s(0.0);
|
||||||
try rt.readOutput(std.mem.asBytes(&color), output_result);
|
try rt.readOutput(std.mem.asBytes(&color), output_result);
|
||||||
|
|
||||||
|
try rt.flushDescriptorSets(allocator);
|
||||||
|
|
||||||
return std.math.clamp(color, zm.f32x4s(0.0), zm.f32x4s(1.0));
|
return std.math.clamp(color, zm.f32x4s(0.0), zm.f32x4s(1.0));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,8 @@ inline fn run(data: RunData) !void {
|
|||||||
};
|
};
|
||||||
try rt.readOutput(output.outputs[location].?.blob, result_word);
|
try rt.readOutput(output.outputs[location].?.blob, result_word);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try rt.flushDescriptorSets(data.allocator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ layout: *DescriptorSetLayout,
|
|||||||
vtable: *const VTable,
|
vtable: *const VTable,
|
||||||
|
|
||||||
pub const VTable = struct {
|
pub const VTable = struct {
|
||||||
copy: *const fn (*Self, vk.CopyDescriptorSet) VkError!void,
|
copy: *const fn (*Self, *const Self, vk.CopyDescriptorSet) VkError!void,
|
||||||
destroy: *const fn (*Self, std.mem.Allocator) void,
|
destroy: *const fn (*Self, std.mem.Allocator) void,
|
||||||
write: *const fn (*Self, vk.WriteDescriptorSet) VkError!void,
|
write: *const fn (*Self, vk.WriteDescriptorSet) VkError!void,
|
||||||
};
|
};
|
||||||
@@ -33,8 +33,8 @@ pub fn init(device: *Device, allocator: std.mem.Allocator, layout: *DescriptorSe
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn copy(self: *Self, copy_data: vk.CopyDescriptorSet) VkError!void {
|
pub inline fn copy(self: *Self, src: *const Self, copy_data: vk.CopyDescriptorSet) VkError!void {
|
||||||
try self.vtable.copy(self, copy_data);
|
try self.vtable.copy(self, src, copy_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void {
|
pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void {
|
||||||
|
|||||||
@@ -34,19 +34,6 @@ dynamic_descriptor_count: usize,
|
|||||||
/// Shader stages affected by this descriptor set
|
/// Shader stages affected by this descriptor set
|
||||||
stages: vk.ShaderStageFlags,
|
stages: vk.ShaderStageFlags,
|
||||||
|
|
||||||
/// Mesa's common Vulkan runtime states:
|
|
||||||
///
|
|
||||||
/// It's often necessary to store a pointer to the descriptor set layout in
|
|
||||||
/// the descriptor so that any entrypoint which has access to a descriptor
|
|
||||||
/// set also has the layout. While layouts are often passed into various
|
|
||||||
/// entrypoints, they're notably missing from vkUpdateDescriptorSets(). In
|
|
||||||
/// order to implement descriptor writes, you either need to stash a pointer
|
|
||||||
/// to the descriptor set layout in the descriptor set or you need to copy
|
|
||||||
/// all of the relevant information. Storing a pointer is a lot cheaper.
|
|
||||||
///
|
|
||||||
/// Because descriptor set layout lifetimes and descriptor set lifetimes are
|
|
||||||
/// not guaranteed to coincide, we have to reference count if we're going to
|
|
||||||
/// do this.
|
|
||||||
ref_count: std.atomic.Value(usize),
|
ref_count: std.atomic.Value(usize),
|
||||||
|
|
||||||
vtable: *const VTable,
|
vtable: *const VTable,
|
||||||
|
|||||||
@@ -1598,8 +1598,9 @@ pub export fn strollUpdateDescriptorSets(p_device: vk.Device, write_count: u32,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (copies, 0..copy_count) |copy, _| {
|
for (copies, 0..copy_count) |copy, _| {
|
||||||
const set = NonDispatchable(DescriptorSet).fromHandleObject(copy.dst_set) catch |err| return errorLogger(err);
|
const dst = NonDispatchable(DescriptorSet).fromHandleObject(copy.dst_set) catch |err| return errorLogger(err);
|
||||||
set.copy(copy) catch |err| return errorLogger(err);
|
const src = NonDispatchable(DescriptorSet).fromHandleObject(copy.src_set) catch |err| return errorLogger(err);
|
||||||
|
dst.copy(src, copy) catch |err| return errorLogger(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user