1
0
Adding Descriptor Layout & Buffers, Creating Descriptor pools and sets
This commit is contained in:
2023-12-25 13:41:18 +01:00
parent 94d467d897
commit 487e487fb3
2 changed files with 153 additions and 3 deletions

View File

@@ -1,11 +1,15 @@
/* /*
Following the vulkan tutorial on : Following the vulkan tutorial on :
https://vulkan-tutorial.com/en/Vertex_buffers/Index_buffer https://vulkan-tutorial.com/Texture_mapping/Images
*/ */
#define GLFW_INCLUDE_VULKAN #define GLFW_INCLUDE_VULKAN
#define GLM_FORCE_RADIANS
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <chrono>
#include <iostream> #include <iostream>
#include <stdexcept> #include <stdexcept>
#include <cstdlib> #include <cstdlib>
@@ -67,6 +71,11 @@ const std::vector<const char*> deviceExtensions = {
} }
}; };
struct UniformBufferObject {
alignas(16) glm::mat4 model;
alignas(16) glm::mat4 view;
alignas(16) glm::mat4 proj;
};
const std::vector<Vertex> vertices = { const std::vector<Vertex> vertices = {
{{-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}}, {{-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}},
@@ -103,16 +112,24 @@ const std::vector<const char*> deviceExtensions = {
VkExtent2D swapChainExtent; VkExtent2D swapChainExtent;
std::vector<VkImageView> swapChainImageViews; std::vector<VkImageView> swapChainImageViews;
VkRenderPass renderPass; VkRenderPass renderPass;
VkDescriptorSetLayout descriptorSetLayout;
VkPipelineLayout pipelineLayout; VkPipelineLayout pipelineLayout;
VkPipeline graphicsPipeline; VkPipeline graphicsPipeline;
std::vector<VkFramebuffer> swapchainFrameBuffers; std::vector<VkFramebuffer> swapchainFrameBuffers;
VkCommandPool commandPool; VkCommandPool commandPool;
VkDescriptorPool descriptorPool;
std::vector<VkDescriptorSet> descriptorSets;
VkBuffer vertexBuffer; VkBuffer vertexBuffer;
VkDeviceMemory vertexBufferMemory; VkDeviceMemory vertexBufferMemory;
VkBuffer indexBuffer; VkBuffer indexBuffer;
VkDeviceMemory indexBufferMemory; VkDeviceMemory indexBufferMemory;
std::vector<VkBuffer> uniformBuffers;
std::vector<VkDeviceMemory> uniformBuffersMemory;
std::vector<void*> uniformBuffersMapped;
std::vector<VkCommandBuffer> commandBuffers; std::vector<VkCommandBuffer> commandBuffers;
std::vector<VkSemaphore> imageAvailableSemaphores; std::vector<VkSemaphore> imageAvailableSemaphores;
@@ -154,15 +171,108 @@ const std::vector<const char*> deviceExtensions = {
createSwapChain(); createSwapChain();
createImageViews(); createImageViews();
createRenderPass(); createRenderPass();
createDescriptorSetLayout();
createGraphicsPipeline(); createGraphicsPipeline();
createFramebuffers(); createFramebuffers();
createCommandPool(); createCommandPool();
createVertexBuffer(); createVertexBuffer();
createIndexBuffer(); createIndexBuffer();
createUniformBuffers();
createDescriptorPool();
createDescriptorSets();
createCommandBuffers(); createCommandBuffers();
createSyncObjects(); createSyncObjects();
} }
void createDescriptorSets() {
std::vector<VkDescriptorSetLayout> layouts(MAX_FRAMES_IN_FLIGHT, descriptorSetLayout);
VkDescriptorSetAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocInfo.descriptorPool = descriptorPool;
allocInfo.descriptorSetCount = static_cast<uint32_t>(MAX_FRAMES_IN_FLIGHT);
allocInfo.pSetLayouts = layouts.data();
descriptorSets.resize(MAX_FRAMES_IN_FLIGHT);
if (vkAllocateDescriptorSets(device, &allocInfo, descriptorSets.data()) != VK_SUCCESS) {
throw std::runtime_error("failed to allocate descriptor sets!");
}
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
VkDescriptorBufferInfo bufferInfo{};
bufferInfo.buffer = uniformBuffers[i];
bufferInfo.offset = 0;
bufferInfo.range = sizeof(UniformBufferObject);
VkWriteDescriptorSet descriptorWrite{};
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrite.dstSet = descriptorSets[i];
descriptorWrite.dstBinding = 0;
descriptorWrite.dstArrayElement = 0;
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
descriptorWrite.descriptorCount = 1;
descriptorWrite.pBufferInfo = &bufferInfo;
descriptorWrite.pImageInfo = nullptr; // Optional
descriptorWrite.pTexelBufferView = nullptr; // Optional
vkUpdateDescriptorSets(device, 1, &descriptorWrite, 0, nullptr);
}
}
void createDescriptorPool() {
VkDescriptorPoolSize poolSize{};
poolSize.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
poolSize.descriptorCount = static_cast<uint32_t> (MAX_FRAMES_IN_FLIGHT);
VkDescriptorPoolCreateInfo poolInfo{};
poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
poolInfo.poolSizeCount = 1;
poolInfo.pPoolSizes = &poolSize;
poolInfo.maxSets = static_cast<uint32_t>(MAX_FRAMES_IN_FLIGHT);
if (vkCreateDescriptorPool(device, &poolInfo, nullptr, &descriptorPool) != VK_SUCCESS) {
throw std::runtime_error("failed to create descriptor pool!");
}
}
void createUniformBuffers() {
VkDeviceSize buffersize = sizeof(UniformBufferObject);
uniformBuffers.resize(MAX_FRAMES_IN_FLIGHT);
uniformBuffersMemory.resize(MAX_FRAMES_IN_FLIGHT);
uniformBuffersMapped.resize(MAX_FRAMES_IN_FLIGHT);
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
CreateBuffer(buffersize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, uniformBuffers[i], uniformBuffersMemory[i]);
vkMapMemory(device, uniformBuffersMemory[i], 0, buffersize, 0, &uniformBuffersMapped[i]);
}
}
void createDescriptorSetLayout() {
VkDescriptorSetLayoutBinding uboLayoutBinding{};
uboLayoutBinding.binding = 0;
uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
uboLayoutBinding.descriptorCount = 1;
uboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
uboLayoutBinding.pImmutableSamplers = nullptr; // Optional
VkDescriptorSetLayoutCreateInfo layoutInfo{};
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layoutInfo.bindingCount = 1;
layoutInfo.pBindings = &uboLayoutBinding;
if (vkCreateDescriptorSetLayout(device, &layoutInfo, nullptr, &descriptorSetLayout) != VK_SUCCESS) {
throw std::runtime_error("failed to create descriptor set layout!");
}
}
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) { uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) {
VkPhysicalDeviceMemoryProperties memProperties; VkPhysicalDeviceMemoryProperties memProperties;
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties); vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties);
@@ -391,6 +501,8 @@ const std::vector<const char*> deviceExtensions = {
scissor.extent = swapChainExtent; scissor.extent = swapChainExtent;
vkCmdSetScissor(commandBuffer, 0, 1, &scissor); vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets[currentFrame], 0, nullptr);
vkCmdDrawIndexed(commandBuffer, static_cast<uint32_t>(indices.size()), 1, 0, 0, 0); vkCmdDrawIndexed(commandBuffer, static_cast<uint32_t>(indices.size()), 1, 0, 0, 0);
vkCmdEndRenderPass(commandBuffer); vkCmdEndRenderPass(commandBuffer);
@@ -672,7 +784,7 @@ const std::vector<const char*> deviceExtensions = {
rasterizer.polygonMode = VK_POLYGON_MODE_FILL; rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
rasterizer.lineWidth = 1.0f; rasterizer.lineWidth = 1.0f;
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT; rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE; rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
rasterizer.depthBiasEnable = VK_FALSE; rasterizer.depthBiasEnable = VK_FALSE;
@@ -694,6 +806,8 @@ const std::vector<const char*> deviceExtensions = {
VkPipelineLayoutCreateInfo pipelineLayoutInfo{}; VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = 1;
pipelineLayoutInfo.pSetLayouts = &descriptorSetLayout;
if (vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS) { if (vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS) {
throw std::runtime_error("failed to create pipeline layout!"); throw std::runtime_error("failed to create pipeline layout!");
@@ -1099,6 +1213,8 @@ const std::vector<const char*> deviceExtensions = {
uint32_t imageIndex; uint32_t imageIndex;
VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex); VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
if (result == VK_ERROR_OUT_OF_DATE_KHR) { if (result == VK_ERROR_OUT_OF_DATE_KHR) {
recreateSwapChain(); recreateSwapChain();
return; return;
@@ -1107,8 +1223,11 @@ const std::vector<const char*> deviceExtensions = {
throw std::runtime_error("failed to acquire swap chain image!"); throw std::runtime_error("failed to acquire swap chain image!");
} }
updateUniformBuffer(currentFrame);
vkResetFences(device, 1, &inFlightFences[currentFrame]); vkResetFences(device, 1, &inFlightFences[currentFrame]);
vkResetCommandBuffer(commandBuffers[currentFrame], 0); vkResetCommandBuffer(commandBuffers[currentFrame], 0);
recordCommandBuffer(commandBuffers[currentFrame], imageIndex); recordCommandBuffer(commandBuffers[currentFrame], imageIndex);
@@ -1156,9 +1275,34 @@ const std::vector<const char*> deviceExtensions = {
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT; currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
} }
void updateUniformBuffer(uint32_t currentImage) {
static auto startTime = std::chrono::high_resolution_clock::now();
auto currentTime = std::chrono::high_resolution_clock::now();
float time = std::chrono::duration<float, std::chrono::seconds::period>(currentTime - startTime).count();
UniformBufferObject ubo{};
ubo.model = glm::rotate(glm::mat4(1.0f), time * glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f));
ubo.view = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f));
ubo.proj = glm::perspective(glm::radians(45.0f), swapChainExtent.width / (float)swapChainExtent.height, 0.1f, 10.0f);
ubo.proj[1][1] *= -1; // Invert Y to correct for left or right handedness
memcpy(uniformBuffersMapped[currentImage], &ubo, sizeof(ubo));
}
void cleanup(){ void cleanup(){
cleanupSwapChain(); cleanupSwapChain();
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
vkDestroyBuffer(device, uniformBuffers[i], nullptr);
vkFreeMemory(device, uniformBuffersMemory[i], nullptr);
}
vkDestroyDescriptorPool(device, descriptorPool, nullptr);
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
vkDestroyBuffer(device, indexBuffer, nullptr); vkDestroyBuffer(device, indexBuffer, nullptr);
vkFreeMemory(device, vertexBufferMemory, nullptr); vkFreeMemory(device, vertexBufferMemory, nullptr);

View File

@@ -1,11 +1,17 @@
#version 450 #version 450
layout(binding = 0) uniform UniformBufferObject {
mat4 model;
mat4 view;
mat4 proj;
} ubo;
layout(location = 0) in vec2 inPosition; layout(location = 0) in vec2 inPosition;
layout(location = 1) in vec3 inColor; layout(location = 1) in vec3 inColor;
layout(location = 0) out vec3 fragColor; layout(location = 0) out vec3 fragColor;
void main() { void main() {
gl_Position = vec4(inPosition, 0.0 , 1.0); gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 0.0 , 1.0);
fragColor = inColor; fragColor = inColor;
} }