-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtrtl_shell.c
151 lines (123 loc) · 4.38 KB
/
trtl_shell.c
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <string.h>
#include <talloc.h>
#include <vulkan/vulkan.h>
#include "trtl_seer.h"
#include "trtl_shell.h"
#include "trtl_solo.h"
#include "turtle.h"
#include "vertex.h"
VkCommandBuffer beginSingleTimeCommands(struct render_context *render);
void endSingleTimeCommands(struct render_context *render, VkCommandBuffer commandBuffer);
static void
copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size)
{
struct trtl_solo *solo = trtl_solo_start();
VkBufferCopy copyRegion = {0};
copyRegion.size = size;
vkCmdCopyBuffer(solo->command_buffer, srcBuffer, dstBuffer, 1, ©Region);
// Executes!
talloc_free(solo);
}
// FIXME: Trtl should take a model and create a vertex buffer for this
// FIXME: This code and the create_index buffer are like super similar
// FIXME: This should be in trtl_seer I'm pretty sure. It owns the objects, so it
// should do the allocation for vertex and index buffers.
VkBuffer
create_vertex_buffers(struct turtle *turtle, const struct trtl_seer_vertexset *vertices)
{
uint32_t nvertexes;
uint32_t nobjects = 1;
nvertexes = vertices->nvertexes;
printf("%d vertices; %d objects\n", nvertexes, nobjects);
if (nvertexes == 0) {
return VK_NULL_HANDLE;
}
assert(vertices->vertex_size != 0);
VkDeviceSize bufferSize = vertices->vertex_size * nvertexes;
printf("Buffer size is %zu %d %d\n", (size_t)bufferSize, vertices->vertex_size, nvertexes);
VkBuffer stagingBuffer;
VkDeviceMemory stagingBufferMemory;
create_buffer(turtle, bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
&stagingBuffer, &stagingBufferMemory);
{
void *data;
VkResult result =
vkMapMemory(turtle->device, stagingBufferMemory, 0, bufferSize, 0, &data);
if (result != VK_SUCCESS) {
error_msg(result, "failed to map bytes\n");
}
memcpy(data, vertices->vertices, bufferSize);
vkUnmapMemory(turtle->device, stagingBufferMemory);
}
VkBuffer vertex_buffer;
VkDeviceMemory vertex_buffer_memory;
create_buffer(turtle, bufferSize,
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &vertex_buffer, &vertex_buffer_memory);
copyBuffer(stagingBuffer, vertex_buffer, bufferSize);
vkDestroyBuffer(turtle->device, stagingBuffer, NULL);
vkFreeMemory(turtle->device, stagingBufferMemory, NULL);
return vertex_buffer;
}
/**
* Copy indexes from base -> dest, adjusting each by adjust.
*
* Used to concat a number of index arrays together.
*
* Buffers may not overlap.
*
* @param dest Destination pointer
* @param base Where to copy from
* @param count How many uint32_ts to copy
*/
static void
copy_indexes(uint32_t *restrict dest, const uint32_t *restrict base, uint32_t count)
{
// FIXME: This is glorifed memcpy
for (uint32_t i = 0; i < count; i++) {
*dest = *base;
dest++;
base++;
}
}
VkBuffer
create_index_buffer(struct turtle *turtle, const struct trtl_seer_indexset *indexes)
{
// FIXME: Hardcoded indice size
uint32_t nindexes = indexes->nindexes; // total number of indexes
VkDeviceSize buffer_size;
VkDeviceMemory memory; // FIXME: Should be returned so it can be freed
if (nindexes == 0) {
return VK_NULL_HANDLE;
}
buffer_size = nindexes * sizeof(uint32_t);
VkBuffer stagingBuffer;
VkDeviceMemory stagingBufferMemory;
create_buffer(turtle, buffer_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
&stagingBuffer, &stagingBufferMemory);
uint32_t *dest;
{
void *data;
vkMapMemory(turtle->device, stagingBufferMemory, 0, buffer_size, 0, &data);
dest = data;
}
// This ugly; update the index by the current poistion as we copy it accross
// Vulkan probalby supports a way to do this
uint32_t offset = 0;
for (uint32_t i = 0; i < 1; i++) {
copy_indexes(dest, indexes[i].indexes, indexes[i].nindexes);
dest += indexes[i].nindexes;
offset += indexes[i].indexrange;
}
vkUnmapMemory(turtle->device, stagingBufferMemory);
VkBuffer index_buffer;
create_buffer(turtle, buffer_size,
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &index_buffer, &memory);
copyBuffer(stagingBuffer, index_buffer, buffer_size);
vkDestroyBuffer(turtle->device, stagingBuffer, NULL);
vkFreeMemory(turtle->device, stagingBufferMemory, NULL);
return index_buffer;
}