Name vulkan objects for debugging, got first meshes to draw, spirv debug output for Aftermath
This commit is contained in:
parent
bd903da009
commit
c1c81ee761
17
build.zig
17
build.zig
@ -41,24 +41,10 @@ pub fn build(b: *Build) void {
|
||||
|
||||
const vk = buildVulkanWrapper(b, target, optimize);
|
||||
|
||||
const vma_dep = b.dependency("vma", .{});
|
||||
const vma = b.addStaticLibrary(.{
|
||||
.name = "vma",
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
vma.linkLibC();
|
||||
vma.linkLibCpp();
|
||||
vma.addIncludePath(b.dependency("vulkan_headers", .{}).path("include"));
|
||||
vma.addIncludePath(vma_dep.path("include"));
|
||||
vma.installHeadersDirectory(vma_dep.path("include"), "", .{});
|
||||
vma.addCSourceFile(.{
|
||||
.file = b.path("libs/vma/vma.cpp"),
|
||||
});
|
||||
|
||||
const tracy = b.dependency("zig-tracy", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.tracy_enable = false,
|
||||
});
|
||||
const zalgebra_dep = b.dependency("zalgebra", .{});
|
||||
|
||||
@ -102,7 +88,6 @@ pub fn build(b: *Build) void {
|
||||
l.root_module.addImport("tracy", tracy.module("tracy"));
|
||||
l.root_module.addImport("vk", vk);
|
||||
l.linkLibrary(tracy.artifact("tracy"));
|
||||
l.linkLibrary(vma);
|
||||
}
|
||||
|
||||
const install_lib = b.addInstallArtifact(lib, .{ .dest_dir = .{ .override = .prefix } });
|
||||
|
@ -43,10 +43,6 @@
|
||||
.url = "https://github.com/sinnwrig/mach-dxcompiler/tarball/c3dfe92f3f04d4a3262dbc1a71f0016b9af92eb4",
|
||||
.hash = "12202f48e7cf06b1f2ecfd84f16effbd5bb9d644ea17e8a6144b4301a4dea198cf9c",
|
||||
},
|
||||
.vma = .{
|
||||
.url = "https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator/tarball/1c35ba99ce775f8342d87a83a3f0f696f99c2a39",
|
||||
.hash = "1220521e256ea64cb942c37cfe08065073f2c71bfaa91d5c929fd382314c73ac0369",
|
||||
},
|
||||
.@"spirv-cross" = .{
|
||||
.url = "https://github.com/hexops/spirv-cross/tarball/872bd405fece4bf6388abdea916356e26cb8fed9",
|
||||
.hash = "12207bebf82eef06f4f80a7e54c91e4402c0055d04167fdbcf1f350846a350266976",
|
||||
|
@ -1,4 +0,0 @@
|
||||
#define VMA_IMPLEMENTATION
|
||||
#define VMA_STATIC_VULKAN_FUNCTIONS 0
|
||||
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1
|
||||
#include "vk_mem_alloc.h"
|
BIN
post_process.glsl.spirv
Normal file
BIN
post_process.glsl.spirv
Normal file
Binary file not shown.
@ -100,7 +100,7 @@ const AssetWatcher = struct {
|
||||
}
|
||||
|
||||
pub fn startWatching(self: *AssetWatcher) void {
|
||||
self.thread = sdl.SDL_CreateThread(watcherThread, "AssetManager Watcher", @ptrCast(self)) orelse {
|
||||
self.thread = sdl.SDL_CreateThread(watcherThread, "AssetManager Watcher", @ptrCast(self), null, null) orelse {
|
||||
std.log.err("SDL Error: {s}\n", .{sdl.SDL_GetError()});
|
||||
@panic("SDL_CreateThread");
|
||||
};
|
||||
@ -190,6 +190,9 @@ pub fn init(allocator: std.mem.Allocator, frame_arena: std.mem.Allocator, gc: *G
|
||||
.command_pool = try queue.createCommandPool(.{ .transient_bit = true }),
|
||||
};
|
||||
|
||||
NullMesh.positions = result.vertex_heap.heap_address;
|
||||
NullMesh.other_data = result.vertex_heap.heap_address;
|
||||
|
||||
result.texture_heap_memory = try gc.device.allocateMemory(&.{
|
||||
.allocation_size = result.texture_heap.getSize(),
|
||||
.memory_type_index = gc.memory_config.gpu.type_index,
|
||||
@ -564,7 +567,7 @@ const NullShaderProgram = LoadedShaderProgram{
|
||||
.pipeline = .null_handle,
|
||||
};
|
||||
|
||||
const NullMesh = LoadedMesh{
|
||||
var NullMesh = LoadedMesh{
|
||||
.aabb = .{},
|
||||
.allocation = .{},
|
||||
.positions = 0,
|
||||
@ -643,7 +646,8 @@ fn loadMeshErr(self: *AssetManager, id: AssetId) !LoadedMesh {
|
||||
|
||||
self.gc.device.unmapMemory(staging_mem);
|
||||
|
||||
const cmds = try self.command_pool.allocateCommandBuffer();
|
||||
const cmd_buf_name = try std.fmt.allocPrintZ(self.frame_arena, "MeshLoadCMDBuf ({s})", .{path});
|
||||
const cmds = try self.command_pool.allocateCommandBuffer(cmd_buf_name);
|
||||
|
||||
try cmds.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
|
||||
|
||||
@ -830,6 +834,11 @@ fn loadTextureErr(self: *AssetManager, id: AssetId) !LoadedTexture {
|
||||
.initial_layout = .undefined,
|
||||
}, null);
|
||||
errdefer self.gc.device.destroyImage(image, null);
|
||||
try self.gc.device.setDebugUtilsObjectNameEXT(&vk.DebugUtilsObjectNameInfoEXT{
|
||||
.object_type = .image,
|
||||
.object_handle = @intFromEnum(image),
|
||||
.p_object_name = @ptrCast(path.ptr),
|
||||
});
|
||||
|
||||
const mem_reqs = self.gc.getImageMemoryRequirements(image);
|
||||
const allocation = try self.texture_heap.alloc(mem_reqs.size);
|
||||
@ -853,6 +862,11 @@ fn loadTextureErr(self: *AssetManager, id: AssetId) !LoadedTexture {
|
||||
.level_count = texture.header.mip_count,
|
||||
},
|
||||
}, null);
|
||||
try self.gc.device.setDebugUtilsObjectNameEXT(&vk.DebugUtilsObjectNameInfoEXT{
|
||||
.object_type = .image_view,
|
||||
.object_handle = @intFromEnum(view),
|
||||
.p_object_name = @ptrCast(path.ptr),
|
||||
});
|
||||
errdefer self.gc.device.destroyImageView(view, null);
|
||||
|
||||
var data_size: u64 = 0;
|
||||
@ -889,7 +903,8 @@ fn loadTextureErr(self: *AssetManager, id: AssetId) !LoadedTexture {
|
||||
|
||||
self.gc.device.unmapMemory(staging_mem);
|
||||
|
||||
const cmds = try self.command_pool.allocateCommandBuffer();
|
||||
const cmd_buf_name = try std.fmt.allocPrintZ(self.frame_arena, "TextureLoadCMDBuf ({s})", .{path});
|
||||
const cmds = try self.command_pool.allocateCommandBuffer(cmd_buf_name);
|
||||
|
||||
try cmds.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
|
||||
|
||||
@ -1087,7 +1102,7 @@ fn finishLoadingAsset(self: *AssetManager, id: AssetId) void {
|
||||
.allocation = loading_mesh.allocation,
|
||||
.positions = self.vertex_heap.heap_address + loading_mesh.allocation.positions.offset,
|
||||
.other_data = self.vertex_heap.heap_address + loading_mesh.allocation.other_data.offset,
|
||||
.indices_offset = loading_mesh.allocation.indices.offset,
|
||||
.indices_offset = loading_mesh.allocation.indices.offset / @sizeOf(formats.Index),
|
||||
},
|
||||
}) catch @panic("OOM");
|
||||
}
|
||||
@ -1885,6 +1900,11 @@ const VertexBufferHeap = struct {
|
||||
.sharing_mode = .exclusive,
|
||||
.usage = .{ .shader_device_address_bit = true, .storage_buffer_bit = true, .transfer_dst_bit = true, .index_buffer_bit = true },
|
||||
}, null);
|
||||
try device.setDebugUtilsObjectNameEXT(&vk.DebugUtilsObjectNameInfoEXT{
|
||||
.object_type = .buffer,
|
||||
.object_handle = @intFromEnum(heap_buffer),
|
||||
.p_object_name = "VertexBufferHeap",
|
||||
});
|
||||
errdefer device.destroyBuffer(heap_buffer, null);
|
||||
const mem_reqs = device.getBufferMemoryRequirements(heap_buffer);
|
||||
|
||||
|
@ -329,6 +329,11 @@ pub fn init(gc: *GraphicsContext, frame_allocator: std.mem.Allocator) !Descripto
|
||||
.p_set_layouts = &.{self.descriptor_set_layouts.global},
|
||||
}, &descriptor_set_buf);
|
||||
self.global_descriptor_set = descriptor_set_buf[0];
|
||||
try gc.device.setDebugUtilsObjectNameEXT(&vk.DebugUtilsObjectNameInfoEXT{
|
||||
.object_type = .descriptor_set,
|
||||
.object_handle = @intFromEnum(self.global_descriptor_set),
|
||||
.p_object_name = "GlobalDescriptorSet",
|
||||
});
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
const std = @import("std");
|
||||
const vk = @import("vk");
|
||||
const c = @import("sdl.zig");
|
||||
const vma = @import("vma.zig");
|
||||
|
||||
pub const GraphicsContext = @This();
|
||||
|
||||
@ -12,6 +11,7 @@ const apis: []const vk.ApiInfo = &.{
|
||||
vk.features.version_1_3,
|
||||
vk.extensions.khr_surface,
|
||||
vk.extensions.khr_swapchain,
|
||||
vk.extensions.ext_debug_utils,
|
||||
};
|
||||
|
||||
pub const Instance = vk.InstanceProxy(apis);
|
||||
@ -22,13 +22,17 @@ const BaseDispatch = vk.BaseWrapper(apis);
|
||||
const InstanceDispatch = vk.InstanceWrapper(apis);
|
||||
const DeviceDispatch = Device.Wrapper;
|
||||
|
||||
const instance_extensions = [_][*:0]const u8{
|
||||
vk.extensions.ext_debug_utils.name,
|
||||
};
|
||||
const device_extensions = [_][:0]const u8{
|
||||
vk.extensions.khr_swapchain.name,
|
||||
};
|
||||
const vk_layers = [_][:0]const u8{"VK_LAYER_KHRONOS_validation"};
|
||||
const vk_layers = [_][:0]const u8{
|
||||
// "VK_LAYER_KHRONOS_validation",
|
||||
};
|
||||
|
||||
allocator: std.mem.Allocator = undefined,
|
||||
vma_allocator: vma.Allocator = null,
|
||||
window: *c.SDL_Window = undefined,
|
||||
vkb: BaseDispatch = undefined,
|
||||
vki: InstanceDispatch = undefined,
|
||||
@ -49,13 +53,20 @@ pub const CommandPool = struct {
|
||||
device: Device,
|
||||
handle: vk.CommandPool,
|
||||
|
||||
pub fn allocateCommandBuffer(self: *const CommandPool) !CommandBuffer {
|
||||
pub fn allocateCommandBuffer(self: *const CommandPool, maybe_debug_name: ?[:0]const u8) !CommandBuffer {
|
||||
var cmd_bufs = [_]vk.CommandBuffer{.null_handle};
|
||||
try self.device.allocateCommandBuffers(&.{
|
||||
.command_pool = self.handle,
|
||||
.level = .primary,
|
||||
.command_buffer_count = cmd_bufs.len,
|
||||
}, &cmd_bufs);
|
||||
if (maybe_debug_name) |debug_name| {
|
||||
try self.device.setDebugUtilsObjectNameEXT(&vk.DebugUtilsObjectNameInfoEXT{
|
||||
.object_type = .command_buffer,
|
||||
.object_handle = @intFromEnum(cmd_bufs[0]),
|
||||
.p_object_name = debug_name,
|
||||
});
|
||||
}
|
||||
return CommandBuffer.init(cmd_bufs[0], self.device.wrapper);
|
||||
}
|
||||
|
||||
@ -312,13 +323,14 @@ pub fn init(self: *GraphicsContext, allocator: std.mem.Allocator, window: *c.SDL
|
||||
return error.GetSDLExtensions;
|
||||
}
|
||||
|
||||
const sdl_instance_ext_names = try fba.allocator().alloc([*:0]const u8, sdl_instance_ext_count);
|
||||
if (c.SDL_Vulkan_GetInstanceExtensions(window, &sdl_instance_ext_count, @ptrCast(sdl_instance_ext_names.ptr)) == c.SDL_FALSE) {
|
||||
const instance_ext_names = try fba.allocator().alloc([*:0]const u8, sdl_instance_ext_count + instance_extensions.len);
|
||||
if (c.SDL_Vulkan_GetInstanceExtensions(window, &sdl_instance_ext_count, @ptrCast(instance_ext_names.ptr)) == c.SDL_FALSE) {
|
||||
std.debug.print("SDL_Vulkan_GetInstanceExtensions: get names {s}\n", .{c.SDL_GetError()});
|
||||
return error.GetSDLExtensions;
|
||||
}
|
||||
@memcpy(instance_ext_names[sdl_instance_ext_count..], &instance_extensions);
|
||||
|
||||
std.debug.print("SDL Extensions: {s}\n", .{sdl_instance_ext_names});
|
||||
std.debug.print("Instance Extensions: {s}\n", .{instance_ext_names});
|
||||
|
||||
self.vkb = try BaseDispatch.load(vkGetInstanceProcAddr);
|
||||
|
||||
@ -330,8 +342,8 @@ pub fn init(self: *GraphicsContext, allocator: std.mem.Allocator, window: *c.SDL
|
||||
},
|
||||
.pp_enabled_layer_names = @ptrCast((&vk_layers).ptr),
|
||||
.enabled_layer_count = @intCast(vk_layers.len),
|
||||
.enabled_extension_count = @intCast(sdl_instance_ext_names.len),
|
||||
.pp_enabled_extension_names = sdl_instance_ext_names.ptr,
|
||||
.enabled_extension_count = @intCast(instance_ext_names.len),
|
||||
.pp_enabled_extension_names = instance_ext_names.ptr,
|
||||
}, null);
|
||||
|
||||
self.vki = try InstanceDispatch.load(instance_handle, vkGetInstanceProcAddr);
|
||||
@ -415,21 +427,6 @@ pub fn init(self: *GraphicsContext, allocator: std.mem.Allocator, window: *c.SDL
|
||||
errdefer self.vkd.destroyDevice(device_handle, null);
|
||||
self.device = Device.init(device_handle, &self.vkd);
|
||||
|
||||
self.vma_allocator = vma.createAllocator(&.{
|
||||
.flags = .{
|
||||
.buffer_device_address_bit = true,
|
||||
},
|
||||
.instance = instance_handle,
|
||||
.physical_device = self.device_info.physical_device,
|
||||
.device = device_handle,
|
||||
.vulkanApiVersion = vk.API_VERSION_1_3,
|
||||
.pVulkanFunctions = &vma.VulkanFunctions{
|
||||
.vkGetInstanceProcAddr = @ptrCast(vkGetInstanceProcAddr),
|
||||
.vkGetDeviceProcAddr = @ptrCast(self.instance.wrapper.dispatch.vkGetDeviceProcAddr),
|
||||
},
|
||||
});
|
||||
std.debug.assert(self.vma_allocator != null);
|
||||
|
||||
try self.maybeResizeSwapchain();
|
||||
errdefer self.device.destroySwapchainKHR(self.swapchain, null);
|
||||
|
||||
@ -454,22 +451,14 @@ pub fn init(self: *GraphicsContext, allocator: std.mem.Allocator, window: *c.SDL
|
||||
self.pipeline_cache = try self.device.createPipelineCache(&.{}, null);
|
||||
}
|
||||
|
||||
pub fn createBuffer(self: *GraphicsContext, create_info: *const vk.BufferCreateInfo, allocation_create_info: *const vma.AllocationCreateInfo) !Buffer {
|
||||
var result: Buffer = undefined;
|
||||
result.gc = self;
|
||||
result.handle = try vma.createBuffer(self.vma_allocator, create_info, allocation_create_info, &result.allocation, &result.allocation_info);
|
||||
result.sync_state = .{};
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn acquireSwapchainImage(self: *GraphicsContext, acuire_semaphore: vk.Semaphore) !u32 {
|
||||
pub fn acquireSwapchainImage(self: *GraphicsContext, acuire_semaphore: vk.Semaphore, acquire_fence: vk.Fence) !u32 {
|
||||
var found = false;
|
||||
var swapchain_img: u32 = 0;
|
||||
|
||||
try self.maybeResizeSwapchain();
|
||||
|
||||
while (!found) {
|
||||
const acquire_result = try self.device.acquireNextImageKHR(self.swapchain, std.math.maxInt(u64), acuire_semaphore, .null_handle);
|
||||
const acquire_result = try self.device.acquireNextImageKHR(self.swapchain, std.math.maxInt(u64), acuire_semaphore, acquire_fence);
|
||||
|
||||
switch (acquire_result.result) {
|
||||
.success, .suboptimal_khr => {
|
||||
@ -537,6 +526,7 @@ fn maybeResizeSwapchain(self: *GraphicsContext) !void {
|
||||
self.allocator.free(self.swapchain_images);
|
||||
self.swapchain_images = &.{};
|
||||
}
|
||||
|
||||
self.swapchain_extent = new_extent;
|
||||
const surface_caps = self.device_info.surface_capabilities;
|
||||
self.swapchain = try self.device.createSwapchainKHR(&.{
|
||||
|
101
src/Render2.zig
101
src/Render2.zig
@ -6,6 +6,7 @@ const vk = @import("vk");
|
||||
const a = @import("asset_manifest");
|
||||
const za = @import("zalgebra");
|
||||
const Vec3 = za.Vec3;
|
||||
const Vec4 = za.Vec4;
|
||||
const Mat4 = za.Mat4;
|
||||
const common = @import("common.zig");
|
||||
const formats = @import("formats.zig");
|
||||
@ -313,6 +314,11 @@ fn allocateRenderTarget(self: *Render2) !MainRenderTarget {
|
||||
.samples = .{ .@"1_bit" = true },
|
||||
.initial_layout = .undefined,
|
||||
}, &color_img_address);
|
||||
try self.gc.device.setDebugUtilsObjectNameEXT(&vk.DebugUtilsObjectNameInfoEXT{
|
||||
.object_type = .image,
|
||||
.object_handle = @intFromEnum(color_image),
|
||||
.p_object_name = "Main RT (Color)",
|
||||
});
|
||||
|
||||
const color_image_view = try self.createPerFrameImageView(&vk.ImageViewCreateInfo{
|
||||
.image = color_image,
|
||||
@ -327,6 +333,11 @@ fn allocateRenderTarget(self: *Render2) !MainRenderTarget {
|
||||
.level_count = 1,
|
||||
},
|
||||
});
|
||||
try self.gc.device.setDebugUtilsObjectNameEXT(&vk.DebugUtilsObjectNameInfoEXT{
|
||||
.object_type = .image_view,
|
||||
.object_handle = @intFromEnum(color_image_view),
|
||||
.p_object_name = "Main RT View (Color)",
|
||||
});
|
||||
|
||||
const depth_image = try self.createPerFrameImage(&.{
|
||||
.image_type = .@"2d",
|
||||
@ -340,6 +351,11 @@ fn allocateRenderTarget(self: *Render2) !MainRenderTarget {
|
||||
.samples = .{ .@"1_bit" = true },
|
||||
.initial_layout = .undefined,
|
||||
}, &depth_img_address);
|
||||
try self.gc.device.setDebugUtilsObjectNameEXT(&vk.DebugUtilsObjectNameInfoEXT{
|
||||
.object_type = .image,
|
||||
.object_handle = @intFromEnum(depth_image),
|
||||
.p_object_name = "Main RT (Depth)",
|
||||
});
|
||||
const depth_image_view = try self.createPerFrameImageView(&vk.ImageViewCreateInfo{
|
||||
.image = depth_image,
|
||||
.view_type = .@"2d",
|
||||
@ -353,6 +369,11 @@ fn allocateRenderTarget(self: *Render2) !MainRenderTarget {
|
||||
.level_count = 1,
|
||||
},
|
||||
});
|
||||
try self.gc.device.setDebugUtilsObjectNameEXT(&vk.DebugUtilsObjectNameInfoEXT{
|
||||
.object_type = .image_view,
|
||||
.object_handle = @intFromEnum(depth_image_view),
|
||||
.p_object_name = "Main RT View (Depth)",
|
||||
});
|
||||
|
||||
return MainRenderTarget{
|
||||
.color = GraphicsContext.Image{
|
||||
@ -439,6 +460,8 @@ pub fn draw(self: *Render2, cmd: DrawCommand) void {
|
||||
self.draw_command_count += 1;
|
||||
}
|
||||
|
||||
const debug_label_color: [4]f32 = .{ 0.15, 0.6, 0.15, 1 };
|
||||
|
||||
pub fn finish(self: *Render2) !void {
|
||||
const gc = self.gc;
|
||||
const device = gc.device;
|
||||
@ -446,7 +469,7 @@ pub fn finish(self: *Render2) !void {
|
||||
|
||||
try frame.waitForDrawAndReset(self.gc.device, self.descriptorman);
|
||||
|
||||
const swapchain_image_index: u32 = try gc.acquireSwapchainImage(frame.acquire_swapchain_image);
|
||||
const swapchain_image_index: u32 = try gc.acquireSwapchainImage(frame.acquire_swapchain_image, .null_handle);
|
||||
|
||||
self.vulkan_frame_arena.startFrame(self.frame_state.frame);
|
||||
|
||||
@ -461,7 +484,7 @@ pub fn finish(self: *Render2) !void {
|
||||
const projection = self.camera.projection().mul(Mat4{
|
||||
.data = .{
|
||||
.{ 1, 0, 0, 0 },
|
||||
.{ 0, 1, 0, 0 },
|
||||
.{ 0, -1, 0, 0 },
|
||||
.{ 0, 0, 1, 0 },
|
||||
.{ 0, 0, 0, 1 },
|
||||
},
|
||||
@ -483,19 +506,36 @@ pub fn finish(self: *Render2) !void {
|
||||
const depth_image: *GraphicsContext.Image = &main_render_target.depth;
|
||||
|
||||
var swapchain_image = GraphicsContext.Image{ .handle = gc.swapchain_images[swapchain_image_index], .mip_count = 1, .layer_count = 1, .format = .r8g8b8a8_unorm };
|
||||
// NOTE: I don't think this is actually needed, but validation is screaming at me
|
||||
swapchain_image.sync_state.sync_state.last_writer.stage_mask = .{ .color_attachment_output_bit = true };
|
||||
const swapchain_image_view = try swapchain_image.createView(gc.device, .{ .color_bit = true });
|
||||
defer gc.device.destroyImageView(swapchain_image_view, null);
|
||||
|
||||
const cmds = frame.command_buffer;
|
||||
|
||||
try cmds.beginCommandBuffer(&.{});
|
||||
{
|
||||
try global_uniform_buffer.sync(cmds, .{ .stage_mask = .{ .copy_bit = true }, .access_mask = .{ .transfer_write_bit = true } });
|
||||
cmds.updateBuffer(global_uniform_buffer.handle, 0, @sizeOf(GlobalUniform), &global_uniform);
|
||||
try global_uniform_buffer.sync(cmds, .{ .stage_mask = .{ .vertex_shader_bit = true }, .access_mask = .{ .shader_read_bit = true } });
|
||||
|
||||
const global_descriptor_set = self.descriptorman.global_descriptor_set;
|
||||
|
||||
{
|
||||
const cmds = frame.draw_cmdbuf;
|
||||
try cmds.beginCommandBuffer(&.{});
|
||||
defer cmds.endCommandBuffer() catch @panic("endCommandBuffer");
|
||||
|
||||
// Main Pass
|
||||
{
|
||||
cmds.beginDebugUtilsLabelEXT(&vk.DebugUtilsLabelEXT{
|
||||
.color = debug_label_color,
|
||||
.p_label_name = "Draw",
|
||||
});
|
||||
defer cmds.endDebugUtilsLabelEXT();
|
||||
{
|
||||
cmds.beginDebugUtilsLabelEXT(&vk.DebugUtilsLabelEXT{
|
||||
.color = debug_label_color,
|
||||
.p_label_name = "UpdateGlobalUniformBuffer",
|
||||
});
|
||||
defer cmds.endDebugUtilsLabelEXT();
|
||||
try global_uniform_buffer.sync(cmds, .{ .stage_mask = .{ .clear_bit = true, .copy_bit = true }, .access_mask = .{ .transfer_write_bit = true } });
|
||||
cmds.updateBuffer(global_uniform_buffer.handle, 0, @sizeOf(GlobalUniform), &global_uniform);
|
||||
try global_uniform_buffer.sync(cmds, .{ .stage_mask = .{ .vertex_shader_bit = true, .fragment_shader_bit = true }, .access_mask = .{ .uniform_read_bit = true } });
|
||||
}
|
||||
|
||||
// TODO: move this into descriptorman
|
||||
device.updateDescriptorSets(1, &.{
|
||||
vk.WriteDescriptorSet{
|
||||
@ -542,6 +582,12 @@ pub fn finish(self: *Render2) !void {
|
||||
|
||||
// Actual draws
|
||||
{
|
||||
cmds.beginDebugUtilsLabelEXT(&vk.DebugUtilsLabelEXT{
|
||||
.color = debug_label_color,
|
||||
.p_label_name = "MainPass",
|
||||
});
|
||||
defer cmds.endDebugUtilsLabelEXT();
|
||||
|
||||
cmds.beginRendering(&vk.RenderingInfo{
|
||||
.render_area = vk.Rect2D{ .offset = .{ .x = 0, .y = 0 }, .extent = gc.swapchain_extent },
|
||||
.layer_count = 1,
|
||||
@ -617,18 +663,10 @@ pub fn finish(self: *Render2) !void {
|
||||
cmds.drawIndexed(mesh.index_count, 1, mesh.indices_offset, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Post process and convert from f16 to rgba8_unorm
|
||||
{
|
||||
try swapchain_image.sync(
|
||||
cmds,
|
||||
.{
|
||||
.stage_mask = .{ .color_attachment_output_bit = true },
|
||||
.access_mask = .{ .color_attachment_write_bit = true },
|
||||
},
|
||||
.color_attachment_optimal,
|
||||
.{ .color_bit = true },
|
||||
);
|
||||
try color_image.sync(
|
||||
cmds,
|
||||
.{
|
||||
@ -638,6 +676,21 @@ pub fn finish(self: *Render2) !void {
|
||||
.shader_read_only_optimal,
|
||||
.{ .color_bit = true },
|
||||
);
|
||||
cmds.beginDebugUtilsLabelEXT(&vk.DebugUtilsLabelEXT{
|
||||
.color = debug_label_color,
|
||||
.p_label_name = "PostProcess",
|
||||
});
|
||||
defer cmds.endDebugUtilsLabelEXT();
|
||||
|
||||
try swapchain_image.sync(
|
||||
cmds,
|
||||
.{
|
||||
.stage_mask = .{ .color_attachment_output_bit = true },
|
||||
.access_mask = .{ .color_attachment_write_bit = true },
|
||||
},
|
||||
.color_attachment_optimal,
|
||||
.{ .color_bit = true },
|
||||
);
|
||||
cmds.beginRendering(&.{
|
||||
.render_area = vk.Rect2D{ .offset = .{ .x = 0, .y = 0 }, .extent = gc.swapchain_extent },
|
||||
.layer_count = 1,
|
||||
@ -690,19 +743,21 @@ pub fn finish(self: *Render2) !void {
|
||||
|
||||
try swapchain_image.sync(cmds, .{ .stage_mask = .{}, .access_mask = .{} }, .present_src_khr, .{ .color_bit = true });
|
||||
}
|
||||
try cmds.endCommandBuffer();
|
||||
|
||||
self.draw_command_count = 0;
|
||||
|
||||
try gc.queues.graphics.submit(
|
||||
&GraphicsContext.SubmitInfo{
|
||||
.wait_semaphores = &.{frame.acquire_swapchain_image},
|
||||
.wait_dst_stage_mask = &.{vk.PipelineStageFlags{}},
|
||||
.command_buffers = &.{cmds.handle},
|
||||
.wait_dst_stage_mask = &.{
|
||||
vk.PipelineStageFlags{ .color_attachment_output_bit = true }, // Wait for swapchain acquire before rendering into it
|
||||
},
|
||||
.command_buffers = &.{frame.draw_cmdbuf.handle},
|
||||
.signal_semaphores = &.{frame.draw_sema},
|
||||
},
|
||||
frame.draw_fence,
|
||||
frame.end_draw_fence,
|
||||
);
|
||||
|
||||
frame.draw_submitted = true;
|
||||
|
||||
_ = try gc.device.queuePresentKHR(gc.queues.graphics.handle, &.{
|
||||
|
@ -7,11 +7,12 @@ pub const ShaderPrograms = manifest.ShaderPrograms;
|
||||
pub const Textures = manifest.Textures;
|
||||
pub const Materials = manifest.Materials;
|
||||
|
||||
const empty: [:0]const u8 = "";
|
||||
pub fn getPath(asset_id: u64) []const u8 {
|
||||
manifest.init();
|
||||
if (asset_id == 0) return "";
|
||||
if (asset_id == 0) return empty;
|
||||
|
||||
return manifest.asset_paths.get(asset_id) orelse "";
|
||||
return manifest.asset_paths.get(asset_id) orelse empty;
|
||||
}
|
||||
|
||||
pub fn getAssetByPath(path: []const u8) u32 {
|
||||
|
@ -71,7 +71,7 @@ pub const FreeLookCamera = struct {
|
||||
|
||||
pub fn update(self: *FreeLookCamera, dt: f32, move: Vec3, look: Vec2) void {
|
||||
self.yaw += look.x();
|
||||
self.pitch -= look.y();
|
||||
self.pitch += look.y();
|
||||
// First rotate pitch, then yaw
|
||||
const rot = Mat4.fromRotation(self.pitch, Vec3.right()).mul(Mat4.fromRotation(self.yaw, Vec3.up()));
|
||||
|
||||
|
@ -104,11 +104,11 @@ pub const FrameData = struct {
|
||||
// Sync
|
||||
acquire_swapchain_image: vk.Semaphore,
|
||||
draw_sema: vk.Semaphore,
|
||||
draw_fence: vk.Fence,
|
||||
end_draw_fence: vk.Fence,
|
||||
draw_submitted: bool = true,
|
||||
destroy_queue: DeferredDestroyQueue,
|
||||
|
||||
command_buffer: GraphicsContext.CommandBuffer,
|
||||
draw_cmdbuf: GraphicsContext.CommandBuffer,
|
||||
|
||||
pub fn init(gc: *GraphicsContext, command_pool: GraphicsContext.CommandPool) !FrameData {
|
||||
const fence = try gc.device.createFence(&.{ .flags = .{ .signaled_bit = true } }, null);
|
||||
@ -116,9 +116,9 @@ pub const FrameData = struct {
|
||||
return FrameData{
|
||||
.acquire_swapchain_image = try gc.device.createSemaphore(&.{}, null),
|
||||
.draw_sema = try gc.device.createSemaphore(&.{}, null),
|
||||
.draw_fence = fence,
|
||||
.end_draw_fence = fence,
|
||||
|
||||
.command_buffer = try command_pool.allocateCommandBuffer(),
|
||||
.draw_cmdbuf = try command_pool.allocateCommandBuffer("MainPass"),
|
||||
.destroy_queue = DeferredDestroyQueue.init(fence),
|
||||
};
|
||||
}
|
||||
@ -127,13 +127,13 @@ pub const FrameData = struct {
|
||||
if (!self.draw_submitted) return;
|
||||
|
||||
self.draw_submitted = false;
|
||||
_ = try device.waitForFences(1, &.{self.draw_fence}, vk.TRUE, std.math.maxInt(u64));
|
||||
_ = try device.waitForFences(1, &.{self.end_draw_fence}, vk.TRUE, std.math.maxInt(u64));
|
||||
|
||||
try self.destroy_queue.destroy(device, descriptorman);
|
||||
|
||||
try device.resetFences(1, &.{self.draw_fence});
|
||||
try device.resetFences(1, &.{self.end_draw_fence});
|
||||
|
||||
try self.command_buffer.resetCommandBuffer(.{ .release_resources_bit = true });
|
||||
try self.draw_cmdbuf.resetCommandBuffer(.{ .release_resources_bit = true });
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -154,7 +154,7 @@ fn writeAssetManifest(arena: std.mem.Allocator, writer: anytype, assets: []Asset
|
||||
try writer.writeAll(
|
||||
\\var buf: [1024 * 1024]u8 = undefined;
|
||||
\\var fba = std.heap.FixedBufferAllocator.init(&buf);
|
||||
\\pub var asset_paths = std.AutoHashMapUnmanaged(u64, []const u8){};
|
||||
\\pub var asset_paths = std.AutoHashMapUnmanaged(u64, [:0]const u8){};
|
||||
\\var initialized = false;
|
||||
\\
|
||||
\\// Fill map with data
|
||||
|
@ -59,7 +59,6 @@ const Args = struct {
|
||||
|
||||
fn parseArgs(allocator: std.mem.Allocator) !Args {
|
||||
var args = try std.process.argsWithAllocator(allocator);
|
||||
defer args.deinit();
|
||||
|
||||
var result: Args = .{};
|
||||
|
||||
@ -138,7 +137,7 @@ pub fn main() !void {
|
||||
|
||||
switch (asset_type) {
|
||||
.Scene => try processScene(allocator, rel_input, output_dir, asset_list_writer),
|
||||
.ShaderProgram => try processShaderProgram(allocator, rel_input, output_dir, args.dep_file, asset_list_writer),
|
||||
.ShaderProgram => try processShaderProgram(allocator, rel_input, rel_output, output_dir, args.dep_file, asset_list_writer),
|
||||
.Texture => try processTextureFromFile(allocator, rel_input, output_dir, asset_list_writer),
|
||||
else => unreachable,
|
||||
}
|
||||
@ -585,22 +584,29 @@ fn readFileContents(allocator: std.mem.Allocator, path: []const u8) ![]u8 {
|
||||
|
||||
// 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) ![]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);
|
||||
fn processShader(allocator: std.mem.Allocator, rel_output: []const u8, flags: []const []const u8, input: []const u8, stage: []const u8, maybe_dep_file: ?[]const u8) ![]u8 {
|
||||
// const input_dir = std.fs.path.dirname(input).?;
|
||||
const basename = std.fs.path.basename(input);
|
||||
const basename_spirv = try std.mem.concat(allocator, u8, &.{ basename, ".", stage, ".spirv" });
|
||||
defer allocator.free(basename_spirv);
|
||||
const out_spirv_path = try std.fs.path.join(allocator, &.{ rel_output, "assets", "shader_debug", basename_spirv });
|
||||
defer allocator.free(out_spirv_path);
|
||||
|
||||
const dirpath = std.fs.path.dirname(out_spirv_path).?;
|
||||
try std.fs.cwd().makePath(dirpath);
|
||||
|
||||
// TODO: make sure output is stdout
|
||||
const compile_result = try std.process.Child.run(.{
|
||||
.allocator = allocator,
|
||||
.argv = try std.mem.concat(allocator, []const u8, &.{
|
||||
&.{ "glslc", "--target-env=vulkan1.3", "-std=460core", "-g", "-O0", "-o", "-" },
|
||||
&.{ "glslc", "--target-env=vulkan1.3", "-std=460core", "-g", "-o", out_spirv_path },
|
||||
if (maybe_dep_file) |dep| &.{ "-MD", "-MF", dep } else &.{},
|
||||
flags,
|
||||
&.{input},
|
||||
}),
|
||||
});
|
||||
defer allocator.free(compile_result.stderr);
|
||||
errdefer allocator.free(compile_result.stdout);
|
||||
defer allocator.free(compile_result.stdout);
|
||||
|
||||
switch (compile_result.term) {
|
||||
.Exited => |status| {
|
||||
@ -614,10 +620,12 @@ fn processShader(allocator: std.mem.Allocator, flags: []const []const u8, input:
|
||||
},
|
||||
}
|
||||
|
||||
return compile_result.stdout;
|
||||
const spirv = try std.fs.cwd().readFileAlloc(allocator, out_spirv_path, 9999999999999);
|
||||
|
||||
return spirv;
|
||||
}
|
||||
|
||||
fn processShaderProgram(allocator: std.mem.Allocator, input: []const u8, output_dir: std.fs.Dir, dep_file: ?[]const u8, asset_list_writer: anytype) !void {
|
||||
fn processShaderProgram(allocator: std.mem.Allocator, input: []const u8, rel_output: []const u8, output_dir: std.fs.Dir, dep_file: ?[]const u8, asset_list_writer: anytype) !void {
|
||||
const input_dir = std.fs.path.dirname(input).?;
|
||||
|
||||
// Recreate file in case it's not empty
|
||||
@ -671,7 +679,7 @@ fn processShaderProgram(allocator: std.mem.Allocator, input: []const u8, output_
|
||||
const shader_source_path = try std.fs.path.resolve(allocator, &.{ input_dir, stage });
|
||||
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);
|
||||
const shader = try processShader(allocator, rel_output, &.{ "-DVERTEX_SHADER=1", "-fshader-stage=vert", "-fpreserve-bindings" }, relative_path, "vert", dep_file);
|
||||
result.graphics.vertex.source = @alignCast(shader);
|
||||
}
|
||||
{
|
||||
@ -679,7 +687,7 @@ fn processShaderProgram(allocator: std.mem.Allocator, input: []const u8, output_
|
||||
const shader_source_path = try std.fs.path.resolve(allocator, &.{ input_dir, stage });
|
||||
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);
|
||||
const shader = try processShader(allocator, rel_output, &.{ "-DFRAGMENT_SHADER=1", "-fshader-stage=frag", "-fpreserve-bindings" }, relative_path, "frag", dep_file);
|
||||
result.graphics.fragment.source = @alignCast(shader);
|
||||
}
|
||||
} else if (program.value.compute != null) {
|
||||
@ -689,7 +697,7 @@ fn processShaderProgram(allocator: std.mem.Allocator, input: []const u8, output_
|
||||
const shader_source_path = try std.fs.path.resolve(allocator, &.{ input_dir, stage });
|
||||
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);
|
||||
const shader = try processShader(allocator, rel_output, &.{ "-DCOMPUTE_SHADER=1", "-fshader-stage=compute" }, relative_path, "comp", dep_file);
|
||||
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", .{});
|
||||
|
Loading…
x
Reference in New Issue
Block a user