diff --git a/src/vulkan_wrapper.c b/src/vulkan_wrapper.c index bdf0bb5..d80996d 100644 --- a/src/vulkan_wrapper.c +++ b/src/vulkan_wrapper.c @@ -659,6 +659,7 @@ typedef struct { const Vertex 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}}}; +const size_t vertexCount = 3; static VkVertexInputBindingDescription getBindingDescription() { VkVertexInputBindingDescription bindingDescription = {0}; @@ -732,8 +733,10 @@ void createGraphicsPipeline(VulkanApp *app) { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; VkVertexInputBindingDescription bindingDescription = getBindingDescription(); - #define attributeDescriptionsCount 2 - VkVertexInputAttributeDescription attributeDescriptions[attributeDescriptionsCount] = {0}; +#define attributeDescriptionsCount 2 + VkVertexInputAttributeDescription + attributeDescriptions[attributeDescriptionsCount] = { + 0}; // TODO: Probably better to move to dynamic array populateAttributeDescriptions( (VkVertexInputAttributeDescription *)&attributeDescriptions); @@ -981,6 +984,15 @@ void recordCommandBuffer(VulkanApp *app, VkCommandBuffer commandBuffer, vkCmdDraw(commandBuffer, 3, 1, 0, 0); + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + app->graphicsPipeline); + + VkBuffer vertexBuffers[] = {app->vertexBuffer}; + VkDeviceSize offsets[] = {0}; + vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets); + + vkCmdDraw(commandBuffer, (uint32_t)vertexCount, 1, 0, 0); + vkCmdEndRenderPass(commandBuffer); if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS) { @@ -1057,6 +1069,61 @@ void recreateSwapChain(VulkanApp *app) { createFramebuffers(app); } +uint32_t findMemoryType(VkPhysicalDevice physicalDevice, uint32_t typeFilter, + VkMemoryPropertyFlags properties) { + VkPhysicalDeviceMemoryProperties memProperties; + vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties); + + for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) { + if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & + properties) == properties) { + return i; + } + } + fprintf(stderr, "Failed to find suitable memory type!\n"); + exit(EXIT_FAILURE); +} + +void createVertexBuffer(VulkanApp *app) { + VkBufferCreateInfo bufferInfo = {0}; + bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + bufferInfo.size = sizeof(vertices[0]) * vertexCount; + bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + if (vkCreateBuffer(app->device, &bufferInfo, NULL, &app->vertexBuffer) != + VK_SUCCESS) { + fprintf(stderr, "Failed to create vertex buffer!\n"); + exit(EXIT_FAILURE); + } + + VkMemoryRequirements memRequirements; + vkGetBufferMemoryRequirements(app->device, app->vertexBuffer, + &memRequirements); + + VkMemoryAllocateInfo allocInfo = {0}; + allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + allocInfo.allocationSize = memRequirements.size; + allocInfo.memoryTypeIndex = + findMemoryType(app->physicalDevice, memRequirements.memoryTypeBits, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + + if (vkAllocateMemory(app->device, &allocInfo, NULL, + &app->vertexBufferMemory) != VK_SUCCESS) { + fprintf(stderr, "Failed to allocate vertex buffer memory!\n"); + exit(EXIT_FAILURE); + } + + vkBindBufferMemory(app->device, app->vertexBuffer, app->vertexBufferMemory, + 0); + + void *data; + vkMapMemory(app->device, app->vertexBufferMemory, 0, bufferInfo.size, 0, + &data); + memcpy(data, vertices, (size_t)bufferInfo.size); + vkUnmapMemory(app->device, app->vertexBufferMemory); +} + void vulkan_init(VulkanApp *app) { createInstance(app); setupDebugMessenger(app); @@ -1069,6 +1136,7 @@ void vulkan_init(VulkanApp *app) { createGraphicsPipeline(app); createFramebuffers(app); CreateCommandPool(app); + createVertexBuffer(app); createCommandBuffer(app); createSyncObjects(app); } @@ -1115,7 +1183,7 @@ void drawFrame(VulkanApp *app) { if (vkQueueSubmit(app->graphicsQueue, 1, &submitInfo, app->inFlightFences[app->currentFrame]) != VK_SUCCESS) { - fprintf(stderr, "failed to submit draw command buffer!"); + fprintf(stderr, "failed to submit draw command buffer!\n"); exit(EXIT_FAILURE); } @@ -1154,6 +1222,9 @@ void mainLoop(VulkanApp *app) { void vulkan_deinit(VulkanApp *app) { cleanupSwapChain(app); + vkDestroyBuffer(app->device, app->vertexBuffer, NULL); + vkFreeMemory(app->device, app->vertexBufferMemory, NULL); + for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { vkDestroySemaphore(app->device, app->imageAvailableSemaphores[i], NULL); vkDestroySemaphore(app->device, app->renderFinishedSemaphore[i], NULL); diff --git a/src/vulkan_wrapper.h b/src/vulkan_wrapper.h index 9942739..1c28ce8 100644 --- a/src/vulkan_wrapper.h +++ b/src/vulkan_wrapper.h @@ -34,6 +34,8 @@ typedef struct { VkSemaphore renderFinishedSemaphore[MAX_FRAMES_IN_FLIGHT]; VkFence inFlightFences[MAX_FRAMES_IN_FLIGHT]; uint32_t currentFrame; // initialised to 0 + VkBuffer vertexBuffer; + VkDeviceMemory vertexBufferMemory; } VulkanApp; void vulkan_init(VulkanApp *app);