dusk: abilibity to reference global decl after current decl
This commit is contained in:
parent
2025ac8d17
commit
9f58497771
4 changed files with 826 additions and 504 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -5,8 +5,9 @@ const ErrorMsg = @import("main.zig").ErrorMsg;
|
|||
const IR = @This();
|
||||
|
||||
allocator: std.mem.Allocator,
|
||||
globals_index: u32,
|
||||
instructions: []const Inst,
|
||||
refs: []const Ref,
|
||||
refs: []const Inst.Ref,
|
||||
strings: []const u8,
|
||||
|
||||
pub fn deinit(self: IR) void {
|
||||
|
|
@ -28,28 +29,65 @@ pub fn generate(allocator: std.mem.Allocator, tree: *const Ast) !AstGenResult {
|
|||
};
|
||||
defer astgen.deinit();
|
||||
|
||||
if (!try astgen.translationUnit()) {
|
||||
return .{ .errors = try astgen.errors.toOwnedSlice(allocator) };
|
||||
}
|
||||
const globals_index = astgen.genTranslationUnit() catch |err| switch (err) {
|
||||
error.AnalysisFail => return .{ .errors = try astgen.errors.toOwnedSlice(allocator) },
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
};
|
||||
|
||||
return .{ .ir = .{
|
||||
.allocator = allocator,
|
||||
.globals_index = globals_index,
|
||||
.instructions = try astgen.instructions.toOwnedSlice(allocator),
|
||||
.refs = try astgen.refs.toOwnedSlice(allocator),
|
||||
.strings = try astgen.strings.toOwnedSlice(allocator),
|
||||
} };
|
||||
}
|
||||
|
||||
pub const Ref = u32;
|
||||
pub const null_ref: Ref = std.math.maxInt(Ref);
|
||||
pub fn getStr(self: IR, index: u32) []const u8 {
|
||||
return std.mem.sliceTo(self.strings[index..], 0);
|
||||
}
|
||||
|
||||
pub const Inst = packed struct {
|
||||
pub const Inst = struct {
|
||||
tag: Tag,
|
||||
data: Data,
|
||||
|
||||
pub const Index = u32;
|
||||
|
||||
const ref_start_index = @typeInfo(Ref).Enum.fields.len;
|
||||
pub fn toRef(index: Inst.Index) Ref {
|
||||
return @intToEnum(Ref, ref_start_index + index);
|
||||
}
|
||||
|
||||
pub const Ref = enum(u32) {
|
||||
none,
|
||||
|
||||
bool_type,
|
||||
i32_type,
|
||||
u32_type,
|
||||
f32_type,
|
||||
f16_type,
|
||||
sampler_type,
|
||||
comparison_sampler_type,
|
||||
external_sampled_texture_type,
|
||||
|
||||
true_literal,
|
||||
false_literal,
|
||||
|
||||
_,
|
||||
|
||||
pub fn toIndex(inst: Ref) ?Inst.Index {
|
||||
const ref_int = @enumToInt(inst);
|
||||
if (ref_int >= ref_start_index) {
|
||||
return @intCast(Inst.Index, ref_int - ref_start_index);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub const Tag = enum(u6) {
|
||||
/// data is global_variable
|
||||
global_variable,
|
||||
/// data is global_variable_decl
|
||||
global_variable_decl,
|
||||
|
||||
/// data is struct_decl
|
||||
struct_decl,
|
||||
|
|
@ -67,16 +105,6 @@ pub const Inst = packed struct {
|
|||
/// data is attr_interpolate
|
||||
attr_interpolate,
|
||||
|
||||
/// data is none
|
||||
bool_type,
|
||||
/// data is none
|
||||
i32_type,
|
||||
/// data is none
|
||||
u32_type,
|
||||
/// data is none
|
||||
f32_type,
|
||||
/// data is none
|
||||
f16_type,
|
||||
/// data is vector_type
|
||||
vector_type,
|
||||
/// data is matrix_type
|
||||
|
|
@ -87,10 +115,6 @@ pub const Inst = packed struct {
|
|||
array_type,
|
||||
/// data is ptr_type
|
||||
ptr_type,
|
||||
/// data is none
|
||||
sampler_type,
|
||||
/// data is none
|
||||
comparison_sampler_type,
|
||||
/// data is sampled_texture_type
|
||||
sampled_texture_type,
|
||||
/// data is multisampled_texture_type
|
||||
|
|
@ -99,17 +123,11 @@ pub const Inst = packed struct {
|
|||
storage_texture_type,
|
||||
/// data is depth_texture_type
|
||||
depth_texture_type,
|
||||
/// data is none
|
||||
external_sampled_texture_type,
|
||||
|
||||
/// data is integer_literal
|
||||
integer_literal,
|
||||
/// data is float_literal
|
||||
float_literal,
|
||||
/// data is none
|
||||
true_literal,
|
||||
/// data is none
|
||||
false_literal,
|
||||
|
||||
/// data is ref
|
||||
not,
|
||||
|
|
@ -163,13 +181,47 @@ pub const Inst = packed struct {
|
|||
member_access,
|
||||
/// data is binary (lhs is expr, rhs is type)
|
||||
bitcast,
|
||||
|
||||
pub fn isDecl(self: Tag) bool {
|
||||
return switch (self) {
|
||||
.global_variable_decl, .struct_decl => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const Data = packed union {
|
||||
/// TODO: https://github.com/ziglang/zig/issues/14980
|
||||
none: u1,
|
||||
pub const Data = union {
|
||||
ref: Ref,
|
||||
global_variable: packed struct {
|
||||
global_variable_decl: GlobalVariableDecl,
|
||||
struct_decl: StructDecl,
|
||||
struct_member: StructMember,
|
||||
/// attributes with no argument.
|
||||
attr_simple: AttrSimple,
|
||||
/// attributes with an expression argument.
|
||||
attr_expr: AttrExpr,
|
||||
/// @builtin attribute which accepts a BuiltinValue argument.
|
||||
attr_builtin: Ast.BuiltinValue,
|
||||
/// @workgroup attribute. accepts at laest 1 argument.
|
||||
attr_workgroup: AttrWorkgroup,
|
||||
/// @interpolate attribute. accepts 2 arguments.
|
||||
attr_interpolate: AttrInterpolate,
|
||||
vector_type: VectorType,
|
||||
matrix_type: MatrixType,
|
||||
atomic_type: AtomicType,
|
||||
array_type: ArrayType,
|
||||
ptr_type: PointerType,
|
||||
sampled_texture_type: SampledTextureType,
|
||||
multisampled_texture_type: MultisampledTextureType,
|
||||
storage_texture_type: StorageTextureType,
|
||||
depth_texture_type: DepthTextureType,
|
||||
integer_literal: i64,
|
||||
float_literal: f64,
|
||||
/// meaning of LHS and RHS depends on the corresponding Tag.
|
||||
binary: BinaryExpr,
|
||||
member_access: MemberAccess,
|
||||
};
|
||||
|
||||
pub const GlobalVariableDecl = struct {
|
||||
/// index to null-terminated string in `strings`
|
||||
name: u32,
|
||||
type: Ref,
|
||||
|
|
@ -177,120 +229,229 @@ pub const Inst = packed struct {
|
|||
access_mode: Ast.AccessMode = .none,
|
||||
/// length of attributes
|
||||
attrs: u4 = 0,
|
||||
},
|
||||
struct_decl: packed struct {
|
||||
};
|
||||
|
||||
pub const StructDecl = struct {
|
||||
/// index to null-terminated string in `strings`
|
||||
name: u32,
|
||||
/// length of the member Ref's which comes after this
|
||||
members: u32,
|
||||
},
|
||||
struct_member: packed struct {
|
||||
};
|
||||
|
||||
pub const StructMember = struct {
|
||||
/// index to null-terminated string in `strings`
|
||||
name: u32,
|
||||
type: Ref,
|
||||
@"align": u29, // 0 means null
|
||||
},
|
||||
/// attributes with no argument.
|
||||
attr_simple: enum {
|
||||
};
|
||||
|
||||
pub const AttrSimple = enum {
|
||||
invariant,
|
||||
@"const",
|
||||
vertex,
|
||||
fragment,
|
||||
compute,
|
||||
},
|
||||
/// attributes with an expression argument.
|
||||
attr_expr: packed struct {
|
||||
kind: enum {
|
||||
};
|
||||
|
||||
pub const AttrExpr = struct {
|
||||
kind: Kind,
|
||||
expr: Ref,
|
||||
|
||||
pub const Kind = enum {
|
||||
@"align",
|
||||
binding,
|
||||
group,
|
||||
id,
|
||||
location,
|
||||
size,
|
||||
},
|
||||
expr: Ref,
|
||||
},
|
||||
/// @builtin attribute which accepts a BuiltinValue argument.
|
||||
attr_builtin: Ast.BuiltinValue,
|
||||
/// @workgroup attribute. accepts at laest 1 argument.
|
||||
attr_workgroup: packed struct {
|
||||
};
|
||||
};
|
||||
|
||||
pub const AttrWorkgroup = struct {
|
||||
expr0: Ref,
|
||||
expr1: Ref = null_ref,
|
||||
expr2: Ref = null_ref,
|
||||
},
|
||||
/// @interpolate attribute. accepts 2 arguments.
|
||||
attr_interpolate: packed struct {
|
||||
expr1: Ref = .none,
|
||||
expr2: Ref = .none,
|
||||
};
|
||||
|
||||
pub const AttrInterpolate = struct {
|
||||
type: Ast.InterpolationType,
|
||||
sample: Ast.InterpolationSample,
|
||||
},
|
||||
vector_type: packed struct {
|
||||
};
|
||||
|
||||
pub const VectorType = struct {
|
||||
component_type: Ref,
|
||||
size: enum { two, three, four },
|
||||
},
|
||||
matrix_type: packed struct {
|
||||
size: Size,
|
||||
|
||||
pub const Size = enum { two, three, four };
|
||||
};
|
||||
|
||||
pub const MatrixType = struct {
|
||||
component_type: Ref,
|
||||
cols: enum { two, three, four },
|
||||
rows: enum { two, three, four },
|
||||
},
|
||||
atomic_type: packed struct { component_type: Ref },
|
||||
array_type: packed struct {
|
||||
cols: VectorType.Size,
|
||||
rows: VectorType.Size,
|
||||
};
|
||||
|
||||
pub const AtomicType = struct { component_type: Ref };
|
||||
|
||||
pub const ArrayType = struct {
|
||||
component_type: Ref,
|
||||
size: Ref = null_ref,
|
||||
},
|
||||
ptr_type: packed struct {
|
||||
size: Ref = .none,
|
||||
};
|
||||
|
||||
pub const PointerType = struct {
|
||||
component_type: Ref,
|
||||
addr_space: Ast.AddressSpace,
|
||||
access_mode: Ast.AccessMode,
|
||||
},
|
||||
sampled_texture_type: packed struct {
|
||||
kind: enum {
|
||||
};
|
||||
|
||||
pub const SampledTextureType = struct {
|
||||
kind: Kind,
|
||||
component_type: Ref,
|
||||
|
||||
pub const Kind = enum {
|
||||
@"1d",
|
||||
@"2d",
|
||||
@"2d_array",
|
||||
@"3d",
|
||||
cube,
|
||||
cube_array,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
pub const MultisampledTextureType = struct {
|
||||
kind: Kind,
|
||||
component_type: Ref,
|
||||
},
|
||||
multisampled_texture_type: packed struct {
|
||||
kind: enum { @"2d" },
|
||||
component_type: Ref,
|
||||
},
|
||||
storage_texture_type: packed struct {
|
||||
kind: enum {
|
||||
|
||||
pub const Kind = enum { @"2d" };
|
||||
};
|
||||
|
||||
pub const StorageTextureType = struct {
|
||||
kind: Kind,
|
||||
texel_format: Ast.TexelFormat,
|
||||
access_mode: AccessMode,
|
||||
|
||||
pub const Kind = enum {
|
||||
@"1d",
|
||||
@"2d",
|
||||
@"2d_array",
|
||||
@"3d",
|
||||
},
|
||||
texel_format: Ast.TexelFormat,
|
||||
access_mode: MultisampledTextureTypeKind,
|
||||
},
|
||||
depth_texture_type: enum {
|
||||
};
|
||||
|
||||
pub const AccessMode = enum { write };
|
||||
};
|
||||
|
||||
pub const DepthTextureType = enum {
|
||||
@"2d",
|
||||
@"2d_array",
|
||||
cube,
|
||||
cube_array,
|
||||
multisampled_2d,
|
||||
},
|
||||
integer_literal: i64,
|
||||
float_literal: f64,
|
||||
/// meaning of LHS and RHS depends on the corresponding Tag.
|
||||
binary: packed struct {
|
||||
};
|
||||
|
||||
pub const BinaryExpr = struct {
|
||||
lhs: Ref,
|
||||
rhs: Ref,
|
||||
},
|
||||
member_access: packed struct {
|
||||
};
|
||||
|
||||
pub const MemberAccess = struct {
|
||||
base: Ref,
|
||||
/// index to null-terminated string in `strings`
|
||||
name: u32,
|
||||
},
|
||||
|
||||
pub const MultisampledTextureTypeKind = enum { write };
|
||||
};
|
||||
|
||||
comptime {
|
||||
std.debug.assert(@bitSizeOf(Inst) <= 104); // 13B
|
||||
std.debug.assert(@sizeOf(Inst) <= 24);
|
||||
}
|
||||
};
|
||||
|
||||
pub fn print(self: IR, writer: anytype) !void {
|
||||
const globals = std.mem.sliceTo(self.refs[self.globals_index..], .none);
|
||||
for (globals) |ref| {
|
||||
try self.printInst(writer, 0, ref, false);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn printInst(self: IR, writer: anytype, indention: u16, ref: Inst.Ref, as_ref: bool) !void {
|
||||
switch (ref) {
|
||||
.none,
|
||||
.bool_type,
|
||||
.i32_type,
|
||||
.u32_type,
|
||||
.f32_type,
|
||||
.f16_type,
|
||||
.sampler_type,
|
||||
.comparison_sampler_type,
|
||||
.external_sampled_texture_type,
|
||||
.true_literal,
|
||||
.false_literal,
|
||||
=> {
|
||||
try writer.print("{s}()", .{@tagName(ref)});
|
||||
},
|
||||
_ => {
|
||||
const index = ref.toIndex().?;
|
||||
const inst = self.instructions[index];
|
||||
|
||||
if (as_ref and inst.tag.isDecl()) {
|
||||
try writer.print("%{d}", .{index});
|
||||
return;
|
||||
}
|
||||
|
||||
try writer.print("%{d} = {s}{{", .{ index, @tagName(inst.tag) });
|
||||
switch (inst.tag) {
|
||||
.global_variable_decl => {
|
||||
try writer.writeByte('\n');
|
||||
|
||||
try printIndent(writer, indention + 1);
|
||||
try writer.writeAll(".type = ");
|
||||
try self.printInst(writer, indention + 2, inst.data.global_variable_decl.type, true);
|
||||
try writer.writeAll(",\n");
|
||||
|
||||
try printIndent(writer, indention);
|
||||
try writer.writeAll("},\n");
|
||||
},
|
||||
.struct_decl => {
|
||||
try writer.writeByte('\n');
|
||||
|
||||
try printIndent(writer, indention + 1);
|
||||
try writer.print(".name = \"{s}\",\n", .{self.getStr(inst.data.struct_decl.name)});
|
||||
|
||||
const members = std.mem.sliceTo(self.refs[inst.data.struct_decl.members..], .none);
|
||||
try printIndent(writer, indention + 1);
|
||||
try writer.writeAll(".members = [\n");
|
||||
for (members) |member| {
|
||||
try printIndent(writer, indention + 2);
|
||||
try self.printInst(writer, indention + 2, member, false);
|
||||
}
|
||||
try printIndent(writer, indention + 1);
|
||||
try writer.writeAll("],\n");
|
||||
|
||||
try printIndent(writer, indention);
|
||||
try writer.writeAll("},\n");
|
||||
},
|
||||
.struct_member => {
|
||||
try writer.writeByte('\n');
|
||||
|
||||
try printIndent(writer, indention + 1);
|
||||
try writer.print(".name = \"{s}\",\n", .{self.getStr(inst.data.struct_member.name)});
|
||||
|
||||
try printIndent(writer, indention + 1);
|
||||
try writer.writeAll(".type = ");
|
||||
try self.printInst(writer, indention + 2, inst.data.struct_member.type, true);
|
||||
try writer.writeAll(",\n");
|
||||
|
||||
try printIndent(writer, indention);
|
||||
try writer.writeAll("},\n");
|
||||
},
|
||||
else => {
|
||||
try writer.print("TODO", .{});
|
||||
try writer.writeAll("}");
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const indention_size = 2;
|
||||
pub fn printIndent(writer: anytype, indent: u16) !void {
|
||||
try writer.writeByteNTimes(' ', indent * indention_size);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
const NUM_PARTICLES: u32 = 1500u;
|
||||
|
||||
struct Particles {
|
||||
particles : array<Particle>
|
||||
}
|
||||
|
||||
struct Particle {
|
||||
pos : vec2<f32>,
|
||||
vel : vec2<f32>,
|
||||
|
|
@ -15,10 +19,6 @@ struct SimParams {
|
|||
rule3Scale : f32,
|
||||
}
|
||||
|
||||
struct Particles {
|
||||
particles : array<Particle>
|
||||
}
|
||||
|
||||
@group(0) @binding(0) var<uniform> params : SimParams;
|
||||
@group(0) @binding(1) var<storage> particlesSrc : Particles;
|
||||
@group(0) @binding(2) var<storage,read_write> particlesDst : Particles;
|
||||
|
|
|
|||
|
|
@ -183,6 +183,7 @@ test "boids" {
|
|||
const source = @embedFile("boids.wgsl");
|
||||
var ir = try expectIR(source);
|
||||
defer ir.deinit();
|
||||
// try ir.print(std.io.getStdOut().writer());
|
||||
}
|
||||
|
||||
test "gkurve" {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue