summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkartofen <mladenovnasko0@gmail.com>2023-10-29 13:06:40 +0200
committerkartofen <mladenovnasko0@gmail.com>2023-10-29 13:06:40 +0200
commit4512fafc57d2ad95b83c8476781ce105a2cdc4e5 (patch)
treea37817c9bfa2f183f02439a31dcb38f78a7a0ccc
parentff5bf11c5f319f9c90de7a59eb4f8f338a74a38f (diff)
index buffer and staging
-rw-r--r--src/graphics.c247
-rw-r--r--src/graphics.h9
-rw-r--r--src/main.c13
3 files changed, 181 insertions, 88 deletions
diff --git a/src/graphics.c b/src/graphics.c
index 0e77c3a..95f6630 100644
--- a/src/graphics.c
+++ b/src/graphics.c
@@ -6,15 +6,14 @@
#include "graphics.h"
#include "common.h"
-// TODO: finish buffer_copy
-
-// TODO: explicitly make a transfer queue for
-// the buffer staging/copying
-// TODO: vkAllocateMemory shouldn't be called for every buffer,
-// a memory allocator should be used (the offset parameter)
+// TODO: the amount of vertices is currently
+// hardcoded in command_buffer_record
+// thats bad
// TODO: add more error checking
// TODO: add log output
// TODO: check for memory leaks
+// TODO: vkAllocateMemory shouldn't be called for every buffer,
+// a memory allocator should be used (the offset parameter)
#define SWAP_CHAIN_IMAGES 3
@@ -47,6 +46,9 @@ struct queue_family_idx {
u32 present_family;
bool has_present_family;
+
+ u32 transfer_family;
+ bool has_transfer_family;
};
struct swap_chain_support_details {
@@ -78,8 +80,13 @@ static void destroy_swap_chain(graphics_t graphics);
// static void destroy_command_pool(graphics_t graphics);
static void destroy_sync_objects(graphics_t graphics);
+static int buffer_create(graphics_t graphics, size_t size, VkBufferUsageFlags usageflg,
+ VkMemoryPropertyFlags propflg, buffer_t *buffer);
+static int buffer_copy(graphics_t graphics, buffer_t dest, buffer_t src, size_t size);
+static void buffer_destroy(graphics_t graphics, buffer_t buffer);
+
// --- Helper Functions ---
-static char *str_VkResult(VkResult result);
+static int buffer_find_memory_type(VkPhysicalDevice device, u32 type_filter, VkMemoryPropertyFlags flags, u32 *memory_type_idx);
static bool device_is_suitable(VkPhysicalDevice phy_device, VkSurfaceKHR surface);
static bool device_has_extension_support(VkPhysicalDevice phy_device);
@@ -95,21 +102,18 @@ static int swap_chain_choose_format(VkSurfaceFormatKHR* formats, u32 nformats, V
static int swap_chain_choose_present_mode(VkPresentModeKHR *modes, u32 nmodes, VkPresentModeKHR *mode);
static int swap_chain_get_extent(VkSurfaceCapabilitiesKHR capabilities, VkExtent2D *extent);
-#define CMND graphics->command
+#define CMND graphics->command_graphics
+#define CMND_TRNS graphics->command_transfer
static int command_buffer_record(graphics_t graphics, u32 image_index);
#define SYNC graphics->sync
#define VBFF graphics->vertex_buffer
+#define IBFF graphics->index_buffer
+static int graphics_buffer_create(graphics_t graphics, VkBufferUsageFlags flags, void *data, size_t size, buffer_t *buffer);
static int vertex_populate_descriptions(VkVertexInputBindingDescription *binding_desc, VkVertexInputAttributeDescription *attribute_desc);
-static int buffer_create(VkDevice device, VkPhysicalDevice physical_device,
- VkDeviceSize size, VkBufferUsageFlags usageflg,
- VkMemoryPropertyFlags propflg, buffer_t *buffer);
-static void buffer_destroy(VkDevice device, buffer_t buffer);
-static int buffer_copy(VkBuffer dest, VkBuffer, VkBuffer src, VkDeviceSize size, VkDevice devie, VkCommandPool pool, u32 queue_idx);
-static int buffer_find_memory_type(VkPhysicalDevice device, u32 type_filter, VkMemoryPropertyFlags flags, u32 *memory_type_idx);
-
+static char *str_VkResult(VkResult result);
F_LOAD_FILE_ALIGNED(u32) // from config.h
// --- Debug Functions ---
@@ -170,8 +174,8 @@ graphics_t graphics_create(struct graphics_info *info)
CCHECK(create_logical_device);
CCHECK(create_pipeline);
CCHECK(create_swap_chain);
- CCHECK(create_vertex_buffer);
CCHECK(create_command_pool);
+ CCHECK(create_vertex_buffer);
CCHECK(create_sync_objects);
return graphics;
@@ -189,8 +193,10 @@ void graphics_destroy(graphics_t graphics)
destroy_sync_objects(graphics);
vkDestroyCommandPool(graphics->logical_device, CMND.pool, NULL);
+ vkDestroyCommandPool(graphics->logical_device, CMND_TRNS.pool, NULL);
- buffer_destroy(graphics->logical_device, VBFF);
+ buffer_destroy(graphics, VBFF);
+ buffer_destroy(graphics, IBFF);
destroy_swap_chain(graphics);
destroy_pipeline(graphics);
@@ -397,7 +403,7 @@ static int create_logical_device(graphics_t graphics, struct graphics_info *info
// queue infos
u32 unique_queue_family_count = 0;
u32 queue_indices[] = {
- indices.graphics_family, indices.present_family,
+ indices.graphics_family, indices.present_family, indices.transfer_family
};
VkDeviceQueueCreateInfo queue_infos[ARR_SIZE(queue_indices)] = {0};
@@ -448,6 +454,7 @@ static int create_logical_device(graphics_t graphics, struct graphics_info *info
vkGetDeviceQueue(graphics->logical_device, indices.graphics_family, 0, &graphics->graphics_queue);
vkGetDeviceQueue(graphics->logical_device, indices.present_family, 0, &graphics->present_queue);
+ vkGetDeviceQueue(graphics->logical_device, indices.transfer_family, 0, &graphics->transfer_queue);
ret = 0;
exit:
@@ -791,22 +798,40 @@ static int create_command_pool(graphics_t graphics, struct graphics_info *info)
struct queue_family_idx indices;
device_queue_families(graphics->physical_device, graphics->surface, &indices);
-
- VkCommandPoolCreateInfo pool_info = {0};
- pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
- pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
- pool_info.queueFamilyIndex = indices.graphics_family;
- VCHECK(vkCreateCommandPool, graphics->logical_device, &pool_info, NULL, &CMND.pool);
+ // graphics pool
+ VkCommandPoolCreateInfo graphics_pool_info = {0};
+ graphics_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+ graphics_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+ graphics_pool_info.queueFamilyIndex = indices.graphics_family;
+
+ VCHECK(vkCreateCommandPool, graphics->logical_device, &graphics_pool_info, NULL, &CMND.pool);
+
+ // graphics buffer
+ VkCommandBufferAllocateInfo graphics_allocate_info = {0};
+ graphics_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+ graphics_allocate_info.commandPool = CMND.pool;
+ graphics_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+ graphics_allocate_info.commandBufferCount = 1;
+
+ VCHECK(vkAllocateCommandBuffers, graphics->logical_device, &graphics_allocate_info, &CMND.buffer);
+
+ // transfer pool
+ VkCommandPoolCreateInfo transfer_pool_info = {0};
+ transfer_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+ transfer_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+ transfer_pool_info.queueFamilyIndex = indices.transfer_family;
- // allocate the command buffer(s)
- VkCommandBufferAllocateInfo allocate_info = {0};
- allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
- allocate_info.commandPool = CMND.pool;
- allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
- allocate_info.commandBufferCount = 1;
+ VCHECK(vkCreateCommandPool, graphics->logical_device, &transfer_pool_info, NULL, &CMND_TRNS.pool);
- VCHECK(vkAllocateCommandBuffers, graphics->logical_device, &allocate_info, &CMND.buffer);
+ // graphics buffer
+ VkCommandBufferAllocateInfo transfer_allocate_info = {0};
+ transfer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+ transfer_allocate_info.commandPool = CMND_TRNS.pool;
+ transfer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+ transfer_allocate_info.commandBufferCount = 1;
+
+ VCHECK(vkAllocateCommandBuffers, graphics->logical_device, &transfer_allocate_info, &CMND_TRNS.buffer);
ret = 0;
exit:
@@ -843,26 +868,94 @@ static void destroy_sync_objects(graphics_t graphics)
static int create_vertex_buffer(graphics_t graphics, struct graphics_info *info)
{
- (void)info;
+ graphics_buffer_create(graphics, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, info->vertices,
+ sizeof(*info->vertices) *info->nvertices, &VBFF);
+ graphics_buffer_create(graphics, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, info->indices,
+ sizeof(*info->indices) * info->nindices, &IBFF);
+ return 0;
+}
+
+static int buffer_create(graphics_t graphics, size_t size, VkBufferUsageFlags usageflg, VkMemoryPropertyFlags propflg, buffer_t *buffer)
+{
int ret = 1;
- size_t size = sizeof(*info->vertices) * info->nvertices;
+ VkBufferCreateInfo buffer_info = {0};
+ buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+ buffer_info.size = size;
+ buffer_info.usage = usageflg;
- buffer_create(graphics->logical_device, graphics->physical_device,
- size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
- (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
- VK_MEMORY_PROPERTY_HOST_COHERENT_BIT), &VBFF);
+ // share between the graphics nad transfer queue families
+ struct queue_family_idx indices;
+ device_queue_families(graphics->physical_device, graphics->surface, &indices);
+ u32 queue_family_indices[] = { indices.graphics_family, indices.transfer_family };
+
+ // buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ buffer_info.sharingMode = VK_SHARING_MODE_CONCURRENT;
+ buffer_info.pQueueFamilyIndices = queue_family_indices;
+ buffer_info.queueFamilyIndexCount = ARR_SIZE(queue_family_indices);
+
+ VCHECK(vkCreateBuffer, graphics->logical_device, &buffer_info, NULL, &buffer->buffer);
- void *data;
- vkMapMemory(graphics->logical_device, VBFF.memory, 0, size, 0, &data);
- memcpy(data, info->vertices, size);
- vkUnmapMemory(graphics->logical_device, VBFF.memory);
+ VkMemoryRequirements memory_requirements;
+ vkGetBufferMemoryRequirements(graphics->logical_device, buffer->buffer, &memory_requirements);
+ VkMemoryAllocateInfo allocate_info = {0};
+ allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+ allocate_info.allocationSize = memory_requirements.size;
+
+ u32 memory_type_idx;
+ buffer_find_memory_type(graphics->physical_device, memory_requirements.memoryTypeBits, propflg, &memory_type_idx);
+ allocate_info.memoryTypeIndex = memory_type_idx;
+
+ VCHECK(vkAllocateMemory, graphics->logical_device, &allocate_info, NULL, &buffer->memory);
+ VCHECK(vkBindBufferMemory, graphics->logical_device, buffer->buffer, buffer->memory, 0);
+
ret = 0;
exit:
return ret;
}
+static int buffer_copy(graphics_t graphics, buffer_t dest, buffer_t src, size_t size)
+{
+ // TODO: add error checking
+ int ret = 1;
+
+ vkResetCommandBuffer(CMND_TRNS.buffer, 0);
+
+ VkCommandBufferBeginInfo begin_info = {0};
+ begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+
+ vkBeginCommandBuffer(CMND_TRNS.buffer, &begin_info);
+
+ VkBufferCopy copy_region = {0};
+ copy_region.srcOffset = 0; // Optional
+ copy_region.dstOffset = 0; // Optional
+ copy_region.size = size;
+
+ vkCmdCopyBuffer(CMND_TRNS.buffer, src.buffer, dest.buffer, 1, &copy_region);
+
+ vkEndCommandBuffer(CMND_TRNS.buffer);
+
+ VkSubmitInfo submit_info = {0};
+ submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submit_info.commandBufferCount = 1;
+ submit_info.pCommandBuffers = &CMND_TRNS.buffer;
+
+ vkQueueSubmit(graphics->transfer_queue, 1, &submit_info, VK_NULL_HANDLE);
+ vkQueueWaitIdle(graphics->transfer_queue);
+
+ ret = 0;
+exit:
+ return ret;
+}
+
+static void buffer_destroy(graphics_t graphics, buffer_t buffer)
+{
+ vkDestroyBuffer(graphics->logical_device, buffer.buffer, NULL);
+ vkFreeMemory(graphics->logical_device, buffer.memory, NULL);
+}
+
static int device_queue_families(VkPhysicalDevice phy_device, VkSurfaceKHR surface, struct queue_family_idx *queue_family)
{
u32 count = 0;
@@ -877,6 +970,11 @@ static int device_queue_families(VkPhysicalDevice phy_device, VkSurfaceKHR surfa
queue_family->has_graphics_family = true;
}
+ if(properties[i].queueFlags & VK_QUEUE_TRANSFER_BIT) {
+ queue_family->transfer_family = i;
+ queue_family->has_transfer_family = true;
+ }
+
VkBool32 present_support = false;
vkGetPhysicalDeviceSurfaceSupportKHR(phy_device, i, surface, &present_support);
@@ -897,7 +995,9 @@ static bool device_is_suitable(VkPhysicalDevice phy_device, VkSurfaceKHR surface
return
(device_queue_families(phy_device, surface, &indices),
- indices.has_graphics_family && indices.has_present_family)
+ indices.has_graphics_family &&
+ indices.has_present_family &&
+ indices.has_transfer_family)
&&
(device_has_extension_support(phy_device))
&&
@@ -1056,6 +1156,8 @@ static int command_buffer_record(graphics_t graphics, u32 image_index)
VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(CMND.buffer, 0, 1, vertex_buffers, offsets);
+ vkCmdBindIndexBuffer(CMND.buffer, IBFF.buffer, 0, VK_INDEX_TYPE_UINT32);
+
VkViewport viewport = {0};
viewport.x = 0.0f;
viewport.y = 0.0f;
@@ -1073,7 +1175,7 @@ static int command_buffer_record(graphics_t graphics, u32 image_index)
// 3 is the number of vertices
// TODO: fix this
- vkCmdDraw(CMND.buffer, 3, 1, 0, 0);
+ vkCmdDrawIndexed(CMND.buffer, 6, 1, 0, 0, 0);
// Cleaning up
vkCmdEndRenderPass(CMND.buffer);
@@ -1085,6 +1187,26 @@ exit:
return ret;
}
+static int graphics_buffer_create(graphics_t graphics, VkBufferUsageFlags flags, void *data, size_t size, buffer_t *buffer)
+{
+ buffer_t staging;
+ buffer_create(graphics, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
+ (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
+ VK_MEMORY_PROPERTY_HOST_COHERENT_BIT), &staging);
+
+ void *dest_data;
+ vkMapMemory(graphics->logical_device, staging.memory, 0, size, 0, &dest_data);
+ memcpy(dest_data, data, size);
+ vkUnmapMemory(graphics->logical_device, staging.memory);
+
+ buffer_create(graphics, size, (flags | VK_BUFFER_USAGE_TRANSFER_DST_BIT),
+ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, buffer);
+
+ buffer_copy(graphics, *buffer, staging, size);
+ buffer_destroy(graphics, staging);
+ return 0;
+}
+
static int vertex_populate_descriptions(VkVertexInputBindingDescription *binding_desc, VkVertexInputAttributeDescription *attribute_desc)
{
binding_desc->binding = 0;
@@ -1104,45 +1226,6 @@ static int vertex_populate_descriptions(VkVertexInputBindingDescription *binding
return 0;
}
-static int buffer_create(VkDevice device, VkPhysicalDevice physical_device,
- VkDeviceSize size, VkBufferUsageFlags usageflg,
- VkMemoryPropertyFlags propflg, buffer_t *buffer)
-{
- int ret = 1;
-
- VkBufferCreateInfo buffer_info = {0};
- buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
- buffer_info.size = size;
- buffer_info.usage = usageflg;
- buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
-
- VCHECK(vkCreateBuffer, device, &buffer_info, NULL, &buffer->buffer);
-
- VkMemoryRequirements memory_requirements;
- vkGetBufferMemoryRequirements(device, buffer->buffer, &memory_requirements);
-
- VkMemoryAllocateInfo allocate_info = {0};
- allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
- allocate_info.allocationSize = memory_requirements.size;
-
- u32 memory_type_idx;
- buffer_find_memory_type(physical_device, memory_requirements.memoryTypeBits, propflg, &memory_type_idx);
- allocate_info.memoryTypeIndex = memory_type_idx;
-
- VCHECK(vkAllocateMemory, device, &allocate_info, NULL, &buffer->memory);
- VCHECK(vkBindBufferMemory, device, buffer->buffer, buffer->memory, 0);
-
- ret = 0;
-exit:
- return ret;
-}
-
-static void buffer_destroy(VkDevice device, buffer_t buffer)
-{
- vkDestroyBuffer(device, buffer.buffer, NULL);
- vkFreeMemory(device, buffer.memory, NULL);
-}
-
static int buffer_find_memory_type(VkPhysicalDevice device, u32 type_filter, VkMemoryPropertyFlags flags, u32 *memory_type_idx)
{
VkPhysicalDeviceMemoryProperties properties;
diff --git a/src/graphics.h b/src/graphics.h
index 470ea9b..71a8889 100644
--- a/src/graphics.h
+++ b/src/graphics.h
@@ -33,6 +33,7 @@ typedef struct graphics {
VkQueue graphics_queue;
VkQueue present_queue;
+ VkQueue transfer_queue;
VkSurfaceKHR surface;
@@ -57,16 +58,16 @@ typedef struct graphics {
struct command {
VkCommandPool pool;
VkCommandBuffer buffer;
- } command;
+ } command_graphics, command_transfer;
struct sync {
VkSemaphore semph_image_available;
VkSemaphore semph_render_finished;
VkFence fence_inflight;
} sync;
-
+
buffer_t vertex_buffer;
- buffer_t staging_buffer;
+ buffer_t index_buffer;
} * graphics_t;
@@ -79,6 +80,8 @@ struct graphics_info {
vertex_t *vertices;
size_t nvertices;
+ u32 *indices;
+ size_t nindices;
int (*surface_func)(VkInstance instance, VkSurfaceKHR *surface);
};
diff --git a/src/main.c b/src/main.c
index cc6c3d5..4b5685d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -11,9 +11,14 @@ graphics_t graphics;
int _create_surface(VkInstance instance, VkSurfaceKHR *surface);
vertex_t vertices[] = {
- {{0.0f, -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, 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}}
+};
+
+u32 indices[] = {
+ 0, 1, 2, 2, 3, 0
};
int main(void)
@@ -56,6 +61,8 @@ int main(void)
grph_info.vertices = vertices;
grph_info.nvertices = ARR_SIZE(vertices);
+ grph_info.indices = indices;
+ grph_info.nindices = ARR_SIZE(indices);
grph_info.surface_func = _create_surface;