diff --git a/examples/graphics_context.zig b/examples/graphics-context.zig similarity index 88% rename from examples/graphics_context.zig rename to examples/graphics-context.zig index 0969a86..0be86d0 100644 --- a/examples/graphics_context.zig +++ b/examples/graphics-context.zig @@ -24,6 +24,7 @@ const InstanceDispatch = struct { vkGetPhysicalDeviceSurfaceCapabilitiesKHR: vk.PfnGetPhysicalDeviceSurfaceCapabilitiesKHR, vkGetPhysicalDeviceQueueFamilyProperties: vk.PfnGetPhysicalDeviceQueueFamilyProperties, vkGetPhysicalDeviceSurfaceSupportKHR: vk.PfnGetPhysicalDeviceSurfaceSupportKHR, + vkGetPhysicalDeviceMemoryProperties: vk.PfnGetPhysicalDeviceMemoryProperties, vkGetDeviceProcAddr: vk.PfnGetDeviceProcAddr, usingnamespace vk.InstanceWrapper(@This()); }; @@ -63,12 +64,21 @@ const DeviceDispatch = struct { vkDestroyFramebuffer: vk.PfnDestroyFramebuffer, vkBeginCommandBuffer: vk.PfnBeginCommandBuffer, vkEndCommandBuffer: vk.PfnEndCommandBuffer, + vkAllocateMemory: vk.PfnAllocateMemory, + vkFreeMemory: vk.PfnFreeMemory, + vkCreateBuffer: vk.PfnCreateBuffer, + vkDestroyBuffer: vk.PfnDestroyBuffer, + vkGetBufferMemoryRequirements: vk.PfnGetBufferMemoryRequirements, + vkMapMemory: vk.PfnMapMemory, + vkUnmapMemory: vk.PfnUnmapMemory, + vkBindBufferMemory: vk.PfnBindBufferMemory, vkCmdBeginRenderPass: vk.PfnCmdBeginRenderPass, vkCmdEndRenderPass: vk.PfnCmdEndRenderPass, vkCmdBindPipeline: vk.PfnCmdBindPipeline, vkCmdDraw: vk.PfnCmdDraw, vkCmdSetViewport: vk.PfnCmdSetViewport, vkCmdSetScissor: vk.PfnCmdSetScissor, + vkCmdBindVertexBuffers: vk.PfnCmdBindVertexBuffers, usingnamespace vk.DeviceWrapper(@This()); }; @@ -81,6 +91,8 @@ pub const GraphicsContext = struct { surface: vk.SurfaceKHR, pdev: vk.PhysicalDevice, props: vk.PhysicalDeviceProperties, + mem_props: vk.PhysicalDeviceMemoryProperties, + dev: vk.Device, graphics_queue: Queue, present_queue: Queue, @@ -125,6 +137,8 @@ pub const GraphicsContext = struct { self.graphics_queue = Queue.init(self.vkd, self.dev, candidate.queues.graphics_family); self.present_queue = Queue.init(self.vkd, self.dev, candidate.queues.graphics_family); + self.mem_props = self.vki.getPhysicalDeviceMemoryProperties(self.pdev); + return self; } @@ -138,6 +152,23 @@ pub const GraphicsContext = struct { const len = std.mem.indexOfScalar(u8, &self.props.device_name, 0).?; return self.props.device_name[0 .. len]; } + + pub fn findMemoryTypeIndex(self: GraphicsContext, memory_type_bits: u32, flags: vk.MemoryPropertyFlags) !u32 { + for (self.mem_props.memory_types[0 .. self.mem_props.memory_type_count]) |mem_type, i| { + if (memory_type_bits & (@as(u32, 1) << @truncate(u5, i)) != 0 and mem_type.property_flags.contains(flags)) { + return @truncate(u32, i); + } + } + + return error.NoSuitableMemoryType; + } + + pub fn allocate(self: GraphicsContext, requirements: vk.MemoryRequirements, flags: vk.MemoryPropertyFlags) !vk.DeviceMemory { + return try self.vkd.allocateMemory(self.dev, .{ + .allocation_size = requirements.size, + .memory_type_index = try self.findMemoryTypeIndex(requirements.memory_type_bits, flags), + }, null); + } }; pub const Queue = struct { diff --git a/examples/main.zig b/examples/main.zig index def318f..0242d7c 100644 --- a/examples/main.zig +++ b/examples/main.zig @@ -2,12 +2,44 @@ const std = @import("std"); const vk = @import("vulkan"); const c = @import("c.zig"); const resources = @import("resources"); -const GraphicsContext = @import("graphics_context.zig").GraphicsContext; +const GraphicsContext = @import("graphics-context.zig").GraphicsContext; const Swapchain = @import("swapchain.zig").Swapchain; const Allocator = std.mem.Allocator; const app_name = "vulkan-zig example"; +const Vertex = struct { + const binding_description = vk.VertexInputBindingDescription{ + .binding = 0, + .stride = @sizeOf(Vertex), + .input_rate = .vertex, + }; + + const attribute_description = [_]vk.VertexInputAttributeDescription{ + .{ + .binding = 0, + .location = 0, + .format = .r32g32_sfloat, + .offset = @byteOffsetOf(Vertex, "pos"), + }, + .{ + .binding = 0, + .location = 1, + .format = .r32g32b32_sfloat, + .offset = @byteOffsetOf(Vertex, "color"), + }, + }; + + pos: [2]f32, + color: [3]f32, +}; + +const vertices = [_]Vertex{ + .{.pos = .{0, -0.5}, .color = .{1, 0, 0}}, + .{.pos = .{0.5, 0.5}, .color = .{0, 1, 0}}, + .{.pos = .{-0.5, 0.5}, .color = .{0, 0, 1}}, +}; + pub fn main() !void { if (c.glfwInit() != c.GLFW_TRUE) return error.GlfwInitFailed; defer c.glfwTerminate(); @@ -52,6 +84,30 @@ pub fn main() !void { var framebuffers = try createFramebuffers(&gc, allocator, render_pass, swapchain); defer destroyFramebuffers(&gc, allocator, framebuffers); + const buffer = try gc.vkd.createBuffer(gc.dev, .{ + .flags = .{}, + .size = @sizeOf(@TypeOf(vertices)), + .usage = .{.vertex_buffer_bit = true}, + .sharing_mode = .exclusive, + .queue_family_index_count = 0, + .p_queue_family_indices = undefined, + }, null); + defer gc.vkd.destroyBuffer(gc.dev, buffer, null); + const mem_reqs = gc.vkd.getBufferMemoryRequirements(gc.dev, buffer); + const memory = try gc.allocate(mem_reqs, .{.host_visible_bit = true, .host_coherent_bit = true}); + defer gc.vkd.freeMemory(gc.dev, memory, null); + try gc.vkd.bindBufferMemory(gc.dev, buffer, memory, 0); + + { + const data = try gc.vkd.mapMemory(gc.dev, memory, 0, vk.WHOLE_SIZE, .{}); + defer gc.vkd.unmapMemory(gc.dev, memory); + + const gpu_vertices = @ptrCast([*]Vertex, @alignCast(@alignOf(Vertex), data)); + for (vertices) |vertex, i| { + gpu_vertices[i] = vertex; + } + } + const pool = try gc.vkd.createCommandPool(gc.dev, .{ .flags = .{}, .queue_family_index = gc.graphics_queue.family, @@ -62,6 +118,7 @@ pub fn main() !void { &gc, pool, allocator, + buffer, swapchain.extent, render_pass, pipeline, @@ -93,6 +150,7 @@ pub fn main() !void { &gc, pool, allocator, + buffer, swapchain.extent, render_pass, pipeline, @@ -111,6 +169,7 @@ fn createCommandBuffers( gc: *const GraphicsContext, pool: vk.CommandPool, allocator: *Allocator, + buffer: vk.Buffer, extent: vk.Extent2D, render_pass: vk.RenderPass, pipeline: vk.Pipeline, @@ -165,7 +224,9 @@ fn createCommandBuffers( }, .@"inline"); gc.vkd.cmdBindPipeline(cmdbuf, .graphics, pipeline); - gc.vkd.cmdDraw(cmdbuf, 3, 1, 0, 0); + const offset = [_]vk.DeviceSize{0}; + gc.vkd.cmdBindVertexBuffers(cmdbuf, 0, 1, @ptrCast([*]const vk.Buffer, &buffer), &offset); + gc.vkd.cmdDraw(cmdbuf, vertices.len, 1, 0, 0); gc.vkd.cmdEndRenderPass(cmdbuf); try gc.vkd.endCommandBuffer(cmdbuf); @@ -293,10 +354,10 @@ fn createPipeline( const pvisci = vk.PipelineVertexInputStateCreateInfo{ .flags = .{}, - .vertex_binding_description_count = 0, - .p_vertex_binding_descriptions = undefined, - .vertex_attribute_description_count = 0, - .p_vertex_attribute_descriptions = undefined, + .vertex_binding_description_count = 1, + .p_vertex_binding_descriptions = @ptrCast([*]const vk.VertexInputBindingDescription, &Vertex.binding_description), + .vertex_attribute_description_count = Vertex.attribute_description.len, + .p_vertex_attribute_descriptions = &Vertex.attribute_description, }; const piasci = vk.PipelineInputAssemblyStateCreateInfo{ diff --git a/examples/shaders/triangle.vert b/examples/shaders/triangle.vert index 23666c7..2b8dfa5 100644 --- a/examples/shaders/triangle.vert +++ b/examples/shaders/triangle.vert @@ -1,20 +1,11 @@ #version 450 -const vec2 positions[3] = vec2[]( - vec2(0.0, -0.5), - vec2(0.5, 0.5), - vec2(-0.5, 0.5) -); - -const vec3 colors[3] = vec3[]( - vec3(1.0, 0.0, 0.0), - vec3(0.0, 1.0, 0.0), - vec3(0.0, 0.0, 1.0) -); +layout(location = 0) in vec2 a_pos; +layout(location = 1) in vec3 a_color; layout(location = 0) out vec3 v_color; void main() { - gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); - v_color = colors[gl_VertexIndex]; + gl_Position = vec4(a_pos, 0.0, 1.0); + v_color = a_color; } diff --git a/examples/swapchain.zig b/examples/swapchain.zig index 7394d4f..cf42f80 100644 --- a/examples/swapchain.zig +++ b/examples/swapchain.zig @@ -1,7 +1,7 @@ const std = @import("std"); const vk = @import("vulkan"); const c = @import("c.zig"); -const GraphicsContext = @import("graphics_context.zig").GraphicsContext; +const GraphicsContext = @import("graphics-context.zig").GraphicsContext; const Allocator = std.mem.Allocator; pub const Swapchain = struct { diff --git a/generator/vulkan/generator.zig b/generator/vulkan/generator.zig index 1198272..fb693dd 100644 --- a/generator/vulkan/generator.zig +++ b/generator/vulkan/generator.zig @@ -173,10 +173,10 @@ pub const Generator = struct { fn removePromotedExtensions(self: *Generator) void { var write_index: usize = 0; for (self.registry.extensions) |ext| { - if (ext.promoted_to == .none) { + // if (ext.promoted_to == .none) { self.registry.extensions[write_index] = ext; write_index += 1; - } + // } } self.registry.extensions.len = write_index; } diff --git a/generator/vulkan/render.zig b/generator/vulkan/render.zig index 9fe641a..a507ffd 100644 --- a/generator/vulkan/render.zig +++ b/generator/vulkan/render.zig @@ -597,7 +597,7 @@ fn Renderer(comptime WriterType: type) type { try self.writer.writeAll("pub const "); try self.renderEnumFieldName(name, field.name); - try self.writer.writeAll(" = "); + try self.writer.writeAll(" = ."); try self.renderEnumFieldName(name, field.value.alias.name); try self.writer.writeAll(";"); } @@ -1033,13 +1033,13 @@ fn Renderer(comptime WriterType: type) type { try self.writer.writeAll(") {\n"); for (command.success_codes) |success| { - try self.writer.writeByte('.'); + try self.writer.writeAll("Result."); try self.renderEnumFieldName("VkResult", success); try self.writer.writeAll(" => {},"); } for (command.error_codes) |err| { - try self.writer.writeByte('.'); + try self.writer.writeAll("Result."); try self.renderEnumFieldName("VkResult", err); try self.writer.writeAll(" => return error."); try self.renderResultAsErrorName(err);