Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion assets/shaders/default.vert
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
#version 450

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;
}
145 changes: 138 additions & 7 deletions src/runtime/renderer/RHIVulkan.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
#include "RHI.h"
#include "rendercore.h"

#include "volk.h"
#include "SDL_vulkan.h"
#define GLM_FORCE_RADIANS
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <vector>
#include <glm/glm.hpp>
#include <iostream>
#include <cassert>
#include <optional>
#include <set>
#include <algorithm>
#include <fstream>
#include <array>
#include <chrono>

namespace segfault::renderer {

Expand Down Expand Up @@ -79,7 +84,7 @@
std::vector<VkPresentModeKHR> presentModes{};
};

struct RHIImpl final {

Check warning on line 87 in src/runtime/renderer/RHIVulkan.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Class has 39 methods, which is greater than the 35 authorized. Split it into smaller classes.

See more on https://sonarcloud.io/project/issues?id=kimkulling_Segfault&issues=AZq814TsHrYHAQ2VvOwx&open=AZq814TsHrYHAQ2VvOwx&pullRequest=2
static constexpr int MAX_FRAMES_IN_FLIGHT = 2;

SDL_Window *window{nullptr};
Expand All @@ -99,6 +104,10 @@
VkShaderModule vertShaderModule{};
VkShaderModule fragShaderModule{};
VkRenderPass renderPass{};
VkDescriptorSetLayout descriptorSetLayout{};
VkDescriptorPool descriptorPool{};
std::vector<VkDescriptorSet> descriptorSets{};

VkPipelineLayout pipelineLayout{};
std::vector<VkFramebuffer> swapChainFramebuffers{};
VkCommandPool commandPool{};
Expand All @@ -110,6 +119,10 @@
VkPipeline graphicsPipeline{};
bool framebufferResized{false};
VkBuffer vertexBuffer{};

std::vector<VkBuffer> uniformBuffers{};
std::vector<VkDeviceMemory> uniformBuffersMemory{};
std::vector<void*> uniformBuffersMapped{};
VkDeviceMemory vertexBufferMemory{};
VkBuffer indexBuffer{};
VkDeviceMemory indexBufferMemory{};
Expand Down Expand Up @@ -137,18 +150,23 @@
void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory);
void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size);
void createRenderPass();
void createDescriptorSetLayout();
void createGraphicsPipeline();
void createFramebuffers();
void createCommandPool(QueueFamilyIndices& indices);
void createCommandBuffer();
void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex);
void createSyncObjects();
void updateUniformBuffer(uint32_t currentImage);
void drawFrame();
void cleanupSwapChain();
void recreateSwapChain();
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
void createVertexBuffer();
void createIndexBuffer();
void createUniformBuffers();
void createDescriptorPool();
void createDescriptorSets();
};

static std::vector<char> readFile(const std::string& filename) {
Expand Down Expand Up @@ -561,6 +579,25 @@
}
}

void RHIImpl::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!");

Check warning on line 597 in src/runtime/renderer/RHIVulkan.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define and throw a dedicated exception instead of using a generic one.

See more on https://sonarcloud.io/project/issues?id=kimkulling_Segfault&issues=AZq814TsHrYHAQ2VvOwy&open=AZq814TsHrYHAQ2VvOwy&pullRequest=2
}
}

void RHIImpl::createGraphicsPipeline() {
auto vertShaderCode = readFile("shaders/vert.spv");
auto fragShaderCode = readFile("shaders/frag.spv");
Expand Down Expand Up @@ -639,13 +676,14 @@
rasterizer.lineWidth = 1.0f;

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.depthBiasConstantFactor = 0.0f; // Optional
rasterizer.depthBiasClamp = 0.0f; // Optional
rasterizer.depthBiasSlopeFactor = 0.0f; // Optional


VkPipelineMultisampleStateCreateInfo multisampling{};
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
multisampling.sampleShadingEnable = VK_FALSE;
Expand Down Expand Up @@ -676,12 +714,13 @@
colorBlending.blendConstants[2] = 0.0f; // Optional
colorBlending.blendConstants[3] = 0.0f; // Optional

VkPipelineLayout pipelineLayout;

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

pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.pPushConstantRanges = nullptr; // Optional

if (vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS) {
Expand Down Expand Up @@ -876,7 +915,8 @@
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets);
vkCmdBindIndexBuffer(commandBuffer, indexBuffer, 0, VK_INDEX_TYPE_UINT16);

//vkCmdDraw(commandBuffer, 3, 1, 0, 0);
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);

vkCmdEndRenderPass(commandBuffer);
Expand Down Expand Up @@ -909,6 +949,18 @@
}
}
}
void RHIImpl::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;
memcpy(uniformBuffersMapped[currentImage], &ubo, sizeof(ubo));
}

void RHIImpl::drawFrame() {
vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
Expand All @@ -924,6 +976,8 @@
core::logMessage(core::LogType::Error, "failed to acquire swap chain image!");
throw std::runtime_error("failed to acquire swap chain image!");
}

updateUniformBuffer(currentFrame);

vkResetFences(device, 1, &inFlightFences[currentFrame]);
vkResetCommandBuffer(commandBuffers[currentFrame], 0);
Expand Down Expand Up @@ -1050,6 +1104,73 @@
vkFreeMemory(device, stagingBufferMemory, nullptr);
}

void RHIImpl::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 RHIImpl::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!");

Check warning on line 1134 in src/runtime/renderer/RHIVulkan.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define and throw a dedicated exception instead of using a generic one.

See more on https://sonarcloud.io/project/issues?id=kimkulling_Segfault&issues=AZq814TsHrYHAQ2VvOwz&open=AZq814TsHrYHAQ2VvOwz&pullRequest=2
}
}

void RHIImpl::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!");

Check warning on line 1148 in src/runtime/renderer/RHIVulkan.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define and throw a dedicated exception instead of using a generic one.

See more on https://sonarcloud.io/project/issues?id=kimkulling_Segfault&issues=AZq814TsHrYHAQ2VvOw0&open=AZq814TsHrYHAQ2VvOw0&pullRequest=2
}

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

RHI::RHI() : mImpl(nullptr) {
// empty
}
Expand Down Expand Up @@ -1127,6 +1248,10 @@
mImpl->createSwapChain();
mImpl->createImageViews();
mImpl->createRenderPass();
mImpl->createDescriptorSetLayout();
mImpl->createUniformBuffers();
mImpl->createDescriptorPool();
mImpl->createDescriptorSets();
mImpl->createGraphicsPipeline();
mImpl->createFramebuffers();
mImpl->createCommandPool(mImpl->queueFamilyIndices);
Expand All @@ -1140,6 +1265,12 @@

bool RHI::shutdown() {
mImpl->cleanupSwapChain();
for (size_t i = 0; i < RHIImpl::MAX_FRAMES_IN_FLIGHT; i++) {
vkDestroyBuffer(mImpl->device, mImpl->uniformBuffers[i], nullptr);
vkFreeMemory(mImpl->device, mImpl->uniformBuffersMemory[i], nullptr);
}
vkDestroyDescriptorPool(mImpl->device, mImpl->descriptorPool, nullptr);
vkDestroyDescriptorSetLayout(mImpl->device, mImpl->descriptorSetLayout, nullptr);
vkDestroyBuffer(mImpl->device, mImpl->vertexBuffer, nullptr);
vkFreeMemory(mImpl->device, mImpl->vertexBufferMemory, nullptr);

Expand Down
2 changes: 1 addition & 1 deletion src/runtime/renderer/rendercore.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
};

struct DrawCommand {
RenderPipelineState rpState;
//RenderPipelineState rpState;

Check warning on line 25 in src/runtime/renderer/rendercore.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the commented out code.

See more on https://sonarcloud.io/project/issues?id=kimkulling_Segfault&issues=AZq814XqHrYHAQ2VvOw5&open=AZq814XqHrYHAQ2VvOw5&pullRequest=2

uint32_t numVertices = 0;
uint32_t numInstances = 0;
Expand All @@ -36,11 +36,11 @@
RenderGraph() = default;
~RenderGraph() = default;

void addCommand(const DrawCommand& command) {

Check warning on line 39 in src/runtime/renderer/rendercore.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the unused parameter "command", make it unnamed, or declare it "[[maybe_unused]]".

See more on https://sonarcloud.io/project/issues?id=kimkulling_Segfault&issues=AZq814XqHrYHAQ2VvOw2&open=AZq814XqHrYHAQ2VvOw2&pullRequest=2

Check warning on line 39 in src/runtime/renderer/rendercore.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

This function should be declared "const".

See more on https://sonarcloud.io/project/issues?id=kimkulling_Segfault&issues=AZq814XqHrYHAQ2VvOw1&open=AZq814XqHrYHAQ2VvOw1&pullRequest=2
// Implementation for adding a draw command to the render graph
}

void execute(RHI &rhi) {

Check warning on line 43 in src/runtime/renderer/rendercore.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

This function should be declared "const".

See more on https://sonarcloud.io/project/issues?id=kimkulling_Segfault&issues=AZq814XqHrYHAQ2VvOw3&open=AZq814XqHrYHAQ2VvOw3&pullRequest=2

Check warning on line 43 in src/runtime/renderer/rendercore.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the unused parameter "rhi", make it unnamed, or declare it "[[maybe_unused]]".

See more on https://sonarcloud.io/project/issues?id=kimkulling_Segfault&issues=AZq814XqHrYHAQ2VvOw4&open=AZq814XqHrYHAQ2VvOw4&pullRequest=2
// Implementation for executing the render graph
}
};
Expand Down
Loading