Render square from vertex buffer

This commit is contained in:
2026-05-15 20:06:05 -08:00
parent 0e348fe0a0
commit b36f5b0b84
6 changed files with 190 additions and 13 deletions
+109
View File
@@ -0,0 +1,109 @@
const std = @import("std");
const vk = @import("vulkan");
const geometry = @import("../geometry.zig");
const context = @import("context.zig");
const device = @import("device.zig");
pub const VertexBufferContext = struct {
buffer: vk.Buffer,
memory: vk.DeviceMemory,
vertex_count: u32,
pub fn destroy(self: *const VertexBufferContext, ldc: *const device.LogicalDeviceContext) void {
ldc.vkd.destroyBuffer(ldc.device, self.buffer, null);
ldc.vkd.freeMemory(ldc.device, self.memory, null);
}
};
pub fn initVertexBuffer(
vc: context.VulkanContext,
ldc: device.LogicalDeviceContext,
vertices: []const geometry.Vertex,
) !VertexBufferContext {
const buffer_size: vk.DeviceSize = @intCast(@sizeOf(geometry.Vertex) * vertices.len);
const buffer_create_info = vk.BufferCreateInfo{
.size = buffer_size,
.usage = .{
.vertex_buffer_bit = true,
},
.sharing_mode = .exclusive,
};
const buffer = try ldc.vkd.createBuffer(ldc.device, &buffer_create_info, null);
errdefer ldc.vkd.destroyBuffer(ldc.device, buffer, null);
const memory_requirements = ldc.vkd.getBufferMemoryRequirements(
ldc.device,
buffer,
);
const memory_index = try findMemoryType(
vc,
ldc,
memory_requirements.memory_type_bits,
.{
.host_visible_bit = true,
.host_coherent_bit = true,
},
);
const alloc_info = vk.MemoryAllocateInfo{
.allocation_size = memory_requirements.size,
.memory_type_index = memory_index,
};
const memory = try ldc.vkd.allocateMemory(ldc.device, &alloc_info, null);
errdefer ldc.vkd.freeMemory(ldc.device, memory, null);
try ldc.vkd.bindBufferMemory(ldc.device, buffer, memory, 0);
const mapped = try ldc.vkd.mapMemory(
ldc.device,
memory,
0,
buffer_size,
.{},
);
defer ldc.vkd.unmapMemory(ldc.device, memory);
const dst: [*]u8 = @ptrCast(mapped);
const dst_slice = dst[0..buffer_size];
const src_bytes = std.mem.sliceAsBytes(vertices);
std.mem.copyForwards(u8, dst_slice, src_bytes);
return .{
.buffer = buffer,
.memory = memory,
.vertex_count = @intCast(vertices.len),
};
}
fn findMemoryType(
vc: context.VulkanContext,
ldc: device.LogicalDeviceContext,
type_filter: u32,
properties: vk.MemoryPropertyFlags,
) !u32 {
const memory_properties = vc.vki.getPhysicalDeviceMemoryProperties(ldc.physical_device);
var i: u5 = 0;
while (i < memory_properties.memory_type_count) : (i += 1) {
const type_supported = (type_filter & (@as(u32, 1) << i)) != 0;
const flags = memory_properties.memory_types[i].property_flags;
const has_properties =
(!properties.device_local_bit or flags.device_local_bit) and
(!properties.host_visible_bit or flags.host_visible_bit) and
(!properties.host_coherent_bit or flags.host_coherent_bit) and
(!properties.host_cached_bit or flags.host_cached_bit) and
(!properties.lazily_allocated_bit or flags.lazily_allocated_bit);
if (type_supported and has_properties) {
return i;
}
}
return error.NoSuitableMemoryType;
}
+18 -1
View File
@@ -6,6 +6,7 @@ const framebuffers = @import("framebuffers.zig");
const render_pass = @import("render_pass.zig");
const swapchain = @import("swapchain.zig");
const pipeline = @import("pipeline.zig");
const buffer = @import("buffer.zig");
pub const CommandContext = struct {
command_pool: vk.CommandPool,
@@ -24,6 +25,7 @@ pub fn initCommandBuffers(
framebuffer_context: framebuffers.FramebufferContext,
pipeline_context: pipeline.PipelineContext,
swapchain_context: swapchain.SwapchainContext,
vertex_buffer_context: buffer.VertexBufferContext,
allocator: std.mem.Allocator,
) !CommandContext {
const command_pool_create_info = vk.CommandPoolCreateInfo{
@@ -94,7 +96,22 @@ pub fn initCommandBuffers(
pipeline_context.graphics_pipeline,
);
ldc.vkd.cmdDraw(command_buffer, 3, 1, 0, 0);
const vertex_buffers = [_]vk.Buffer{
vertex_buffer_context.buffer,
};
const offsets = [_]vk.DeviceSize{
0,
};
ldc.vkd.cmdBindVertexBuffers(
command_buffer,
0,
&vertex_buffers,
&offsets,
);
ldc.vkd.cmdDraw(command_buffer, vertex_buffer_context.vertex_count, 1, 0, 0);
ldc.vkd.cmdEndRenderPass(command_buffer);
+18 -4
View File
@@ -2,6 +2,7 @@ const std = @import("std");
const vk = @import("vulkan");
const device = @import("device.zig");
const geometry = @import("../geometry.zig");
pub const PipelineContext = struct {
graphics_pipeline: vk.Pipeline,
@@ -63,11 +64,24 @@ pub fn initPipelineContext(ldc: device.LogicalDeviceContext, extent: vk.Extent2D
frag_shader_stage_info,
};
const binding_description = vk.VertexInputBindingDescription{
.binding = 0,
.stride = @sizeOf(geometry.Vertex),
.input_rate = .vertex,
};
const attribute_description = vk.VertexInputAttributeDescription{
.location = 0,
.binding = 0,
.format = .r32g32_sfloat,
.offset = @offsetOf(geometry.Vertex, "position"),
};
const vertex_input_info = vk.PipelineVertexInputStateCreateInfo{
.vertex_binding_description_count = 0,
.p_vertex_binding_descriptions = null,
.vertex_attribute_description_count = 0,
.p_vertex_attribute_descriptions = null,
.vertex_binding_description_count = 1,
.p_vertex_binding_descriptions = @ptrCast(&binding_description),
.vertex_attribute_description_count = 1,
.p_vertex_attribute_descriptions = @ptrCast(&attribute_description),
};
const input_assembly = vk.PipelineInputAssemblyStateCreateInfo{