Skip to content

Commit

Permalink
uniform buffers
Browse files Browse the repository at this point in the history
  • Loading branch information
Jerboa-app committed Sep 7, 2023
1 parent 671923c commit 065980c
Show file tree
Hide file tree
Showing 3 changed files with 205 additions and 4 deletions.
31 changes: 31 additions & 0 deletions include/Renderer/vulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@

#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>

#define GLM_FORCE_RADIANS
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <chrono>


#include <Renderer/renderer.h>
#include <Shader/shader.h>
Expand Down Expand Up @@ -38,6 +44,13 @@ const std::vector<const char *> deviceExtensions =
const bool enableValidationLayers = false;
#endif

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

struct Vertex
{
glm::vec2 pos;
Expand Down Expand Up @@ -133,12 +146,21 @@ namespace Renderer
VkRect2D scissor;

VkRenderPass renderPass;

VkDescriptorSetLayout descriptorSetLayout;
VkDescriptorPool descriptorPool;
std::vector<VkDescriptorSet> descriptorSets;

VkPipelineLayout pipelineLayout;
VkPipeline pipeline;

VkBuffer vertexBuffer;
VkDeviceMemory vertexBufferMemory;

std::vector<VkBuffer> uniformBuffers;
std::vector<VkDeviceMemory> uniformBuffersMemory;
std::vector<void*> uniformBuffersMapped;

VkCommandPool commandPool;
std::vector<VkCommandBuffer> commandBuffers;

Expand Down Expand Up @@ -193,6 +215,15 @@ namespace Renderer

void createVertexBuffer();

void createUniformBuffers();

void updateUniformBuffer();

void createDescriptorSetLayout();

void createDescriptorPool();
void createDescriptorSets();

void createCommandPool();
void createCommandBuffers();
void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex);
Expand Down
9 changes: 8 additions & 1 deletion include/Shaders/trig.vert
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
#version 450

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

layout(location = 0) in vec2 a_position;
layout(location = 1) in vec3 a_colour;

layout(location = 0) out vec3 fragColour;

void main()
{
gl_Position = vec4(a_position, 0.0, 1.0);
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(a_position, 0.0, 1.0);
fragColour = a_colour;
}
169 changes: 166 additions & 3 deletions src/Renderer/vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ namespace Renderer

createRenderPass();

createDescriptorSetLayout();

createGraphicsPipeline();

createFramebuffers();
Expand All @@ -81,6 +83,12 @@ namespace Renderer

createVertexBuffer();

createUniformBuffers();

createDescriptorPool();

createDescriptorSets();

createCommandBuffers();

createSyncObjects();
Expand All @@ -90,6 +98,16 @@ namespace Renderer
{
cleanupSwapChain();

for (size_t i = 0; i < MAX_CONCURRENT_FRAMES; i++)
{
vkDestroyBuffer(device, uniformBuffers[i], nullptr);
vkFreeMemory(device, uniformBuffersMemory[i], nullptr);
}

vkDestroyDescriptorPool(device, descriptorPool, nullptr);

vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);

vkDestroyBuffer(device, vertexBuffer, nullptr);

vkFreeMemory(device, vertexBufferMemory, nullptr);
Expand Down Expand Up @@ -720,7 +738,7 @@ namespace Renderer
// 1.0f requires wideLines enabled
rasterInfo.lineWidth = 1.0f;
rasterInfo.cullMode = VK_CULL_MODE_BACK_BIT;
rasterInfo.frontFace = VK_FRONT_FACE_CLOCKWISE;
rasterInfo.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
rasterInfo.depthBiasEnable = VK_FALSE;
rasterInfo.depthBiasConstantFactor = 0.0f;
rasterInfo.depthBiasClamp = 0.0f;
Expand Down Expand Up @@ -758,8 +776,8 @@ namespace Renderer

VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = 0;
pipelineLayoutInfo.pSetLayouts = nullptr;
pipelineLayoutInfo.setLayoutCount = 1;
pipelineLayoutInfo.pSetLayouts = &descriptorSetLayout;
pipelineLayoutInfo.pushConstantRangeCount = 0;
pipelineLayoutInfo.pPushConstantRanges = nullptr;

Expand Down Expand Up @@ -864,6 +882,136 @@ namespace Renderer

}

void VulkanRenderer::createUniformBuffers()
{
VkDeviceSize bufferSize = sizeof(UniformBufferObject);
uniformBuffers.resize(MAX_CONCURRENT_FRAMES);
uniformBuffersMemory.resize(MAX_CONCURRENT_FRAMES);
uniformBuffersMapped.resize(MAX_CONCURRENT_FRAMES);

for (size_t i = 0; i < MAX_CONCURRENT_FRAMES; 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 VulkanRenderer::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();

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;

memcpy(uniformBuffersMapped[currentFrame], &ubo, sizeof(ubo));
}

void VulkanRenderer::createDescriptorSetLayout()
{

VkDescriptorSetLayoutBinding uboLayoutBinding{};
uboLayoutBinding.binding = 0;
uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
uboLayoutBinding.descriptorCount = 1;
uboLayoutBinding.pImmutableSamplers = nullptr;
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(device, &layoutInfo, nullptr, &descriptorSetLayout) != VK_SUCCESS)
{
throw std::runtime_error("Failed to create descriptor set layout");
}

}

void VulkanRenderer::createDescriptorPool()
{
VkDescriptorPoolSize poolSize{};
poolSize.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
poolSize.descriptorCount = static_cast<uint32_t>(MAX_CONCURRENT_FRAMES);

VkDescriptorPoolCreateInfo poolInfo{};
poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
poolInfo.poolSizeCount = 1;
poolInfo.pPoolSizes = &poolSize;
poolInfo.maxSets = static_cast<uint32_t>(MAX_CONCURRENT_FRAMES);

if (vkCreateDescriptorPool(device, &poolInfo, nullptr, &descriptorPool) != VK_SUCCESS)
{
throw std::runtime_error("Failed to create descriptor pool");
}

}

void VulkanRenderer::createDescriptorSets()
{
std::vector<VkDescriptorSetLayout> layouts(MAX_CONCURRENT_FRAMES, descriptorSetLayout);
VkDescriptorSetAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocInfo.descriptorPool = descriptorPool;
allocInfo.descriptorSetCount = static_cast<uint32_t>(MAX_CONCURRENT_FRAMES);
allocInfo.pSetLayouts = layouts.data();

descriptorSets.resize(MAX_CONCURRENT_FRAMES);
if (vkAllocateDescriptorSets(device, &allocInfo, descriptorSets.data()) != VK_SUCCESS)
{
throw std::runtime_error("Failed to allocate descriptor sets");
}

for (size_t i = 0; i < MAX_CONCURRENT_FRAMES; 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 VulkanRenderer::createCommandPool()
{
QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice);
Expand Down Expand Up @@ -938,6 +1086,19 @@ namespace Renderer
VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets);

// use descriptor stes
vkCmdBindDescriptorSets
(
commandBuffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
pipelineLayout,
0,
1,
&descriptorSets[currentFrame],
0,
nullptr
);

// the draw command is issues
// vertexCount, instanceCount, firstVertex, firstInstance
vkCmdDraw(commandBuffer, vertices.size(), 1, 0, 0);
Expand Down Expand Up @@ -1029,6 +1190,8 @@ namespace Renderer
throw std::runtime_error("Failed to aquire swap chain image");
}

updateUniformBuffer();

vkResetFences(device, 1, &framesFinished[currentFrame]);

vkResetCommandBuffer(commandBuffers[currentFrame], 0);
Expand Down

0 comments on commit 065980c

Please sign in to comment.