#include "render/mesh.h" #include "render/buffer.h" #include "render/renderer.h" #include #include #include static VkCommandBuffer begin_single_command(struct renderer *ren) { VkCommandBufferAllocateInfo alloc_info = { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, .commandPool = ren->command.pool, .commandBufferCount = 1 }; VkCommandBuffer buffer; vkAllocateCommandBuffers(ren->gpu.device, &alloc_info, &buffer); VkCommandBufferBeginInfo begin_info = { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; vkBeginCommandBuffer(buffer, &begin_info); return buffer; } static void end_single_command(struct renderer *ren, VkCommandBuffer buffer) { vkEndCommandBuffer(buffer); VkSubmitInfo submit_info = { .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .commandBufferCount = 1, .pCommandBuffers = &buffer }; vkQueueSubmit(ren->gpu.gfx_queue, 1, &submit_info, VK_NULL_HANDLE); vkQueueWaitIdle(ren->gpu.gfx_queue); vkFreeCommandBuffers(ren->gpu.device, ren->command.pool, 1, &buffer); } struct mesh upload_mesh(struct renderer *ren, size_t vertex_count, struct vertex vertices[vertex_count], size_t index_count, uint32_t indices[index_count], struct vec3 position) { const VkDeviceSize vertex_buffer_size = sizeof(*vertices) * vertex_count; const VkDeviceSize index_buffer_size = sizeof(*indices) * index_count; struct mesh buf; buffer_create(ren, vertex_buffer_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &buf.vertex); buffer_create(ren, index_buffer_size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &buf.index); struct buffer tmp; buffer_create(ren, vertex_buffer_size + index_buffer_size + sizeof(mat4x4), VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &tmp); void *data; vkMapMemory(ren->gpu.device, tmp.memory, 0, vertex_buffer_size + index_buffer_size + sizeof(mat4x4), 0, &data); memcpy(data, vertices, vertex_buffer_size); memcpy((char *)data + vertex_buffer_size, indices, index_buffer_size); vkUnmapMemory(ren->gpu.device, tmp.memory); VkCommandBuffer cmd = begin_single_command(ren); vkCmdCopyBuffer(cmd, tmp.buffer, buf.vertex.buffer, 1, &(VkBufferCopy) { .size = vertex_buffer_size }); vkCmdCopyBuffer(cmd, tmp.buffer, buf.index.buffer, 1, &(VkBufferCopy) { .size = index_buffer_size, .srcOffset = vertex_buffer_size }); end_single_command(ren, cmd); buffer_destroy(ren, &tmp); buf.index_count = index_count; mat4x4_translate(buf.position, position.x, position.y, position.z); return buf; } void mesh_destroy(struct renderer *ren, struct mesh *mesh) { vkDeviceWaitIdle(ren->gpu.device); buffer_destroy(ren, &mesh->vertex); buffer_destroy(ren, &mesh->index); }