authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2022-11-29 23:44:31+01:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-04-09 01:51:51+02:00
log8a00ec162c76ef28cbbca59a7124d7d175a77e97
treecaa6c579cb256603f8d5e08a52c0eb627c31a98b
parent700dee34d5c7bdedc678032689c761e3a417fa03
signaturelock-open Commit is signed but in an unrecognized format.

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

3 files changed, 132 insertions(+), 139 deletions(-)

src/codegen/spirv.zig+60-70
...@@ -880,7 +880,9 @@ pub const DeclGen = struct {...@@ -880,7 +880,9 @@ pub const DeclGen = struct {
880 // TODO: We probably need to have a special implementation of this for the C abi.880 // TODO: We probably need to have a special implementation of this for the C abi.
881 .ret_ptr => try self.airAlloc(inst),881 .ret_ptr => try self.airAlloc(inst),
882 .block => try self.airBlock(inst),882 .block => try self.airBlock(inst),
883
883 .load => try self.airLoad(inst),884 .load => try self.airLoad(inst),
885 .store => return self.airStore(inst),
884886
885 .br => return self.airBr(inst),887 .br => return self.airBr(inst),
886 .breakpoint => return,888 .breakpoint => return,
...@@ -891,7 +893,6 @@ pub const DeclGen = struct {...@@ -891,7 +893,6 @@ pub const DeclGen = struct {
891 .loop => return self.airLoop(inst),893 .loop => return self.airLoop(inst),
892 .ret => return self.airRet(inst),894 .ret => return self.airRet(inst),
893 .ret_load => return self.airRetLoad(inst),895 .ret_load => return self.airRetLoad(inst),
894 .store => return self.airStore(inst),
895 .switch_br => return self.airSwitchBr(inst),896 .switch_br => return self.airSwitchBr(inst),
896 .unreach => return self.airUnreach(),897 .unreach => return self.airUnreach(),
897898
...@@ -964,13 +965,8 @@ pub const DeclGen = struct {...@@ -964,13 +965,8 @@ pub const DeclGen = struct {
964 33...64 => .{ .uint64 = mask_value },965 33...64 => .{ .uint64 = mask_value },
965 else => unreachable,966 else => unreachable,
966 };967 };
967 // TODO: We should probably optimize these constants a bit.968 // TODO: We should probably optimize the amount of these constants a bit.
968 const mask_id = self.spv.allocId();969 const mask_id = try self.spv.emitConstant(ty_id, mask_lit);
969 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpConstant, .{
970 .id_result_type = ty_id,
971 .id_result = mask_id,
972 .value = mask_lit,
973 });
974 const result_id = self.spv.allocId();970 const result_id = self.spv.allocId();
975 try self.func.body.emit(self.spv.gpa, .OpBitwiseAnd, .{971 try self.func.body.emit(self.spv.gpa, .OpBitwiseAnd, .{
976 .id_result_type = ty_id,972 .id_result_type = ty_id,
...@@ -1119,13 +1115,11 @@ pub const DeclGen = struct {...@@ -1119,13 +1115,11 @@ pub const DeclGen = struct {
1119 // Finally, construct the Zig type.1115 // Finally, construct the Zig type.
1120 // Layout is result, overflow.1116 // Layout is result, overflow.
1121 const result_id = self.spv.allocId();1117 const result_id = self.spv.allocId();
1118 const constituents = [_]IdRef{ result, casted_overflow };
1122 try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{1119 try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{
1123 .id_result_type = result_type_id,1120 .id_result_type = result_type_id,
1124 .id_result = result_id,1121 .id_result = result_id,
1125 .constituents = &.{1122 .constituents = &constituents,
1126 result,
1127 casted_overflow,
1128 },
1129 });1123 });
1130 return result_id;1124 return result_id;
1131 }1125 }
...@@ -1277,11 +1271,12 @@ pub const DeclGen = struct {...@@ -1277,11 +1271,12 @@ pub const DeclGen = struct {
12771271
1278 fn extractField(self: *DeclGen, result_ty: IdResultType, object: IdRef, field: u32) !IdRef {1272 fn extractField(self: *DeclGen, result_ty: IdResultType, object: IdRef, field: u32) !IdRef {
1279 const result_id = self.spv.allocId();1273 const result_id = self.spv.allocId();
1274 const indexes = [_]u32{field};
1280 try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{1275 try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{
1281 .id_result_type = result_ty,1276 .id_result_type = result_ty,
1282 .id_result = result_id,1277 .id_result = result_id,
1283 .composite = object,1278 .composite = object,
1284 .indexes = &.{field},1279 .indexes = &indexes,
1285 });1280 });
1286 return result_id;1281 return result_id;
1287 }1282 }
...@@ -1318,11 +1313,12 @@ pub const DeclGen = struct {...@@ -1318,11 +1313,12 @@ pub const DeclGen = struct {
1318 };1313 };
13191314
1320 const result_id = self.spv.allocId();1315 const result_id = self.spv.allocId();
1316 const indexes = [_]IdRef{index};
1321 try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{1317 try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{
1322 .id_result_type = spv_ptr_ty,1318 .id_result_type = spv_ptr_ty,
1323 .id_result = result_id,1319 .id_result = result_id,
1324 .base = slice_ptr,1320 .base = slice_ptr,
1325 .indexes = &.{index},1321 .indexes = &indexes,
1326 });1322 });
1327 return result_id;1323 return result_id;
1328 }1324 }
...@@ -1335,14 +1331,13 @@ pub const DeclGen = struct {...@@ -1335,14 +1331,13 @@ pub const DeclGen = struct {
1335 const slice = try self.resolve(bin_op.lhs);1331 const slice = try self.resolve(bin_op.lhs);
1336 const index = try self.resolve(bin_op.rhs);1332 const index = try self.resolve(bin_op.rhs);
13371333
1338 const spv_elem_ty = try self.resolveTypeId(self.air.typeOfIndex(inst));
1339 var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined;1334 var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined;
1340 const spv_ptr_ty = try self.resolveTypeId(slice_ty.slicePtrFieldType(&slice_buf));1335 const ptr_ty_id = try self.resolveTypeId(slice_ty.slicePtrFieldType(&slice_buf));
13411336
1342 const slice_ptr = blk: {1337 const slice_ptr = blk: {
1343 const result_id = self.spv.allocId();1338 const result_id = self.spv.allocId();
1344 try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{1339 try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{
1345 .id_result_type = spv_ptr_ty,1340 .id_result_type = ptr_ty_id,
1346 .id_result = result_id,1341 .id_result = result_id,
1347 .composite = slice,1342 .composite = slice,
1348 .indexes = &.{0},1343 .indexes = &.{0},
...@@ -1352,22 +1347,17 @@ pub const DeclGen = struct {...@@ -1352,22 +1347,17 @@ pub const DeclGen = struct {
13521347
1353 const elem_ptr = blk: {1348 const elem_ptr = blk: {
1354 const result_id = self.spv.allocId();1349 const result_id = self.spv.allocId();
1350 const indexes = [_]IdRef{index};
1355 try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{1351 try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{
1356 .id_result_type = spv_ptr_ty,1352 .id_result_type = ptr_ty_id,
1357 .id_result = result_id,1353 .id_result = result_id,
1358 .base = slice_ptr,1354 .base = slice_ptr,
1359 .indexes = &.{index},1355 .indexes = &indexes,
1360 });1356 });
1361 break :blk result_id;1357 break :blk result_id;
1362 };1358 };
13631359
1364 const result_id = self.spv.allocId();1360 return try self.load(slice_ty, elem_ptr);
1365 try self.func.body.emit(self.spv.gpa, .OpLoad, .{
1366 .id_result_type = spv_elem_ty,
1367 .id_result = result_id,
1368 .pointer = elem_ptr,
1369 });
1370 return result_id;
1371 }1361 }
13721362
1373 fn airPtrElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {1363 fn airPtrElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
...@@ -1386,11 +1376,12 @@ pub const DeclGen = struct {...@@ -1386,11 +1376,12 @@ pub const DeclGen = struct {
1386 const rhs = try self.resolve(bin_op.rhs);1376 const rhs = try self.resolve(bin_op.rhs);
13871377
1388 const result_id = self.spv.allocId();1378 const result_id = self.spv.allocId();
1379 const indexes = [_]IdRef{rhs};
1389 try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{1380 try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{
1390 .id_result_type = result_type_id,1381 .id_result_type = result_type_id,
1391 .id_result = result_id,1382 .id_result = result_id,
1392 .base = base_ptr,1383 .base = base_ptr,
1393 .indexes = &.{rhs},1384 .indexes = &indexes,
1394 });1385 });
1395 return result_id;1386 return result_id;
1396 }1387 }
...@@ -1412,11 +1403,12 @@ pub const DeclGen = struct {...@@ -1412,11 +1403,12 @@ pub const DeclGen = struct {
1412 assert(struct_ty.zigTypeTag() == .Struct); // Cannot do unions yet.1403 assert(struct_ty.zigTypeTag() == .Struct); // Cannot do unions yet.
14131404
1414 const result_id = self.spv.allocId();1405 const result_id = self.spv.allocId();
1406 const indexes = [_]u32{field_index};
1415 try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{1407 try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{
1416 .id_result_type = field_ty_id,1408 .id_result_type = field_ty_id,
1417 .id_result = result_id,1409 .id_result = result_id,
1418 .composite = object,1410 .composite = object,
1419 .indexes = &.{field_index},1411 .indexes = &indexes,
1420 });1412 });
1421 return result_id;1413 return result_id;
1422 }1414 }
...@@ -1433,20 +1425,16 @@ pub const DeclGen = struct {...@@ -1433,20 +1425,16 @@ pub const DeclGen = struct {
1433 .Struct => switch (object_ty.containerLayout()) {1425 .Struct => switch (object_ty.containerLayout()) {
1434 .Packed => unreachable, // TODO1426 .Packed => unreachable, // TODO
1435 else => {1427 else => {
1436 const field_index_id = self.spv.allocId();
1437 const u32_ty_id = self.spv.typeResultId(try self.intType(.unsigned, 32));1428 const u32_ty_id = self.spv.typeResultId(try self.intType(.unsigned, 32));
1438 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpConstant, .{1429 const field_index_id = try self.spv.emitConstant(u32_ty_id, .{ .uint32 = field_index });
1439 .id_result_type = u32_ty_id,
1440 .id_result = field_index_id,
1441 .value = .{ .uint32 = field_index },
1442 });
1443 const result_id = self.spv.allocId();1430 const result_id = self.spv.allocId();
1444 const result_type_id = try self.resolveTypeId(result_ptr_ty);1431 const result_type_id = try self.resolveTypeId(result_ptr_ty);
1432 const indexes = [_]IdRef{field_index_id};
1445 try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{1433 try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{
1446 .id_result_type = result_type_id,1434 .id_result_type = result_type_id,
1447 .id_result = result_id,1435 .id_result = result_id,
1448 .base = object_ptr,1436 .base = object_ptr,
1449 .indexes = &.{field_index_id},1437 .indexes = &indexes,
1450 });1438 });
1451 return result_id;1439 return result_id;
1452 },1440 },
...@@ -1591,28 +1579,51 @@ pub const DeclGen = struct {...@@ -1591,28 +1579,51 @@ pub const DeclGen = struct {
1591 });1579 });
1592 }1580 }
15931581
1594 fn airLoad(self: *DeclGen, inst: Air.Inst.Index) !IdRef {1582 fn airLoad(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
1595 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1583 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1596 const operand_id = try self.resolve(ty_op.operand);1584 const ptr_ty = self.air.typeOf(ty_op.operand);
1597 const ty = self.air.typeOfIndex(inst);1585 const operand = try self.resolve(ty_op.operand);
1586 if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null;
15981587
1599 const result_type_id = try self.resolveTypeId(ty);1588 return try self.load(ptr_ty, operand);
1600 const result_id = self.spv.allocId();1589 }
16011590
1591 fn load(self: *DeclGen, ptr_ty: Type, ptr: IdRef) !IdRef {
1592 const value_ty = ptr_ty.childType();
1593 const result_type_id = try self.resolveTypeId(value_ty);
1594 const result_id = self.spv.allocId();
1602 const access = spec.MemoryAccess.Extended{1595 const access = spec.MemoryAccess.Extended{
1603 .Volatile = ty.isVolatilePtr(),1596 .Volatile = ptr_ty.isVolatilePtr(),
1604 };1597 };
1605
1606 try self.func.body.emit(self.spv.gpa, .OpLoad, .{1598 try self.func.body.emit(self.spv.gpa, .OpLoad, .{
1607 .id_result_type = result_type_id,1599 .id_result_type = result_type_id,
1608 .id_result = result_id,1600 .id_result = result_id,
1609 .pointer = operand_id,1601 .pointer = ptr,
1610 .memory_access = access,1602 .memory_access = access,
1611 });1603 });
1612
1613 return result_id;1604 return result_id;
1614 }1605 }
16151606
1607 fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void {
1608 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1609 const ptr_ty = self.air.typeOf(bin_op.lhs);
1610 const ptr = try self.resolve(bin_op.lhs);
1611 const value = try self.resolve(bin_op.rhs);
1612
1613 try self.store(ptr_ty, ptr, value);
1614 }
1615
1616 fn store(self: *DeclGen, ptr_ty: Type, ptr: IdRef, value: IdRef) !void {
1617 const access = spec.MemoryAccess.Extended{
1618 .Volatile = ptr_ty.isVolatilePtr(),
1619 };
1620 try self.func.body.emit(self.spv.gpa, .OpStore, .{
1621 .pointer = ptr,
1622 .object = value,
1623 .memory_access = access,
1624 });
1625 }
1626
1616 fn airLoop(self: *DeclGen, inst: Air.Inst.Index) !void {1627 fn airLoop(self: *DeclGen, inst: Air.Inst.Index) !void {
1617 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;1628 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
1618 const loop = self.air.extraData(Air.Block, ty_pl.payload);1629 const loop = self.air.extraData(Air.Block, ty_pl.payload);
...@@ -1644,7 +1655,6 @@ pub const DeclGen = struct {...@@ -1644,7 +1655,6 @@ pub const DeclGen = struct {
1644 const un_op = self.air.instructions.items(.data)[inst].un_op;1655 const un_op = self.air.instructions.items(.data)[inst].un_op;
1645 const ptr_ty = self.air.typeOf(un_op);1656 const ptr_ty = self.air.typeOf(un_op);
1646 const ret_ty = ptr_ty.childType();1657 const ret_ty = ptr_ty.childType();
1647 const ret_ty_id = try self.resolveTypeId(ret_ty);
16481658
1649 if (!ret_ty.hasRuntimeBitsIgnoreComptime()) {1659 if (!ret_ty.hasRuntimeBitsIgnoreComptime()) {
1650 try self.func.body.emit(self.spv.gpa, .OpReturn, {});1660 try self.func.body.emit(self.spv.gpa, .OpReturn, {});
...@@ -1652,29 +1662,9 @@ pub const DeclGen = struct {...@@ -1652,29 +1662,9 @@ pub const DeclGen = struct {
1652 }1662 }
16531663
1654 const ptr = try self.resolve(un_op);1664 const ptr = try self.resolve(un_op);
1655 const result_id = self.spv.allocId();1665 const value = try self.load(ptr_ty, ptr);
1656 try self.func.body.emit(self.spv.gpa, .OpLoad, .{1666 try self.func.body.emit(self.spv.gpa, .OpReturnValue, .{
1657 .id_result_type = ret_ty_id,1667 .value = value,
1658 .id_result = result_id,
1659 .pointer = ptr,
1660 });
1661 try self.func.body.emit(self.spv.gpa, .OpReturnValue, .{ .value = result_id });
1662 }
1663
1664 fn airStore(self: *DeclGen, inst: Air.Inst.Index) !void {
1665 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
1666 const dst_ptr_id = try self.resolve(bin_op.lhs);
1667 const src_val_id = try self.resolve(bin_op.rhs);
1668 const lhs_ty = self.air.typeOf(bin_op.lhs);
1669
1670 const access = spec.MemoryAccess.Extended{
1671 .Volatile = lhs_ty.isVolatilePtr(),
1672 };
1673
1674 try self.func.body.emit(self.spv.gpa, .OpStore, .{
1675 .pointer = dst_ptr_id,
1676 .object = src_val_id,
1677 .memory_access = access,
1678 });1668 });
1679 }1669 }
16801670
...@@ -1691,7 +1681,7 @@ pub const DeclGen = struct {...@@ -1691,7 +1681,7 @@ pub const DeclGen = struct {
1691 const backing_bits = self.backingIntBits(bits) orelse {1681 const backing_bits = self.backingIntBits(bits) orelse {
1692 return self.todo("implement composite int switch", .{});1682 return self.todo("implement composite int switch", .{});
1693 };1683 };
1694 break :blk if (backing_bits <= 32) 1 else 2;1684 break :blk if (backing_bits <= 32) @as(u32, 1) else 2;
1695 },1685 },
1696 .Enum => blk: {1686 .Enum => blk: {
1697 var buffer: Type.Payload.Bits = undefined;1687 var buffer: Type.Payload.Bits = undefined;
...@@ -1700,7 +1690,7 @@ pub const DeclGen = struct {...@@ -1700,7 +1690,7 @@ pub const DeclGen = struct {
1700 const backing_bits = self.backingIntBits(int_info.bits) orelse {1690 const backing_bits = self.backingIntBits(int_info.bits) orelse {
1701 return self.todo("implement composite int switch", .{});1691 return self.todo("implement composite int switch", .{});
1702 };1692 };
1703 break :blk if (backing_bits <= 32) 1 else 2;1693 break :blk if (backing_bits <= 32) @as(u32, 1) else 2;
1704 },1694 },
1705 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.1695 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.
1706 };1696 };
src/codegen/spirv/Module.zig+72-41
...@@ -253,7 +253,6 @@ pub fn emitType(self: *Module, ty: Type) error{OutOfMemory}!IdResultType {...@@ -253,7 +253,6 @@ pub fn emitType(self: *Module, ty: Type) error{OutOfMemory}!IdResultType {
253 const ref_id = result_id;253 const ref_id = result_id;
254 const types = &self.sections.types_globals_constants;254 const types = &self.sections.types_globals_constants;
255 const debug_names = &self.sections.debug_names;255 const debug_names = &self.sections.debug_names;
256 const annotations = &self.sections.annotations;
257 const result_id_operand = .{ .id_result = result_id };256 const result_id_operand = .{ .id_result = result_id };
258257
259 switch (ty.tag()) {258 switch (ty.tag()) {
...@@ -355,13 +354,7 @@ pub fn emitType(self: *Module, ty: Type) error{OutOfMemory}!IdResultType {...@@ -355,13 +354,7 @@ pub fn emitType(self: *Module, ty: Type) error{OutOfMemory}!IdResultType {
355354
356 const size_type = Type.initTag(.u32);355 const size_type = Type.initTag(.u32);
357 const size_type_id = try self.resolveTypeId(size_type);356 const size_type_id = try self.resolveTypeId(size_type);
358357 const length_id = try self.emitConstant(size_type_id, .{ .uint32 = info.length });
359 const length_id = self.allocId();
360 try types.emit(self.gpa, .OpConstant, .{
361 .id_result_type = size_type_id,
362 .id_result = length_id,
363 .value = .{ .uint32 = info.length },
364 });
365358
366 try types.emit(self.gpa, .OpTypeArray, .{359 try types.emit(self.gpa, .OpTypeArray, .{
367 .id_result = result_id,360 .id_result = result_id,
...@@ -369,7 +362,7 @@ pub fn emitType(self: *Module, ty: Type) error{OutOfMemory}!IdResultType {...@@ -369,7 +362,7 @@ pub fn emitType(self: *Module, ty: Type) error{OutOfMemory}!IdResultType {
369 .length = length_id,362 .length = length_id,
370 });363 });
371 if (info.array_stride != 0) {364 if (info.array_stride != 0) {
372 try annotations.decorate(self.gpa, ref_id, .{ .ArrayStride = .{ .array_stride = info.array_stride } });365 try self.decorate(ref_id, .{ .ArrayStride = .{ .array_stride = info.array_stride } });
373 }366 }
374 },367 },
375 .runtime_array => {368 .runtime_array => {
...@@ -379,7 +372,7 @@ pub fn emitType(self: *Module, ty: Type) error{OutOfMemory}!IdResultType {...@@ -379,7 +372,7 @@ pub fn emitType(self: *Module, ty: Type) error{OutOfMemory}!IdResultType {
379 .element_type = self.typeResultId(ty.childType()),372 .element_type = self.typeResultId(ty.childType()),
380 });373 });
381 if (info.array_stride != 0) {374 if (info.array_stride != 0) {
382 try annotations.decorate(self.gpa, ref_id, .{ .ArrayStride = .{ .array_stride = info.array_stride } });375 try self.decorate(ref_id, .{ .ArrayStride = .{ .array_stride = info.array_stride } });
383 }376 }
384 },377 },
385 .@"struct" => {378 .@"struct" => {
...@@ -403,13 +396,13 @@ pub fn emitType(self: *Module, ty: Type) error{OutOfMemory}!IdResultType {...@@ -403,13 +396,13 @@ pub fn emitType(self: *Module, ty: Type) error{OutOfMemory}!IdResultType {
403 .type = self.typeResultId(ty.childType()),396 .type = self.typeResultId(ty.childType()),
404 });397 });
405 if (info.array_stride != 0) {398 if (info.array_stride != 0) {
406 try annotations.decorate(self.gpa, ref_id, .{ .ArrayStride = .{ .array_stride = info.array_stride } });399 try self.decorate(ref_id, .{ .ArrayStride = .{ .array_stride = info.array_stride } });
407 }400 }
408 if (info.alignment) |alignment| {401 if (info.alignment) |alignment| {
409 try annotations.decorate(self.gpa, ref_id, .{ .Alignment = .{ .alignment = alignment } });402 try self.decorate(ref_id, .{ .Alignment = .{ .alignment = alignment } });
410 }403 }
411 if (info.max_byte_offset) |max_byte_offset| {404 if (info.max_byte_offset) |max_byte_offset| {
412 try annotations.decorate(self.gpa, ref_id, .{ .MaxByteOffset = .{ .max_byte_offset = max_byte_offset } });405 try self.decorate(ref_id, .{ .MaxByteOffset = .{ .max_byte_offset = max_byte_offset } });
413 }406 }
414 },407 },
415 .function => {408 .function => {
...@@ -438,7 +431,6 @@ pub fn emitType(self: *Module, ty: Type) error{OutOfMemory}!IdResultType {...@@ -438,7 +431,6 @@ pub fn emitType(self: *Module, ty: Type) error{OutOfMemory}!IdResultType {
438431
439fn decorateStruct(self: *Module, target: IdRef, info: *const Type.Payload.Struct) !void {432fn decorateStruct(self: *Module, target: IdRef, info: *const Type.Payload.Struct) !void {
440 const debug_names = &self.sections.debug_names;433 const debug_names = &self.sections.debug_names;
441 const annotations = &self.sections.annotations;
442434
443 if (info.name.len != 0) {435 if (info.name.len != 0) {
444 try debug_names.emit(self.gpa, .OpName, .{436 try debug_names.emit(self.gpa, .OpName, .{
...@@ -449,15 +441,15 @@ fn decorateStruct(self: *Module, target: IdRef, info: *const Type.Payload.Struct...@@ -449,15 +441,15 @@ fn decorateStruct(self: *Module, target: IdRef, info: *const Type.Payload.Struct
449441
450 // Decorations for the struct type itself.442 // Decorations for the struct type itself.
451 if (info.decorations.block)443 if (info.decorations.block)
452 try annotations.decorate(self.gpa, target, .Block);444 try self.decorate(target, .Block);
453 if (info.decorations.buffer_block)445 if (info.decorations.buffer_block)
454 try annotations.decorate(self.gpa, target, .BufferBlock);446 try self.decorate(target, .BufferBlock);
455 if (info.decorations.glsl_shared)447 if (info.decorations.glsl_shared)
456 try annotations.decorate(self.gpa, target, .GLSLShared);448 try self.decorate(target, .GLSLShared);
457 if (info.decorations.glsl_packed)449 if (info.decorations.glsl_packed)
458 try annotations.decorate(self.gpa, target, .GLSLPacked);450 try self.decorate(target, .GLSLPacked);
459 if (info.decorations.c_packed)451 if (info.decorations.c_packed)
460 try annotations.decorate(self.gpa, target, .CPacked);452 try self.decorate(target, .CPacked);
461453
462 // Decorations for the struct members.454 // Decorations for the struct members.
463 const extra = info.member_decoration_extra;455 const extra = info.member_decoration_extra;
...@@ -476,8 +468,7 @@ fn decorateStruct(self: *Module, target: IdRef, info: *const Type.Payload.Struct...@@ -476,8 +468,7 @@ fn decorateStruct(self: *Module, target: IdRef, info: *const Type.Payload.Struct
476468
477 switch (member.offset) {469 switch (member.offset) {
478 .none => {},470 .none => {},
479 else => try annotations.decorateMember(471 else => try self.decorateMember(
480 self.gpa,
481 target,472 target,
482 index,473 index,
483 .{ .Offset = .{ .byte_offset = @enumToInt(member.offset) } },474 .{ .Offset = .{ .byte_offset = @enumToInt(member.offset) } },
...@@ -485,70 +476,70 @@ fn decorateStruct(self: *Module, target: IdRef, info: *const Type.Payload.Struct...@@ -485,70 +476,70 @@ fn decorateStruct(self: *Module, target: IdRef, info: *const Type.Payload.Struct
485 }476 }
486477
487 switch (d.matrix_layout) {478 switch (d.matrix_layout) {
488 .row_major => try annotations.decorateMember(self.gpa, target, index, .RowMajor),479 .row_major => try self.decorateMember(target, index, .RowMajor),
489 .col_major => try annotations.decorateMember(self.gpa, target, index, .ColMajor),480 .col_major => try self.decorateMember(target, index, .ColMajor),
490 .none => {},481 .none => {},
491 }482 }
492 if (d.matrix_layout != .none) {483 if (d.matrix_layout != .none) {
493 try annotations.decorateMember(self.gpa, target, index, .{484 try self.decorateMember(target, index, .{
494 .MatrixStride = .{ .matrix_stride = extra[extra_i] },485 .MatrixStride = .{ .matrix_stride = extra[extra_i] },
495 });486 });
496 extra_i += 1;487 extra_i += 1;
497 }488 }
498489
499 if (d.no_perspective)490 if (d.no_perspective)
500 try annotations.decorateMember(self.gpa, target, index, .NoPerspective);491 try self.decorateMember(target, index, .NoPerspective);
501 if (d.flat)492 if (d.flat)
502 try annotations.decorateMember(self.gpa, target, index, .Flat);493 try self.decorateMember(target, index, .Flat);
503 if (d.patch)494 if (d.patch)
504 try annotations.decorateMember(self.gpa, target, index, .Patch);495 try self.decorateMember(target, index, .Patch);
505 if (d.centroid)496 if (d.centroid)
506 try annotations.decorateMember(self.gpa, target, index, .Centroid);497 try self.decorateMember(target, index, .Centroid);
507 if (d.sample)498 if (d.sample)
508 try annotations.decorateMember(self.gpa, target, index, .Sample);499 try self.decorateMember(target, index, .Sample);
509 if (d.invariant)500 if (d.invariant)
510 try annotations.decorateMember(self.gpa, target, index, .Invariant);501 try self.decorateMember(target, index, .Invariant);
511 if (d.@"volatile")502 if (d.@"volatile")
512 try annotations.decorateMember(self.gpa, target, index, .Volatile);503 try self.decorateMember(target, index, .Volatile);
513 if (d.coherent)504 if (d.coherent)
514 try annotations.decorateMember(self.gpa, target, index, .Coherent);505 try self.decorateMember(target, index, .Coherent);
515 if (d.non_writable)506 if (d.non_writable)
516 try annotations.decorateMember(self.gpa, target, index, .NonWritable);507 try self.decorateMember(target, index, .NonWritable);
517 if (d.non_readable)508 if (d.non_readable)
518 try annotations.decorateMember(self.gpa, target, index, .NonReadable);509 try self.decorateMember(target, index, .NonReadable);
519510
520 if (d.builtin) {511 if (d.builtin) {
521 try annotations.decorateMember(self.gpa, target, index, .{512 try self.decorateMember(target, index, .{
522 .BuiltIn = .{ .built_in = @intToEnum(spec.BuiltIn, extra[extra_i]) },513 .BuiltIn = .{ .built_in = @intToEnum(spec.BuiltIn, extra[extra_i]) },
523 });514 });
524 extra_i += 1;515 extra_i += 1;
525 }516 }
526 if (d.stream) {517 if (d.stream) {
527 try annotations.decorateMember(self.gpa, target, index, .{518 try self.decorateMember(target, index, .{
528 .Stream = .{ .stream_number = extra[extra_i] },519 .Stream = .{ .stream_number = extra[extra_i] },
529 });520 });
530 extra_i += 1;521 extra_i += 1;
531 }522 }
532 if (d.location) {523 if (d.location) {
533 try annotations.decorateMember(self.gpa, target, index, .{524 try self.decorateMember(target, index, .{
534 .Location = .{ .location = extra[extra_i] },525 .Location = .{ .location = extra[extra_i] },
535 });526 });
536 extra_i += 1;527 extra_i += 1;
537 }528 }
538 if (d.component) {529 if (d.component) {
539 try annotations.decorateMember(self.gpa, target, index, .{530 try self.decorateMember(target, index, .{
540 .Component = .{ .component = extra[extra_i] },531 .Component = .{ .component = extra[extra_i] },
541 });532 });
542 extra_i += 1;533 extra_i += 1;
543 }534 }
544 if (d.xfb_buffer) {535 if (d.xfb_buffer) {
545 try annotations.decorateMember(self.gpa, target, index, .{536 try self.decorateMember(target, index, .{
546 .XfbBuffer = .{ .xfb_buffer_number = extra[extra_i] },537 .XfbBuffer = .{ .xfb_buffer_number = extra[extra_i] },
547 });538 });
548 extra_i += 1;539 extra_i += 1;
549 }540 }
550 if (d.xfb_stride) {541 if (d.xfb_stride) {
551 try annotations.decorateMember(self.gpa, target, index, .{542 try self.decorateMember(target, index, .{
552 .XfbStride = .{ .xfb_stride = extra[extra_i] },543 .XfbStride = .{ .xfb_stride = extra[extra_i] },
553 });544 });
554 extra_i += 1;545 extra_i += 1;
...@@ -557,10 +548,50 @@ fn decorateStruct(self: *Module, target: IdRef, info: *const Type.Payload.Struct...@@ -557,10 +548,50 @@ fn decorateStruct(self: *Module, target: IdRef, info: *const Type.Payload.Struct
557 const len = extra[extra_i];548 const len = extra[extra_i];
558 extra_i += 1;549 extra_i += 1;
559 const semantic = @ptrCast([*]const u8, &extra[extra_i])[0..len];550 const semantic = @ptrCast([*]const u8, &extra[extra_i])[0..len];
560 try annotations.decorateMember(self.gpa, target, index, .{551 try self.decorateMember(target, index, .{
561 .UserSemantic = .{ .semantic = semantic },552 .UserSemantic = .{ .semantic = semantic },
562 });553 });
563 extra_i += std.math.divCeil(u32, extra_i, @sizeOf(u32)) catch unreachable;554 extra_i += std.math.divCeil(u32, extra_i, @sizeOf(u32)) catch unreachable;
564 }555 }
565 }556 }
566}557}
558
559pub fn emitConstant(
560 self: *Module,
561 ty_id: spec.IdRef,
562 value: spec.LiteralContextDependentNumber,
563) !IdRef {
564 const result_id = self.allocId();
565 try self.sections.types_globals_constants.emit(self.gpa, .OpConstant, .{
566 .id_result_type = ty_id,
567 .id_result = result_id,
568 .value = value,
569 });
570 return result_id;
571}
572
573/// Decorate a result-id.
574pub fn decorate(
575 self: *Module,
576 target: spec.IdRef,
577 decoration: spec.Decoration.Extended,
578) !void {
579 try self.sections.annotations.emit(self.gpa, .OpDecorate, .{
580 .target = target,
581 .decoration = decoration,
582 });
583}
584
585/// Decorate a result-id which is a member of some struct.
586pub fn decorateMember(
587 self: *Module,
588 structure_type: spec.IdRef,
589 member: u32,
590 decoration: spec.Decoration.Extended,
591) !void {
592 try self.sections.annotations.emit(self.gpa, .OpMemberDecorate, .{
593 .structure_type = structure_type,
594 .member = member,
595 .decoration = decoration,
596 });
597}
src/codegen/spirv/Section.zig-28
...@@ -65,34 +65,6 @@ pub fn emit(...@@ -65,34 +65,6 @@ pub fn emit(
65 section.writeOperands(opcode.Operands(), operands);65 section.writeOperands(opcode.Operands(), operands);
66}66}
6767
68/// Decorate a result-id.
69pub fn decorate(
70 section: *Section,
71 allocator: Allocator,
72 target: spec.IdRef,
73 decoration: spec.Decoration.Extended,
74) !void {
75 try section.emit(allocator, .OpDecorate, .{
76 .target = target,
77 .decoration = decoration,
78 });
79}
80
81/// Decorate a result-id which is a member of some struct.
82pub fn decorateMember(
83 section: *Section,
84 allocator: Allocator,
85 structure_type: spec.IdRef,
86 member: u32,
87 decoration: spec.Decoration.Extended,
88) !void {
89 try section.emit(allocator, .OpMemberDecorate, .{
90 .structure_type = structure_type,
91 .member = member,
92 .decoration = decoration,
93 });
94}
95
96pub fn writeWord(section: *Section, word: Word) void {68pub fn writeWord(section: *Section, word: Word) void {
97 section.instructions.appendAssumeCapacity(word);69 section.instructions.appendAssumeCapacity(word);
98}70}