adding point rasterization
This commit is contained in:
+2
-2
@@ -32,8 +32,8 @@
|
||||
|
||||
// Soft dependencies
|
||||
.SPIRV_Interpreter = .{
|
||||
.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#42554a5cc1069e8174b377e95ce2ac2d802a44ff",
|
||||
.hash = "SPIRV_Interpreter-0.0.1-ajmpn0GXBwD01BnmV_Kf8EeNqTDoyuq7UvHVaq-WoBP0",
|
||||
.url = "git+https://github.com/Kbz-8/SPIRV-Interpreter#391f4415d9a77d15455f4d7efab65fc8cc931bc5",
|
||||
.hash = "SPIRV_Interpreter-0.0.1-ajmpn6mrBwDO21UuGIRs3iP-0Z9GyhivF3N8V_X4tLzX",
|
||||
.lazy = true,
|
||||
},
|
||||
//.SPIRV_Interpreter = .{
|
||||
|
||||
@@ -55,6 +55,7 @@ pub const DynamicState = struct {
|
||||
pub const Vertex = struct {
|
||||
primitive_restart: bool,
|
||||
position: F32x4,
|
||||
point_size: f32,
|
||||
outputs: [spv.SPIRV_MAX_OUTPUT_LOCATIONS][4]?struct {
|
||||
interpolation_type: enum { smooth, flat, noperspective },
|
||||
blob: []u8,
|
||||
@@ -106,6 +107,7 @@ pub const DrawCall = struct {
|
||||
|
||||
for (self.vertices) |*vertex| {
|
||||
vertex.primitive_restart = false;
|
||||
vertex.point_size = 1.0;
|
||||
for (&vertex.outputs) |*location| {
|
||||
@memset(location, null);
|
||||
}
|
||||
|
||||
@@ -171,6 +171,7 @@ fn interpolateVertexForClipping(allocator: std.mem.Allocator, a: *const Vertex,
|
||||
var result: Vertex = .{
|
||||
.primitive_restart = false,
|
||||
.position = a.position + ((b.position - a.position) * zm.f32x4s(t)),
|
||||
.point_size = a.point_size + ((b.point_size - a.point_size) * t),
|
||||
.outputs = undefined,
|
||||
};
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ pub fn shaderInvocation(
|
||||
draw_call: *Renderer.DrawCall,
|
||||
batch_id: usize,
|
||||
position: zm.F32x4,
|
||||
point_coord: ?@Vector(2, f32),
|
||||
front_face: bool,
|
||||
inputs: [spv.SPIRV_MAX_OUTPUT_LOCATIONS]VertexInterpolationLocation,
|
||||
derivative_inputs: ?DerivativeInputs,
|
||||
@@ -54,6 +55,12 @@ pub fn shaderInvocation(
|
||||
SpvRuntimeError.NotFound => {},
|
||||
else => return err,
|
||||
};
|
||||
if (point_coord) |coord| {
|
||||
rt.writeBuiltIn(std.mem.asBytes(&coord), .PointCoord) catch |err| switch (err) {
|
||||
SpvRuntimeError.NotFound => {},
|
||||
else => return err,
|
||||
};
|
||||
}
|
||||
rt.writeBuiltIn(std.mem.asBytes(&front_face), .FrontFacing) catch |err| switch (err) {
|
||||
SpvRuntimeError.NotFound => {},
|
||||
else => return err,
|
||||
|
||||
@@ -165,25 +165,25 @@ pub fn processThenFragmentStage(renderer: *Renderer, allocator: std.mem.Allocato
|
||||
var segment_start = firstNonRestart(draw_call, range.start, range.end);
|
||||
while (segment_start < range.end) {
|
||||
const segment_end = nextRestart(draw_call, segment_start, range.end);
|
||||
if (segment_end - segment_start >= 3) {
|
||||
const v0 = &draw_call.vertices[segment_start];
|
||||
for ((segment_start + 1)..(segment_end - 1)) |vertex_index| {
|
||||
const v1 = &draw_call.vertices[vertex_index];
|
||||
const v2 = &draw_call.vertices[vertex_index + 1];
|
||||
if (segment_end - segment_start >= 3) {
|
||||
const v0 = &draw_call.vertices[segment_start];
|
||||
for ((segment_start + 1)..(segment_end - 1)) |vertex_index| {
|
||||
const v1 = &draw_call.vertices[vertex_index];
|
||||
const v2 = &draw_call.vertices[vertex_index + 1];
|
||||
|
||||
try clipTransformAndRasterizeTriangle(
|
||||
renderer,
|
||||
allocator,
|
||||
draw_call,
|
||||
v0,
|
||||
v1,
|
||||
v2,
|
||||
color_attachment_access,
|
||||
if (depth_attachment_access) |*access| access else null,
|
||||
if (stencil_attachment_access) |*access| access else null,
|
||||
);
|
||||
try clipTransformAndRasterizeTriangle(
|
||||
renderer,
|
||||
allocator,
|
||||
draw_call,
|
||||
v0,
|
||||
v1,
|
||||
v2,
|
||||
color_attachment_access,
|
||||
if (depth_attachment_access) |*access| access else null,
|
||||
if (stencil_attachment_access) |*access| access else null,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
segment_start = firstNonRestart(draw_call, segment_end + 1, range.end);
|
||||
}
|
||||
}
|
||||
@@ -194,40 +194,40 @@ pub fn processThenFragmentStage(renderer: *Renderer, allocator: std.mem.Allocato
|
||||
var segment_start = firstNonRestart(draw_call, range.start, range.end);
|
||||
while (segment_start < range.end) {
|
||||
const segment_end = nextRestart(draw_call, segment_start, range.end);
|
||||
if (segment_end - segment_start >= 3) {
|
||||
for (segment_start..(segment_end - 2)) |vertex_index| {
|
||||
const local_index = vertex_index - segment_start;
|
||||
const v0 = &draw_call.vertices[vertex_index + 0];
|
||||
const v1 = &draw_call.vertices[vertex_index + 1];
|
||||
const v2 = &draw_call.vertices[vertex_index + 2];
|
||||
if (segment_end - segment_start >= 3) {
|
||||
for (segment_start..(segment_end - 2)) |vertex_index| {
|
||||
const local_index = vertex_index - segment_start;
|
||||
const v0 = &draw_call.vertices[vertex_index + 0];
|
||||
const v1 = &draw_call.vertices[vertex_index + 1];
|
||||
const v2 = &draw_call.vertices[vertex_index + 2];
|
||||
|
||||
if ((local_index & 1) == 0) {
|
||||
try clipTransformAndRasterizeTriangle(
|
||||
renderer,
|
||||
allocator,
|
||||
draw_call,
|
||||
v0,
|
||||
v1,
|
||||
v2,
|
||||
color_attachment_access,
|
||||
if (depth_attachment_access) |*access| access else null,
|
||||
if (stencil_attachment_access) |*access| access else null,
|
||||
);
|
||||
} else {
|
||||
try clipTransformAndRasterizeTriangle(
|
||||
renderer,
|
||||
allocator,
|
||||
draw_call,
|
||||
v1,
|
||||
v0,
|
||||
v2,
|
||||
color_attachment_access,
|
||||
if (depth_attachment_access) |*access| access else null,
|
||||
if (stencil_attachment_access) |*access| access else null,
|
||||
);
|
||||
if ((local_index & 1) == 0) {
|
||||
try clipTransformAndRasterizeTriangle(
|
||||
renderer,
|
||||
allocator,
|
||||
draw_call,
|
||||
v0,
|
||||
v1,
|
||||
v2,
|
||||
color_attachment_access,
|
||||
if (depth_attachment_access) |*access| access else null,
|
||||
if (stencil_attachment_access) |*access| access else null,
|
||||
);
|
||||
} else {
|
||||
try clipTransformAndRasterizeTriangle(
|
||||
renderer,
|
||||
allocator,
|
||||
draw_call,
|
||||
v1,
|
||||
v0,
|
||||
v2,
|
||||
color_attachment_access,
|
||||
if (depth_attachment_access) |*access| access else null,
|
||||
if (stencil_attachment_access) |*access| access else null,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
segment_start = firstNonRestart(draw_call, segment_end + 1, range.end);
|
||||
}
|
||||
}
|
||||
@@ -257,22 +257,22 @@ pub fn processThenFragmentStage(renderer: *Renderer, allocator: std.mem.Allocato
|
||||
var segment_start = firstNonRestart(draw_call, range.start, range.end);
|
||||
while (segment_start < range.end) {
|
||||
const segment_end = nextRestart(draw_call, segment_start, range.end);
|
||||
if (segment_end - segment_start >= 2) {
|
||||
for (segment_start..(segment_end - 1)) |vertex_index| {
|
||||
const v0 = &draw_call.vertices[vertex_index + 0];
|
||||
const v1 = &draw_call.vertices[vertex_index + 1];
|
||||
if (segment_end - segment_start >= 2) {
|
||||
for (segment_start..(segment_end - 1)) |vertex_index| {
|
||||
const v0 = &draw_call.vertices[vertex_index + 0];
|
||||
const v1 = &draw_call.vertices[vertex_index + 1];
|
||||
|
||||
try clipTransformAndRasterizeLine(
|
||||
allocator,
|
||||
draw_call,
|
||||
v0,
|
||||
v1,
|
||||
color_attachment_access,
|
||||
if (depth_attachment_access) |*access| access else null,
|
||||
if (stencil_attachment_access) |*access| access else null,
|
||||
);
|
||||
try clipTransformAndRasterizeLine(
|
||||
allocator,
|
||||
draw_call,
|
||||
v0,
|
||||
v1,
|
||||
color_attachment_access,
|
||||
if (depth_attachment_access) |*access| access else null,
|
||||
if (stencil_attachment_access) |*access| access else null,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
segment_start = firstNonRestart(draw_call, segment_end + 1, range.end);
|
||||
}
|
||||
}
|
||||
@@ -323,11 +323,13 @@ fn clipTransformAndRasterizePoint(
|
||||
var transformed = vertex.*;
|
||||
clip.viewportTransformVertex(draw_call.viewport, &transformed);
|
||||
|
||||
const point_size = 1.0;
|
||||
const point_size = transformed.point_size;
|
||||
const min_x: i32 = @intFromFloat(@ceil(transformed.position[0] - (point_size / 2.0) - 0.5));
|
||||
const max_x: i32 = @intFromFloat(@ceil(transformed.position[0] + (point_size / 2.0) - 0.5) - 1.0);
|
||||
const min_y: i32 = @intFromFloat(@ceil(transformed.position[1] - (point_size / 2.0) - 0.5));
|
||||
const max_y: i32 = @intFromFloat(@ceil(transformed.position[1] + (point_size / 2.0) - 0.5) - 1.0);
|
||||
const point_min_x = transformed.position[0] - (point_size / 2.0);
|
||||
const point_min_y = transformed.position[1] - (point_size / 2.0);
|
||||
const pipeline = draw_call.renderer.state.pipeline orelse return;
|
||||
const has_fragment_shader = pipeline.stages.getPtr(.fragment) != null;
|
||||
|
||||
@@ -340,11 +342,19 @@ fn clipTransformAndRasterizePoint(
|
||||
|
||||
var outputs = std.mem.zeroes([spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(zm.F32x4)]u8);
|
||||
if (has_fragment_shader) {
|
||||
const frag_x = @as(f32, @floatFromInt(px)) + 0.5;
|
||||
const frag_y = @as(f32, @floatFromInt(py)) + 0.5;
|
||||
const point_coord = @Vector(2, f32){
|
||||
(frag_x - point_min_x) / point_size,
|
||||
(frag_y - point_min_y) / point_size,
|
||||
};
|
||||
|
||||
outputs = fragment.shaderInvocation(
|
||||
allocator,
|
||||
draw_call,
|
||||
0,
|
||||
zm.f32x4(@floatFromInt(px), @floatFromInt(py), transformed.position[2], 1.0),
|
||||
zm.f32x4(frag_x, frag_y, transformed.position[2], 1.0 / transformed.position[3]),
|
||||
point_coord,
|
||||
true,
|
||||
try common.interpolateVertexOutputs(allocator, &transformed, &transformed, &transformed, 1.0, 0.0, 0.0),
|
||||
null,
|
||||
|
||||
@@ -45,9 +45,9 @@ pub fn drawLine(
|
||||
const io = draw_call.renderer.device.interface.io();
|
||||
|
||||
var x0: i32 = @intFromFloat(v0.position[0]);
|
||||
var y0: i32 = @intFromFloat(v0.position[1]);
|
||||
var y0: i32 = @intFromFloat(@floor(v0.position[1] - 0.5));
|
||||
var x1: i32 = @intFromFloat(v1.position[0]);
|
||||
var y1: i32 = @intFromFloat(v1.position[1]);
|
||||
var y1: i32 = @intFromFloat(@floor(v1.position[1] - 0.5));
|
||||
|
||||
const steep = blk: {
|
||||
if (@abs(y1 - y0) > @abs(x1 - x0)) {
|
||||
@@ -76,7 +76,7 @@ pub fn drawLine(
|
||||
if (runtimes_count == 0)
|
||||
return;
|
||||
|
||||
const step_count: usize = @as(usize, @intCast(d_x)) + 1;
|
||||
const step_count: usize = if (d_x == 0) 1 else @intCast(d_x);
|
||||
const runs_count = @min(runtimes_count, step_count);
|
||||
const steps_per_run = @divTrunc(step_count + runs_count - 1, runs_count);
|
||||
|
||||
@@ -151,6 +151,7 @@ inline fn run(data: RunData) !void {
|
||||
|
||||
const t = @as(f32, @floatFromInt(step)) / @as(f32, @floatFromInt(@max(data.d_x, 1)));
|
||||
const z = ((1.0 - t) * data.start_vertex.position[2]) + (t * data.end_vertex.position[2]);
|
||||
const frag_w = ((1.0 - t) / data.start_vertex.position[3]) + (t / data.end_vertex.position[3]);
|
||||
|
||||
var outputs = std.mem.zeroes([spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(F32x4)]u8);
|
||||
if (data.has_fragment_shader) {
|
||||
@@ -158,7 +159,8 @@ inline fn run(data: RunData) !void {
|
||||
data.allocator,
|
||||
data.draw_call,
|
||||
data.batch_id,
|
||||
zm.f32x4(@floatFromInt(pixel_x), @floatFromInt(pixel_y), z, 1.0),
|
||||
zm.f32x4(@as(f32, @floatFromInt(pixel_x)) + 0.5, @as(f32, @floatFromInt(pixel_y)) + 0.5, z, frag_w),
|
||||
null,
|
||||
true,
|
||||
try common.interpolateLineOutputs(data.allocator, data.start_vertex, data.end_vertex, t),
|
||||
null,
|
||||
|
||||
@@ -177,6 +177,7 @@ inline fn run(data: RunData) !void {
|
||||
const b1 = w1 / 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 frag_w = (b0 / data.v0.position[3]) + (b1 / data.v1.position[3]) + (b2 / data.v2.position[3]);
|
||||
|
||||
var outputs = std.mem.zeroes([spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(F32x4)]u8);
|
||||
if (data.has_fragment_shader) {
|
||||
@@ -218,7 +219,8 @@ inline fn run(data: RunData) !void {
|
||||
data.allocator,
|
||||
data.draw_call,
|
||||
data.batch_id,
|
||||
zm.f32x4(@floatFromInt(x), @floatFromInt(y), z, 1.0),
|
||||
zm.f32x4(@as(f32, @floatFromInt(x)) + 0.5, @as(f32, @floatFromInt(y)) + 0.5, z, frag_w),
|
||||
null,
|
||||
data.front_face,
|
||||
inputs,
|
||||
derivative_inputs,
|
||||
|
||||
@@ -107,6 +107,7 @@ inline fn run(data: RunData) !void {
|
||||
};
|
||||
|
||||
try readPosition(rt, std.mem.asBytes(&output.position));
|
||||
try readPointSize(rt, &output.point_size);
|
||||
|
||||
for (0..spv.SPIRV_MAX_OUTPUT_LOCATIONS) |location| {
|
||||
for (0..4) |component| {
|
||||
@@ -187,6 +188,15 @@ fn readPosition(rt: *spv.Runtime, output: []u8) !void {
|
||||
return SpvRuntimeError.InvalidSpirV;
|
||||
}
|
||||
|
||||
fn readPointSize(rt: *spv.Runtime, output: *f32) !void {
|
||||
if (rt.readBuiltIn(std.mem.asBytes(output), .PointSize)) {
|
||||
return;
|
||||
} else |err| switch (err) {
|
||||
SpvRuntimeError.InvalidSpirV, SpvRuntimeError.NotFound => {},
|
||||
else => return err,
|
||||
}
|
||||
}
|
||||
|
||||
fn isConstantZero(rt: *spv.Runtime, result_word: spv.SpvWord) bool {
|
||||
if (result_word >= rt.results.len)
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user