fixing synchronization issues, implementing missing entrypoints
This commit is contained in:
@@ -89,11 +89,11 @@ vkCmdResetEvent | ✅ Implemented
|
|||||||
vkCmdResetQueryPool | ✅ Implemented
|
vkCmdResetQueryPool | ✅ Implemented
|
||||||
vkCmdResolveImage | ✅ Implemented
|
vkCmdResolveImage | ✅ Implemented
|
||||||
vkCmdSetBlendConstants | ✅ Implemented
|
vkCmdSetBlendConstants | ✅ Implemented
|
||||||
vkCmdSetDepthBias | ⚙️ WIP
|
vkCmdSetDepthBias | ✅ Implemented
|
||||||
vkCmdSetDepthBounds | ⚙️ WIP
|
vkCmdSetDepthBounds | ✅ Implemented
|
||||||
vkCmdSetDeviceMaskKHR | ✅ Implemented
|
vkCmdSetDeviceMaskKHR | ✅ Implemented
|
||||||
vkCmdSetEvent | ✅ Implemented
|
vkCmdSetEvent | ✅ Implemented
|
||||||
vkCmdSetLineWidth | ⚙️ WIP
|
vkCmdSetLineWidth | ✅ Implemented
|
||||||
vkCmdSetScissor | ✅ Implemented
|
vkCmdSetScissor | ✅ Implemented
|
||||||
vkCmdSetStencilCompareMask | ✅ Implemented
|
vkCmdSetStencilCompareMask | ✅ Implemented
|
||||||
vkCmdSetStencilReference | ✅ Implemented
|
vkCmdSetStencilReference | ✅ Implemented
|
||||||
@@ -101,7 +101,7 @@ vkCmdSetStencilWriteMask | ✅ Implemented
|
|||||||
vkCmdSetViewport | ✅ Implemented
|
vkCmdSetViewport | ✅ Implemented
|
||||||
vkCmdUpdateBuffer | ✅ Implemented
|
vkCmdUpdateBuffer | ✅ Implemented
|
||||||
vkCmdWaitEvents | ✅ Implemented
|
vkCmdWaitEvents | ✅ Implemented
|
||||||
vkCmdWriteTimestamp | ⚙️ WIP
|
vkCmdWriteTimestamp | ✅ Implemented
|
||||||
vkCreateBuffer | ✅ Implemented
|
vkCreateBuffer | ✅ Implemented
|
||||||
vkCreateBufferView | ✅ Implemented
|
vkCreateBufferView | ✅ Implemented
|
||||||
vkCreateCommandPool | ✅ Implemented
|
vkCreateCommandPool | ✅ Implemented
|
||||||
@@ -169,7 +169,7 @@ vkGetBufferMemoryRequirements | ✅ Implemented
|
|||||||
vkGetDeviceGroupPeerMemoryFeaturesKHR | ✅ Implemented
|
vkGetDeviceGroupPeerMemoryFeaturesKHR | ✅ Implemented
|
||||||
vkGetDeviceGroupPresentCapabilitiesKHR | ✅ Implemented
|
vkGetDeviceGroupPresentCapabilitiesKHR | ✅ Implemented
|
||||||
vkGetDeviceGroupSurfacePresentModesKHR | ✅ Implemented
|
vkGetDeviceGroupSurfacePresentModesKHR | ✅ Implemented
|
||||||
vkGetDeviceMemoryCommitment | ⚙️ WIP
|
vkGetDeviceMemoryCommitment | ✅ Implemented
|
||||||
vkGetDeviceProcAddr | ✅ Implemented
|
vkGetDeviceProcAddr | ✅ Implemented
|
||||||
vkGetDeviceQueue | ✅ Implemented
|
vkGetDeviceQueue | ✅ Implemented
|
||||||
vkGetEventStatus | ✅ Implemented
|
vkGetEventStatus | ✅ Implemented
|
||||||
|
|||||||
@@ -53,7 +53,10 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v
|
|||||||
.resolveImage = resolveImage,
|
.resolveImage = resolveImage,
|
||||||
.setEvent = setEvent,
|
.setEvent = setEvent,
|
||||||
.setBlendConstants = setBlendConstants,
|
.setBlendConstants = setBlendConstants,
|
||||||
|
.setDepthBias = setDepthBias,
|
||||||
|
.setDepthBounds = setDepthBounds,
|
||||||
.setDeviceMask = setDeviceMask,
|
.setDeviceMask = setDeviceMask,
|
||||||
|
.setLineWidth = setLineWidth,
|
||||||
.setScissor = setScissor,
|
.setScissor = setScissor,
|
||||||
.setStencilCompareMask = setStencilCompareMask,
|
.setStencilCompareMask = setStencilCompareMask,
|
||||||
.setStencilReference = setStencilReference,
|
.setStencilReference = setStencilReference,
|
||||||
@@ -61,6 +64,7 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v
|
|||||||
.setViewport = setViewport,
|
.setViewport = setViewport,
|
||||||
.updateBuffer = updateBuffer,
|
.updateBuffer = updateBuffer,
|
||||||
.waitEvent = waitEvent,
|
.waitEvent = waitEvent,
|
||||||
|
.writeTimestamp = writeTimestamp,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.* = .{ .interface = interface };
|
self.* = .{ .interface = interface };
|
||||||
@@ -363,6 +367,24 @@ pub fn setBlendConstants(interface: *Interface, constants: [4]f32) VkError!void
|
|||||||
_ = constants;
|
_ = constants;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setDepthBias(interface: *Interface, constant_factor: f32, clamp: f32, slope_factor: f32) VkError!void {
|
||||||
|
_ = interface;
|
||||||
|
_ = constant_factor;
|
||||||
|
_ = clamp;
|
||||||
|
_ = slope_factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn setDepthBounds(interface: *Interface, min: f32, max: f32) VkError!void {
|
||||||
|
_ = interface;
|
||||||
|
_ = min;
|
||||||
|
_ = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn setLineWidth(interface: *Interface, width: f32) VkError!void {
|
||||||
|
_ = interface;
|
||||||
|
_ = width;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn setStencilCompareMask(interface: *Interface, face_mask: vk.StencilFaceFlags, compare_mask: u32) VkError!void {
|
pub fn setStencilCompareMask(interface: *Interface, face_mask: vk.StencilFaceFlags, compare_mask: u32) VkError!void {
|
||||||
_ = interface;
|
_ = interface;
|
||||||
_ = face_mask;
|
_ = face_mask;
|
||||||
@@ -390,3 +412,9 @@ pub fn waitEvent(interface: *Interface, event: *base.Event, src_stage: vk.Pipeli
|
|||||||
_ = buffer_barriers;
|
_ = buffer_barriers;
|
||||||
_ = image_barriers;
|
_ = image_barriers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn writeTimestamp(interface: *Interface, stage: vk.PipelineStageFlags, pool: *base.QueryPool, query: u32) VkError!void {
|
||||||
|
_ = interface;
|
||||||
|
_ = stage;
|
||||||
|
try pool.writeTimestamp(query, 0);
|
||||||
|
}
|
||||||
|
|||||||
@@ -113,7 +113,10 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v
|
|||||||
.resolveImage = resolveImage,
|
.resolveImage = resolveImage,
|
||||||
.setEvent = setEvent,
|
.setEvent = setEvent,
|
||||||
.setBlendConstants = setBlendConstants,
|
.setBlendConstants = setBlendConstants,
|
||||||
|
.setDepthBias = setDepthBias,
|
||||||
|
.setDepthBounds = setDepthBounds,
|
||||||
.setDeviceMask = setDeviceMask,
|
.setDeviceMask = setDeviceMask,
|
||||||
|
.setLineWidth = setLineWidth,
|
||||||
.setScissor = setScissor,
|
.setScissor = setScissor,
|
||||||
.setStencilCompareMask = setStencilCompareMask,
|
.setStencilCompareMask = setStencilCompareMask,
|
||||||
.setStencilReference = setStencilReference,
|
.setStencilReference = setStencilReference,
|
||||||
@@ -121,6 +124,7 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v
|
|||||||
.setViewport = setViewport,
|
.setViewport = setViewport,
|
||||||
.updateBuffer = updateBuffer,
|
.updateBuffer = updateBuffer,
|
||||||
.waitEvent = waitEvent,
|
.waitEvent = waitEvent,
|
||||||
|
.writeTimestamp = writeTimestamp,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
@@ -283,6 +287,36 @@ pub fn resetQueryPool(interface: *Interface, pool: *base.QueryPool, first: u32,
|
|||||||
self.commands.append(allocator, .{ .ptr = cmd, .vtable = &.{ .execute = CommandImpl.execute } }) catch return VkError.OutOfHostMemory;
|
self.commands.append(allocator, .{ .ptr = cmd, .vtable = &.{ .execute = CommandImpl.execute } }) catch return VkError.OutOfHostMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn writeTimestamp(interface: *Interface, stage: vk.PipelineStageFlags, pool: *base.QueryPool, query: u32) VkError!void {
|
||||||
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
|
const allocator = self.command_allocator.allocator();
|
||||||
|
|
||||||
|
const CommandImpl = struct {
|
||||||
|
const Impl = @This();
|
||||||
|
|
||||||
|
stage: vk.PipelineStageFlags,
|
||||||
|
pool: *base.QueryPool,
|
||||||
|
query: u32,
|
||||||
|
|
||||||
|
pub fn execute(context: *anyopaque, device: *ExecutionDevice) VkError!void {
|
||||||
|
const impl: *Impl = @ptrCast(@alignCast(context));
|
||||||
|
_ = impl.stage;
|
||||||
|
const io = device.renderer.device.interface.io();
|
||||||
|
const now = std.Io.Timestamp.now(io, .real).toNanoseconds();
|
||||||
|
try impl.pool.writeTimestamp(impl.query, if (now > 0) @intCast(now) else 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const cmd = allocator.create(CommandImpl) catch return VkError.OutOfHostMemory;
|
||||||
|
errdefer allocator.destroy(cmd);
|
||||||
|
cmd.* = .{
|
||||||
|
.stage = stage,
|
||||||
|
.pool = pool,
|
||||||
|
.query = query,
|
||||||
|
};
|
||||||
|
self.commands.append(allocator, .{ .ptr = cmd, .vtable = &.{ .execute = CommandImpl.execute } }) catch return VkError.OutOfHostMemory;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn beginRenderPass(interface: *Interface, render_pass: *base.RenderPass, framebuffer: *base.Framebuffer, render_area: vk.Rect2D, clear_values: ?[]const vk.ClearValue) VkError!void {
|
pub fn beginRenderPass(interface: *Interface, render_pass: *base.RenderPass, framebuffer: *base.Framebuffer, render_area: vk.Rect2D, clear_values: ?[]const vk.ClearValue) VkError!void {
|
||||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
const allocator = self.command_allocator.allocator();
|
const allocator = self.command_allocator.allocator();
|
||||||
@@ -1330,6 +1364,75 @@ pub fn setBlendConstants(interface: *Interface, constants: [4]f32) VkError!void
|
|||||||
self.commands.append(allocator, .{ .ptr = cmd, .vtable = &.{ .execute = CommandImpl.execute } }) catch return VkError.OutOfHostMemory;
|
self.commands.append(allocator, .{ .ptr = cmd, .vtable = &.{ .execute = CommandImpl.execute } }) catch return VkError.OutOfHostMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setDepthBias(interface: *Interface, constant_factor: f32, clamp: f32, slope_factor: f32) VkError!void {
|
||||||
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
|
const allocator = self.command_allocator.allocator();
|
||||||
|
|
||||||
|
const CommandImpl = struct {
|
||||||
|
const Impl = @This();
|
||||||
|
|
||||||
|
depth_bias: @import("device/Renderer.zig").DepthBias,
|
||||||
|
|
||||||
|
pub fn execute(context: *anyopaque, device: *ExecutionDevice) VkError!void {
|
||||||
|
const impl: *Impl = @ptrCast(@alignCast(context));
|
||||||
|
device.renderer.dynamic_state.depth_bias = impl.depth_bias;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const cmd = allocator.create(CommandImpl) catch return VkError.OutOfHostMemory;
|
||||||
|
errdefer allocator.destroy(cmd);
|
||||||
|
cmd.* = .{
|
||||||
|
.depth_bias = .{
|
||||||
|
.constant_factor = constant_factor,
|
||||||
|
.clamp = clamp,
|
||||||
|
.slope_factor = slope_factor,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
self.commands.append(allocator, .{ .ptr = cmd, .vtable = &.{ .execute = CommandImpl.execute } }) catch return VkError.OutOfHostMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn setDepthBounds(interface: *Interface, min: f32, max: f32) VkError!void {
|
||||||
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
|
const allocator = self.command_allocator.allocator();
|
||||||
|
|
||||||
|
const CommandImpl = struct {
|
||||||
|
const Impl = @This();
|
||||||
|
|
||||||
|
depth_bounds: @import("device/Renderer.zig").DepthBounds,
|
||||||
|
|
||||||
|
pub fn execute(context: *anyopaque, device: *ExecutionDevice) VkError!void {
|
||||||
|
const impl: *Impl = @ptrCast(@alignCast(context));
|
||||||
|
device.renderer.dynamic_state.depth_bounds = impl.depth_bounds;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const cmd = allocator.create(CommandImpl) catch return VkError.OutOfHostMemory;
|
||||||
|
errdefer allocator.destroy(cmd);
|
||||||
|
cmd.* = .{ .depth_bounds = .{ .min = min, .max = max } };
|
||||||
|
self.commands.append(allocator, .{ .ptr = cmd, .vtable = &.{ .execute = CommandImpl.execute } }) catch return VkError.OutOfHostMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn setLineWidth(interface: *Interface, width: f32) VkError!void {
|
||||||
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
|
const allocator = self.command_allocator.allocator();
|
||||||
|
|
||||||
|
const CommandImpl = struct {
|
||||||
|
const Impl = @This();
|
||||||
|
|
||||||
|
width: f32,
|
||||||
|
|
||||||
|
pub fn execute(context: *anyopaque, device: *ExecutionDevice) VkError!void {
|
||||||
|
const impl: *Impl = @ptrCast(@alignCast(context));
|
||||||
|
device.renderer.dynamic_state.line_width = impl.width;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const cmd = allocator.create(CommandImpl) catch return VkError.OutOfHostMemory;
|
||||||
|
errdefer allocator.destroy(cmd);
|
||||||
|
cmd.* = .{ .width = width };
|
||||||
|
self.commands.append(allocator, .{ .ptr = cmd, .vtable = &.{ .execute = CommandImpl.execute } }) catch return VkError.OutOfHostMemory;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn setStencilCompareMask(interface: *Interface, face_mask: vk.StencilFaceFlags, compare_mask: u32) VkError!void {
|
pub fn setStencilCompareMask(interface: *Interface, face_mask: vk.StencilFaceFlags, compare_mask: u32) VkError!void {
|
||||||
try setStencilDynamicState(interface, face_mask, compare_mask, .compare_mask);
|
try setStencilDynamicState(interface, face_mask, compare_mask, .compare_mask);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,11 @@ pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void {
|
|||||||
|
|
||||||
pub fn getStatus(interface: *Interface) VkError!void {
|
pub fn getStatus(interface: *Interface) VkError!void {
|
||||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
|
const io = interface.owner.io();
|
||||||
|
|
||||||
|
self.mutex.lock(io) catch return VkError.DeviceLost;
|
||||||
|
defer self.mutex.unlock(io);
|
||||||
|
|
||||||
if (!self.is_signaled) {
|
if (!self.is_signaled) {
|
||||||
return VkError.NotReady;
|
return VkError.NotReady;
|
||||||
}
|
}
|
||||||
@@ -50,6 +55,11 @@ pub fn getStatus(interface: *Interface) VkError!void {
|
|||||||
|
|
||||||
pub fn reset(interface: *Interface) VkError!void {
|
pub fn reset(interface: *Interface) VkError!void {
|
||||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
|
const io = interface.owner.io();
|
||||||
|
|
||||||
|
self.mutex.lock(io) catch return VkError.DeviceLost;
|
||||||
|
defer self.mutex.unlock(io);
|
||||||
|
|
||||||
self.is_signaled = false;
|
self.is_signaled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,18 +78,34 @@ pub fn wait(interface: *Interface, timeout: u64) VkError!void {
|
|||||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
const io = interface.owner.io();
|
const io = interface.owner.io();
|
||||||
|
|
||||||
|
if (timeout == std.math.maxInt(@TypeOf(timeout))) {
|
||||||
|
self.mutex.lock(io) catch return VkError.DeviceLost;
|
||||||
|
defer self.mutex.unlock(io);
|
||||||
|
|
||||||
|
while (!self.is_signaled) {
|
||||||
|
self.condition.wait(io, &self.mutex) catch return VkError.DeviceLost;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const deadline = std.Io.Clock.Timestamp.fromNow(io, .{
|
||||||
|
.raw = .fromNanoseconds(@intCast(timeout)),
|
||||||
|
.clock = .awake,
|
||||||
|
});
|
||||||
|
while (true) {
|
||||||
|
{
|
||||||
self.mutex.lock(io) catch return VkError.DeviceLost;
|
self.mutex.lock(io) catch return VkError.DeviceLost;
|
||||||
defer self.mutex.unlock(io);
|
defer self.mutex.unlock(io);
|
||||||
|
|
||||||
if (self.is_signaled) return;
|
if (self.is_signaled) return;
|
||||||
if (timeout == 0) return VkError.Timeout;
|
}
|
||||||
|
|
||||||
if (timeout != std.math.maxInt(@TypeOf(timeout))) {
|
const remaining = deadline.durationFromNow(io);
|
||||||
const duration: std.Io.Clock.Duration = .{
|
if (remaining.raw.nanoseconds <= 0) return VkError.Timeout;
|
||||||
.raw = .fromNanoseconds(@intCast(timeout)),
|
|
||||||
.clock = .cpu_process,
|
(std.Io.Clock.Duration{
|
||||||
};
|
.raw = .fromNanoseconds(@min(remaining.raw.nanoseconds, std.time.ns_per_ms)),
|
||||||
duration.sleep(io) catch return VkError.DeviceLost;
|
.clock = .awake,
|
||||||
|
}).sleep(io) catch return VkError.DeviceLost;
|
||||||
}
|
}
|
||||||
self.condition.wait(io, &self.mutex) catch return VkError.DeviceLost;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,7 +184,6 @@ inline fn run(data: RunData) !void {
|
|||||||
const workgroup_memory = try rt.createWorkgroupMemory(allocator);
|
const workgroup_memory = try rt.createWorkgroupMemory(allocator);
|
||||||
defer rt.destroyWorkgroupMemory(allocator, workgroup_memory);
|
defer rt.destroyWorkgroupMemory(allocator, workgroup_memory);
|
||||||
|
|
||||||
for (0..data.invocations_per_workgroup) |i| {
|
|
||||||
rt.resetInvocation(allocator);
|
rt.resetInvocation(allocator);
|
||||||
if (rt.specialization_constants.count() != 0)
|
if (rt.specialization_constants.count() != 0)
|
||||||
try rt.applySpecializationInvocationLayout(allocator);
|
try rt.applySpecializationInvocationLayout(allocator);
|
||||||
@@ -193,6 +192,9 @@ inline fn run(data: RunData) !void {
|
|||||||
try rt.bindWorkgroupMemory(workgroup_memory);
|
try rt.bindWorkgroupMemory(workgroup_memory);
|
||||||
try setupWorkgroupBuiltins(data.self, rt, data.local_size, group_count_vec, group_id_vec);
|
try setupWorkgroupBuiltins(data.self, rt, data.local_size, group_count_vec, group_id_vec);
|
||||||
|
|
||||||
|
for (0..data.invocations_per_workgroup) |i| {
|
||||||
|
rt.resetInvocation(allocator);
|
||||||
|
|
||||||
const invocation_index = data.self.invocation_index.fetchAdd(1, .monotonic);
|
const invocation_index = data.self.invocation_index.fetchAdd(1, .monotonic);
|
||||||
|
|
||||||
try setupSubgroupBuiltins(data.self, rt, data.local_size, .{
|
try setupSubgroupBuiltins(data.self, rt, data.local_size, .{
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ pub const DynamicState = struct {
|
|||||||
viewports: ?[]const vk.Viewport,
|
viewports: ?[]const vk.Viewport,
|
||||||
scissor: ?[]const vk.Rect2D,
|
scissor: ?[]const vk.Rect2D,
|
||||||
line_width: ?f32,
|
line_width: ?f32,
|
||||||
|
depth_bias: ?DepthBias,
|
||||||
|
depth_bounds: ?DepthBounds,
|
||||||
blend_constants: ?[4]f32,
|
blend_constants: ?[4]f32,
|
||||||
stencil_front_compare_mask: ?u32,
|
stencil_front_compare_mask: ?u32,
|
||||||
stencil_back_compare_mask: ?u32,
|
stencil_back_compare_mask: ?u32,
|
||||||
@@ -54,6 +56,17 @@ pub const DynamicState = struct {
|
|||||||
stencil_back_reference: ?u32,
|
stencil_back_reference: ?u32,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const DepthBias = struct {
|
||||||
|
constant_factor: f32,
|
||||||
|
clamp: f32,
|
||||||
|
slope_factor: f32,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const DepthBounds = struct {
|
||||||
|
min: f32,
|
||||||
|
max: f32,
|
||||||
|
};
|
||||||
|
|
||||||
pub const Vertex = struct {
|
pub const Vertex = struct {
|
||||||
primitive_restart: bool,
|
primitive_restart: bool,
|
||||||
position: F32x4,
|
position: F32x4,
|
||||||
@@ -158,6 +171,8 @@ pub fn init(device: *SoftDevice, state: *PipelineState, active_occlusion_queries
|
|||||||
.viewports = null,
|
.viewports = null,
|
||||||
.scissor = null,
|
.scissor = null,
|
||||||
.line_width = null,
|
.line_width = null,
|
||||||
|
.depth_bias = null,
|
||||||
|
.depth_bounds = null,
|
||||||
.blend_constants = null,
|
.blend_constants = null,
|
||||||
.stencil_front_compare_mask = null,
|
.stencil_front_compare_mask = null,
|
||||||
.stencil_back_compare_mask = null,
|
.stencil_back_compare_mask = null,
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ pub fn processThenFragmentStage(renderer: *Renderer, allocator: std.mem.Allocato
|
|||||||
v0,
|
v0,
|
||||||
v1,
|
v1,
|
||||||
v2,
|
v2,
|
||||||
v0,
|
v1,
|
||||||
color_attachment_access,
|
color_attachment_access,
|
||||||
if (depth_attachment_access) |*access| access else null,
|
if (depth_attachment_access) |*access| access else null,
|
||||||
if (stencil_attachment_access) |*access| access else null,
|
if (stencil_attachment_access) |*access| access else null,
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ const RunData = struct {
|
|||||||
steep: bool,
|
steep: bool,
|
||||||
start_vertex: *Renderer.Vertex,
|
start_vertex: *Renderer.Vertex,
|
||||||
end_vertex: *Renderer.Vertex,
|
end_vertex: *Renderer.Vertex,
|
||||||
|
provoking_vertex: *Renderer.Vertex,
|
||||||
start_step: usize,
|
start_step: usize,
|
||||||
end_step: usize,
|
end_step: usize,
|
||||||
color_attachment_access: []const ?common.RenderTargetAccess,
|
color_attachment_access: []const ?common.RenderTargetAccess,
|
||||||
@@ -68,78 +69,183 @@ fn drawLineWithEndpointMode(
|
|||||||
stencil_attachment_access: ?*common.RenderTargetAccess,
|
stencil_attachment_access: ?*common.RenderTargetAccess,
|
||||||
include_last_endpoint: bool,
|
include_last_endpoint: bool,
|
||||||
) VkError!void {
|
) VkError!void {
|
||||||
const io = draw_call.renderer.device.interface.io();
|
try drawLineDiamond(
|
||||||
|
allocator,
|
||||||
var x0: i32 = @intFromFloat(v0.position[0]);
|
draw_call,
|
||||||
var y0: i32 = @intFromFloat(@floor(v0.position[1] - 0.5));
|
v0,
|
||||||
var x1: i32 = @intFromFloat(v1.position[0]);
|
v1,
|
||||||
var y1: i32 = @intFromFloat(@floor(v1.position[1] - 0.5));
|
color_attachment_access,
|
||||||
|
depth_attachment_access,
|
||||||
const steep = blk: {
|
stencil_attachment_access,
|
||||||
if (@abs(y1 - y0) > @abs(x1 - x0)) {
|
include_last_endpoint,
|
||||||
std.mem.swap(i32, &x0, &y0);
|
);
|
||||||
std.mem.swap(i32, &x1, &y1);
|
|
||||||
break :blk true;
|
|
||||||
}
|
|
||||||
break :blk false;
|
|
||||||
};
|
|
||||||
|
|
||||||
var start_vertex = v0;
|
|
||||||
var end_vertex = v1;
|
|
||||||
if (x0 > x1) {
|
|
||||||
std.mem.swap(i32, &x0, &x1);
|
|
||||||
std.mem.swap(i32, &y0, &y1);
|
|
||||||
std.mem.swap(*Renderer.Vertex, &start_vertex, &end_vertex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const d_err: i32 = @intCast(@abs(y1 - y0));
|
fn drawLineDiamond(
|
||||||
const d_x = x1 - x0;
|
allocator: std.mem.Allocator,
|
||||||
const y_step: i32 = if (y0 > y1) -1 else 1;
|
draw_call: *Renderer.DrawCall,
|
||||||
|
v0: *Renderer.Vertex,
|
||||||
|
v1: *Renderer.Vertex,
|
||||||
|
color_attachment_access: []const ?common.RenderTargetAccess,
|
||||||
|
depth_attachment_access: ?*common.RenderTargetAccess,
|
||||||
|
stencil_attachment_access: ?*common.RenderTargetAccess,
|
||||||
|
include_last_endpoint: bool,
|
||||||
|
) VkError!void {
|
||||||
const pipeline = draw_call.renderer.state.pipeline orelse return;
|
const pipeline = draw_call.renderer.state.pipeline orelse return;
|
||||||
const fragment_stage = pipeline.stages.getPtr(.fragment);
|
const fragment_stage = pipeline.stages.getPtr(.fragment);
|
||||||
const runtimes_count = if (fragment_stage) |stage| stage.runtimes.len else 1;
|
const has_fragment_shader = fragment_stage != null;
|
||||||
if (runtimes_count == 0)
|
const batch_id: usize = 0;
|
||||||
return;
|
|
||||||
|
|
||||||
const step_count: usize = @intCast(if (include_last_endpoint) @max(d_x, 0) + 1 else @max(d_x, 1));
|
const min_x: i32 = @intFromFloat(@floor(@min(v0.position[0], v1.position[0]) - 1.0));
|
||||||
const runs_count = @min(runtimes_count, step_count);
|
const max_x: i32 = @intFromFloat(@ceil(@max(v0.position[0], v1.position[0]) + 1.0));
|
||||||
const steps_per_run = @divTrunc(step_count + runs_count - 1, runs_count);
|
const min_y: i32 = @intFromFloat(@floor(@min(v0.position[1], v1.position[1]) - 1.0));
|
||||||
|
const max_y: i32 = @intFromFloat(@ceil(@max(v0.position[1], v1.position[1]) + 1.0));
|
||||||
|
|
||||||
var batch_id: usize = 0;
|
var y = min_y;
|
||||||
for (0..runs_count) |run_index| {
|
while (y <= max_y) : (y += 1) {
|
||||||
defer batch_id = @mod(batch_id + 1, runtimes_count);
|
var x = min_x;
|
||||||
|
while (x <= max_x) : (x += 1) {
|
||||||
const start_step = run_index * steps_per_run;
|
if (!common.scissorContainsPixel(draw_call.scissor, x, y))
|
||||||
if (start_step >= step_count)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const end_step = @min(start_step + steps_per_run - 1, step_count - 1);
|
const coverage = diamondCoverage(v0.position, v1.position, x, y, include_last_endpoint);
|
||||||
|
const t = coverage orelse continue;
|
||||||
|
const z = ((1.0 - t) * v0.position[2]) + (t * v1.position[2]);
|
||||||
|
const frag_w = ((1.0 - t) / v0.position[3]) + (t / v1.position[3]);
|
||||||
|
|
||||||
const run_data: RunData = .{
|
var fragment_result: fragment.InvocationResult = .{
|
||||||
.allocator = allocator,
|
.outputs = std.mem.zeroes([spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(F32x4)]u8),
|
||||||
.draw_call = draw_call,
|
.depth = null,
|
||||||
.batch_id = batch_id,
|
.sample_mask = null,
|
||||||
.x0 = x0,
|
|
||||||
.y0 = y0,
|
|
||||||
.d_x = d_x,
|
|
||||||
.d_err = d_err,
|
|
||||||
.y_step = y_step,
|
|
||||||
.steep = steep,
|
|
||||||
.start_vertex = start_vertex,
|
|
||||||
.end_vertex = end_vertex,
|
|
||||||
.start_step = start_step,
|
|
||||||
.end_step = end_step,
|
|
||||||
.color_attachment_access = color_attachment_access,
|
|
||||||
.depth_attachment_access = depth_attachment_access,
|
|
||||||
.stencil_attachment_access = stencil_attachment_access,
|
|
||||||
.has_fragment_shader = fragment_stage != null,
|
|
||||||
};
|
};
|
||||||
|
if (has_fragment_shader) {
|
||||||
|
fragment_result = fragment.shaderInvocation(
|
||||||
|
allocator,
|
||||||
|
draw_call,
|
||||||
|
batch_id,
|
||||||
|
zm.f32x4(@as(f32, @floatFromInt(x)) + 0.5, @as(f32, @floatFromInt(y)) + 0.5, z, frag_w),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
try common.interpolateLineOutputs(allocator, v0, v1, v0, t),
|
||||||
|
null,
|
||||||
|
) catch |err| {
|
||||||
|
if (err == SpvRuntimeError.Killed)
|
||||||
|
continue;
|
||||||
|
|
||||||
draw_call.rasterizer_wait_group.async(io, runWrapper, .{run_data});
|
std.log.scoped(.@"Fragment stage").err("catched a '{s}'", .{@errorName(err)});
|
||||||
|
if (comptime base.config.logs == .verbose) {
|
||||||
|
if (@errorReturnTrace()) |trace| {
|
||||||
|
std.debug.dumpErrorReturnTrace(trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_call.rasterizer_wait_group.await(io) catch return VkError.DeviceLost;
|
try common.writeToTargets(
|
||||||
|
fragment_result.outputs,
|
||||||
|
draw_call,
|
||||||
|
color_attachment_access,
|
||||||
|
depth_attachment_access,
|
||||||
|
stencil_attachment_access,
|
||||||
|
true,
|
||||||
|
@intCast(x),
|
||||||
|
@intCast(y),
|
||||||
|
fragment_result.depth orelse z,
|
||||||
|
lineCoverageMaskFloat(
|
||||||
|
v0.position,
|
||||||
|
v1.position,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
pipeline.interface.mode.graphics.multisample.rasterization_samples.toInt(),
|
||||||
|
),
|
||||||
|
fragment_result.sample_mask,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn diamondCoverage(a: F32x4, b: F32x4, pixel_x: i32, pixel_y: i32, include_last_endpoint: bool) ?f32 {
|
||||||
|
const cx = @as(f32, @floatFromInt(pixel_x)) + 0.5;
|
||||||
|
const cy = @as(f32, @floatFromInt(pixel_y)) + 0.5;
|
||||||
|
const clipped = clipSegmentToDiamond(a[0], a[1], b[0], b[1], cx, cy) orelse return null;
|
||||||
|
if (!include_last_endpoint and a[3] == 1.0 and b[3] == 1.0 and clipped.min_t <= 0.0)
|
||||||
|
return null;
|
||||||
|
if (!include_last_endpoint and clipped.min_t >= 1.0)
|
||||||
|
return null;
|
||||||
|
return std.math.clamp((clipped.min_t + clipped.max_t) * 0.5, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clipSegmentToDiamond(ax: f32, ay: f32, bx: f32, by: f32, cx: f32, cy: f32) ?struct { min_t: f32, max_t: f32 } {
|
||||||
|
var min_t: f32 = 0.0;
|
||||||
|
var max_t: f32 = 1.0;
|
||||||
|
const dx = bx - ax;
|
||||||
|
const dy = by - ay;
|
||||||
|
|
||||||
|
const normals = [_]struct { nx: f32, ny: f32 }{
|
||||||
|
.{ .nx = 1.0, .ny = 1.0 },
|
||||||
|
.{ .nx = 1.0, .ny = -1.0 },
|
||||||
|
.{ .nx = -1.0, .ny = 1.0 },
|
||||||
|
.{ .nx = -1.0, .ny = -1.0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
for (normals) |normal| {
|
||||||
|
const origin_distance = normal.nx * (ax - cx) + normal.ny * (ay - cy) - 0.5;
|
||||||
|
const delta_distance = normal.nx * dx + normal.ny * dy;
|
||||||
|
if (delta_distance == 0.0) {
|
||||||
|
if (origin_distance > 0.0)
|
||||||
|
return null;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const t = -origin_distance / delta_distance;
|
||||||
|
if (delta_distance > 0.0) {
|
||||||
|
max_t = @min(max_t, t);
|
||||||
|
} else {
|
||||||
|
min_t = @max(min_t, t);
|
||||||
|
}
|
||||||
|
if (min_t > max_t)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{ .min_t = min_t, .max_t = max_t };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lineCoverageMaskFloat(a: F32x4, b: F32x4, pixel_x: i32, pixel_y: i32, sample_count: usize) vk.SampleMask {
|
||||||
|
if (sample_count <= 1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
const ab_x = b[0] - a[0];
|
||||||
|
const ab_y = b[1] - a[1];
|
||||||
|
const ab_len2 = ab_x * ab_x + ab_y * ab_y;
|
||||||
|
if (ab_len2 == 0.0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
var mask: vk.SampleMask = 0;
|
||||||
|
for (0..sample_count) |sample_index| {
|
||||||
|
if (sample_index >= @bitSizeOf(vk.SampleMask))
|
||||||
|
break;
|
||||||
|
|
||||||
|
const sample_pos = standardSamplePosition(sample_count, sample_index);
|
||||||
|
const sample_x = @as(f32, @floatFromInt(pixel_x)) + sample_pos.x;
|
||||||
|
const sample_y = @as(f32, @floatFromInt(pixel_y)) + sample_pos.y;
|
||||||
|
const ap_x = sample_x - a[0];
|
||||||
|
const ap_y = sample_y - a[1];
|
||||||
|
const t = std.math.clamp(((ap_x * ab_x) + (ap_y * ab_y)) / ab_len2, 0.0, 1.0);
|
||||||
|
const closest_x = a[0] + ab_x * t;
|
||||||
|
const closest_y = a[1] + ab_y * t;
|
||||||
|
const dx = sample_x - closest_x;
|
||||||
|
const dy = sample_y - closest_y;
|
||||||
|
|
||||||
|
if (dx * dx + dy * dy <= 0.25) {
|
||||||
|
const bit_index: u5 = @intCast(sample_index);
|
||||||
|
mask |= @as(vk.SampleMask, 1) << bit_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (mask == 0) 1 else mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bresenhamYAtStep(y0: i32, d_x: i32, d_err: i32, y_step: i32, step: usize) i32 {
|
fn bresenhamYAtStep(y0: i32, d_x: i32, d_err: i32, y_step: i32, step: usize) i32 {
|
||||||
@@ -249,7 +355,7 @@ inline fn run(data: RunData) !void {
|
|||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
true,
|
true,
|
||||||
try common.interpolateLineOutputs(data.allocator, data.start_vertex, data.end_vertex, t),
|
try common.interpolateLineOutputs(data.allocator, data.start_vertex, data.end_vertex, data.provoking_vertex, t),
|
||||||
null,
|
null,
|
||||||
) catch |err| {
|
) catch |err| {
|
||||||
if (err == SpvRuntimeError.Killed)
|
if (err == SpvRuntimeError.Killed)
|
||||||
|
|||||||
@@ -31,6 +31,27 @@ pub const VertexInterpolation = struct {
|
|||||||
|
|
||||||
pub const VertexInterpolationLocation = [4]VertexInterpolation;
|
pub const VertexInterpolationLocation = [4]VertexInterpolation;
|
||||||
|
|
||||||
|
pub fn depthBiasConstantUnit(format: vk.Format, z: f32) f32 {
|
||||||
|
return switch (format) {
|
||||||
|
.d16_unorm => 1.0 / @as(f32, @floatFromInt(std.math.maxInt(u16))),
|
||||||
|
.x8_d24_unorm_pack32,
|
||||||
|
.d24_unorm_s8_uint,
|
||||||
|
=> 1.0 / @as(f32, @floatFromInt(0x00ff_ffff)),
|
||||||
|
.d32_sfloat,
|
||||||
|
.d32_sfloat_s8_uint,
|
||||||
|
=> if (z > 0.0) std.math.pow(f32, 2.0, @floor(@log2(z)) - 23.0) else 0.0,
|
||||||
|
else => 0.0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clampDepthBias(bias: f32, clamp: f32) f32 {
|
||||||
|
if (clamp > 0.0)
|
||||||
|
return @min(bias, clamp);
|
||||||
|
if (clamp < 0.0)
|
||||||
|
return @max(bias, clamp);
|
||||||
|
return bias;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn scissorContainsPixel(scissor: vk.Rect2D, x: i32, y: i32) bool {
|
pub fn scissorContainsPixel(scissor: vk.Rect2D, x: i32, y: i32) bool {
|
||||||
const min_x: i64 = @as(i64, scissor.offset.x);
|
const min_x: i64 = @as(i64, scissor.offset.x);
|
||||||
const min_y: i64 = @as(i64, scissor.offset.y);
|
const min_y: i64 = @as(i64, scissor.offset.y);
|
||||||
@@ -172,6 +193,20 @@ pub fn depthTestAndUpdate(depth: *RenderTargetAccess, x: usize, y: usize, z: f32
|
|||||||
return depthTestAndUpdateAtOffset(depth, offset, z, state);
|
return depthTestAndUpdateAtOffset(depth, offset, z, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn resolveDepthStencilState(draw_call: *Renderer.DrawCall, state: vk.PipelineDepthStencilStateCreateInfo) vk.PipelineDepthStencilStateCreateInfo {
|
||||||
|
var resolved = state;
|
||||||
|
const pipeline_data = draw_call.renderer.state.pipeline.?.interface.mode.graphics;
|
||||||
|
if (pipeline_data.dynamic_state.depth_bounds) {
|
||||||
|
const bounds = draw_call.renderer.dynamic_state.depth_bounds orelse Renderer.DepthBounds{
|
||||||
|
.min = 0.0,
|
||||||
|
.max = 1.0,
|
||||||
|
};
|
||||||
|
resolved.min_depth_bounds = bounds.min;
|
||||||
|
resolved.max_depth_bounds = bounds.max;
|
||||||
|
}
|
||||||
|
return resolved;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn depthTestSampleAndUpdate(
|
pub fn depthTestSampleAndUpdate(
|
||||||
io: std.Io,
|
io: std.Io,
|
||||||
depth: *RenderTargetAccess,
|
depth: *RenderTargetAccess,
|
||||||
@@ -198,10 +233,14 @@ pub fn depthTestSampleAndUpdate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn depthTestAndUpdateAtOffset(depth: *RenderTargetAccess, offset: usize, z: f32, state: vk.PipelineDepthStencilStateCreateInfo) bool {
|
fn depthTestAndUpdateAtOffset(depth: *RenderTargetAccess, offset: usize, z: f32, state: vk.PipelineDepthStencilStateCreateInfo) bool {
|
||||||
|
const reference = quantizeDepthForFormat(depth.format, z);
|
||||||
|
if (state.depth_bounds_test_enable == .true and
|
||||||
|
(reference < state.min_depth_bounds or reference > state.max_depth_bounds))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (state.depth_test_enable == .false)
|
if (state.depth_test_enable == .false)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
const reference = quantizeDepthForFormat(depth.format, z);
|
|
||||||
const depth_value = blitter.readFloat4(depth.base[offset..], depth.format);
|
const depth_value = blitter.readFloat4(depth.base[offset..], depth.format);
|
||||||
const passed = compare(f32, state.depth_compare_op, reference, depth_value[0]);
|
const passed = compare(f32, state.depth_compare_op, reference, depth_value[0]);
|
||||||
if (passed and state.depth_write_enable == .true)
|
if (passed and state.depth_write_enable == .true)
|
||||||
@@ -287,9 +326,10 @@ pub fn interpolateLineOutputs(
|
|||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
v0: *const Renderer.Vertex,
|
v0: *const Renderer.Vertex,
|
||||||
v1: *const Renderer.Vertex,
|
v1: *const Renderer.Vertex,
|
||||||
|
provoking_vertex: *const Renderer.Vertex,
|
||||||
t: f32,
|
t: f32,
|
||||||
) VkError![spv.SPIRV_MAX_OUTPUT_LOCATIONS]VertexInterpolationLocation {
|
) VkError![spv.SPIRV_MAX_OUTPUT_LOCATIONS]VertexInterpolationLocation {
|
||||||
return interpolateVertexOutputs(allocator, v0, v1, v0, v0, 1.0 - t, t, 0.0);
|
return interpolateVertexOutputs(allocator, v0, v1, v0, provoking_vertex, 1.0 - t, t, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn interpolateVertexOutputDerivatives(
|
pub fn interpolateVertexOutputDerivatives(
|
||||||
@@ -506,7 +546,7 @@ pub fn writeToTargets(
|
|||||||
) VkError!void {
|
) VkError!void {
|
||||||
const io = draw_call.renderer.device.interface.io();
|
const io = draw_call.renderer.device.interface.io();
|
||||||
const pipeline_data = draw_call.renderer.state.pipeline.?.interface.mode.graphics;
|
const pipeline_data = draw_call.renderer.state.pipeline.?.interface.mode.graphics;
|
||||||
const depth_stencil_state = pipeline_data.depth_stencil;
|
const depth_stencil_state = if (pipeline_data.depth_stencil) |state| resolveDepthStencilState(draw_call, state) else null;
|
||||||
const effective_fragment_sample_mask = alphaToCoverageMask(
|
const effective_fragment_sample_mask = alphaToCoverageMask(
|
||||||
pipeline_data.multisample,
|
pipeline_data.multisample,
|
||||||
outputs,
|
outputs,
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ const RunData = struct {
|
|||||||
fragment_uses_derivatives: bool,
|
fragment_uses_derivatives: bool,
|
||||||
fragment_uses_sample_id: bool,
|
fragment_uses_sample_id: bool,
|
||||||
fragment_uses_centroid: bool,
|
fragment_uses_centroid: bool,
|
||||||
|
depth_bias_slope: f32,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn drawTriangle(
|
pub fn drawTriangle(
|
||||||
@@ -64,6 +65,16 @@ pub fn drawTriangle(
|
|||||||
const area = edgeFunction(v0.position, v1.position, v2.position);
|
const area = edgeFunction(v0.position, v1.position, v2.position);
|
||||||
if (area == 0.0)
|
if (area == 0.0)
|
||||||
return;
|
return;
|
||||||
|
const inv_area = 1.0 / area;
|
||||||
|
const dz_dx =
|
||||||
|
(v0.position[2] * ((v1.position[1] - v2.position[1]) * inv_area)) +
|
||||||
|
(v1.position[2] * ((v2.position[1] - v0.position[1]) * inv_area)) +
|
||||||
|
(v2.position[2] * ((v0.position[1] - v1.position[1]) * inv_area));
|
||||||
|
const dz_dy =
|
||||||
|
(v0.position[2] * ((v2.position[0] - v1.position[0]) * inv_area)) +
|
||||||
|
(v1.position[2] * ((v0.position[0] - v2.position[0]) * inv_area)) +
|
||||||
|
(v2.position[2] * ((v1.position[0] - v0.position[0]) * inv_area));
|
||||||
|
const depth_bias_slope = @max(@abs(dz_dx), @abs(dz_dy));
|
||||||
|
|
||||||
const pipeline = draw_call.renderer.state.pipeline orelse return;
|
const pipeline = draw_call.renderer.state.pipeline orelse return;
|
||||||
const fragment_stage = pipeline.stages.getPtr(.fragment);
|
const fragment_stage = pipeline.stages.getPtr(.fragment);
|
||||||
@@ -139,6 +150,7 @@ pub fn drawTriangle(
|
|||||||
.fragment_uses_derivatives = fragment_uses_derivatives,
|
.fragment_uses_derivatives = fragment_uses_derivatives,
|
||||||
.fragment_uses_sample_id = fragment_uses_sample_id,
|
.fragment_uses_sample_id = fragment_uses_sample_id,
|
||||||
.fragment_uses_centroid = fragment_uses_centroid,
|
.fragment_uses_centroid = fragment_uses_centroid,
|
||||||
|
.depth_bias_slope = depth_bias_slope,
|
||||||
};
|
};
|
||||||
|
|
||||||
draw_call.rasterizer_wait_group.async(io, runWrapper, .{run_data});
|
draw_call.rasterizer_wait_group.async(io, runWrapper, .{run_data});
|
||||||
@@ -250,6 +262,7 @@ fn applyEarlyDepth(data: RunData, coverage_sample_mask: vk.SampleMask, x: i32, y
|
|||||||
|
|
||||||
const depth = data.depth_attachment_access orelse return .{ .mask = coverage_sample_mask, .applied = false };
|
const depth = data.depth_attachment_access orelse return .{ .mask = coverage_sample_mask, .applied = false };
|
||||||
const pipeline_data = data.draw_call.renderer.state.pipeline.?.interface.mode.graphics;
|
const pipeline_data = data.draw_call.renderer.state.pipeline.?.interface.mode.graphics;
|
||||||
|
const depth_stencil_state = if (pipeline_data.depth_stencil) |state| common.resolveDepthStencilState(data.draw_call, state) else null;
|
||||||
const io = data.draw_call.renderer.device.interface.io();
|
const io = data.draw_call.renderer.device.interface.io();
|
||||||
|
|
||||||
var passed_mask: vk.SampleMask = 0;
|
var passed_mask: vk.SampleMask = 0;
|
||||||
@@ -261,13 +274,38 @@ fn applyEarlyDepth(data: RunData, coverage_sample_mask: vk.SampleMask, x: i32, y
|
|||||||
if ((coverage_sample_mask & bit) == 0)
|
if ((coverage_sample_mask & bit) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (try common.depthTestSampleAndUpdate(io, depth, @intCast(x), @intCast(y), sample_index, z, pipeline_data.depth_stencil))
|
if (try common.depthTestSampleAndUpdate(io, depth, @intCast(x), @intCast(y), sample_index, z, depth_stencil_state))
|
||||||
passed_mask |= bit;
|
passed_mask |= bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
return .{ .mask = passed_mask, .applied = true };
|
return .{ .mask = passed_mask, .applied = true };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn biasedDepth(data: RunData, z: f32) f32 {
|
||||||
|
const pipeline_data = data.draw_call.renderer.state.pipeline.?.interface.mode.graphics;
|
||||||
|
if (pipeline_data.rasterization.depth_bias_enable == .false)
|
||||||
|
return z;
|
||||||
|
|
||||||
|
const depth = data.depth_attachment_access orelse return z;
|
||||||
|
const bias_state: Renderer.DepthBias = if (pipeline_data.dynamic_state.depth_bias)
|
||||||
|
data.draw_call.renderer.dynamic_state.depth_bias orelse Renderer.DepthBias{
|
||||||
|
.constant_factor = 0.0,
|
||||||
|
.clamp = 0.0,
|
||||||
|
.slope_factor = 0.0,
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Renderer.DepthBias{
|
||||||
|
.constant_factor = pipeline_data.rasterization.depth_bias_constant_factor,
|
||||||
|
.clamp = pipeline_data.rasterization.depth_bias_clamp,
|
||||||
|
.slope_factor = pipeline_data.rasterization.depth_bias_slope_factor,
|
||||||
|
};
|
||||||
|
|
||||||
|
const bias =
|
||||||
|
bias_state.constant_factor * common.depthBiasConstantUnit(depth.format, z) +
|
||||||
|
bias_state.slope_factor * data.depth_bias_slope;
|
||||||
|
return z + common.clampDepthBias(bias, bias_state.clamp);
|
||||||
|
}
|
||||||
|
|
||||||
fn runWrapper(data: RunData) void {
|
fn runWrapper(data: RunData) void {
|
||||||
@call(.always_inline, run, .{data}) catch |err| {
|
@call(.always_inline, run, .{data}) catch |err| {
|
||||||
std.log.scoped(.@"Rasterization stage").err("triangle fill mode catched a '{s}'", .{@errorName(err)});
|
std.log.scoped(.@"Rasterization stage").err("triangle fill mode catched a '{s}'", .{@errorName(err)});
|
||||||
@@ -304,8 +342,9 @@ inline fn run(data: RunData) !void {
|
|||||||
const b1 = w1 / data.area;
|
const b1 = w1 / data.area;
|
||||||
const b2 = w2 / data.area;
|
const b2 = w2 / data.area;
|
||||||
const z = (b0 * data.v0.position[2]) + (b1 * data.v1.position[2]) + (b2 * data.v2.position[2]);
|
const z = (b0 * data.v0.position[2]) + (b1 * data.v1.position[2]) + (b2 * data.v2.position[2]);
|
||||||
|
const depth_z = biasedDepth(data, z);
|
||||||
const frag_w = (b0 / data.v0.position[3]) + (b1 / data.v1.position[3]) + (b2 / data.v2.position[3]);
|
const frag_w = (b0 / data.v0.position[3]) + (b1 / data.v1.position[3]) + (b2 / data.v2.position[3]);
|
||||||
const early_depth = try applyEarlyDepth(data, coverage_sample_mask, x, y, z, sample_count);
|
const early_depth = try applyEarlyDepth(data, coverage_sample_mask, x, y, depth_z, sample_count);
|
||||||
if (early_depth.mask == 0)
|
if (early_depth.mask == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -378,7 +417,7 @@ inline fn run(data: RunData) !void {
|
|||||||
data.front_face,
|
data.front_face,
|
||||||
@intCast(x),
|
@intCast(x),
|
||||||
@intCast(y),
|
@intCast(y),
|
||||||
sample_result.depth orelse z,
|
sample_result.depth orelse depth_z,
|
||||||
sample_coverage_mask,
|
sample_coverage_mask,
|
||||||
sample_result.sample_mask,
|
sample_result.sample_mask,
|
||||||
early_depth.applied,
|
early_depth.applied,
|
||||||
@@ -460,7 +499,7 @@ inline fn run(data: RunData) !void {
|
|||||||
data.front_face,
|
data.front_face,
|
||||||
@intCast(x),
|
@intCast(x),
|
||||||
@intCast(y),
|
@intCast(y),
|
||||||
fragment_result.depth orelse z,
|
fragment_result.depth orelse depth_z,
|
||||||
early_depth.mask,
|
early_depth.mask,
|
||||||
fragment_result.sample_mask,
|
fragment_result.sample_mask,
|
||||||
early_depth.applied,
|
early_depth.applied,
|
||||||
|
|||||||
@@ -78,7 +78,10 @@ pub const DispatchTable = struct {
|
|||||||
resolveImage: *const fn (*Self, *Image, vk.ImageLayout, *Image, vk.ImageLayout, vk.ImageResolve) VkError!void,
|
resolveImage: *const fn (*Self, *Image, vk.ImageLayout, *Image, vk.ImageLayout, vk.ImageResolve) VkError!void,
|
||||||
setEvent: *const fn (*Self, *Event, vk.PipelineStageFlags) VkError!void,
|
setEvent: *const fn (*Self, *Event, vk.PipelineStageFlags) VkError!void,
|
||||||
setBlendConstants: *const fn (*Self, [4]f32) VkError!void,
|
setBlendConstants: *const fn (*Self, [4]f32) VkError!void,
|
||||||
|
setDepthBias: *const fn (*Self, f32, f32, f32) VkError!void,
|
||||||
|
setDepthBounds: *const fn (*Self, f32, f32) VkError!void,
|
||||||
setDeviceMask: *const fn (*Self, u32) VkError!void,
|
setDeviceMask: *const fn (*Self, u32) VkError!void,
|
||||||
|
setLineWidth: *const fn (*Self, f32) VkError!void,
|
||||||
setScissor: *const fn (*Self, u32, []const vk.Rect2D) VkError!void,
|
setScissor: *const fn (*Self, u32, []const vk.Rect2D) VkError!void,
|
||||||
setStencilCompareMask: *const fn (*Self, vk.StencilFaceFlags, u32) VkError!void,
|
setStencilCompareMask: *const fn (*Self, vk.StencilFaceFlags, u32) VkError!void,
|
||||||
setStencilReference: *const fn (*Self, vk.StencilFaceFlags, u32) VkError!void,
|
setStencilReference: *const fn (*Self, vk.StencilFaceFlags, u32) VkError!void,
|
||||||
@@ -86,6 +89,7 @@ pub const DispatchTable = struct {
|
|||||||
setViewport: *const fn (*Self, u32, []const vk.Viewport) VkError!void,
|
setViewport: *const fn (*Self, u32, []const vk.Viewport) VkError!void,
|
||||||
updateBuffer: *const fn (*Self, *Buffer, vk.DeviceSize, []const u8) VkError!void,
|
updateBuffer: *const fn (*Self, *Buffer, vk.DeviceSize, []const u8) VkError!void,
|
||||||
waitEvent: *const fn (*Self, *Event, vk.PipelineStageFlags, vk.PipelineStageFlags, []const vk.MemoryBarrier, []const vk.BufferMemoryBarrier, []const vk.ImageMemoryBarrier) VkError!void,
|
waitEvent: *const fn (*Self, *Event, vk.PipelineStageFlags, vk.PipelineStageFlags, []const vk.MemoryBarrier, []const vk.BufferMemoryBarrier, []const vk.ImageMemoryBarrier) VkError!void,
|
||||||
|
writeTimestamp: *const fn (*Self, vk.PipelineStageFlags, *QueryPool, u32) VkError!void,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const VTable = struct {
|
pub const VTable = struct {
|
||||||
@@ -338,6 +342,14 @@ pub inline fn setBlendConstants(self: *Self, constants: [4]f32) VkError!void {
|
|||||||
try self.dispatch_table.setBlendConstants(self, constants);
|
try self.dispatch_table.setBlendConstants(self, constants);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn setDepthBias(self: *Self, constant_factor: f32, clamp: f32, slope_factor: f32) VkError!void {
|
||||||
|
try self.dispatch_table.setDepthBias(self, constant_factor, clamp, slope_factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn setDepthBounds(self: *Self, min: f32, max: f32) VkError!void {
|
||||||
|
try self.dispatch_table.setDepthBounds(self, min, max);
|
||||||
|
}
|
||||||
|
|
||||||
pub inline fn setDeviceMask(self: *Self, device_mask: u32) VkError!void {
|
pub inline fn setDeviceMask(self: *Self, device_mask: u32) VkError!void {
|
||||||
if (device_mask != 1)
|
if (device_mask != 1)
|
||||||
return VkError.ValidationFailed;
|
return VkError.ValidationFailed;
|
||||||
@@ -345,6 +357,10 @@ pub inline fn setDeviceMask(self: *Self, device_mask: u32) VkError!void {
|
|||||||
try self.dispatch_table.setDeviceMask(self, device_mask);
|
try self.dispatch_table.setDeviceMask(self, device_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn setLineWidth(self: *Self, width: f32) VkError!void {
|
||||||
|
try self.dispatch_table.setLineWidth(self, width);
|
||||||
|
}
|
||||||
|
|
||||||
pub inline fn setScissor(self: *Self, first: u32, scissor: []const vk.Rect2D) VkError!void {
|
pub inline fn setScissor(self: *Self, first: u32, scissor: []const vk.Rect2D) VkError!void {
|
||||||
try self.dispatch_table.setScissor(self, first, scissor);
|
try self.dispatch_table.setScissor(self, first, scissor);
|
||||||
}
|
}
|
||||||
@@ -376,3 +392,7 @@ pub inline fn waitEvent(
|
|||||||
) VkError!void {
|
) VkError!void {
|
||||||
try self.dispatch_table.waitEvent(self, event, src_stage, dst_stage, memory_barriers, buffer_barriers, image_barriers);
|
try self.dispatch_table.waitEvent(self, event, src_stage, dst_stage, memory_barriers, buffer_barriers, image_barriers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn writeTimestamp(self: *Self, stage: vk.PipelineStageFlags, pool: *QueryPool, query: u32) VkError!void {
|
||||||
|
try self.dispatch_table.writeTimestamp(self, stage, pool, query);
|
||||||
|
}
|
||||||
|
|||||||
@@ -48,3 +48,41 @@ pub inline fn signal(self: *Self) VkError!void {
|
|||||||
pub inline fn wait(self: *Self, timeout: u64) VkError!void {
|
pub inline fn wait(self: *Self, timeout: u64) VkError!void {
|
||||||
try self.vtable.wait(self, timeout);
|
try self.vtable.wait(self, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn waitMany(device: *Device, fences: []const *Self, wait_for_all: vk.Bool32, timeout: u64) VkError!void {
|
||||||
|
const forever = timeout == std.math.maxInt(@TypeOf(timeout));
|
||||||
|
const io = device.io();
|
||||||
|
const deadline = if (forever) null else std.Io.Clock.Timestamp.fromNow(io, .{
|
||||||
|
.raw = .fromNanoseconds(@intCast(timeout)),
|
||||||
|
.clock = .awake,
|
||||||
|
});
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
var signaled_count: usize = 0;
|
||||||
|
for (fences) |fence| {
|
||||||
|
if (fence.owner != device) return VkError.InvalidHandleDrv;
|
||||||
|
|
||||||
|
fence.getStatus() catch |err| switch (err) {
|
||||||
|
VkError.NotReady => continue,
|
||||||
|
else => return err,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (wait_for_all == .false) return;
|
||||||
|
signaled_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (signaled_count == fences.len) return;
|
||||||
|
if (timeout == 0) return VkError.Timeout;
|
||||||
|
|
||||||
|
const sleep_ns = if (deadline) |value| blk: {
|
||||||
|
const remaining = value.durationFromNow(io);
|
||||||
|
if (remaining.raw.nanoseconds <= 0) return VkError.Timeout;
|
||||||
|
break :blk @min(remaining.raw.nanoseconds, std.time.ns_per_ms);
|
||||||
|
} else std.time.ns_per_ms;
|
||||||
|
|
||||||
|
(std.Io.Clock.Duration{
|
||||||
|
.raw = .fromNanoseconds(sleep_ns),
|
||||||
|
.clock = .awake,
|
||||||
|
}).sleep(io) catch return VkError.DeviceLost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -49,6 +49,10 @@ mode: union(enum) {
|
|||||||
cull_mode: vk.CullModeFlags,
|
cull_mode: vk.CullModeFlags,
|
||||||
front_face: vk.FrontFace,
|
front_face: vk.FrontFace,
|
||||||
line_width: f32,
|
line_width: f32,
|
||||||
|
depth_bias_enable: vk.Bool32,
|
||||||
|
depth_bias_constant_factor: f32,
|
||||||
|
depth_bias_clamp: f32,
|
||||||
|
depth_bias_slope_factor: f32,
|
||||||
},
|
},
|
||||||
multisample: struct {
|
multisample: struct {
|
||||||
rasterization_samples: vk.SampleCountFlags,
|
rasterization_samples: vk.SampleCountFlags,
|
||||||
@@ -194,6 +198,10 @@ pub fn initGraphics(device: *Device, allocator: std.mem.Allocator, cache: ?*Pipe
|
|||||||
.cull_mode = if (info.p_rasterization_state) |state| state.cull_mode else return VkError.ValidationFailed,
|
.cull_mode = if (info.p_rasterization_state) |state| state.cull_mode else return VkError.ValidationFailed,
|
||||||
.front_face = if (info.p_rasterization_state) |state| state.front_face else return VkError.ValidationFailed,
|
.front_face = if (info.p_rasterization_state) |state| state.front_face else return VkError.ValidationFailed,
|
||||||
.line_width = if (info.p_rasterization_state) |state| state.line_width else return VkError.ValidationFailed,
|
.line_width = if (info.p_rasterization_state) |state| state.line_width else return VkError.ValidationFailed,
|
||||||
|
.depth_bias_enable = if (info.p_rasterization_state) |state| state.depth_bias_enable else return VkError.ValidationFailed,
|
||||||
|
.depth_bias_constant_factor = if (info.p_rasterization_state) |state| state.depth_bias_constant_factor else return VkError.ValidationFailed,
|
||||||
|
.depth_bias_clamp = if (info.p_rasterization_state) |state| state.depth_bias_clamp else return VkError.ValidationFailed,
|
||||||
|
.depth_bias_slope_factor = if (info.p_rasterization_state) |state| state.depth_bias_slope_factor else return VkError.ValidationFailed,
|
||||||
},
|
},
|
||||||
.multisample = blk: {
|
.multisample = blk: {
|
||||||
if (rasterizer_discard_enable) {
|
if (rasterizer_discard_enable) {
|
||||||
|
|||||||
@@ -69,6 +69,16 @@ pub fn end(self: *Self, query: u32) VkError!void {
|
|||||||
q.available = true;
|
q.available = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn writeTimestamp(self: *Self, query: u32, value: u64) VkError!void {
|
||||||
|
if (self.query_type != .timestamp)
|
||||||
|
return VkError.ValidationFailed;
|
||||||
|
|
||||||
|
const q = try self.queryAt(query);
|
||||||
|
q.value.store(value, .seq_cst);
|
||||||
|
q.available = true;
|
||||||
|
q.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn addSamples(self: *Self, query: u32, samples: u64) VkError!void {
|
pub fn addSamples(self: *Self, query: u32, samples: u64) VkError!void {
|
||||||
const q = try self.queryAt(query);
|
const q = try self.queryAt(query);
|
||||||
if (q.active)
|
if (q.active)
|
||||||
|
|||||||
+18
-36
@@ -1434,13 +1434,11 @@ pub export fn apeGetDeviceMemoryCommitment(p_device: vk.Device, p_memory: vk.Dev
|
|||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return errorLogger(err);
|
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return errorLogger(err);
|
||||||
const memory = Dispatchable(DeviceMemory).fromHandleObject(p_memory) catch |err| return errorLogger(err);
|
const memory = NonDispatchable(DeviceMemory).fromHandleObject(p_memory) catch |err| return errorLogger(err);
|
||||||
|
if (memory.owner != device)
|
||||||
|
return errorLogger(VkError.InvalidHandleDrv);
|
||||||
|
|
||||||
notImplementedWarning();
|
committed_memory.* = memory.size;
|
||||||
|
|
||||||
_ = device;
|
|
||||||
_ = memory;
|
|
||||||
_ = committed_memory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub export fn apeGetDeviceGroupPeerMemoryFeatures(
|
pub export fn apeGetDeviceGroupPeerMemoryFeatures(
|
||||||
@@ -1759,13 +1757,17 @@ pub export fn apeWaitForFences(p_device: vk.Device, count: u32, p_fences: [*]con
|
|||||||
entryPointBeginLogTrace(.vkWaitForFences);
|
entryPointBeginLogTrace(.vkWaitForFences);
|
||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return toVkResult(err);
|
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err);
|
||||||
|
|
||||||
for (p_fences, 0..count) |p_fence, _| {
|
const allocator = VulkanAllocator.init(null, .command).allocator();
|
||||||
const fence = NonDispatchable(Fence).fromHandleObject(p_fence) catch |err| return toVkResult(err);
|
const fences = allocator.alloc(*Fence, count) catch return toVkResult(VkError.OutOfHostMemory);
|
||||||
fence.wait(timeout) catch |err| return toVkResult(err);
|
defer allocator.free(fences);
|
||||||
if (waitForAll == .false) break;
|
|
||||||
|
for (p_fences[0..count], fences) |p_fence, *fence| {
|
||||||
|
fence.* = NonDispatchable(Fence).fromHandleObject(p_fence) catch |err| return toVkResult(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Fence.waitMany(device, fences, waitForAll, timeout) catch |err| return toVkResult(err);
|
||||||
return .success;
|
return .success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2152,13 +2154,7 @@ pub export fn apeCmdSetDepthBias(p_cmd: vk.CommandBuffer, constant_factor: f32,
|
|||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
|
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
|
||||||
|
cmd.setDepthBias(constant_factor, clamp, slope_factor) catch |err| return errorLogger(err);
|
||||||
notImplementedWarning();
|
|
||||||
|
|
||||||
_ = cmd;
|
|
||||||
_ = constant_factor;
|
|
||||||
_ = clamp;
|
|
||||||
_ = slope_factor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub export fn apeCmdSetDepthBounds(p_cmd: vk.CommandBuffer, min: f32, max: f32) callconv(vk.vulkan_call_conv) void {
|
pub export fn apeCmdSetDepthBounds(p_cmd: vk.CommandBuffer, min: f32, max: f32) callconv(vk.vulkan_call_conv) void {
|
||||||
@@ -2166,12 +2162,7 @@ pub export fn apeCmdSetDepthBounds(p_cmd: vk.CommandBuffer, min: f32, max: f32)
|
|||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
|
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
|
||||||
|
cmd.setDepthBounds(min, max) catch |err| return errorLogger(err);
|
||||||
notImplementedWarning();
|
|
||||||
|
|
||||||
_ = cmd;
|
|
||||||
_ = min;
|
|
||||||
_ = max;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub export fn apeCmdSetDeviceMask(p_cmd: vk.CommandBuffer, device_mask: u32) callconv(vk.vulkan_call_conv) void {
|
pub export fn apeCmdSetDeviceMask(p_cmd: vk.CommandBuffer, device_mask: u32) callconv(vk.vulkan_call_conv) void {
|
||||||
@@ -2200,11 +2191,7 @@ pub export fn apeCmdSetLineWidth(p_cmd: vk.CommandBuffer, width: f32) callconv(v
|
|||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
|
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
|
||||||
|
cmd.setLineWidth(width) catch |err| return errorLogger(err);
|
||||||
notImplementedWarning();
|
|
||||||
|
|
||||||
_ = cmd;
|
|
||||||
_ = width;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub export fn apeCmdSetScissor(p_cmd: vk.CommandBuffer, first: u32, count: u32, scissors: [*]const vk.Rect2D) callconv(vk.vulkan_call_conv) void {
|
pub export fn apeCmdSetScissor(p_cmd: vk.CommandBuffer, first: u32, count: u32, scissors: [*]const vk.Rect2D) callconv(vk.vulkan_call_conv) void {
|
||||||
@@ -2292,13 +2279,8 @@ pub export fn apeCmdWriteTimestamp(p_cmd: vk.CommandBuffer, stage: vk.PipelineSt
|
|||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
|
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
|
||||||
|
const pool = NonDispatchable(QueryPool).fromHandleObject(p_pool) catch |err| return errorLogger(err);
|
||||||
notImplementedWarning();
|
cmd.writeTimestamp(stage, pool, query) catch |err| return errorLogger(err);
|
||||||
|
|
||||||
_ = cmd;
|
|
||||||
_ = stage;
|
|
||||||
_ = p_pool;
|
|
||||||
_ = query;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub export fn apeEndCommandBuffer(p_cmd: vk.CommandBuffer) callconv(vk.vulkan_call_conv) vk.Result {
|
pub export fn apeEndCommandBuffer(p_cmd: vk.CommandBuffer) callconv(vk.vulkan_call_conv) vk.Result {
|
||||||
|
|||||||
Reference in New Issue
Block a user