adding point rasterization
This commit is contained in:
+2
-2
@@ -32,8 +32,8 @@
|
|||||||
|
|
||||||
// Soft dependencies
|
// Soft dependencies
|
||||||
.SPIRV_Interpreter = .{
|
.SPIRV_Interpreter = .{
|
||||||
.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#42554a5cc1069e8174b377e95ce2ac2d802a44ff",
|
.url = "git+https://github.com/Kbz-8/SPIRV-Interpreter#391f4415d9a77d15455f4d7efab65fc8cc931bc5",
|
||||||
.hash = "SPIRV_Interpreter-0.0.1-ajmpn0GXBwD01BnmV_Kf8EeNqTDoyuq7UvHVaq-WoBP0",
|
.hash = "SPIRV_Interpreter-0.0.1-ajmpn6mrBwDO21UuGIRs3iP-0Z9GyhivF3N8V_X4tLzX",
|
||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
//.SPIRV_Interpreter = .{
|
//.SPIRV_Interpreter = .{
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ pub const DynamicState = struct {
|
|||||||
pub const Vertex = struct {
|
pub const Vertex = struct {
|
||||||
primitive_restart: bool,
|
primitive_restart: bool,
|
||||||
position: F32x4,
|
position: F32x4,
|
||||||
|
point_size: f32,
|
||||||
outputs: [spv.SPIRV_MAX_OUTPUT_LOCATIONS][4]?struct {
|
outputs: [spv.SPIRV_MAX_OUTPUT_LOCATIONS][4]?struct {
|
||||||
interpolation_type: enum { smooth, flat, noperspective },
|
interpolation_type: enum { smooth, flat, noperspective },
|
||||||
blob: []u8,
|
blob: []u8,
|
||||||
@@ -106,6 +107,7 @@ pub const DrawCall = struct {
|
|||||||
|
|
||||||
for (self.vertices) |*vertex| {
|
for (self.vertices) |*vertex| {
|
||||||
vertex.primitive_restart = false;
|
vertex.primitive_restart = false;
|
||||||
|
vertex.point_size = 1.0;
|
||||||
for (&vertex.outputs) |*location| {
|
for (&vertex.outputs) |*location| {
|
||||||
@memset(location, null);
|
@memset(location, null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -171,6 +171,7 @@ fn interpolateVertexForClipping(allocator: std.mem.Allocator, a: *const Vertex,
|
|||||||
var result: Vertex = .{
|
var result: Vertex = .{
|
||||||
.primitive_restart = false,
|
.primitive_restart = false,
|
||||||
.position = a.position + ((b.position - a.position) * zm.f32x4s(t)),
|
.position = a.position + ((b.position - a.position) * zm.f32x4s(t)),
|
||||||
|
.point_size = a.point_size + ((b.point_size - a.point_size) * t),
|
||||||
.outputs = undefined,
|
.outputs = undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ pub fn shaderInvocation(
|
|||||||
draw_call: *Renderer.DrawCall,
|
draw_call: *Renderer.DrawCall,
|
||||||
batch_id: usize,
|
batch_id: usize,
|
||||||
position: zm.F32x4,
|
position: zm.F32x4,
|
||||||
|
point_coord: ?@Vector(2, f32),
|
||||||
front_face: bool,
|
front_face: bool,
|
||||||
inputs: [spv.SPIRV_MAX_OUTPUT_LOCATIONS]VertexInterpolationLocation,
|
inputs: [spv.SPIRV_MAX_OUTPUT_LOCATIONS]VertexInterpolationLocation,
|
||||||
derivative_inputs: ?DerivativeInputs,
|
derivative_inputs: ?DerivativeInputs,
|
||||||
@@ -54,6 +55,12 @@ pub fn shaderInvocation(
|
|||||||
SpvRuntimeError.NotFound => {},
|
SpvRuntimeError.NotFound => {},
|
||||||
else => return err,
|
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) {
|
rt.writeBuiltIn(std.mem.asBytes(&front_face), .FrontFacing) catch |err| switch (err) {
|
||||||
SpvRuntimeError.NotFound => {},
|
SpvRuntimeError.NotFound => {},
|
||||||
else => return err,
|
else => return err,
|
||||||
|
|||||||
@@ -323,11 +323,13 @@ fn clipTransformAndRasterizePoint(
|
|||||||
var transformed = vertex.*;
|
var transformed = vertex.*;
|
||||||
clip.viewportTransformVertex(draw_call.viewport, &transformed);
|
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 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 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 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 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 pipeline = draw_call.renderer.state.pipeline orelse return;
|
||||||
const has_fragment_shader = pipeline.stages.getPtr(.fragment) != null;
|
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);
|
var outputs = std.mem.zeroes([spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(zm.F32x4)]u8);
|
||||||
if (has_fragment_shader) {
|
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(
|
outputs = fragment.shaderInvocation(
|
||||||
allocator,
|
allocator,
|
||||||
draw_call,
|
draw_call,
|
||||||
0,
|
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,
|
true,
|
||||||
try common.interpolateVertexOutputs(allocator, &transformed, &transformed, &transformed, 1.0, 0.0, 0.0),
|
try common.interpolateVertexOutputs(allocator, &transformed, &transformed, &transformed, 1.0, 0.0, 0.0),
|
||||||
null,
|
null,
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ pub fn drawLine(
|
|||||||
const io = draw_call.renderer.device.interface.io();
|
const io = draw_call.renderer.device.interface.io();
|
||||||
|
|
||||||
var x0: i32 = @intFromFloat(v0.position[0]);
|
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 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: {
|
const steep = blk: {
|
||||||
if (@abs(y1 - y0) > @abs(x1 - x0)) {
|
if (@abs(y1 - y0) > @abs(x1 - x0)) {
|
||||||
@@ -76,7 +76,7 @@ pub fn drawLine(
|
|||||||
if (runtimes_count == 0)
|
if (runtimes_count == 0)
|
||||||
return;
|
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 runs_count = @min(runtimes_count, step_count);
|
||||||
const steps_per_run = @divTrunc(step_count + runs_count - 1, runs_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 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 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);
|
var outputs = std.mem.zeroes([spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(F32x4)]u8);
|
||||||
if (data.has_fragment_shader) {
|
if (data.has_fragment_shader) {
|
||||||
@@ -158,7 +159,8 @@ inline fn run(data: RunData) !void {
|
|||||||
data.allocator,
|
data.allocator,
|
||||||
data.draw_call,
|
data.draw_call,
|
||||||
data.batch_id,
|
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,
|
true,
|
||||||
try common.interpolateLineOutputs(data.allocator, data.start_vertex, data.end_vertex, t),
|
try common.interpolateLineOutputs(data.allocator, data.start_vertex, data.end_vertex, t),
|
||||||
null,
|
null,
|
||||||
|
|||||||
@@ -177,6 +177,7 @@ 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 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);
|
var outputs = std.mem.zeroes([spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(F32x4)]u8);
|
||||||
if (data.has_fragment_shader) {
|
if (data.has_fragment_shader) {
|
||||||
@@ -218,7 +219,8 @@ inline fn run(data: RunData) !void {
|
|||||||
data.allocator,
|
data.allocator,
|
||||||
data.draw_call,
|
data.draw_call,
|
||||||
data.batch_id,
|
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,
|
data.front_face,
|
||||||
inputs,
|
inputs,
|
||||||
derivative_inputs,
|
derivative_inputs,
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ inline fn run(data: RunData) !void {
|
|||||||
};
|
};
|
||||||
|
|
||||||
try readPosition(rt, std.mem.asBytes(&output.position));
|
try readPosition(rt, std.mem.asBytes(&output.position));
|
||||||
|
try readPointSize(rt, &output.point_size);
|
||||||
|
|
||||||
for (0..spv.SPIRV_MAX_OUTPUT_LOCATIONS) |location| {
|
for (0..spv.SPIRV_MAX_OUTPUT_LOCATIONS) |location| {
|
||||||
for (0..4) |component| {
|
for (0..4) |component| {
|
||||||
@@ -187,6 +188,15 @@ fn readPosition(rt: *spv.Runtime, output: []u8) !void {
|
|||||||
return SpvRuntimeError.InvalidSpirV;
|
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 {
|
fn isConstantZero(rt: *spv.Runtime, result_word: spv.SpvWord) bool {
|
||||||
if (result_word >= rt.results.len)
|
if (result_word >= rt.results.len)
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user