From 960f0b94eaab70e168846472b04c6998f83b4012 Mon Sep 17 00:00:00 2001 From: Noah Metz Date: Mon, 8 Jan 2024 11:59:58 -0700 Subject: [PATCH] Added staged buffers and indexed triangle drawing --- src/main.c | 329 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 245 insertions(+), 84 deletions(-) diff --git a/src/main.c b/src/main.c index 75588bb..502ce16 100644 --- a/src/main.c +++ b/src/main.c @@ -18,11 +18,15 @@ typedef struct QueueIndicesStruct { uint32_t present_family; uint32_t present_index; + + uint32_t transfer_family; + uint32_t transfer_index; } QueueIndices; typedef struct QueuesStruct { VkQueue graphics; VkQueue present; + VkQueue transfer; } Queues; typedef struct SwapchainDetailsStruct { @@ -79,10 +83,12 @@ typedef struct VulkanContextStruct { VkRenderPass render_pass; VkCommandPool graphics_command_pool; + VkCommandPool transfer_command_pool; VkPipelineLayout triangle_pipeline_layout; VkPipeline triangle_pipeline; - AllocatedBuffer triangle_buffer; + AllocatedBuffer triangle_vertex_buffer; + AllocatedBuffer triangle_index_buffer; uint32_t current_frame; } VulkanContext; @@ -93,13 +99,22 @@ struct Vertex{ }; const struct Vertex vertices[] = { - {.pos = { 0.0f, -0.5f}, .color = {1.0f, 0.0f, 0.0f}}, - {.pos = { 0.5f, 0.5f}, .color = {0.0f, 1.0f, 0.0f}}, - {.pos = {-0.5f, 0.5f}, .color = {0.0f, 0.0f, 1.0f}}, + {.pos = {-0.5f, -0.5f}, .color = {1.0f, 0.0f, 0.0f}}, + {.pos = { 0.5f, -0.5f}, .color = {0.0f, 1.0f, 0.0f}}, + {.pos = { 0.5f, 0.5f}, .color = {0.0f, 0.0f, 1.0f}}, + {.pos = {-0.5f, 0.5f}, .color = {1.0f, 1.0f, 1.0f}}, +}; + +const uint16_t indices[] = { + 0, 1, 2, 2, 3, 0, }; const char * validation_layers[] = { "VK_LAYER_KHRONOS_validation", + //"VK_LAYER_LUNARG_api_dump", + //"VK_LAYER_KHRONOS_profiles", + //"VK_LAYER_KHRONOS_synchronization2", + "VK_LAYER_KHRONOS_shader_object", }; uint32_t validation_layer_count = sizeof(validation_layers) / sizeof(const char *); @@ -266,17 +281,20 @@ VkPhysicalDevice get_best_physical_device(VkInstance instance) { return device; } -struct MaybeQueueIndices { - bool valid; - QueueIndices indices; -}; +bool check_queue_indices(QueueIndices indices) { + return ((indices.graphics_family != 0xFFFFFFFF) + && (indices.present_family != 0xFFFFFFFF) + && (indices.transfer_family != 0xFFFFFFFF)); +} -struct MaybeQueueIndices get_queue_indices(VkPhysicalDevice physical_device, VkSurfaceKHR surface) { - struct MaybeQueueIndices ret = {}; - ret.indices.graphics_family = 0xFFFFFFFF; - ret.indices.graphics_index = 0xFFFFFFFF; - ret.indices.present_family = 0xFFFFFFFF; - ret.indices.present_index = 0xFFFFFFFF; +QueueIndices get_queue_indices(VkPhysicalDevice physical_device, VkSurfaceKHR surface) { + QueueIndices indices = {}; + indices.graphics_family = 0xFFFFFFFF; + indices.graphics_index = 0xFFFFFFFF; + indices.present_family = 0xFFFFFFFF; + indices.present_index = 0xFFFFFFFF; + indices.transfer_family = 0xFFFFFFFF; + indices.transfer_index = 0xFFFFFFFF; uint32_t queue_family_count; vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, 0); @@ -285,31 +303,43 @@ struct MaybeQueueIndices get_queue_indices(VkPhysicalDevice physical_device, VkS vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, queue_families); - for(uint32_t i = 0; - (i < queue_family_count) - && ((ret.indices.graphics_family == 0xFFFFFFFF) || (ret.indices.present_family == 0xFFFFFFFF)); - i++) { - if(queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { - ret.indices.graphics_family = i; - ret.indices.graphics_index = 0; - } - - VkBool32 present_support = false; - vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, i, surface, &present_support); - - if(present_support == VK_TRUE) { - ret.indices.present_family = i; - ret.indices.present_index = 0; + for(uint32_t family_idx = 0; family_idx < queue_family_count; family_idx++) { + VkBool32 present_support; + vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, family_idx, surface, &present_support); + for(uint32_t queue_idx = 0; queue_idx < queue_families[family_idx].queueCount; queue_idx++) { + if(((indices.graphics_family == 0xFFFFFFFF) + || (indices.present_family == 0xFFFFFFFF) + || (indices.present_family != indices.graphics_family)) + && (queue_families[family_idx].queueFlags & VK_QUEUE_GRAPHICS_BIT) + && (present_support == VK_TRUE)) { + fprintf(stderr, "Selected %d:%d for graphics and present queues\n", family_idx, queue_idx); + indices.graphics_family = family_idx; + indices.graphics_index = queue_idx; + + indices.present_family = family_idx; + indices.present_index = queue_idx; + } else if((indices.graphics_family == 0xFFFFFFFF) + && (queue_families[family_idx].queueFlags & VK_QUEUE_GRAPHICS_BIT)) { + fprintf(stderr, "Selected %d:%d for graphics queue\n", family_idx, queue_idx); + indices.graphics_family = family_idx; + indices.graphics_index = queue_idx; + } else if((indices.present_family == 0xFFFFFFFF) + && (present_support == VK_TRUE)) { + fprintf(stderr, "Selected %d:%d for present queue\n", family_idx, queue_idx); + indices.present_family = family_idx; + indices.present_index = queue_idx; + } else if((indices.transfer_family == 0xFFFFFFFF) + && (queue_families[family_idx].queueFlags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT))) { + fprintf(stderr, "Selected %d:%d for transfer queue\n", family_idx, queue_idx); + indices.transfer_family = family_idx; + indices.transfer_index = queue_idx; + } } } - if((ret.indices.graphics_family != 0xFFFFFFFF) && (ret.indices.present_family != 0xFFFFFFFF)) { - ret.valid = true; - } - free(queue_families); - return ret; + return indices; } VkDebugUtilsMessengerEXT create_debug_messenger(VkInstance instance) { @@ -318,7 +348,7 @@ VkDebugUtilsMessengerEXT create_debug_messenger(VkInstance instance) { VkDebugUtilsMessengerCreateInfoEXT messenger_info = {}; messenger_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; messenger_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT; - messenger_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; + messenger_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_DEVICE_ADDRESS_BINDING_BIT_EXT; messenger_info.pfnUserCallback = debug_callback; messenger_info.pUserData = 0; @@ -390,35 +420,50 @@ VkInstance create_instance() { VkDevice create_logical_device(VkPhysicalDevice physical_device, QueueIndices queue_indices) { VkDevice device; - VkDeviceQueueCreateInfo queue_create_info[2] = {}; - uint32_t queue_create_count; - float default_queue_priority = 1.0f; - if(queue_indices.graphics_family == queue_indices.present_family) { - queue_create_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queue_create_info[0].queueFamilyIndex = queue_indices.graphics_family; - queue_create_info[0].queueCount = 1; - queue_create_info[0].pQueuePriorities = &default_queue_priority; - queue_create_count = 1; - } else { - queue_create_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queue_create_info[0].queueFamilyIndex = queue_indices.graphics_family; - queue_create_info[0].queueCount = 1; - queue_create_info[0].pQueuePriorities = &default_queue_priority; + uint32_t unique_families[3] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; + uint32_t unique_family_queues[3] = {0, 0, 0}; + uint32_t unique_family_count = 0; + + uint32_t queue_family[] = {queue_indices.transfer_family, queue_indices.graphics_family, queue_indices.present_family}; + uint32_t unique_queue_count = 3; + if((queue_indices.graphics_family == queue_indices.present_family) + && (queue_indices.graphics_index == queue_indices.present_index)) { + unique_queue_count = 2; + } + + for(uint32_t queue_idx = 0; queue_idx < unique_queue_count; queue_idx++) { + uint32_t idx = 0xFFFFFFFF; + for(uint32_t check_idx = 0; check_idx < unique_family_count; check_idx++) { + if(queue_family[queue_idx] == unique_families[check_idx]) { + idx = check_idx; + break; + } + } - queue_create_info[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queue_create_info[1].queueFamilyIndex = queue_indices.present_family; - queue_create_info[1].queueCount = 1; - queue_create_info[1].pQueuePriorities = &default_queue_priority; - queue_create_count = 2; + if(idx == 0xFFFFFFFF) { + unique_families[unique_family_count] = queue_family[queue_idx]; + unique_family_queues[unique_family_count] += 1; + unique_family_count += 1; + } else { + unique_family_queues[idx] += 1; + } } + VkDeviceQueueCreateInfo queue_create_info[3] = {}; + float default_queue_priority = 1.0f; + for(uint32_t i = 0; i < unique_family_count; i++) { + queue_create_info[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_create_info[i].queueFamilyIndex = unique_families[i]; + queue_create_info[i].queueCount = unique_family_queues[i]; + queue_create_info[i].pQueuePriorities = &default_queue_priority; + } VkPhysicalDeviceFeatures device_features = {}; VkDeviceCreateInfo device_create_info = {}; device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; device_create_info.pQueueCreateInfos = queue_create_info; - device_create_info.queueCreateInfoCount = queue_create_count; + device_create_info.queueCreateInfoCount = unique_family_count; device_create_info.pEnabledFeatures = &device_features; device_create_info.enabledExtensionCount = device_extension_count; @@ -753,51 +798,150 @@ uint32_t find_memory_type(VkPhysicalDevice physical_device, uint32_t type_filter return 0xFFFFFFFF; } -AllocatedBuffer create_vertex_buffer(VkPhysicalDevice physical_device, VkDevice device, void* data, uint32_t size) { - AllocatedBuffer allocated_buffer = {}; - allocated_buffer.buffer = VK_NULL_HANDLE; - allocated_buffer.memory = VK_NULL_HANDLE; +AllocatedBuffer allocate_buffer(VkPhysicalDevice physical_device, VkDevice device, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties) { + AllocatedBuffer ret = {}; + ret.memory = VK_NULL_HANDLE; + ret.buffer = VK_NULL_HANDLE; + VkBufferCreateInfo buffer_info = {}; buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; buffer_info.size = size; - buffer_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + buffer_info.usage = usage; buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - VkResult result = vkCreateBuffer(device, &buffer_info, 0, &allocated_buffer.buffer); + VkResult result = vkCreateBuffer(device, &buffer_info, 0, &ret.buffer); if(result != VK_SUCCESS) { - return allocated_buffer; + ret.buffer = VK_NULL_HANDLE; + ret.memory = VK_NULL_HANDLE; + return ret; } VkMemoryRequirements memory_requirements; - vkGetBufferMemoryRequirements(device, allocated_buffer.buffer, &memory_requirements); + vkGetBufferMemoryRequirements(device, ret.buffer, &memory_requirements); VkMemoryAllocateInfo alloc_info = {}; alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; alloc_info.allocationSize = memory_requirements.size; - alloc_info.memoryTypeIndex = find_memory_type(physical_device, memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + alloc_info.memoryTypeIndex = find_memory_type(physical_device, memory_requirements.memoryTypeBits, properties); + + result = vkAllocateMemory(device, &alloc_info, 0, &ret.memory); + if(result != VK_SUCCESS) { + vkDestroyBuffer(device, ret.buffer, 0); + ret.buffer = VK_NULL_HANDLE; + ret.memory = VK_NULL_HANDLE; + return ret; + } + + result = vkBindBufferMemory(device, ret.buffer, ret.memory, 0); + if(result != VK_SUCCESS) { + vkDestroyBuffer(device, ret.buffer, 0); + ret.buffer = VK_NULL_HANDLE; + ret.memory = VK_NULL_HANDLE; + return ret; + } + + return ret; +} + +void deallocate_buffer(VkDevice device, AllocatedBuffer buffer) { + vkDestroyBuffer(device, buffer.buffer, 0); + vkFreeMemory(device, buffer.memory, 0); +}; + +VkResult command_copy_buffers(VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, VkBuffer source, VkBuffer dest, VkDeviceSize size) { + VkCommandBufferAllocateInfo command_info = {}; + command_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + command_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + command_info.commandPool = transfer_pool; + command_info.commandBufferCount = 1; + + VkCommandBuffer command_buffer; + VkResult result = vkAllocateCommandBuffers(device, &command_info, &command_buffer); + if(result != VK_SUCCESS) { + return result; + } + + VkCommandBufferBeginInfo begin_info = {}; + begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + + result = vkBeginCommandBuffer(command_buffer, &begin_info); + if(result != VK_SUCCESS) { + vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); + return result; + } - result = vkAllocateMemory(device, &alloc_info, 0, &allocated_buffer.memory); + VkBufferCopy copy_region = {}; + copy_region.srcOffset = 0; + copy_region.dstOffset = 0; + copy_region.size = size; + + vkCmdCopyBuffer(command_buffer, source, dest, 1, ©_region); + result = vkEndCommandBuffer(command_buffer); + if(result != VK_SUCCESS) { + vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); + return result; + } + + VkSubmitInfo submit_info = {}; + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = &command_buffer; + + result = vkQueueSubmit(transfer_queue, 1, &submit_info, 0); if(result != VK_SUCCESS) { - return allocated_buffer; + vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); + return result; } - result = vkBindBufferMemory(device, allocated_buffer.buffer, allocated_buffer.memory, 0); + result = vkQueueWaitIdle(transfer_queue); if(result != VK_SUCCESS) { - return allocated_buffer; + vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); + return result; + } + + vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); + + return VK_SUCCESS; +} + +AllocatedBuffer create_populated_buffer(VkPhysicalDevice physical_device, VkDevice device, void* data, VkDeviceSize size, VkCommandPool transfer_pool, VkQueue transfer_queue, VkBufferUsageFlags usage) { + AllocatedBuffer staging_buffer = {}; + AllocatedBuffer vertex_buffer = {}; + staging_buffer = allocate_buffer(physical_device, device, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + if(staging_buffer.memory == VK_NULL_HANDLE) { + return vertex_buffer; } + void* buffer_data; - result = vkMapMemory(device, allocated_buffer.memory, 0, buffer_info.size, 0, &buffer_data); + VkResult result = vkMapMemory(device, staging_buffer.memory, 0, size, 0, &buffer_data); if(result != VK_SUCCESS) { - return allocated_buffer; + deallocate_buffer(device, staging_buffer); + return vertex_buffer; } memcpy(buffer_data, data, size); - vkUnmapMemory(device, allocated_buffer.memory); + vkUnmapMemory(device, staging_buffer.memory); + + vertex_buffer = allocate_buffer(physical_device, device, size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | usage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + if(vertex_buffer.memory == VK_NULL_HANDLE) { + deallocate_buffer(device, staging_buffer); + return vertex_buffer; + } + + result = command_copy_buffers(device, transfer_pool, transfer_queue, staging_buffer.buffer, vertex_buffer.buffer, size); + if(result != VK_SUCCESS) { + deallocate_buffer(device, staging_buffer); + deallocate_buffer(device, vertex_buffer); + vertex_buffer.buffer = VK_NULL_HANDLE; + vertex_buffer.memory = VK_NULL_HANDLE; + return vertex_buffer; + } - return allocated_buffer; + return vertex_buffer; } VkPipeline create_graphics_pipeline(VkDevice device, VkExtent2D extent, VkPipelineLayout layout, VkRenderPass render_pass) { @@ -943,7 +1087,7 @@ VkCommandPool create_command_pool(VkDevice device, uint32_t queue_family) { return command_pool; } -VkResult record_command_buffer_triangle(VkCommandBuffer command_buffer, uint32_t image_index, VkRenderPass render_pass, VkFramebuffer* framebuffers, VkExtent2D extent, VkPipeline graphics_pipeline, VkBuffer vertex_buffer, uint32_t num_vertices) { +VkResult record_command_buffer_triangle(VkCommandBuffer command_buffer, uint32_t image_index, VkRenderPass render_pass, VkFramebuffer* framebuffers, VkExtent2D extent, VkPipeline graphics_pipeline, VkBuffer vertex_buffer, VkBuffer index_buffer, uint32_t num_vertices) { VkCommandBufferBeginInfo begin_info = {}; begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; begin_info.flags = 0; @@ -971,6 +1115,7 @@ VkResult record_command_buffer_triangle(VkCommandBuffer command_buffer, uint32_t VkBuffer vertex_buffers[] = {vertex_buffer}; VkDeviceSize offsets[] = {0}; vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, offsets); + vkCmdBindIndexBuffer(command_buffer, index_buffer, 0, VK_INDEX_TYPE_UINT16); VkViewport viewport = {}; viewport.x = 0.0f; @@ -987,7 +1132,7 @@ VkResult record_command_buffer_triangle(VkCommandBuffer command_buffer, uint32_t scissor.extent = extent; vkCmdSetScissor(command_buffer, 0, 1, &scissor); - vkCmdDraw(command_buffer, num_vertices, 1, 0, 0); + vkCmdDrawIndexed(command_buffer, num_vertices, 1, 0, 0, 0); vkCmdEndRenderPass(command_buffer); return vkEndCommandBuffer(command_buffer); @@ -1088,12 +1233,12 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { context->surface = surface; } - struct MaybeQueueIndices maybe_indices = get_queue_indices(context->physical_device, context->surface); - if(maybe_indices.valid == false) { + QueueIndices queue_indices = get_queue_indices(context->physical_device, context->surface); + if(check_queue_indices(queue_indices) == false) { fprintf(stderr, "failed to get vulkan queue indices\n"); return 0; } else { - context->queue_indices = maybe_indices.indices; + context->queue_indices = queue_indices; } VkDevice device = create_logical_device(context->physical_device, context->queue_indices); @@ -1105,6 +1250,7 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { } vkGetDeviceQueue(device, context->queue_indices.graphics_family, context->queue_indices.graphics_index, &context->queues.graphics); vkGetDeviceQueue(device, context->queue_indices.present_family, context->queue_indices.present_index, &context->queues.present); + vkGetDeviceQueue(device, context->queue_indices.transfer_family, context->queue_indices.transfer_index, &context->queues.transfer); struct MaybeSwapchainDetails maybe_details = get_swapchain_details(context->physical_device, context->surface); if(maybe_details.valid == false) { @@ -1159,12 +1305,20 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { context->swapchain_framebuffers = framebuffers; } - VkCommandPool command_pool = create_command_pool(context->device, context->queue_indices.graphics_family); - if(command_pool == VK_NULL_HANDLE) { + VkCommandPool graphics_command_pool = create_command_pool(context->device, context->queue_indices.graphics_family); + if(graphics_command_pool == VK_NULL_HANDLE) { fprintf(stderr, "failed to create vulkan graphics command pool"); return 0; } else { - context->graphics_command_pool = command_pool; + context->graphics_command_pool = graphics_command_pool; + } + + VkCommandPool transfer_command_pool = create_command_pool(context->device, context->queue_indices.transfer_family); + if(transfer_command_pool == VK_NULL_HANDLE) { + fprintf(stderr, "failed to create vulkan transfer command pool"); + return 0; + } else { + context->transfer_command_pool = transfer_command_pool; } context->max_frames_in_flight = max_frames_in_flight; @@ -1217,11 +1371,18 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { context->triangle_pipeline = triangle_pipeline; } - AllocatedBuffer triangle_buffer = create_vertex_buffer(context->physical_device, context->device, (void*)vertices, sizeof(vertices)); - if(triangle_buffer.memory == VK_NULL_HANDLE) { + AllocatedBuffer triangle_vertex_buffer = create_populated_buffer(context->physical_device, context->device, (void*)vertices, sizeof(vertices), context->transfer_command_pool, context->queues.transfer, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); + if(triangle_vertex_buffer.memory == VK_NULL_HANDLE) { + fprintf(stderr, "failed to allocate vulkan buffer for triangle buffer\n"); + } else { + context->triangle_vertex_buffer = triangle_vertex_buffer; + } + + AllocatedBuffer triangle_index_buffer = create_populated_buffer(context->physical_device, context->device, (void*)indices, sizeof(indices), context->transfer_command_pool, context->queues.transfer, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); + if(triangle_index_buffer.memory == VK_NULL_HANDLE) { fprintf(stderr, "failed to allocate vulkan buffer for triangle buffer\n"); } else { - context->triangle_buffer = triangle_buffer; + context->triangle_index_buffer = triangle_index_buffer; } return context; @@ -1250,7 +1411,7 @@ VkResult draw_frame(VulkanContext* context) { return result; } - result = record_command_buffer_triangle(context->swapchain_command_buffers[context->current_frame], image_index, context->render_pass, context->swapchain_framebuffers, context->swapchain_extent, context->triangle_pipeline, context->triangle_buffer.buffer, 3); + result = record_command_buffer_triangle(context->swapchain_command_buffers[context->current_frame], image_index, context->render_pass, context->swapchain_framebuffers, context->swapchain_extent, context->triangle_pipeline, context->triangle_vertex_buffer.buffer, context->triangle_index_buffer.buffer, 6); if(result != VK_SUCCESS) { return result; }