authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-05-18 18:55:15+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-05-20 17:30:21+02:00
log6c055570720197af242b4c5538dd784d2e3a58f7
treef85e0efa0d9c488172c301542b528a89cf1a3797
parent0ba0d8fecb255cf19a225e4cb160921d73f83652
signaturelock-open Commit is signed but in an unrecognized format.

spirv: fix some (Ptr)AccessChain uses

The first dereference of PtrAccessChain returns a pointer of the same type as the base pointer, in contrast to AccessChain, where the first dereference returns a pointer of the dereferenced type of the base pointer.

1 files changed, 56 insertions(+), 50 deletions(-)

src/codegen/spirv.zig+56-50
......@@ -457,14 +457,8 @@ pub const DeclGen = struct {
457457 const members = spv_composite_ty.payload(.@"struct").members;
458458 for (constituents, members, 0..) |constitent_id, member, index| {
459459 const index_id = try self.constInt(index_ty_ref, index);
460 const ptr_id = self.spv.allocId();
461460 const ptr_member_ty_ref = try self.spv.ptrType(member.ty, .Generic, 0);
462 try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{
463 .id_result_type = self.typeId(ptr_member_ty_ref),
464 .id_result = ptr_id,
465 .base = ptr_composite_id,
466 .indexes = &.{index_id},
467 });
461 const ptr_id = try self.accessChain(ptr_member_ty_ref, ptr_composite_id, &.{index_id});
468462 try self.func.body.emit(self.spv.gpa, .OpStore, .{
469463 .pointer = ptr_id,
470464 .object = constitent_id,
......@@ -2089,6 +2083,44 @@ pub const DeclGen = struct {
20892083 return result_id;
20902084 }
20912085
2086 /// AccessChain is essentially PtrAccessChain with 0 as initial argument. The effective
2087 /// difference lies in whether the resulting type of the first dereference will be the
2088 /// same as that of the base pointer, or that of a dereferenced base pointer. AccessChain
2089 /// is the latter and PtrAccessChain is the former.
2090 fn accessChain(
2091 self: *DeclGen,
2092 result_ty_ref: SpvType.Ref,
2093 base: IdRef,
2094 indexes: []const IdRef,
2095 ) !IdRef {
2096 const result_id = self.spv.allocId();
2097 try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{
2098 .id_result_type = self.typeId(result_ty_ref),
2099 .id_result = result_id,
2100 .base = base,
2101 .indexes = indexes,
2102 });
2103 return result_id;
2104 }
2105
2106 fn ptrAccessChain(
2107 self: *DeclGen,
2108 result_ty_ref: SpvType.Ref,
2109 base: IdRef,
2110 element: IdRef,
2111 indexes: []const IdRef,
2112 ) !IdRef {
2113 const result_id = self.spv.allocId();
2114 try self.func.body.emit(self.spv.gpa, .OpInBoundsPtrAccessChain, .{
2115 .id_result_type = self.typeId(result_ty_ref),
2116 .id_result = result_id,
2117 .base = base,
2118 .element = element,
2119 .indexes = indexes,
2120 });
2121 return result_id;
2122 }
2123
20922124 fn cmp(
20932125 self: *DeclGen,
20942126 comptime op: std.math.CompareOperator,
......@@ -2353,12 +2385,12 @@ pub const DeclGen = struct {
23532385 const slice = try self.resolve(bin_op.lhs);
23542386 const index = try self.resolve(bin_op.rhs);
23552387
2356 const spv_ptr_ty = try self.resolveTypeId(self.air.typeOfIndex(inst));
2388 const ptr_ty_ref = try self.resolveType(self.air.typeOfIndex(inst), .direct);
23572389
23582390 const slice_ptr = blk: {
23592391 const result_id = self.spv.allocId();
23602392 try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{
2361 .id_result_type = spv_ptr_ty,
2393 .id_result_type = self.typeId(ptr_ty_ref),
23622394 .id_result = result_id,
23632395 .composite = slice,
23642396 .indexes = &.{0},
......@@ -2366,14 +2398,7 @@ pub const DeclGen = struct {
23662398 break :blk result_id;
23672399 };
23682400
2369 const result_id = self.spv.allocId();
2370 try self.func.body.emit(self.spv.gpa, .OpInBoundsPtrAccessChain, .{
2371 .id_result_type = spv_ptr_ty,
2372 .id_result = result_id,
2373 .base = slice_ptr,
2374 .element = index,
2375 });
2376 return result_id;
2401 return try self.ptrAccessChain(ptr_ty_ref, slice_ptr, index, &.{});
23772402 }
23782403
23792404 fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
......@@ -2385,12 +2410,12 @@ pub const DeclGen = struct {
23852410 const index = try self.resolve(bin_op.rhs);
23862411
23872412 var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined;
2388 const ptr_ty_id = try self.resolveTypeId(slice_ty.slicePtrFieldType(&slice_buf));
2413 const ptr_ty_ref = try self.resolveType(slice_ty.slicePtrFieldType(&slice_buf), .direct);
23892414
23902415 const slice_ptr = blk: {
23912416 const result_id = self.spv.allocId();
23922417 try self.func.body.emit(self.spv.gpa, .OpCompositeExtract, .{
2393 .id_result_type = ptr_ty_id,
2418 .id_result_type = self.typeId(ptr_ty_ref),
23942419 .id_result = result_id,
23952420 .composite = slice,
23962421 .indexes = &.{0},
......@@ -2398,17 +2423,7 @@ pub const DeclGen = struct {
23982423 break :blk result_id;
23992424 };
24002425
2401 const elem_ptr = blk: {
2402 const result_id = self.spv.allocId();
2403 try self.func.body.emit(self.spv.gpa, .OpInBoundsPtrAccessChain, .{
2404 .id_result_type = ptr_ty_id,
2405 .id_result = result_id,
2406 .base = slice_ptr,
2407 .element = index,
2408 });
2409 break :blk result_id;
2410 };
2411
2426 const elem_ptr = try self.ptrAccessChain(ptr_ty_ref, slice_ptr, index, &.{});
24122427 return try self.load(slice_ty, elem_ptr);
24132428 }
24142429
......@@ -2423,19 +2438,18 @@ pub const DeclGen = struct {
24232438 // TODO: Make this return a null ptr or something
24242439 if (!elem_ty.hasRuntimeBitsIgnoreComptime()) return null;
24252440
2426 const result_type_id = try self.resolveTypeId(result_ty);
2441 const result_ty_ref = try self.resolveType(result_ty, .direct);
24272442 const base_ptr = try self.resolve(bin_op.lhs);
24282443 const rhs = try self.resolve(bin_op.rhs);
24292444
2430 const result_id = self.spv.allocId();
2431 const indexes = [_]IdRef{rhs};
2432 try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{
2433 .id_result_type = result_type_id,
2434 .id_result = result_id,
2435 .base = base_ptr,
2436 .indexes = &indexes,
2437 });
2438 return result_id;
2445 if (ptr_ty.isSinglePointer()) {
2446 // Pointer-to-array. In this case, the resulting pointer is not of the same type
2447 // as the ptr_ty, and hence we need to use accessChain.
2448 return try self.accessChain(result_ty_ref, base_ptr, &.{rhs});
2449 } else {
2450 // Resulting pointer type is the same as the ptr_ty, so use ptrAccessChain
2451 return try self.ptrAccessChain(result_ty_ref, base_ptr, rhs, &.{});
2452 }
24392453 }
24402454
24412455 fn airStructFieldVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
......@@ -2480,16 +2494,8 @@ pub const DeclGen = struct {
24802494 const u32_ty_id = self.typeId(try self.intType(.unsigned, 32));
24812495 const field_index_id = self.spv.allocId();
24822496 try self.spv.emitConstant(u32_ty_id, field_index_id, .{ .uint32 = field_index });
2483 const result_id = self.spv.allocId();
2484 const result_type_id = try self.resolveTypeId(result_ptr_ty);
2485 const indexes = [_]IdRef{field_index_id};
2486 try self.func.body.emit(self.spv.gpa, .OpInBoundsAccessChain, .{
2487 .id_result_type = result_type_id,
2488 .id_result = result_id,
2489 .base = object_ptr,
2490 .indexes = &indexes,
2491 });
2492 return result_id;
2497 const result_ty_ref = try self.resolveType(result_ptr_ty, .direct);
2498 return try self.accessChain(result_ty_ref, object_ptr, &.{field_index_id});
24932499 },
24942500 },
24952501 else => unreachable, // TODO