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