| ... | @@ -1306,12 +1306,11 @@ pub const DeclGen = struct { | ... | @@ -1306,12 +1306,11 @@ pub const DeclGen = struct { |
| 1306 | }; | 1306 | }; |
| 1307 | | 1307 | |
| 1308 | const result_id = self.spv.allocId(); | 1308 | const result_id = self.spv.allocId(); |
| 1309 | const indexes = [_]IdRef{index}; | 1309 | try self.func.body.emit(self.spv.gpa, .OpInBoundsPtrAccessChain, .{ |
| 1310 | try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{ | | |
| 1311 | .id_result_type = spv_ptr_ty, | 1310 | .id_result_type = spv_ptr_ty, |
| 1312 | .id_result = result_id, | 1311 | .id_result = result_id, |
| 1313 | .base = slice_ptr, | 1312 | .base = slice_ptr, |
| 1314 | .indexes = &indexes, | 1313 | .element = index, |
| 1315 | }); | 1314 | }); |
| 1316 | return result_id; | 1315 | return result_id; |
| 1317 | } | 1316 | } |
| ... | @@ -1340,12 +1339,11 @@ pub const DeclGen = struct { | ... | @@ -1340,12 +1339,11 @@ pub const DeclGen = struct { |
| 1340 | | 1339 | |
| 1341 | const elem_ptr = blk: { | 1340 | const elem_ptr = blk: { |
| 1342 | const result_id = self.spv.allocId(); | 1341 | const result_id = self.spv.allocId(); |
| 1343 | const indexes = [_]IdRef{index}; | 1342 | try self.func.body.emit(self.spv.gpa, .OpInBoundsPtrAccessChain, .{ |
| 1344 | try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{ | | |
| 1345 | .id_result_type = ptr_ty_id, | 1343 | .id_result_type = ptr_ty_id, |
| 1346 | .id_result = result_id, | 1344 | .id_result = result_id, |
| 1347 | .base = slice_ptr, | 1345 | .base = slice_ptr, |
| 1348 | .indexes = &indexes, | 1346 | .element = index, |
| 1349 | }); | 1347 | }); |
| 1350 | break :blk result_id; | 1348 | break :blk result_id; |
| 1351 | }; | 1349 | }; |
| ... | @@ -1448,22 +1446,45 @@ pub const DeclGen = struct { | ... | @@ -1448,22 +1446,45 @@ pub const DeclGen = struct { |
| 1448 | fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 1446 | fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 1449 | if (self.liveness.isUnused(inst)) return null; | 1447 | if (self.liveness.isUnused(inst)) return null; |
| 1450 | const ty = self.air.typeOfIndex(inst); | 1448 | const ty = self.air.typeOfIndex(inst); |
| 1451 | const result_type_id = try self.resolveTypeId(ty); | 1449 | const result_ty_ref = try self.resolveType(ty, .direct); |
| | 1450 | const result_ty_id = self.typeId(result_ty_ref); |
| 1452 | const result_id = self.spv.allocId(); | 1451 | const result_id = self.spv.allocId(); |
| 1453 | | 1452 | |
| 1454 | // Rather than generating into code here, we're just going to generate directly into the functions section so that | | |
| 1455 | // variable declarations appear in the first block of the function. | | |
| 1456 | const storage_class = spirvStorageClass(ty.ptrAddressSpace()); | 1453 | const storage_class = spirvStorageClass(ty.ptrAddressSpace()); |
| 1457 | const section = if (storage_class == .Function or storage_class == .Generic) | | |
| 1458 | &self.func.prologue | | |
| 1459 | else | | |
| 1460 | &self.spv.sections.types_globals_constants; | | |
| 1461 | | 1454 | |
| | 1455 | const ptr_ty_id = switch (storage_class) { |
| | 1456 | .Generic => blk: { |
| | 1457 | const payload = try self.spv.arena.create(SpvType.Payload.Pointer); |
| | 1458 | payload.* = self.spv.typeRefType(result_ty_ref).payload(.pointer).*; |
| | 1459 | payload.storage_class = .Function; |
| | 1460 | break :blk try self.spv.resolveTypeId(SpvType.initPayload(&payload.base)); |
| | 1461 | }, |
| | 1462 | else => result_ty_id, |
| | 1463 | }; |
| | 1464 | const actual_storage_class = switch (storage_class) { |
| | 1465 | .Generic, .Function => .Function, |
| | 1466 | else => storage_class, |
| | 1467 | }; |
| | 1468 | const section = switch (storage_class) { |
| | 1469 | // SPIR-V requires that OpVariable declarations for locals go into the first block, so we are just going to |
| | 1470 | // directly generate them into func.prologue instead of the body. |
| | 1471 | .Generic, .Function => &self.func.prologue, |
| | 1472 | else => &self.spv.sections.types_globals_constants, |
| | 1473 | }; |
| 1462 | try section.emit(self.spv.gpa, .OpVariable, .{ | 1474 | try section.emit(self.spv.gpa, .OpVariable, .{ |
| 1463 | .id_result_type = result_type_id, | 1475 | .id_result_type = ptr_ty_id, |
| 1464 | .id_result = result_id, | 1476 | .id_result = result_id, |
| 1465 | .storage_class = storage_class, | 1477 | .storage_class = actual_storage_class, |
| 1466 | }); | 1478 | }); |
| | 1479 | if (storage_class == .Generic) { |
| | 1480 | const casted_result_id = self.spv.allocId(); |
| | 1481 | try self.func.body.emit(self.spv.gpa, .OpPtrCastToGeneric, .{ |
| | 1482 | .id_result_type = result_ty_id, |
| | 1483 | .id_result = casted_result_id, |
| | 1484 | .pointer = result_id, |
| | 1485 | }); |
| | 1486 | return casted_result_id; |
| | 1487 | } |
| 1467 | return result_id; | 1488 | return result_id; |
| 1468 | } | 1489 | } |
| 1469 | | 1490 | |