added per-output centroid flag to vertex outputs
This commit is contained in:
@@ -73,6 +73,7 @@ pub const Vertex = struct {
|
|||||||
point_size: f32,
|
point_size: f32,
|
||||||
outputs: [spv.SPIRV_MAX_OUTPUT_LOCATIONS][4]?struct {
|
outputs: [spv.SPIRV_MAX_OUTPUT_LOCATIONS][4]?struct {
|
||||||
interpolation_type: InterpolationType,
|
interpolation_type: InterpolationType,
|
||||||
|
centroid: bool,
|
||||||
blob: []u8,
|
blob: []u8,
|
||||||
size: usize,
|
size: usize,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -187,6 +187,7 @@ fn interpolateVertexForClipping(allocator: std.mem.Allocator, a: *const Vertex,
|
|||||||
|
|
||||||
result.outputs[location][component] = .{
|
result.outputs[location][component] = .{
|
||||||
.interpolation_type = out_a.interpolation_type,
|
.interpolation_type = out_a.interpolation_type,
|
||||||
|
.centroid = out_a.centroid,
|
||||||
.blob = if (out_a.interpolation_type == .flat)
|
.blob = if (out_a.interpolation_type == .flat)
|
||||||
allocator.dupe(u8, out_a.blob) catch return VkError.OutOfDeviceMemory
|
allocator.dupe(u8, out_a.blob) catch return VkError.OutOfDeviceMemory
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -477,7 +477,7 @@ fn rasterizeTransformedPoint(
|
|||||||
point_coord,
|
point_coord,
|
||||||
null,
|
null,
|
||||||
true,
|
true,
|
||||||
try common.interpolateVertexOutputs(allocator, vertex, vertex, vertex, vertex, 1.0, 0.0, 0.0),
|
try common.interpolateVertexOutputs(allocator, vertex, vertex, vertex, vertex, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0),
|
||||||
null,
|
null,
|
||||||
) catch |err| {
|
) catch |err| {
|
||||||
if (err == SpvRuntimeError.Killed)
|
if (err == SpvRuntimeError.Killed)
|
||||||
|
|||||||
@@ -262,6 +262,9 @@ pub fn interpolateVertexOutputs(
|
|||||||
b0: f32,
|
b0: f32,
|
||||||
b1: f32,
|
b1: f32,
|
||||||
b2: f32,
|
b2: f32,
|
||||||
|
centroid_b0: f32,
|
||||||
|
centroid_b1: f32,
|
||||||
|
centroid_b2: f32,
|
||||||
) VkError![spv.SPIRV_MAX_OUTPUT_LOCATIONS]VertexInterpolationLocation {
|
) VkError![spv.SPIRV_MAX_OUTPUT_LOCATIONS]VertexInterpolationLocation {
|
||||||
var inputs = [_]VertexInterpolationLocation{[_]VertexInterpolation{.{
|
var inputs = [_]VertexInterpolationLocation{[_]VertexInterpolation{.{
|
||||||
.blob = &.{},
|
.blob = &.{},
|
||||||
@@ -290,19 +293,23 @@ pub fn interpolateVertexOutputs(
|
|||||||
const input = allocator.alloc(u8, len + @sizeOf(F32x4)) catch return VkError.OutOfDeviceMemory;
|
const input = allocator.alloc(u8, len + @sizeOf(F32x4)) catch return VkError.OutOfDeviceMemory;
|
||||||
@memset(input, 0);
|
@memset(input, 0);
|
||||||
|
|
||||||
|
const input_b0 = if (out0.centroid) centroid_b0 else b0;
|
||||||
|
const input_b1 = if (out0.centroid) centroid_b1 else b1;
|
||||||
|
const input_b2 = if (out0.centroid) centroid_b2 else b2;
|
||||||
|
|
||||||
var byte_index: usize = 0;
|
var byte_index: usize = 0;
|
||||||
while (byte_index + @sizeOf(F32x4) <= len) : (byte_index += @sizeOf(F32x4)) {
|
while (byte_index + @sizeOf(F32x4) <= len) : (byte_index += @sizeOf(F32x4)) {
|
||||||
const value0 = std.mem.bytesToValue(F32x4, out0.blob[byte_index..]);
|
const value0 = std.mem.bytesToValue(F32x4, out0.blob[byte_index..]);
|
||||||
const value1 = std.mem.bytesToValue(F32x4, out1.blob[byte_index..]);
|
const value1 = std.mem.bytesToValue(F32x4, out1.blob[byte_index..]);
|
||||||
const value2 = std.mem.bytesToValue(F32x4, out2.blob[byte_index..]);
|
const value2 = std.mem.bytesToValue(F32x4, out2.blob[byte_index..]);
|
||||||
base.utils.writePacked(F32x4, input[byte_index..], interpolateF32x4(out0.interpolation_type, value0, value1, value2, v0, v1, v2, b0, b1, b2));
|
base.utils.writePacked(F32x4, input[byte_index..], interpolateF32x4(out0.interpolation_type, value0, value1, value2, v0, v1, v2, input_b0, input_b1, input_b2));
|
||||||
}
|
}
|
||||||
|
|
||||||
while (byte_index + @sizeOf(f32) <= len) : (byte_index += @sizeOf(f32)) {
|
while (byte_index + @sizeOf(f32) <= len) : (byte_index += @sizeOf(f32)) {
|
||||||
const value0 = std.mem.bytesToValue(f32, out0.blob[byte_index..]);
|
const value0 = std.mem.bytesToValue(f32, out0.blob[byte_index..]);
|
||||||
const value1 = std.mem.bytesToValue(f32, out1.blob[byte_index..]);
|
const value1 = std.mem.bytesToValue(f32, out1.blob[byte_index..]);
|
||||||
const value2 = std.mem.bytesToValue(f32, out2.blob[byte_index..]);
|
const value2 = std.mem.bytesToValue(f32, out2.blob[byte_index..]);
|
||||||
base.utils.writePacked(f32, input[byte_index..], interpolateF32(out0.interpolation_type, value0, value1, value2, v0, v1, v2, b0, b1, b2));
|
base.utils.writePacked(f32, input[byte_index..], interpolateF32(out0.interpolation_type, value0, value1, value2, v0, v1, v2, input_b0, input_b1, input_b2));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (byte_index < len)
|
if (byte_index < len)
|
||||||
@@ -322,7 +329,7 @@ pub fn interpolateLineOutputs(
|
|||||||
provoking_vertex: *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, provoking_vertex, 1.0 - t, t, 0.0);
|
return interpolateVertexOutputs(allocator, v0, v1, v0, provoking_vertex, 1.0 - t, t, 0.0, 1.0 - t, t, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn interpolateVertexOutputDerivatives(
|
pub fn interpolateVertexOutputDerivatives(
|
||||||
|
|||||||
@@ -381,7 +381,7 @@ inline fn run(data: RunData) !void {
|
|||||||
if (early_depth.mask == 0)
|
if (early_depth.mask == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const interpolation_barycentrics = if (data.sample_count > 1 and data.fragment_uses_centroid) blk: {
|
const centroid_barycentrics = if (data.sample_count > 1 and data.fragment_uses_centroid) blk: {
|
||||||
const sample_pos = firstCoveredSamplePosition(data.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,
|
||||||
@@ -398,9 +398,9 @@ inline fn run(data: RunData) !void {
|
|||||||
centroid_w2 / data.area,
|
centroid_w2 / data.area,
|
||||||
};
|
};
|
||||||
} else .{ b0, b1, b2 };
|
} else .{ b0, b1, b2 };
|
||||||
const input_b0 = interpolation_barycentrics[0];
|
const centroid_b0 = centroid_barycentrics[0];
|
||||||
const input_b1 = interpolation_barycentrics[1];
|
const centroid_b1 = centroid_barycentrics[1];
|
||||||
const input_b2 = interpolation_barycentrics[2];
|
const centroid_b2 = centroid_barycentrics[2];
|
||||||
|
|
||||||
var fragment_result: fragment.InvocationResult = .{
|
var fragment_result: fragment.InvocationResult = .{
|
||||||
.outputs = std.mem.zeroes([spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(F32x4)]u8),
|
.outputs = std.mem.zeroes([spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(F32x4)]u8),
|
||||||
@@ -417,7 +417,19 @@ inline fn run(data: RunData) !void {
|
|||||||
if ((early_depth.mask & sample_coverage_mask) == 0)
|
if ((early_depth.mask & sample_coverage_mask) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const inputs = try common.interpolateVertexOutputs(data.allocator, &data.v0, &data.v1, &data.v2, &data.provoking_vertex, input_b0, input_b1, input_b2);
|
const inputs = try common.interpolateVertexOutputs(
|
||||||
|
data.allocator,
|
||||||
|
&data.v0,
|
||||||
|
&data.v1,
|
||||||
|
&data.v2,
|
||||||
|
&data.provoking_vertex,
|
||||||
|
b0,
|
||||||
|
b1,
|
||||||
|
b2,
|
||||||
|
centroid_b0,
|
||||||
|
centroid_b1,
|
||||||
|
centroid_b2,
|
||||||
|
);
|
||||||
const sample_result = fragment.shaderInvocation(
|
const sample_result = fragment.shaderInvocation(
|
||||||
data.allocator,
|
data.allocator,
|
||||||
data.draw_call,
|
data.draw_call,
|
||||||
@@ -459,7 +471,19 @@ inline fn run(data: RunData) !void {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (data.has_fragment_shader) {
|
if (data.has_fragment_shader) {
|
||||||
const inputs = try common.interpolateVertexOutputs(data.allocator, &data.v0, &data.v1, &data.v2, &data.provoking_vertex, input_b0, input_b1, input_b2);
|
const inputs = try common.interpolateVertexOutputs(
|
||||||
|
data.allocator,
|
||||||
|
&data.v0,
|
||||||
|
&data.v1,
|
||||||
|
&data.v2,
|
||||||
|
&data.provoking_vertex,
|
||||||
|
b0,
|
||||||
|
b1,
|
||||||
|
b2,
|
||||||
|
centroid_b0,
|
||||||
|
centroid_b1,
|
||||||
|
centroid_b2,
|
||||||
|
);
|
||||||
const derivative_inputs: ?fragment.DerivativeInputs = if (data.fragment_uses_derivatives) blk: {
|
const derivative_inputs: ?fragment.DerivativeInputs = if (data.fragment_uses_derivatives) blk: {
|
||||||
var derivatives: fragment.DerivativeInputs = undefined;
|
var derivatives: fragment.DerivativeInputs = undefined;
|
||||||
|
|
||||||
|
|||||||
@@ -202,9 +202,10 @@ fn readVertexOutput(data: RunData, output: *Renderer.Vertex, rt: *spv.Runtime, l
|
|||||||
const value = try rt.results[result_word].getConstValue();
|
const value = try rt.results[result_word].getConstValue();
|
||||||
const memory_size = try rt.getResultMemorySize(result_word);
|
const memory_size = try rt.getResultMemorySize(result_word);
|
||||||
const interpolation_type = vertexOutputInterpolationType(data, rt, location, component, result_word);
|
const interpolation_type = vertexOutputInterpolationType(data, rt, location, component, result_word);
|
||||||
|
const centroid = fragmentInputHasDecoration(data, location, component, .Centroid);
|
||||||
switch (value.*) {
|
switch (value.*) {
|
||||||
.Array, .Matrix => {
|
.Array, .Matrix => {
|
||||||
try readVertexOutputAggregate(data, output, value, location, component, interpolation_type);
|
try readVertexOutputAggregate(data, output, value, location, component, interpolation_type, centroid);
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
@@ -212,6 +213,7 @@ fn readVertexOutput(data: RunData, output: *Renderer.Vertex, rt: *spv.Runtime, l
|
|||||||
|
|
||||||
output.outputs[location][component] = .{
|
output.outputs[location][component] = .{
|
||||||
.interpolation_type = interpolation_type,
|
.interpolation_type = interpolation_type,
|
||||||
|
.centroid = centroid,
|
||||||
.blob = data.allocator.alloc(u8, memory_size + INTERFACE_BLOB_PADDING) catch return VkError.OutOfDeviceMemory,
|
.blob = data.allocator.alloc(u8, memory_size + INTERFACE_BLOB_PADDING) catch return VkError.OutOfDeviceMemory,
|
||||||
.size = memory_size,
|
.size = memory_size,
|
||||||
};
|
};
|
||||||
@@ -226,22 +228,23 @@ fn readVertexOutputAggregate(
|
|||||||
location: usize,
|
location: usize,
|
||||||
component: usize,
|
component: usize,
|
||||||
interpolation_type: Renderer.InterpolationType,
|
interpolation_type: Renderer.InterpolationType,
|
||||||
|
centroid: bool,
|
||||||
) !void {
|
) !void {
|
||||||
var target_location = location;
|
var target_location = location;
|
||||||
switch (value.*) {
|
switch (value.*) {
|
||||||
.Array => |array| {
|
.Array => |array| {
|
||||||
for (array.values) |*element| {
|
for (array.values) |*element| {
|
||||||
try readVertexOutputAggregate(data, output, element, target_location, component, interpolation_type);
|
try readVertexOutputAggregate(data, output, element, target_location, component, interpolation_type, centroid);
|
||||||
target_location += vertexOutputValueLocationCount(element);
|
target_location += vertexOutputValueLocationCount(element);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.Matrix => |columns| {
|
.Matrix => |columns| {
|
||||||
for (columns) |*column| {
|
for (columns) |*column| {
|
||||||
try writeVertexOutputValue(data, output, column, target_location, component, interpolation_type);
|
try writeVertexOutputValue(data, output, column, target_location, component, interpolation_type, centroid);
|
||||||
target_location += 1;
|
target_location += 1;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
else => try writeVertexOutputValue(data, output, value, location, component, interpolation_type),
|
else => try writeVertexOutputValue(data, output, value, location, component, interpolation_type, centroid),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,6 +255,7 @@ fn writeVertexOutputValue(
|
|||||||
location: usize,
|
location: usize,
|
||||||
component: usize,
|
component: usize,
|
||||||
interpolation_type: Renderer.InterpolationType,
|
interpolation_type: Renderer.InterpolationType,
|
||||||
|
centroid: bool,
|
||||||
) !void {
|
) !void {
|
||||||
if (location >= spv.SPIRV_MAX_OUTPUT_LOCATIONS or component >= 4)
|
if (location >= spv.SPIRV_MAX_OUTPUT_LOCATIONS or component >= 4)
|
||||||
return VkError.ValidationFailed;
|
return VkError.ValidationFailed;
|
||||||
@@ -259,6 +263,7 @@ fn writeVertexOutputValue(
|
|||||||
const memory_size = try value.getPlainMemorySize();
|
const memory_size = try value.getPlainMemorySize();
|
||||||
output.outputs[location][component] = .{
|
output.outputs[location][component] = .{
|
||||||
.interpolation_type = interpolation_type,
|
.interpolation_type = interpolation_type,
|
||||||
|
.centroid = centroid,
|
||||||
.blob = data.allocator.alloc(u8, memory_size + INTERFACE_BLOB_PADDING) catch return VkError.OutOfDeviceMemory,
|
.blob = data.allocator.alloc(u8, memory_size + INTERFACE_BLOB_PADDING) catch return VkError.OutOfDeviceMemory,
|
||||||
.size = memory_size,
|
.size = memory_size,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user