summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkartofen <mladenovnasko0@gmail.com>2023-10-28 00:16:54 +0300
committerkartofen <mladenovnasko0@gmail.com>2023-10-28 00:16:54 +0300
commitff5bf11c5f319f9c90de7a59eb4f8f338a74a38f (patch)
treee58ef28897986cb32f85d741ab4cc2efdf9622e4
parente9bd321c8bd6bdb6aa7305c6da8b33e8cac462f7 (diff)
added vertex buffers
-rw-r--r--Makefile6
-rw-r--r--files/shaders/shader1.frag1
-rw-r--r--files/shaders/shader1.vert19
-rw-r--r--src/graphics.c145
-rw-r--r--src/graphics.h17
-rw-r--r--src/main.c11
6 files changed, 170 insertions, 29 deletions
diff --git a/Makefile b/Makefile
index f4d58ba..939fb4c 100644
--- a/Makefile
+++ b/Makefile
@@ -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);
};
diff --git a/src/main.c b/src/main.c
index 0f35679..cc6c3d5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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) {