diff options
author | kartofen <mladenovnasko0@gmail.com> | 2023-10-28 00:16:54 +0300 |
---|---|---|
committer | kartofen <mladenovnasko0@gmail.com> | 2023-10-28 00:16:54 +0300 |
commit | ff5bf11c5f319f9c90de7a59eb4f8f338a74a38f (patch) | |
tree | e58ef28897986cb32f85d741ab4cc2efdf9622e4 | |
parent | e9bd321c8bd6bdb6aa7305c6da8b33e8cac462f7 (diff) |
added vertex buffers
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | files/shaders/shader1.frag | 1 | ||||
-rw-r--r-- | files/shaders/shader1.vert | 19 | ||||
-rw-r--r-- | src/graphics.c | 145 | ||||
-rw-r--r-- | src/graphics.h | 17 | ||||
-rw-r--r-- | src/main.c | 11 |
6 files changed, 170 insertions, 29 deletions
@@ -4,10 +4,10 @@ GLSLC := glslc ifeq ($(PROD),1) CFLAGS := -O2 # production flags else -CFLAGS := -Wall -Wextra -Wpedantic -g -DDEBUG # debug flags +CFLAGS := -Wall -Wextra -Wpedantic -lprofiler -g -DDEBUG # debug flags endif -CFLAGS += -std=c99 -lm -lvulkan `sdl2-config --cflags --libs` +CFLAGS += -std=c99 -lm -lvulkan `sdl2-config --cflags --libs` /usr/local/lib/libcglm.a SRCD := src OBJD := obj @@ -79,5 +79,3 @@ run: $(NAME) valgrind: all valgrind -s --leak-check=full --show-leak-kinds=all $(RUN_CMD) - - diff --git a/files/shaders/shader1.frag b/files/shaders/shader1.frag index 7c5b0e7..7122ce8 100644 --- a/files/shaders/shader1.frag +++ b/files/shaders/shader1.frag @@ -1,7 +1,6 @@ #version 450 layout(location = 0) in vec3 fragColor; - layout(location = 0) out vec4 outColor; void main() { diff --git a/files/shaders/shader1.vert b/files/shaders/shader1.vert index f5b2f8d..9f27f54 100644 --- a/files/shaders/shader1.vert +++ b/files/shaders/shader1.vert @@ -1,20 +1,11 @@ #version 450 -layout(location = 0) out vec3 fragColor; - -vec2 positions[3] = vec2[]( - vec2(0.0, -0.5), - vec2(0.5, 0.5), - vec2(-0.5, 0.5) -); +layout(location = 0) in vec2 inPosition; +layout(location = 1) in vec3 inColor; -vec3 colors[3] = vec3[]( - vec3(1.0, 0.0, 0.0), - vec3(0.0, 1.0, 0.0), - vec3(0.0, 0.0, 1.0) -); +layout(location = 0) out vec3 fragColor; void main() { - gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); - fragColor = colors[gl_VertexIndex]; + gl_Position = vec4(inPosition, 0.0, 1.0); + fragColor = inColor; } diff --git a/src/graphics.c b/src/graphics.c index 8da9c43..0e77c3a 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -1,10 +1,17 @@ #include <string.h> #include <errno.h> +#include <cglm/cglm.h> #include <vulkan/vulkan.h> #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: add more error checking // TODO: add log output // TODO: check for memory leaks @@ -62,11 +69,12 @@ static int create_physical_device(graphics_t graphics, struct graphics_info *inf static int create_logical_device(graphics_t graphics, struct graphics_info *info); static int create_pipeline(graphics_t graphics, struct graphics_info *info); static int create_swap_chain(graphics_t graphics, struct graphics_info *info); +static int create_vertex_buffer(graphics_t graphics, struct graphics_info *info); static int create_command_pool(graphics_t graphics, struct graphics_info *info); static int create_sync_objects(graphics_t graphics, struct graphics_info *info); -static void destroy_swap_chain(graphics_t graphics); static void destroy_pipeline(graphics_t graphics); +static void destroy_swap_chain(graphics_t graphics); // static void destroy_command_pool(graphics_t graphics); static void destroy_sync_objects(graphics_t graphics); @@ -92,6 +100,16 @@ static int command_buffer_record(graphics_t graphics, u32 image_index); #define SYNC graphics->sync +#define VBFF graphics->vertex_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); + F_LOAD_FILE_ALIGNED(u32) // from config.h // --- Debug Functions --- @@ -127,7 +145,6 @@ graphics_t graphics_create(struct graphics_info *info) graphics->instance = VK_NULL_HANDLE; graphics->logical_device = VK_NULL_HANDLE; - PPLN.pipeline = VK_NULL_HANDLE; PPLN.layout = VK_NULL_HANDLE; PPLN.render_pass = VK_NULL_HANDLE; @@ -140,6 +157,9 @@ graphics_t graphics_create(struct graphics_info *info) SYNC.semph_image_available = VK_NULL_HANDLE; SYNC.semph_render_finished = VK_NULL_HANDLE; SYNC.fence_inflight = VK_NULL_HANDLE; + + VBFF.buffer = VK_NULL_HANDLE; + VBFF.memory = VK_NULL_HANDLE; CCHECK(create_instance); CCHECK(create_surface); @@ -150,6 +170,7 @@ 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_sync_objects); @@ -168,6 +189,8 @@ void graphics_destroy(graphics_t graphics) destroy_sync_objects(graphics); vkDestroyCommandPool(graphics->logical_device, CMND.pool, NULL); + + buffer_destroy(graphics->logical_device, VBFF); destroy_swap_chain(graphics); destroy_pipeline(graphics); @@ -599,13 +622,17 @@ static int create_pipeline(graphics_t graphics, struct graphics_info *info) dynamic_state.dynamicStateCount = ARR_SIZE(dynamic_states); dynamic_state.pDynamicStates = dynamic_states; - // vertex things - hard coded (for now) + // vertex things + VkVertexInputBindingDescription binding_description = {0}; + VkVertexInputAttributeDescription attribute_description[2] = {0}; + vertex_populate_descriptions(&binding_description, attribute_description); + VkPipelineVertexInputStateCreateInfo vertex_input = {0}; vertex_input.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vertex_input.vertexBindingDescriptionCount = 0; - vertex_input.pVertexBindingDescriptions = NULL; - vertex_input.vertexAttributeDescriptionCount = 0; - vertex_input.pVertexAttributeDescriptions = NULL; + vertex_input.vertexBindingDescriptionCount = 1; + vertex_input.pVertexBindingDescriptions = &binding_description; + vertex_input.vertexAttributeDescriptionCount = ARR_SIZE(attribute_description); + vertex_input.pVertexAttributeDescriptions = attribute_description; VkPipelineInputAssemblyStateCreateInfo input_assembly = {0}; input_assembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; @@ -814,6 +841,28 @@ static void destroy_sync_objects(graphics_t graphics) vkDestroyFence(graphics->logical_device, SYNC.fence_inflight, NULL); } +static int create_vertex_buffer(graphics_t graphics, struct graphics_info *info) +{ + (void)info; + int ret = 1; + + size_t size = sizeof(*info->vertices) * info->nvertices; + + 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); + + void *data; + vkMapMemory(graphics->logical_device, VBFF.memory, 0, size, 0, &data); + memcpy(data, info->vertices, size); + vkUnmapMemory(graphics->logical_device, VBFF.memory); + + ret = 0; +exit: + return ret; +} + static int device_queue_families(VkPhysicalDevice phy_device, VkSurfaceKHR surface, struct queue_family_idx *queue_family) { u32 count = 0; @@ -1003,6 +1052,10 @@ static int command_buffer_record(graphics_t graphics, u32 image_index) // Begin the drawing commands vkCmdBindPipeline(CMND.buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, PPLN.pipeline); + VkBuffer vertex_buffers[] = { VBFF.buffer }; + VkDeviceSize offsets[] = {0}; + vkCmdBindVertexBuffers(CMND.buffer, 0, 1, vertex_buffers, offsets); + VkViewport viewport = {0}; viewport.x = 0.0f; viewport.y = 0.0f; @@ -1018,8 +1071,8 @@ static int command_buffer_record(graphics_t graphics, u32 image_index) scissor.extent = SWCH.extent; vkCmdSetScissor(CMND.buffer, 0, 1, &scissor); - // 3 vertices, 1 instance (for instanced rendering) - // 0 is the first vertex, 0 is the fist instance + // 3 is the number of vertices + // TODO: fix this vkCmdDraw(CMND.buffer, 3, 1, 0, 0); // Cleaning up @@ -1032,6 +1085,80 @@ exit: return ret; } +static int vertex_populate_descriptions(VkVertexInputBindingDescription *binding_desc, VkVertexInputAttributeDescription *attribute_desc) +{ + binding_desc->binding = 0; + binding_desc->stride = sizeof(struct vertex); + binding_desc->inputRate = VK_VERTEX_INPUT_RATE_VERTEX; + + attribute_desc[0].binding = 0; + attribute_desc[0].location = 0; + attribute_desc[0].format = VK_FORMAT_R32G32_SFLOAT; + attribute_desc[0].offset = offsetof(struct vertex, pos); + + attribute_desc[1].binding = 0; + attribute_desc[1].location = 1; + attribute_desc[1].format = VK_FORMAT_R32G32B32_SFLOAT; + attribute_desc[1].offset = offsetof(struct vertex, color); + + 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; + vkGetPhysicalDeviceMemoryProperties(device, &properties); + + for(u32 i = 0; i < properties.memoryTypeCount; i++) { + if((type_filter & (i << i)) && ((properties.memoryTypes[i].propertyFlags & flags) == flags)) { + *memory_type_idx = i; + return 0; + } + } + + err("No suitable memory type was found"); + return 1; +} + #define X_VK_RESULT_TABLE(X) \ X(VK_SUCCESS) \ X(VK_NOT_READY) \ diff --git a/src/graphics.h b/src/graphics.h index 52e511e..470ea9b 100644 --- a/src/graphics.h +++ b/src/graphics.h @@ -3,6 +3,7 @@ #include <stdint.h> #include <stdbool.h> +#include <cglm/cglm.h> #include <vulkan/vulkan.h> #include "common.h" @@ -13,6 +14,16 @@ typedef uint32_t u32; +typedef struct vertex { + vec2 pos; + vec3 color; +} vertex_t; + +typedef struct buffer { + VkBuffer buffer; + VkDeviceMemory memory; +} buffer_t; + typedef struct graphics { VkInstance instance; VkDebugUtilsMessengerEXT debug_messenger; @@ -54,6 +65,9 @@ typedef struct graphics { VkFence fence_inflight; } sync; + buffer_t vertex_buffer; + buffer_t staging_buffer; + } * graphics_t; struct graphics_info { @@ -63,6 +77,9 @@ struct graphics_info { const char* const* extensions; u32 ext_count; + vertex_t *vertices; + size_t nvertices; + int (*surface_func)(VkInstance instance, VkSurfaceKHR *surface); }; @@ -10,6 +10,12 @@ 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}} +}; + int main(void) { int ret = 1; @@ -47,9 +53,12 @@ int main(void) grph_info.ext_count = ext_count; grph_info.extensions = (const char * const *)extensions; + + grph_info.vertices = vertices; + grph_info.nvertices = ARR_SIZE(vertices); grph_info.surface_func = _create_surface; - + // create the device graphics = graphics_create(&grph_info); if(!graphics) { |