From e229da931500672f11486ab5b718d8baa2c6d583 Mon Sep 17 00:00:00 2001 From: sergeypdev Date: Sun, 15 Dec 2024 22:52:44 +0400 Subject: [PATCH] Simplify things, use just one pipeline layout for all shaders (nice), remove spirv-reflect --- build.zig | 6 --- build.zig.zon | 4 -- src/AssetManager.zig | 58 +-------------------------- src/DescriptorManager.zig | 43 +++++++++----------- src/GraphicsContext.zig | 3 ++ src/Render2.zig | 82 ++++++++++++--------------------------- src/formats.zig | 4 -- src/game.zig | 8 +--- tools/asset_compiler.zig | 75 +++-------------------------------- 9 files changed, 54 insertions(+), 229 deletions(-) diff --git a/build.zig b/build.zig index 2f9376e..f409019 100644 --- a/build.zig +++ b/build.zig @@ -282,12 +282,7 @@ fn buildAssetCompiler(b: *Build, optimize: std.builtin.OptimizeMode, assets_mod: .skip_tests = true, }); const zalgebra_dep = b.dependency("zalgebra", .{}); - const spirv_reflect_dep = b.dependency("SPIRV-Reflect", .{ - .target = b.host, - .optimize = optimize, - }); const assimp_lib = assimp_dep.artifact("assimp"); - const spirv_reflect_lib = spirv_reflect_dep.artifact("spirv-reflect"); const assetc = b.addExecutable(.{ .name = "assetc", @@ -317,7 +312,6 @@ fn buildAssetCompiler(b: *Build, optimize: std.builtin.OptimizeMode, assets_mod: assetc.root_module.addImport("assets", assets_mod); assetc.linkLibrary(assimp_lib); - assetc.linkLibrary(spirv_reflect_lib); assetc.linkLibC(); assetc.linkLibCpp(); diff --git a/build.zig.zon b/build.zig.zon index 5c4d63d..1e73f1b 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -51,10 +51,6 @@ .url = "https://github.com/hexops/spirv-cross/tarball/872bd405fece4bf6388abdea916356e26cb8fed9", .hash = "12207bebf82eef06f4f80a7e54c91e4402c0055d04167fdbcf1f350846a350266976", }, - .@"SPIRV-Reflect" = .{ - .url = "https://github.com/sergeypdev/SPIRV-Reflect/tarball/bb3e8b8d5dee32b65e1d16598c526415470fc863", - .hash = "122048fdee255a7ac992068d5ded4bfa88927ddc8af12a5068c69198153a60dbe779", - }, }, .paths = .{ // This makes *all* files, recursively, included in this package. It is generally diff --git a/src/AssetManager.zig b/src/AssetManager.zig index e6181df..e94e694 100644 --- a/src/AssetManager.zig +++ b/src/AssetManager.zig @@ -320,65 +320,12 @@ pub fn loadShaderProgram(self: *AssetManager, handle: Handle.ShaderProgram) Load }; } -fn getPushConstantRanges(program: formats.ShaderProgram, buffer: []vk.PushConstantRange) []vk.PushConstantRange { - var len: usize = 0; - switch (program) { - .graphics => { - std.debug.assert(buffer.len >= 2); - if (program.graphics.vertex.push_constant_range.size > 0) { - buffer[len] = vk.PushConstantRange{ - .offset = program.graphics.vertex.push_constant_range.offset, - .size = program.graphics.vertex.push_constant_range.size, - .stage_flags = .{ .vertex_bit = true }, - }; - - len += 1; - } - if (program.graphics.fragment.push_constant_range.size > 0) { - buffer[len] = vk.PushConstantRange{ - .offset = program.graphics.fragment.push_constant_range.offset, - .size = program.graphics.fragment.push_constant_range.size, - .stage_flags = .{ .fragment_bit = true }, - }; - - len += 1; - } - }, - .compute => { - std.debug.assert(buffer.len >= 1); - if (program.compute.compute.push_constant_range.size > 0) { - buffer[len] = vk.PushConstantRange{ - .offset = program.compute.compute.push_constant_range.offset, - .size = program.graphics.vertex.push_constant_range.size, - .stage_flags = .{ .compute_bit = true }, - }; - - len += 1; - } - }, - } - - return buffer[0..len]; -} - fn loadShaderProgramErr(self: *AssetManager, id: AssetId) !LoadedShaderProgram { const data = try self.loadFile(self.frame_arena, asset_manifest.getPath(id), SHADER_MAX_BYTES); var serializer = formats.Serializer{ .write = false, .endian = formats.native_endian, .stream = .{ .buffer = std.io.fixedBufferStream(data.bytes) } }; var program: formats.ShaderProgram = undefined; try program.serialize(&serializer); - var push_constant_ranges_buf: [2]vk.PushConstantRange = undefined; - const push_constant_ranges = getPushConstantRanges(program, &push_constant_ranges_buf); - std.debug.print("push constant ranges: {any}\n", .{push_constant_ranges}); - - // TODO: parse from shaders or something - const pipeline_layout = try self.gc.device.createPipelineLayout(&.{ - .p_set_layouts = &.{self.descriptorman.descriptor_set_layouts.global}, - .set_layout_count = 1, - .push_constant_range_count = @intCast(push_constant_ranges.len), - .p_push_constant_ranges = push_constant_ranges.ptr, - }, null); - const pipeline = blk: { switch (program) { .graphics => |graphics_pipeline| { @@ -433,7 +380,7 @@ fn loadShaderProgramErr(self: *AssetManager, id: AssetId) !LoadedShaderProgram { .line_width = 1.0, }, .p_viewport_state = &vk.PipelineViewportStateCreateInfo{}, - .layout = pipeline_layout, + .layout = self.descriptorman.pipeline_layout, .p_depth_stencil_state = &vk.PipelineDepthStencilStateCreateInfo{ // Dynamic States .depth_test_enable = vk.FALSE, @@ -523,7 +470,6 @@ fn loadShaderProgramErr(self: *AssetManager, id: AssetId) !LoadedShaderProgram { const loaded_shader_program = LoadedShaderProgram{ .pipeline = pipeline, - .layout = pipeline_layout, }; { @@ -546,7 +492,6 @@ const NullShader = LoadedShader{ const NullShaderProgram = LoadedShaderProgram{ .pipeline = .null_handle, - .layout = .null_handle, }; const NullMesh = LoadedMesh{ @@ -836,7 +781,6 @@ const LoadedShader = struct { const LoadedShaderProgram = struct { pipeline: vk.Pipeline, - layout: vk.PipelineLayout, }; pub const LoadedMesh = struct { diff --git a/src/DescriptorManager.zig b/src/DescriptorManager.zig index ecf5edf..8bb783e 100644 --- a/src/DescriptorManager.zig +++ b/src/DescriptorManager.zig @@ -156,6 +156,8 @@ gc: *GraphicsContext, descriptor_set_layouts: DescriptorSetLayouts = .{}, image_descriptor_array_2d: DescriptorArray(SampledImageDescriptorData, 1024) = .{}, +pipeline_layout: vk.PipelineLayout = .null_handle, + pub fn init(gc: *GraphicsContext) !DescriptorManager { var self = DescriptorManager{ .gc = gc, @@ -201,30 +203,23 @@ pub fn init(gc: *GraphicsContext) !DescriptorManager { }, null); } - // Post Process Pass Descriptor Set Layout - // { - // const descriptor_set_layout_bindings = [_]vk.DescriptorSetLayoutBinding{ - // vk.DescriptorSetLayoutBinding{ - // .binding = DescriptorSets.Passes.PostProcess.Bindings.ScreenSampler.value(), - // .descriptor_type = .sampler, - // .descriptor_count = 1, - // .stage_flags = vk.ShaderStageFlags.fromInt(0x7FFFFFFF), // SHADER_STAGE_ALL - // }, - // vk.DescriptorSetLayoutBinding{ - // .binding = DescriptorSets.Passes.PostProcess.Bindings.ScreenTexture.value(), - // .descriptor_type = .sampled_image, - // .descriptor_count = 1, - // .stage_flags = vk.ShaderStageFlags.fromInt(0x7FFFFFFF), // SHADER_STAGE_ALL - // }, - // }; - // self.descriptor_set_layouts.passes.post_process = try self.gc.device.createDescriptorSetLayout(&.{ - // .flags = .{ - // .push_descriptor_bit_khr = true, - // }, - // .p_bindings = &descriptor_set_layout_bindings, - // .binding_count = descriptor_set_layout_bindings.len, - // }, null); - // } + self.pipeline_layout = try self.gc.device.createPipelineLayout(&.{ + .set_layout_count = 1, + .p_set_layouts = &.{self.descriptor_set_layouts.global}, + .push_constant_range_count = 2, + .p_push_constant_ranges = &.{ + vk.PushConstantRange{ + .stage_flags = .{ .vertex_bit = true }, + .offset = 0, + .size = 128, + }, + vk.PushConstantRange{ + .stage_flags = .{ .fragment_bit = true }, + .offset = 0, + .size = 128, + }, + }, + }, null); return self; } diff --git a/src/GraphicsContext.zig b/src/GraphicsContext.zig index 7843b31..a88bc0a 100644 --- a/src/GraphicsContext.zig +++ b/src/GraphicsContext.zig @@ -520,6 +520,9 @@ fn maybeResizeSwapchain(self: *GraphicsContext) !void { return; } + std.debug.print("resizing swapchain {}\n", .{new_extent}); + self.swapchain_extent = new_extent; + if (self.swapchain_images.len > 0) { self.allocator.free(self.swapchain_images); self.swapchain_images = &.{}; diff --git a/src/Render2.zig b/src/Render2.zig index 8ffbdcd..4ba1faf 100644 --- a/src/Render2.zig +++ b/src/Render2.zig @@ -30,7 +30,7 @@ pub const Camera = struct { var default_camera: Camera = .{}; const MAX_FRAME_LAG = 3; -const PER_FRAME_ARENA_SIZE = 64 * common.MB; +const PER_FRAME_ARENA_SIZE = 256 * common.MB; frame_allocator: std.mem.Allocator, gc: *GraphicsContext, @@ -116,16 +116,13 @@ pub const VulkanPerFrameArena = struct { // Record start position of this frame if (self.frame_regions[self.frame]) |*cur_region| { cur_region.end = self.tail; + + // std.debug.print("frame {} region: {}-{}, wraps: {}\n", .{ self.frame, cur_region.start, cur_region.end, cur_region.end < cur_region.start }); } self.frame = frame_index; self.frame_regions[self.frame] = FrameRegion.init(self.tail, self.tail); } - // Caller guarantees that memory from given frame can be safely stomped, buffers destroyed etc. - pub fn resetFrame(self: *VulkanPerFrameArena, frame_index: u32) void { - self.frame_regions[frame_index] = null; - } - pub fn getModifiedMemoryRanges(self: *VulkanPerFrameArena, out_ranges: []vk.MappedMemoryRange) []const vk.MappedMemoryRange { std.debug.assert(out_ranges.len >= 2); std.debug.assert(self.frame_regions[self.frame] != null); @@ -178,6 +175,7 @@ pub const VulkanPerFrameArena = struct { const allocated_region = FrameRegion.init(offset, offset + size); if (next_frame_region.intersectsWrapping(&allocated_region, self.size)) { + // std.debug.print("overlapped alloc of size: {d}MB align: {}\n", .{ @as(f32, @floatFromInt(size)) / common.MB, alignment }); return error.OverlapsPreviousFrame; } } @@ -412,10 +410,10 @@ fn createPerFrameBuffer(self: *Render2, usage: vk.BufferUsageFlags, size: u64, o error.OverlapsPreviousFrame => { const overlapped_frame = (self.frame + 1) % MAX_FRAME_LAG; - std.debug.print("Vulkan Frame Allocator Overlapped frame {}, waiting for it to finish...", .{overlapped_frame}); + std.debug.print("Vulkan Frame Allocator Overlapped frame {}, waiting for it to finish...\n", .{overlapped_frame}); try self.frame_data[overlapped_frame].waitForDrawAndReset(self); - self.vulkan_frame_arena.resetFrame(overlapped_frame); + self.vulkan_frame_arena.frame_regions[overlapped_frame] = null; }, else => return err, } @@ -430,10 +428,10 @@ fn createPerFrameImage(self: *Render2, create_info: *const vk.ImageCreateInfo, o error.OverlapsPreviousFrame => { const overlapped_frame = (self.frame + 1) % MAX_FRAME_LAG; - std.debug.print("Vulkan Frame Allocator Overlapped frame {}, waiting for it to finish...", .{overlapped_frame}); + std.debug.print("Vulkan Frame Allocator Overlapped frame {}, waiting for it to finish...\n", .{overlapped_frame}); try self.frame_data[overlapped_frame].waitForDrawAndReset(self); - self.vulkan_frame_arena.resetFrame(overlapped_frame); + self.vulkan_frame_arena.frame_regions[overlapped_frame] = null; }, else => return err, } @@ -453,8 +451,8 @@ fn createPerFrameImageDescriptor(self: *Render2, view: vk.ImageView, layout: vk. return result; } -fn pushConstants(cmds: GraphicsContext.CommandBuffer, layout: vk.PipelineLayout, stage_flags: vk.ShaderStageFlags, value: anytype) void { - cmds.pushConstants(layout, stage_flags, 0, @sizeOf(@TypeOf(value)), &value); +fn pushConstants(self: *Render2, cmds: GraphicsContext.CommandBuffer, stage_flags: vk.ShaderStageFlags, value: anytype) void { + cmds.pushConstants(self.descriptorman.pipeline_layout, stage_flags, 0, @sizeOf(@TypeOf(value)), &value); } pub fn draw(self: *Render2) !void { @@ -463,17 +461,19 @@ pub fn draw(self: *Render2) !void { const frame = &self.frame_data[self.frame]; try frame.waitForDrawAndReset(self); - self.vulkan_frame_arena.resetFrame(self.frame); + + const swapchain_image_index: u32 = try gc.acquireSwapchainImage(frame.acquire_swapchain_image); + self.vulkan_frame_arena.startFrame(self.frame); var global_buffer_addr: u64 = 0; const global_uniform_buffer_handle = try self.createPerFrameBuffer(.{ .uniform_buffer_bit = true, .transfer_dst_bit = true }, @sizeOf(GlobalUniform), &global_buffer_addr); var global_uniform_buffer = GraphicsContext.Buffer{ .gc = gc, .handle = global_uniform_buffer_handle, .size = @sizeOf(GlobalUniform) }; + self.camera.aspect = @as(f32, @floatFromInt(self.gc.swapchain_extent.width)) / @as(f32, @floatFromInt(self.gc.swapchain_extent.height)); + const global_uniform = blk: { const view = self.camera.view_mat; - // const fwidth: f32 = @floatFromInt(gc.swapchain_extent.width); - // const fheight: f32 = @floatFromInt(gc.swapchain_extent.height); const projection = self.camera.projection(); const view_projection = projection.mul(view); @@ -486,9 +486,6 @@ pub fn draw(self: *Render2) !void { }; }; - // Move this out into a separate func - const swapchain_image_index: u32 = try gc.acquireSwapchainImage(frame.acquire_swapchain_image); - var main_render_target = try self.allocateRenderTarget(); const color_image: *GraphicsContext.Image = &main_render_target.color; @@ -607,7 +604,7 @@ pub fn draw(self: *Render2) !void { .color_attachment_count = 1, .p_color_attachments = &.{ vk.RenderingAttachmentInfo{ - .clear_value = .{ .color = .{ .float_32 = .{ 0.8, 0.7, 0.6, 1.0 } } }, + .clear_value = .{ .color = .{ .float_32 = .{ 0.9, 0.8, 0.7, 1.0 } } }, .load_op = .clear, .store_op = .store, .image_layout = .color_attachment_optimal, @@ -644,7 +641,7 @@ pub fn draw(self: *Render2) !void { const triangle = self.assetman.resolveShaderProgram(a.ShaderPrograms.shaders.triangle); cmds.bindPipeline(.graphics, triangle.pipeline); - cmds.bindDescriptorSets(.graphics, triangle.layout, 0, 1, &.{global_descriptor_set}, 0, null); + cmds.bindDescriptorSets(.graphics, self.descriptorman.pipeline_layout, 0, 1, &.{global_descriptor_set}, 0, null); cmds.setViewportWithCount(1, &.{vk.Viewport{ .x = 0, @@ -709,9 +706,9 @@ pub fn draw(self: *Render2) !void { const post_process = self.assetman.resolveShaderProgram(a.ShaderPrograms.shaders.post_process); cmds.bindPipeline(.graphics, post_process.pipeline); - cmds.bindDescriptorSets(.graphics, post_process.layout, 0, 1, &.{global_descriptor_set}, 0, null); + cmds.bindDescriptorSets(.graphics, self.descriptorman.pipeline_layout, 0, 1, &.{global_descriptor_set}, 0, null); - pushConstants(cmds, post_process.layout, .{ .fragment_bit = true }, PostProcessPushConstants{ + self.pushConstants(cmds, .{ .vertex_bit = true, .fragment_bit = true }, PostProcessPushConstants{ .scene_color_texture = main_render_target.color_descriptor.index(), .scene_color_sampler = 0, }); @@ -732,42 +729,6 @@ pub fn draw(self: *Render2) !void { cmds.draw(6, 1, 0, 0); } - // Direct blit without PP - // if (false) { - // try color_image.sync(cmds, .{ .stage_mask = .{ .blit_bit = true }, .access_mask = .{ .transfer_read_bit = true } }, .transfer_src_optimal, .{ .color_bit = true }); - // try swapchain_image.sync(cmds, .{ .stage_mask = .{ .blit_bit = true }, .access_mask = .{ .transfer_write_bit = true } }, .transfer_dst_optimal, .{ .color_bit = true }); - // cmds.blitImage( - // color_image.handle, - // color_image.sync_state.layout, - // swapchain_image.handle, - // swapchain_image.sync_state.layout, - // 1, - // &.{vk.ImageBlit{ - // .src_subresource = vk.ImageSubresourceLayers{ - // .aspect_mask = .{ .color_bit = true }, - // .mip_level = 0, - // .base_array_layer = 0, - // .layer_count = 1, - // }, - // .src_offsets = .{ - // vk.Offset3D{ .x = 0, .y = 0, .z = 0 }, - // vk.Offset3D{ .x = @intCast(gc.swapchain_extent.width), .y = @intCast(gc.swapchain_extent.height), .z = 1 }, - // }, - // .dst_subresource = vk.ImageSubresourceLayers{ - // .aspect_mask = .{ .color_bit = true }, - // .mip_level = 0, - // .base_array_layer = 0, - // .layer_count = 1, - // }, - // .dst_offsets = .{ - // vk.Offset3D{ .x = 0, .y = 0, .z = 0 }, - // vk.Offset3D{ .x = @intCast(gc.swapchain_extent.width), .y = @intCast(gc.swapchain_extent.height), .z = 1 }, - // }, - // }}, - // .nearest, - // ); - // } - try swapchain_image.sync(cmds, .{ .stage_mask = .{}, .access_mask = .{} }, .present_src_khr, .{ .color_bit = true }); } try cmds.endCommandBuffer(); @@ -781,6 +742,7 @@ pub fn draw(self: *Render2) !void { }, frame.draw_fence, ); + frame.draw_submitted = true; _ = try gc.device.queuePresentKHR(gc.queues.graphics.handle, &.{ .swapchain_count = 1, @@ -814,6 +776,7 @@ const FrameData = struct { acquire_swapchain_image: vk.Semaphore, draw_sema: vk.Semaphore, draw_fence: vk.Fence, + draw_submitted: bool = true, command_buffer: GraphicsContext.CommandBuffer, @@ -861,6 +824,9 @@ const FrameData = struct { } pub fn waitForDrawAndReset(self: *FrameData, render: *Render2) !void { + if (!self.draw_submitted) return; + + self.draw_submitted = false; const device = render.gc.device; _ = try device.waitForFences(1, &.{self.draw_fence}, vk.TRUE, std.math.maxInt(u64)); try device.resetFences(1, &.{self.draw_fence}); diff --git a/src/formats.zig b/src/formats.zig index 49c6d17..229cb51 100644 --- a/src/formats.zig +++ b/src/formats.zig @@ -130,13 +130,9 @@ pub const ShaderProgram = union(ShaderProgramPipelineType) { pub const ShaderStage = struct { source: []align(4) u8, - push_constant_range: PushConstantRange, - pub fn serialize(self: *ShaderStage, serializer: *Serializer) !void { try serializer.skipAlign(4); try serializer.serializeByteSlice(&self.source); - try serializer.serializeInt(u32, &self.push_constant_range.offset); - try serializer.serializeInt(u32, &self.push_constant_range.size); } }; diff --git a/src/game.zig b/src/game.zig index 7d0ba8f..9c603d5 100644 --- a/src/game.zig +++ b/src/game.zig @@ -406,8 +406,8 @@ export fn game_update() bool { c.SDL_WINDOWEVENT => { switch (event.window.event) { c.SDL_WINDOWEVENT_SIZE_CHANGED => { - c.SDL_GL_GetDrawableSize(ginit.window, &ginit.width, &ginit.height); - std.log.debug("w: {}, h: {}\n", .{ ginit.width, ginit.height }); + // c.SDL_GL_GetDrawableSize(ginit.window, &ginit.width, &ginit.height); + // std.log.debug("w: {}, h: {}\n", .{ ginit.width, ginit.height }); // gl.viewport(0, 0, ginit.width, ginit.height); }, @@ -443,10 +443,6 @@ export fn game_update() bool { move.zMut().* -= 1; } - const f_width: f32 = @floatFromInt(ginit.width); - const f_height: f32 = @floatFromInt(ginit.height); - - gmem.free_cam.camera.aspect = f_width / f_height; gmem.rotation += 60 * gmem.delta_time; // TODO: make this an entity diff --git a/tools/asset_compiler.zig b/tools/asset_compiler.zig index bbc4f94..4cec663 100644 --- a/tools/asset_compiler.zig +++ b/tools/asset_compiler.zig @@ -21,8 +21,6 @@ const c = @cImport({ @cInclude("stb_image.h"); @cInclude("ispc_texcomp.h"); - - @cInclude("spirv_reflect.h"); }); const ASSET_MAX_BYTES = 1024 * 1024 * 1024; @@ -585,19 +583,9 @@ fn readFileContents(allocator: std.mem.Allocator, path: []const u8) ![]u8 { }; } -const PushConstantRange = struct { - offset: u32 = 0, - size: u32 = 0, -}; - -const ProcessedShader = struct { - spirv: []u8, - push_constant_range: PushConstantRange = .{}, -}; - // Returns spirv binary source // Caller owns memory -fn processShader(allocator: std.mem.Allocator, flags: []const []const u8, input: []const u8, maybe_dep_file: ?[]const u8) !ProcessedShader { +fn processShader(allocator: std.mem.Allocator, flags: []const []const u8, input: []const u8, maybe_dep_file: ?[]const u8) ![]u8 { // const old_depfile_contents = if (maybe_dep_file) |dep| try readFileContents(allocator, dep) else try allocator.alloc(u8, 0); // defer allocator.free(old_depfile_contents); @@ -626,57 +614,7 @@ fn processShader(allocator: std.mem.Allocator, flags: []const []const u8, input: }, } - // TODO: align pointer to 4 bytes - var result = ProcessedShader{ .spirv = compile_result.stdout }; - - { - var shader_module: c.SpvReflectShaderModule = std.mem.zeroes(c.SpvReflectShaderModule); - try spvReflectTry(c.spvReflectCreateShaderModule(compile_result.stdout.len, compile_result.stdout.ptr, &shader_module)); - defer c.spvReflectDestroyShaderModule(&shader_module); - - var spv_result: c.SpvReflectResult = c.SPV_REFLECT_RESULT_SUCCESS; - const push_constant_block: ?*const c.SpvReflectBlockVariable = @ptrCast(c.spvReflectGetEntryPointPushConstantBlock(&shader_module, "main", &spv_result)); - spvReflectTry(spv_result) catch |err| switch (err) { - error.SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND => {}, - else => return err, - }; - - if (push_constant_block) |block| { - // Assuming single push constant block per stage, this is what glslc enforces - std.debug.assert(shader_module.push_constant_block_count == 1); - result.push_constant_range = .{ .offset = block.offset, .size = block.size }; - } - } - - return result; -} - -fn spvReflectTry(result: c.SpvReflectResult) !void { - switch (result) { - c.SPV_REFLECT_RESULT_SUCCESS => {}, - c.SPV_REFLECT_RESULT_NOT_READY => return error.SPV_REFLECT_RESULT_NOT_READY, - c.SPV_REFLECT_RESULT_ERROR_PARSE_FAILED => return error.SPV_REFLECT_RESULT_ERROR_PARSE_FAILED, - c.SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED => return error.SPV_REFLECT_RESULT_ERROR_ALLOC_FAILED, - c.SPV_REFLECT_RESULT_ERROR_RANGE_EXCEEDED => return error.SPV_REFLECT_RESULT_ERROR_RANGE_EXCEEDED, - c.SPV_REFLECT_RESULT_ERROR_NULL_POINTER => return error.SPV_REFLECT_RESULT_ERROR_NULL_POINTER, - c.SPV_REFLECT_RESULT_ERROR_INTERNAL_ERROR => return error.SPV_REFLECT_RESULT_ERROR_INTERNAL_ERROR, - c.SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH => return error.SPV_REFLECT_RESULT_ERROR_COUNT_MISMATCH, - c.SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND => return error.SPV_REFLECT_RESULT_ERROR_ELEMENT_NOT_FOUND, - c.SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_CODE_SIZE => return error.SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_CODE_SIZE, - c.SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_MAGIC_NUMBER => return error.SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_MAGIC_NUMBER, - c.SPV_REFLECT_RESULT_ERROR_SPIRV_UNEXPECTED_EOF => return error.SPV_REFLECT_RESULT_ERROR_SPIRV_UNEXPECTED_EOF, - c.SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE => return error.SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ID_REFERENCE, - c.SPV_REFLECT_RESULT_ERROR_SPIRV_SET_NUMBER_OVERFLOW => return error.SPV_REFLECT_RESULT_ERROR_SPIRV_SET_NUMBER_OVERFLOW, - c.SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_STORAGE_CLASS => return error.SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_STORAGE_CLASS, - c.SPV_REFLECT_RESULT_ERROR_SPIRV_RECURSION => return error.SPV_REFLECT_RESULT_ERROR_SPIRV_RECURSION, - c.SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_INSTRUCTION => return error.SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_INSTRUCTION, - c.SPV_REFLECT_RESULT_ERROR_SPIRV_UNEXPECTED_BLOCK_DATA => return error.SPV_REFLECT_RESULT_ERROR_SPIRV_UNEXPECTED_BLOCK_DATA, - c.SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_BLOCK_MEMBER_REFERENCE => return error.SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_BLOCK_MEMBER_REFERENCE, - c.SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ENTRY_POINT => return error.SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ENTRY_POINT, - c.SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_EXECUTION_MODE => return error.SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_EXECUTION_MODE, - c.SPV_REFLECT_RESULT_ERROR_SPIRV_MAX_RECURSIVE_EXCEEDED => return error.SPV_REFLECT_RESULT_ERROR_SPIRV_MAX_RECURSIVE_EXCEEDED, - else => unreachable, - } + return compile_result.stdout; } fn processShaderProgram(allocator: std.mem.Allocator, input: []const u8, output_dir: std.fs.Dir, dep_file: ?[]const u8, asset_list_writer: anytype) !void { @@ -734,8 +672,7 @@ fn processShaderProgram(allocator: std.mem.Allocator, input: []const u8, output_ const relative_path = try std.fs.path.relative(allocator, try std.fs.cwd().realpathAlloc(allocator, "."), shader_source_path); const shader = try processShader(allocator, &.{ "-DVERTEX_SHADER=1", "-fshader-stage=vert", "-fpreserve-bindings" }, relative_path, dep_file); - result.graphics.vertex.source = @alignCast(shader.spirv); - result.graphics.vertex.push_constant_range = .{ .offset = shader.push_constant_range.offset, .size = shader.push_constant_range.size }; + result.graphics.vertex.source = @alignCast(shader); } { const stage = program.value.fragment.?; @@ -743,8 +680,7 @@ fn processShaderProgram(allocator: std.mem.Allocator, input: []const u8, output_ const relative_path = try std.fs.path.relative(allocator, try std.fs.cwd().realpathAlloc(allocator, "."), shader_source_path); const shader = try processShader(allocator, &.{ "-DFRAGMENT_SHADER=1", "-fshader-stage=frag", "-fpreserve-bindings" }, relative_path, dep_file); - result.graphics.fragment.source = @alignCast(shader.spirv); - result.graphics.fragment.push_constant_range = .{ .offset = shader.push_constant_range.offset, .size = shader.push_constant_range.size }; + result.graphics.fragment.source = @alignCast(shader); } } else if (program.value.compute != null) { result = .{ .compute = undefined }; @@ -754,8 +690,7 @@ fn processShaderProgram(allocator: std.mem.Allocator, input: []const u8, output_ const relative_path = try std.fs.path.relative(allocator, try std.fs.cwd().realpathAlloc(allocator, "."), shader_source_path); const shader = try processShader(allocator, &.{ "-DCOMPUTE_SHADER=1", "-fshader-stage=compute" }, relative_path, dep_file); - result.compute.compute.source = @alignCast(shader.spirv); - result.compute.compute.push_constant_range = .{ .offset = shader.push_constant_range.offset, .size = shader.push_constant_range.size }; + result.compute.compute.source = @alignCast(shader); } else { std.log.err("Provide vertex and fragment shaders for a graphics pipeline or a compute shader for a compute pipeline\n", .{}); return error.InvalidPipelines;