gpu.executionMode in 0.15.1

Is it normal that std.gpu.executionMode stopped working after upgrading from 0.15.0-dev.1254+c9ce1debe to 0.15.1 ? Is there any alternatives now? I only found this, which hasn’t been merged yet, and I’d prefer to use stable version.

error: failed to assemble SPIR-V inline assembly
note: cannot set execution mode in assembly

Hello @MaxCross2500,
Welcome to ziggit :slight_smile:

What is the problem with std.gpu.executionMode? Do you get some error?

Also note that SPIR-V is mentioned in 0.15.1 release notes:

Zig now allows using LLVM’s SPIR-V backend. Note that the self-hosted SPIR-V backend remains the default. To use the LLVM backend, build with -fllvm.

I’m getting errors that I specified in original post.

Full code and errors:

const gpu = @import("std").gpu;
const zm = @import("zmath");

export fn vert() callconv(.spirv_vertex) void {
    vertex.main();
}

pub const vertex = struct {
    const UBO = struct {
        offset: zm.F32x4,
        projection: zm.Mat,
    };
    const uniform = @extern(*addrspace(.uniform) UBO, .{ .name = "ubo" });
    const in = struct {
        const position = @extern(*addrspace(.input) @Vector(3, f32), .{ .name = "position.in" });
        const uv = @extern(*addrspace(.input) @Vector(2, f32), .{ .name = "uv.in" });
    };
    const out = struct {
        const position = gpu.position_out;
        const uv = @extern(*addrspace(.output) @Vector(2, f32), .{ .name = "uv.out" });
    };

    pub inline fn main() void {
        gpu.location(in.position, 0);
        gpu.location(in.uv, 1);
        gpu.location(out.uv, 1);
        gpu.binding(uniform, 1, 0);

        const position: @Vector(4, f32) = .{ in.position.*[0], in.position.*[1], in.position.*[2], 1 };
        out.position.* = zm.mul(position, uniform.projection);
        // out.position[2] = 1;
        // out.position[3] = 1;

        // out.position.* = .{ in.position.*[0], in.position.*[1], in.position.*[2], 1 };
        // out.position.* += uniform.offset;

        out.uv.* = in.uv.*;
    }
};

export fn frag() callconv(.spirv_fragment) void {
    fragment.main();
}

const fragment = struct {
    const in = struct {
        const uv = @extern(*addrspace(.input) @Vector(2, f32), .{ .name = "uv.in" });
    };

    const out = struct {
        const color = @extern(*addrspace(.output) @Vector(4, f32), .{ .name = "color.out" });
    };

    pub inline fn main() void {
        gpu.executionMode(frag, .origin_upper_left);
        gpu.location(in.uv, 1);
        gpu.location(out.color, 0);

        out.color.* = sampler2d(2, 0, in.uv.*);
    }
};

pub fn sampler2d(
    comptime set: u32,
    comptime bind: u32,
    uv: @Vector(2, f32),
) @Vector(4, f32) {
    return asm volatile (
        \\%float          = OpTypeFloat 32
        \\%v4float        = OpTypeVector %float 4
        \\%img_type       = OpTypeImage %float 2D 0 0 0 1 Unknown
        \\%sampler_type   = OpTypeSampledImage %img_type
        \\%sampler_ptr    = OpTypePointer UniformConstant %sampler_type
        \\%tex            = OpVariable %sampler_ptr UniformConstant
        \\                  OpDecorate %tex DescriptorSet $set
        \\                  OpDecorate %tex Binding $bind
        \\%loaded_sampler = OpLoad %sampler_type %tex
        \\%ret            = OpImageSampleImplicitLod %v4float %loaded_sampler %uv
        : [ret] "" (-> @Vector(4, f32)),
        : [uv] "" (uv),
          [set] "c" (set),
          [bind] "c" (bind),
    );
}
/home/maxcross/.cache/zig/p/N-V-__8AAN5NhBR0oTsvnwjPdeNiiDLtEsfXRHd1fv-R3TOv/lib/std/gpu.zig:84:5: error: failed to assemble SPIR-V inline assembly
pub fn executionMode(comptime entry_point: anytype, comptime mode: ExecutionMode) void {
~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/maxcross/.cache/zig/p/N-V-__8AAN5NhBR0oTsvnwjPdeNiiDLtEsfXRHd1fv-R3TOv/lib/std/gpu.zig:84:5: note: cannot set execution mode in assembly

I believe that there are remains from different zig versions in your cache.
Try to clean your cache folder ( /home/maxcross/.cache/zig).

Deleted it and also .zig-cache and zig-out in project folder - still the same error.
I mean - error explicitly says that execution mode cannot be set in assembly, and that what std.gpu.executionMode is trying to do - I don’t think that clearing the cache would change that.

On the 0.15.x branch the SPIR-V assembler unconditionally fails when assembling the OpExecutionMode instruction.

But browsing the code using the c9ce1debe commit reveals that there was code that assembles the instruction:

The commit that changes/removes the code is: 31de2c8 spirv: refactor
The change might be unintended!

1 Like

The change is intentional. We are switching to a better way to set execution mode by using callconv instead. See Expand SPIR-V features by DialecticalMaterialist · Pull Request #24681 · ziglang/zig · GitHub.

Sorry for the breakage.

3 Likes