/* SPDX-License-Identifier:BSD-3-Clause */ #include "buffer.h" #include "../../core/log.h" #include static u32 find_memory_type(struct renderer_context *context, u32 type_filter, VkMemoryPropertyFlags properties) { VkPhysicalDeviceMemoryProperties mem_props; vkGetPhysicalDeviceMemoryProperties(context->physical_device, &mem_props); for (u32 i = 0; i < mem_props.memoryTypeCount; i++) { if ((type_filter & (1 << i)) && (mem_props.memoryTypes[i].propertyFlags & properties) == properties) { return i; } } fatal("Can't find suitable memory type.\n"); return 0; } void vk_buffer_create(struct renderer_context *context, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer *buffer, VkDeviceMemory *memory) { VkBufferCreateInfo buffer_info = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .size = size, .usage = usage, .sharingMode = VK_SHARING_MODE_EXCLUSIVE }; if (vkCreateBuffer(context->device, &buffer_info, NULL, buffer) != VK_SUCCESS) { fatal("Can't create buffer.\n"); } VkMemoryRequirements mem_reqs; vkGetBufferMemoryRequirements(context->device, *buffer, &mem_reqs); VkMemoryAllocateInfo alloc_info = { .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, .allocationSize = mem_reqs.size, .memoryTypeIndex = find_memory_type(context, mem_reqs.memoryTypeBits, properties) }; if (vkAllocateMemory(context->device, &alloc_info, NULL, memory) != VK_SUCCESS) { fatal("Can't allocate buffer memory.\n"); } vkBindBufferMemory(context->device, *buffer, *memory, 0); } void vk_buffer_destroy(struct renderer_context *context, VkBuffer buffer, VkDeviceMemory memory) { vkDestroyBuffer(context->device, buffer, NULL); vkFreeMemory(context->device, memory, NULL); } void vk_quad_buffers_init(struct renderer_context *context) { /* Quad vertices: position (x, y) + color (r, g, b) */ f32 vertices[] = { -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f }; /* Indices for two triangles forming a quad */ u16 indices[] = { 0, 1, 2, 2, 3, 0 }; VkDeviceSize vertex_size = sizeof(vertices); VkDeviceSize index_size = sizeof(indices); vk_buffer_create(context, vertex_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &context->vertex_buffer, &context->vertex_buffer_memory); void *data; vkMapMemory(context->device, context->vertex_buffer_memory, 0, vertex_size, 0, &data); memcpy(data, vertices, vertex_size); vkUnmapMemory(context->device, context->vertex_buffer_memory); vk_buffer_create(context, index_size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &context->index_buffer, &context->index_buffer_memory); vkMapMemory(context->device, context->index_buffer_memory, 0, index_size, 0, &data); memcpy(data, indices, index_size); vkUnmapMemory(context->device, context->index_buffer_memory); log_info("Quad buffers created.\n"); } void vk_quad_buffers_deinit(struct renderer_context *context) { vk_buffer_destroy(context, context->index_buffer, context->index_buffer_memory); vk_buffer_destroy(context, context->vertex_buffer, context->vertex_buffer_memory); }