| ... | @@ -451,12 +451,12 @@ const DeclGen = struct { | ... | @@ -451,12 +451,12 @@ const DeclGen = struct { |
| 451 | const spv_decl_index = blk: { | 451 | const spv_decl_index = blk: { |
| 452 | const entry = try self.object.anon_decl_link.getOrPut(self.object.gpa, .{ val, storage_class }); | 452 | const entry = try self.object.anon_decl_link.getOrPut(self.object.gpa, .{ val, storage_class }); |
| 453 | if (entry.found_existing) { | 453 | if (entry.found_existing) { |
| 454 | try self.func.decl_deps.put(self.spv.gpa, entry.value_ptr.*, {}); | 454 | try self.addFunctionDep(entry.value_ptr.*, storage_class); |
| 455 | return self.spv.declPtr(entry.value_ptr.*).result_id; | 455 | return self.spv.declPtr(entry.value_ptr.*).result_id; |
| 456 | } | 456 | } |
| 457 | | 457 | |
| 458 | const spv_decl_index = try self.spv.allocDecl(.global); | 458 | const spv_decl_index = try self.spv.allocDecl(.global); |
| 459 | try self.func.decl_deps.put(self.spv.gpa, spv_decl_index, {}); | 459 | try self.addFunctionDep(spv_decl_index, storage_class); |
| 460 | entry.value_ptr.* = spv_decl_index; | 460 | entry.value_ptr.* = spv_decl_index; |
| 461 | break :blk spv_decl_index; | 461 | break :blk spv_decl_index; |
| 462 | }; | 462 | }; |
| ... | @@ -529,6 +529,37 @@ const DeclGen = struct { | ... | @@ -529,6 +529,37 @@ const DeclGen = struct { |
| 529 | return var_id; | 529 | return var_id; |
| 530 | } | 530 | } |
| 531 | | 531 | |
| | 532 | fn addFunctionDep(self: *DeclGen, decl_index: SpvModule.Decl.Index, storage_class: StorageClass) !void { |
| | 533 | const target = self.getTarget(); |
| | 534 | if (target.os.tag == .vulkan) { |
| | 535 | // Shader entry point dependencies must be variables with Input or Output storage class |
| | 536 | switch (storage_class) { |
| | 537 | .Input, .Output => { |
| | 538 | try self.func.decl_deps.put(self.spv.gpa, decl_index, {}); |
| | 539 | }, |
| | 540 | else => {}, |
| | 541 | } |
| | 542 | } else { |
| | 543 | try self.func.decl_deps.put(self.spv.gpa, decl_index, {}); |
| | 544 | } |
| | 545 | } |
| | 546 | |
| | 547 | fn castToGeneric(self: *DeclGen, type_id: IdRef, ptr_id: IdRef) !IdRef { |
| | 548 | const target = self.getTarget(); |
| | 549 | |
| | 550 | if (target.os.tag == .vulkan) { |
| | 551 | return ptr_id; |
| | 552 | } else { |
| | 553 | const result_id = self.spv.allocId(); |
| | 554 | try self.func.body.emit(self.spv.gpa, .OpPtrCastToGeneric, .{ |
| | 555 | .id_result_type = type_id, |
| | 556 | .id_result = result_id, |
| | 557 | .pointer = ptr_id, |
| | 558 | }); |
| | 559 | return result_id; |
| | 560 | } |
| | 561 | } |
| | 562 | |
| 532 | /// Start a new SPIR-V block, Emits the label of the new block, and stores which | 563 | /// Start a new SPIR-V block, Emits the label of the new block, and stores which |
| 533 | /// block we are currently generating. | 564 | /// block we are currently generating. |
| 534 | /// Note that there is no such thing as nested blocks like in ZIR or AIR, so we don't need to | 565 | /// Note that there is no such thing as nested blocks like in ZIR or AIR, so we don't need to |
| ... | @@ -1019,7 +1050,7 @@ const DeclGen = struct { | ... | @@ -1019,7 +1050,7 @@ const DeclGen = struct { |
| 1019 | | 1050 | |
| 1020 | // TODO: Can we consolidate this in ptrElemPtr? | 1051 | // TODO: Can we consolidate this in ptrElemPtr? |
| 1021 | const elem_ty = parent_ptr_ty.elemType2(mod); // use elemType() so that we get T for *[N]T. | 1052 | const elem_ty = parent_ptr_ty.elemType2(mod); // use elemType() so that we get T for *[N]T. |
| 1022 | const elem_ptr_ty_ref = try self.ptrType(elem_ty, spvStorageClass(parent_ptr_ty.ptrAddressSpace(mod))); | 1053 | const elem_ptr_ty_ref = try self.ptrType(elem_ty, self.spvStorageClass(parent_ptr_ty.ptrAddressSpace(mod))); |
| 1023 | | 1054 | |
| 1024 | if (elem_ptr_ty_ref == result_ty_ref) { | 1055 | if (elem_ptr_ty_ref == result_ty_ref) { |
| 1025 | return elem_ptr_id; | 1056 | return elem_ptr_id; |
| ... | @@ -1074,7 +1105,7 @@ const DeclGen = struct { | ... | @@ -1074,7 +1105,7 @@ const DeclGen = struct { |
| 1074 | unreachable; // TODO | 1105 | unreachable; // TODO |
| 1075 | } | 1106 | } |
| 1076 | | 1107 | |
| 1077 | const final_storage_class = spvStorageClass(ty.ptrAddressSpace(mod)); | 1108 | const final_storage_class = self.spvStorageClass(ty.ptrAddressSpace(mod)); |
| 1078 | const actual_storage_class = switch (final_storage_class) { | 1109 | const actual_storage_class = switch (final_storage_class) { |
| 1079 | .Generic => .CrossWorkgroup, | 1110 | .Generic => .CrossWorkgroup, |
| 1080 | else => |other| other, | 1111 | else => |other| other, |
| ... | @@ -1084,15 +1115,7 @@ const DeclGen = struct { | ... | @@ -1084,15 +1115,7 @@ const DeclGen = struct { |
| 1084 | const decl_ptr_ty_ref = try self.ptrType(decl_ty, final_storage_class); | 1115 | const decl_ptr_ty_ref = try self.ptrType(decl_ty, final_storage_class); |
| 1085 | | 1116 | |
| 1086 | const ptr_id = switch (final_storage_class) { | 1117 | const ptr_id = switch (final_storage_class) { |
| 1087 | .Generic => blk: { | 1118 | .Generic => try self.castToGeneric(self.typeId(decl_ptr_ty_ref), decl_id), |
| 1088 | const result_id = self.spv.allocId(); | | |
| 1089 | try self.func.body.emit(self.spv.gpa, .OpPtrCastToGeneric, .{ | | |
| 1090 | .id_result_type = self.typeId(decl_ptr_ty_ref), | | |
| 1091 | .id_result = result_id, | | |
| 1092 | .pointer = decl_id, | | |
| 1093 | }); | | |
| 1094 | break :blk result_id; | | |
| 1095 | }, | | |
| 1096 | else => decl_id, | 1119 | else => decl_id, |
| 1097 | }; | 1120 | }; |
| 1098 | | 1121 | |
| ... | @@ -1115,6 +1138,7 @@ const DeclGen = struct { | ... | @@ -1115,6 +1138,7 @@ const DeclGen = struct { |
| 1115 | const ty_ref = try self.resolveType(ty, .direct); | 1138 | const ty_ref = try self.resolveType(ty, .direct); |
| 1116 | const ty_id = self.typeId(ty_ref); | 1139 | const ty_id = self.typeId(ty_ref); |
| 1117 | const decl = mod.declPtr(decl_index); | 1140 | const decl = mod.declPtr(decl_index); |
| | 1141 | |
| 1118 | switch (mod.intern_pool.indexToKey(decl.val.ip_index)) { | 1142 | switch (mod.intern_pool.indexToKey(decl.val.ip_index)) { |
| 1119 | .func => { | 1143 | .func => { |
| 1120 | // TODO: Properly lower function pointers. For now we are going to hack around it and | 1144 | // TODO: Properly lower function pointers. For now we are going to hack around it and |
| ... | @@ -1133,23 +1157,13 @@ const DeclGen = struct { | ... | @@ -1133,23 +1157,13 @@ const DeclGen = struct { |
| 1133 | const spv_decl_index = try self.object.resolveDecl(mod, decl_index); | 1157 | const spv_decl_index = try self.object.resolveDecl(mod, decl_index); |
| 1134 | | 1158 | |
| 1135 | const decl_id = self.spv.declPtr(spv_decl_index).result_id; | 1159 | const decl_id = self.spv.declPtr(spv_decl_index).result_id; |
| 1136 | try self.func.decl_deps.put(self.spv.gpa, spv_decl_index, {}); | 1160 | const final_storage_class = self.spvStorageClass(decl.@"addrspace"); |
| 1137 | | 1161 | try self.addFunctionDep(spv_decl_index, final_storage_class); |
| 1138 | const final_storage_class = spvStorageClass(decl.@"addrspace"); | | |
| 1139 | | 1162 | |
| 1140 | const decl_ptr_ty_ref = try self.ptrType(decl.ty, final_storage_class); | 1163 | const decl_ptr_ty_ref = try self.ptrType(decl.ty, final_storage_class); |
| 1141 | | 1164 | |
| 1142 | const ptr_id = switch (final_storage_class) { | 1165 | const ptr_id = switch (final_storage_class) { |
| 1143 | .Generic => blk: { | 1166 | .Generic => try self.castToGeneric(self.typeId(decl_ptr_ty_ref), decl_id), |
| 1144 | // Pointer should be Generic, but is actually placed in CrossWorkgroup. | | |
| 1145 | const result_id = self.spv.allocId(); | | |
| 1146 | try self.func.body.emit(self.spv.gpa, .OpPtrCastToGeneric, .{ | | |
| 1147 | .id_result_type = self.typeId(decl_ptr_ty_ref), | | |
| 1148 | .id_result = result_id, | | |
| 1149 | .pointer = decl_id, | | |
| 1150 | }); | | |
| 1151 | break :blk result_id; | | |
| 1152 | }, | | |
| 1153 | else => decl_id, | 1167 | else => decl_id, |
| 1154 | }; | 1168 | }; |
| 1155 | | 1169 | |
| ... | @@ -1195,8 +1209,12 @@ const DeclGen = struct { | ... | @@ -1195,8 +1209,12 @@ const DeclGen = struct { |
| 1195 | // An array of largestSupportedIntBits. | 1209 | // An array of largestSupportedIntBits. |
| 1196 | return self.todo("Implement {s} composite int type of {} bits", .{ @tagName(signedness), bits }); | 1210 | return self.todo("Implement {s} composite int type of {} bits", .{ @tagName(signedness), bits }); |
| 1197 | }; | 1211 | }; |
| | 1212 | |
| 1198 | // Kernel only supports unsigned ints. | 1213 | // Kernel only supports unsigned ints. |
| 1199 | // TODO: Only do this with Kernels | 1214 | if (self.getTarget().os.tag == .vulkan) { |
| | 1215 | return self.spv.intType(signedness, backing_bits); |
| | 1216 | } |
| | 1217 | |
| 1200 | return self.spv.intType(.unsigned, backing_bits); | 1218 | return self.spv.intType(.unsigned, backing_bits); |
| 1201 | } | 1219 | } |
| 1202 | | 1220 | |
| ... | @@ -1453,7 +1471,7 @@ const DeclGen = struct { | ... | @@ -1453,7 +1471,7 @@ const DeclGen = struct { |
| 1453 | // Note: Don't cache this pointer type, it would mess up the recursive pointer functionality | 1471 | // Note: Don't cache this pointer type, it would mess up the recursive pointer functionality |
| 1454 | // in ptrType()! | 1472 | // in ptrType()! |
| 1455 | | 1473 | |
| 1456 | const storage_class = spvStorageClass(ptr_info.flags.address_space); | 1474 | const storage_class = self.spvStorageClass(ptr_info.flags.address_space); |
| 1457 | const ptr_ty_ref = try self.ptrType(Type.fromInterned(ptr_info.child), storage_class); | 1475 | const ptr_ty_ref = try self.ptrType(Type.fromInterned(ptr_info.child), storage_class); |
| 1458 | | 1476 | |
| 1459 | if (ptr_info.flags.size != .Slice) { | 1477 | if (ptr_info.flags.size != .Slice) { |
| ... | @@ -1634,13 +1652,20 @@ const DeclGen = struct { | ... | @@ -1634,13 +1652,20 @@ const DeclGen = struct { |
| 1634 | } | 1652 | } |
| 1635 | } | 1653 | } |
| 1636 | | 1654 | |
| 1637 | fn spvStorageClass(as: std.builtin.AddressSpace) StorageClass { | 1655 | fn spvStorageClass(self: *DeclGen, as: std.builtin.AddressSpace) StorageClass { |
| | 1656 | const target = self.getTarget(); |
| 1638 | return switch (as) { | 1657 | return switch (as) { |
| 1639 | .generic => .Generic, | 1658 | .generic => switch (target.os.tag) { |
| | 1659 | .vulkan => .Private, |
| | 1660 | else => .Generic, |
| | 1661 | }, |
| 1640 | .shared => .Workgroup, | 1662 | .shared => .Workgroup, |
| 1641 | .local => .Private, | 1663 | .local => .Private, |
| 1642 | .global => .CrossWorkgroup, | 1664 | .global => .CrossWorkgroup, |
| 1643 | .constant => .UniformConstant, | 1665 | .constant => .UniformConstant, |
| | 1666 | .input => .Input, |
| | 1667 | .output => .Output, |
| | 1668 | .uniform => .Uniform, |
| 1644 | .gs, | 1669 | .gs, |
| 1645 | .fs, | 1670 | .fs, |
| 1646 | .ss, | 1671 | .ss, |
| ... | @@ -1920,7 +1945,7 @@ const DeclGen = struct { | ... | @@ -1920,7 +1945,7 @@ const DeclGen = struct { |
| 1920 | // point name is the same as a different OpName. | 1945 | // point name is the same as a different OpName. |
| 1921 | const test_name = try std.fmt.allocPrint(self.gpa, "test {s}", .{name}); | 1946 | const test_name = try std.fmt.allocPrint(self.gpa, "test {s}", .{name}); |
| 1922 | defer self.gpa.free(test_name); | 1947 | defer self.gpa.free(test_name); |
| 1923 | try self.spv.declareEntryPoint(spv_decl_index, test_name); | 1948 | try self.spv.declareEntryPoint(spv_decl_index, test_name, .Kernel); |
| 1924 | } | 1949 | } |
| 1925 | | 1950 | |
| 1926 | fn genDecl(self: *DeclGen) !void { | 1951 | fn genDecl(self: *DeclGen) !void { |
| ... | @@ -1928,6 +1953,7 @@ const DeclGen = struct { | ... | @@ -1928,6 +1953,7 @@ const DeclGen = struct { |
| 1928 | const ip = &mod.intern_pool; | 1953 | const ip = &mod.intern_pool; |
| 1929 | const decl = mod.declPtr(self.decl_index); | 1954 | const decl = mod.declPtr(self.decl_index); |
| 1930 | const spv_decl_index = try self.object.resolveDecl(mod, self.decl_index); | 1955 | const spv_decl_index = try self.object.resolveDecl(mod, self.decl_index); |
| | 1956 | const target = self.getTarget(); |
| 1931 | | 1957 | |
| 1932 | const decl_id = self.spv.declPtr(spv_decl_index).result_id; | 1958 | const decl_id = self.spv.declPtr(spv_decl_index).result_id; |
| 1933 | | 1959 | |
| ... | @@ -1994,30 +2020,24 @@ const DeclGen = struct { | ... | @@ -1994,30 +2020,24 @@ const DeclGen = struct { |
| 1994 | try self.generateTestEntryPoint(fqn, spv_decl_index); | 2020 | try self.generateTestEntryPoint(fqn, spv_decl_index); |
| 1995 | } | 2021 | } |
| 1996 | } else { | 2022 | } else { |
| 1997 | const init_val = if (decl.val.getVariable(mod)) |payload| | 2023 | const opt_init_val: ?Value = blk: { |
| 1998 | Value.fromInterned(payload.init) | 2024 | if (decl.val.getVariable(mod)) |payload| { |
| 1999 | else | 2025 | if (payload.is_extern) break :blk null; |
| 2000 | decl.val; | 2026 | break :blk Value.fromInterned(payload.init); |
| 2001 | | 2027 | } |
| 2002 | if (init_val.ip_index == .unreachable_value) { | 2028 | break :blk decl.val; |
| 2003 | return self.todo("importing extern variables", .{}); | 2029 | }; |
| 2004 | } | | |
| 2005 | | | |
| 2006 | // Currently, initializers for CrossWorkgroup variables is not implemented | | |
| 2007 | // in Mesa. Therefore we generate an initialization kernel instead. | | |
| 2008 | | | |
| 2009 | const void_ty_ref = try self.resolveType(Type.void, .direct); | | |
| 2010 | | | |
| 2011 | const initializer_proto_ty_ref = try self.spv.resolve(.{ .function_type = .{ | | |
| 2012 | .return_type = void_ty_ref, | | |
| 2013 | .parameters = &.{}, | | |
| 2014 | } }); | | |
| 2015 | | 2030 | |
| 2016 | // Generate the actual variable for the global... | 2031 | // Generate the actual variable for the global... |
| 2017 | const final_storage_class = spvStorageClass(decl.@"addrspace"); | 2032 | const final_storage_class = self.spvStorageClass(decl.@"addrspace"); |
| 2018 | const actual_storage_class = switch (final_storage_class) { | 2033 | const actual_storage_class = blk: { |
| 2019 | .Generic => .CrossWorkgroup, | 2034 | if (target.os.tag != .vulkan) { |
| 2020 | else => final_storage_class, | 2035 | break :blk switch (final_storage_class) { |
| | 2036 | .Generic => .CrossWorkgroup, |
| | 2037 | else => final_storage_class, |
| | 2038 | }; |
| | 2039 | } |
| | 2040 | break :blk final_storage_class; |
| 2021 | }; | 2041 | }; |
| 2022 | | 2042 | |
| 2023 | const ptr_ty_ref = try self.ptrType(decl.ty, actual_storage_class); | 2043 | const ptr_ty_ref = try self.ptrType(decl.ty, actual_storage_class); |
| ... | @@ -2028,37 +2048,51 @@ const DeclGen = struct { | ... | @@ -2028,37 +2048,51 @@ const DeclGen = struct { |
| 2028 | .id_result = decl_id, | 2048 | .id_result = decl_id, |
| 2029 | .storage_class = actual_storage_class, | 2049 | .storage_class = actual_storage_class, |
| 2030 | }); | 2050 | }); |
| | 2051 | const fqn = ip.stringToSlice(try decl.getFullyQualifiedName(self.module)); |
| | 2052 | try self.spv.debugName(decl_id, fqn); |
| 2031 | | 2053 | |
| 2032 | // Now emit the instructions that initialize the variable. | 2054 | if (opt_init_val) |init_val| { |
| 2033 | const initializer_id = self.spv.allocId(); | 2055 | // Currently, initializers for CrossWorkgroup variables is not implemented |
| 2034 | try self.func.prologue.emit(self.spv.gpa, .OpFunction, .{ | 2056 | // in Mesa. Therefore we generate an initialization kernel instead. |
| 2035 | .id_result_type = self.typeId(void_ty_ref), | 2057 | const void_ty_ref = try self.resolveType(Type.void, .direct); |
| 2036 | .id_result = initializer_id, | | |
| 2037 | .function_control = .{}, | | |
| 2038 | .function_type = self.typeId(initializer_proto_ty_ref), | | |
| 2039 | }); | | |
| 2040 | const root_block_id = self.spv.allocId(); | | |
| 2041 | try self.func.prologue.emit(self.spv.gpa, .OpLabel, .{ | | |
| 2042 | .id_result = root_block_id, | | |
| 2043 | }); | | |
| 2044 | self.current_block_label = root_block_id; | | |
| 2045 | | 2058 | |
| 2046 | const val_id = try self.constant(decl.ty, init_val, .indirect); | 2059 | const initializer_proto_ty_ref = try self.spv.resolve(.{ .function_type = .{ |
| 2047 | try self.func.body.emit(self.spv.gpa, .OpStore, .{ | 2060 | .return_type = void_ty_ref, |
| 2048 | .pointer = decl_id, | 2061 | .parameters = &.{}, |
| 2049 | .object = val_id, | 2062 | } }); |
| 2050 | }); | | |
| 2051 | | 2063 | |
| 2052 | // TODO: We should be able to get rid of this by now... | 2064 | // Now emit the instructions that initialize the variable. |
| 2053 | self.spv.endGlobal(spv_decl_index, begin, decl_id, initializer_id); | 2065 | const initializer_id = self.spv.allocId(); |
| | 2066 | try self.func.prologue.emit(self.spv.gpa, .OpFunction, .{ |
| | 2067 | .id_result_type = self.typeId(void_ty_ref), |
| | 2068 | .id_result = initializer_id, |
| | 2069 | .function_control = .{}, |
| | 2070 | .function_type = self.typeId(initializer_proto_ty_ref), |
| | 2071 | }); |
| | 2072 | const root_block_id = self.spv.allocId(); |
| | 2073 | try self.func.prologue.emit(self.spv.gpa, .OpLabel, .{ |
| | 2074 | .id_result = root_block_id, |
| | 2075 | }); |
| | 2076 | self.current_block_label = root_block_id; |
| 2054 | | 2077 | |
| 2055 | try self.func.body.emit(self.spv.gpa, .OpReturn, {}); | 2078 | const val_id = try self.constant(decl.ty, init_val, .indirect); |
| 2056 | try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {}); | 2079 | try self.func.body.emit(self.spv.gpa, .OpStore, .{ |
| 2057 | try self.spv.addFunction(spv_decl_index, self.func); | 2080 | .pointer = decl_id, |
| | 2081 | .object = val_id, |
| | 2082 | }); |
| 2058 | | 2083 | |
| 2059 | const fqn = ip.stringToSlice(try decl.getFullyQualifiedName(self.module)); | 2084 | // TODO: We should be able to get rid of this by now... |
| 2060 | try self.spv.debugName(decl_id, fqn); | 2085 | self.spv.endGlobal(spv_decl_index, begin, decl_id, initializer_id); |
| 2061 | try self.spv.debugNameFmt(initializer_id, "initializer of {s}", .{fqn}); | 2086 | |
| | 2087 | try self.func.body.emit(self.spv.gpa, .OpReturn, {}); |
| | 2088 | try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {}); |
| | 2089 | try self.spv.addFunction(spv_decl_index, self.func); |
| | 2090 | |
| | 2091 | try self.spv.debugNameFmt(initializer_id, "initializer of {s}", .{fqn}); |
| | 2092 | } else { |
| | 2093 | self.spv.endGlobal(spv_decl_index, begin, decl_id, null); |
| | 2094 | try self.spv.declareDeclDeps(spv_decl_index, &.{}); |
| | 2095 | } |
| 2062 | } | 2096 | } |
| 2063 | } | 2097 | } |
| 2064 | | 2098 | |
| ... | @@ -3761,7 +3795,7 @@ const DeclGen = struct { | ... | @@ -3761,7 +3795,7 @@ const DeclGen = struct { |
| 3761 | const mod = self.module; | 3795 | const mod = self.module; |
| 3762 | // Construct new pointer type for the resulting pointer | 3796 | // Construct new pointer type for the resulting pointer |
| 3763 | const elem_ty = ptr_ty.elemType2(mod); // use elemType() so that we get T for *[N]T. | 3797 | const elem_ty = ptr_ty.elemType2(mod); // use elemType() so that we get T for *[N]T. |
| 3764 | const elem_ptr_ty_ref = try self.ptrType(elem_ty, spvStorageClass(ptr_ty.ptrAddressSpace(mod))); | 3798 | const elem_ptr_ty_ref = try self.ptrType(elem_ty, self.spvStorageClass(ptr_ty.ptrAddressSpace(mod))); |
| 3765 | if (ptr_ty.isSinglePointer(mod)) { | 3799 | if (ptr_ty.isSinglePointer(mod)) { |
| 3766 | // Pointer-to-array. In this case, the resulting pointer is not of the same type | 3800 | // Pointer-to-array. In this case, the resulting pointer is not of the same type |
| 3767 | // as the ptr_ty (we want a *T, not a *[N]T), and hence we need to use accessChain. | 3801 | // as the ptr_ty (we want a *T, not a *[N]T), and hence we need to use accessChain. |
| ... | @@ -3835,7 +3869,7 @@ const DeclGen = struct { | ... | @@ -3835,7 +3869,7 @@ const DeclGen = struct { |
| 3835 | const vector_ty = vector_ptr_ty.childType(mod); | 3869 | const vector_ty = vector_ptr_ty.childType(mod); |
| 3836 | const scalar_ty = vector_ty.scalarType(mod); | 3870 | const scalar_ty = vector_ty.scalarType(mod); |
| 3837 | | 3871 | |
| 3838 | const storage_class = spvStorageClass(vector_ptr_ty.ptrAddressSpace(mod)); | 3872 | const storage_class = self.spvStorageClass(vector_ptr_ty.ptrAddressSpace(mod)); |
| 3839 | const scalar_ptr_ty_ref = try self.ptrType(scalar_ty, storage_class); | 3873 | const scalar_ptr_ty_ref = try self.ptrType(scalar_ty, storage_class); |
| 3840 | | 3874 | |
| 3841 | const vector_ptr = try self.resolve(data.vector_ptr); | 3875 | const vector_ptr = try self.resolve(data.vector_ptr); |
| ... | @@ -3858,7 +3892,7 @@ const DeclGen = struct { | ... | @@ -3858,7 +3892,7 @@ const DeclGen = struct { |
| 3858 | if (layout.tag_size == 0) return; | 3892 | if (layout.tag_size == 0) return; |
| 3859 | | 3893 | |
| 3860 | const tag_ty = un_ty.unionTagTypeSafety(mod).?; | 3894 | const tag_ty = un_ty.unionTagTypeSafety(mod).?; |
| 3861 | const tag_ptr_ty_ref = try self.ptrType(tag_ty, spvStorageClass(un_ptr_ty.ptrAddressSpace(mod))); | 3895 | const tag_ptr_ty_ref = try self.ptrType(tag_ty, self.spvStorageClass(un_ptr_ty.ptrAddressSpace(mod))); |
| 3862 | | 3896 | |
| 3863 | const union_ptr_id = try self.resolve(bin_op.lhs); | 3897 | const union_ptr_id = try self.resolve(bin_op.lhs); |
| 3864 | const new_tag_id = try self.resolve(bin_op.rhs); | 3898 | const new_tag_id = try self.resolve(bin_op.rhs); |
| ... | @@ -4079,7 +4113,7 @@ const DeclGen = struct { | ... | @@ -4079,7 +4113,7 @@ const DeclGen = struct { |
| 4079 | return try self.spv.constUndef(result_ty_ref); | 4113 | return try self.spv.constUndef(result_ty_ref); |
| 4080 | } | 4114 | } |
| 4081 | | 4115 | |
| 4082 | const storage_class = spvStorageClass(object_ptr_ty.ptrAddressSpace(mod)); | 4116 | const storage_class = self.spvStorageClass(object_ptr_ty.ptrAddressSpace(mod)); |
| 4083 | const pl_ptr_ty_ref = try self.ptrType(layout.payload_ty, storage_class); | 4117 | const pl_ptr_ty_ref = try self.ptrType(layout.payload_ty, storage_class); |
| 4084 | const pl_ptr_id = try self.accessChain(pl_ptr_ty_ref, object_ptr, &.{layout.payload_index}); | 4118 | const pl_ptr_id = try self.accessChain(pl_ptr_ty_ref, object_ptr, &.{layout.payload_index}); |
| 4085 | | 4119 | |
| ... | @@ -4134,17 +4168,16 @@ const DeclGen = struct { | ... | @@ -4134,17 +4168,16 @@ const DeclGen = struct { |
| 4134 | .initializer = options.initializer, | 4168 | .initializer = options.initializer, |
| 4135 | }); | 4169 | }); |
| 4136 | | 4170 | |
| | 4171 | const target = self.getTarget(); |
| | 4172 | if (target.os.tag == .vulkan) { |
| | 4173 | return var_id; |
| | 4174 | } |
| | 4175 | |
| 4137 | switch (options.storage_class) { | 4176 | switch (options.storage_class) { |
| 4138 | .Generic => { | 4177 | .Generic => { |
| 4139 | const ptr_gn_ty_ref = try self.ptrType(ty, .Generic); | 4178 | const ptr_gn_ty_ref = try self.ptrType(ty, .Generic); |
| 4140 | // Convert to a generic pointer | 4179 | // Convert to a generic pointer |
| 4141 | const result_id = self.spv.allocId(); | 4180 | return self.castToGeneric(self.typeId(ptr_gn_ty_ref), var_id); |
| 4142 | try self.func.body.emit(self.spv.gpa, .OpPtrCastToGeneric, .{ | | |
| 4143 | .id_result_type = self.typeId(ptr_gn_ty_ref), | | |
| 4144 | .id_result = result_id, | | |
| 4145 | .pointer = var_id, | | |
| 4146 | }); | | |
| 4147 | return result_id; | | |
| 4148 | }, | 4181 | }, |
| 4149 | .Function => return var_id, | 4182 | .Function => return var_id, |
| 4150 | else => unreachable, | 4183 | else => unreachable, |
| ... | @@ -4880,7 +4913,7 @@ const DeclGen = struct { | ... | @@ -4880,7 +4913,7 @@ const DeclGen = struct { |
| 4880 | const is_non_null_id = blk: { | 4913 | const is_non_null_id = blk: { |
| 4881 | if (is_pointer) { | 4914 | if (is_pointer) { |
| 4882 | if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 4915 | if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 4883 | const storage_class = spvStorageClass(operand_ty.ptrAddressSpace(mod)); | 4916 | const storage_class = self.spvStorageClass(operand_ty.ptrAddressSpace(mod)); |
| 4884 | const bool_ptr_ty = try self.ptrType(Type.bool, storage_class); | 4917 | const bool_ptr_ty = try self.ptrType(Type.bool, storage_class); |
| 4885 | const tag_ptr_id = try self.accessChain(bool_ptr_ty, operand_id, &.{1}); | 4918 | const tag_ptr_id = try self.accessChain(bool_ptr_ty, operand_id, &.{1}); |
| 4886 | break :blk try self.load(Type.bool, tag_ptr_id, .{}); | 4919 | break :blk try self.load(Type.bool, tag_ptr_id, .{}); |