1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
#include "render/mesh.h"
#include "render/buffer.h"
#include "render/renderer.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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);
}
|