Skip to content

Commit

Permalink
Feat: Calculate uniform buffer size
Browse files Browse the repository at this point in the history
  • Loading branch information
brenocq committed Dec 9, 2023
1 parent fa47c9d commit c3853ff
Show file tree
Hide file tree
Showing 12 changed files with 243 additions and 240 deletions.
2 changes: 1 addition & 1 deletion src/atta/graphics/apis/vulkan/descriptorPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ DescriptorPool::DescriptorPool(std::vector<DescriptorSetLayout::Binding> descrip
for (auto binding : descriptorBindings)
poolSizes.push_back(VkDescriptorPoolSize{binding.type, static_cast<uint32_t>(binding.descriptorCount * maxSets)});

VkDescriptorPoolCreateInfo poolInfo = {};
VkDescriptorPoolCreateInfo poolInfo{};
poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
poolInfo.poolSizeCount = static_cast<uint32_t>(poolSizes.size());
poolInfo.pPoolSizes = poolSizes.data();
Expand Down
64 changes: 29 additions & 35 deletions src/atta/graphics/apis/vulkan/pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,12 @@

namespace atta::graphics::vk {

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

Pipeline::Pipeline(const gfx::Pipeline::CreateInfo& info) : gfx::Pipeline(info), _device(common::getDevice()) {
// Create framebuffer
_framebuffers.push_back(std::dynamic_pointer_cast<vk::Framebuffer>(_renderPass->getFramebuffer()));

// Uniform buffers
_uniformBuffer = std::make_shared<UniformBuffer>(sizeof(UniformBufferObject));
_uniformBuffer = std::make_shared<UniformBuffer>(_shader->getUniformBufferLayout().getStride());

// Vertex input
BufferLayout layout = _shader->getVertexBufferLayout();
Expand Down Expand Up @@ -122,7 +116,7 @@ Pipeline::Pipeline(const gfx::Pipeline::CreateInfo& info) : gfx::Pipeline(info),

// Descriptor set layout
std::vector<DescriptorSetLayout::Binding> bindings;
bindings.push_back({0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT});
bindings.push_back({0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT});
_descriptorSetLayout = std::make_shared<DescriptorSetLayout>(bindings);

// Pipeline layout
Expand Down Expand Up @@ -165,39 +159,39 @@ Pipeline::~Pipeline() {

void Pipeline::begin() {
// Bind
VkCommandBuffer commandBuffer = common::getCommandBuffers()->getCurrent();
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, _pipeline);

// Viewport
VkViewport viewport{};
viewport.x = 0.0f;
viewport.y = 0.0f;
viewport.width = _renderPass->getFramebuffer()->getWidth();
viewport.height = _renderPass->getFramebuffer()->getHeight();
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);

// Scissor
VkRect2D scissor{};
scissor.offset = {0, 0};
scissor.extent = {(uint32_t)viewport.width, (uint32_t)viewport.height};
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);

_descriptorSets->bind(0);
// VkCommandBuffer commandBuffer = common::getCommandBuffers()->getCurrent();
// vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, _pipeline);

//// Viewport
// VkViewport viewport{};
// viewport.x = 0.0f;
// viewport.y = 0.0f;
// viewport.width = _renderPass->getFramebuffer()->getWidth();
// viewport.height = _renderPass->getFramebuffer()->getHeight();
// viewport.minDepth = 0.0f;
// viewport.maxDepth = 1.0f;
// vkCmdSetViewport(commandBuffer, 0, 1, &viewport);

//// Scissor
// VkRect2D scissor{};
// scissor.offset = {0, 0};
// scissor.extent = {(uint32_t)viewport.width, (uint32_t)viewport.height};
// vkCmdSetScissor(commandBuffer, 0, 1, &scissor);

//_descriptorSets->bind(0);
}

void Pipeline::end() {
//---------- Update uniform buffers ----------//
//---------- TODO Update uniform buffers ----------//
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 = mat4(1.0f);
ubo.model.mat[3][0] = time * 0.1f;
ubo.view = mat4(1.0f);
ubo.proj = mat4(1.0f);
memcpy(_uniformBuffer->getMappedData(), &ubo, sizeof(ubo));
// UniformBufferObject ubo{};
// ubo.model = mat4(1.0f);
// ubo.model.mat[3][0] = time * 0.1f;
// ubo.view = mat4(1.0f);
// ubo.proj = mat4(1.0f);
// memcpy(_uniformBuffer->getMappedData(), &ubo, sizeof(ubo));
}
void* Pipeline::getImGuiTexture() const { return nullptr; }

Expand Down
34 changes: 1 addition & 33 deletions src/atta/graphics/apis/vulkan/shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ void Shader::setCubemap(const char* name, std::shared_ptr<gfx::Image> image) {}
std::vector<VkPipelineShaderStageCreateInfo> Shader::getShaderStages() const {
std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
for (auto& [type, shader] : _shaders) {
VkPipelineShaderStageCreateInfo shaderStageInfo;
VkPipelineShaderStageCreateInfo shaderStageInfo{};
shaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shaderStageInfo.module = shader;
shaderStageInfo.pName = "main";
Expand Down Expand Up @@ -126,15 +126,13 @@ void Shader::compile() {
if (file.is_open()) {
file << shaderCode.apiCode;
file.close();
LOG_DEBUG("shader", "Saved $0 code", in);
} else {
LOG_ERROR("gfx::vk::Shader", "Failed to save shader code to [w]$0[] when compiling [w]$1[]", in, _file.string());
continue;
}

// Compile shader
fs::path out = in.string() + ".spv";
LOG_DEBUG("Shader", "in $0 out $1", in, out);
if (!runCommand("glslc " + in.string() + " -o " + out.string()))
return;

Expand All @@ -155,36 +153,6 @@ void Shader::compile() {

void Shader::bind() {}

VkShaderModule Shader::getHandle() const {
// TODO
return {};
}

VkPipelineShaderStageCreateInfo Shader::getShaderStage() const {
// VkShaderStageFlagBits stage = convertFileToShaderStage(_filepath);

VkPipelineShaderStageCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
// createInfo.stage = stage;
// createInfo.module = _shader;
createInfo.pName = "main";

return createInfo;
}

VkShaderStageFlagBits Shader::convertFileToShaderStage(const fs::path& filepath) {
// std::string extension = filepath.extension().string();
// if (extension == ".vert")
// return VK_SHADER_STAGE_VERTEX_BIT;
// if (extension == ".frag")
// return VK_SHADER_STAGE_FRAGMENT_BIT;
// if (extension == ".geom")
// return VK_SHADER_STAGE_GEOMETRY_BIT;
// ASSERT(false, "Unknown shader file format [w]$0[]. Instead of [*w]$1[], it should be [w].vert[], [w].frag[], or [w].geom[]", filepath.string(),
// extension);
return {};
}

bool Shader::runCommand(std::string cmd) {
std::array<char, 512> buffer;

Expand Down
3 changes: 0 additions & 3 deletions src/atta/graphics/apis/vulkan/shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ class Shader final : public gfx::Shader {
Shader(const fs::path& file);
~Shader();

VkShaderModule getHandle() const;
VkPipelineShaderStageCreateInfo getShaderStage() const;

std::string generateApiCode(ShaderType type, std::string iCode) override;
void compile() override;
void bind() override;
Expand Down
65 changes: 52 additions & 13 deletions src/atta/graphics/bufferLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ std::string BufferLayout::Element::typeToString(Type type) { return toStr[(int)t

uint32_t BufferLayout::Element::sizeFromType(Type type) {
switch (type) {
case Type::NONE:
LOG_WARN("gfx::BufferLayout::Element", "Trying to get size of unknown type");
return 0;
case Type::BOOL:
return 4;
case Type::INT:
Expand Down Expand Up @@ -56,8 +53,35 @@ uint32_t BufferLayout::Element::sizeFromType(Type type) {
return 4;
case Type::SAMPLER_CUBE:
return 4;
default:
LOG_WARN("gfx::BufferLayout::Element", "Trying to get size of unknown type");
return 0;
}
return 0;
}

uint32_t BufferLayout::Element::alignmentFromType(Type type) {
switch (type) {
case Type::BOOL:
case Type::SAMPLER_2D:
case Type::SAMPLER_CUBE:
return 1;
case Type::INT:
case Type::UINT:
case Type::FLOAT:
case Type::VEC2:
case Type::VEC3:
case Type::VEC4:
case Type::IVEC2:
case Type::IVEC3:
case Type::IVEC4:
case Type::MAT3:
case Type::MAT4:
return 4;
default:
LOG_WARN("gfx::BufferLayout::Element", "Trying to get alignment of unknown type");
return 0;
}
LOG_WARN("gfx::BufferLayout::Element", "Trying to get size of unknown type");
return 0;
}

Expand Down Expand Up @@ -93,12 +117,9 @@ uint32_t BufferLayout::Element::componentCountFromType(Type type) {
//----------------------------------//
//---------- BufferLayout ----------//
//----------------------------------//
BufferLayout::BufferLayout(const std::initializer_list<Element>& elements) : _elements(elements) {
uint32_t offset = 0;
for (auto& element : _elements) {
element.offset = offset;
offset += element.size;
}
BufferLayout::BufferLayout(const std::initializer_list<Element>& elements) {
for (const auto& element : elements)
push(element.type, element.name);
}

void BufferLayout::push(Element::Type type, std::string name) {
Expand All @@ -108,7 +129,16 @@ void BufferLayout::push(Element::Type type, std::string name) {
e.name = name;
e.type = type;
e.size = Element::sizeFromType(type);
e.offset = getStride();

// Calculate offset in buffer
if (_elements.empty())
e.offset = 0;
else {
uint32_t align = Element::alignmentFromType(type);
uint32_t offset = _elements.back().offset;
e.offset = (offset + align - 1) & ~(align - 1);
}

_elements.push_back(e);
}

Expand All @@ -124,9 +154,18 @@ bool BufferLayout::exists(std::string name) const {
uint32_t BufferLayout::getElementCount() const { return static_cast<uint32_t>(_elements.size()); }

uint32_t BufferLayout::getStride() const {
uint32_t stride = 0;
if (_elements.empty())
return 0;

// Get buffer alignment (largest type alignment)
uint32_t bufferAlignment = 0;
for (auto& element : _elements)
stride += element.size;
bufferAlignment = std::max(bufferAlignment, Element::alignmentFromType(element.type));

// Align buffer
uint32_t stride = _elements.back().offset + _elements.back().size;
stride = (stride + bufferAlignment - 1) & ~(bufferAlignment - 1);

return stride;
}

Expand Down
4 changes: 3 additions & 1 deletion src/atta/graphics/bufferLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class BufferLayout final {
static std::string typeToString(Type type);
/// Type size in bytes
static uint32_t sizeFromType(Type type);
/// Type alignment in bytes
static uint32_t alignmentFromType(Type type);
/// Number of component in the type (FLOAT -> 1, VEC2 -> 2, MAT4 -> 16, ...)
static uint32_t componentCountFromType(Type type);
};
Expand All @@ -48,7 +50,7 @@ class BufferLayout final {
bool exists(std::string name) const;
/// Get number of elements
uint32_t getElementCount() const;
/// Get buffer stride in bytes (sum of the size of all elements)
/// Get buffer stride in bytes (aligned sum of the size of all elements)
uint32_t getStride() const;

private:
Expand Down
Loading

0 comments on commit c3853ff

Please sign in to comment.