Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 66 additions & 91 deletions samples/basic_planes.zig
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ var external_extensions: ?[][*:0]const u8 = null;

var context: *Context = undefined;

var graphics_queue: api.GraphicsQueue = undefined;
var present_queue: api.PresentQueue = undefined;
var swapchain: api.Swapchain = undefined;

var window_handle: *glfw.Window = undefined;
Expand All @@ -52,9 +50,9 @@ var command_buffer: api.CommandBuffer = undefined;
const validation_layers: [1][*:0]const u8 = .{"VK_LAYER_KHRONOS_validation"};
const device_extensions = [_][*:0]const u8{api.extensions.khr_swapchain.name};

var render_finished_semaphore: api.Semaphore = .null_handle;
var image_finished_semaphore: api.Semaphore = .null_handle;
var present_finished_fence: api.Fence = .null_handle;
var render_finished_semaphore: api.Semaphore = undefined;
var image_finished_semaphore: api.Semaphore = undefined;
var present_finished_fence: api.Fence = undefined;

var dev: *const api.DeviceHandler = undefined;
var pr_dev: *const api.DeviceInterface = undefined;
Expand All @@ -81,11 +79,9 @@ var vertex_buffer: VertexBuffer = undefined;
var index_buffer: IndexBuffer = undefined;
var uniform_buffer: UniformBuffer = undefined;

var vb_interface: api.BufInterface = undefined;
var ib_interface: api.BufInterface = undefined;

var test_descriptor: api.Descriptor = undefined;
var test_tex: api.TexImage = undefined;
var test_tex: api.Image = undefined;
var test_tex_view: api.Image.View = undefined;

fn glfwErrorCallback(code: c_int, desc: [*c]const u8) callconv(.c) void {
glfw_log.err("error code {d} -- Message: {s}", .{ code, desc });
Expand Down Expand Up @@ -120,12 +116,6 @@ fn init(allocator: Allocator) !void {
dev = context.env(.dev);
pr_dev = context.env(.di);

graphics_queue = try api.GraphicsQueue.init(context);
errdefer graphics_queue.deinit();

present_queue = try api.PresentQueue.init(context);
errdefer present_queue.deinit();

swapchain = try api.Swapchain.init(context, allocator, .{
.requested_present_mode = .mailbox_khr,
.requested_format = .{
Expand All @@ -139,54 +129,62 @@ fn init(allocator: Allocator) !void {
});
errdefer swapchain.deinit();

const vert_shader_module = try api.ShaderModule.fromSourceFile(context, allocator, .{
.stage = .Vertex,
.filename = "shaders/shader.vert",
});
const vert_shader_module = try api.ShaderModule.fromSourceFile(
context,
allocator,
"shaders/shader.vert",
.Vertex,
);

defer vert_shader_module.deinit();
const frag_shader_module = try api.ShaderModule.fromSourceFile(context, allocator, .{
.stage = .Fragment,
.filename = "shaders/shader.frag",
});
const frag_shader_module = try api.ShaderModule.fromSourceFile(
context,
allocator,
"shaders/shader.frag",
.Fragment,
);
defer frag_shader_module.deinit();

const dynamic_states = [_]api.DynamicState{
.viewport,
.scissor,
};

test_tex = try api.TexImage.fromFile(context, allocator, "textures/shrek.png");
test_tex = try api.Image.fromFile(context, allocator, "textures/shrek.png");
errdefer test_tex.deinit();

test_tex_view = try test_tex.createView(.{ .color_bit = true });
errdefer test_tex_view.deinit();

uniform_buffer = try UniformBuffer.create(context);
errdefer uniform_buffer.buffer().deinit();
errdefer uniform_buffer.deinit();

const desc_bindings = [_]api.ResolvedDescriptorBinding{ .{
test_descriptor = try api.Descriptor.init(context, allocator, .{ .bindings = &.{ .{
.stages = .{ .vertex_bit = true },
.data = .{ .Uniform = uniform_buffer.buffer() },
}, .{
.stages = .{ .fragment_bit = true },
.data = .{ .Sampler = &test_tex },
} };

test_descriptor = try api.Descriptor.init(context, allocator, .{
.bindings = desc_bindings[0..],
});
.data = .{ .Sampler = .{
.view = test_tex_view.h_view,
.sampler = try test_tex.getSampler(.{}),
} },
} } });
errdefer test_descriptor.deinit();

root_log.debug("vertex stride: {d}", .{VertexBuffer.Description.vertex_desc.stride});

var fixed_function_state = api.FixedFunctionState{};
fixed_function_state.init_self(context, &.{
.viewport = .{ .Swapchain = &swapchain },
.dynamic_states = &dynamic_states,
.deez_nuts = true,
.vertex_binding = VertexBuffer.Description.vertex_desc,
.vertex_attribs = VertexBuffer.Description.attrib_desc,
.descriptors = &[_]api.vk.DescriptorSetLayout{test_descriptor.h_desc_layout},
.descriptors = &.{test_descriptor.h_desc_layout},
});
defer fixed_function_state.deinit();

renderpass = try api.RenderPass.initAlloc(context, scratch, &[_]api.RenderPass.ConfigEntry{
renderpass = try api.RenderPass.initAlloc(context, scratch, &.{
.{
.attachment = .{
.format = swapchain.surface_format.format,
Expand Down Expand Up @@ -216,37 +214,33 @@ fn init(allocator: Allocator) !void {
});
errdefer renderpass.deinit();

graphics_pipeline = try api.GraphicsPipeline.init(context, &.{
graphics_pipeline = try api.GraphicsPipeline.init(context, .{
.renderpass = &renderpass,
.fixed_functions = &fixed_function_state,
.shader_stages = &[_]api.ShaderModule{ vert_shader_module, frag_shader_module },
.shader_stages = &.{ vert_shader_module, frag_shader_module },
}, scratch);
errdefer graphics_pipeline.deinit();

depth_image = try api.DepthImage.init(context, swapchain.extent);
errdefer depth_image.deinit();

framebuffers = try api.FrameBuffer.initAlloc(context, allocator, &.{
framebuffers = try api.FrameBuffer.initAlloc(context, allocator, .{
.renderpass = &renderpass,
.image_views = swapchain.images,
.swapchain = &swapchain,
.depth_view = depth_image.view.h_view,
.extent = api.vk.Rect2D{
.extent = swapchain.extent,
.offset = .{ .x = 0, .y = 0 },
},
});
errdefer framebuffers.deinit();

// create a bunch of stupid synchronization objects and stuff
// I didn't really integrate these into the wrapper structs cuz i kinda don't really
// know where to put them
render_finished_semaphore = try pr_dev.createSemaphore(&.{}, null);
image_finished_semaphore = try pr_dev.createSemaphore(&.{}, null);
present_finished_fence = try pr_dev.createFence(&.{
.flags = .{ .signaled_bit = true },
}, null);
render_finished_semaphore = try api.Semaphore.init(context);
image_finished_semaphore = try api.Semaphore.init(context);
present_finished_fence = try api.Fence.init(context, true);

command_buffer = try api.CommandBuffer.init(context);
command_buffer = try api.CommandBuffer.init(context, .{
.src_queue_family = .Graphics,
});

const vertex_data = [_]TestVertexInput{
.{ .position = math.vec(.{ -0.5, 0.0, -0.5 }), .color = math.vec(.{ 1.0, 0.0, 0.0 }), .uv = math.vec(.{ 1.0, 0.0 }) },
Expand All @@ -265,10 +259,7 @@ fn init(allocator: Allocator) !void {
return err;
};

vb_interface = vertex_buffer.buffer();
errdefer vb_interface.deinit();

vb_interface.setData(vertex_data[0..]) catch |err| {
vertex_buffer.setData(vertex_data[0..]) catch |err| {
root_log.err("Failed to load vertex data: {!}", .{err});
return err;
};
Expand All @@ -280,10 +271,7 @@ fn init(allocator: Allocator) !void {
return err;
};

ib_interface = index_buffer.buffer();
errdefer ib_interface.deinit();

ib_interface.setData(index_data[0..]) catch |err| {
index_buffer.setData(index_data[0..]) catch |err| {
root_log.err("Failed to load index buffer data: {!}", .{err});
return err;
};
Expand Down Expand Up @@ -326,77 +314,64 @@ fn updateUniforms() !void {
}

fn mainLoop() !void {
_ = pr_dev.waitForFences(
1,
util.asManyPtr(api.Fence, &present_finished_fence),
vk_true,
std.math.maxInt(u64),
) catch {}; // fuck rendering errors
try present_finished_fence.wait();
try present_finished_fence.reset();

pr_dev.resetFences(
1,
util.asManyPtr(api.Fence, &present_finished_fence),
) catch {};

const current_image = try swapchain.getNextImage(image_finished_semaphore, null);
_ = try swapchain.getNextImage(image_finished_semaphore.h_sem, null);

try command_buffer.reset();

try command_buffer.begin();
renderpass.begin(&command_buffer, &framebuffers, current_image);
renderpass.begin(&command_buffer, &framebuffers, swapchain.image_index);

try updateUniforms();

graphics_pipeline.bind(&command_buffer);

vb_interface.bind(&command_buffer);
ib_interface.bind(&command_buffer);
test_descriptor.bind(&command_buffer, graphics_pipeline.h_pipeline_layout);
vertex_buffer.bind(&command_buffer);
index_buffer.bind(&command_buffer);
test_descriptor.bind(&command_buffer, graphics_pipeline.h_pipeline_layout, .{});

dev.drawIndexed(&command_buffer, @intCast(index_buffer.buf.size), 1, 0, 0, 0);

renderpass.end(&command_buffer);

try command_buffer.end();

try graphics_queue.submit(
&command_buffer,
image_finished_semaphore,
render_finished_semaphore,
present_finished_fence,
);
try command_buffer.submit(.Graphics, .{
.sem_sig = render_finished_semaphore.h_sem,
.sem_wait = image_finished_semaphore.h_sem,
.fence_wait = present_finished_fence.h_fence,
});

try present_queue.present(
&swapchain,
current_image,
render_finished_semaphore,
);
try context.presentFrame(&swapchain, .{
.sem_wait = render_finished_semaphore.h_sem,
});
}

fn deinit() void {
dev.waitIdle() catch {
root_log.err("Failed to wait on device", .{});
};
// destroy synchronization objects
dev.pr_dev.destroySemaphore(render_finished_semaphore, null);
dev.pr_dev.destroySemaphore(image_finished_semaphore, null);
dev.pr_dev.destroyFence(present_finished_fence, null);
render_finished_semaphore.deinit();
image_finished_semaphore.deinit();
present_finished_fence.deinit();

test_tex_view.deinit();
test_tex.deinit();

ib_interface.deinit();
vb_interface.deinit();
index_buffer.deinit();
vertex_buffer.deinit();

uniform_buffer.buffer().deinit();
uniform_buffer.deinit();

depth_image.deinit();
framebuffers.deinit();
graphics_pipeline.deinit();
test_descriptor.deinit();
renderpass.deinit();
swapchain.deinit();
graphics_queue.deinit();
present_queue.deinit();
context.deinit();
}

Expand Down
6 changes: 2 additions & 4 deletions src/api/depth.zig
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@ dev: *const DeviceHandler,
pub fn init(ctx: *const Context, dimensions: vk.Extent2D) !Self {
const dev: *const DeviceHandler = ctx.env(.dev);
log.debug("Chosen depth format: {s}", .{@tagName(try dev.findDepthFormat())});
const image = try Image.init(ctx, &.{
const image = try Image.init(ctx, .{
.format = try dev.findDepthFormat(),
.height = dimensions.height,
.width = dimensions.width,

.extent = dimensions,
.mem_flags = .{ .device_local_bit = true },
.tiling = .optimal,
.usage = .{ .depth_stencil_attachment_bit = true },
Expand Down
4 changes: 2 additions & 2 deletions src/api/graphics_pipeline.zig
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ pub const FixedFunctionState = struct {

self.vertex_input = vk.PipelineVertexInputStateCreateInfo{
.vertex_binding_description_count = if (config.vertex_binding != null) 1 else 0,
.p_vertex_binding_descriptions = if (config.vertex_binding) |vb| util.asManyPtr(
.p_vertex_binding_descriptions = if (config.vertex_binding) |*vb| util.asManyPtr(
vk.VertexInputBindingDescription,
&vb,
vb,
) else null,
.vertex_attribute_description_count = @intCast(config.vertex_attribs.len),
.p_vertex_attribute_descriptions = config.vertex_attribs.ptr,
Expand Down
12 changes: 6 additions & 6 deletions src/api/image.zig
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ pub fn init(ctx: *const Context, config: Config) !Self {

/// creates an image from an image file.
/// Image parameters will be tuned for usage as a texture
/// more so than a general purpose image for now...
/// more so than a general purpose image
pub fn fromFile(ctx: *const Context, allocator: Allocator, path: []const u8) !Self {
var image_data = rsh.loadImageFile(path, allocator) catch |err| {
log.err("Failed to load image: {!}", .{err});
Expand All @@ -446,13 +446,13 @@ pub fn fromFile(ctx: *const Context, allocator: Allocator, path: []const u8) !Se
try staging_buffer.buffer().setData(image_data.pixels.asBytes().ptr);
defer staging_buffer.deinit();

const image = try Self.init(ctx, &.{
const image = try Self.init(ctx, .{
.format = .r8g8b8a8_srgb,
.tiling = .optimal,

.height = @intCast(image_data.height),
.width = @intCast(image_data.width),

.extent = .{
.height = @intCast(image_data.height),
.width = @intCast(image_data.width),
},
.usage = .{ .transfer_dst_bit = true, .sampled_bit = true },
.mem_flags = .{ .device_local_bit = true },
.staging_buf = &staging_buffer,
Expand Down
Loading
Loading