| ... | ... | @@ -20641,62 +20641,59 @@ fn zirReifySpirvType( |
| 20641 | 20641 | break :ip_data .{ |
| 20642 | 20642 | .name = name, |
| 20643 | 20643 | .zir_index = tracked_inst, |
| 20644 | | .ty = switch (usage_tag) { |
| 20645 | | .sampled, .unknown => blk: { |
| 20646 | | const sampled_type = usage_val.unionPayload(zcu).toType(); |
| 20647 | | std.hash.autoHash(&hasher, sampled_type.toIntern()); |
| 20644 | .ty = blk: { |
| 20645 | const sampled_type = usage_val.unionPayload(zcu).toType(); |
| 20646 | std.hash.autoHash(&hasher, sampled_type.toIntern()); |
| 20648 | 20647 | |
| 20649 | | if (target.os.tag != .opencl and sampled_type.toIntern() == .void_type) { |
| 20650 | | return sema.fail(block, operand_src, "'void' type for '{t}' field is only valid under the 'opencl' os", .{usage_tag}); |
| 20651 | | } |
| 20652 | | if (target.os.tag == .opencl and sampled_type.toIntern() != .void_type) { |
| 20653 | | return sema.fail(block, operand_src, "'{t}' field type must be 'void' under the 'opencl' os", .{usage_tag}); |
| 20654 | | } |
| 20648 | if (target.os.tag != .opencl and sampled_type.toIntern() == .void_type) { |
| 20649 | return sema.fail(block, operand_src, "'void' type for '{t}' field is only valid under the 'opencl' os", .{usage_tag}); |
| 20650 | } |
| 20651 | if (target.os.tag == .opencl and sampled_type.toIntern() != .void_type) { |
| 20652 | return sema.fail(block, operand_src, "'{t}' field type must be 'void' under the 'opencl' os", .{usage_tag}); |
| 20653 | } |
| 20655 | 20654 | |
| 20656 | | if (sampled_type.toIntern() != .void_type and |
| 20657 | | (!sampled_type.hasRuntimeBits(zcu) or (!sampled_type.isRuntimeFloat() and !sampled_type.isInt(zcu)))) |
| 20658 | | { |
| 20659 | | return sema.fail(block, operand_src, "invalid '{t}' field value '{f}'", .{ usage_tag, sampled_type.fmt(pt) }); |
| 20655 | if (sampled_type.toIntern() != .void_type and |
| 20656 | (!sampled_type.hasRuntimeBits(zcu) or (!sampled_type.isRuntimeFloat() and !sampled_type.isInt(zcu)))) |
| 20657 | { |
| 20658 | return sema.fail(block, operand_src, "invalid '{t}' field value '{f}'", .{ usage_tag, sampled_type.fmt(pt) }); |
| 20659 | } |
| 20660 | |
| 20661 | if (target.os.tag == .vulkan) { |
| 20662 | const ok = (sampled_type.isRuntimeFloat() and sampled_type.bitSize(zcu) == 32) or |
| 20663 | (sampled_type.isInt(zcu) and (sampled_type.bitSize(zcu) == 32 or sampled_type.bitSize(zcu) == 64)); |
| 20664 | if (!ok) { |
| 20665 | return sema.fail( |
| 20666 | block, |
| 20667 | operand_src, |
| 20668 | "'{t}' field value must be a 32-bit int, 64-bit int or 32-bit float under the 'vulkan' os", |
| 20669 | .{usage_tag}, |
| 20670 | ); |
| 20660 | 20671 | } |
| 20661 | 20672 | |
| 20662 | | if (target.os.tag == .vulkan) { |
| 20663 | | const ok = (sampled_type.isRuntimeFloat() and sampled_type.bitSize(zcu) == 32) or |
| 20664 | | (sampled_type.isInt(zcu) and (sampled_type.bitSize(zcu) == 32 or sampled_type.bitSize(zcu) == 64)); |
| 20665 | | if (!ok) { |
| 20673 | if (format != .unknown) { |
| 20674 | const format_kind: enum { float, sint, uint } = switch (format) { |
| 20675 | .rgba32f, .rgba16f, .rgba8unorm, .rgba8snorm, .r32f => .float, |
| 20676 | .rgba32i, .rgba16i, .rgba8i, .r32i => .sint, |
| 20677 | .rgba32u, .rgba16u, .rgba8u, .r32u => .uint, |
| 20678 | .unknown => unreachable, |
| 20679 | }; |
| 20680 | const matches = switch (format_kind) { |
| 20681 | .float => sampled_type.isRuntimeFloat(), |
| 20682 | .sint => sampled_type.isInt(zcu) and sampled_type.intInfo(zcu).signedness == .signed, |
| 20683 | .uint => sampled_type.isInt(zcu) and sampled_type.intInfo(zcu).signedness == .unsigned, |
| 20684 | }; |
| 20685 | if (!matches) { |
| 20666 | 20686 | return sema.fail( |
| 20667 | 20687 | block, |
| 20668 | 20688 | operand_src, |
| 20669 | | "'{t}' field value must be a 32-bit int, 64-bit int or 32-bit float under the 'vulkan' os", |
| 20670 | | .{usage_tag}, |
| 20689 | "image 'format' '.{t}' does not match '{t}' type '{f}' under the 'vulkan' os", |
| 20690 | .{ format, usage_tag, sampled_type.fmt(pt) }, |
| 20671 | 20691 | ); |
| 20672 | 20692 | } |
| 20673 | | |
| 20674 | | if (format != .unknown) { |
| 20675 | | const format_kind: enum { float, sint, uint } = switch (format) { |
| 20676 | | .rgba32f, .rgba16f, .rgba8unorm, .rgba8snorm, .r32f => .float, |
| 20677 | | .rgba32i, .rgba16i, .rgba8i, .r32i => .sint, |
| 20678 | | .rgba32u, .rgba16u, .rgba8u, .r32u => .uint, |
| 20679 | | .unknown => unreachable, |
| 20680 | | }; |
| 20681 | | const matches = switch (format_kind) { |
| 20682 | | .float => sampled_type.isRuntimeFloat(), |
| 20683 | | .sint => sampled_type.isInt(zcu) and sampled_type.intInfo(zcu).signedness == .signed, |
| 20684 | | .uint => sampled_type.isInt(zcu) and sampled_type.intInfo(zcu).signedness == .unsigned, |
| 20685 | | }; |
| 20686 | | if (!matches) { |
| 20687 | | return sema.fail( |
| 20688 | | block, |
| 20689 | | operand_src, |
| 20690 | | "image 'format' '.{t}' does not match '{t}' type '{f}' under the 'vulkan' os", |
| 20691 | | .{ format, usage_tag, sampled_type.fmt(pt) }, |
| 20692 | | ); |
| 20693 | | } |
| 20694 | | } |
| 20695 | 20693 | } |
| 20694 | } |
| 20696 | 20695 | |
| 20697 | | break :blk sampled_type.toIntern(); |
| 20698 | | }, |
| 20699 | | .storage => .none, |
| 20696 | break :blk sampled_type.toIntern(); |
| 20700 | 20697 | }, |
| 20701 | 20698 | .flags = .{ |
| 20702 | 20699 | .tag = .image, |