1
0
Fork 0

Vulkan uniform buffer object

tmp
May B. 2020-09-29 21:28:11 +02:00
parent c00f3f64a6
commit 87fc0c3f10
21 changed files with 257 additions and 112 deletions

BIN
resource/content/shaders/Tris.vs.spv (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

BIN
resource/content/shaders/Voxel.fs.geo.spv (Stored with Git LFS)

Binary file not shown.

BIN
resource/content/shaders/Voxel.fs.ins.spv (Stored with Git LFS)

Binary file not shown.

BIN
resource/content/shaders/Voxel.fs.spv (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

BIN
resource/content/shaders/Voxel.vs.geo.spv (Stored with Git LFS)

Binary file not shown.

BIN
resource/content/shaders/Voxel.vs.ins.spv (Stored with Git LFS)

Binary file not shown.

BIN
resource/content/shaders/Voxel.vs.spv (Stored with Git LFS)

Binary file not shown.

View File

@ -1,12 +1,18 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable
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;
}

View File

@ -9,6 +9,12 @@ layout (constant_id = 4) const bool BLEND = true;
// ...
layout (constant_id = 16) const int UNIT_SIZE = 8;
layout (binding = 0) uniform UniformBufferObject {
vec3 FogColor;
float FogDepth;
vec3 LightInvDirection_worldspace;
} UBO;
layout (binding = 1) uniform sampler2DArray TextureAtlas;
layout (binding = 2) uniform sampler2DArray NormalAtlas;
layout (binding = 3) uniform sampler2DArray HOSAtlas;
@ -22,12 +28,6 @@ layout(push_constant) uniform PushConstants {
vec4 SphereProj;
float Curvature;
//MAYBE: extract
vec3 FogColor;
float FogDepth;
vec3 LightInvDirection_worldspace;
} Push;
#ifdef GEOMETRY
@ -234,7 +234,7 @@ if(PBR) {
}
if(FOG) {
float ratio = exp(vs.Depth * 0.69)-1;
color = mix(color, pow(Push.FogColor, vec3(2.2)), clamp(ratio, 0, 1));
color = mix(color, pow(UBO.FogColor, vec3(2.2)), clamp(ratio, 0, 1));
}
color = pow(color, vec3(1.0 / 2.2));
if(color.r > 1 || color.g > 1 || color.b > 1) {

View File

@ -7,8 +7,15 @@ layout (constant_id = 1) const bool PBR = true;
layout (constant_id = 5) const bool DO_CURVATURE = false;
layout (constant_id = 6) const bool CURV_DEPTH = true;
layout (binding = 0) uniform UniformBufferObject {
vec3 FogColor;
float FogDepth;
vec3 LightInvDirection_worldspace;
} UBO;
layout(push_constant) uniform PushConstants {
mat4 Proj;
mat4 Proj; //MAYBE: move Proj View to UBO
mat4 View;
#ifndef INSTANCED
mat4 Model;
@ -16,12 +23,6 @@ layout(push_constant) uniform PushConstants {
vec4 SphereProj;
float Curvature;
//MAYBE: extract
vec3 FogColor;
float FogDepth;
vec3 LightInvDirection_worldspace;
} Push;
layout (location = 0) in vec3 Position_modelspace;
@ -66,7 +67,7 @@ if(DO_CURVATURE) {
gl_Position = Push.Proj * Position_cameraspace;
if(FOG) {
vs.Depth = length(Position_cameraspace.xyz) / Push.FogDepth;
vs.Depth = length(Position_cameraspace.xyz) / UBO.FogDepth;
}
vs.Texture = Texture_model;
@ -81,6 +82,6 @@ if(PBR) {
vs.EyeDirection_cameraspace = vec3(0,0,0) - Position_cameraspace.xyz;
// Vector that goes from the vertex to the light, in camera space
vs.LightDirection_cameraspace = (Push.View * vec4(Push.LightInvDirection_worldspace,0)).xyz;
vs.LightDirection_cameraspace = (Push.View * vec4(UBO.LightInvDirection_worldspace,0)).xyz;
}
}

View File

@ -2,15 +2,15 @@
#include "PhysicalDeviceInfo.hpp"
#include <TracyVulkan.hpp>
#include "buffer/VertexData.hpp"
#include <memory.h>
#include <cassert>
using namespace render::vk;
const auto NO_DELETER = Allocator::MemoryDeleter(nullptr);
Allocator::memory_ptr get_null_ptr() { return Allocator::memory_ptr(nullptr, NO_DELETER); }
Allocator::memory_ptr Allocator::GetNull() { return Allocator::memory_ptr(nullptr, NO_DELETER); }
Allocator::Allocator(VkDevice device, const PhysicalDeviceInfo &info) : device(device), indexedBufferMemory(get_null_ptr()) {
Allocator::Allocator(VkDevice device, const PhysicalDeviceInfo &info) : device(device) {
vkGetPhysicalDeviceMemoryProperties(info.device, &properties);
{
@ -39,39 +39,8 @@ Allocator::Allocator(VkDevice device, const PhysicalDeviceInfo &info) : device(d
vkAllocateCommandBuffers(device, &allocInfo, &transferBuffer);
tracyCtx = TracyVkContext(info.device, device, transferQueue, transferBuffer);
}
{
size_t vertexSize = sizeof(buffer::vk::vertices[0]) * buffer::vk::vertices.size();
size_t indexSize = sizeof(buffer::vk::indices[0]) * buffer::vk::indices.size();
size_t stagingSize = std::max(vertexSize, indexSize);
buffer_info stagingBuffer;
if(auto stagingMemory = createBuffer(stagingSize, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, stagingBuffer)) {
std::vector<buffer_requirement> requirements = {
{indexSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT},
{vertexSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT}
};
if(std::vector<buffer_info> out; indexedBufferMemory = createBuffers(requirements, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, out)) {
indexBuffer = out[0];
vertexBuffer = out[1];
} else {
FATAL("Cannot allocate buffer memory");
}
stagingMemory->write(buffer::vk::vertices.data(), vertexSize);
copyBuffer(stagingBuffer, vertexBuffer, vertexSize);
stagingMemory->write(buffer::vk::indices.data(), indexSize);
copyBuffer(stagingBuffer, indexBuffer, indexSize);
vkDestroyBuffer(device, stagingBuffer.buffer, ALLOC); //TODO: move to buffer
} else {
FATAL("Cannot allocate staging memory");
}
}
}
Allocator::~Allocator() {
vkDestroyBuffer(device, indexBuffer.buffer, ALLOC);
vkDestroyBuffer(device, vertexBuffer.buffer, ALLOC);
indexedBufferMemory.reset();
TracyVkDestroy(tracyCtx);
vkFreeCommandBuffers(device, transferPool, 1, &transferBuffer);
@ -94,8 +63,9 @@ Allocator::memory_ptr Allocator::createBuffer(VkDeviceSize size, VkMemoryPropert
if (vkCreateBuffer(device, &bufferInfo, ALLOC, &out.buffer) != VK_SUCCESS) {
LOG_E("Failed to create buffer");
return get_null_ptr();
return GetNull();
}
out.offset = 0;
VkMemoryRequirements memRequirements;
vkGetBufferMemoryRequirements(device, out.buffer, &memRequirements);
@ -105,16 +75,16 @@ Allocator::memory_ptr Allocator::createBuffer(VkDeviceSize size, VkMemoryPropert
return memory;
}
LOG_E("Failed to allocate buffer memory");
return get_null_ptr();
return GetNull();
}
Allocator::memory_ptr Allocator::createBuffers(const std::vector<buffer_requirement>& requirements, VkMemoryPropertyFlags properties, std::vector<buffer_info>& out) {
assert(!requirements.empty());
out.resize(requirements.size());
out.resize(requirements.size()+1);
// Create buffers
VkMemoryRequirements memRequirements = {0, 0, UINT32_MAX};
std::vector<std::pair<VkDeviceSize, VkDeviceSize>> ranges;
ranges.resize(requirements.size());
std::vector<VkDeviceSize> sizes;
sizes.resize(requirements.size());
for (size_t i = 0; i < requirements.size(); i++) {
VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
@ -124,14 +94,14 @@ Allocator::memory_ptr Allocator::createBuffers(const std::vector<buffer_requirem
if (vkCreateBuffer(device, &bufferInfo, ALLOC, &out[i].buffer) != VK_SUCCESS) {
LOG_E("Failed to create buffer");
return get_null_ptr();
return GetNull();
}
VkMemoryRequirements individualMemRequirements;
vkGetBufferMemoryRequirements(device, out[i].buffer, &individualMemRequirements);
memRequirements.alignment = std::max(memRequirements.alignment, individualMemRequirements.alignment);
memRequirements.memoryTypeBits &= individualMemRequirements.memoryTypeBits;
ranges[i].first = individualMemRequirements.size;
sizes[i] = individualMemRequirements.size;
}
// Align blocks
@ -140,24 +110,25 @@ Allocator::memory_ptr Allocator::createBuffers(const std::vector<buffer_requirem
return offset;
return offset + memRequirements.alignment - (offset % memRequirements.alignment);
};
ranges[0].second = 0;
for (size_t i = 1; i < requirements.size(); i++) {
ranges[i].second = aligned(ranges[i-1].second + ranges[i-1].first);
out[0].offset = 0;
for (size_t i = 1; i < out.size(); i++) {
out[i].offset = aligned(out[i-1].offset + sizes[i-1]);
}
memRequirements.size = aligned(ranges.back().second + ranges.back().first);
memRequirements.size = out.back().offset;
out.pop_back();
// Bind memory
if (auto memory = allocate(memRequirements, properties)) {
for (size_t i = 0; i < requirements.size(); i++) {
if (vkBindBufferMemory(device, out[i].buffer, memory->ref, memory->offset + ranges[i].second) != VK_SUCCESS) {
if (vkBindBufferMemory(device, out[i].buffer, memory->ref, memory->offset + out[i].offset) != VK_SUCCESS) {
LOG_E("Failed to bind buffer");
return get_null_ptr();
return GetNull();
}
}
return memory;
}
LOG_E("Failed to allocate buffers");
return get_null_ptr();
return GetNull();
}
Allocator::memory_ptr Allocator::allocate(VkMemoryRequirements requirements, VkMemoryPropertyFlags properties) {
@ -172,13 +143,13 @@ Allocator::memory_ptr Allocator::allocate(VkMemoryRequirements requirements, VkM
allocInfo.memoryTypeIndex = memIdx.value();
} else {
LOG_E("No suitable memory heap");
return get_null_ptr();
return GetNull();
}
VkDeviceMemory memory;
if (vkAllocateMemory(device, &allocInfo, ALLOC, &memory) != VK_SUCCESS) {
LOG_E("Failed to allocate memory!");
return get_null_ptr();
return GetNull();
}
void *ptr = nullptr;

View File

@ -43,6 +43,7 @@ public:
struct buffer_info {
VkBuffer buffer = nullptr;
VkDeviceSize offset = 0;
};
memory_ptr createBuffer(VkDeviceSize, VkMemoryPropertyFlags, VkBufferUsageFlags, buffer_info&);
struct buffer_requirement {
@ -55,9 +56,10 @@ public:
void copyBuffer(buffer_info srcBuffer, buffer_info dstBuffer, VkDeviceSize size);
std::pair<VkBuffer, VkBuffer> getBuffer() { return {vertexBuffer.buffer, indexBuffer.buffer}; }
void setTracyZone(const char* name);
static memory_ptr GetNull();
private:
std::optional<uint32_t> findMemory(uint32_t, VkMemoryPropertyFlags, VkDeviceSize size = 0) const;
@ -84,9 +86,6 @@ private:
VkCommandBuffer transferBuffer; // MAYBE: parallel upload
TracyVkCtx tracyCtx;
buffer_info vertexBuffer;
buffer_info indexBuffer;
memory_ptr indexedBufferMemory;
std::vector<std::unique_ptr<Allocation>> allocations;
};
}

View File

@ -1,14 +1,16 @@
#include "CommandCenter.hpp"
#include "PhysicalDeviceInfo.hpp"
#include "Pipeline.hpp"
#include "../Renderer.hpp"
#include "buffer/VertexData.hpp"
using namespace render::vk;
CommandCenter::CommandCenter(VkDevice device, const std::vector<VkImageView> &views, PipelineRef pipe,
std::pair<VkBuffer, VkBuffer> buffer, const PhysicalDeviceInfo &info, const renderOptions &opt) : device(device) {
{
CommandCenter::CommandCenter(VkDevice device, Allocator& alloc, const std::vector<VkImageView> &views,
const Pipeline& pipe, const PhysicalDeviceInfo &info, const renderOptions &opt):
device(device), indexedBufferMemory(Allocator::GetNull()), uniformBuffersMemory(Allocator::GetNull()) {
{ // Graphics command pool
vkGetDeviceQueue(device, info.queueIndices.graphicsFamily.value(), 0, &graphicsQueue);
VkCommandPoolCreateInfo poolInfo{};
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
@ -19,16 +21,47 @@ CommandCenter::CommandCenter(VkDevice device, const std::vector<VkImageView> &vi
FATAL("Failed to create graphics pool!");
}
}
{ // Vertex buffers (const)
size_t vertexSize = sizeof(buffer::vk::vertices[0]) * buffer::vk::vertices.size();
size_t indexSize = sizeof(buffer::vk::indices[0]) * buffer::vk::indices.size();
size_t stagingSize = std::max(vertexSize, indexSize);
Allocator::buffer_info stagingBuffer;
if(auto stagingMemory = alloc.createBuffer(stagingSize, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, stagingBuffer)) {
if(std::vector<Allocator::buffer_info> out; indexedBufferMemory = alloc.createBuffers({
{indexSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT},
{vertexSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT}
}, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, out)) {
indexBuffer = out[0];
vertexBuffer = out[1];
} else {
FATAL("Cannot allocate buffer memory");
}
allocate(views, pipe, buffer, info.swapDetails.capabilities.currentExtent, opt);
stagingMemory->write(buffer::vk::vertices.data(), vertexSize);
alloc.copyBuffer(stagingBuffer, vertexBuffer, vertexSize);
stagingMemory->write(buffer::vk::indices.data(), indexSize);
alloc.copyBuffer(stagingBuffer, indexBuffer, indexSize);
vkDestroyBuffer(device, stagingBuffer.buffer, ALLOC); //TODO: move to buffer
} else {
FATAL("Cannot allocate staging memory");
}
}
allocate(alloc, views, pipe, info.swapDetails.capabilities.currentExtent, opt);
}
CommandCenter::~CommandCenter() {
if(!freed)
free();
vkDestroyBuffer(device, indexBuffer.buffer, ALLOC);
vkDestroyBuffer(device, vertexBuffer.buffer, ALLOC);
indexedBufferMemory.reset();
vkDestroyCommandPool(device, graphicsPool, ALLOC);
}
void CommandCenter::allocate(const std::vector<VkImageView>& views, PipelineRef pipe, std::pair<VkBuffer, VkBuffer> buffer, VkExtent2D extent,
#include <glm/gtc/matrix_transform.hpp>
void CommandCenter::allocate(Allocator& alloc, const std::vector<VkImageView>& views, const Pipeline& pipe, VkExtent2D extent,
const renderOptions& opt)
{
assert(freed);
@ -40,7 +73,7 @@ void CommandCenter::allocate(const std::vector<VkImageView>& views, PipelineRef
VkFramebufferCreateInfo framebufferInfo{};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.renderPass = pipe.first;
framebufferInfo.renderPass = pipe.getRenderPass();
framebufferInfo.attachmentCount = 1;
framebufferInfo.pAttachments = attachments;
framebufferInfo.width = extent.width;
@ -52,6 +85,68 @@ void CommandCenter::allocate(const std::vector<VkImageView>& views, PipelineRef
}
}
{ // Uniform buffers
VkDeviceSize bufferSize = sizeof(buffer::vk::UniformBufferObject);
std::vector<Allocator::buffer_requirement> requirements;
requirements.resize(framebuffers.size(), Allocator::buffer_requirement{bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT});
uniformBuffersMemory = alloc.createBuffers(requirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, uniformBuffers);
if (!uniformBuffersMemory) {
FATAL("Failed to allocate UBO");
}
}
{ // Descriptor pool
VkDescriptorPoolSize poolSize{};
poolSize.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
poolSize.descriptorCount = framebuffers.size();
VkDescriptorPoolCreateInfo poolInfo{};
poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
poolInfo.poolSizeCount = 1;
poolInfo.pPoolSizes = &poolSize;
poolInfo.maxSets = framebuffers.size();
poolInfo.flags = 0; //VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT
if (vkCreateDescriptorPool(device, &poolInfo, nullptr, &descriptorPool) != VK_SUCCESS) {
FATAL("Failed to create descriptor pool!");
}
}
{ // Descriptor sets
std::vector<VkDescriptorSetLayout> layouts(framebuffers.size(), pipe.getDescriptorSet());
VkDescriptorSetAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocInfo.descriptorPool = descriptorPool;
allocInfo.descriptorSetCount = framebuffers.size();
allocInfo.pSetLayouts = layouts.data();
descriptorSets.resize(framebuffers.size());
if (vkAllocateDescriptorSets(device, &allocInfo, descriptorSets.data()) != VK_SUCCESS) {
FATAL("Failed to allocate descriptor sets!");
}
for (size_t i = 0; i < descriptorSets.size(); i++) {
VkDescriptorBufferInfo bufferInfo{};
bufferInfo.buffer = uniformBuffers[i].buffer;
bufferInfo.offset = 0;
bufferInfo.range = sizeof(buffer::vk::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;
descriptorWrite.pTexelBufferView = nullptr;
vkUpdateDescriptorSets(device, 1, &descriptorWrite, 0, nullptr);
}
}
{
graphicsBuffers.resize(framebuffers.size());
VkCommandBufferAllocateInfo allocInfo{};
@ -77,7 +172,7 @@ void CommandCenter::allocate(const std::vector<VkImageView>& views, PipelineRef
VkRenderPassBeginInfo renderPassInfo{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassInfo.renderPass = pipe.first;
renderPassInfo.renderPass = pipe.getRenderPass();
renderPassInfo.framebuffer = framebuffers[i];
renderPassInfo.renderArea.offset = {0, 0};
renderPassInfo.renderArea.extent = extent;
@ -87,11 +182,12 @@ void CommandCenter::allocate(const std::vector<VkImageView>& views, PipelineRef
renderPassInfo.pClearValues = &clearColor;
vkCmdBeginRenderPass(graphicsBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(graphicsBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.second);
VkBuffer vertexBuffers[] = {buffer.first};
vkCmdBindPipeline(graphicsBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.getPipeline());
VkBuffer vertexBuffers[] = {vertexBuffer.buffer};
VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(graphicsBuffers[i], 0, 1, vertexBuffers, offsets);
vkCmdBindIndexBuffer(graphicsBuffers[i], buffer.second, 0, VK_INDEX_TYPE_UINT16);
vkCmdBindIndexBuffer(graphicsBuffers[i], indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT16);
vkCmdBindDescriptorSets(graphicsBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.getLayout(), 0, 1, &descriptorSets[i], 0, nullptr);
vkCmdDrawIndexed(graphicsBuffers[i], static_cast<uint32_t>(buffer::vk::indices.size()), 1, 0, 0, 0);
vkCmdEndRenderPass(graphicsBuffers[i]);
@ -100,19 +196,46 @@ void CommandCenter::allocate(const std::vector<VkImageView>& views, PipelineRef
}
}
proj = glm::perspective(glm::radians(45.0f), extent.width / (float) extent.height, 0.1f, 10.0f);
proj[1][1] *= -1;
freed = false;
}
void CommandCenter::free() {
assert(!freed);
vkFreeCommandBuffers(device, graphicsPool, static_cast<uint32_t>(graphicsBuffers.size()), graphicsBuffers.data());
vkDestroyDescriptorPool(device, descriptorPool, nullptr);
for (size_t i = 0; i < uniformBuffers.size(); i++) {
vkDestroyBuffer(device, uniformBuffers[i].buffer, ALLOC);
}
uniformBuffersMemory.reset();
for (size_t i = 0; i < framebuffers.size(); i++) {
vkDestroyFramebuffer(device, framebuffers[i], nullptr);
}
vkFreeCommandBuffers(device, graphicsPool, static_cast<uint32_t>(graphicsBuffers.size()), graphicsBuffers.data());
freed = true;
}
#include <chrono>
#include <memory.h>
void CommandCenter::updateUBO(uint32_t idx) {
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();
buffer::vk::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 = proj;
memcpy(uniformBuffersMemory->ptr + uniformBuffers[idx].offset, &ubo, sizeof(ubo));
}
void CommandCenter::submitGraphics(uint32_t idx, VkSemaphore waitSemaphore, VkSemaphore signalSemaphore, VkFence submittedFence) {
assert(!freed);

View File

@ -2,6 +2,8 @@
#include "forward.hpp"
#include <vector>
#include "Allocator.hpp"
#include <glm/mat4x4.hpp>
namespace render::vk {
class SwapChain;
@ -9,12 +11,13 @@ class Pipeline;
class CommandCenter {
public:
CommandCenter(VkDevice, const std::vector<VkImageView>&, PipelineRef, std::pair<VkBuffer, VkBuffer>, const PhysicalDeviceInfo&, const renderOptions&);
CommandCenter(VkDevice, Allocator&, const std::vector<VkImageView>&, const Pipeline&, const PhysicalDeviceInfo&, const renderOptions&);
~CommandCenter();
void updateUBO(uint32_t idx);
void submitGraphics(uint32_t, VkSemaphore, VkSemaphore, VkFence);
void allocate(const std::vector<VkImageView> &, PipelineRef, std::pair<VkBuffer, VkBuffer>, VkExtent2D, const renderOptions&);
void allocate(Allocator&, const std::vector<VkImageView> &, const Pipeline&, VkExtent2D, const renderOptions&);
void free();
private:
@ -26,6 +29,17 @@ private:
VkCommandPool graphicsPool;
std::vector<VkCommandBuffer> graphicsBuffers;
VkDescriptorPool descriptorPool;
std::vector<VkDescriptorSet> descriptorSets;
Allocator::buffer_info vertexBuffer;
Allocator::buffer_info indexBuffer;
Allocator::memory_ptr indexedBufferMemory;
glm::mat4 proj;
std::vector<Allocator::buffer_info> uniformBuffers;
Allocator::memory_ptr uniformBuffersMemory;
bool freed = true;
};
}

View File

@ -57,11 +57,22 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
FATAL("Failed to create render pass!");
}
}
{
VkDescriptorSetLayoutCreateInfo layoutInfo{};
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layoutInfo.bindingCount = 1;
std::vector<VkDescriptorSetLayoutBinding> bindings = {buffer::vk::UniformBufferObject::getLayoutBinding()};
layoutInfo.pBindings = bindings.data();
if (vkCreateDescriptorSetLayout(device, &layoutInfo, ALLOC, &descriptorSetLayout) != VK_SUCCESS) {
FATAL("Failed to create descriptor set layout!");
}
}
{
VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = 0; // TODO: setup layouts
pipelineLayoutInfo.pSetLayouts = nullptr;
pipelineLayoutInfo.setLayoutCount = 1;
pipelineLayoutInfo.pSetLayouts = &descriptorSetLayout;
pipelineLayoutInfo.pushConstantRangeCount = 0;
pipelineLayoutInfo.pPushConstantRanges = nullptr;
@ -151,7 +162,7 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
rasterizer.polygonMode = options.wireframe ? VK_POLYGON_MODE_LINE : VK_POLYGON_MODE_FILL;
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;
rasterizer.depthBiasClamp = 0.0f;
@ -235,6 +246,7 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
Pipeline::~Pipeline() {
vkDestroyPipeline(device, graphicsPipeline, ALLOC);
vkDestroyPipelineLayout(device, pipelineLayout, ALLOC);
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, ALLOC);
vkDestroyRenderPass(device, renderPass, ALLOC);
vkDestroyShaderModule(device, fsShader, ALLOC);

View File

@ -9,7 +9,10 @@ public:
Pipeline(VkDevice, const PhysicalDeviceInfo&, const renderOptions&);
~Pipeline();
PipelineRef getRef() { return std::make_pair(renderPass, graphicsPipeline); }
constexpr VkRenderPass getRenderPass() const { return renderPass; }
constexpr VkPipeline getPipeline() const { return graphicsPipeline; }
constexpr VkPipelineLayout getLayout() const { return pipelineLayout; }
constexpr VkDescriptorSetLayout getDescriptorSet() const { return descriptorSetLayout; }
private:
VkDevice device;
@ -18,6 +21,7 @@ private:
VkShaderModule fsShader;
VkRenderPass renderPass;
VkDescriptorSetLayout descriptorSetLayout;
VkPipelineLayout pipelineLayout;
VkPipeline graphicsPipeline;
};

View File

@ -27,7 +27,7 @@ Renderer::Renderer(VkInstance instance, VkDevice device, const PhysicalDeviceInf
allocator = std::make_unique<Allocator>(device, *physicalInfo.get());
swapChain = std::make_unique<SwapChain>(device, *physicalInfo.get());
pipeline = std::make_unique<Pipeline>(device, *physicalInfo.get(), options);
commandCenter = std::make_unique<CommandCenter>(device, swapChain->getImageViews(), pipeline->getRef(), allocator->getBuffer(), *physicalInfo.get(), options);
commandCenter = std::make_unique<CommandCenter>(device, *allocator.get(), swapChain->getImageViews(), *pipeline.get(), *physicalInfo.get(), options);
{
imageAvailableSemaphores.resize(opt.inFlightFrames);
@ -78,7 +78,7 @@ void Renderer::recreateSwapChain() {
set_current_extent(physicalInfo->swapDetails.capabilities, physicalInfo->window);
swapChain = std::make_unique<SwapChain>(device, *physicalInfo.get());
pipeline = std::make_unique<Pipeline>(device, *physicalInfo.get(), options);
commandCenter->allocate(swapChain->getImageViews(), pipeline->getRef(), allocator->getBuffer(), physicalInfo->swapDetails.capabilities.currentExtent, options);
commandCenter->allocate(*allocator.get(), swapChain->getImageViews(), *pipeline.get(), physicalInfo->swapDetails.capabilities.currentExtent, options);
}
void Renderer::destroySwapChain() {
commandCenter->free();
@ -342,9 +342,9 @@ void Renderer::beginFrame() {
std::function<buffer::params(glm::mat4)> Renderer::beginWorldPass() {
assert(currentImage < swapChain->getImageViews().size());
commandCenter->updateUBO(currentImage);
commandCenter->submitGraphics(currentImage, imageAvailableSemaphores[currentFrame],
renderFinishedSemaphores[currentFrame], inFlightFences[currentFrame]);
/*WorldPass->useIt();
WorldPass->start(this);*/
return [&](glm::mat4) {

View File

@ -42,4 +42,21 @@ const std::vector<uint16_t> indices = {
0, 1, 2, 2, 3, 0
};
struct UniformBufferObject {
alignas(16) glm::mat4 model;
alignas(16) glm::mat4 view;
alignas(16) glm::mat4 proj;
static VkDescriptorSetLayoutBinding getLayoutBinding() {
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;
return uboLayoutBinding;
}
};
}

View File

@ -1,10 +1,8 @@
#pragma once
#include <volk.h>
#include <tuple>
namespace render { struct renderOptions; }
namespace render::vk {
struct PhysicalDeviceInfo;
using PipelineRef = std::pair<VkRenderPass, VkPipeline>;
constexpr VkAllocationCallbacks *ALLOC = nullptr;
}