fixing push constant management
This commit is contained in:
+4
-1
@@ -502,6 +502,7 @@ fn applySpecializationConstants(self: *Self, allocator: std.mem.Allocator) Runti
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn applySpecializationDependentLayout(self: *Self, allocator: std.mem.Allocator) RuntimeError!void {
|
fn applySpecializationDependentLayout(self: *Self, allocator: std.mem.Allocator) RuntimeError!void {
|
||||||
|
self.reset();
|
||||||
try self.pass(allocator, .initMany(&.{
|
try self.pass(allocator, .initMany(&.{
|
||||||
.TypeArray,
|
.TypeArray,
|
||||||
.Variable,
|
.Variable,
|
||||||
@@ -778,6 +779,7 @@ pub fn populatePushConstants(self: *Self, blob: []const u8) RuntimeError!void {
|
|||||||
if (variable.storage_class != .PushConstant)
|
if (variable.storage_class != .PushConstant)
|
||||||
continue;
|
continue;
|
||||||
_ = try variable.value.write(blob);
|
_ = try variable.value.write(blob);
|
||||||
|
variable.value.clearExternalData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1282,7 +1284,8 @@ pub fn resetInvocation(self: *Self, allocator: std.mem.Allocator) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn reset(self: *Self) void {
|
fn reset(self: *Self) void {
|
||||||
self.it = self.mod.it;
|
self.it = WordIterator.init(self.mod.code);
|
||||||
|
self.it.index = 5;
|
||||||
self.function_stack.clearRetainingCapacity();
|
self.function_stack.clearRetainingCapacity();
|
||||||
self.current_parameter_index = 0;
|
self.current_parameter_index = 0;
|
||||||
self.current_function = null;
|
self.current_function = null;
|
||||||
|
|||||||
+48
-10
@@ -449,6 +449,7 @@ pub fn initRuntimeDispatcher() void {
|
|||||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.SpecConstantFalse)] = opSpecConstantFalse;
|
runtime_dispatcher[@intFromEnum(spv.SpvOp.SpecConstantFalse)] = opSpecConstantFalse;
|
||||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.SpecConstantOp)] = opSpecConstantOp;
|
runtime_dispatcher[@intFromEnum(spv.SpvOp.SpecConstantOp)] = opSpecConstantOp;
|
||||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.SpecConstantTrue)] = opSpecConstantTrue;
|
runtime_dispatcher[@intFromEnum(spv.SpvOp.SpecConstantTrue)] = opSpecConstantTrue;
|
||||||
|
runtime_dispatcher[@intFromEnum(spv.SpvOp.TypeArray)] = opTypeArray;
|
||||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.Store)] = opStore;
|
runtime_dispatcher[@intFromEnum(spv.SpvOp.Store)] = opStore;
|
||||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.Switch)] = opSwitch;
|
runtime_dispatcher[@intFromEnum(spv.SpvOp.Switch)] = opSwitch;
|
||||||
runtime_dispatcher[@intFromEnum(spv.SpvOp.TerminateInvocation)] = opKill;
|
runtime_dispatcher[@intFromEnum(spv.SpvOp.TerminateInvocation)] = opKill;
|
||||||
@@ -1623,8 +1624,14 @@ fn ImageEngine(comptime Op: ImageOp) type {
|
|||||||
const dy_y: i32 = @intFromFloat(coord_derivatives.dy.y);
|
const dy_y: i32 = @intFromFloat(coord_derivatives.dy.y);
|
||||||
const dy_z: i32 = @intFromFloat(coord_derivatives.dy.z);
|
const dy_z: i32 = @intFromFloat(coord_derivatives.dy.z);
|
||||||
|
|
||||||
try readImage(rt, &dx_read, driver_image, dim, x + dx_x, y + dx_y, z + dx_z, lod);
|
readImage(rt, &dx_read, driver_image, dim, x + dx_x, y + dx_y, z + dx_z, lod) catch {
|
||||||
try readImage(rt, &dy_read, driver_image, dim, x + dy_x, y + dy_y, z + dy_z, lod);
|
rt.clearDerivative(allocator, result_id);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
readImage(rt, &dy_read, driver_image, dim, x + dy_x, y + dy_y, z + dy_z, lod) catch {
|
||||||
|
rt.clearDerivative(allocator, result_id);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
var dx = try Value.init(allocator, rt.results, result_type_word, false);
|
var dx = try Value.init(allocator, rt.results, result_type_word, false);
|
||||||
defer dx.deinit(allocator);
|
defer dx.deinit(allocator);
|
||||||
@@ -1825,7 +1832,9 @@ fn ImageEngine(comptime Op: ImageOp) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn implicitSampleLod(rt: *Runtime, coordinate_id: SpvWord, coordinate: *const Value, projected: bool, driver_image: *anyopaque, driver_sampler: *anyopaque, dim: spv.SpvDim, x: f32, y: f32, z: f32, bias: f32) RuntimeError!?f32 {
|
fn implicitSampleLod(rt: *Runtime, coordinate_id: SpvWord, coordinate: *const Value, projected: bool, driver_image: *anyopaque, driver_sampler: *anyopaque, dim: spv.SpvDim, x: f32, y: f32, z: f32, bias: f32) RuntimeError!?f32 {
|
||||||
const fallback_lod = if (bias != 0.0) bias else null;
|
if (bias != 0.0)
|
||||||
|
return bias;
|
||||||
|
const fallback_lod = null;
|
||||||
const coord_derivatives = if (projected)
|
const coord_derivatives = if (projected)
|
||||||
(try projectedSampleDerivatives(rt, coordinate_id, coordinate)) orelse return fallback_lod
|
(try projectedSampleDerivatives(rt, coordinate_id, coordinate)) orelse return fallback_lod
|
||||||
else
|
else
|
||||||
@@ -2303,7 +2312,13 @@ fn ImageEngine(comptime Op: ImageOp) type {
|
|||||||
const y = (readStorageCoordLane(coordinate, 1) catch 0) + parsed_operands.offset.y;
|
const y = (readStorageCoordLane(coordinate, 1) catch 0) + parsed_operands.offset.y;
|
||||||
const z = (readStorageCoordLane(coordinate, 2) catch 0) + parsed_operands.offset.z;
|
const z = (readStorageCoordLane(coordinate, 2) catch 0) + parsed_operands.offset.z;
|
||||||
|
|
||||||
const read_z = if (image_operand.arrayed) z else parsed_operands.sample orelse z;
|
const read_z = if (image_operand.arrayed) blk: {
|
||||||
|
if (parsed_operands.sample) |sample| {
|
||||||
|
const sample_count: i32 = @intCast(try rt.image_api.queryImageSamples(image_operand.driver_image));
|
||||||
|
break :blk z * sample_count + sample;
|
||||||
|
}
|
||||||
|
break :blk z;
|
||||||
|
} else parsed_operands.sample orelse z;
|
||||||
try readImage(rt, dst, image_operand.driver_image, image_operand.dim, x, y, read_z, parsed_operands.image_lod);
|
try readImage(rt, dst, image_operand.driver_image, image_operand.dim, x, y, read_z, parsed_operands.image_lod);
|
||||||
try setImageReadDerivative(allocator, rt, result_type_word, result_id, coordinate_id, dst, image_operand.driver_image, image_operand.dim, x, y, read_z, parsed_operands.image_lod);
|
try setImageReadDerivative(allocator, rt, result_type_word, result_id, coordinate_id, dst, image_operand.driver_image, image_operand.dim, x, y, read_z, parsed_operands.image_lod);
|
||||||
},
|
},
|
||||||
@@ -3096,6 +3111,23 @@ fn MathEngine(comptime T: PrimitiveType, comptime Op: MathOp, comptime IsAtomic:
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn derivativeBinary(comptime ScalarT: type, lhs: ScalarT, rhs: ScalarT, lhs_d: ScalarT, rhs_d: ScalarT) RuntimeError!ScalarT {
|
||||||
|
return switch (@typeInfo(ScalarT)) {
|
||||||
|
.float => switch (comptime Op) {
|
||||||
|
.Add => lhs_d + rhs_d,
|
||||||
|
.Sub => lhs_d - rhs_d,
|
||||||
|
.Mul, .VectorTimesScalar => lhs_d * rhs + lhs * rhs_d,
|
||||||
|
.Div => if (rhs == 0.0) 0.0 else ((lhs_d * rhs) - (lhs * rhs_d)) / (rhs * rhs),
|
||||||
|
.Mod => lhs_d - @floor(lhs / rhs) * rhs_d,
|
||||||
|
else => return RuntimeError.UnsupportedSpirV,
|
||||||
|
},
|
||||||
|
else => blk: {
|
||||||
|
const base = try operation(ScalarT, lhs, rhs);
|
||||||
|
break :blk derivativeSub(ScalarT, try operation(ScalarT, derivativeAdd(ScalarT, lhs, lhs_d), derivativeAdd(ScalarT, rhs, rhs_d)), base);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
inline fn applySIMDVectorSingle(comptime ElemT: type, comptime N: usize, d: *@Vector(N, ElemT), v: *const @Vector(N, ElemT)) RuntimeError!void {
|
inline fn applySIMDVectorSingle(comptime ElemT: type, comptime N: usize, d: *@Vector(N, ElemT), v: *const @Vector(N, ElemT)) RuntimeError!void {
|
||||||
inline for (0..N) |i| {
|
inline for (0..N) |i| {
|
||||||
d[i] = try operationSingle(ElemT, v[i]);
|
d[i] = try operationSingle(ElemT, v[i]);
|
||||||
@@ -3160,9 +3192,8 @@ fn MathEngine(comptime T: PrimitiveType, comptime Op: MathOp, comptime IsAtomic:
|
|||||||
else
|
else
|
||||||
@as(ScalarT, 0);
|
@as(ScalarT, 0);
|
||||||
|
|
||||||
const base = try operation(ScalarT, l, r);
|
const dx_lane = try derivativeBinary(ScalarT, l, r, ldx, rdx);
|
||||||
const dx_lane = derivativeSub(ScalarT, try operation(ScalarT, derivativeAdd(ScalarT, l, ldx), derivativeAdd(ScalarT, r, rdx)), base);
|
const dy_lane = try derivativeBinary(ScalarT, l, r, ldy, rdy);
|
||||||
const dy_lane = derivativeSub(ScalarT, try operation(ScalarT, derivativeAdd(ScalarT, l, ldy), derivativeAdd(ScalarT, r, rdy)), base);
|
|
||||||
|
|
||||||
try Value.writeLane(T, bits, &dx, lane_index, dx_lane);
|
try Value.writeLane(T, bits, &dx, lane_index, dx_lane);
|
||||||
try Value.writeLane(T, bits, &dy, lane_index, dy_lane);
|
try Value.writeLane(T, bits, &dy, lane_index, dy_lane);
|
||||||
@@ -6284,6 +6315,7 @@ fn opTypeArray(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void
|
|||||||
const components_type_word = try rt.it.next();
|
const components_type_word = try rt.it.next();
|
||||||
const components_type_data = &((try rt.results[components_type_word].getVariant()).*).Type;
|
const components_type_data = &((try rt.results[components_type_word].getVariant()).*).Type;
|
||||||
const length_word = try rt.it.next();
|
const length_word = try rt.it.next();
|
||||||
|
const member_count = try arrayMemberCount(rt, length_word);
|
||||||
target.variant = .{
|
target.variant = .{
|
||||||
.Type = .{
|
.Type = .{
|
||||||
.Array = .{
|
.Array = .{
|
||||||
@@ -6292,7 +6324,7 @@ fn opTypeArray(_: std.mem.Allocator, _: SpvWord, rt: *Runtime) RuntimeError!void
|
|||||||
.Type => |t| @as(Result.Type, t),
|
.Type => |t| @as(Result.Type, t),
|
||||||
else => return RuntimeError.InvalidSpirV,
|
else => return RuntimeError.InvalidSpirV,
|
||||||
},
|
},
|
||||||
.member_count = try arrayMemberCount(rt, length_word),
|
.member_count = member_count,
|
||||||
.stride = blk: {
|
.stride = blk: {
|
||||||
for (target.decorations.items) |decoration| {
|
for (target.decorations.items) |decoration| {
|
||||||
if (decoration.rtype == .ArrayStride)
|
if (decoration.rtype == .ArrayStride)
|
||||||
@@ -6638,8 +6670,14 @@ fn opVariable(allocator: std.mem.Allocator, word_count: SpvWord, rt: *Runtime) R
|
|||||||
variable.storage_class = storage_class;
|
variable.storage_class = storage_class;
|
||||||
variable.type_word = resolved_word;
|
variable.type_word = resolved_word;
|
||||||
variable.type = resolved_type;
|
variable.type = resolved_type;
|
||||||
try copyValue(&variable.value, &initial_value);
|
const old_size = variable.value.getPlainMemorySize() catch 0;
|
||||||
initial_value.deinit(allocator);
|
const new_size = initial_value.getPlainMemorySize() catch 0;
|
||||||
|
if (std.meta.activeTag(variable.value) == std.meta.activeTag(initial_value) and old_size == new_size) {
|
||||||
|
try copyValue(&variable.value, &initial_value);
|
||||||
|
initial_value.deinit(allocator);
|
||||||
|
} else {
|
||||||
|
variable.value = initial_value;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
|
|||||||
Reference in New Issue
Block a user