diff --git a/vulkan/vulkan_app.cpp b/vulkan/vulkan_app.cpp index ca336fe..6f6b83c 100644 --- a/vulkan/vulkan_app.cpp +++ b/vulkan/vulkan_app.cpp @@ -703,6 +703,7 @@ namespace vapp{ allocInfo.allocationSize = memRequirements.size; allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties); + // TODO: switch vkAllocateMemory with own implementation or GPUOpen's VulkanMemoryAllocator if(vkAllocateMemory(device, &allocInfo, nullptr, &bufferMemory) != VK_SUCCESS){ throw std::runtime_error("Func: createBuffer\nError: Failed to allocate memory for buffer!\n"); } @@ -765,6 +766,27 @@ namespace vapp{ vkFreeMemory(device, stagingBufferMemory, nullptr); } + void Vulkan::createIndexBuffer(){ + VkDeviceSize bufferSize = sizeof(indices[0]) * indices.size(); + + VkBuffer stagingBuffer; + VkDeviceMemory stagingBufferMemory; + + createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, stagingBuffer, stagingBufferMemory); + + void *data; + vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, &data); + memcpy(data, indices.data(), (size_t)bufferSize); + vkUnmapMemory(device, stagingBufferMemory); + + createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer, indexBufferMemory); + + copyBuffer(stagingBuffer, indexBuffer, bufferSize); + + vkDestroyBuffer(device, stagingBuffer, nullptr); + vkFreeMemory(device, stagingBufferMemory, nullptr); + } + void Vulkan::createCommandBuffers(){ commandBuffers.resize(MAX_FRAMES_IN_FLIGHT); @@ -805,6 +827,8 @@ namespace vapp{ VkDeviceSize offsets[] = { 0 }; vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets); + vkCmdBindIndexBuffer(commandBuffer, indexBuffer, 0, VK_INDEX_TYPE_UINT32); + VkViewport viewport{}; viewport.x = 0.0f; viewport.y = 0.0f; @@ -819,7 +843,9 @@ namespace vapp{ scissor.extent = swapChainExtent; vkCmdSetScissor(commandBuffer, 0, 1, &scissor); - vkCmdDraw(commandBuffer, static_cast(vertices.size()), 1, 0, 0); + // vkCmdDraw(commandBuffer, static_cast(vertices.size()), 1, 0, 0); + // -> goto indexed draw + vkCmdDrawIndexed(commandBuffer, static_cast(indices.size()), 1, 0, 0, 0); vkCmdEndRenderPass(commandBuffer); if(vkEndCommandBuffer(commandBuffer) != VK_SUCCESS){ @@ -957,6 +983,7 @@ namespace vapp{ createFrameBuffers(); createCommandPool(); createVertexBuffer(); + createIndexBuffer(); createCommandBuffers(); createSyncObjects(); } @@ -974,6 +1001,9 @@ namespace vapp{ // Vulkan cleanupSwapChain(); + vkDestroyBuffer(device, indexBuffer, nullptr); + vkFreeMemory(device, indexBufferMemory, nullptr); + vkDestroyBuffer(device, vertexBuffer, nullptr); vkFreeMemory(device, vertexBufferMemory, nullptr); diff --git a/vulkan/vulkan_app.hpp b/vulkan/vulkan_app.hpp index dc83997..fb0c61c 100644 --- a/vulkan/vulkan_app.hpp +++ b/vulkan/vulkan_app.hpp @@ -57,11 +57,16 @@ namespace vapp{ // TODO: Remove const std::vector vertices = { - {{0.0f, -0.5f}, {0.0f, 1.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}, {0.0f, 1.0f, 0.0f}}, {{-0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}} }; + // uint16_t also possible -> change in vkCmdBindIndexBuffer also + const std::vector indices = { 0, 1, 2, 2, 3, 0 }; + // END Remove + struct QueueFamilyIndices{ std::optional graphicsFamily; std::optional presentFamily; @@ -123,6 +128,8 @@ namespace vapp{ VkBuffer vertexBuffer; VkDeviceMemory vertexBufferMemory; + VkBuffer indexBuffer; + VkDeviceMemory indexBufferMemory; #pragma endregion bool checkValidationLayerSupport(); @@ -151,6 +158,7 @@ namespace vapp{ void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer &buffer, VkDeviceMemory &bufferMemory); void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size); void createVertexBuffer(); + void createIndexBuffer(); void createCommandBuffers(); void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex); void createSyncObjects();