|
|
|
|
@@ -7,14 +7,49 @@
|
|
|
|
|
#include <stdexcept>
|
|
|
|
|
#include <optional>
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <array>
|
|
|
|
|
#include <glm/glm.hpp>
|
|
|
|
|
|
|
|
|
|
#define GLFW_INCLUDE_VULKAN
|
|
|
|
|
#include <GLFW/glfw3.h>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <cstring>
|
|
|
|
|
|
|
|
|
|
#include "queues.h"
|
|
|
|
|
#include "util.h"
|
|
|
|
|
|
|
|
|
|
struct Vertex {
|
|
|
|
|
glm::vec2 pos;
|
|
|
|
|
glm::vec3 color;
|
|
|
|
|
|
|
|
|
|
static VkVertexInputBindingDescription getBindingDescription() {
|
|
|
|
|
VkVertexInputBindingDescription bindingDescription{
|
|
|
|
|
.binding = 0,
|
|
|
|
|
.stride = sizeof(Vertex),
|
|
|
|
|
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
|
|
|
|
|
};
|
|
|
|
|
return bindingDescription;
|
|
|
|
|
}
|
|
|
|
|
static std::array<VkVertexInputAttributeDescription, 2> getAttributeDescription() {
|
|
|
|
|
std::array<VkVertexInputAttributeDescription, 2> attributeDescriptions{};
|
|
|
|
|
attributeDescriptions[0].binding = 0;
|
|
|
|
|
attributeDescriptions[0].location = 0;
|
|
|
|
|
attributeDescriptions[0].format = VK_FORMAT_R32G32_SFLOAT;
|
|
|
|
|
attributeDescriptions[0].offset = offsetof(Vertex, pos);
|
|
|
|
|
attributeDescriptions[1].binding = 0;
|
|
|
|
|
attributeDescriptions[1].location = 1;
|
|
|
|
|
attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
|
|
|
|
|
attributeDescriptions[1].offset = offsetof(Vertex, color);
|
|
|
|
|
return attributeDescriptions;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const std::vector<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}},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkShaderModule HelloTriangleApplication::createShaderModule(const std::vector<char> &code) {
|
|
|
|
|
VkShaderModuleCreateInfo createInfo{};
|
|
|
|
|
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
|
|
|
|
@@ -179,12 +214,15 @@ void HelloTriangleApplication::createGraphicsPipeline() {
|
|
|
|
|
|
|
|
|
|
VkPipelineShaderStageCreateInfo shaderStages[] = {vertShaderStageInfo, fragShaderStageInfo};
|
|
|
|
|
|
|
|
|
|
auto bindingDescription = Vertex::getBindingDescription();
|
|
|
|
|
auto attributeDescriptions = Vertex::getAttributeDescription();
|
|
|
|
|
|
|
|
|
|
VkPipelineVertexInputStateCreateInfo vertexInputInfo{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
|
|
|
|
.vertexBindingDescriptionCount = 0,
|
|
|
|
|
.pVertexBindingDescriptions = nullptr,
|
|
|
|
|
.vertexAttributeDescriptionCount = 0,
|
|
|
|
|
.pVertexAttributeDescriptions = nullptr,
|
|
|
|
|
.vertexBindingDescriptionCount = 1,
|
|
|
|
|
.pVertexBindingDescriptions = &bindingDescription,
|
|
|
|
|
.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributeDescriptions.size()),
|
|
|
|
|
.pVertexAttributeDescriptions = attributeDescriptions.data(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkPipelineInputAssemblyStateCreateInfo inputAssembly{
|
|
|
|
|
@@ -338,6 +376,38 @@ void HelloTriangleApplication::createFrameBuffers() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HelloTriangleApplication::createVertexBuffer() {
|
|
|
|
|
VkBufferCreateInfo bufferCreateInfo {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
|
|
|
|
.size = sizeof(vertices[0]) * vertices.size(),
|
|
|
|
|
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
|
|
|
|
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (vkCreateBuffer(myVkInstance->device, &bufferCreateInfo, nullptr, &vertexBuffer) != VK_SUCCESS) {
|
|
|
|
|
throw std::runtime_error("Failed to create vertex buffer");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkMemoryRequirements memoryRequirements;
|
|
|
|
|
vkGetBufferMemoryRequirements(myVkInstance->device, vertexBuffer, &memoryRequirements);
|
|
|
|
|
|
|
|
|
|
VkMemoryAllocateInfo allocateInfo{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
|
|
|
|
.allocationSize = memoryRequirements.size,
|
|
|
|
|
.memoryTypeIndex = myVkInstance->findMemoryType(memoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (vkAllocateMemory(myVkInstance->device, &allocateInfo, nullptr, &vertexBufferMemory) != VK_SUCCESS) {
|
|
|
|
|
throw std::runtime_error("Failed to allocate vertex buffer memory");
|
|
|
|
|
}
|
|
|
|
|
vkBindBufferMemory(myVkInstance->device, vertexBuffer, vertexBufferMemory, 0);
|
|
|
|
|
|
|
|
|
|
void* data;
|
|
|
|
|
vkMapMemory(myVkInstance->device, vertexBufferMemory, 0, bufferCreateInfo.size, 0, &data);
|
|
|
|
|
memcpy(data, vertices.data(), (size_t)bufferCreateInfo.size);
|
|
|
|
|
vkUnmapMemory(myVkInstance->device, vertexBufferMemory);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void HelloTriangleApplication::createCommandPool() {
|
|
|
|
|
VkCommandPoolCreateInfo poolInfo{
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
|
|
|
|
@@ -386,7 +456,10 @@ void HelloTriangleApplication::createCommandBuffers() {
|
|
|
|
|
renderPassInfo.pClearValues = &clearColor;
|
|
|
|
|
vkCmdBeginRenderPass(commandBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
|
|
|
|
vkCmdBindPipeline(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
|
|
|
|
|
vkCmdDraw(commandBuffers[i], 3, 1, 0, 0);
|
|
|
|
|
VkBuffer vertexBuffers[] = {vertexBuffer};
|
|
|
|
|
VkDeviceSize offset[] = {0};
|
|
|
|
|
vkCmdBindVertexBuffers(commandBuffers[i], 0, 1, vertexBuffers, offset);
|
|
|
|
|
vkCmdDraw(commandBuffers[i], static_cast<uint32_t>(vertices.size()), 1, 0, 0);
|
|
|
|
|
vkCmdEndRenderPass(commandBuffers[i]);
|
|
|
|
|
if (vkEndCommandBuffer(commandBuffers[i]) != VK_SUCCESS) {
|
|
|
|
|
throw std::runtime_error{"Failed to record command buffer"};
|
|
|
|
|
@@ -423,6 +496,7 @@ void HelloTriangleApplication::initVulkan() {
|
|
|
|
|
createGraphicsPipeline();
|
|
|
|
|
createFrameBuffers();
|
|
|
|
|
createCommandPool();
|
|
|
|
|
createVertexBuffer();
|
|
|
|
|
createCommandBuffers();
|
|
|
|
|
createSyncObjects();
|
|
|
|
|
}
|
|
|
|
|
@@ -546,6 +620,9 @@ void HelloTriangleApplication::drawFrame() {
|
|
|
|
|
void HelloTriangleApplication::cleanup() {
|
|
|
|
|
cleanupSwapChain();
|
|
|
|
|
|
|
|
|
|
vkDestroyBuffer(myVkInstance->device, vertexBuffer, nullptr);
|
|
|
|
|
vkFreeMemory(myVkInstance->device, vertexBufferMemory, nullptr);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
|
|
|
|
|
vkDestroySemaphore(myVkInstance->device, renderFinishedSemaphores[i], nullptr);
|
|
|
|
|
vkDestroySemaphore(myVkInstance->device, imageAvailableSemaphores[i], nullptr);
|
|
|
|
|
|