#vulkan: replacing @embedfile shaders with runtime known shaders

1 messages · Page 1 of 1 (latest)

plain silo
#

Hi, sorry for the bad title, couldn't think of a good one.

im having trouble, im trying to replace @embedfile with runtime known code, that way i don't have to recompile every time i change shader code.

    var shader_modules: [2]vk.ShaderModule = undefined;
    for (shader_paths, 0..) |s, i| {
        const shader_file = try std.fs.cwd().openFile(s, .{});
        defer shader_file.close();

        const spirv: []u8 align(@alignOf(u32)) = try allocator.alloc(u8, try shader_file.getEndPos());
        defer allocator.free(spirv);
        const shader_len = try shader_file.readAll(spirv);

        std.debug.assert(shader_len == spirv.len);

        const shader_mod = try gc.dev.createShaderModule(&.{
            .code_size = spirv.len,
            .p_code = @ptrCast(&spirv),
        }, null);
        shader_modules[i] = shader_mod;
    }

    defer gc.dev.destroyShaderModule(shader_modules[0], null);
    defer gc.dev.destroyShaderModule(shader_modules[1], null);

this code is for a vulkan shader module, the problem is, it expects a ?[*]const u32 array, but due to alignemnt or some other reason. the SPIRV code seems to be wrong.

readall expects a []u8, so i can't supply it with a []u32, i tried aligning as you see in the code, but it doesn't work either.

this is the vulkan error, although im not sure if it'll be much of help

VUID-VkShaderModuleCreateInfo-pCode-07912(ERROR / SPEC): msgNum: 979894520 - Validation Error: [ VUID-VkShaderModuleCreateInfo-pCode-07912 ] | MessageID = 0x3a6800f8 | vkCreateShaderModule(): pCreateInfo->pCode doesn't point to a SPIR-V module. The Vulkan spec states: If the VK_NV_glsl_shader extension is not enabled, pCode must be a pointer to SPIR-V code (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkShaderModuleCreateInfo-pCode-07912)
    Objects: 0
#

previously, the code worked just fine with just

const vert_spv align(@alignOf(u32)) = @embedFile("../shaders/vert.spv").*;
const frag_spv align(@alignOf(u32)) = @embedFile("../shaders/frag.spv").*;

but as i said, i want to move away from comptime known files.

#

vulkan: replacing @embedfile shaders with runtime known shaders

acoustic barn
#

are the files "../shaders/vert.spv"... supposed to be utf8 source or bytecode? why is the u32 alignment needed?

plain silo
#

bytecode

#

u32 is needed because uhh...yes, the vulkan-zig guide had the files embeded while aligned.
which i assume because vulkan expects an array of u32

#

to be clear, .spv files are shader files compiled to SPIRV.

acoustic barn
#

uh huh. where are these files gotten from?

#

does the build script compile them from some source?

#

there's a function alignedAlloc you may want to look into

#

pass the alignment of u32 in

#

also, what's the thing that requires a ?[*]const u32?

plain silo
acoustic barn
#

oh ok

plain silo
acoustic barn
#

oh i see

#

so what's your current problem right now

#

&spirv is going to be *const []u8 if i am not mistaken here (before being casted)

plain silo
#

i must've done the alignment wrong or the array setup wrong because vulkan throws an error that the compiled shader code is wrong

acoustic barn
#

did you try alignedAlloc as i pointed out?

#

does it give the same error

plain silo
#

yep

#
const spirv: []u8 align(@alignOf(u32)) = try allocator.alignedAlloc(u8, @alignOf(u32), try shader_file.getEndPos());
        defer allocator.free(spirv);
        const shader_len = try shader_file.readAll(spirv);

here's what i changed

acoustic barn
plain silo
#

yep

#
VUID-VkShaderModuleCreateInfo-pCode-07912(ERROR / SPEC): msgNum: 979894520 - Validation Error: [ VUID-VkShaderModuleCreateInfo-pCode-07912 ] | MessageID = 0x3a6800f8 | vkCreateShaderModule(): pCreateInfo->pCode doesn't point to a SPIR-V module. The Vulkan spec states: If the VK_NV_glsl_shader extension is not enabled, pCode must be a pointer to SPIR-V code (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkShaderModuleCreateInfo-pCode-07912)
    Objects: 0
VUID-VkShaderModuleCreateInfo-pCode-08737(ERROR / SPEC): msgNum: -1520283006 - Validation Error: [ VUID-VkShaderModuleCreateInfo-pCode-08737 ] | MessageID = 0xa5625282 | vkCreateShaderModule(): pCreateInfo->pCode (spirv-val produced an error):
Invalid SPIR-V magic number. The Vulkan spec states: If pCode is a pointer to SPIR-V code, pCode must adhere to the validation rules described by the Validation Rules within a Module section of the SPIR-V Environment appendix (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkShaderModuleCreateInfo-pCode-08737)
    Objects: 0

it's just the same two errors

acoustic barn
#

can you assert that @ptrCast(&spirv) is of type ?[*]const u32 by refactoring it into a separate value?

#

aka.

const intermediatry_ptr: ?[*]const u32 = @ptrCast(&spirv);
#

because what i feel is happening here is &spirv makes a pointer to the stack value where the spirv value lives

#

and when you pointer cast it, it just reads the slice and past it

#

you may need to remove that & in front of the spirv

acoustic barn
#

im glad that i could be of help

plain silo
#

thank you very much

#

i had a feeling it was ptrCast, but no way i would've guessed its a stack pointer

acoustic barn
#

yeah spirv itself is already []u8

#

which is something like a ptr + length struct

#

you'll read at most 4 u32's out of that value