| ... | @@ -176,10 +176,10 @@ pub const Object = struct { | ... | @@ -176,10 +176,10 @@ pub const Object = struct { |
| 176 | push_constant_ptr: SpvModule.Decl.Index, | 176 | push_constant_ptr: SpvModule.Decl.Index, |
| 177 | } = null, | 177 | } = null, |
| 178 | | 178 | |
| 179 | pub fn init(gpa: Allocator) Object { | 179 | pub fn init(gpa: Allocator, target: std.Target) Object { |
| 180 | return .{ | 180 | return .{ |
| 181 | .gpa = gpa, | 181 | .gpa = gpa, |
| 182 | .spv = SpvModule.init(gpa), | 182 | .spv = SpvModule.init(gpa, target), |
| 183 | }; | 183 | }; |
| 184 | } | 184 | } |
| 185 | | 185 | |
| ... | @@ -412,11 +412,6 @@ const NavGen = struct { | ... | @@ -412,11 +412,6 @@ const NavGen = struct { |
| 412 | self.func.deinit(self.gpa); | 412 | self.func.deinit(self.gpa); |
| 413 | } | 413 | } |
| 414 | | 414 | |
| 415 | /// Return the target which we are currently compiling for. | | |
| 416 | pub fn getTarget(self: *NavGen) std.Target { | | |
| 417 | return self.pt.zcu.getTarget(); | | |
| 418 | } | | |
| 419 | | | |
| 420 | pub fn fail(self: *NavGen, comptime format: []const u8, args: anytype) Error { | 415 | pub fn fail(self: *NavGen, comptime format: []const u8, args: anytype) Error { |
| 421 | @branchHint(.cold); | 416 | @branchHint(.cold); |
| 422 | const zcu = self.pt.zcu; | 417 | const zcu = self.pt.zcu; |
| ... | @@ -431,12 +426,12 @@ const NavGen = struct { | ... | @@ -431,12 +426,12 @@ const NavGen = struct { |
| 431 | } | 426 | } |
| 432 | | 427 | |
| 433 | /// This imports the "default" extended instruction set for the target | 428 | /// This imports the "default" extended instruction set for the target |
| 434 | /// For OpenCL, OpenCL.std.100. For Vulkan, GLSL.std.450. | 429 | /// For OpenCL, OpenCL.std.100. For Vulkan and OpenGL, GLSL.std.450. |
| 435 | fn importExtendedSet(self: *NavGen) !IdResult { | 430 | fn importExtendedSet(self: *NavGen) !IdResult { |
| 436 | const target = self.getTarget(); | 431 | const target = self.spv.target; |
| 437 | return switch (target.os.tag) { | 432 | return switch (target.os.tag) { |
| 438 | .opencl => try self.spv.importInstructionSet(.@"OpenCL.std"), | 433 | .opencl => try self.spv.importInstructionSet(.@"OpenCL.std"), |
| 439 | .vulkan => try self.spv.importInstructionSet(.@"GLSL.std.450"), | 434 | .vulkan, .opengl => try self.spv.importInstructionSet(.@"GLSL.std.450"), |
| 440 | else => unreachable, | 435 | else => unreachable, |
| 441 | }; | 436 | }; |
| 442 | } | 437 | } |
| ... | @@ -546,14 +541,10 @@ const NavGen = struct { | ... | @@ -546,14 +541,10 @@ const NavGen = struct { |
| 546 | } | 541 | } |
| 547 | | 542 | |
| 548 | fn addFunctionDep(self: *NavGen, decl_index: SpvModule.Decl.Index, storage_class: StorageClass) !void { | 543 | fn addFunctionDep(self: *NavGen, decl_index: SpvModule.Decl.Index, storage_class: StorageClass) !void { |
| 549 | const target = self.getTarget(); | 544 | if (self.spv.version.minor < 4) { |
| 550 | if (target.os.tag == .vulkan) { | 545 | // Before version 1.4, the interface’s storage classes are limited to the Input and Output |
| 551 | // Shader entry point dependencies must be variables with Input or Output storage class | 546 | if (storage_class == .Input or storage_class == .Output) { |
| 552 | switch (storage_class) { | 547 | try self.func.decl_deps.put(self.spv.gpa, decl_index, {}); |
| 553 | .Input, .Output => { | | |
| 554 | try self.func.decl_deps.put(self.spv.gpa, decl_index, {}); | | |
| 555 | }, | | |
| 556 | else => {}, | | |
| 557 | } | 548 | } |
| 558 | } else { | 549 | } else { |
| 559 | try self.func.decl_deps.put(self.spv.gpa, decl_index, {}); | 550 | try self.func.decl_deps.put(self.spv.gpa, decl_index, {}); |
| ... | @@ -561,11 +552,7 @@ const NavGen = struct { | ... | @@ -561,11 +552,7 @@ const NavGen = struct { |
| 561 | } | 552 | } |
| 562 | | 553 | |
| 563 | fn castToGeneric(self: *NavGen, type_id: IdRef, ptr_id: IdRef) !IdRef { | 554 | fn castToGeneric(self: *NavGen, type_id: IdRef, ptr_id: IdRef) !IdRef { |
| 564 | const target = self.getTarget(); | 555 | if (self.spv.hasFeature(.Kernel)) { |
| 565 | | | |
| 566 | if (target.os.tag == .vulkan) { | | |
| 567 | return ptr_id; | | |
| 568 | } else { | | |
| 569 | const result_id = self.spv.allocId(); | 556 | const result_id = self.spv.allocId(); |
| 570 | try self.func.body.emit(self.spv.gpa, .OpPtrCastToGeneric, .{ | 557 | try self.func.body.emit(self.spv.gpa, .OpPtrCastToGeneric, .{ |
| 571 | .id_result_type = type_id, | 558 | .id_result_type = type_id, |
| ... | @@ -574,6 +561,8 @@ const NavGen = struct { | ... | @@ -574,6 +561,8 @@ const NavGen = struct { |
| 574 | }); | 561 | }); |
| 575 | return result_id; | 562 | return result_id; |
| 576 | } | 563 | } |
| | 564 | |
| | 565 | return ptr_id; |
| 577 | } | 566 | } |
| 578 | | 567 | |
| 579 | /// Start a new SPIR-V block, Emits the label of the new block, and stores which | 568 | /// Start a new SPIR-V block, Emits the label of the new block, and stores which |
| ... | @@ -596,8 +585,6 @@ const NavGen = struct { | ... | @@ -596,8 +585,6 @@ const NavGen = struct { |
| 596 | /// TODO: This probably needs an ABI-version as well (especially in combination with SPV_INTEL_arbitrary_precision_integers). | 585 | /// TODO: This probably needs an ABI-version as well (especially in combination with SPV_INTEL_arbitrary_precision_integers). |
| 597 | /// TODO: Should the result of this function be cached? | 586 | /// TODO: Should the result of this function be cached? |
| 598 | fn backingIntBits(self: *NavGen, bits: u16) ?u16 { | 587 | fn backingIntBits(self: *NavGen, bits: u16) ?u16 { |
| 599 | const target = self.getTarget(); | | |
| 600 | | | |
| 601 | // The backend will never be asked to compiler a 0-bit integer, so we won't have to handle those in this function. | 588 | // The backend will never be asked to compiler a 0-bit integer, so we won't have to handle those in this function. |
| 602 | assert(bits != 0); | 589 | assert(bits != 0); |
| 603 | | 590 | |
| ... | @@ -611,14 +598,8 @@ const NavGen = struct { | ... | @@ -611,14 +598,8 @@ const NavGen = struct { |
| 611 | }; | 598 | }; |
| 612 | | 599 | |
| 613 | for (ints) |int| { | 600 | for (ints) |int| { |
| 614 | const has_feature = if (int.feature) |feature| | 601 | const has_feature = if (int.feature) |feature| self.spv.hasFeature(feature) else true; |
| 615 | Target.spirv.featureSetHas(target.cpu.features, feature) | 602 | if (bits <= int.bits and has_feature) return int.bits; |
| 616 | else | | |
| 617 | true; | | |
| 618 | | | |
| 619 | if (bits <= int.bits and has_feature) { | | |
| 620 | return int.bits; | | |
| 621 | } | | |
| 622 | } | 603 | } |
| 623 | | 604 | |
| 624 | return null; | 605 | return null; |
| ... | @@ -631,11 +612,7 @@ const NavGen = struct { | ... | @@ -631,11 +612,7 @@ const NavGen = struct { |
| 631 | /// is no way of knowing whether those are actually supported. | 612 | /// is no way of knowing whether those are actually supported. |
| 632 | /// TODO: Maybe this should be cached? | 613 | /// TODO: Maybe this should be cached? |
| 633 | fn largestSupportedIntBits(self: *NavGen) u16 { | 614 | fn largestSupportedIntBits(self: *NavGen) u16 { |
| 634 | const target = self.getTarget(); | 615 | return if (self.spv.hasFeature(.Int64)) 64 else 32; |
| 635 | return if (Target.spirv.featureSetHas(target.cpu.features, .Int64)) | | |
| 636 | 64 | | |
| 637 | else | | |
| 638 | 32; | | |
| 639 | } | 616 | } |
| 640 | | 617 | |
| 641 | /// Checks whether the type is "composite int", an integer consisting of multiple native integers. These are represented by | 618 | /// Checks whether the type is "composite int", an integer consisting of multiple native integers. These are represented by |
| ... | @@ -648,7 +625,6 @@ const NavGen = struct { | ... | @@ -648,7 +625,6 @@ const NavGen = struct { |
| 648 | /// Checks whether the type can be directly translated to SPIR-V vectors | 625 | /// Checks whether the type can be directly translated to SPIR-V vectors |
| 649 | fn isSpvVector(self: *NavGen, ty: Type) bool { | 626 | fn isSpvVector(self: *NavGen, ty: Type) bool { |
| 650 | const zcu = self.pt.zcu; | 627 | const zcu = self.pt.zcu; |
| 651 | const target = self.getTarget(); | | |
| 652 | if (ty.zigTypeTag(zcu) != .vector) return false; | 628 | if (ty.zigTypeTag(zcu) != .vector) return false; |
| 653 | | 629 | |
| 654 | // TODO: This check must be expanded for types that can be represented | 630 | // TODO: This check must be expanded for types that can be represented |
| ... | @@ -664,17 +640,19 @@ const NavGen = struct { | ... | @@ -664,17 +640,19 @@ const NavGen = struct { |
| 664 | } | 640 | } |
| 665 | | 641 | |
| 666 | const elem_ty = ty.childType(zcu); | 642 | const elem_ty = ty.childType(zcu); |
| 667 | | | |
| 668 | const len = ty.vectorLen(zcu); | 643 | const len = ty.vectorLen(zcu); |
| 669 | const is_scalar = elem_ty.isNumeric(zcu) or elem_ty.toIntern() == .bool_type; | 644 | |
| 670 | const spirv_len = len > 1 and len <= 4; | 645 | if (elem_ty.isNumeric(zcu) or elem_ty.toIntern() == .bool_type) { |
| 671 | const opencl_len = if (target.os.tag == .opencl) (len == 8 or len == 16) else false; | 646 | if (len > 1 and len <= 4) return true; |
| 672 | return is_scalar and (spirv_len or opencl_len); | 647 | if (self.spv.hasFeature(.Vector16)) return (len == 8 or len == 16); |
| | 648 | } |
| | 649 | |
| | 650 | return false; |
| 673 | } | 651 | } |
| 674 | | 652 | |
| 675 | fn arithmeticTypeInfo(self: *NavGen, ty: Type) ArithmeticTypeInfo { | 653 | fn arithmeticTypeInfo(self: *NavGen, ty: Type) ArithmeticTypeInfo { |
| 676 | const zcu = self.pt.zcu; | 654 | const zcu = self.pt.zcu; |
| 677 | const target = self.getTarget(); | 655 | const target = self.spv.target; |
| 678 | var scalar_ty = ty.scalarType(zcu); | 656 | var scalar_ty = ty.scalarType(zcu); |
| 679 | if (scalar_ty.zigTypeTag(zcu) == .@"enum") { | 657 | if (scalar_ty.zigTypeTag(zcu) == .@"enum") { |
| 680 | scalar_ty = scalar_ty.intTagType(zcu); | 658 | scalar_ty = scalar_ty.intTagType(zcu); |
| ... | @@ -791,7 +769,7 @@ const NavGen = struct { | ... | @@ -791,7 +769,7 @@ const NavGen = struct { |
| 791 | /// ty must be an aggregate type. | 769 | /// ty must be an aggregate type. |
| 792 | fn constructCompositeSplat(self: *NavGen, ty: Type, constituent: IdRef) !IdRef { | 770 | fn constructCompositeSplat(self: *NavGen, ty: Type, constituent: IdRef) !IdRef { |
| 793 | const zcu = self.pt.zcu; | 771 | const zcu = self.pt.zcu; |
| 794 | const n = ty.arrayLen(zcu); | 772 | const n: usize = @intCast(ty.arrayLen(zcu)); |
| 795 | | 773 | |
| 796 | const constituents = try self.gpa.alloc(IdRef, n); | 774 | const constituents = try self.gpa.alloc(IdRef, n); |
| 797 | defer self.gpa.free(constituents); | 775 | defer self.gpa.free(constituents); |
| ... | @@ -817,7 +795,7 @@ const NavGen = struct { | ... | @@ -817,7 +795,7 @@ const NavGen = struct { |
| 817 | | 795 | |
| 818 | const pt = self.pt; | 796 | const pt = self.pt; |
| 819 | const zcu = pt.zcu; | 797 | const zcu = pt.zcu; |
| 820 | const target = self.getTarget(); | 798 | const target = self.spv.target; |
| 821 | const result_ty_id = try self.resolveType(ty, repr); | 799 | const result_ty_id = try self.resolveType(ty, repr); |
| 822 | const ip = &zcu.intern_pool; | 800 | const ip = &zcu.intern_pool; |
| 823 | | 801 | |
| ... | @@ -1263,11 +1241,11 @@ const NavGen = struct { | ... | @@ -1263,11 +1241,11 @@ const NavGen = struct { |
| 1263 | }; | 1241 | }; |
| 1264 | | 1242 | |
| 1265 | // Kernel only supports unsigned ints. | 1243 | // Kernel only supports unsigned ints. |
| 1266 | if (self.getTarget().os.tag == .vulkan) { | 1244 | if (self.spv.hasFeature(.Kernel)) { |
| 1267 | return self.spv.intType(signedness, backing_bits); | 1245 | return self.spv.intType(.unsigned, backing_bits); |
| 1268 | } | 1246 | } |
| 1269 | | 1247 | |
| 1270 | return self.spv.intType(.unsigned, backing_bits); | 1248 | return self.spv.intType(signedness, backing_bits); |
| 1271 | } | 1249 | } |
| 1272 | | 1250 | |
| 1273 | fn arrayType(self: *NavGen, len: u32, child_ty: IdRef) !IdRef { | 1251 | fn arrayType(self: *NavGen, len: u32, child_ty: IdRef) !IdRef { |
| ... | @@ -1436,7 +1414,7 @@ const NavGen = struct { | ... | @@ -1436,7 +1414,7 @@ const NavGen = struct { |
| 1436 | const zcu = pt.zcu; | 1414 | const zcu = pt.zcu; |
| 1437 | const ip = &zcu.intern_pool; | 1415 | const ip = &zcu.intern_pool; |
| 1438 | log.debug("resolveType: ty = {}", .{ty.fmt(pt)}); | 1416 | log.debug("resolveType: ty = {}", .{ty.fmt(pt)}); |
| 1439 | const target = self.getTarget(); | 1417 | const target = self.spv.target; |
| 1440 | | 1418 | |
| 1441 | const section = &self.spv.sections.types_globals_constants; | 1419 | const section = &self.spv.sections.types_globals_constants; |
| 1442 | | 1420 | |
| ... | @@ -1533,7 +1511,7 @@ const NavGen = struct { | ... | @@ -1533,7 +1511,7 @@ const NavGen = struct { |
| 1533 | return try self.arrayType(1, elem_ty_id); | 1511 | return try self.arrayType(1, elem_ty_id); |
| 1534 | } else { | 1512 | } else { |
| 1535 | const result_id = try self.arrayType(total_len, elem_ty_id); | 1513 | const result_id = try self.arrayType(total_len, elem_ty_id); |
| 1536 | if (target.os.tag == .vulkan) { | 1514 | if (self.spv.hasFeature(.Shader)) { |
| 1537 | try self.spv.decorate(result_id, .{ .ArrayStride = .{ | 1515 | try self.spv.decorate(result_id, .{ .ArrayStride = .{ |
| 1538 | .array_stride = @intCast(elem_ty.abiSize(zcu)), | 1516 | .array_stride = @intCast(elem_ty.abiSize(zcu)), |
| 1539 | } }); | 1517 | } }); |
| ... | @@ -1667,7 +1645,7 @@ const NavGen = struct { | ... | @@ -1667,7 +1645,7 @@ const NavGen = struct { |
| 1667 | continue; | 1645 | continue; |
| 1668 | } | 1646 | } |
| 1669 | | 1647 | |
| 1670 | if (target.os.tag == .vulkan) { | 1648 | if (self.spv.hasFeature(.Shader)) { |
| 1671 | try self.spv.decorateMember(result_id, index, .{ .Offset = .{ | 1649 | try self.spv.decorateMember(result_id, index, .{ .Offset = .{ |
| 1672 | .byte_offset = @intCast(ty.structFieldOffset(field_index, zcu)), | 1650 | .byte_offset = @intCast(ty.structFieldOffset(field_index, zcu)), |
| 1673 | } }); | 1651 | } }); |
| ... | @@ -1769,20 +1747,11 @@ const NavGen = struct { | ... | @@ -1769,20 +1747,11 @@ const NavGen = struct { |
| 1769 | } | 1747 | } |
| 1770 | | 1748 | |
| 1771 | fn spvStorageClass(self: *NavGen, as: std.builtin.AddressSpace) StorageClass { | 1749 | fn spvStorageClass(self: *NavGen, as: std.builtin.AddressSpace) StorageClass { |
| 1772 | const target = self.getTarget(); | | |
| 1773 | return switch (as) { | 1750 | return switch (as) { |
| 1774 | .generic => switch (target.os.tag) { | 1751 | .generic => if (self.spv.hasFeature(.GenericPointer)) .Generic else .Function, |
| 1775 | .vulkan => .Function, | | |
| 1776 | .opencl => .Generic, | | |
| 1777 | else => unreachable, | | |
| 1778 | }, | | |
| 1779 | .shared => .Workgroup, | 1752 | .shared => .Workgroup, |
| 1780 | .local => .Function, | 1753 | .local => .Function, |
| 1781 | .global => switch (target.os.tag) { | 1754 | .global => if (self.spv.hasFeature(.Shader)) .PhysicalStorageBuffer else .CrossWorkgroup, |
| 1782 | .opencl => .CrossWorkgroup, | | |
| 1783 | .vulkan => .PhysicalStorageBuffer, | | |
| 1784 | else => unreachable, | | |
| 1785 | }, | | |
| 1786 | .constant => .UniformConstant, | 1755 | .constant => .UniformConstant, |
| 1787 | .push_constant => .PushConstant, | 1756 | .push_constant => .PushConstant, |
| 1788 | .input => .Input, | 1757 | .input => .Input, |
| ... | @@ -2326,7 +2295,7 @@ const NavGen = struct { | ... | @@ -2326,7 +2295,7 @@ const NavGen = struct { |
| 2326 | } | 2295 | } |
| 2327 | | 2296 | |
| 2328 | fn buildFma(self: *NavGen, a: Temporary, b: Temporary, c: Temporary) !Temporary { | 2297 | fn buildFma(self: *NavGen, a: Temporary, b: Temporary, c: Temporary) !Temporary { |
| 2329 | const target = self.getTarget(); | 2298 | const target = self.spv.target; |
| 2330 | | 2299 | |
| 2331 | const v = self.vectorization(.{ a, b, c }); | 2300 | const v = self.vectorization(.{ a, b, c }); |
| 2332 | const ops = v.operations(); | 2301 | const ops = v.operations(); |
| ... | @@ -2348,7 +2317,7 @@ const NavGen = struct { | ... | @@ -2348,7 +2317,7 @@ const NavGen = struct { |
| 2348 | // NOTE: Vulkan's FMA instruction does *NOT* produce the right values! | 2317 | // NOTE: Vulkan's FMA instruction does *NOT* produce the right values! |
| 2349 | // its precision guarantees do NOT match zigs and it does NOT match OpenCLs! | 2318 | // its precision guarantees do NOT match zigs and it does NOT match OpenCLs! |
| 2350 | // it needs to be emulated! | 2319 | // it needs to be emulated! |
| 2351 | .vulkan => unreachable, // TODO: See above | 2320 | .vulkan, .opengl => unreachable, // TODO: See above |
| 2352 | else => unreachable, | 2321 | else => unreachable, |
| 2353 | }; | 2322 | }; |
| 2354 | | 2323 | |
| ... | @@ -2485,14 +2454,14 @@ const NavGen = struct { | ... | @@ -2485,14 +2454,14 @@ const NavGen = struct { |
| 2485 | }; | 2454 | }; |
| 2486 | | 2455 | |
| 2487 | fn buildUnary(self: *NavGen, op: UnaryOp, operand: Temporary) !Temporary { | 2456 | fn buildUnary(self: *NavGen, op: UnaryOp, operand: Temporary) !Temporary { |
| 2488 | const target = self.getTarget(); | 2457 | const target = self.spv.target; |
| 2489 | const v = blk: { | 2458 | const v = blk: { |
| 2490 | const v = self.vectorization(.{operand}); | 2459 | const v = self.vectorization(.{operand}); |
| 2491 | break :blk switch (op) { | 2460 | break :blk switch (op) { |
| 2492 | // TODO: These instructions don't seem to be working | 2461 | // TODO: These instructions don't seem to be working |
| 2493 | // properly for LLVM-based backends on OpenCL for 8- and | 2462 | // properly for LLVM-based backends on OpenCL for 8- and |
| 2494 | // 16-component vectors. | 2463 | // 16-component vectors. |
| 2495 | .i_abs => if (target.os.tag == .opencl and v.components() >= 8) v.unroll() else v, | 2464 | .i_abs => if (self.spv.hasFeature(.Vector16) and v.components() >= 8) v.unroll() else v, |
| 2496 | else => v, | 2465 | else => v, |
| 2497 | }; | 2466 | }; |
| 2498 | }; | 2467 | }; |
| ... | @@ -2545,7 +2514,7 @@ const NavGen = struct { | ... | @@ -2545,7 +2514,7 @@ const NavGen = struct { |
| 2545 | // Note: We'll need to check these for floating point accuracy | 2514 | // Note: We'll need to check these for floating point accuracy |
| 2546 | // Vulkan does not put tight requirements on these, for correction | 2515 | // Vulkan does not put tight requirements on these, for correction |
| 2547 | // we might want to emulate them at some point. | 2516 | // we might want to emulate them at some point. |
| 2548 | .vulkan => switch (op) { | 2517 | .vulkan, .opengl => switch (op) { |
| 2549 | .i_abs => 5, // SAbs | 2518 | .i_abs => 5, // SAbs |
| 2550 | .f_abs => 4, // FAbs | 2519 | .f_abs => 4, // FAbs |
| 2551 | .clz => unreachable, // TODO | 2520 | .clz => unreachable, // TODO |
| ... | @@ -2615,7 +2584,7 @@ const NavGen = struct { | ... | @@ -2615,7 +2584,7 @@ const NavGen = struct { |
| 2615 | }; | 2584 | }; |
| 2616 | | 2585 | |
| 2617 | fn buildBinary(self: *NavGen, op: BinaryOp, lhs: Temporary, rhs: Temporary) !Temporary { | 2586 | fn buildBinary(self: *NavGen, op: BinaryOp, lhs: Temporary, rhs: Temporary) !Temporary { |
| 2618 | const target = self.getTarget(); | 2587 | const target = self.spv.target; |
| 2619 | | 2588 | |
| 2620 | const v = self.vectorization(.{ lhs, rhs }); | 2589 | const v = self.vectorization(.{ lhs, rhs }); |
| 2621 | const ops = v.operations(); | 2590 | const ops = v.operations(); |
| ... | @@ -2674,7 +2643,7 @@ const NavGen = struct { | ... | @@ -2674,7 +2643,7 @@ const NavGen = struct { |
| 2674 | .u_min => 159, // u_min | 2643 | .u_min => 159, // u_min |
| 2675 | else => unreachable, | 2644 | else => unreachable, |
| 2676 | }, | 2645 | }, |
| 2677 | .vulkan => switch (op) { | 2646 | .vulkan, .opengl => switch (op) { |
| 2678 | .f_max => 40, // FMax | 2647 | .f_max => 40, // FMax |
| 2679 | .s_max => 42, // SMax | 2648 | .s_max => 42, // SMax |
| 2680 | .u_max => 41, // UMax | 2649 | .u_max => 41, // UMax |
| ... | @@ -2713,7 +2682,7 @@ const NavGen = struct { | ... | @@ -2713,7 +2682,7 @@ const NavGen = struct { |
| 2713 | ) !struct { Temporary, Temporary } { | 2682 | ) !struct { Temporary, Temporary } { |
| 2714 | const pt = self.pt; | 2683 | const pt = self.pt; |
| 2715 | const zcu = pt.zcu; | 2684 | const zcu = pt.zcu; |
| 2716 | const target = self.getTarget(); | 2685 | const target = self.spv.target; |
| 2717 | const ip = &zcu.intern_pool; | 2686 | const ip = &zcu.intern_pool; |
| 2718 | | 2687 | |
| 2719 | const v = lhs.vectorization(self).unify(rhs.vectorization(self)); | 2688 | const v = lhs.vectorization(self).unify(rhs.vectorization(self)); |
| ... | @@ -2756,7 +2725,7 @@ const NavGen = struct { | ... | @@ -2756,7 +2725,7 @@ const NavGen = struct { |
| 2756 | }); | 2725 | }); |
| 2757 | } | 2726 | } |
| 2758 | }, | 2727 | }, |
| 2759 | .vulkan => { | 2728 | .vulkan, .opengl => { |
| 2760 | // Operations return a struct{T, T} | 2729 | // Operations return a struct{T, T} |
| 2761 | // where T is maybe vectorized. | 2730 | // where T is maybe vectorized. |
| 2762 | const op_result_ty: Type = .fromInterned(try ip.getTupleType(zcu.gpa, pt.tid, .{ | 2731 | const op_result_ty: Type = .fromInterned(try ip.getTupleType(zcu.gpa, pt.tid, .{ |
| ... | @@ -2843,7 +2812,7 @@ const NavGen = struct { | ... | @@ -2843,7 +2812,7 @@ const NavGen = struct { |
| 2843 | | 2812 | |
| 2844 | const section = &self.spv.sections.functions; | 2813 | const section = &self.spv.sections.functions; |
| 2845 | | 2814 | |
| 2846 | const target = self.getTarget(); | 2815 | const target = self.spv.target; |
| 2847 | | 2816 | |
| 2848 | const p_error_id = self.spv.allocId(); | 2817 | const p_error_id = self.spv.allocId(); |
| 2849 | switch (target.os.tag) { | 2818 | switch (target.os.tag) { |
| ... | @@ -2866,7 +2835,7 @@ const NavGen = struct { | ... | @@ -2866,7 +2835,7 @@ const NavGen = struct { |
| 2866 | .id_result = self.spv.allocId(), | 2835 | .id_result = self.spv.allocId(), |
| 2867 | }); | 2836 | }); |
| 2868 | }, | 2837 | }, |
| 2869 | .vulkan => { | 2838 | .vulkan, .opengl => { |
| 2870 | const ptr_ptr_anyerror_ty_id = self.spv.allocId(); | 2839 | const ptr_ptr_anyerror_ty_id = self.spv.allocId(); |
| 2871 | try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpTypePointer, .{ | 2840 | try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpTypePointer, .{ |
| 2872 | .id_result = ptr_ptr_anyerror_ty_id, | 2841 | .id_result = ptr_ptr_anyerror_ty_id, |
| ... | @@ -2967,7 +2936,7 @@ const NavGen = struct { | ... | @@ -2967,7 +2936,7 @@ const NavGen = struct { |
| 2967 | defer self.gpa.free(test_name); | 2936 | defer self.gpa.free(test_name); |
| 2968 | | 2937 | |
| 2969 | const execution_mode: spec.ExecutionModel = switch (target.os.tag) { | 2938 | const execution_mode: spec.ExecutionModel = switch (target.os.tag) { |
| 2970 | .vulkan => .GLCompute, | 2939 | .vulkan, .opengl => .GLCompute, |
| 2971 | .opencl => .Kernel, | 2940 | .opencl => .Kernel, |
| 2972 | else => unreachable, | 2941 | else => unreachable, |
| 2973 | }; | 2942 | }; |
| ... | @@ -3670,7 +3639,6 @@ const NavGen = struct { | ... | @@ -3670,7 +3639,6 @@ const NavGen = struct { |
| 3670 | } | 3639 | } |
| 3671 | | 3640 | |
| 3672 | fn abs(self: *NavGen, result_ty: Type, value: Temporary) !Temporary { | 3641 | fn abs(self: *NavGen, result_ty: Type, value: Temporary) !Temporary { |
| 3673 | const target = self.getTarget(); | | |
| 3674 | const operand_info = self.arithmeticTypeInfo(value.ty); | 3642 | const operand_info = self.arithmeticTypeInfo(value.ty); |
| 3675 | | 3643 | |
| 3676 | switch (operand_info.class) { | 3644 | switch (operand_info.class) { |
| ... | @@ -3682,7 +3650,7 @@ const NavGen = struct { | ... | @@ -3682,7 +3650,7 @@ const NavGen = struct { |
| 3682 | // depending on the result type. Do that when | 3650 | // depending on the result type. Do that when |
| 3683 | // bitCast is implemented for vectors. | 3651 | // bitCast is implemented for vectors. |
| 3684 | // This is only relevant for Vulkan | 3652 | // This is only relevant for Vulkan |
| 3685 | assert(target.os.tag != .vulkan); // TODO | 3653 | assert(self.spv.hasFeature(.Kernel)); // TODO |
| 3686 | | 3654 | |
| 3687 | return try self.normalize(abs_value, self.arithmeticTypeInfo(result_ty)); | 3655 | return try self.normalize(abs_value, self.arithmeticTypeInfo(result_ty)); |
| 3688 | }, | 3656 | }, |
| ... | @@ -3756,7 +3724,6 @@ const NavGen = struct { | ... | @@ -3756,7 +3724,6 @@ const NavGen = struct { |
| 3756 | } | 3724 | } |
| 3757 | | 3725 | |
| 3758 | fn airMulOverflow(self: *NavGen, inst: Air.Inst.Index) !?IdRef { | 3726 | fn airMulOverflow(self: *NavGen, inst: Air.Inst.Index) !?IdRef { |
| 3759 | const target = self.getTarget(); | | |
| 3760 | const pt = self.pt; | 3727 | const pt = self.pt; |
| 3761 | | 3728 | |
| 3762 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 3729 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| ... | @@ -3780,7 +3747,7 @@ const NavGen = struct { | ... | @@ -3780,7 +3747,7 @@ const NavGen = struct { |
| 3780 | // - Additionally, if info.bits != 32, we'll have to check the high bits | 3747 | // - Additionally, if info.bits != 32, we'll have to check the high bits |
| 3781 | // of the result too. | 3748 | // of the result too. |
| 3782 | | 3749 | |
| 3783 | const largest_int_bits: u16 = if (Target.spirv.featureSetHas(target.cpu.features, .Int64)) 64 else 32; | 3750 | const largest_int_bits = self.largestSupportedIntBits(); |
| 3784 | // If non-null, the number of bits that the multiplication should be performed in. If | 3751 | // If non-null, the number of bits that the multiplication should be performed in. If |
| 3785 | // null, we have to use wide multiplication. | 3752 | // null, we have to use wide multiplication. |
| 3786 | const maybe_op_ty_bits: ?u16 = switch (info.bits) { | 3753 | const maybe_op_ty_bits: ?u16 = switch (info.bits) { |
| ... | @@ -3989,7 +3956,6 @@ const NavGen = struct { | ... | @@ -3989,7 +3956,6 @@ const NavGen = struct { |
| 3989 | if (self.liveness.isUnused(inst)) return null; | 3956 | if (self.liveness.isUnused(inst)) return null; |
| 3990 | | 3957 | |
| 3991 | const zcu = self.pt.zcu; | 3958 | const zcu = self.pt.zcu; |
| 3992 | const target = self.getTarget(); | | |
| 3993 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 3959 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3994 | const operand = try self.temporary(ty_op.operand); | 3960 | const operand = try self.temporary(ty_op.operand); |
| 3995 | | 3961 | |
| ... | @@ -4002,10 +3968,7 @@ const NavGen = struct { | ... | @@ -4002,10 +3968,7 @@ const NavGen = struct { |
| 4002 | .float, .bool => unreachable, | 3968 | .float, .bool => unreachable, |
| 4003 | } | 3969 | } |
| 4004 | | 3970 | |
| 4005 | switch (target.os.tag) { | 3971 | assert(self.spv.hasFeature(.Kernel)); // TODO |
| 4006 | .vulkan => unreachable, // TODO | | |
| 4007 | else => {}, | | |
| 4008 | } | | |
| 4009 | | 3972 | |
| 4010 | const count = try self.buildUnary(op, operand); | 3973 | const count = try self.buildUnary(op, operand); |
| 4011 | | 3974 | |
| ... | @@ -4241,23 +4204,22 @@ const NavGen = struct { | ... | @@ -4241,23 +4204,22 @@ const NavGen = struct { |
| 4241 | defer self.gpa.free(ids); | 4204 | defer self.gpa.free(ids); |
| 4242 | | 4205 | |
| 4243 | const result_id = self.spv.allocId(); | 4206 | const result_id = self.spv.allocId(); |
| 4244 | const target = self.getTarget(); | 4207 | if (self.spv.hasFeature(.Kernel)) { |
| 4245 | switch (target.os.tag) { | 4208 | try self.func.body.emit(self.spv.gpa, .OpInBoundsPtrAccessChain, .{ |
| 4246 | .opencl => try self.func.body.emit(self.spv.gpa, .OpInBoundsPtrAccessChain, .{ | | |
| 4247 | .id_result_type = result_ty_id, | 4209 | .id_result_type = result_ty_id, |
| 4248 | .id_result = result_id, | 4210 | .id_result = result_id, |
| 4249 | .base = base, | 4211 | .base = base, |
| 4250 | .element = element, | 4212 | .element = element, |
| 4251 | .indexes = ids, | 4213 | .indexes = ids, |
| 4252 | }), | 4214 | }); |
| 4253 | .vulkan => try self.func.body.emit(self.spv.gpa, .OpPtrAccessChain, .{ | 4215 | } else { |
| | 4216 | try self.func.body.emit(self.spv.gpa, .OpPtrAccessChain, .{ |
| 4254 | .id_result_type = result_ty_id, | 4217 | .id_result_type = result_ty_id, |
| 4255 | .id_result = result_id, | 4218 | .id_result = result_id, |
| 4256 | .base = base, | 4219 | .base = base, |
| 4257 | .element = element, | 4220 | .element = element, |
| 4258 | .indexes = ids, | 4221 | .indexes = ids, |
| 4259 | }), | 4222 | }); |
| 4260 | else => unreachable, | | |
| 4261 | } | 4223 | } |
| 4262 | return result_id; | 4224 | return result_id; |
| 4263 | } | 4225 | } |
| ... | @@ -5328,10 +5290,7 @@ const NavGen = struct { | ... | @@ -5328,10 +5290,7 @@ const NavGen = struct { |
| 5328 | .initializer = options.initializer, | 5290 | .initializer = options.initializer, |
| 5329 | }); | 5291 | }); |
| 5330 | | 5292 | |
| 5331 | const target = self.getTarget(); | 5293 | if (self.spv.hasFeature(.Shader)) return var_id; |
| 5332 | if (target.os.tag == .vulkan) { | | |
| 5333 | return var_id; | | |
| 5334 | } | | |
| 5335 | | 5294 | |
| 5336 | switch (options.storage_class) { | 5295 | switch (options.storage_class) { |
| 5337 | .Generic => { | 5296 | .Generic => { |
| ... | @@ -6204,7 +6163,7 @@ const NavGen = struct { | ... | @@ -6204,7 +6163,7 @@ const NavGen = struct { |
| 6204 | fn airSwitchBr(self: *NavGen, inst: Air.Inst.Index) !void { | 6163 | fn airSwitchBr(self: *NavGen, inst: Air.Inst.Index) !void { |
| 6205 | const pt = self.pt; | 6164 | const pt = self.pt; |
| 6206 | const zcu = pt.zcu; | 6165 | const zcu = pt.zcu; |
| 6207 | const target = self.getTarget(); | 6166 | const target = self.spv.target; |
| 6208 | const switch_br = self.air.unwrapSwitch(inst); | 6167 | const switch_br = self.air.unwrapSwitch(inst); |
| 6209 | const cond_ty = self.typeOf(switch_br.operand); | 6168 | const cond_ty = self.typeOf(switch_br.operand); |
| 6210 | const cond = try self.resolve(switch_br.operand); | 6169 | const cond = try self.resolve(switch_br.operand); |