From a94e7a95f5bfcb2890c23068ce890a29c988bb65 Mon Sep 17 00:00:00 2001 From: Piotr Krygier Date: Sat, 17 Dec 2022 21:57:11 +0100 Subject: [PATCH] Add index buffer --- include/vulkanBase.hpp | 7 +++- src/vulkanBase.cpp | 90 +++++++++++++++++++++++++++++++++++------- 2 files changed, 81 insertions(+), 16 deletions(-) diff --git a/include/vulkanBase.hpp b/include/vulkanBase.hpp index bd5a48d1..f35447c6 100644 --- a/include/vulkanBase.hpp +++ b/include/vulkanBase.hpp @@ -9,7 +9,8 @@ * */ -#pragma once +#ifndef RSE_GRAPHICS_VULKANBASE_HPP +#define RSE_GRAPHICS_VULKANBASE_HPP #include @@ -37,4 +38,6 @@ void deinitVulkan(); */ void drawFrame(); -} /* namespace rse::graphics::vulkanbase */ \ No newline at end of file +} /* namespace rse::graphics::vulkanbase */ + +#endif /* RSE_GRAPHICS_VULKANBASE_HPP */ \ No newline at end of file diff --git a/src/vulkanBase.cpp b/src/vulkanBase.cpp index c4593726..f3b7852b 100644 --- a/src/vulkanBase.cpp +++ b/src/vulkanBase.cpp @@ -15,7 +15,7 @@ #include "vulkanBase.hpp" -#include +#include #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" #pragma GCC diagnostic ignored "-Wunused-variable" @@ -143,9 +143,15 @@ struct Buffer // FIXME: Temporary array of vertices, for testing purposes const std::vector 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}} +}; + +// FIXME: Temporary array of vertices, for testing purposes +std::vector indices = { + 0, 1, 2, 2, 3, 0 }; /* Define Validation Layers for debug build */ @@ -210,6 +216,8 @@ std::vector gInFlightFences = {}; Buffer gVertexBuffer = {}; /* CPU visible buffer. TODO: Do we need this global? */ Buffer gVertexStagingBuffer = {}; +Buffer gIndexBuffer = {}; +Buffer gIndexStagingBuffer = {}; /** * @brief Helper function. Creates a buffer object @@ -239,7 +247,7 @@ static uint8_t copyBuffer(VkBuffer src, VkBuffer dst, VkDeviceSize size); * @brief Create the Vulkan Instance object * * @return uint8_t VULKAN_ERROR_NO_ERROR on success. Possible errors: - * VULKAN_ERROR_INSTANCE_INIT_FAILED + * VULKAN_ERROR_INSTANCE_INIT_FAILED */ static uint8_t createInstance(); @@ -254,8 +262,8 @@ static uint8_t createSurface(); * @brief Choose physical device. Used later for vkDevice * * @return uint8_t VULKAN_ERROR_NO_ERROR on success. Possible errors: - * VULKAN_ERROR_NO_PHYSICAL_DEVICE_FOUND - * VULKAN_ERROR_NO_SUITABLE_PHYSICAL_DEVICE_FOUND + * VULKAN_ERROR_NO_PHYSICAL_DEVICE_FOUND + * VULKAN_ERROR_NO_SUITABLE_PHYSICAL_DEVICE_FOUND */ static uint8_t pickPhysicalDevice(); @@ -263,8 +271,8 @@ static uint8_t pickPhysicalDevice(); * @brief Create vkDevice object * * @return uint8_t VULKAN_ERROR_NO_ERROR on success. Possible errors: - * VULKAN_ERROR_QUEUE_NOT_SUPPORTED - * VULKAN_ERROR_DEVICE_CREATION_FAILED + * VULKAN_ERROR_QUEUE_NOT_SUPPORTED + * VULKAN_ERROR_DEVICE_CREATION_FAILED */ static uint8_t createDevice(); @@ -279,7 +287,7 @@ static void setupDebugMessenger(); * @brief Create a Memory Allocator object * * @return uint8_t VULKAN_ERROR_NO_ERROR on success. Possible errors: - * VULKAN_ERROR_ALLOCATOR_CREATION_FAILED + * VULKAN_ERROR_ALLOCATOR_CREATION_FAILED */ static uint8_t createMemoryAllocator(); @@ -287,7 +295,7 @@ static uint8_t createMemoryAllocator(); * @brief Create Command Pools * * @return uint8_t VULKAN_ERROR_NO_ERROR on success. Possible errors: - * VULKAN_ERROR_COMMAND_POOL_CREATION_FAILED + * VULKAN_ERROR_COMMAND_POOL_CREATION_FAILED */ static uint8_t createCommandPools(); @@ -296,10 +304,18 @@ static uint8_t createCommandPools(); * * @return uint8_t VULKAN_ERROR_NO_ERROR on success. Possible errors: * VULKAN_ERROR_BUFFER_CREATION_FAILED -* VULKAN_ERROR_VERTEX_BUFFER_MAPPING_FAILED + * VULKAN_ERROR_VERTEX_BUFFER_MAPPING_FAILED */ static uint8_t createVertexBuffer(); +/** + * @brief Create an index buffer, connected with vertex buffer + * + * @return uint8_t VULKAN_ERROR_NO_ERROR on success. Possible errors: + * VULKAN_ERROR_BUFFER_CREATION_FAILED + */ +static uint8_t createIndexBuffer(); + /** * @brief Allocate Command Buffers * @@ -876,7 +892,6 @@ static uint8_t createVertexBuffer() return VULKAN_ERROR_BUFFER_CREATION_FAILED; } - /* Fill staging buffer */ if (VK_SUCCESS != vmaMapMemory(gAllocator, gVertexStagingBuffer.allocation, &mappedData)) { @@ -891,6 +906,48 @@ static uint8_t createVertexBuffer() return VULKAN_ERROR_NO_ERROR; } +static uint8_t createIndexBuffer() +{ + void* mappedData; + VkDeviceSize bufferSize; + + bufferSize = sizeof(indices[0]) * indices.size(); + + /* Creating staging buffer*/ + if (VK_SUCCESS != createBuffer(bufferSize, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + VMA_MEMORY_USAGE_AUTO_PREFER_HOST, + VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, + gIndexStagingBuffer)) { + LOGF << vulkanErrorMesssages[VULKAN_BUFFER_CREATION_FAILED]; + return VULKAN_ERROR_BUFFER_CREATION_FAILED; + } + + /* Create Vertex Buffer*/ + if (VK_SUCCESS != createBuffer(bufferSize, + VK_BUFFER_USAGE_TRANSFER_DST_BIT + | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, + VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, + 0, /* Will not be mapped with vmaMapMemory */ + gIndexBuffer)) { + LOGF << vulkanErrorMesssages[VULKAN_BUFFER_CREATION_FAILED]; + return VULKAN_ERROR_BUFFER_CREATION_FAILED; + } + + /* Fill staging buffer */ + if (VK_SUCCESS != vmaMapMemory(gAllocator, gIndexStagingBuffer.allocation, &mappedData)) + { + LOGF << vulkanErrorMesssages[VULKAN_VERTEX_BUFFER_MAPPING_FAILED]; + return VULKAN_ERROR_VERTEX_BUFFER_MAPPING_FAILED; + } + memcpy(mappedData, indices.data(), static_cast(bufferSize)); + vmaUnmapMemory(gAllocator, gIndexStagingBuffer.allocation); + + copyBuffer(gIndexStagingBuffer.buffer, gIndexBuffer.buffer, bufferSize); + + return VULKAN_ERROR_NO_ERROR; +} + static uint8_t allocateCommandBuffers() { VkCommandBufferAllocateInfo allocateInfo; @@ -1419,7 +1476,9 @@ static uint8_t recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t image vkCmdSetScissor(commandBuffer, 0, 1, &scissor); vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets); - vkCmdDraw(commandBuffer, static_cast(vertices.size()), 1, 0, 0); + vkCmdBindIndexBuffer(commandBuffer, gIndexBuffer.buffer, 0, VK_INDEX_TYPE_UINT16); + + vkCmdDrawIndexed(commandBuffer, static_cast(indices.size()), 1, 0, 0, 0); vkCmdEndRenderPass(commandBuffer); @@ -1493,6 +1552,7 @@ uint8_t initVulkan() STATUS_CHECK(createMemoryAllocator()); STATUS_CHECK(createCommandPools()); STATUS_CHECK(createVertexBuffer()); + STATUS_CHECK(createIndexBuffer()); STATUS_CHECK(allocateCommandBuffers()); STATUS_CHECK(createSwapchain()); STATUS_CHECK(createSwapchainImageViews()); @@ -1569,6 +1629,8 @@ void deinitVulkan() vmaDestroyBuffer(gAllocator, gVertexBuffer.buffer, gVertexBuffer.allocation); vmaDestroyBuffer(gAllocator, gVertexStagingBuffer.buffer, gVertexStagingBuffer.allocation); + vmaDestroyBuffer(gAllocator, gIndexBuffer.buffer, gIndexBuffer.allocation); + vmaDestroyBuffer(gAllocator, gIndexStagingBuffer.buffer, gIndexStagingBuffer.allocation); for (size_t i = 0; i < SWAP_BUFFER_COUNT; ++i) { vkDestroySemaphore(gDevice, gImageAvailableSemaphores[i], nullptr); vkDestroySemaphore(gDevice, gRenderFinishedSemaphores[i], nullptr);