reswitching to async queue
This commit is contained in:
@@ -12,6 +12,7 @@ const SoftImage = @import("../SoftImage.zig");
|
|||||||
const VkError = base.VkError;
|
const VkError = base.VkError;
|
||||||
const SpvRuntimeError = spv.Runtime.RuntimeError;
|
const SpvRuntimeError = spv.Runtime.RuntimeError;
|
||||||
const INTERFACE_BLOB_PADDING = @sizeOf(zm.F32x4);
|
const INTERFACE_BLOB_PADDING = @sizeOf(zm.F32x4);
|
||||||
|
const PROCESSED_INPUTS_STACK_CAPACITY = 4096;
|
||||||
|
|
||||||
pub const InvocationResult = struct {
|
pub const InvocationResult = struct {
|
||||||
outputs: [spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(zm.F32x4)]u8,
|
outputs: [spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(zm.F32x4)]u8,
|
||||||
@@ -119,8 +120,13 @@ pub fn shaderInvocation(
|
|||||||
|
|
||||||
const entry = try rt.getEntryPointByName(shader.entry);
|
const entry = try rt.getEntryPointByName(shader.entry);
|
||||||
|
|
||||||
const processed_inputs = allocator.alloc(bool, rt.results.len) catch return SpvRuntimeError.OutOfMemory;
|
var processed_inputs_stack: [PROCESSED_INPUTS_STACK_CAPACITY]bool = undefined;
|
||||||
defer allocator.free(processed_inputs);
|
const processed_inputs = if (rt.results.len <= processed_inputs_stack.len)
|
||||||
|
processed_inputs_stack[0..rt.results.len]
|
||||||
|
else
|
||||||
|
allocator.alloc(bool, rt.results.len) catch return SpvRuntimeError.OutOfMemory;
|
||||||
|
defer if (processed_inputs.ptr != &processed_inputs_stack)
|
||||||
|
allocator.free(processed_inputs);
|
||||||
@memset(processed_inputs, false);
|
@memset(processed_inputs, false);
|
||||||
|
|
||||||
for (0..spv.SPIRV_MAX_OUTPUT_LOCATIONS) |location| {
|
for (0..spv.SPIRV_MAX_OUTPUT_LOCATIONS) |location| {
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ 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,
|
||||||
|
sample_count: usize,
|
||||||
|
depth_stencil_state: ?vk.PipelineDepthStencilStateCreateInfo,
|
||||||
|
depth_bias: ?Renderer.DepthBias,
|
||||||
depth_bias_slope: f32,
|
depth_bias_slope: f32,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -57,10 +60,10 @@ pub fn drawTriangle(
|
|||||||
) VkError!void {
|
) VkError!void {
|
||||||
const io = draw_call.renderer.device.interface.io();
|
const io = draw_call.renderer.device.interface.io();
|
||||||
|
|
||||||
const min_x: i32 = @intFromFloat(@floor(@min(v0.position[0], v1.position[0], v2.position[0])));
|
var min_x: i32 = @intFromFloat(@floor(@min(v0.position[0], v1.position[0], v2.position[0])));
|
||||||
const max_x: i32 = @intFromFloat(@ceil(@max(v0.position[0], v1.position[0], v2.position[0])));
|
var max_x: i32 = @intFromFloat(@ceil(@max(v0.position[0], v1.position[0], v2.position[0])));
|
||||||
const min_y: i32 = @intFromFloat(@floor(@min(v0.position[1], v1.position[1], v2.position[1])));
|
var min_y: i32 = @intFromFloat(@floor(@min(v0.position[1], v1.position[1], v2.position[1])));
|
||||||
const max_y: i32 = @intFromFloat(@ceil(@max(v0.position[1], v1.position[1], v2.position[1])));
|
var max_y: i32 = @intFromFloat(@ceil(@max(v0.position[1], v1.position[1], v2.position[1])));
|
||||||
|
|
||||||
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)
|
||||||
@@ -77,6 +80,14 @@ pub fn drawTriangle(
|
|||||||
const depth_bias_slope = @max(@abs(dz_dx), @abs(dz_dy));
|
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 pipeline_data = pipeline.interface.mode.graphics;
|
||||||
|
if (!clipToRect(&min_x, &max_x, &min_y, &max_y, draw_call.scissor))
|
||||||
|
return;
|
||||||
|
if (draw_call.renderer.render_area) |render_area| {
|
||||||
|
if (!clipToRect(&min_x, &max_x, &min_y, &max_y, render_area))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const fragment_stage = pipeline.stages.getPtr(.fragment);
|
const fragment_stage = pipeline.stages.getPtr(.fragment);
|
||||||
const fragment_uses_derivatives = if (fragment_stage) |stage|
|
const fragment_uses_derivatives = if (fragment_stage) |stage|
|
||||||
stage.module.module.reflection_infos.needs_derivatives
|
stage.module.module.reflection_infos.needs_derivatives
|
||||||
@@ -98,6 +109,23 @@ pub fn drawTriangle(
|
|||||||
const runtimes_count = if (fragment_stage) |stage| stage.runtimes.len else 1;
|
const runtimes_count = if (fragment_stage) |stage| stage.runtimes.len else 1;
|
||||||
if (runtimes_count == 0)
|
if (runtimes_count == 0)
|
||||||
return;
|
return;
|
||||||
|
const sample_count = pipeline_data.multisample.rasterization_samples.toInt();
|
||||||
|
const depth_stencil_state = if (pipeline_data.depth_stencil) |state| common.resolveDepthStencilState(draw_call, state) else null;
|
||||||
|
const depth_bias: ?Renderer.DepthBias = if (pipeline_data.rasterization.depth_bias_enable == .true and depth_attachment_access != null)
|
||||||
|
if (pipeline_data.dynamic_state.depth_bias)
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
else
|
||||||
|
null;
|
||||||
const grid_size: usize = @intFromFloat(@ceil(@sqrt(@as(f32, @floatFromInt(runtimes_count)))));
|
const grid_size: usize = @intFromFloat(@ceil(@sqrt(@as(f32, @floatFromInt(runtimes_count)))));
|
||||||
|
|
||||||
const width: usize = @intCast(max_x - min_x + 1);
|
const width: usize = @intCast(max_x - min_x + 1);
|
||||||
@@ -150,6 +178,9 @@ 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,
|
||||||
|
.sample_count = sample_count,
|
||||||
|
.depth_stencil_state = depth_stencil_state,
|
||||||
|
.depth_bias = depth_bias,
|
||||||
.depth_bias_slope = depth_bias_slope,
|
.depth_bias_slope = depth_bias_slope,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -160,6 +191,26 @@ pub fn drawTriangle(
|
|||||||
draw_call.rasterizer_wait_group.await(io) catch return VkError.DeviceLost;
|
draw_call.rasterizer_wait_group.await(io) catch return VkError.DeviceLost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clipToRect(min_x: *i32, max_x: *i32, min_y: *i32, max_y: *i32, rect: vk.Rect2D) bool {
|
||||||
|
if (rect.extent.width == 0 or rect.extent.height == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const rect_min_x = rect.offset.x;
|
||||||
|
const rect_min_y = rect.offset.y;
|
||||||
|
const rect_max_x = clampI64ToI32(@as(i64, rect.offset.x) + @as(i64, @intCast(rect.extent.width)) - 1);
|
||||||
|
const rect_max_y = clampI64ToI32(@as(i64, rect.offset.y) + @as(i64, @intCast(rect.extent.height)) - 1);
|
||||||
|
|
||||||
|
min_x.* = @max(min_x.*, rect_min_x);
|
||||||
|
min_y.* = @max(min_y.*, rect_min_y);
|
||||||
|
max_x.* = @min(max_x.*, rect_max_x);
|
||||||
|
max_y.* = @min(max_y.*, rect_max_y);
|
||||||
|
return min_x.* <= max_x.* and min_y.* <= max_y.*;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clampI64ToI32(value: i64) i32 {
|
||||||
|
return @intCast(std.math.clamp(value, std.math.minInt(i32), std.math.maxInt(i32)));
|
||||||
|
}
|
||||||
|
|
||||||
inline fn edgeFunction(a: F32x4, b: F32x4, p: F32x4) f32 {
|
inline fn edgeFunction(a: F32x4, b: F32x4, p: F32x4) f32 {
|
||||||
return ((p[0] - a[0]) * (b[1] - a[1])) - ((p[1] - a[1]) * (b[0] - a[0]));
|
return ((p[0] - a[0]) * (b[1] - a[1])) - ((p[1] - a[1]) * (b[0] - a[0]));
|
||||||
}
|
}
|
||||||
@@ -261,8 +312,6 @@ fn applyEarlyDepth(data: RunData, coverage_sample_mask: vk.SampleMask, x: i32, y
|
|||||||
return .{ .mask = coverage_sample_mask, .applied = false };
|
return .{ .mask = coverage_sample_mask, .applied = false };
|
||||||
|
|
||||||
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 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;
|
||||||
@@ -274,7 +323,7 @@ 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, depth_stencil_state))
|
if (try common.depthTestSampleAndUpdate(io, depth, @intCast(x), @intCast(y), sample_index, z, data.depth_stencil_state))
|
||||||
passed_mask |= bit;
|
passed_mask |= bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,23 +331,8 @@ fn applyEarlyDepth(data: RunData, coverage_sample_mask: vk.SampleMask, x: i32, y
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn biasedDepth(data: RunData, z: f32) f32 {
|
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 depth = data.depth_attachment_access orelse return z;
|
||||||
const bias_state: Renderer.DepthBias = if (pipeline_data.dynamic_state.depth_bias)
|
const bias_state = data.depth_bias orelse return z;
|
||||||
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 =
|
const bias =
|
||||||
bias_state.constant_factor * common.depthBiasConstantUnit(depth.format, z) +
|
bias_state.constant_factor * common.depthBiasConstantUnit(depth.format, z) +
|
||||||
@@ -322,21 +356,20 @@ inline fn run(data: RunData) !void {
|
|||||||
while (y <= data.max_y) : (y += 1) {
|
while (y <= data.max_y) : (y += 1) {
|
||||||
var x = data.min_x;
|
var x = data.min_x;
|
||||||
while (x <= data.max_x) : (x += 1) {
|
while (x <= data.max_x) : (x += 1) {
|
||||||
if (!common.scissorContainsPixel(data.draw_call.scissor, x, y)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const pipeline_data = data.draw_call.renderer.state.pipeline.?.interface.mode.graphics;
|
|
||||||
const sample_count = pipeline_data.multisample.rasterization_samples.toInt();
|
|
||||||
const coverage_sample_mask = triangleCoverageMask(data, x, y, sample_count);
|
|
||||||
if (coverage_sample_mask == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const p = zm.f32x4(@as(f32, @floatFromInt(x)) + 0.5, @as(f32, @floatFromInt(y)) + 0.5, 0.0, 1.0);
|
const p = zm.f32x4(@as(f32, @floatFromInt(x)) + 0.5, @as(f32, @floatFromInt(y)) + 0.5, 0.0, 1.0);
|
||||||
|
|
||||||
const w0 = edgeFunction(data.v1.position, data.v2.position, p);
|
const w0 = edgeFunction(data.v1.position, data.v2.position, p);
|
||||||
const w1 = edgeFunction(data.v2.position, data.v0.position, p);
|
const w1 = edgeFunction(data.v2.position, data.v0.position, p);
|
||||||
const w2 = edgeFunction(data.v0.position, data.v1.position, p);
|
const w2 = edgeFunction(data.v0.position, data.v1.position, p);
|
||||||
|
const coverage_sample_mask = if (data.sample_count == 1) blk: {
|
||||||
|
const inside =
|
||||||
|
edgeContainsPixel(data.v1.position, data.v2.position, w0, data.area) and
|
||||||
|
edgeContainsPixel(data.v2.position, data.v0.position, w1, data.area) and
|
||||||
|
edgeContainsPixel(data.v0.position, data.v1.position, w2, data.area);
|
||||||
|
break :blk if (inside) @as(vk.SampleMask, 1) else @as(vk.SampleMask, 0);
|
||||||
|
} else triangleCoverageMask(data, x, y, data.sample_count);
|
||||||
|
if (coverage_sample_mask == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
const b0 = w0 / data.area;
|
const b0 = w0 / data.area;
|
||||||
const b1 = w1 / data.area;
|
const b1 = w1 / data.area;
|
||||||
@@ -344,12 +377,12 @@ inline fn run(data: RunData) !void {
|
|||||||
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 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, depth_z, sample_count);
|
const early_depth = try applyEarlyDepth(data, coverage_sample_mask, x, y, depth_z, data.sample_count);
|
||||||
if (early_depth.mask == 0)
|
if (early_depth.mask == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const interpolation_barycentrics = if (sample_count > 1) blk: {
|
const interpolation_barycentrics = if (data.sample_count > 1) blk: {
|
||||||
const sample_pos = firstCoveredSamplePosition(sample_count, early_depth.mask);
|
const sample_pos = firstCoveredSamplePosition(data.sample_count, early_depth.mask);
|
||||||
const centroid_p = zm.f32x4(
|
const centroid_p = zm.f32x4(
|
||||||
@as(f32, @floatFromInt(x)) + sample_pos.x,
|
@as(f32, @floatFromInt(x)) + sample_pos.x,
|
||||||
@as(f32, @floatFromInt(y)) + sample_pos.y,
|
@as(f32, @floatFromInt(y)) + sample_pos.y,
|
||||||
@@ -374,8 +407,8 @@ inline fn run(data: RunData) !void {
|
|||||||
.depth = null,
|
.depth = null,
|
||||||
.sample_mask = null,
|
.sample_mask = null,
|
||||||
};
|
};
|
||||||
if (data.has_fragment_shader and data.fragment_uses_sample_id and sample_count > 1) {
|
if (data.has_fragment_shader and data.fragment_uses_sample_id and data.sample_count > 1) {
|
||||||
for (0..sample_count) |sample_index| {
|
for (0..data.sample_count) |sample_index| {
|
||||||
if (sample_index >= @bitSizeOf(vk.SampleMask))
|
if (sample_index >= @bitSizeOf(vk.SampleMask))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user