spirv: more fixes and improvements

- Formatting.
- Improve `decorate` helper function to generate a decoration for a result-id.
- Reorder some functions in a more logical way
This commit is contained in:
Robin Voetter 2022-11-29 23:44:31 +01:00
parent 700dee34d5
commit 8a00ec162c
No known key found for this signature in database
GPG Key ID: E755662F227CB468
3 changed files with 132 additions and 139 deletions

View File

@ -880,7 +880,9 @@ pub const DeclGen = struct {
// TODO: We probably need to have a special implementation of this for the C abi. // TODO: We probably need to have a special implementation of this for the C abi.
.ret_ptr => try self.airAlloc(inst), .ret_ptr => try self.airAlloc(inst),
.block => try self.airBlock(inst), .block => try self.airBlock(inst),
.load => try self.airLoad(inst), .load => try self.airLoad(inst),
.store => return self.airStore(inst),
.br => return self.airBr(inst), .br => return self.airBr(inst),
.breakpoint => return, .breakpoint => return,
@ -891,7 +893,6 @@ pub const DeclGen = struct {
.loop => return self.airLoop(inst), .loop => return self.airLoop(inst),
.ret => return self.airRet(inst), .ret => return self.airRet(inst),
.ret_load => return self.airRetLoad(inst), .ret_load => return self.airRetLoad(inst),
.store => return self.airStore(inst),
.switch_br => return self.airSwitchBr(inst), .switch_br => return self.airSwitchBr(inst),
.unreach => return self.airUnreach(), .unreach => return self.airUnreach(),
@ -964,13 +965,8 @@ pub const DeclGen = struct {
33...64 => .{ .uint64 = mask_value }, 33...64 => .{ .uint64 = mask_value },
else => unreachable, else => unreachable,
}; };
// TODO: We should probably optimize these constants a bit. // TODO: We should probably optimize the amount of these constants a bit.
const mask_id = self.spv.allocId(); const mask_id = try self.spv.emitConstant(ty_id, mask_lit);
try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpConstant, .{
.id_result_type = ty_id,
.id_result = mask_id,
.value = mask_lit,
});
const result_id = self.spv.allocId(); const result_id = self.spv.allocId();
try self.func.body.emit(self.spv.gpa, .OpBitwiseAnd, .{ try self.func.body.emit(self.spv.gpa, .OpBitwiseAnd, .{
.id_result_type = ty_id, .id_result_type = ty_id,
@ -1119,13 +1115,11 @@ pub const DeclGen = struct {
// Finally, construct the Zig type. // Finally, construct the Zig type.
// Layout is result, overflow. // Layout is result, overflow.
const result_id = self.spv.allocId(); const result_id = self.spv.allocId();
const constituents = [_]IdRef{ result, casted_overflow };
try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{ try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{
.id_result_type = result_type_id, .id_result_type = result_type_id,
.id_result = result_id, .id_result = result_id,
.constituents = &.{ .constituents = &constituents,
result,
casted_overflow,
},
}); });
return result_id; return result_id;
} }
@ -1277,11 +1271,12 @@ pub const DeclGen = struct {
fn extractField(self: *DeclGen, result_ty: IdResultType, object: IdRef, field: u32) !IdRef { fn extractField(self: *DeclGen, result_ty: IdResultType, object: IdRef, field: u32) !IdRef {
const result_id = self.spv.allocId(); const result_id = self.spv.allocId();
const indexes = [_]u32{field};
try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{ try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{
.id_result_type = result_ty, .id_result_type = result_ty,
.id_result = result_id, .id_result = result_id,
.composite = object, .composite = object,
.indexes = &.{field}, .indexes = &indexes,
}); });
return result_id; return result_id;
} }
@ -1318,11 +1313,12 @@ pub const DeclGen = struct {
}; };
const result_id = self.spv.allocId(); const result_id = self.spv.allocId();
const indexes = [_]IdRef{index};
try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{ try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{
.id_result_type = spv_ptr_ty, .id_result_type = spv_ptr_ty,
.id_result = result_id, .id_result = result_id,
.base = slice_ptr, .base = slice_ptr,
.indexes = &.{index}, .indexes = &indexes,
}); });
return result_id; return result_id;
} }
@ -1335,14 +1331,13 @@ pub const DeclGen = struct {
const slice = try self.resolve(bin_op.lhs); const slice = try self.resolve(bin_op.lhs);
const index = try self.resolve(bin_op.rhs); const index = try self.resolve(bin_op.rhs);
const spv_elem_ty = try self.resolveTypeId(self.air.typeOfIndex(inst));
var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined; var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined;
const spv_ptr_ty = try self.resolveTypeId(slice_ty.slicePtrFieldType(&slice_buf)); const ptr_ty_id = try self.resolveTypeId(slice_ty.slicePtrFieldType(&slice_buf));
const slice_ptr = blk: { const slice_ptr = blk: {
const result_id = self.spv.allocId(); const result_id = self.spv.allocId();
try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{ try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{
.id_result_type = spv_ptr_ty, .id_result_type = ptr_ty_id,
.id_result = result_id, .id_result = result_id,
.composite = slice, .composite = slice,
.indexes = &.{0}, .indexes = &.{0},
@ -1352,22 +1347,17 @@ pub const DeclGen = struct {
const elem_ptr = blk: { const elem_ptr = blk: {
const result_id = self.spv.allocId(); const result_id = self.spv.allocId();
const indexes = [_]IdRef{index};
try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{ try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{
.id_result_type = spv_ptr_ty, .id_result_type = ptr_ty_id,
.id_result = result_id, .id_result = result_id,
.base = slice_ptr, .base = slice_ptr,
.indexes = &.{index}, .indexes = &indexes,
}); });
break :blk result_id; break :blk result_id;
}; };
const result_id = self.spv.allocId(); return try self.load(slice_ty, elem_ptr);
try self.func.body.emit(self.spv.gpa, .OpLoad, .{
.id_result_type = spv_elem_ty,
.id_result = result_id,
.pointer = elem_ptr,
});
return result_id;
} }
fn airPtrElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { fn airPtrElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
@ -1386,11 +1376,12 @@ pub const DeclGen = struct {
const rhs = try self.resolve(bin_op.rhs); const rhs = try self.resolve(bin_op.rhs);
const result_id = self.spv.allocId(); const result_id = self.spv.allocId();
const indexes = [_]IdRef{rhs};
try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{ try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{
.id_result_type = result_type_id, .id_result_type = result_type_id,
.id_result = result_id, .id_result = result_id,
.base = base_ptr, .base = base_ptr,
.indexes = &.{rhs}, .indexes = &indexes,
}); });
return result_id; return result_id;
} }
@ -1412,11 +1403,12 @@ pub const DeclGen = struct {
assert(struct_ty.zigTypeTag() == .Struct); // Cannot do unions yet. assert(struct_ty.zigTypeTag() == .Struct); // Cannot do unions yet.
const result_id = self.spv.allocId(); const result_id = self.spv.allocId();
const indexes = [_]u32{field_index};
try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{ try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{
.id_result_type = field_ty_id, .id_result_type = field_ty_id,
.id_result = result_id, .id_result = result_id,
.composite = object, .composite = object,
.indexes = &.{field_index}, .indexes = &indexes,
}); });
return result_id; return result_id;
} }
@ -1433,20 +1425,16 @@ pub const DeclGen = struct {
.Struct => switch (object_ty.containerLayout()) { .Struct => switch (object_ty.containerLayout()) {
.Packed => unreachable, // TODO .Packed => unreachable, // TODO
else => { else => {
const field_index_id = self.spv.allocId();
const u32_ty_id = self.spv.typeResultId(try self.intType(.unsigned, 32)); const u32_ty_id = self.spv.typeResultId(try self.intType(.unsigned, 32));
try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpConstant, .{ const field_index_id = try self.spv.emitConstant(u32_ty_id, .{ .uint32 = field_index });
.id_result_type = u32_ty_id,
.id_result = field_index_id,
.value = .{ .uint32 = field_index },
});
const result_id = self.spv.allocId(); const result_id = self.spv.allocId();
const result_type_id = try self.resolveTypeId(result_ptr_ty); const result_type_id = try self.resolveTypeId(result_ptr_ty);
const indexes = [_]IdRef{field_index_id};
try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{ try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{
.id_result_type = result_type_id, .id_result_type = result_type_id,
.id_result = result_id, .id_result = result_id,
.base = object_ptr, .base = object_ptr,
.indexes = &.{field_index_id}, .indexes = &indexes,
}); });
return result_id; return result_id;
}, },
@ -1591,28 +1579,51 @@ pub const DeclGen = struct {
}); });
} }
fn airLoad(self: *DeclGen, inst: Air.Inst.Index) !IdRef { fn airLoad(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
const ty_op = self.air.instructions.items(.data)[inst].ty_op; const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const operand_id = try self.resolve(ty_op.operand); const ptr_ty = self.air.typeOf(ty_op.operand);
const ty = self.air.typeOfIndex(inst); const operand = try self.resolve(ty_op.operand);
if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
const result_type_id = try self.resolveTypeId(ty); return try self.load(ptr_ty, operand);
}
fn load(self: *DeclGen, ptr_ty: Type, ptr: IdRef) !IdRef {
const value_ty = ptr_ty.childType();
const result_type_id = try self.resolveTypeId(value_ty);
const result_id = self.spv.allocId(); const result_id = self.spv.allocId();
const access = spec.MemoryAccess.Extended{ const access = spec.MemoryAccess.Extended{
.Volatile = ty.isVolatilePtr(), .Volatile = ptr_ty.isVolatilePtr(),
}; };
try self.func.body.emit(self.spv.gpa, .OpLoad, .{ try self.func.body.emit(self.spv.gpa, .OpLoad, .{
.id_result_type = result_type_id, .id_result_type = result_type_id,
.id_result = result_id, .id_result = result_id,
.pointer = operand_id, .pointer = ptr,
.memory_access = access, .memory_access = access,
}); });
return result_id; return result_id;
} }
fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const ptr_ty = self.air.typeOf(bin_op.lhs);
const ptr = try self.resolve(bin_op.lhs);
const value = try self.resolve(bin_op.rhs);
try self.store(ptr_ty, ptr, value);
}
fn store(self: *DeclGen, ptr_ty: Type, ptr: IdRef, value: IdRef) !void {
const access = spec.MemoryAccess.Extended{
.Volatile = ptr_ty.isVolatilePtr(),
};
try self.func.body.emit(self.spv.gpa, .OpStore, .{
.pointer = ptr,
.object = value,
.memory_access = access,
});
}
fn airLoop(self: *DeclGen, inst: Air.Inst.Index) !void { fn airLoop(self: *DeclGen, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
const loop = self.air.extraData(Air.Block, ty_pl.payload); const loop = self.air.extraData(Air.Block, ty_pl.payload);
@ -1644,7 +1655,6 @@ pub const DeclGen = struct {
const un_op = self.air.instructions.items(.data)[inst].un_op; const un_op = self.air.instructions.items(.data)[inst].un_op;
const ptr_ty = self.air.typeOf(un_op); const ptr_ty = self.air.typeOf(un_op);
const ret_ty = ptr_ty.childType(); const ret_ty = ptr_ty.childType();
const ret_ty_id = try self.resolveTypeId(ret_ty);
if (!ret_ty.hasRuntimeBitsIgnoreComptime()) { if (!ret_ty.hasRuntimeBitsIgnoreComptime()) {
try self.func.body.emit(self.spv.gpa, .OpReturn, {}); try self.func.body.emit(self.spv.gpa, .OpReturn, {});
@ -1652,29 +1662,9 @@ pub const DeclGen = struct {
} }
const ptr = try self.resolve(un_op); const ptr = try self.resolve(un_op);
const result_id = self.spv.allocId(); const value = try self.load(ptr_ty, ptr);
try self.func.body.emit(self.spv.gpa, .OpLoad, .{ try self.func.body.emit(self.spv.gpa, .OpReturnValue, .{
.id_result_type = ret_ty_id, .value = value,
.id_result = result_id,
.pointer = ptr,
});
try self.func.body.emit(self.spv.gpa, .OpReturnValue, .{ .value = result_id });
}
fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void {
const bin_op = self.air.instructions.items(.data)[inst].bin_op;
const dst_ptr_id = try self.resolve(bin_op.lhs);
const src_val_id = try self.resolve(bin_op.rhs);
const lhs_ty = self.air.typeOf(bin_op.lhs);
const access = spec.MemoryAccess.Extended{
.Volatile = lhs_ty.isVolatilePtr(),
};
try self.func.body.emit(self.spv.gpa, .OpStore, .{
.pointer = dst_ptr_id,
.object = src_val_id,
.memory_access = access,
}); });
} }
@ -1691,7 +1681,7 @@ pub const DeclGen = struct {
const backing_bits = self.backingIntBits(bits) orelse { const backing_bits = self.backingIntBits(bits) orelse {
return self.todo("implement composite int switch", .{}); return self.todo("implement composite int switch", .{});
}; };
break :blk if (backing_bits <= 32) 1 else 2; break :blk if (backing_bits <= 32) @as(u32, 1) else 2;
}, },
.Enum => blk: { .Enum => blk: {
var buffer: Type.Payload.Bits = undefined; var buffer: Type.Payload.Bits = undefined;
@ -1700,7 +1690,7 @@ pub const DeclGen = struct {
const backing_bits = self.backingIntBits(int_info.bits) orelse { const backing_bits = self.backingIntBits(int_info.bits) orelse {
return self.todo("implement composite int switch", .{}); return self.todo("implement composite int switch", .{});
}; };
break :blk if (backing_bits <= 32) 1 else 2; break :blk if (backing_bits <= 32) @as(u32, 1) else 2;
}, },
else => return self.todo("implement switch for type {s}", .{@tagName(cond_ty.zigTypeTag())}), // TODO: Figure out which types apply here, and work around them as we can only do integers. else => return self.todo("implement switch for type {s}", .{@tagName(cond_ty.zigTypeTag())}), // TODO: Figure out which types apply here, and work around them as we can only do integers.
}; };

View File

@ -253,7 +253,6 @@ pub fn emitType(self: *Module, ty: Type) error{OutOfMemory}!IdResultType {
const ref_id = result_id; const ref_id = result_id;
const types = &self.sections.types_globals_constants; const types = &self.sections.types_globals_constants;
const debug_names = &self.sections.debug_names; const debug_names = &self.sections.debug_names;
const annotations = &self.sections.annotations;
const result_id_operand = .{ .id_result = result_id }; const result_id_operand = .{ .id_result = result_id };
switch (ty.tag()) { switch (ty.tag()) {
@ -355,13 +354,7 @@ pub fn emitType(self: *Module, ty: Type) error{OutOfMemory}!IdResultType {
const size_type = Type.initTag(.u32); const size_type = Type.initTag(.u32);
const size_type_id = try self.resolveTypeId(size_type); const size_type_id = try self.resolveTypeId(size_type);
const length_id = try self.emitConstant(size_type_id, .{ .uint32 = info.length });
const length_id = self.allocId();
try types.emit(self.gpa, .OpConstant, .{
.id_result_type = size_type_id,
.id_result = length_id,
.value = .{ .uint32 = info.length },
});
try types.emit(self.gpa, .OpTypeArray, .{ try types.emit(self.gpa, .OpTypeArray, .{
.id_result = result_id, .id_result = result_id,
@ -369,7 +362,7 @@ pub fn emitType(self: *Module, ty: Type) error{OutOfMemory}!IdResultType {
.length = length_id, .length = length_id,
}); });
if (info.array_stride != 0) { if (info.array_stride != 0) {
try annotations.decorate(self.gpa, ref_id, .{ .ArrayStride = .{ .array_stride = info.array_stride } }); try self.decorate(ref_id, .{ .ArrayStride = .{ .array_stride = info.array_stride } });
} }
}, },
.runtime_array => { .runtime_array => {
@ -379,7 +372,7 @@ pub fn emitType(self: *Module, ty: Type) error{OutOfMemory}!IdResultType {
.element_type = self.typeResultId(ty.childType()), .element_type = self.typeResultId(ty.childType()),
}); });
if (info.array_stride != 0) { if (info.array_stride != 0) {
try annotations.decorate(self.gpa, ref_id, .{ .ArrayStride = .{ .array_stride = info.array_stride } }); try self.decorate(ref_id, .{ .ArrayStride = .{ .array_stride = info.array_stride } });
} }
}, },
.@"struct" => { .@"struct" => {
@ -403,13 +396,13 @@ pub fn emitType(self: *Module, ty: Type) error{OutOfMemory}!IdResultType {
.type = self.typeResultId(ty.childType()), .type = self.typeResultId(ty.childType()),
}); });
if (info.array_stride != 0) { if (info.array_stride != 0) {
try annotations.decorate(self.gpa, ref_id, .{ .ArrayStride = .{ .array_stride = info.array_stride } }); try self.decorate(ref_id, .{ .ArrayStride = .{ .array_stride = info.array_stride } });
} }
if (info.alignment) |alignment| { if (info.alignment) |alignment| {
try annotations.decorate(self.gpa, ref_id, .{ .Alignment = .{ .alignment = alignment } }); try self.decorate(ref_id, .{ .Alignment = .{ .alignment = alignment } });
} }
if (info.max_byte_offset) |max_byte_offset| { if (info.max_byte_offset) |max_byte_offset| {
try annotations.decorate(self.gpa, ref_id, .{ .MaxByteOffset = .{ .max_byte_offset = max_byte_offset } }); try self.decorate(ref_id, .{ .MaxByteOffset = .{ .max_byte_offset = max_byte_offset } });
} }
}, },
.function => { .function => {
@ -438,7 +431,6 @@ pub fn emitType(self: *Module, ty: Type) error{OutOfMemory}!IdResultType {
fn decorateStruct(self: *Module, target: IdRef, info: *const Type.Payload.Struct) !void { fn decorateStruct(self: *Module, target: IdRef, info: *const Type.Payload.Struct) !void {
const debug_names = &self.sections.debug_names; const debug_names = &self.sections.debug_names;
const annotations = &self.sections.annotations;
if (info.name.len != 0) { if (info.name.len != 0) {
try debug_names.emit(self.gpa, .OpName, .{ try debug_names.emit(self.gpa, .OpName, .{
@ -449,15 +441,15 @@ fn decorateStruct(self: *Module, target: IdRef, info: *const Type.Payload.Struct
// Decorations for the struct type itself. // Decorations for the struct type itself.
if (info.decorations.block) if (info.decorations.block)
try annotations.decorate(self.gpa, target, .Block); try self.decorate(target, .Block);
if (info.decorations.buffer_block) if (info.decorations.buffer_block)
try annotations.decorate(self.gpa, target, .BufferBlock); try self.decorate(target, .BufferBlock);
if (info.decorations.glsl_shared) if (info.decorations.glsl_shared)
try annotations.decorate(self.gpa, target, .GLSLShared); try self.decorate(target, .GLSLShared);
if (info.decorations.glsl_packed) if (info.decorations.glsl_packed)
try annotations.decorate(self.gpa, target, .GLSLPacked); try self.decorate(target, .GLSLPacked);
if (info.decorations.c_packed) if (info.decorations.c_packed)
try annotations.decorate(self.gpa, target, .CPacked); try self.decorate(target, .CPacked);
// Decorations for the struct members. // Decorations for the struct members.
const extra = info.member_decoration_extra; const extra = info.member_decoration_extra;
@ -476,8 +468,7 @@ fn decorateStruct(self: *Module, target: IdRef, info: *const Type.Payload.Struct
switch (member.offset) { switch (member.offset) {
.none => {}, .none => {},
else => try annotations.decorateMember( else => try self.decorateMember(
self.gpa,
target, target,
index, index,
.{ .Offset = .{ .byte_offset = @enumToInt(member.offset) } }, .{ .Offset = .{ .byte_offset = @enumToInt(member.offset) } },
@ -485,70 +476,70 @@ fn decorateStruct(self: *Module, target: IdRef, info: *const Type.Payload.Struct
} }
switch (d.matrix_layout) { switch (d.matrix_layout) {
.row_major => try annotations.decorateMember(self.gpa, target, index, .RowMajor), .row_major => try self.decorateMember(target, index, .RowMajor),
.col_major => try annotations.decorateMember(self.gpa, target, index, .ColMajor), .col_major => try self.decorateMember(target, index, .ColMajor),
.none => {}, .none => {},
} }
if (d.matrix_layout != .none) { if (d.matrix_layout != .none) {
try annotations.decorateMember(self.gpa, target, index, .{ try self.decorateMember(target, index, .{
.MatrixStride = .{ .matrix_stride = extra[extra_i] }, .MatrixStride = .{ .matrix_stride = extra[extra_i] },
}); });
extra_i += 1; extra_i += 1;
} }
if (d.no_perspective) if (d.no_perspective)
try annotations.decorateMember(self.gpa, target, index, .NoPerspective); try self.decorateMember(target, index, .NoPerspective);
if (d.flat) if (d.flat)
try annotations.decorateMember(self.gpa, target, index, .Flat); try self.decorateMember(target, index, .Flat);
if (d.patch) if (d.patch)
try annotations.decorateMember(self.gpa, target, index, .Patch); try self.decorateMember(target, index, .Patch);
if (d.centroid) if (d.centroid)
try annotations.decorateMember(self.gpa, target, index, .Centroid); try self.decorateMember(target, index, .Centroid);
if (d.sample) if (d.sample)
try annotations.decorateMember(self.gpa, target, index, .Sample); try self.decorateMember(target, index, .Sample);
if (d.invariant) if (d.invariant)
try annotations.decorateMember(self.gpa, target, index, .Invariant); try self.decorateMember(target, index, .Invariant);
if (d.@"volatile") if (d.@"volatile")
try annotations.decorateMember(self.gpa, target, index, .Volatile); try self.decorateMember(target, index, .Volatile);
if (d.coherent) if (d.coherent)
try annotations.decorateMember(self.gpa, target, index, .Coherent); try self.decorateMember(target, index, .Coherent);
if (d.non_writable) if (d.non_writable)
try annotations.decorateMember(self.gpa, target, index, .NonWritable); try self.decorateMember(target, index, .NonWritable);
if (d.non_readable) if (d.non_readable)
try annotations.decorateMember(self.gpa, target, index, .NonReadable); try self.decorateMember(target, index, .NonReadable);
if (d.builtin) { if (d.builtin) {
try annotations.decorateMember(self.gpa, target, index, .{ try self.decorateMember(target, index, .{
.BuiltIn = .{ .built_in = @intToEnum(spec.BuiltIn, extra[extra_i]) }, .BuiltIn = .{ .built_in = @intToEnum(spec.BuiltIn, extra[extra_i]) },
}); });
extra_i += 1; extra_i += 1;
} }
if (d.stream) { if (d.stream) {
try annotations.decorateMember(self.gpa, target, index, .{ try self.decorateMember(target, index, .{
.Stream = .{ .stream_number = extra[extra_i] }, .Stream = .{ .stream_number = extra[extra_i] },
}); });
extra_i += 1; extra_i += 1;
} }
if (d.location) { if (d.location) {
try annotations.decorateMember(self.gpa, target, index, .{ try self.decorateMember(target, index, .{
.Location = .{ .location = extra[extra_i] }, .Location = .{ .location = extra[extra_i] },
}); });
extra_i += 1; extra_i += 1;
} }
if (d.component) { if (d.component) {
try annotations.decorateMember(self.gpa, target, index, .{ try self.decorateMember(target, index, .{
.Component = .{ .component = extra[extra_i] }, .Component = .{ .component = extra[extra_i] },
}); });
extra_i += 1; extra_i += 1;
} }
if (d.xfb_buffer) { if (d.xfb_buffer) {
try annotations.decorateMember(self.gpa, target, index, .{ try self.decorateMember(target, index, .{
.XfbBuffer = .{ .xfb_buffer_number = extra[extra_i] }, .XfbBuffer = .{ .xfb_buffer_number = extra[extra_i] },
}); });
extra_i += 1; extra_i += 1;
} }
if (d.xfb_stride) { if (d.xfb_stride) {
try annotations.decorateMember(self.gpa, target, index, .{ try self.decorateMember(target, index, .{
.XfbStride = .{ .xfb_stride = extra[extra_i] }, .XfbStride = .{ .xfb_stride = extra[extra_i] },
}); });
extra_i += 1; extra_i += 1;
@ -557,10 +548,50 @@ fn decorateStruct(self: *Module, target: IdRef, info: *const Type.Payload.Struct
const len = extra[extra_i]; const len = extra[extra_i];
extra_i += 1; extra_i += 1;
const semantic = @ptrCast([*]const u8, &extra[extra_i])[0..len]; const semantic = @ptrCast([*]const u8, &extra[extra_i])[0..len];
try annotations.decorateMember(self.gpa, target, index, .{ try self.decorateMember(target, index, .{
.UserSemantic = .{ .semantic = semantic }, .UserSemantic = .{ .semantic = semantic },
}); });
extra_i += std.math.divCeil(u32, extra_i, @sizeOf(u32)) catch unreachable; extra_i += std.math.divCeil(u32, extra_i, @sizeOf(u32)) catch unreachable;
} }
} }
} }
pub fn emitConstant(
self: *Module,
ty_id: spec.IdRef,
value: spec.LiteralContextDependentNumber,
) !IdRef {
const result_id = self.allocId();
try self.sections.types_globals_constants.emit(self.gpa, .OpConstant, .{
.id_result_type = ty_id,
.id_result = result_id,
.value = value,
});
return result_id;
}
/// Decorate a result-id.
pub fn decorate(
self: *Module,
target: spec.IdRef,
decoration: spec.Decoration.Extended,
) !void {
try self.sections.annotations.emit(self.gpa, .OpDecorate, .{
.target = target,
.decoration = decoration,
});
}
/// Decorate a result-id which is a member of some struct.
pub fn decorateMember(
self: *Module,
structure_type: spec.IdRef,
member: u32,
decoration: spec.Decoration.Extended,
) !void {
try self.sections.annotations.emit(self.gpa, .OpMemberDecorate, .{
.structure_type = structure_type,
.member = member,
.decoration = decoration,
});
}

View File

@ -65,34 +65,6 @@ pub fn emit(
section.writeOperands(opcode.Operands(), operands); section.writeOperands(opcode.Operands(), operands);
} }
/// Decorate a result-id.
pub fn decorate(
section: *Section,
allocator: Allocator,
target: spec.IdRef,
decoration: spec.Decoration.Extended,
) !void {
try section.emit(allocator, .OpDecorate, .{
.target = target,
.decoration = decoration,
});
}
/// Decorate a result-id which is a member of some struct.
pub fn decorateMember(
section: *Section,
allocator: Allocator,
structure_type: spec.IdRef,
member: u32,
decoration: spec.Decoration.Extended,
) !void {
try section.emit(allocator, .OpMemberDecorate, .{
.structure_type = structure_type,
.member = member,
.decoration = decoration,
});
}
pub fn writeWord(section: *Section, word: Word) void { pub fn writeWord(section: *Section, word: Word) void {
section.instructions.appendAssumeCapacity(word); section.instructions.appendAssumeCapacity(word);
} }