forked from vv/efemra
1
0
Fork 0

tons of progress, currently compile borken.

This commit is contained in:
Vivianne 2022-07-17 05:54:29 -07:00
parent 54854b1c48
commit c8694479a4
14 changed files with 277 additions and 46 deletions

1
src/math/float4.zig Normal file
View File

@ -0,0 +1 @@
pub const Float4 = @Vector(4, f32);

9
src/math/float4x4.zig Normal file
View File

@ -0,0 +1,9 @@
const Float4 = @import("float4.zig").Float4;
// TODO: comptime magic?
pub const Float4x4 = packed struct {
c0: Float4,
c1: Float4,
c2: Float4,
c3: Float4,
};

View File

@ -3,6 +3,7 @@ const assert = @import("std").debug.assert;
const vk = @import("vulkan");
const settings = @import("settings.zig");
const Pass = @import("Pass.zig");
const Swapchain = @import("swapchain.zig").Swapchain;
const Image = @import("image.zig").Image;
const Context = @import("Context.zig");
@ -60,7 +61,6 @@ pub fn init(device: *const Device, queue: *queues.Queue, id: queues.QueueId) Com
errdefer queue.cmd_pool.deinit(device);
try device.dispatch.allocateCommandBuffers(device.handle, &.{
.s_type = .command_buffer_allocate_info,
.command_pool = queue.cmd_pool.handle,
.level = .primary,
.command_buffer_count = settings.cmds_per_queue,
@ -144,7 +144,6 @@ pub const Buffer = struct {
if (!cmd.began) {
try device.dispatch.beginCommandBuffer(cmd.handle, &.{
.s_type = .command_buffer_begin_info,
.flags = .{ .one_time_submit_bit = true },
.p_inheritance_info = null,
});
@ -219,7 +218,6 @@ pub const Buffer = struct {
assert(self.handle != .null_handle);
assert(!self.in_render_pass);
device.dispatch.beginRenderPass(self.handle, &.{
.s_type = .render_pass_begin_info,
.render_pass = pass,
.framebuffer = framebuf,
.render_area = rect,
@ -240,11 +238,35 @@ pub const Buffer = struct {
pub fn endRenderPass(self: *Self, device: *const Device) void {
assert(self.handle != .null_handle);
assert(self.in_render_pass);
try device.dispatch.cmdEndRenderPass(self.handle);
device.dispatch.cmdEndRenderPass(self.handle);
self.in_render_pass = 0;
self.subpass = 0;
}
pub fn pushConstants(self: *Self, device: *const Device, pass: *const Pass, constants: anytype) void {
const Ptr = @TypeOf(constants);
comptime if (@typeInfo(Ptr) != .Pointer) {
@compileError("constants argument provided to Command.pushConstants must be a pointer type, got " ++ @typeName(Ptr));
};
comptime if (@typeInfo(Ptr).Pointer.size != .One) {
@compileError("constants argument provided to Command.pushConstants must be a single-item pointer");
};
const size = @sizeOf(@typeInfo(Ptr).Pointer.child);
comptime if (size <= 0) {
@compileError("constants argument provided to Command.pushConstants must have > 0 bytes.");
};
assert(self.handle != .null_handle);
assert(self.gfx or self.comp);
assert(size == pass.push_constant_bytes);
assert(pass.layout.toInt() != 0);
assert(pass.stage_flags.toInt() != 0);
device.dispatch.cmdPushConstants(self.handle, pass.layout, pass.stage_flags, 0, size, constants);
}
pub fn viewport(self: *Self, device: *const Device, vp: vk.Viewport, scissor: vk.Rect2D) void {
assert(self.handle != .null_handle);
device.dispatch.cmdSetViewport(self.handle, 0, 1, &vp);
@ -313,7 +335,6 @@ pub const Buffer = struct {
assert((try fence.stat(device)) == .unsignaled);
const submit_info = vk.SubmitInfo{
.s_type = .submit_info,
.wait_semaphore_count = if (wait_sema != null) @as(u32, 1) else 0,
.p_wait_semaphores = if (wait_sema) |s| @ptrCast([*]const vk.Semaphore, &s.handle) else undefined,
.p_wait_dst_stage_mask = @ptrCast([*]const vk.PipelineStageFlags, &wait_mask),
@ -374,7 +395,6 @@ pub const Pool = struct {
pub const InitError = DeviceDispatch.CreateCommandPoolError;
pub fn init(device: *const Device, family: u32, flags: vk.CommandPoolCreateFlags) InitError!Self {
const handle = try device.dispatch.createCommandPool(device.handle, &.{
.s_type = .command_pool_create_info,
.flags = flags,
.queue_family_index = family,
}, null);

View File

@ -10,7 +10,6 @@ messenger: if (settings.messenger_on) vk.DebugUtilsMessengerEXT else void,
pub fn init(instance: *Instance) !Self {
if (settings.messenger_on) {
const messenger = try instance.dispatch.createDebugUtilsMessengerEXT(instance.handle, &.{
.s_type = .debug_utils_messenger_create_info_ext,
.flags = .{},
.message_severity = .{
.error_bit_ext = true,

View File

@ -0,0 +1,187 @@
const std = @import("std");
const vk = @import("vulkan");
const ProfileMark = @import("../../common/profiler.zig").ProfileMark;
const Device = @import("device.zig").Device;
const Command = @import("Command.zig");
const Swapchain = @import("swapchain.zig").Swapchain;
const Image = @import("image.zig").Image;
const Camera = @import("Camera.zig");
const Shader = @import("Shader.zig");
const Pass = @import("Pass.zig");
const framebuffer = @import("framebuffer.zig");
const DepthBuffer = @import("DepthBuffer.zig");
const RenderPass = @import("RenderPass.zig");
const Float4 = @import("../../math/float4.zig").Float4;
const Float4x4 = @import("../../math/float4x4.zig").Float4x4;
const PushConstants = struct {
local_to_clip: Float4x4,
};
pub fn init() !void {
errdefer {
std.debug.print("Failed to init MainPass");
deinit();
}
// try ScreenBlit.init()
try DepthPass.init();
try OpaquePass.init();
// try Exposure.init();
// try UIPass.init();
}
pub fn deinit() void {
// ScreenBlit.deinit()
DepthPass.deinit();
OpaquePass.deinit();
// Exposure.deinit();
// UIPass.deinit();
}
const pm_setup = ProfileMark.init("MainPass.setup");
pub fn setup() void {
pm_setup.begin();
defer pm_setup.end();
DepthPass.setup();
OpaquePass.setup();
// Exposure.setup();
// UIPass.setup();
}
const pm_execute = ProfileMark.init("MainPass.execute");
pub fn execute() void {
pm_execute.begin();
defer pm_execute.end();
// todo: pt_trace convar check
DepthPass.execute();
OpaquePass.execute();
// Exposure.execute();
// UIPass.execute();
}
const DepthPass = struct {
var s_render_pass: vk.RenderPass = undefined;
var s_pass: Pass = undefined;
pub fn init() !void {
errdefer DepthPass.deinit();
const depth_buffer = DepthBuffer.get();
var info = RenderPass.Description{
.src_stage_mask = .{ .early_fragment_tests_bit = true },
.src_access_mask = .{ .depth_stencil_attachment_read_bit = true },
.dst_stage_mask = .{ .late_fragment_tests_bit = true },
.dst_access_mask = .{ .depth_stencil_attachment_write_bit = true },
.attachments = undefined,
};
info.attachments[0] = .{
.format = depth_buffer.format,
.layout = .depth_stencil_attachment_optimal,
.load = vk.VK_ATTACHMENT_LOAD_OP_CLEAR,
.store = vk.VK_ATTACHMENT_LOAD_OP_STORE,
};
s_render_pass = try RenderPass.get(&info);
var shaders = std.mem.zeroes([2]vk.PipelineShaderStageCreateInfo);
try Shader.init(&shaders[0], "DepthOnly.hlsl", "VSMain", .vertex);
errdefer Shader.deinit(&shaders[0]);
try Shader.init(&shaders[1], "DepthOnly.hlsl", "PSMain", .fragment);
errdefer Shader.deinit(&shaders[1]);
const vert_bindings = []vk.VertexInputBindingDescription{
.{
.binding = 0,
.stride = @sizeOf(Float4),
.input_rate = .vertex,
},
};
const vert_attributes = []vk.VertexInputAtttributeDescription{
.{
.binding = 0,
.format = .r32g32b32a32_sfloat,
.location = 0,
},
};
try Pass.new(&s_pass, &.{
.push_constant_bytes = @sizeOf(PushConstants),
.shader_count = shaders.len,
.shaders = shaders,
.render_pass = s_render_pass,
.subpass = 0,
.vert_layout = .{
.binding_count = vert_bindings.len,
.bindings = vert_bindings.ptr,
.attribute_count = vert_attributes.len,
.attributes = vert_attributes.ptr,
},
.fixed_funcs = .{
.viewport = Swapchain.getViewport(),
.scissor = Swapchain.getRect(),
.topology = .triangle_list,
.polygon_mode = .fill,
.front_face = .counter_clockwise,
.cull_mode = .back_bit,
.depth_compare_op = .less,
.scissor_on = false,
.depth_clamp = false,
.depth_test_enable = true,
.depth_write_enable = true,
.attachment_count = 0,
},
});
}
pub fn deinit() void {
s_pass.deinit();
}
pub fn setup() void {}
const pm_depth_execute = ProfileMark.init("DepthPass.execute");
pub fn execute(device: *const Device) void {
pm_depth_execute.begin();
defer pm_depth_execute.end();
const camera = Camera.get();
const world_to_clip = camera.getWorldToClip(Swapchain.getAspect());
const attachments = []Image{DepthBuffer.get()};
const rect = vk.Rect2D{
.offset = std.mem.zeroes(vk.Offset2D),
.extent = .{
.width = attachments[0].width,
.height = attachments[0].height,
},
};
const fbuf = framebuffer.get(attachments, rect.extent.width, rect.extent.height);
const cmd = try Command.Buffer.get(.graphics, device);
Image.State.depthAttachWrite(cmd, attachments[0]);
cmd.defaultViewport(device);
cmd.bindPass(device, &s_pass);
cmd.beginRenderPass(device, s_render_pass, fbuf, rect, .{
.{
.depth_stencil = .{ .depth = 1.0, .stencil = 0.0 },
},
});
defer cmd.endRenderPass(device);
// TODO: draw entities/meshes
cmd.pushConstants(device, &s_pass, &PushConstants{ .local_to_clip = world_to_clip });
// TODO: imSys_drawDepth()
}
};
const OpaquePass = struct {};

View File

View File

@ -7,10 +7,27 @@ const vkd = @import("device.zig").DeviceDispatch;
const allocator: std.mem.Allocator = undefined;
const Description = struct {};
const s_cache = std.HashMap(Description, vk.RenderPass).init(allocator);
// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#renderpass-compatibility
// compatibility:
// refs: matching format and sample count, or both VK_ATTACHMENT_UNUSED, or both NULL
// arrays of refs: treats missing refs as VK_ATTACHMENT_UNUSED
const AttachmentState = packed struct {
format: vk.Format, // must match
layout: vk.ImageLayout, // can vary
load: u2, // vk.AttachmentLoadOp, can vary
store: u2, // vk.AttachmentStoreOp, can vary
};
pub const Description = struct {
attachments: [8]AttachmentState = std.mem.zeroes([8]AttachmentState),
src_access_mask: vk.AccessFlags,
dst_access_mask: vk.AccessFlags,
src_stage_mask: vk.PipelineStageFlags,
dst_stage_mask: vk.PipelineStageFlags,
};
const pm_get = profiler.ProfileMark.init("renderpass.get");
pub fn get(desc: *const Description) !vk.RenderPass {
pm_get.begin();
@ -80,7 +97,6 @@ pub fn get(desc: *const Description) !vk.RenderPass {
fn new(device: *Device, attachment_count: i32, p_attachments: *const vk.AttachmentDescription, subpass_count: i32, p_subpasses: *const vk.SubpassDescription, dependency_count: i32, p_dependencies: *const vk.SubpassDependency) !vk.RenderPass {
const handle: vk.RenderPass = undefined;
try vkd.createRenderPass(device.dev, &.{
.s_type = .render_pass_create_info,
.attachment_count = attachment_count,
.p_attachments = p_attachments,
.subpass_count = subpass_count,

View File

@ -9,7 +9,7 @@ const memory = @import("memory.zig");
const framebuffer = @import("framebuffer.zig");
const Swapchain = @import("swapchain.zig").Swapchain;
const Context = @import("Context.zig");
//const MainPass = @import("main_pass.zig").MainPass;
const MainPass = @import("MainPass.zig");
const Command = @import("Command.zig");
instance: Instance,
@ -23,7 +23,7 @@ context: Context,
// targets: Targets, TODO
// mesh_sys: MeshSys, TODO
// im_sys: ImSys, TODO
//main_pass: MainPass,
main_pass: MainPass,
const Self = @This();
@ -60,7 +60,7 @@ pub fn init() !Self {
// try self.targets.init();
// try self.meshSys.init();
// try self.imSys.init();
//try self.main_pass.init();
const main_pass = try MainPass.init();
return Self{
.instance = instance,
@ -68,6 +68,7 @@ pub fn init() !Self {
.device = device,
.swapchain = swapchain,
.context = context,
.main_pass = main_pass,
};
}
@ -88,14 +89,14 @@ pub fn update(self: *Self) !void {
// setup phase
{
//self.main_pass.setup();
self.main_pass.setup();
// TODO textable update
try Command.flush(&self.device);
// TODO bindings update
}
// execute phase
//self.main_pass.execute();
self.main_pass.execute();
// present phase
// currently only graphics queue
@ -113,7 +114,7 @@ pub fn deinit(self: Self) void {
// TODO: delete lightmap pack
//self.main_pass.deinit();
self.main_pass.deinit();
// self.imSys.deinit();
// self.meshSys.deinit();

View File

@ -1,7 +1,7 @@
const std = @import("std");
const vk = @import("vulkan");
const Image = @import("image.zig").Image;
const renderpass = @import("render_pass.zig");
const RenderPass = @import("RenderPass.zig");
const Device = @import("device.zig").Device;
// TODO memory
@ -88,11 +88,11 @@ fn containsView(key: *const Key, view: vk.ImageView) bool {
pub const Framebuffer = struct {
pub fn init(device: *Device, attachments: []const vk.ImageView, formats: []const vk.Format, width: i32, height: i32) !vk.Framebuffer {
const pass_desc: renderpass.Description = .{
.src_access_mask = .shader_read_bit,
.dst_access_mask = .color_attachment_write_bit,
.src_stage_mask = .fragment_shader_bit,
.dst_stage_mask = .color_attachment_output_bit,
const pass_desc: RenderPass.Description = .{
.src_access_mask = .{ .shader_read_bit = true },
.dst_access_mask = .{ .color_attachment_write_bit = true },
.src_stage_mask = .{ .fragment_shader_bit = true },
.dst_stage_mask = .{ .color_attachment_output_bit = true },
};
for (formats) |format, i| {
@ -104,9 +104,8 @@ pub const Framebuffer = struct {
pass_desc.attachments[i].layout = layout;
}
const pass = try renderpass.get(&pass_desc);
const pass = try RenderPass.get(&pass_desc);
return try device.dispatch.createFramebuffer(device.handle, .{
.s_type = .framebuffer_create_info,
.render_pass = pass,
.attachment_count = attachments.len,
.p_attachments = attachments.ptr,

View File

@ -50,6 +50,8 @@ pub const Image = struct {
/// import vk.Image handle into an existing Image object.
pub fn import(self: *Image, device: *const Device, info: vk.ImageCreateInfo, handle: vk.Image) !void {
errdefer memory.imageDel(self, device);
self.handle = handle;
self.image_type = info.image_type;
self.format = info.format;
@ -66,8 +68,6 @@ pub const Image = struct {
var view_info = try infoToViewInfo(&info);
view_info.image = self.handle;
self.view = try device.dispatch.createImageView(device.handle, &view_info, null);
errdefer memory.imageDel(self);
}
fn getSubmit(self: *Self) SubmitId {
@ -260,13 +260,15 @@ pub const Image = struct {
.layout = self.layout,
}, 0, img.array_layers, 0, img.mip_levels);
assert(img.state.substates == null);
std.debug.print("substates\n", .{});
return inserted_barrier;
}
const new_resource = if (prev.stage.toInt() == 0) {
var new_resource = false;
if (prev.stage.toInt() == 0) {
prev.stage = .{ .top_of_pipe_bit = true };
return true;
} else false;
new_resource = true;
}
const aspect = if (img.usage.depth_stencil_attachment_bit) vk.ImageAspectFlags{ .depth_bit = true } else vk.ImageAspectFlags{ .color_bit = true };
@ -279,7 +281,6 @@ pub const Image = struct {
}
const barrier: vk.ImageMemoryBarrier = .{
.s_type = .image_memory_barrier,
.src_access_mask = prev.access,
.dst_access_mask = self.access,
.old_layout = prev.layout,
@ -302,7 +303,9 @@ pub const Image = struct {
assert(!dst_cmd.queue_transfer_src);
dst_cmd.queue_transfer_dst = true;
device.dispatch.cmdPipelineBarrier(dst_cmd.handle, prev.stage, self.stage, .{}, 0, undefined, 0, undefined, 1, @ptrCast([*]const vk.ImageMemoryBarrier, &barrier));
std.debug.print("prev: {},\n\nself: {}\n\n", .{ prev, self });
prev.* = self.*;
std.debug.print("AFTERWARDS prev: {},\n\nself: {}\n\n", .{ prev, self });
inserted_barrier = true;
} else {
const layout_change = prev.layout != self.layout;
@ -317,7 +320,6 @@ pub const Image = struct {
// data hazard, insert barrier
const cmd = try Command.Buffer.get(self.owner, device);
const barrier: vk.ImageMemoryBarrier = .{
.s_type = .image_memory_barrier,
.src_access_mask = prev.access,
.dst_access_mask = self.access,
.old_layout = prev.layout,
@ -334,7 +336,9 @@ pub const Image = struct {
},
};
device.dispatch.cmdPipelineBarrier(cmd.handle, prev.stage, self.stage, .{}, 0, undefined, 0, undefined, 1, @ptrCast([*]const vk.ImageMemoryBarrier, &barrier));
std.debug.print("prev: {},\n\nself: {}\n\n", .{ prev, self });
prev.* = self.*;
std.debug.print("AFTERWARDS prev: {},\n\nself: {}\n\n", .{ prev, self });
inserted_barrier = true;
} else {
// no data hazard, append usage state
@ -346,6 +350,7 @@ pub const Image = struct {
(try Command.Buffer.get(self.owner, device)).touchImage(img);
assert(img.state.layout == self.layout);
std.debug.print("inserted barrier: {}\n", .{inserted_barrier});
return inserted_barrier;
}
};
@ -553,7 +558,6 @@ pub const Image = struct {
const barrier = &barriers[b];
b += 1;
barrier.* = .{
.s_type = .image_memory_barrier,
.src_access_mask = prev_sub.access,
.dst_access_mask = next.access,
.old_layout = prev_sub.layout,
@ -717,7 +721,6 @@ pub fn infoToViewInfo(info: *const vk.ImageCreateInfo) !vk.ImageViewCreateInfo {
const viewless: vk.ImageUsageFlags = .{ .transfer_src_bit = true, .transfer_dst_bit = true };
if (!info.usage.contains(viewless)) {
return vk.ImageViewCreateInfo{
.s_type = .image_view_create_info,
.flags = .{},
.format = info.format,
.view_type = infoToViewType(info),

View File

@ -1,5 +0,0 @@
const vk = @import("vulkan");
pub fn init() !void {}
pub fn deinit() !void {}

View File

@ -138,7 +138,6 @@ const Pool = struct {
if (buffer_usage) |usage| {
const mem_type_index = try handle.findMemoryTypeIndexForBufferInfo(.{
.s_type = .buffer_create_info,
.flags = .{},
.size = size_u32,
.usage = usage,
@ -166,7 +165,6 @@ const Pool = struct {
};
} else if (image_usage) |usage| {
const mem_type_index = try handle.findMemoryTypeIndexForImageInfo(.{
.s_type = .image_create_info,
.flags = .{},
.image_type = .@"2d",
.format = .r16g16b16a16_sfloat,

View File

@ -159,7 +159,6 @@ pub const Swapchain = struct {
const usage: vk.ImageUsageFlags = .{ .color_attachment_bit = true };
const swap_info = vk.SwapchainCreateInfoKHR{
.s_type = .swapchain_create_info_khr,
.flags = .{},
.surface = window.surface,
.present_mode = mode,
@ -213,7 +212,6 @@ pub const Swapchain = struct {
for (images[0..img_count]) |img, i| {
try self.images[i].import(device, .{
.s_type = .image_create_info,
.flags = .{},
.image_type = .@"2d",
.extent = .{
@ -300,7 +298,6 @@ pub const Swapchain = struct {
{
const backbuf = self.getBackBuffer();
const prev_use = backbuf.state.stage;
//std.debug.print("PRESENT... swapchain {}\n\n{} \n", .{self, images});
_ = try Image.State.presentSrc(device, command, backbuf);
const submit_id = try command.submit(device, self.available_semas[sync_index], prev_use, self.rendered_semas[sync_index]);
@ -314,7 +311,14 @@ pub const Swapchain = struct {
queue = queues.get(.present);
}
_ = try device.dispatch.queuePresentKHR(queue.handle, &.{ .s_type = .present_info_khr, .wait_semaphore_count = 1, .p_wait_semaphores = @ptrCast([*]const vk.Semaphore, &self.rendered_semas[sync_index]), .swapchain_count = 1, .p_swapchains = @ptrCast([*]const vk.SwapchainKHR, &self.handle), .p_results = null, .p_image_indices = @ptrCast([*]const u32, &self.image_index) });
_ = try device.dispatch.queuePresentKHR(queue.handle, &.{
.wait_semaphore_count = 1,
.p_wait_semaphores = @ptrCast([*]const vk.Semaphore, &self.rendered_semas[sync_index]),
.swapchain_count = 1,
.p_swapchains = @ptrCast([*]const vk.SwapchainKHR, &self.handle),
.p_results = null,
.p_image_indices = @ptrCast([*]const u32, &self.image_index),
});
}
}

View File

@ -14,7 +14,6 @@ pub const Semaphore = struct {
pub fn init(device: *const Device) !Self {
const handle = try device.dispatch.createSemaphore(device.handle, &.{
.s_type = .semaphore_create_info,
.flags = .{},
}, null);
@ -40,7 +39,7 @@ pub const Fence = struct {
pub const InitError = DeviceDispatch.CreateFenceError;
pub fn init(device: *const Device, signaled: bool) !Self {
const handle = try device.dispatch.createFence(device.handle, &.{ .s_type = .fence_create_info, .flags = .{
const handle = try device.dispatch.createFence(device.handle, &.{ .flags = .{
.signaled_bit = if (signaled) true else false,
} }, null);