topaz/rendering/vk/buffer.c

101 lines
3.4 KiB
C

/* SPDX-License-Identifier:BSD-3-Clause */
#include "buffer.h"
#include "../../core/log.h"
#include <string.h>
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);
}