Browse Source

Uniform buffer

master
Alexander Memer 1 year ago
parent
commit
bdec05cfa2
5 changed files with 153 additions and 4 deletions
  1. 21
    1
      include/Renderer.hpp
  2. 7
    1
      shaders/shader.vert
  3. BIN
      shaders/vert.spv
  4. 1
    0
      src/Engine.cpp
  5. 124
    2
      src/Renderer.cpp

+ 21
- 1
include/Renderer.hpp View File

@@ -4,6 +4,12 @@
#include "Engine.hpp"
#include "Vertex.hpp"

struct UniformBufferObject {
glm::mat4 model;
glm::mat4 view;
glm::mat4 proj;
};

class Renderer
{
public:
@@ -16,6 +22,9 @@ public:
VkSwapchainKHR vkSwapChain;
VkPipeline vkPipeline;
VkPipelineLayout vkPipelineLayout;
VkDescriptorSetLayout vkDescriptorSetLayout;
VkDescriptorPool vkDescriptorPool;
VkDescriptorSet vkDescriptorSet;
VkRenderPass vkRenderPass;
VkCommandPool vkCommandPool;
std::vector<VkCommandBuffer> vkCommandBuffers;
@@ -31,6 +40,9 @@ public:
VkBuffer vkIndexBuffer;
VkDeviceMemory vkIndexBufferMemory;

VkBuffer vkUniformBuffer;
VkDeviceMemory vkUniformBufferMemory;

VkBuffer vkStagingBuffer;
VkDeviceMemory vkStagingBufferMemory;

@@ -45,6 +57,8 @@ public:
0, 1, 2, 2, 3, 0
};

UniformBufferObject ubo;

VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& formats);
VkPresentModeKHR chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& modes);
VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities);
@@ -60,11 +74,15 @@ public:
void initVulkanSwapChain();
void initVulkanImageViews();
void initVulkanRenderPass();
void initVulkanDescriptorSetLayout();
void initVulkanGraphicsPipeline();
void initVulkanFramebuffers();
void initVulkanCommandPool();
void initVulkanVertexBuffer();
void initVulkanIndexBuffer();
void initVulkanVertexBuffer();
void initVulkanUniformBuffer();
void initVulkanDescriptorPool();
void initVulkanDescriptorSet();
void initVulkanCommandBuffers();
void initVulkanSemaphores();
VkShaderModule createShaderModule(const std::vector<char>& code);
@@ -72,6 +90,8 @@ public:
void createVulkanBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags propertyFlags, VkBuffer& buffer, VkDeviceMemory &bufferMemory);
void copyVulkanBuffer(VkBuffer src, VkBuffer dst, VkDeviceSize size);

void updateUniformBuffer();

void cleanupSwapChain();
void recreateVulkanSwapChain();
};

+ 7
- 1
shaders/shader.vert View File

@@ -5,12 +5,18 @@ out gl_PerVertex {
vec4 gl_Position;
};

layout(binding = 0) uniform UniformBufferObject {
mat4 model;
mat4 view;
mat4 proj;
} ubo;

layout(location = 0) in vec2 inPosition;
layout(location = 1) in vec3 inColor;

layout(location = 0) out vec3 fragColor;

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;
}

BIN
shaders/vert.spv View File


+ 1
- 0
src/Engine.cpp View File

@@ -48,6 +48,7 @@ void Engine::start()
}
}

renderer->updateUniformBuffer();
renderer->render();
frameTime = clock.time() - frameTime;


+ 124
- 2
src/Renderer.cpp View File

@@ -7,11 +7,15 @@ void Renderer::init()
initVulkanSwapChain();
initVulkanImageViews();
initVulkanRenderPass();
initVulkanDescriptorSetLayout();
initVulkanGraphicsPipeline();
initVulkanFramebuffers();
initVulkanCommandPool();
initVulkanIndexBuffer();
initVulkanVertexBuffer();
initVulkanUniformBuffer();
initVulkanDescriptorPool();
initVulkanDescriptorSet();
initVulkanCommandBuffers();
initVulkanSemaphores();
}
@@ -307,6 +311,30 @@ void Renderer::initVulkanRenderPass()
}
}

void Renderer::initVulkanDescriptorSetLayout()
{
VkDescriptorSetLayoutBinding uboLayoutBinding = {};

uboLayoutBinding.binding = 0;
uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
uboLayoutBinding.descriptorCount = 1;
uboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;

VkDescriptorSetLayoutCreateInfo layoutInfo = {};
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layoutInfo.bindingCount = 1;
layoutInfo.pBindings = &uboLayoutBinding;

if (vkCreateDescriptorSetLayout(vkLogicalDevice, &layoutInfo, VK_NULL_HANDLE, &vkDescriptorSetLayout) != VK_SUCCESS)
{
LOG_FATAL("Failed to create descriptor set layout!");
}
else
{
LOG_INFO("Descriptor set layout created successfully");
}
}

static std::vector<char> readFile(const std::string& filename)
{
std::ifstream file(filename, std::ios::ate | std::ios::binary);
@@ -394,7 +422,7 @@ void Renderer::initVulkanGraphicsPipeline()
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
rasterizer.lineWidth = 1.f;
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
rasterizer.depthBiasEnable = VK_FALSE;

VkPipelineMultisampleStateCreateInfo multisampling = {};
@@ -420,7 +448,8 @@ void Renderer::initVulkanGraphicsPipeline()

VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = 0;
pipelineLayoutInfo.setLayoutCount = 1;
pipelineLayoutInfo.pSetLayouts = &vkDescriptorSetLayout;
pipelineLayoutInfo.pushConstantRangeCount = 0;

if (vkCreatePipelineLayout(vkLogicalDevice, &pipelineLayoutInfo, nullptr, &vkPipelineLayout) != VK_SUCCESS)
@@ -548,6 +577,74 @@ void Renderer::initVulkanIndexBuffer()
vkFreeMemory(vkLogicalDevice, vkStagingBufferMemory, nullptr);
}

void Renderer::initVulkanUniformBuffer()
{
LOG_INFO("Creating uniform buffer");
VkDeviceSize bufferSize = sizeof(UniformBufferObject);
createVulkanBuffer(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, vkUniformBuffer, vkUniformBufferMemory);
}

void Renderer::initVulkanDescriptorPool()
{
VkDescriptorPoolSize poolSize = {};
poolSize.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
poolSize.descriptorCount = 1;

VkDescriptorPoolCreateInfo poolInfo = {};
poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
poolInfo.poolSizeCount = 1;
poolInfo.pPoolSizes = &poolSize;
poolInfo.maxSets = 1;

if (vkCreateDescriptorPool(vkLogicalDevice, &poolInfo, VK_NULL_HANDLE, &vkDescriptorPool) != VK_SUCCESS)
{
LOG_FATAL("Failed to create descriptor pool");
}
else
{
LOG_INFO("Descriptor pool created successfully");
}
}


void Renderer::initVulkanDescriptorSet() {

VkDescriptorSetLayout layouts[] = { vkDescriptorSetLayout };
VkDescriptorSetAllocateInfo allocInfo = {};
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocInfo.descriptorPool = vkDescriptorPool;
allocInfo.descriptorSetCount = 1;
allocInfo.pSetLayouts = layouts;

if (vkAllocateDescriptorSets(vkLogicalDevice, &allocInfo, &vkDescriptorSet) != VK_SUCCESS)
{
LOG_FATAL("Failed to allocate descriptor set");
}
else
{
LOG_INFO("Descriptor set allocated successfully");
}

VkDescriptorBufferInfo bufferInfo = {};
bufferInfo.buffer = vkUniformBuffer;
bufferInfo.offset = 0;
bufferInfo.range = sizeof(UniformBufferObject);

VkWriteDescriptorSet descriptorWrite = {};
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrite.dstSet = vkDescriptorSet;
descriptorWrite.dstBinding = 0;
descriptorWrite.dstArrayElement = 0;
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
descriptorWrite.descriptorCount = 1;
descriptorWrite.pBufferInfo = &bufferInfo;
descriptorWrite.pImageInfo = nullptr;
descriptorWrite.pTexelBufferView = nullptr;

vkUpdateDescriptorSets(vkLogicalDevice, 1, &descriptorWrite, 0, nullptr);

}

void Renderer::initVulkanCommandBuffers()
{
LOG_INFO("Creating Vulkan command buffers");
@@ -586,6 +683,8 @@ void Renderer::initVulkanCommandBuffers()

vkCmdBindPipeline(vkCommandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, vkPipeline);

vkCmdBindDescriptorSets(vkCommandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, vkPipelineLayout, 0, 1, &vkDescriptorSet, 0, nullptr);

VkBuffer vertexBuffers[] = { vkVertexBuffer };
VkDeviceSize offsets[] = { 0 };
vkCmdBindVertexBuffers(vkCommandBuffers[i], 0, 1, vertexBuffers, offsets);
@@ -602,6 +701,7 @@ void Renderer::initVulkanCommandBuffers()

}


void Renderer::initVulkanSemaphores()
{
VkSemaphoreCreateInfo semaphoreInfo = {};
@@ -635,6 +735,24 @@ VkShaderModule Renderer::createShaderModule(const std::vector<char>& code) {

}

void Renderer::updateUniformBuffer()
{
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();

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;

void* data;
vkMapMemory(vkLogicalDevice, vkUniformBufferMemory, 0, sizeof(ubo), 0, &data);
memcpy(data, &ubo, sizeof(ubo));
vkUnmapMemory(vkLogicalDevice, vkUniformBufferMemory);
}

void Renderer::createVulkanBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags propertyFlags,
VkBuffer& buffer, VkDeviceMemory &bufferMemory)
{
@@ -702,6 +820,10 @@ void Renderer::copyVulkanBuffer(VkBuffer src, VkBuffer dst, VkDeviceSize size) {
void Renderer::cleanup()
{
cleanupSwapChain();
vkDestroyDescriptorPool(vkLogicalDevice, vkDescriptorPool, nullptr);
vkDestroyDescriptorSetLayout(vkLogicalDevice, vkDescriptorSetLayout, nullptr);
vkDestroyBuffer(vkLogicalDevice, vkUniformBuffer, nullptr);
vkFreeMemory(vkLogicalDevice, vkUniformBufferMemory, nullptr);
vkDestroyBuffer(vkLogicalDevice, vkIndexBuffer, nullptr);
vkFreeMemory(vkLogicalDevice, vkIndexBufferMemory, nullptr);
vkDestroyBuffer(vkLogicalDevice, vkVertexBuffer, nullptr);

Loading…
Cancel
Save