still working on code refactoring

This commit is contained in:
2024-04-23 22:59:33 +02:00
parent ace4c98945
commit 1d9a51e4f7
16 changed files with 560 additions and 518 deletions

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/01/23 18:40:44 by maldavid #+# #+# */
/* Updated: 2024/04/23 19:50:06 by maldavid ### ########.fr */
/* Updated: 2024/04/23 21:17:39 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -24,9 +24,9 @@ namespace mlx
void DescriptorSet::Init(NonOwningPtr<Renderer> renderer, NonOwningPtr<DescriptorPool> pool, DescriptorSetLayout layout)
{
MLX_PROFILE_FUNCTION();
m_renderer = renderer;
p_renderer = renderer;
m_layout = layout;
m_pool = pool;
p_pool = pool;
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
m_desc_set[i] = pool->AllocateDescriptorSet(layout);
@@ -79,29 +79,34 @@ namespace mlx
vkUpdateDescriptorSets(device, 1, &descriptor_write, 0, nullptr);
}
void DescriptorSet::Bind() noexcept
{
vkCmdBindDescriptorSets(p_renderer->GetActiveCmdBuffer().Get(), VK_PIPELINE_BIND_POINT_GRAPHICS, p_renderer->GetPipeline().GetPipelineLayout(), 0, 1, m_desc_set[p_renderer->GetActiveImageIndex()], 0, nullptr);
}
DescriptorSet DescriptorSet::Duplicate()
{
MLX_PROFILE_FUNCTION();
DescriptorSet set;
set.Init(m_renderer, &RenderCore::Get().GetDescriptorPool(), m_layout);
set.Init(p_renderer, &RenderCore::Get().GetDescriptorPool(), m_layout);
return set;
}
VkDescriptorSet& DescriptorSet::operator()() noexcept
{
return m_desc_set[m_renderer->GetActiveImageIndex()];
return m_desc_set[p_renderer->GetActiveImageIndex()];
}
VkDescriptorSet& DescriptorSet::Get() noexcept
{
return m_desc_set[m_renderer->GetActiveImageIndex()];
return m_desc_set[p_renderer->GetActiveImageIndex()];
}
void DescriptorSet::Destroy() noexcept
{
MLX_PROFILE_FUNCTION();
if(m_pool != nullptr && RenderCore::Get().IsInit()) // checks if the render core is still init (it should always be init but just in case)
m_pool->FreeDescriptor(*this);
if(p_pool != nullptr && RenderCore::Get().IsInit()) // checks if the render core is still init (it should always be init but just in case)
p_pool->FreeDescriptor(*this);
for(auto& set : m_desc_set)
{
if(set != VK_NULL_HANDLE)

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/03/31 18:03:35 by maldavid #+# #+# */
/* Updated: 2024/04/23 20:59:20 by maldavid ### ########.fr */
/* Updated: 2024/04/23 21:52:23 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -27,30 +27,30 @@
namespace mlx
{
void Texture::create(std::uint8_t* pixels, std::uint32_t width, std::uint32_t height, VkFormat format, const char* name, bool dedicated_memory)
void Texture::Create(std::uint8_t* pixels, std::uint32_t width, std::uint32_t height, VkFormat format, const char* name, bool dedicated_memory)
{
MLX_PROFILE_FUNCTION();
Image::create(width, height, format, TILING, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, name, dedicated_memory);
Image::createImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT);
Image::createSampler();
transitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
Image::Create(width, height, format, TILING, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, name, dedicated_memory);
Image::CreateImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT);
Image::CreateSampler();
TransitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
std::vector<Vertex> vertexData = {
std::vector<Vertex> vertex_data = {
{{0, 0}, {1.f, 1.f, 1.f, 1.f}, {0.0f, 0.0f}},
{{width, 0}, {1.f, 1.f, 1.f, 1.f}, {1.0f, 0.0f}},
{{width, height}, {1.f, 1.f, 1.f, 1.f}, {1.0f, 1.0f}},
{{0, height}, {1.f, 1.f, 1.f, 1.f}, {0.0f, 1.0f}}
};
std::vector<std::uint16_t> indexData = { 0, 1, 2, 2, 3, 0 };
std::vector<std::uint16_t> index_data = { 0, 1, 2, 2, 3, 0 };
#ifdef DEBUG
_vbo.create(sizeof(Vertex) * vertexData.size(), vertexData.data(), name);
_ibo.create(sizeof(std::uint16_t) * indexData.size(), indexData.data(), name);
_name = name;
m_vbo.Create(sizeof(Vertex) * vertex_data.size(), vertex_data.data(), name);
m_ibo.Create(sizeof(std::uint16_t) * index_data.size(), index_data.data(), name);
m_name = name;
#else
_vbo.create(sizeof(Vertex) * vertexData.size(), vertexData.data(), nullptr);
_ibo.create(sizeof(std::uint16_t) * indexData.size(), indexData.data(), nullptr);
m_vbo.Create(sizeof(Vertex) * vertex_data.size(), vertex_data.data(), nullptr);
m_ibo.Create(sizeof(std::uint16_t) * index_data.size(), index_data.data(), nullptr);
#endif
Buffer staging_buffer;
@@ -58,43 +58,43 @@ namespace mlx
if(pixels != nullptr)
{
#ifdef DEBUG
staging_buffer.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, name, pixels);
staging_buffer.Create(BufferType::HighDynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, name, pixels);
#else
staging_buffer.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, nullptr, pixels);
staging_buffer.Create(BufferType::HighDynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, nullptr, pixels);
#endif
}
else
{
std::vector<std::uint32_t> default_pixels(width * height, 0x00000000);
#ifdef DEBUG
staging_buffer.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, name, default_pixels.data());
staging_buffer.Create(BufferType::HighDynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, name, default_pixels.data());
#else
staging_buffer.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, nullptr, default_pixels.data());
staging_buffer.Create(BufferType::HighDynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, nullptr, default_pixels.data());
#endif
}
Image::copyFromBuffer(staging_buffer);
staging_buffer.destroy();
Image::CopyFromBuffer(staging_buffer);
staging_buffer.Destroy();
}
void Texture::setPixel(int x, int y, std::uint32_t color) noexcept
void Texture::SetPixel(int x, int y, std::uint32_t color) noexcept
{
MLX_PROFILE_FUNCTION();
if(x < 0 || y < 0 || static_cast<std::uint32_t>(x) > getWidth() || static_cast<std::uint32_t>(y) > getHeight())
if(x < 0 || y < 0 || static_cast<std::uint32_t>(x) > GetWidth() || static_cast<std::uint32_t>(y) > GetHeight())
return;
if(_map == nullptr)
openCPUmap();
_cpu_map[(y * getWidth()) + x] = color;
_has_been_modified = true;
if(m_map == nullptr)
PpenCPUmap();
m_cpu_map[(y * GetWidth()) + x] = color;
m_has_been_modified = true;
}
int Texture::getPixel(int x, int y) noexcept
int Texture::GetPixel(int x, int y) noexcept
{
MLX_PROFILE_FUNCTION();
if(x < 0 || y < 0 || static_cast<std::uint32_t>(x) > getWidth() || static_cast<std::uint32_t>(y) > getHeight())
if(x < 0 || y < 0 || static_cast<std::uint32_t>(x) > GetWidth() || static_cast<std::uint32_t>(y) > GetHeight())
return 0;
if(_map == nullptr)
openCPUmap();
std::uint32_t color = _cpu_map[(y * getWidth()) + x];
if(m_map == nullptr)
OpenCPUmap();
std::uint32_t color = m_cpu_map[(y * GetWidth()) + x];
std::uint8_t* bytes = reinterpret_cast<std::uint8_t*>(&color);
std::uint8_t tmp = bytes[0];
bytes[0] = bytes[2];
@@ -102,86 +102,87 @@ namespace mlx
return *reinterpret_cast<int*>(bytes);
}
void Texture::openCPUmap()
void Texture::OpenCPUmap()
{
MLX_PROFILE_FUNCTION();
if(_map != nullptr)
if(m_map != nullptr)
return;
DebugLog("Texture : enabling CPU mapping");
std::size_t size = GetWidth() * GetHeight() * FormatSize(GetFormat());
m_buf_map.emplace();
#ifdef DEBUG
core::error::report(e_kind::message, "Texture : enabling CPU mapping");
#endif
std::size_t size = getWidth() * getHeight() * formatSize(getFormat());
_buf_map.emplace();
#ifdef DEBUG
_buf_map->create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, _name.c_str());
m_buf_map->Create(BufferType::HighDynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, m_name.c_str());
#else
_buf_map->create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, nullptr);
#endif
Image::copyToBuffer(*_buf_map);
_buf_map->mapMem(&_map);
_cpu_map = std::vector<std::uint32_t>(getWidth() * getHeight(), 0);
std::memcpy(_cpu_map.data(), _map, size);
#ifdef DEBUG
core::error::report(e_kind::message, "Texture : mapped CPU memory using staging buffer");
m_buf_map->Create(BufferType::HighDynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, nullptr);
#endif
Image::CopyToBuffer(*m_buf_map);
m_buf_map->MapMem(&_map);
m_cpu_map = std::vector<std::uint32_t>(GetWidth() * GetHeight(), 0);
std::memcpy(m_cpu_map.data(), m_map, size);
DebugLog("Texture : mapped CPU memory using staging buffer");
}
void Texture::render(std::array<VkDescriptorSet, 2>& sets, Renderer& renderer, int x, int y)
void Texture::Render(Renderer& renderer, int x, int y)
{
MLX_PROFILE_FUNCTION();
if(_has_been_modified)
if(m_has_been_modified)
{
std::memcpy(_map, _cpu_map.data(), _cpu_map.size() * formatSize(getFormat()));
Image::copyFromBuffer(*_buf_map);
_has_been_modified = false;
std::memcpy(m_map, m_cpu_map.data(), m_cpu_map.size() * FormatSize(GetFormat()));
Image::copyFromBuffer(*m_buf_map);
m_has_been_modified = false;
}
if(!_set.isInit())
_set = renderer.getFragDescriptorSet().duplicate();
if(getLayout() != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
transitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
if(!_has_set_been_updated)
updateSet(0);
auto cmd = renderer.getActiveCmdBuffer();
_vbo.bind(renderer);
_ibo.bind(renderer);
if(!m_set.IsInit())
m_set = renderer.GetFragDescriptorSet().Duplicate();
if(GetLayout() != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
TransitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
if(!m_has_set_been_updated)
UpdateSet(0);
auto cmd = renderer.GetActiveCmdBuffer();
m_vbo.bind(renderer);
m_ibo.bind(renderer);
glm::vec2 translate(x, y);
vkCmdPushConstants(cmd.get(), renderer.getPipeline().getPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(translate), &translate);
sets[1] = _set.get();
vkCmdBindDescriptorSets(renderer.getActiveCmdBuffer().get(), VK_PIPELINE_BIND_POINT_GRAPHICS, renderer.getPipeline().getPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr);
vkCmdDrawIndexed(cmd.get(), static_cast<std::uint32_t>(_ibo.getSize() / sizeof(std::uint16_t)), 1, 0, 0, 0);
vkCmdPushConstants(cmd.Get(), renderer.GetPipeline().GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(translate), &translate);
m_set.Bind();
vkCmdDrawIndexed(cmd.Get(), static_cast<std::uint32_t>(m_ibo.GetSize() / sizeof(std::uint16_t)), 1, 0, 0, 0);
}
void Texture::destroy() noexcept
void Texture::Destroy() noexcept
{
MLX_PROFILE_FUNCTION();
Image::destroy();
_set.destroy();
if(_buf_map.has_value())
_buf_map->destroy();
_vbo.destroy();
_ibo.destroy();
Image::Destroy();
m_set.Destroy();
if(m_buf_map.has_value())
m_buf_map->Destroy();
m_vbo.destroy();
m_ibo.destroy();
}
Texture stbTextureLoad(std::filesystem::path file, int* w, int* h)
{
MLX_PROFILE_FUNCTION();
Texture texture;
Texture* texture = new Texture;
int channels;
std::uint8_t* data = nullptr;
std::string filename = file.string();
if(!std::filesystem::exists(std::move(file)))
core::error::report(e_kind::fatal_error, "Image : file not found '%s'", filename.c_str());
{
Error("Image : file not found '%s'", filename.c_str());
return nullptr;
}
if(stbi_is_hdr(filename.c_str()))
core::error::report(e_kind::fatal_error, "Texture : unsupported image format '%s'", filename.c_str());
{
Error("Texture : unsupported image format '%s'", filename.c_str());
return nullptr;
}
int dummy_w;
int dummy_h;
data = stbi_load(filename.c_str(), (w == nullptr ? &dummy_w : w), (h == nullptr ? &dummy_h : h), &channels, 4);
#ifdef DEBUG
texture.create(data, (w == nullptr ? dummy_w : *w), (h == nullptr ? dummy_h : *h), VK_FORMAT_R8G8B8A8_UNORM, filename.c_str());
texture->Create(data, (w == nullptr ? dummy_w : *w), (h == nullptr ? dummy_h : *h), VK_FORMAT_R8G8B8A8_UNORM, filename.c_str());
#else
texture.create(data, (w == nullptr ? dummy_w : *w), (h == nullptr ? dummy_h : *h), VK_FORMAT_R8G8B8A8_UNORM, nullptr);
texture->Create(data, (w == nullptr ? dummy_w : *w), (h == nullptr ? dummy_h : *h), VK_FORMAT_R8G8B8A8_UNORM, nullptr);
#endif
stbi_image_free(data);
return texture;

View File

@@ -1,18 +1,18 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* texture_atlas.cpp :+: :+: :+: */
/* TextureAtlas.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/07 16:40:09 by maldavid #+# #+# */
/* Updated: 2024/03/25 19:03:13 by maldavid ### ########.fr */
/* Updated: 2024/04/23 21:54:05 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <pre_compiled.h>
#include <PreCompiled.h>
#include <renderer/images/texture_atlas.h>
#include <Renderer/Images/TextureAtlas.h>
#ifdef IMAGE_OPTIMIZED
#define TILING VK_IMAGE_TILING_OPTIMAL
@@ -22,37 +22,37 @@
namespace mlx
{
void TextureAtlas::create(std::uint8_t* pixels, std::uint32_t width, std::uint32_t height, VkFormat format, const char* name, bool dedicated_memory)
void TextureAtlas::Create(std::uint8_t* pixels, std::uint32_t width, std::uint32_t height, VkFormat format, const char* name, bool dedicated_memory)
{
Image::create(width, height, format, TILING, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, name, dedicated_memory);
Image::createImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT);
Image::createSampler();
transitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
Image::Create(width, height, format, TILING, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, name, dedicated_memory);
Image::CreateImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT);
Image::CreateSampler();
TransitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
if(pixels == nullptr)
{
core::error::report(e_kind::warning, "Renderer : creating an empty texture atlas. They cannot be updated after creation, this might be a mistake or a bug, please report");
Warning("Renderer : creating an empty texture atlas. They cannot be updated after creation, this might be a mistake or a bug, please report");
return;
}
Buffer staging_buffer;
std::size_t size = width * height * formatSize(format);
staging_buffer.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, name, pixels);
Image::copyFromBuffer(staging_buffer);
staging_buffer.destroy();
std::size_t size = width * height * FormatSize(format);
staging_buffer.Create(BufferType::HighDynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, name, pixels);
Image::CopyFromBuffer(staging_buffer);
staging_buffer.Destroy();
}
void TextureAtlas::render(Renderer& renderer, int x, int y, std::uint32_t ibo_size) const
void TextureAtlas::Render(Renderer& renderer, int x, int y, std::uint32_t ibo_size) const
{
auto cmd = renderer.getActiveCmdBuffer().get();
auto cmd = renderer.GetActiveCmdBuffer().Get();
glm::vec2 translate(x, y);
vkCmdPushConstants(cmd, renderer.getPipeline().getPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(translate), &translate);
vkCmdPushConstants(cmd, renderer.GetPipeline().GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(translate), &translate);
vkCmdDrawIndexed(cmd, ibo_size / sizeof(std::uint16_t), 1, 0, 0, 0);
}
void TextureAtlas::destroy() noexcept
void TextureAtlas::Destroy() noexcept
{
Image::destroy();
_set.destroy();
Image::Destroy();
m_set.Destroy();
}
}

View File

@@ -1,21 +1,21 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* pipeline.cpp :+: :+: :+: */
/* Pipeline.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/18 21:27:38 by maldavid #+# #+# */
/* Updated: 2024/03/25 19:03:31 by maldavid ### ########.fr */
/* Updated: 2024/04/23 22:24:13 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <pre_compiled.h>
#include <PreCompiled.h>
#include "pipeline.h"
#include <renderer/renderer.h>
#include <renderer/core/render_core.h>
#include <renderer/descriptors/vk_descriptor_set_layout.h>
#include <Renderer/Pipelines/Pipeline.h>
#include <Renderer/Renderer.h>
#include <Renderer/Core/RenderCore.h>
#include <Renderer/Descriptors/DescriptorSetLayout.h>
namespace mlx
{
@@ -26,19 +26,23 @@ namespace mlx
layout(location = 1) in vec4 aColor;
layout(location = 2) in vec2 aUV;
layout(set = 0, binding = 0) uniform uProjection {
layout(set = 0, binding = 0) uniform uProjection
{
mat4 mat;
} uProj;
layout(push_constant) uniform uModelPushConstant {
layout(push_constant) uniform uModelPushConstant
{
vec2 vec;
} uTranslate;
out gl_PerVertex {
out gl_PerVertex
{
vec4 gl_Position;
};
layout(location = 0) out struct {
layout(location = 0) out struct
{
vec4 Color;
vec2 UV;
} Out;
@@ -113,7 +117,8 @@ namespace mlx
layout(set = 1, binding = 0) uniform sampler2D sTexture;
layout(location = 0) in struct {
layout(location = 0) in struct
{
vec4 Color;
vec2 UV;
} In;
@@ -162,83 +167,83 @@ namespace mlx
0x000100fd,0x00010038
};
void GraphicPipeline::init(Renderer& renderer)
void GraphicPipeline::Init(Renderer& renderer)
{
VkShaderModuleCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
createInfo.codeSize = vertex_shader.size() * sizeof(std::uint32_t);
createInfo.pCode = vertex_shader.data();
VkShaderModuleCreateInfo create_info{};
create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
create_info.codeSize = vertex_shader.size() * sizeof(std::uint32_t);
create_info.pCode = vertex_shader.data();
VkShaderModule vshader;
if(vkCreateShaderModule(Render_Core::get().getDevice().get(), &createInfo, nullptr, &vshader) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a vertex shader module");
if(vkCreateShaderModule(RenderCore::Get().GetDevice().Get(), &create_info, nullptr, &vshader) != VK_SUCCESS)
FatalError("Vulkan : failed to create a vertex shader module");
VkPushConstantRange push_constant;
push_constant.offset = 0;
push_constant.size = sizeof(glm::vec2);
push_constant.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
createInfo.codeSize = fragment_shader.size() * sizeof(std::uint32_t);
createInfo.pCode = fragment_shader.data();
create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
create_info.codeSize = fragment_shader.size() * sizeof(std::uint32_t);
create_info.pCode = fragment_shader.data();
VkShaderModule fshader;
if(vkCreateShaderModule(Render_Core::get().getDevice().get(), &createInfo, nullptr, &fshader) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a fragment shader module");
if(vkCreateShaderModule(RenderCore::Get().GetDevice().Get(), &create_info, nullptr, &fshader) != VK_SUCCESS)
FatalError("Vulkan : failed to create a fragment shader module");
VkPipelineShaderStageCreateInfo vertShaderStageInfo{};
vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
vertShaderStageInfo.module = vshader;
vertShaderStageInfo.pName = "main";
VkPipelineShaderStageCreateInfo vert_shader_stage_info{};
vert_shader_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
vert_shader_stage_info.stage = VK_SHADER_STAGE_VERTEX_BIT;
vert_shader_stage_info.module = vshader;
vert_shader_stage_info.pName = "main";
VkPipelineShaderStageCreateInfo fragShaderStageInfo{};
fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
fragShaderStageInfo.module = fshader;
fragShaderStageInfo.pName = "main";
VkPipelineShaderStageCreateInfo frag_shader_stage_info{};
frag_shader_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
frag_shader_stage_info.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
frag_shader_stage_info.module = fshader;
frag_shader_stage_info.pName = "main";
std::array<VkPipelineShaderStageCreateInfo, 2> stages = {vertShaderStageInfo, fragShaderStageInfo};
std::array<VkPipelineShaderStageCreateInfo, 2> stages = { vert_shader_stage_info, frag_shader_stage_info };
auto bindingDescription = Vertex::getBindingDescription();
auto attributeDescriptions = Vertex::getAttributeDescriptions();
auto binding_description = Vertex::GetBindingDescription();
auto attribute_descriptions = Vertex::GetAttributeDescriptions();
VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo{};
vertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertexInputStateCreateInfo.vertexBindingDescriptionCount = 1;
vertexInputStateCreateInfo.pVertexBindingDescriptions = &bindingDescription;
vertexInputStateCreateInfo.vertexAttributeDescriptionCount = static_cast<std::uint32_t>(attributeDescriptions.size());
vertexInputStateCreateInfo.pVertexAttributeDescriptions = attributeDescriptions.data();
VkPipelineVertexInputStateCreateInfo vertex_input_state_create_info{};
vertex_input_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertex_input_state_create_info.vertexBindingDescriptionCount = 1;
vertex_input_state_create_info.pVertexBindingDescriptions = &binding_description;
vertex_input_state_create_info.vertexAttributeDescriptionCount = static_cast<std::uint32_t>(attribute_descriptions.size());
vertex_input_state_create_info.pVertexAttributeDescriptions = attribute_descriptions.data();
VkPipelineInputAssemblyStateCreateInfo inputAssembly{};
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
inputAssembly.primitiveRestartEnable = VK_FALSE;
VkPipelineInputAssemblyStateCreateInfo input_assembly{};
input_assembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
input_assembly.primitiveRestartEnable = VK_FALSE;
VkDynamicState states[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
constexpr std::size_t statesCount = sizeof(states) / sizeof(VkDynamicState);
VkPipelineDynamicStateCreateInfo dynamicStates{};
dynamicStates.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
dynamicStates.dynamicStateCount = statesCount;
dynamicStates.pDynamicStates = states;
constexpr std::size_t states_count = sizeof(states) / sizeof(VkDynamicState);
VkPipelineDynamicStateCreateInfo dynamic_states{};
dynamic_states.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
dynamic_states.dynamicStateCount = states_count;
dynamic_states.pDynamicStates = states;
VkViewport viewport{};
viewport.x = 0.0f;
viewport.y = 0.0f;
viewport.width = (float)renderer.getFrameBuffer(0).getWidth();
viewport.height = (float)renderer.getFrameBuffer(0).getHeight();
viewport.width = (float)renderer.GetFrameBuffer(0).GetWidth();
viewport.height = (float)renderer.GetFrameBuffer(0).GetHeight();
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
VkRect2D scissor{};
scissor.offset = { 0, 0 };
scissor.extent = { renderer.getFrameBuffer(0).getWidth(), renderer.getFrameBuffer(0).getHeight()};
scissor.extent = { renderer.GetFrameBuffer(0).GetWidth(), renderer.GetFrameBuffer(0).GetHeight()};
VkPipelineViewportStateCreateInfo viewportState{};
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
viewportState.viewportCount = 1;
viewportState.pViewports = &viewport;
viewportState.scissorCount = 1;
viewportState.pScissors = &scissor;
VkPipelineViewportStateCreateInfo viewport_state{};
viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
viewport_state.viewportCount = 1;
viewport_state.pViewports = &viewport;
viewport_state.scissorCount = 1;
viewport_state.pScissors = &scissor;
VkPipelineRasterizationStateCreateInfo rasterizer{};
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
@@ -255,76 +260,72 @@ namespace mlx
multisampling.sampleShadingEnable = VK_FALSE;
multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
VkPipelineColorBlendAttachmentState colorBlendAttachment{};
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
colorBlendAttachment.blendEnable = VK_TRUE;
colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
VkPipelineColorBlendAttachmentState color_blend_attachment{};
color_blend_attachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
color_blend_attachment.blendEnable = VK_TRUE;
color_blend_attachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
color_blend_attachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
color_blend_attachment.colorBlendOp = VK_BLEND_OP_ADD;
color_blend_attachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
color_blend_attachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
color_blend_attachment.alphaBlendOp = VK_BLEND_OP_ADD;
VkPipelineColorBlendStateCreateInfo colorBlending{};
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
colorBlending.logicOpEnable = VK_FALSE;
colorBlending.logicOp = VK_LOGIC_OP_COPY;
colorBlending.attachmentCount = 1;
colorBlending.pAttachments = &colorBlendAttachment;
colorBlending.blendConstants[0] = 1.0f;
colorBlending.blendConstants[1] = 1.0f;
colorBlending.blendConstants[2] = 1.0f;
colorBlending.blendConstants[3] = 1.0f;
VkPipelineColorBlendStateCreateInfo color_blending{};
color_blending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
color_blending.logicOpEnable = VK_FALSE;
color_blending.logicOp = VK_LOGIC_OP_COPY;
color_blending.attachmentCount = 1;
color_blending.pAttachments = &color_blend_attachment;
color_blending.blendConstants[0] = 1.0f;
color_blending.blendConstants[1] = 1.0f;
color_blending.blendConstants[2] = 1.0f;
color_blending.blendConstants[3] = 1.0f;
VkDescriptorSetLayout layouts[] = {
renderer.getVertDescriptorSetLayout().get(),
renderer.getFragDescriptorSetLayout().get()
renderer.GetVertDescriptorSet().GetLayout(),
renderer.GetFragDescriptorSet().GetLayout()
};
VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = 2;
pipelineLayoutInfo.pSetLayouts = layouts;
pipelineLayoutInfo.pushConstantRangeCount = 1;
pipelineLayoutInfo.pPushConstantRanges = &push_constant;
VkPipelineLayoutCreateInfo pipeline_layout_info{};
pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipeline_layout_info.setLayoutCount = 2;
pipeline_layout_info.pSetLayouts = layouts;
pipeline_layout_info.pushConstantRangeCount = 1;
pipeline_layout_info.pPushConstantRanges = &push_constant;
if(vkCreatePipelineLayout(Render_Core::get().getDevice().get(), &pipelineLayoutInfo, nullptr, &_pipeline_layout) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a graphics pipeline layout");
if(vkCreatePipelineLayout(RenderCore::Get().GetDevice().Get(), &pipeline_layout_info, nullptr, &m_pipeline_layout) != VK_SUCCESS)
FatalError("Vulkan : failed to create a graphics pipeline layout");
VkGraphicsPipelineCreateInfo pipelineInfo{};
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipelineInfo.stageCount = stages.size();
pipelineInfo.pStages = stages.data();
pipelineInfo.pVertexInputState = &vertexInputStateCreateInfo;
pipelineInfo.pInputAssemblyState = &inputAssembly;
pipelineInfo.pViewportState = &viewportState;
pipelineInfo.pRasterizationState = &rasterizer;
pipelineInfo.pMultisampleState = &multisampling;
pipelineInfo.pColorBlendState = &colorBlending;
pipelineInfo.pDynamicState = &dynamicStates;
pipelineInfo.layout = _pipeline_layout;
pipelineInfo.renderPass = renderer.getRenderPass().get();
pipelineInfo.subpass = 0;
pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
VkGraphicsPipelineCreateInfo pipeline_info{};
pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipeline_info.stageCount = stages.size();
pipeline_info.pStages = stages.data();
pipeline_info.pVertexInputState = &vertex_input_state_create_info;
pipeline_info.pInputAssemblyState = &input_assembly;
pipeline_info.pViewportState = &viewport_state;
pipeline_info.pRasterizationState = &rasterizer;
pipeline_info.pMultisampleState = &multisampling;
pipeline_info.pColorBlendState = &color_blending;
pipeline_info.pDynamicState = &dynamic_states;
pipeline_info.layout = m_pipeline_layout;
pipeline_info.renderPass = renderer.GetRenderPass().Get();
pipeline_info.subpass = 0;
pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
VkResult res = vkCreateGraphicsPipelines(Render_Core::get().getDevice().get(), VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &_graphics_pipeline);
VkResult res = vkCreateGraphicsPipelines(RenderCore::Get().GetDevice().Get(), VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &m_graphics_pipeline);
if(res != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a graphics pipeline, %s", RCore::verbaliseResultVk(res));
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : created new graphic pipeline");
#endif
FatalError("Vulkan : failed to create a graphics pipeline, %", VerbaliseVkResult(res));
DebugLog("Vulkan : created new graphic pipeline");
vkDestroyShaderModule(Render_Core::get().getDevice().get(), fshader, nullptr);
vkDestroyShaderModule(Render_Core::get().getDevice().get(), vshader, nullptr);
vkDestroyShaderModule(RenderCore::Get().GetDevice().Get(), fshader, nullptr);
vkDestroyShaderModule(RenderCore::Get().GetDevice().Get(), vshader, nullptr);
}
void GraphicPipeline::destroy() noexcept
void GraphicPipeline::Destroy() noexcept
{
vkDestroyPipeline(Render_Core::get().getDevice().get(), _graphics_pipeline, nullptr);
vkDestroyPipelineLayout(Render_Core::get().getDevice().get(), _pipeline_layout, nullptr);
_graphics_pipeline = VK_NULL_HANDLE;
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : destroyed a graphics pipeline");
#endif
vkDestroyPipeline(RenderCore::Get().GetDevice().Get(), m_graphics_pipeline, nullptr);
vkDestroyPipelineLayout(RenderCore::Get().GetDevice().Get(), m_pipeline_layout, nullptr);
m_graphics_pipeline = VK_NULL_HANDLE;
DebugLog("Vulkan : destroyed a graphics pipeline");
}
}

View File

@@ -1,53 +1,49 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* vk_framebuffer.cpp :+: :+: :+: */
/* Framebuffer.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:18:06 by maldavid #+# #+# */
/* Updated: 2024/03/25 19:03:35 by maldavid ### ########.fr */
/* Updated: 2024/04/23 22:28:07 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <pre_compiled.h>
#include <PreCompiled.h>
#include <renderer/core/render_core.h>
#include <renderer/renderer.h>
#include <renderer/images/vk_image.h>
#include <Renderer/Core/RenderCore.h>
#include <Renderer/Renderer.h>
#include <Renderer/Images/Image.h>
namespace mlx
{
void FrameBuffer::init(RenderPass& renderpass, Image& image)
void FrameBuffer::Init(RenderPass& renderpass, Image& image)
{
VkImageView attachments[] = { image.getImageView() };
VkImageView attachments[] = { image.GetImageView() };
_width = image.getWidth();
_height = image.getHeight();
m_width = image.GetWidth();
m_height = image.GetHeight();
VkFramebufferCreateInfo framebufferInfo{};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.renderPass = renderpass.get();
framebufferInfo.attachmentCount = 1;
framebufferInfo.pAttachments = attachments;
framebufferInfo.width = _width;
framebufferInfo.height = _height;
framebufferInfo.layers = 1;
VkFramebufferCreateInfo framebuffer_info{};
framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebuffer_info.renderPass = renderpass.get();
framebuffer_info.attachmentCount = 1;
framebuffer_info.pAttachments = attachments;
framebuffer_info.width = _width;
framebuffer_info.height = _height;
framebuffer_info.layers = 1;
VkResult res = vkCreateFramebuffer(Render_Core::get().getDevice().get(), &framebufferInfo, nullptr, &_framebuffer);
VkResult res = vkCreateFramebuffer(RenderCore::Get().GetDevice().Get(), &framebuffer_info, nullptr, &m_framebuffer);
if(res != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a framebuffer, %s", RCore::verbaliseResultVk(res));
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : created new framebuffer");
#endif
FatalError("Vulkan : failed to create a framebuffer, %s", RCore::verbaliseResultVk(res));
DebugLog("Vulkan : created new framebuffer");
}
void FrameBuffer::destroy() noexcept
void FrameBuffer::Destroy() noexcept
{
vkDestroyFramebuffer(Render_Core::get().getDevice().get(), _framebuffer, nullptr);
_framebuffer = VK_NULL_HANDLE;
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : destroyed a framebuffer");
#endif
vkDestroyFramebuffer(RenderCore::Get().GetDevice().Get(), m_framebuffer, nullptr);
m_framebuffer = VK_NULL_HANDLE;
DebugLog("Vulkan : destroyed a framebuffer");
}
}

View File

@@ -1,12 +1,12 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* vk_render_pass.cpp :+: :+: :+: */
/* Renderpass.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:21:36 by maldavid #+# #+# */
/* Updated: 2024/03/25 19:03:37 by maldavid ### ########.fr */
/* Updated: 2024/04/23 22:31:09 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -20,21 +20,21 @@
namespace mlx
{
static const VkClearValue clearColor = {{{ 0.f, 0.f, 0.f, 1.0f }}}; // wtf, this mess to satisfy a warning
static const VkClearValue clear_color = {{{ 0.f, 0.f, 0.f, 1.0f }}}; // wtf, this mess to satisfy a warning
void RenderPass::init(VkFormat attachement_format, VkImageLayout layout)
void RenderPass::Init(VkFormat attachement_format, VkImageLayout layout)
{
VkAttachmentDescription colorAttachment{};
colorAttachment.format = attachement_format;
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
colorAttachment.finalLayout = layout;
VkAttachmentDescription color_attachment{};
color_attachment.format = attachement_format;
color_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
color_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
color_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
color_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
color_attachment.finalLayout = layout;
VkAttachmentReference colorAttachmentRef{};
VkAttachmentReference color_attachment_ref{};
colorAttachmentRef.attachment = 0;
colorAttachmentRef.layout = (layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : layout);
@@ -45,77 +45,73 @@ namespace mlx
VkSubpassDescription subpasses[] = { subpass1 };
std::vector<VkSubpassDependency> subpassesDeps;
subpassesDeps.emplace_back();
subpassesDeps.back().srcSubpass = VK_SUBPASS_EXTERNAL;
subpassesDeps.back().dstSubpass = 0;
subpassesDeps.back().srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
subpassesDeps.back().dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subpassesDeps.back().srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
subpassesDeps.back().dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
subpassesDeps.back().dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
std::vector<VkSubpassDependency> subpasses_deps;
subpasses_deps.emplace_back();
subpasses_deps.back().srcSubpass = VK_SUBPASS_EXTERNAL;
subpasses_deps.back().dstSubpass = 0;
subpasses_deps.back().srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
subpasses_deps.back().dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subpasses_deps.back().srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
subpasses_deps.back().dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
subpasses_deps.back().dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
subpassesDeps.emplace_back();
subpassesDeps.back().srcSubpass = 0;
subpassesDeps.back().dstSubpass = VK_SUBPASS_EXTERNAL;
subpassesDeps.back().srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subpassesDeps.back().dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
subpassesDeps.back().srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
subpassesDeps.back().dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
subpassesDeps.back().dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
subpasses_deps.emplace_back();
subpasses_deps.back().srcSubpass = 0;
subpasses_deps.back().dstSubpass = VK_SUBPASS_EXTERNAL;
subpasses_deps.back().srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subpasses_deps.back().dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
subpasses_deps.back().srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
subpasses_deps.back().dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
subpasses_deps.back().dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
VkRenderPassCreateInfo renderPassInfo{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassInfo.attachmentCount = 1;
renderPassInfo.pAttachments = &colorAttachment;
renderPassInfo.subpassCount = sizeof(subpasses) / sizeof(VkSubpassDescription);
renderPassInfo.pSubpasses = subpasses;
renderPassInfo.dependencyCount = static_cast<std::uint32_t>(subpassesDeps.size());
renderPassInfo.pDependencies = subpassesDeps.data();
VkRenderPassCreateInfo render_pass_info{};
render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
render_pass_info.attachmentCount = 1;
render_pass_info.pAttachments = &color_attachment;
render_pass_info.subpassCount = sizeof(subpasses) / sizeof(VkSubpassDescription);
render_pass_info.pSubpasses = subpasses;
render_pass_info.dependencyCount = static_cast<std::uint32_t>(subpasses_deps.size());
render_pass_info.pDependencies = subpasses_deps.data();
VkResult res = vkCreateRenderPass(Render_Core::get().getDevice().get(), &renderPassInfo, nullptr, &_render_pass);
VkResult res = vkCreateRenderPass(RenderCore::Get().GetDevice().Get(), &render_pass_info, nullptr, &m_render_pass);
if(res != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create render pass, %s", RCore::verbaliseResultVk(res));
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : created new render pass");
#endif
FatalError("Vulkan : failed to create render pass, %", VerbaliseVkResult(res));
DebugLog("Vulkan : created new render pass");
}
void RenderPass::begin(class CmdBuffer& cmd, class FrameBuffer& fb)
void RenderPass::Begin(class CommandBuffer& cmd, class FrameBuffer& fb)
{
MLX_PROFILE_FUNCTION();
if(_is_running)
if(m_is_running)
return;
VkRenderPassBeginInfo renderPassInfo{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassInfo.renderPass = _render_pass;
renderPassInfo.framebuffer = fb.get();
renderPassInfo.renderArea.offset = { 0, 0 };
renderPassInfo.renderArea.extent = { fb.getWidth(), fb.getHeight() };
renderPassInfo.clearValueCount = 1;
renderPassInfo.pClearValues = &clearColor;
VkRenderPassBeginInfo render_pass_info{};
render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
render_pass_info.renderPass = m_render_pass;
render_pass_info.framebuffer = fb.Get();
render_pass_info.renderArea.offset = { 0, 0 };
render_pass_info.renderArea.extent = { fb.GetWidth(), fb.GetHeight() };
render_pass_info.clearValueCount = 1;
render_pass_info.pClearValues = &clear_color;
vkCmdBeginRenderPass(cmd.get(), &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdBeginRenderPass(cmd.Get(), &render_pass_info, VK_SUBPASS_CONTENTS_INLINE);
_is_running = true;
m_is_running = true;
}
void RenderPass::end(class CmdBuffer& cmd)
void RenderPass::End(class CommandBuffer& cmd)
{
MLX_PROFILE_FUNCTION();
if(!_is_running)
if(!m_is_running)
return;
vkCmdEndRenderPass(cmd.get());
_is_running = false;
vkCmdEndRenderPass(cmdd.Get());
m_is_running = false;
}
void RenderPass::destroy() noexcept
void RenderPass::Destroy() noexcept
{
vkDestroyRenderPass(Render_Core::get().getDevice().get(), _render_pass, nullptr);
_render_pass = VK_NULL_HANDLE;
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : destroyed a renderpass");
#endif
vkDestroyRenderPass(RenderCore::Get().GetDevice().Get(), m_render_pass, nullptr);
m_render_pass = VK_NULL_HANDLE;
DebugLog("Vulkan : destroyed a renderpass");
}
}

View File

@@ -1,152 +1,150 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* vk_swapchain.cpp :+: :+: :+: */
/* Swapchain.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:22:28 by maldavid #+# #+# */
/* Updated: 2024/03/25 23:09:33 by maldavid ### ########.fr */
/* Updated: 2024/04/23 22:43:10 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <pre_compiled.h>
#include <PreCompiled.h>
#include <renderer/core/render_core.h>
#include <renderer/renderer.h>
#include <platform/window.h>
#include <Renderer/Core/RenderCore.h>
#include <Renderer/Renderer.h>
#include <Platform/Window.h>
namespace mlx
{
void SwapChain::init(Renderer* renderer)
void SwapChain::Init(NonOwningPtr<Renderer> renderer)
{
VkDevice device = Render_Core::get().getDevice().get();
VkDevice device = RenderCore::get().GetDevice().Get();
_renderer = renderer;
_swapchain_support = querySwapChainSupport(Render_Core::get().getDevice().getPhysicalDevice());
m_renderer = renderer;
m_swapchain_support = QuerySwapChainSupport(RenderCore::Get().GetDevice().GetPhysicalDevice());
VkSurfaceFormatKHR surfaceFormat = renderer->getSurface().chooseSwapSurfaceFormat(_swapchain_support.formats);
VkPresentModeKHR presentMode = chooseSwapPresentMode(_swapchain_support.present_modes);
_extent = chooseSwapExtent(_swapchain_support.capabilities);
VkSurfaceFormatKHR surface_format = renderer->GetSurface().ChooseSwapSurfaceFormat(m_swapchain_support.formats);
VkPresentModeKHR present_mode = ChooseSwapPresentMode(m_swapchain_support.present_modes);
m_extent = ChooseSwapExtent(m_swapchain_support.capabilities);
std::uint32_t imageCount = _swapchain_support.capabilities.minImageCount + 1;
if(_swapchain_support.capabilities.maxImageCount > 0 && imageCount > _swapchain_support.capabilities.maxImageCount)
imageCount = _swapchain_support.capabilities.maxImageCount;
std::uint32_t image_count = m_swapchain_support.capabilities.minImageCount + 1;
if(m_swapchain_support.capabilities.maxImageCount > 0 && image_count > m_swapchain_support.capabilities.maxImageCount)
image_count = m_swapchain_support.capabilities.maxImageCount;
Queues::QueueFamilyIndices indices = Render_Core::get().getQueue().findQueueFamilies(Render_Core::get().getDevice().getPhysicalDevice());
std::uint32_t queueFamilyIndices[] = { indices.graphics_family.value(), indices.present_family.value() };
Queues::QueueFamilyIndices indices = RenderCore::Get().GetQueue().FindQueueFamilies(RenderCore::Get().GetDevice().GetPhysicalDevice());
std::uint32_t queue_family_indices[] = { indices.graphics_family.value(), indices.present_family.value() };
VkSwapchainCreateInfoKHR createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
createInfo.surface = renderer->getSurface().get();
createInfo.minImageCount = imageCount;
createInfo.imageFormat = surfaceFormat.format;
createInfo.imageColorSpace = surfaceFormat.colorSpace;
createInfo.imageExtent = _extent;
createInfo.imageArrayLayers = 1;
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
createInfo.preTransform = _swapchain_support.capabilities.currentTransform;
createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
createInfo.presentMode = presentMode;
createInfo.clipped = VK_TRUE;
createInfo.oldSwapchain = VK_NULL_HANDLE;
VkSwapchainCreateInfoKHR create_info{};
create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
create_info.surface = renderer->GetSurface().Get();
create_info.minImageCount = image_count;
create_info.imageFormat = surface_format.format;
create_info.imageColorSpace = surface_format.colorSpace;
create_info.imageExtent = m_extent;
create_info.imageArrayLayers = 1;
create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
create_info.preTransform = m_swapchain_support.capabilities.currentTransform;
create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
create_info.presentMode = present_mode;
create_info.clipped = VK_TRUE;
create_info.oldSwapchain = VK_NULL_HANDLE;
if(indices.graphics_family != indices.present_family)
{
createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
createInfo.queueFamilyIndexCount = 2;
createInfo.pQueueFamilyIndices = queueFamilyIndices;
create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
create_info.queueFamilyIndexCount = 2;
create_info.pQueueFamilyIndices = queue_family_indices;
}
else
createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
VkResult res = vkCreateSwapchainKHR(device, &createInfo, nullptr, &_swapchain);
VkResult res = vkCreateSwapchainKHR(device, &create_info, nullptr, &m_swapchain);
if(res != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create the swapchain, %s", RCore::verbaliseResultVk(res));
FatalError("Vulkan : failed to create the swapchain, %", VerbaliseVkResult(res));
std::vector<VkImage> tmp;
vkGetSwapchainImagesKHR(device, _swapchain, &imageCount, nullptr);
_images.resize(imageCount);
tmp.resize(imageCount);
vkGetSwapchainImagesKHR(device, _swapchain, &imageCount, tmp.data());
vkGetSwapchainImagesKHR(device, m_swapchain, &image_count, nullptr);
m_images.resize(image_count);
tmp.resize(image_count);
vkGetSwapchainImagesKHR(device, m_swapchain, &image_count, tmp.data());
for(std::size_t i = 0; i < imageCount; i++)
for(std::size_t i = 0; i < image_count; i++)
{
_images[i].create(tmp[i], surfaceFormat.format, _extent.width, _extent.height);
_images[i].transitionLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
_images[i].createImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT);
m_images[i].Create(tmp[i], surface_format.format, m_extent.width, m_extent.height);
m_images[i].TransitionLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
m_images[i].CreateImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT);
}
_swapchain_image_format = surfaceFormat.format;
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : created new swapchain");
#endif
m_swapchain_image_format = surface_format.format;
DebugLog("Vulkan : created new swapchain");
}
SwapChain::SwapChainSupportDetails SwapChain::querySwapChainSupport(VkPhysicalDevice device)
SwapChain::SwapChainSupportDetails SwapChain::QuerySwapChainSupport(VkPhysicalDevice device)
{
SwapChain::SwapChainSupportDetails details;
VkSurfaceKHR surface = _renderer->getSurface().get();
VkSurfaceKHR surface = m_renderer->GetSurface().Get();
if(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &details.capabilities) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : unable to retrieve surface capabilities");
FatalError("Vulkan : unable to retrieve surface capabilities");
std::uint32_t formatCount = 0;
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr);
std::uint32_t format_count = 0;
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &format_count, nullptr);
if(formatCount != 0)
if(format_count != 0)
{
details.formats.resize(formatCount);
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, details.formats.data());
details.formats.resize(format_count);
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &format_count, details.formats.data());
}
std::uint32_t presentModeCount;
vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, nullptr);
std::uint32_t present_mode_count;
vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &present_mode_count, nullptr);
if(presentModeCount != 0)
if(present_mode_count != 0)
{
details.present_modes.resize(presentModeCount);
vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, details.present_modes.data());
details.present_modes.resize(present_mode_count);
vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &present_mode_count, details.present_modes.data());
}
return details;
}
VkPresentModeKHR SwapChain::chooseSwapPresentMode([[maybe_unused]] const std::vector<VkPresentModeKHR>& availablePresentModes)
VkPresentModeKHR SwapChain::chooseSwapPresentMode([[maybe_unused]] const std::vector<VkPresentModeKHR>& available_present_modes)
{
// in the future, you may choose to activate vsync or not
return VK_PRESENT_MODE_IMMEDIATE_KHR;
}
VkExtent2D SwapChain::chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities)
VkExtent2D SwapChain::ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities)
{
if(capabilities.currentExtent.width != std::numeric_limits<std::uint32_t>::max())
return capabilities.currentExtent;
int width, height;
glfwGetFramebufferSize(_renderer->getWindow()->getNativeWindow(), &width, &height);
glfwGetFramebufferSize(m_renderer->GetWindow()->GetNativeWindow(), &width, &height);
VkExtent2D actualExtent = { static_cast<std::uint32_t>(width), static_cast<std::uint32_t>(height) };
VkExtent2D actual_extent = { static_cast<std::uint32_t>(width), static_cast<std::uint32_t>(height) };
actualExtent.width = std::clamp(actualExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
actualExtent.height = std::clamp(actualExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
actual_extent.width = std::clamp(actual_extent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
actual_extent.height = std::clamp(actual_extent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
return actualExtent;
return actual_extent;
}
void SwapChain::recreate()
void SwapChain::Recreate()
{
destroy();
init(_renderer);
Destroy();
Init(m_renderer);
}
void SwapChain::destroy() noexcept
void SwapChain::Destroy() noexcept
{
if(_swapchain == VK_NULL_HANDLE)
if(m_swapchain == VK_NULL_HANDLE)
return;
vkDeviceWaitIdle(Render_Core::get().getDevice().get());
vkDestroySwapchainKHR(Render_Core::get().getDevice().get(), _swapchain, nullptr);
_swapchain = VK_NULL_HANDLE;
for(Image& img : _images)
img.destroyImageView();
vkDeviceWaitIdle(RenderCore::Get().GetDevice().Get());
vkDestroySwapchainKHR(RenderCore::Get().GetDevice().Get(), m_swapchain, nullptr);
m_swapchain = VK_NULL_HANDLE;
for(Image& img : m_images)
img.DestroyImageView();
}
}

View File

@@ -1,48 +1,47 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* font.cpp :+: :+: :+: */
/* Font.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/12/11 22:06:09 by kbz_8 #+# #+# */
/* Updated: 2024/03/25 19:03:54 by maldavid ### ########.fr */
/* Updated: 2024/04/23 22:48:30 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <pre_compiled.h>
#include <PreCompiled.h>
#include <renderer/texts/font.h>
#include <renderer/renderer.h>
#include <core/profiler.h>
#include <Renderer/Texts/Font.h>
#include <Renderer/Renderer.h>
constexpr const int RANGE = 1024;
namespace mlx
{
Font::Font(Renderer& renderer, const std::filesystem::path& path, float scale) : _name(path.string()), _renderer(renderer), _scale(scale)
Font::Font(Renderer& renderer, const std::filesystem::path& path, float scale) : m_name(path.string()), m_renderer(renderer), m_scale(scale)
{
_build_data = path;
m_build_data = path;
}
Font::Font(class Renderer& renderer, const std::string& name, const std::vector<std::uint8_t>& ttf_data, float scale) : _name(name), _renderer(renderer), _scale(scale)
Font::Font(class Renderer& renderer, const std::string& name, const std::vector<std::uint8_t>& ttf_data, float scale) : m_name(name), m_renderer(renderer), m_scale(scale)
{
_build_data = ttf_data;
m_build_data = ttf_data;
}
void Font::buildFont()
void Font::BuildFont()
{
MLX_PROFILE_FUNCTION();
std::vector<std::uint8_t> file_bytes;
if(std::holds_alternative<std::filesystem::path>(_build_data))
if(std::holds_alternative<std::filesystem::path>(m_build_data))
{
std::ifstream file(std::get<std::filesystem::path>(_build_data), std::ios::binary);
std::ifstream file(std::get<std::filesystem::path>(m_build_data), std::ios::binary);
if(!file.is_open())
{
core::error::report(e_kind::error, "Font load : cannot open font file, %s", _name.c_str());
Error("Font load : cannot open font file, %", m_name.c_str());
return;
}
std::ifstream::pos_type fileSize = std::filesystem::file_size(std::get<std::filesystem::path>(_build_data));
std::ifstream::pos_type fileSize = std::filesystem::file_size(std::get<std::filesystem::path>(m_build_data));
file.seekg(0, std::ios::beg);
file_bytes.resize(fileSize);
file.read(reinterpret_cast<char*>(file_bytes.data()), fileSize);
@@ -53,10 +52,10 @@ namespace mlx
std::vector<std::uint8_t> vulkan_bitmap(RANGE * RANGE * 4);
stbtt_pack_context pc;
stbtt_PackBegin(&pc, tmp_bitmap.data(), RANGE, RANGE, RANGE, 1, nullptr);
if(std::holds_alternative<std::filesystem::path>(_build_data))
stbtt_PackFontRange(&pc, file_bytes.data(), 0, _scale, 32, 96, _cdata.data());
if(std::holds_alternative<std::filesystem::path>(m_build_data))
stbtt_PackFontRange(&pc, file_bytes.data(), 0, m_scale, 32, 96, m_cdata.data());
else
stbtt_PackFontRange(&pc, std::get<std::vector<std::uint8_t>>(_build_data).data(), 0, _scale, 32, 96, _cdata.data());
stbtt_PackFontRange(&pc, std::get<std::vector<std::uint8_t>>(m_build_data).data(), 0, m_scale, 32, 96, m_cdata.data());
stbtt_PackEnd(&pc);
for(int i = 0, j = 0; i < RANGE * RANGE; i++, j += 4)
{
@@ -66,24 +65,24 @@ namespace mlx
vulkan_bitmap[j + 3] = tmp_bitmap[i];
}
#ifdef DEBUG
_atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, std::string(_name + "_font_altas").c_str(), true);
m_atlas.Create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, std::string(m_name + "_font_altas").c_str(), true);
#else
_atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, nullptr, true);
m_atlas.Create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, nullptr, true);
#endif
_atlas.setDescriptor(_renderer.getFragDescriptorSet().duplicate());
_is_init = true;
m_atlas.SetDescriptor(m_renderer.GetFragDescriptorSet().Duplicate());
m_is_init = true;
}
void Font::destroy()
void Font::Destroy()
{
MLX_PROFILE_FUNCTION();
_atlas.destroy();
_is_init = false;
m_atlas.Destroy();
m_is_init = false;
}
Font::~Font()
{
if(_is_init)
if(m_is_init)
destroy();
}
}

View File

@@ -1,16 +1,16 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* font_library.cpp :+: :+: :+: */
/* FontLibrary.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/18 09:28:14 by maldavid #+# #+# */
/* Updated: 2024/03/25 19:03:57 by maldavid ### ########.fr */
/* Updated: 2024/04/23 22:59:16 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <pre_compiled.h>
#include <PreCompiled.h>
#include <renderer/texts/font_library.h>
#include <renderer/texts/font.h>