mirror of
https://github.com/seekrs/MacroLibX.git
synced 2026-01-11 22:53:34 +00:00
adding debug vulkan resources names
This commit is contained in:
@@ -8,7 +8,7 @@
|
|||||||
Error("invalid window ptr (NULL)"); \
|
Error("invalid window ptr (NULL)"); \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
else if(std::find_if(m_graphics.begin(), m_graphics.end(), [win](const std::unique_ptr<GraphicsSupport>& gs){ return *static_cast<int*>(win) == gs->GetID(); }) != m_graphics.end()) \
|
else if(std::find_if(m_graphics.begin(), m_graphics.end(), [win](const std::unique_ptr<GraphicsSupport>& gs){ return *static_cast<int*>(win) == gs->GetID(); }) == m_graphics.end()) \
|
||||||
{ \
|
{ \
|
||||||
Error("invalid window ptr"); \
|
Error("invalid window ptr"); \
|
||||||
return; \
|
return; \
|
||||||
|
|||||||
@@ -39,10 +39,10 @@ namespace mlx
|
|||||||
{
|
{
|
||||||
Sprite& new_sprite = p_scene->CreateSprite(texture);
|
Sprite& new_sprite = p_scene->CreateSprite(texture);
|
||||||
new_sprite.SetPosition(Vec3f{ static_cast<float>(x), static_cast<float>(y), static_cast<float>(m_current_depth) });
|
new_sprite.SetPosition(Vec3f{ static_cast<float>(x), static_cast<float>(y), static_cast<float>(m_current_depth) });
|
||||||
|
m_current_depth++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sprite->SetPosition(Vec3f{ static_cast<float>(x), static_cast<float>(y), static_cast<float>(m_current_depth) });
|
sprite->SetPosition(Vec3f{ static_cast<float>(x), static_cast<float>(y), static_cast<float>(m_current_depth) });
|
||||||
m_current_depth++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsSupport::LoadFont(const std::filesystem::path& filepath, float scale)
|
void GraphicsSupport::LoadFont(const std::filesystem::path& filepath, float scale)
|
||||||
|
|||||||
@@ -20,12 +20,12 @@ namespace mlx
|
|||||||
{
|
{
|
||||||
CPUBuffer vb(vertices.size() * sizeof(Vertex));
|
CPUBuffer vb(vertices.size() * sizeof(Vertex));
|
||||||
std::memcpy(vb.GetData(), vertices.data(), vb.GetSize());
|
std::memcpy(vb.GetData(), vertices.data(), vb.GetSize());
|
||||||
vbo.Init(vb.GetSize());
|
vbo.Init(vb.GetSize(), 0, "mlx_mesh");
|
||||||
vbo.SetData(std::move(vb));
|
vbo.SetData(std::move(vb));
|
||||||
|
|
||||||
CPUBuffer ib(indices.size() * sizeof(std::uint32_t));
|
CPUBuffer ib(indices.size() * sizeof(std::uint32_t));
|
||||||
std::memcpy(ib.GetData(), indices.data(), ib.GetSize());
|
std::memcpy(ib.GetData(), indices.data(), ib.GetSize());
|
||||||
ibo.Init(ib.GetSize());
|
ibo.Init(ib.GetSize(), 0, "mlx_mesh");
|
||||||
ibo.SetData(std::move(ib));
|
ibo.SetData(std::move(ib));
|
||||||
|
|
||||||
triangle_count = vertices.size() / 3;
|
triangle_count = vertices.size() / 3;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace mlx
|
|||||||
public:
|
public:
|
||||||
GPUBuffer() = default;
|
GPUBuffer() = default;
|
||||||
|
|
||||||
void Init(BufferType type, VkDeviceSize size, VkBufferUsageFlags usage, CPUBuffer data);
|
void Init(BufferType type, VkDeviceSize size, VkBufferUsageFlags usage, CPUBuffer data, std::string_view debug_name);
|
||||||
void Destroy() noexcept;
|
void Destroy() noexcept;
|
||||||
|
|
||||||
bool CopyFrom(const GPUBuffer& buffer) noexcept;
|
bool CopyFrom(const GPUBuffer& buffer) noexcept;
|
||||||
@@ -33,6 +33,9 @@ namespace mlx
|
|||||||
void PushToGPU() noexcept;
|
void PushToGPU() noexcept;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
#ifdef DEBUG
|
||||||
|
std::string m_debug_name;
|
||||||
|
#endif
|
||||||
VkBuffer m_buffer = VK_NULL_HANDLE;
|
VkBuffer m_buffer = VK_NULL_HANDLE;
|
||||||
VmaAllocation m_allocation;
|
VmaAllocation m_allocation;
|
||||||
VkDeviceSize m_offset = 0;
|
VkDeviceSize m_offset = 0;
|
||||||
@@ -40,7 +43,7 @@ namespace mlx
|
|||||||
void* p_map = nullptr;
|
void* p_map = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VmaAllocationCreateInfo alloc_info);
|
void CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VmaAllocationCreateInfo alloc_info, std::string_view debug_name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VkBufferUsageFlags m_usage = 0;
|
VkBufferUsageFlags m_usage = 0;
|
||||||
@@ -49,7 +52,7 @@ namespace mlx
|
|||||||
class VertexBuffer : public GPUBuffer
|
class VertexBuffer : public GPUBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline void Init(std::uint32_t size, VkBufferUsageFlags additional_flags = 0) { GPUBuffer::Init(BufferType::LowDynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | additional_flags, {}); }
|
inline void Init(std::uint32_t size, VkBufferUsageFlags additional_flags, std::string_view debug_name) { GPUBuffer::Init(BufferType::LowDynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | additional_flags, {}, std::move(debug_name)); }
|
||||||
void SetData(CPUBuffer data);
|
void SetData(CPUBuffer data);
|
||||||
inline void Bind(VkCommandBuffer cmd) const noexcept { VkDeviceSize offset = 0; RenderCore::Get().vkCmdBindVertexBuffers(cmd, 0, 1, &m_buffer, &offset); }
|
inline void Bind(VkCommandBuffer cmd) const noexcept { VkDeviceSize offset = 0; RenderCore::Get().vkCmdBindVertexBuffers(cmd, 0, 1, &m_buffer, &offset); }
|
||||||
};
|
};
|
||||||
@@ -57,7 +60,7 @@ namespace mlx
|
|||||||
class IndexBuffer : public GPUBuffer
|
class IndexBuffer : public GPUBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline void Init(std::uint32_t size, VkBufferUsageFlags additional_flags = 0) { GPUBuffer::Init(BufferType::LowDynamic, size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | additional_flags, {}); }
|
inline void Init(std::uint32_t size, VkBufferUsageFlags additional_flags, std::string_view debug_name) { GPUBuffer::Init(BufferType::LowDynamic, size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | additional_flags, {}, std::move(debug_name)); }
|
||||||
void SetData(CPUBuffer data);
|
void SetData(CPUBuffer data);
|
||||||
inline void Bind(VkCommandBuffer cmd) const noexcept { RenderCore::Get().vkCmdBindIndexBuffer(cmd, m_buffer, 0, VK_INDEX_TYPE_UINT32); }
|
inline void Bind(VkCommandBuffer cmd) const noexcept { RenderCore::Get().vkCmdBindIndexBuffer(cmd, m_buffer, 0, VK_INDEX_TYPE_UINT32); }
|
||||||
};
|
};
|
||||||
@@ -65,7 +68,7 @@ namespace mlx
|
|||||||
class UniformBuffer
|
class UniformBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void Init(std::uint32_t size);
|
void Init(std::uint32_t size, std::string_view debug_name);
|
||||||
void SetData(CPUBuffer data, std::size_t frame_index);
|
void SetData(CPUBuffer data, std::size_t frame_index);
|
||||||
void Destroy() noexcept;
|
void Destroy() noexcept;
|
||||||
|
|
||||||
|
|||||||
@@ -14,16 +14,19 @@ namespace mlx
|
|||||||
public:
|
public:
|
||||||
Image() = default;
|
Image() = default;
|
||||||
|
|
||||||
inline void Init(VkImage image, VkFormat format, std::uint32_t width, std::uint32_t height, VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED) noexcept
|
inline void Init(VkImage image, VkFormat format, std::uint32_t width, std::uint32_t height, VkImageLayout layout, std::string_view debug_name) noexcept
|
||||||
{
|
{
|
||||||
m_image = image;
|
m_image = image;
|
||||||
m_format = format;
|
m_format = format;
|
||||||
m_width = width;
|
m_width = width;
|
||||||
m_height = height;
|
m_height = height;
|
||||||
m_layout = layout;
|
m_layout = layout;
|
||||||
|
#ifdef DEBUG
|
||||||
|
m_debug_name = std::move(debug_name);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init(ImageType type, std::uint32_t width, std::uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, bool is_multisampled = false);
|
void Init(ImageType type, std::uint32_t width, std::uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, bool is_multisampled, std::string_view debug_name);
|
||||||
void CreateImageView(VkImageViewType type, VkImageAspectFlags aspectFlags, int layer_count = 1) noexcept;
|
void CreateImageView(VkImageViewType type, VkImageAspectFlags aspectFlags, int layer_count = 1) noexcept;
|
||||||
void CreateSampler() noexcept;
|
void CreateSampler() noexcept;
|
||||||
void TransitionLayout(VkImageLayout new_layout, VkCommandBuffer cmd = VK_NULL_HANDLE);
|
void TransitionLayout(VkImageLayout new_layout, VkCommandBuffer cmd = VK_NULL_HANDLE);
|
||||||
@@ -48,6 +51,9 @@ namespace mlx
|
|||||||
virtual ~Image() = default;
|
virtual ~Image() = default;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
#ifdef DEBUG
|
||||||
|
std::string m_debug_name;
|
||||||
|
#endif
|
||||||
VmaAllocation m_allocation;
|
VmaAllocation m_allocation;
|
||||||
VkImage m_image = VK_NULL_HANDLE;
|
VkImage m_image = VK_NULL_HANDLE;
|
||||||
VkImageView m_image_view = VK_NULL_HANDLE;
|
VkImageView m_image_view = VK_NULL_HANDLE;
|
||||||
@@ -65,11 +71,12 @@ namespace mlx
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DepthImage() = default;
|
DepthImage() = default;
|
||||||
inline void Init(std::uint32_t width, std::uint32_t height, bool is_multisampled = false)
|
inline void Init(std::uint32_t width, std::uint32_t height, bool is_multisampled, std::string_view debug_name)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
std::vector<VkFormat> candidates = { VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT };
|
std::vector<VkFormat> candidates = { VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT };
|
||||||
VkFormat format = kvfFindSupportFormatInCandidates(RenderCore::Get().GetDevice(), candidates.data(), candidates.size(), VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
VkFormat format = kvfFindSupportFormatInCandidates(RenderCore::Get().GetDevice(), candidates.data(), candidates.size(), VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||||
Image::Init(ImageType::Depth, width, height, format, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, is_multisampled);
|
Image::Init(ImageType::Depth, width, height, format, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, is_multisampled, std::move(debug_name));
|
||||||
Image::CreateImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_DEPTH_BIT);
|
Image::CreateImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||||
Image::TransitionLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
Image::TransitionLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||||
}
|
}
|
||||||
@@ -80,33 +87,12 @@ namespace mlx
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Texture() = default;
|
Texture() = default;
|
||||||
Texture(CPUBuffer pixels, std::uint32_t width, std::uint32_t height, VkFormat format = VK_FORMAT_R8G8B8A8_SRGB, bool is_multisampled = false)
|
Texture(CPUBuffer pixels, std::uint32_t width, std::uint32_t height, VkFormat format, bool is_multisampled, std::string_view debug_name)
|
||||||
{
|
{
|
||||||
Init(std::move(pixels), width, height, format, is_multisampled);
|
Init(std::move(pixels), width, height, format, is_multisampled, std::move(debug_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Init(CPUBuffer pixels, std::uint32_t width, std::uint32_t height, VkFormat format = VK_FORMAT_R8G8B8A8_SRGB, bool is_multisampled = false)
|
void Init(CPUBuffer pixels, std::uint32_t width, std::uint32_t height, VkFormat format, bool is_multisampled, std::string_view debug_name);
|
||||||
{
|
|
||||||
Image::Init(ImageType::Color, width, height, format, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, is_multisampled);
|
|
||||||
Image::CreateImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT);
|
|
||||||
Image::CreateSampler();
|
|
||||||
if(pixels)
|
|
||||||
{
|
|
||||||
GPUBuffer staging_buffer;
|
|
||||||
std::size_t size = width * height * kvfFormatSize(format);
|
|
||||||
staging_buffer.Init(BufferType::Staging, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, pixels);
|
|
||||||
VkCommandBuffer cmd = kvfCreateCommandBuffer(RenderCore::Get().GetDevice());
|
|
||||||
kvfBeginCommandBuffer(cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
|
||||||
TransitionLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, cmd);
|
|
||||||
kvfCopyBufferToImage(cmd, Image::Get(), staging_buffer.Get(), staging_buffer.GetOffset(), VK_IMAGE_ASPECT_COLOR_BIT, { width, height, 1 });
|
|
||||||
RenderCore::Get().vkEndCommandBuffer(cmd);
|
|
||||||
VkFence fence = kvfCreateFence(RenderCore::Get().GetDevice());
|
|
||||||
kvfSubmitSingleTimeCommandBuffer(RenderCore::Get().GetDevice(), cmd, KVF_GRAPHICS_QUEUE, fence);
|
|
||||||
kvfDestroyFence(RenderCore::Get().GetDevice(), fence);
|
|
||||||
staging_buffer.Destroy();
|
|
||||||
}
|
|
||||||
TransitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetPixel(int x, int y, std::uint32_t color) noexcept;
|
void SetPixel(int x, int y, std::uint32_t color) noexcept;
|
||||||
int GetPixel(int x, int y) noexcept;
|
int GetPixel(int x, int y) noexcept;
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ namespace mlx
|
|||||||
void Destroy() noexcept;
|
void Destroy() noexcept;
|
||||||
|
|
||||||
VmaAllocation CreateBuffer(const VkBufferCreateInfo* binfo, const VmaAllocationCreateInfo* vinfo, VkBuffer& buffer, const char* name = nullptr) noexcept;
|
VmaAllocation CreateBuffer(const VkBufferCreateInfo* binfo, const VmaAllocationCreateInfo* vinfo, VkBuffer& buffer, const char* name = nullptr) noexcept;
|
||||||
void DestroyBuffer(VmaAllocation allocation, VkBuffer buffer) noexcept;
|
void DestroyBuffer(VmaAllocation allocation, VkBuffer buffer, const char* name) noexcept;
|
||||||
|
|
||||||
VmaAllocation CreateImage(const VkImageCreateInfo* iminfo, const VmaAllocationCreateInfo* vinfo, VkImage& image, const char* name = nullptr) noexcept;
|
VmaAllocation CreateImage(const VkImageCreateInfo* iminfo, const VmaAllocationCreateInfo* vinfo, VkImage& image, const char* name = nullptr) noexcept;
|
||||||
void DestroyImage(VmaAllocation allocation, VkImage image) noexcept;
|
void DestroyImage(VmaAllocation allocation, VkImage image, const char* name) noexcept;
|
||||||
|
|
||||||
void MapMemory(VmaAllocation allocation, void** data) noexcept;
|
void MapMemory(VmaAllocation allocation, void** data) noexcept;
|
||||||
void UnmapMemory(VmaAllocation allocation) noexcept;
|
void UnmapMemory(VmaAllocation allocation) noexcept;
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ namespace mlx
|
|||||||
#undef MLX_VULKAN_INSTANCE_FUNCTION
|
#undef MLX_VULKAN_INSTANCE_FUNCTION
|
||||||
#undef MLX_VULKAN_DEVICE_FUNCTION
|
#undef MLX_VULKAN_DEVICE_FUNCTION
|
||||||
|
|
||||||
|
#if defined(DEBUG) && defined(VK_EXT_debug_utils)
|
||||||
|
inline static constexpr bool HAS_DEBUG_UTILS_FUNCTIONS = true;
|
||||||
|
#else
|
||||||
|
inline static constexpr bool HAS_DEBUG_UTILS_FUNCTIONS = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
~RenderCore();
|
~RenderCore();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -20,6 +20,12 @@
|
|||||||
MLX_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceMemoryProperties)
|
MLX_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceMemoryProperties)
|
||||||
MLX_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties)
|
MLX_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties)
|
||||||
MLX_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties)
|
MLX_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties)
|
||||||
|
#ifdef DEBUG
|
||||||
|
#ifdef VK_EXT_debug_utils
|
||||||
|
MLX_VULKAN_INSTANCE_FUNCTION(vkSetDebugUtilsObjectNameEXT)
|
||||||
|
//MLX_VULKAN_INSTANCE_FUNCTION(vkSetDebugUtilsObjectTagEXT)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MLX_VULKAN_DEVICE_FUNCTION
|
#ifdef MLX_VULKAN_DEVICE_FUNCTION
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ namespace mlx
|
|||||||
{
|
{
|
||||||
MLX_PROFILE_FUNCTION();
|
MLX_PROFILE_FUNCTION();
|
||||||
Texture* texture;
|
Texture* texture;
|
||||||
try { texture = new Texture({}, w, h); }
|
try { texture = new Texture({}, w, h, VK_FORMAT_R8G8B8A8_SRGB, false, "mlx_user_image"); }
|
||||||
catch(...) { return NULL; }
|
catch(...) { return NULL; }
|
||||||
m_image_registry.RegisterTexture(texture);
|
m_image_registry.RegisterTexture(texture);
|
||||||
return texture;
|
return texture;
|
||||||
|
|||||||
@@ -6,12 +6,14 @@ namespace mlx
|
|||||||
{
|
{
|
||||||
void Mesh::Draw(VkCommandBuffer cmd, std::size_t& drawcalls, std::size_t& polygondrawn) const noexcept
|
void Mesh::Draw(VkCommandBuffer cmd, std::size_t& drawcalls, std::size_t& polygondrawn) const noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
for(std::size_t i = 0; i < m_sub_meshes.size(); i++)
|
for(std::size_t i = 0; i < m_sub_meshes.size(); i++)
|
||||||
Draw(cmd, drawcalls, polygondrawn, i);
|
Draw(cmd, drawcalls, polygondrawn, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::Draw(VkCommandBuffer cmd, std::size_t& drawcalls, std::size_t& polygondrawn, std::size_t submesh_index) const noexcept
|
void Mesh::Draw(VkCommandBuffer cmd, std::size_t& drawcalls, std::size_t& polygondrawn, std::size_t submesh_index) const noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
Verify(submesh_index < m_sub_meshes.size(), "invalid submesh index");
|
Verify(submesh_index < m_sub_meshes.size(), "invalid submesh index");
|
||||||
m_sub_meshes[submesh_index].vbo.Bind(cmd);
|
m_sub_meshes[submesh_index].vbo.Bind(cmd);
|
||||||
m_sub_meshes[submesh_index].ibo.Bind(cmd);
|
m_sub_meshes[submesh_index].ibo.Bind(cmd);
|
||||||
@@ -22,6 +24,7 @@ namespace mlx
|
|||||||
|
|
||||||
Mesh::~Mesh()
|
Mesh::~Mesh()
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
for(auto& mesh : m_sub_meshes)
|
for(auto& mesh : m_sub_meshes)
|
||||||
{
|
{
|
||||||
mesh.vbo.Destroy();
|
mesh.vbo.Destroy();
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
#include <PreCompiled.h>
|
|
||||||
|
|
||||||
#include <Graphics/PutPixelManager.h>
|
|
||||||
#include <Renderer/Renderer.h>
|
|
||||||
|
|
||||||
namespace mlx
|
|
||||||
{
|
|
||||||
NonOwningPtr<Texture> PutPixelManager::DrawPixel(int x, int y, std::uint64_t z, std::uint32_t color)
|
|
||||||
{
|
|
||||||
Verify((bool)p_renderer, "invalid renderer pointer");
|
|
||||||
auto it = m_textures.find(z);
|
|
||||||
if(it == m_textures.end())
|
|
||||||
{
|
|
||||||
VkExtent2D swapchain_extent = kvfGetSwapchainImagesSize(p_renderer->GetSwapchain());
|
|
||||||
Texture& texture = m_textures[z] = Texture({}, swapchain_extent.width, swapchain_extent.height);
|
|
||||||
texture.SetPixel(x, y, color);
|
|
||||||
return &texture;
|
|
||||||
}
|
|
||||||
it->second.SetPixel(x, y, color);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PutPixelManager::ResetRenderData()
|
|
||||||
{
|
|
||||||
m_textures.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
PutPixelManager::~PutPixelManager()
|
|
||||||
{
|
|
||||||
ResetRenderData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
31
runtime/Sources/Graphics/PutPixelManager.cpp
git.filemode.normal_file
31
runtime/Sources/Graphics/PutPixelManager.cpp
git.filemode.normal_file
@@ -0,0 +1,31 @@
|
|||||||
|
#include <PreCompiled.h>
|
||||||
|
|
||||||
|
#include <Graphics/PutPixelManager.h>
|
||||||
|
#include <Renderer/Renderer.h>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
NonOwningPtr<Texture> PutPixelManager::DrawPixel(int x, int y, std::uint64_t z, std::uint32_t color)
|
||||||
|
{
|
||||||
|
Verify((bool)p_renderer, "invalid renderer pointer");
|
||||||
|
|
||||||
|
VkExtent2D swapchain_extent = kvfGetSwapchainImagesSize(p_renderer->GetSwapchain());
|
||||||
|
#ifdef DEBUG
|
||||||
|
auto res = m_textures.try_emplace(z, CPUBuffer{}, swapchain_extent.width, swapchain_extent.height, VK_FORMAT_R8G8B8A8_SRGB, false, "mlx_put_pixel_layer_" + std::to_string(z));
|
||||||
|
#else
|
||||||
|
auto res = m_textures.try_emplace(z, CPUBuffer{}, swapchain_extent.width, swapchain_extent.height, VK_FORMAT_R8G8B8A8_SRGB, false, {});
|
||||||
|
#endif
|
||||||
|
res.first->second.SetPixel(x, y, color);
|
||||||
|
return (res.second ? &res.first->second : nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PutPixelManager::ResetRenderData()
|
||||||
|
{
|
||||||
|
m_textures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
PutPixelManager::~PutPixelManager()
|
||||||
|
{
|
||||||
|
ResetRenderData();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,12 +8,14 @@ namespace mlx
|
|||||||
Scene::Scene(SceneDescriptor desc)
|
Scene::Scene(SceneDescriptor desc)
|
||||||
: m_descriptor(std::move(desc))
|
: m_descriptor(std::move(desc))
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
Verify((bool)m_descriptor.renderer, "invalid renderer");
|
Verify((bool)m_descriptor.renderer, "invalid renderer");
|
||||||
m_depth.Init(m_descriptor.renderer->GetSwapchainImages().back().GetWidth(), m_descriptor.renderer->GetSwapchainImages().back().GetHeight());
|
m_depth.Init(m_descriptor.renderer->GetSwapchainImages().back().GetWidth(), m_descriptor.renderer->GetSwapchainImages().back().GetHeight(), false, "mlx_scene_depth");
|
||||||
}
|
}
|
||||||
|
|
||||||
Sprite& Scene::CreateSprite(NonOwningPtr<Texture> texture) noexcept
|
Sprite& Scene::CreateSprite(NonOwningPtr<Texture> texture) noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
std::shared_ptr<Sprite> sprite = std::make_shared<Sprite>(texture);
|
std::shared_ptr<Sprite> sprite = std::make_shared<Sprite>(texture);
|
||||||
m_sprites.push_back(sprite);
|
m_sprites.push_back(sprite);
|
||||||
return *sprite;
|
return *sprite;
|
||||||
@@ -21,6 +23,7 @@ namespace mlx
|
|||||||
|
|
||||||
NonOwningPtr<Sprite> Scene::GetSpriteFromTextureAndPosition(NonOwningPtr<Texture> texture, const Vec2f& position) const
|
NonOwningPtr<Sprite> Scene::GetSpriteFromTextureAndPosition(NonOwningPtr<Texture> texture, const Vec2f& position) const
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
auto it = std::find_if(m_sprites.begin(), m_sprites.end(), [texture, position](std::shared_ptr<Sprite> sprite)
|
auto it = std::find_if(m_sprites.begin(), m_sprites.end(), [texture, position](std::shared_ptr<Sprite> sprite)
|
||||||
{
|
{
|
||||||
return sprite->GetPosition().x == position.x && sprite->GetPosition().y == position.y && sprite->GetTexture() == texture;
|
return sprite->GetPosition().x == position.x && sprite->GetPosition().y == position.y && sprite->GetTexture() == texture;
|
||||||
@@ -30,6 +33,7 @@ namespace mlx
|
|||||||
|
|
||||||
void Scene::TryEraseSpriteFromTexture(NonOwningPtr<Texture> texture)
|
void Scene::TryEraseSpriteFromTexture(NonOwningPtr<Texture> texture)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
auto it = m_sprites.begin();
|
auto it = m_sprites.begin();
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace mlx
|
|||||||
{
|
{
|
||||||
std::shared_ptr<Mesh> CreateQuad(float x, float y, float width, float height)
|
std::shared_ptr<Mesh> CreateQuad(float x, float y, float width, float height)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
std::vector<Vertex> data(4);
|
std::vector<Vertex> data(4);
|
||||||
|
|
||||||
data[0].position = Vec4f(x, y, 0.0f, 1.0f);
|
data[0].position = Vec4f(x, y, 0.0f, 1.0f);
|
||||||
@@ -37,6 +38,7 @@ namespace mlx
|
|||||||
|
|
||||||
Sprite::Sprite(NonOwningPtr<Texture> texture)
|
Sprite::Sprite(NonOwningPtr<Texture> texture)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
Verify((bool)texture, "Sprite: invalid texture");
|
Verify((bool)texture, "Sprite: invalid texture");
|
||||||
p_mesh = CreateQuad(0, 0, texture->GetWidth(), texture->GetHeight());
|
p_mesh = CreateQuad(0, 0, texture->GetWidth(), texture->GetHeight());
|
||||||
p_texture = texture;
|
p_texture = texture;
|
||||||
|
|||||||
@@ -4,8 +4,9 @@
|
|||||||
|
|
||||||
namespace mlx
|
namespace mlx
|
||||||
{
|
{
|
||||||
void GPUBuffer::Init(BufferType type, VkDeviceSize size, VkBufferUsageFlags usage, CPUBuffer data)
|
void GPUBuffer::Init(BufferType type, VkDeviceSize size, VkBufferUsageFlags usage, CPUBuffer data, std::string_view debug_name)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
VmaAllocationCreateInfo alloc_info{};
|
VmaAllocationCreateInfo alloc_info{};
|
||||||
alloc_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
|
alloc_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
|
||||||
alloc_info.usage = VMA_MEMORY_USAGE_AUTO;
|
alloc_info.usage = VMA_MEMORY_USAGE_AUTO;
|
||||||
@@ -24,10 +25,7 @@ namespace mlx
|
|||||||
else // LowDynamic or Staging
|
else // LowDynamic or Staging
|
||||||
m_usage = usage | VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
m_usage = usage | VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||||
|
|
||||||
if(type == BufferType::Staging && data.Empty())
|
CreateBuffer(size, m_usage, alloc_info, std::move(debug_name));
|
||||||
Warning("Vulkan : trying to create staging buffer without data (wtf?)");
|
|
||||||
|
|
||||||
CreateBuffer(size, m_usage, alloc_info);
|
|
||||||
|
|
||||||
if(!data.Empty())
|
if(!data.Empty())
|
||||||
{
|
{
|
||||||
@@ -38,21 +36,38 @@ namespace mlx
|
|||||||
PushToGPU();
|
PushToGPU();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPUBuffer::CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VmaAllocationCreateInfo alloc_info)
|
void GPUBuffer::CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VmaAllocationCreateInfo alloc_info, std::string_view debug_name)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
VkBufferCreateInfo bufferInfo{};
|
VkBufferCreateInfo bufferInfo{};
|
||||||
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||||
bufferInfo.size = size;
|
bufferInfo.size = size;
|
||||||
bufferInfo.usage = usage;
|
bufferInfo.usage = usage;
|
||||||
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
|
||||||
m_allocation = RenderCore::Get().GetAllocator().CreateBuffer(&bufferInfo, &alloc_info, m_buffer, nullptr);
|
#ifdef DEBUG
|
||||||
|
std::string alloc_name{ debug_name };
|
||||||
|
if(usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT)
|
||||||
|
alloc_name.append("_index_buffer");
|
||||||
|
else if(usage & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
|
||||||
|
alloc_name.append("_vertex_buffer");
|
||||||
|
else if(usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)
|
||||||
|
alloc_name.append("_uniform_buffer");
|
||||||
|
else
|
||||||
|
alloc_name.append("_buffer");
|
||||||
|
m_allocation = RenderCore::Get().GetAllocator().CreateBuffer(&bufferInfo, &alloc_info, m_buffer, alloc_name.c_str());
|
||||||
|
m_debug_name = std::move(alloc_name);
|
||||||
|
#else
|
||||||
|
m_allocation = RenderCore::Get().GetAllocator().CreateBuffer(&bufferInfo, &alloc_info, m_buffer, nullptr);
|
||||||
|
#endif
|
||||||
if(alloc_info.flags != 0)
|
if(alloc_info.flags != 0)
|
||||||
RenderCore::Get().GetAllocator().MapMemory(m_allocation, &p_map);
|
RenderCore::Get().GetAllocator().MapMemory(m_allocation, &p_map);
|
||||||
|
m_size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPUBuffer::CopyFrom(const GPUBuffer& buffer) noexcept
|
bool GPUBuffer::CopyFrom(const GPUBuffer& buffer) noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
if(!(m_usage & VK_BUFFER_USAGE_TRANSFER_DST_BIT))
|
if(!(m_usage & VK_BUFFER_USAGE_TRANSFER_DST_BIT))
|
||||||
{
|
{
|
||||||
Error("Vulkan : buffer cannot be the destination of a copy because it does not have the correct usage flag");
|
Error("Vulkan : buffer cannot be the destination of a copy because it does not have the correct usage flag");
|
||||||
@@ -77,12 +92,19 @@ namespace mlx
|
|||||||
|
|
||||||
void GPUBuffer::PushToGPU() noexcept
|
void GPUBuffer::PushToGPU() noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
VmaAllocationCreateInfo alloc_info{};
|
VmaAllocationCreateInfo alloc_info{};
|
||||||
alloc_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
|
alloc_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
|
||||||
|
|
||||||
GPUBuffer new_buffer;
|
GPUBuffer new_buffer;
|
||||||
new_buffer.m_usage = (this->m_usage & 0xFFFFFFFC) | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
new_buffer.m_usage = (this->m_usage & 0xFFFFFFFC) | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||||
new_buffer.CreateBuffer(m_size, new_buffer.m_usage, alloc_info);
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
std::string new_name = m_debug_name + "_gpu";
|
||||||
|
new_buffer.CreateBuffer(m_size, new_buffer.m_usage, alloc_info, new_name);
|
||||||
|
#else
|
||||||
|
new_buffer.CreateBuffer(m_size, new_buffer.m_usage, alloc_info, {});
|
||||||
|
#endif
|
||||||
|
|
||||||
if(new_buffer.CopyFrom(*this))
|
if(new_buffer.CopyFrom(*this))
|
||||||
Swap(new_buffer);
|
Swap(new_buffer);
|
||||||
@@ -92,15 +114,21 @@ namespace mlx
|
|||||||
|
|
||||||
void GPUBuffer::Destroy() noexcept
|
void GPUBuffer::Destroy() noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
if(m_buffer == VK_NULL_HANDLE)
|
if(m_buffer == VK_NULL_HANDLE)
|
||||||
return;
|
return;
|
||||||
RenderCore::Get().GetAllocator().UnmapMemory(m_allocation);
|
RenderCore::Get().GetAllocator().UnmapMemory(m_allocation);
|
||||||
RenderCore::Get().GetAllocator().DestroyBuffer(m_allocation, m_buffer);
|
#ifdef DEBUG
|
||||||
|
RenderCore::Get().GetAllocator().DestroyBuffer(m_allocation, m_buffer, m_debug_name.c_str());
|
||||||
|
#else
|
||||||
|
RenderCore::Get().GetAllocator().DestroyBuffer(m_allocation, m_buffer, nullptr);
|
||||||
|
#endif
|
||||||
m_buffer = VK_NULL_HANDLE;
|
m_buffer = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPUBuffer::Swap(GPUBuffer& buffer) noexcept
|
void GPUBuffer::Swap(GPUBuffer& buffer) noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
std::swap(m_buffer, buffer.m_buffer);
|
std::swap(m_buffer, buffer.m_buffer);
|
||||||
std::swap(m_allocation, buffer.m_allocation);
|
std::swap(m_allocation, buffer.m_allocation);
|
||||||
std::swap(m_size, buffer.m_size);
|
std::swap(m_size, buffer.m_size);
|
||||||
@@ -111,6 +139,7 @@ namespace mlx
|
|||||||
|
|
||||||
void VertexBuffer::SetData(CPUBuffer data)
|
void VertexBuffer::SetData(CPUBuffer data)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
if(data.GetSize() > m_size)
|
if(data.GetSize() > m_size)
|
||||||
{
|
{
|
||||||
Error("Vulkan : trying to store to much data in a vertex buffer (% bytes in % bytes)", data.GetSize(), m_size);
|
Error("Vulkan : trying to store to much data in a vertex buffer (% bytes in % bytes)", data.GetSize(), m_size);
|
||||||
@@ -122,13 +151,18 @@ namespace mlx
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GPUBuffer staging;
|
GPUBuffer staging;
|
||||||
staging.Init(BufferType::Staging, data.GetSize(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, data);
|
#ifdef DEBUG
|
||||||
|
staging.Init(BufferType::Staging, data.GetSize(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, data, m_debug_name);
|
||||||
|
#else
|
||||||
|
staging.Init(BufferType::Staging, data.GetSize(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, data, {});
|
||||||
|
#endif
|
||||||
CopyFrom(staging);
|
CopyFrom(staging);
|
||||||
staging.Destroy();
|
staging.Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IndexBuffer::SetData(CPUBuffer data)
|
void IndexBuffer::SetData(CPUBuffer data)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
if(data.GetSize() > m_size)
|
if(data.GetSize() > m_size)
|
||||||
{
|
{
|
||||||
Error("Vulkan : trying to store to much data in an index buffer (% bytes in % bytes)", data.GetSize(), m_size);
|
Error("Vulkan : trying to store to much data in an index buffer (% bytes in % bytes)", data.GetSize(), m_size);
|
||||||
@@ -140,16 +174,25 @@ namespace mlx
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GPUBuffer staging;
|
GPUBuffer staging;
|
||||||
staging.Init(BufferType::Staging, data.GetSize(), VK_BUFFER_USAGE_INDEX_BUFFER_BIT, data);
|
#ifdef DEBUG
|
||||||
|
staging.Init(BufferType::Staging, data.GetSize(), VK_BUFFER_USAGE_INDEX_BUFFER_BIT, data, m_debug_name);
|
||||||
|
#else
|
||||||
|
staging.Init(BufferType::Staging, data.GetSize(), VK_BUFFER_USAGE_INDEX_BUFFER_BIT, data, {});
|
||||||
|
#endif
|
||||||
CopyFrom(staging);
|
CopyFrom(staging);
|
||||||
staging.Destroy();
|
staging.Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UniformBuffer::Init(std::uint32_t size)
|
void UniformBuffer::Init(std::uint32_t size, std::string_view debug_name)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
||||||
{
|
{
|
||||||
m_buffers[i].Init(BufferType::HighDynamic, size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, {});
|
#ifdef DEBUG
|
||||||
|
m_buffers[i].Init(BufferType::HighDynamic, size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, {}, std::string{ debug_name } + '_' + std::to_string(i));
|
||||||
|
#else
|
||||||
|
m_buffers[i].Init(BufferType::HighDynamic, size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, {}, {});
|
||||||
|
#endif
|
||||||
m_maps[i] = m_buffers[i].GetMap();
|
m_maps[i] = m_buffers[i].GetMap();
|
||||||
if(m_maps[i] == nullptr)
|
if(m_maps[i] == nullptr)
|
||||||
FatalError("Vulkan : unable to map a uniform buffer");
|
FatalError("Vulkan : unable to map a uniform buffer");
|
||||||
@@ -158,6 +201,7 @@ namespace mlx
|
|||||||
|
|
||||||
void UniformBuffer::SetData(CPUBuffer data, std::size_t frame_index)
|
void UniformBuffer::SetData(CPUBuffer data, std::size_t frame_index)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
if(data.GetSize() != m_buffers[frame_index].GetSize())
|
if(data.GetSize() != m_buffers[frame_index].GetSize())
|
||||||
{
|
{
|
||||||
Error("Vulkan : invalid data size to update to a uniform buffer, % != %", data.GetSize(), m_buffers[frame_index].GetSize());
|
Error("Vulkan : invalid data size to update to a uniform buffer, % != %", data.GetSize(), m_buffers[frame_index].GetSize());
|
||||||
@@ -169,6 +213,7 @@ namespace mlx
|
|||||||
|
|
||||||
void UniformBuffer::Destroy() noexcept
|
void UniformBuffer::Destroy() noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
||||||
m_buffers[i].Destroy();
|
m_buffers[i].Destroy();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ namespace mlx
|
|||||||
{
|
{
|
||||||
void TransitionImageToCorrectLayout(Image& image, VkCommandBuffer cmd)
|
void TransitionImageToCorrectLayout(Image& image, VkCommandBuffer cmd)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
if(!image.IsInit())
|
if(!image.IsInit())
|
||||||
return;
|
return;
|
||||||
if(image.GetType() == ImageType::Color)
|
if(image.GetType() == ImageType::Color)
|
||||||
@@ -21,6 +22,7 @@ namespace mlx
|
|||||||
DescriptorSet::DescriptorSet(const ShaderSetLayout& layout, VkDescriptorSetLayout vklayout, ShaderType shader_type)
|
DescriptorSet::DescriptorSet(const ShaderSetLayout& layout, VkDescriptorSetLayout vklayout, ShaderType shader_type)
|
||||||
: m_set_layout(vklayout)
|
: m_set_layout(vklayout)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
for(auto& [binding, type] : layout.binds)
|
for(auto& [binding, type] : layout.binds)
|
||||||
{
|
{
|
||||||
m_descriptors.emplace_back();
|
m_descriptors.emplace_back();
|
||||||
@@ -35,12 +37,14 @@ namespace mlx
|
|||||||
DescriptorSet::DescriptorSet(VkDescriptorSetLayout layout, const std::vector<Descriptor>& descriptors)
|
DescriptorSet::DescriptorSet(VkDescriptorSetLayout layout, const std::vector<Descriptor>& descriptors)
|
||||||
: m_descriptors(descriptors), m_set_layout(layout)
|
: m_descriptors(descriptors), m_set_layout(layout)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
for(std::size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
for(std::size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
||||||
m_set[i] = kvfAllocateDescriptorSet(RenderCore::Get().GetDevice(), layout);
|
m_set[i] = kvfAllocateDescriptorSet(RenderCore::Get().GetDevice(), layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::SetImage(std::size_t i, std::uint32_t binding, class Image& image)
|
void DescriptorSet::SetImage(std::size_t i, std::uint32_t binding, class Image& image)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
Verify(m_set[i] != VK_NULL_HANDLE, "invalid descriptor");
|
Verify(m_set[i] != VK_NULL_HANDLE, "invalid descriptor");
|
||||||
auto it = std::find_if(m_descriptors.begin(), m_descriptors.end(), [=](Descriptor descriptor)
|
auto it = std::find_if(m_descriptors.begin(), m_descriptors.end(), [=](Descriptor descriptor)
|
||||||
{
|
{
|
||||||
@@ -61,6 +65,7 @@ namespace mlx
|
|||||||
|
|
||||||
void DescriptorSet::SetStorageBuffer(std::size_t i, std::uint32_t binding, class GPUBuffer& buffer)
|
void DescriptorSet::SetStorageBuffer(std::size_t i, std::uint32_t binding, class GPUBuffer& buffer)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
Verify(m_set[i] != VK_NULL_HANDLE, "invalid descriptor");
|
Verify(m_set[i] != VK_NULL_HANDLE, "invalid descriptor");
|
||||||
auto it = std::find_if(m_descriptors.begin(), m_descriptors.end(), [=](Descriptor descriptor)
|
auto it = std::find_if(m_descriptors.begin(), m_descriptors.end(), [=](Descriptor descriptor)
|
||||||
{
|
{
|
||||||
@@ -81,6 +86,7 @@ namespace mlx
|
|||||||
|
|
||||||
void DescriptorSet::SetUniformBuffer(std::size_t i, std::uint32_t binding, class GPUBuffer& buffer)
|
void DescriptorSet::SetUniformBuffer(std::size_t i, std::uint32_t binding, class GPUBuffer& buffer)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
Verify(m_set[i] != VK_NULL_HANDLE, "invalid descriptor");
|
Verify(m_set[i] != VK_NULL_HANDLE, "invalid descriptor");
|
||||||
auto it = std::find_if(m_descriptors.begin(), m_descriptors.end(), [=](Descriptor descriptor)
|
auto it = std::find_if(m_descriptors.begin(), m_descriptors.end(), [=](Descriptor descriptor)
|
||||||
{
|
{
|
||||||
@@ -101,6 +107,7 @@ namespace mlx
|
|||||||
|
|
||||||
void DescriptorSet::Update(std::size_t i, VkCommandBuffer cmd) noexcept
|
void DescriptorSet::Update(std::size_t i, VkCommandBuffer cmd) noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
Verify(m_set[i] != VK_NULL_HANDLE, "invalid descriptor");
|
Verify(m_set[i] != VK_NULL_HANDLE, "invalid descriptor");
|
||||||
std::vector<VkWriteDescriptorSet> writes;
|
std::vector<VkWriteDescriptorSet> writes;
|
||||||
std::vector<VkDescriptorBufferInfo> buffer_infos;
|
std::vector<VkDescriptorBufferInfo> buffer_infos;
|
||||||
@@ -141,6 +148,7 @@ namespace mlx
|
|||||||
|
|
||||||
void DescriptorSet::Reallocate() noexcept
|
void DescriptorSet::Reallocate() noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
for(std::size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
for(std::size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
||||||
m_set[i] = kvfAllocateDescriptorSet(RenderCore::Get().GetDevice(), m_set_layout);
|
m_set[i] = kvfAllocateDescriptorSet(RenderCore::Get().GetDevice(), m_set_layout);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,14 +15,18 @@
|
|||||||
|
|
||||||
namespace mlx
|
namespace mlx
|
||||||
{
|
{
|
||||||
void Image::Init(ImageType type, std::uint32_t width, std::uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, bool is_multisampled)
|
void Image::Init(ImageType type, std::uint32_t width, std::uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, bool is_multisampled, std::string_view debug_name)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
m_type = type;
|
m_type = type;
|
||||||
m_width = width;
|
m_width = width;
|
||||||
m_height = height;
|
m_height = height;
|
||||||
m_format = format;
|
m_format = format;
|
||||||
m_tiling = tiling;
|
m_tiling = tiling;
|
||||||
m_is_multisampled = is_multisampled;
|
m_is_multisampled = is_multisampled;
|
||||||
|
#ifdef DEBUG
|
||||||
|
m_debug_name = std::move(debug_name);
|
||||||
|
#endif
|
||||||
|
|
||||||
VmaAllocationCreateInfo alloc_info{};
|
VmaAllocationCreateInfo alloc_info{};
|
||||||
alloc_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
|
alloc_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
|
||||||
@@ -41,21 +45,39 @@ namespace mlx
|
|||||||
image_info.usage = usage;
|
image_info.usage = usage;
|
||||||
image_info.samples = (m_is_multisampled ? VK_SAMPLE_COUNT_4_BIT : VK_SAMPLE_COUNT_1_BIT);
|
image_info.samples = (m_is_multisampled ? VK_SAMPLE_COUNT_4_BIT : VK_SAMPLE_COUNT_1_BIT);
|
||||||
image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
m_allocation = RenderCore::Get().GetAllocator().CreateImage(&image_info, &alloc_info, m_image);
|
#ifdef DEBUG
|
||||||
|
m_allocation = RenderCore::Get().GetAllocator().CreateImage(&image_info, &alloc_info, m_image, m_debug_name.c_str());
|
||||||
|
#else
|
||||||
|
m_allocation = RenderCore::Get().GetAllocator().CreateImage(&image_info, &alloc_info, m_image, nullptr);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::CreateImageView(VkImageViewType type, VkImageAspectFlags aspect_flags, int layer_count) noexcept
|
void Image::CreateImageView(VkImageViewType type, VkImageAspectFlags aspect_flags, int layer_count) noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
m_image_view = kvfCreateImageView(RenderCore::Get().GetDevice(), m_image, m_format, type, aspect_flags, layer_count);
|
m_image_view = kvfCreateImageView(RenderCore::Get().GetDevice(), m_image, m_format, type, aspect_flags, layer_count);
|
||||||
|
#ifdef DEBUG
|
||||||
|
if constexpr(RenderCore::HAS_DEBUG_UTILS_FUNCTIONS)
|
||||||
|
{
|
||||||
|
VkDebugUtilsObjectNameInfoEXT name_info{};
|
||||||
|
name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
|
||||||
|
name_info.objectType = VK_OBJECT_TYPE_IMAGE_VIEW;
|
||||||
|
name_info.objectHandle = reinterpret_cast<std::uint64_t>(m_image_view);
|
||||||
|
name_info.pObjectName = m_debug_name.c_str();
|
||||||
|
RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::CreateSampler() noexcept
|
void Image::CreateSampler() noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
m_sampler = kvfCreateSampler(RenderCore::Get().GetDevice(), VK_FILTER_NEAREST, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_MIPMAP_MODE_NEAREST);
|
m_sampler = kvfCreateSampler(RenderCore::Get().GetDevice(), VK_FILTER_NEAREST, VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_SAMPLER_MIPMAP_MODE_NEAREST);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::TransitionLayout(VkImageLayout new_layout, VkCommandBuffer cmd)
|
void Image::TransitionLayout(VkImageLayout new_layout, VkCommandBuffer cmd)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
if(new_layout == m_layout)
|
if(new_layout == m_layout)
|
||||||
return;
|
return;
|
||||||
bool is_single_time_cmd_buffer = (cmd == VK_NULL_HANDLE);
|
bool is_single_time_cmd_buffer = (cmd == VK_NULL_HANDLE);
|
||||||
@@ -74,6 +96,7 @@ namespace mlx
|
|||||||
|
|
||||||
void Image::Clear(VkCommandBuffer cmd, Vec4f color)
|
void Image::Clear(VkCommandBuffer cmd, Vec4f color)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
VkImageSubresourceRange subresource_range{};
|
VkImageSubresourceRange subresource_range{};
|
||||||
subresource_range.baseMipLevel = 0;
|
subresource_range.baseMipLevel = 0;
|
||||||
subresource_range.layerCount = 1;
|
subresource_range.layerCount = 1;
|
||||||
@@ -100,6 +123,7 @@ namespace mlx
|
|||||||
|
|
||||||
void Image::DestroySampler() noexcept
|
void Image::DestroySampler() noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
if(m_sampler != VK_NULL_HANDLE)
|
if(m_sampler != VK_NULL_HANDLE)
|
||||||
kvfDestroySampler(RenderCore::Get().GetDevice(), m_sampler);
|
kvfDestroySampler(RenderCore::Get().GetDevice(), m_sampler);
|
||||||
m_sampler = VK_NULL_HANDLE;
|
m_sampler = VK_NULL_HANDLE;
|
||||||
@@ -107,6 +131,7 @@ namespace mlx
|
|||||||
|
|
||||||
void Image::DestroyImageView() noexcept
|
void Image::DestroyImageView() noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
if(m_image_view != VK_NULL_HANDLE)
|
if(m_image_view != VK_NULL_HANDLE)
|
||||||
kvfDestroyImageView(RenderCore::Get().GetDevice(), m_image_view);
|
kvfDestroyImageView(RenderCore::Get().GetDevice(), m_image_view);
|
||||||
m_image_view = VK_NULL_HANDLE;
|
m_image_view = VK_NULL_HANDLE;
|
||||||
@@ -114,14 +139,45 @@ namespace mlx
|
|||||||
|
|
||||||
void Image::Destroy() noexcept
|
void Image::Destroy() noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
DestroySampler();
|
DestroySampler();
|
||||||
DestroyImageView();
|
DestroyImageView();
|
||||||
|
|
||||||
if(m_image != VK_NULL_HANDLE)
|
if(m_image != VK_NULL_HANDLE)
|
||||||
RenderCore::Get().GetAllocator().DestroyImage(m_allocation, m_image);
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
RenderCore::Get().GetAllocator().DestroyImage(m_allocation, m_image, m_debug_name.c_str());
|
||||||
|
#else
|
||||||
|
RenderCore::Get().GetAllocator().DestroyImage(m_allocation, m_image, nullptr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
m_image = VK_NULL_HANDLE;
|
m_image = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Texture::Init(CPUBuffer pixels, std::uint32_t width, std::uint32_t height, VkFormat format, bool is_multisampled, std::string_view debug_name)
|
||||||
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
|
Image::Init(ImageType::Color, width, height, format, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, is_multisampled, std::move(debug_name));
|
||||||
|
Image::CreateImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
|
Image::CreateSampler();
|
||||||
|
if(pixels)
|
||||||
|
{
|
||||||
|
GPUBuffer staging_buffer;
|
||||||
|
std::size_t size = width * height * kvfFormatSize(format);
|
||||||
|
staging_buffer.Init(BufferType::Staging, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, std::move(pixels), debug_name);
|
||||||
|
VkCommandBuffer cmd = kvfCreateCommandBuffer(RenderCore::Get().GetDevice());
|
||||||
|
kvfBeginCommandBuffer(cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||||
|
TransitionLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, cmd);
|
||||||
|
kvfCopyBufferToImage(cmd, Image::Get(), staging_buffer.Get(), staging_buffer.GetOffset(), VK_IMAGE_ASPECT_COLOR_BIT, { width, height, 1 });
|
||||||
|
RenderCore::Get().vkEndCommandBuffer(cmd);
|
||||||
|
VkFence fence = kvfCreateFence(RenderCore::Get().GetDevice());
|
||||||
|
kvfSubmitSingleTimeCommandBuffer(RenderCore::Get().GetDevice(), cmd, KVF_GRAPHICS_QUEUE, fence);
|
||||||
|
kvfDestroyFence(RenderCore::Get().GetDevice(), fence);
|
||||||
|
staging_buffer.Destroy();
|
||||||
|
}
|
||||||
|
TransitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
|
}
|
||||||
|
|
||||||
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();
|
MLX_PROFILE_FUNCTION();
|
||||||
@@ -150,6 +206,7 @@ namespace mlx
|
|||||||
|
|
||||||
void Texture::Update(VkCommandBuffer cmd)
|
void Texture::Update(VkCommandBuffer cmd)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
if(!m_has_been_modified)
|
if(!m_has_been_modified)
|
||||||
return;
|
return;
|
||||||
std::memcpy(m_staging_buffer->GetMap(), m_cpu_buffer.data(), m_cpu_buffer.size() * kvfFormatSize(m_format));
|
std::memcpy(m_staging_buffer->GetMap(), m_cpu_buffer.data(), m_cpu_buffer.size() * kvfFormatSize(m_format));
|
||||||
@@ -167,10 +224,12 @@ namespace mlx
|
|||||||
MLX_PROFILE_FUNCTION();
|
MLX_PROFILE_FUNCTION();
|
||||||
if(m_staging_buffer.has_value())
|
if(m_staging_buffer.has_value())
|
||||||
return;
|
return;
|
||||||
DebugLog("Texture : enabling CPU mapping");
|
#ifdef DEBUG
|
||||||
|
DebugLog("Texture : enabling CPU mapping for '%'", m_debug_name);
|
||||||
|
#endif
|
||||||
m_staging_buffer.emplace();
|
m_staging_buffer.emplace();
|
||||||
std::size_t size = m_width * m_height * kvfFormatSize(m_format);
|
std::size_t size = m_width * m_height * kvfFormatSize(m_format);
|
||||||
m_staging_buffer->Init(BufferType::Staging, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, {});
|
m_staging_buffer->Init(BufferType::Staging, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, {}, m_debug_name);
|
||||||
|
|
||||||
VkImageLayout old_layout = m_layout;
|
VkImageLayout old_layout = m_layout;
|
||||||
VkCommandBuffer cmd = kvfCreateCommandBuffer(RenderCore::Get().GetDevice());
|
VkCommandBuffer cmd = kvfCreateCommandBuffer(RenderCore::Get().GetDevice());
|
||||||
@@ -199,7 +258,7 @@ namespace mlx
|
|||||||
}
|
}
|
||||||
if(stbi_is_hdr(filename.c_str()))
|
if(stbi_is_hdr(filename.c_str()))
|
||||||
{
|
{
|
||||||
Error("Texture : unsupported image format %", file);
|
Error("Texture : unsupported image format % (HDR image)", file);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
int dummy_w;
|
int dummy_w;
|
||||||
@@ -210,7 +269,7 @@ namespace mlx
|
|||||||
std::memcpy(buffer.GetData(), data, buffer.GetSize());
|
std::memcpy(buffer.GetData(), data, buffer.GetSize());
|
||||||
Texture* texture;
|
Texture* texture;
|
||||||
|
|
||||||
try { texture = new Texture(buffer, (w == nullptr ? dummy_w : *w), (h == nullptr ? dummy_h : *h)); }
|
try { texture = new Texture(buffer, (w == nullptr ? dummy_w : *w), (h == nullptr ? dummy_h : *h), VK_FORMAT_R8G8B8A8_SRGB, false, std::move(filename)); }
|
||||||
catch(...) { return NULL; }
|
catch(...) { return NULL; }
|
||||||
|
|
||||||
stbi_image_free(data);
|
stbi_image_free(data);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ namespace mlx
|
|||||||
{
|
{
|
||||||
void GPUAllocator::Init() noexcept
|
void GPUAllocator::Init() noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
VmaVulkanFunctions vma_vulkan_func{};
|
VmaVulkanFunctions vma_vulkan_func{};
|
||||||
vma_vulkan_func.vkAllocateMemory = RenderCore::Get().vkAllocateMemory;
|
vma_vulkan_func.vkAllocateMemory = RenderCore::Get().vkAllocateMemory;
|
||||||
vma_vulkan_func.vkBindBufferMemory = RenderCore::Get().vkBindBufferMemory;
|
vma_vulkan_func.vkBindBufferMemory = RenderCore::Get().vkBindBufferMemory;
|
||||||
@@ -63,6 +64,15 @@ namespace mlx
|
|||||||
kvfCheckVk(vmaCreateBuffer(m_allocator, binfo, vinfo, &buffer, &allocation, nullptr));
|
kvfCheckVk(vmaCreateBuffer(m_allocator, binfo, vinfo, &buffer, &allocation, nullptr));
|
||||||
if(name != nullptr)
|
if(name != nullptr)
|
||||||
{
|
{
|
||||||
|
if constexpr(RenderCore::HAS_DEBUG_UTILS_FUNCTIONS)
|
||||||
|
{
|
||||||
|
VkDebugUtilsObjectNameInfoEXT name_info{};
|
||||||
|
name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
|
||||||
|
name_info.objectType = VK_OBJECT_TYPE_BUFFER;
|
||||||
|
name_info.objectHandle = reinterpret_cast<std::uint64_t>(buffer);
|
||||||
|
name_info.pObjectName = name;
|
||||||
|
RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info);
|
||||||
|
}
|
||||||
vmaSetAllocationName(m_allocator, allocation, name);
|
vmaSetAllocationName(m_allocator, allocation, name);
|
||||||
}
|
}
|
||||||
DebugLog("Graphics Allocator : created new buffer '%'", name);
|
DebugLog("Graphics Allocator : created new buffer '%'", name);
|
||||||
@@ -70,12 +80,15 @@ namespace mlx
|
|||||||
return allocation;
|
return allocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPUAllocator::DestroyBuffer(VmaAllocation allocation, VkBuffer buffer) noexcept
|
void GPUAllocator::DestroyBuffer(VmaAllocation allocation, VkBuffer buffer, const char* name) noexcept
|
||||||
{
|
{
|
||||||
MLX_PROFILE_FUNCTION();
|
MLX_PROFILE_FUNCTION();
|
||||||
RenderCore::Get().WaitDeviceIdle();
|
RenderCore::Get().WaitDeviceIdle();
|
||||||
vmaDestroyBuffer(m_allocator, buffer, allocation);
|
vmaDestroyBuffer(m_allocator, buffer, allocation);
|
||||||
DebugLog("Graphics Allocator : destroyed buffer");
|
if(name != nullptr)
|
||||||
|
DebugLog("Graphics Allocator : destroyed buffer '%'", name);
|
||||||
|
else
|
||||||
|
DebugLog("Graphics Allocator : destroyed buffer");
|
||||||
m_active_buffers_allocations--;
|
m_active_buffers_allocations--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,6 +99,15 @@ namespace mlx
|
|||||||
kvfCheckVk(vmaCreateImage(m_allocator, iminfo, vinfo, &image, &allocation, nullptr));
|
kvfCheckVk(vmaCreateImage(m_allocator, iminfo, vinfo, &image, &allocation, nullptr));
|
||||||
if(name != nullptr)
|
if(name != nullptr)
|
||||||
{
|
{
|
||||||
|
if constexpr(RenderCore::HAS_DEBUG_UTILS_FUNCTIONS)
|
||||||
|
{
|
||||||
|
VkDebugUtilsObjectNameInfoEXT name_info{};
|
||||||
|
name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
|
||||||
|
name_info.objectType = VK_OBJECT_TYPE_IMAGE;
|
||||||
|
name_info.objectHandle = reinterpret_cast<std::uint64_t>(image);
|
||||||
|
name_info.pObjectName = name;
|
||||||
|
RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info);
|
||||||
|
}
|
||||||
vmaSetAllocationName(m_allocator, allocation, name);
|
vmaSetAllocationName(m_allocator, allocation, name);
|
||||||
}
|
}
|
||||||
DebugLog("Graphics Allocator : created new image '%'", name);
|
DebugLog("Graphics Allocator : created new image '%'", name);
|
||||||
@@ -93,12 +115,15 @@ namespace mlx
|
|||||||
return allocation;
|
return allocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPUAllocator::DestroyImage(VmaAllocation allocation, VkImage image) noexcept
|
void GPUAllocator::DestroyImage(VmaAllocation allocation, VkImage image, const char* name) noexcept
|
||||||
{
|
{
|
||||||
MLX_PROFILE_FUNCTION();
|
MLX_PROFILE_FUNCTION();
|
||||||
RenderCore::Get().WaitDeviceIdle();
|
RenderCore::Get().WaitDeviceIdle();
|
||||||
vmaDestroyImage(m_allocator, image, allocation);
|
vmaDestroyImage(m_allocator, image, allocation);
|
||||||
DebugLog("Graphics Allocator : destroyed image");
|
if(name != nullptr)
|
||||||
|
DebugLog("Graphics Allocator : destroyed image '%'", name);
|
||||||
|
else
|
||||||
|
DebugLog("Graphics Allocator : destroyed image");
|
||||||
m_active_images_allocations--;
|
m_active_images_allocations--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,6 +166,7 @@ namespace mlx
|
|||||||
|
|
||||||
void GPUAllocator::Destroy() noexcept
|
void GPUAllocator::Destroy() noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
if(m_active_images_allocations != 0)
|
if(m_active_images_allocations != 0)
|
||||||
Error("Graphics allocator : some user-dependant allocations were not freed before destroying the display (% active allocations). You may have not destroyed all the MLX resources you've created", m_active_images_allocations);
|
Error("Graphics allocator : some user-dependant allocations were not freed before destroying the display (% active allocations). You may have not destroyed all the MLX resources you've created", m_active_images_allocations);
|
||||||
else if(m_active_buffers_allocations != 0)
|
else if(m_active_buffers_allocations != 0)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ namespace mlx
|
|||||||
{
|
{
|
||||||
void GraphicPipeline::Init(const GraphicPipelineDescriptor& descriptor)
|
void GraphicPipeline::Init(const GraphicPipelineDescriptor& descriptor)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
if(!descriptor.vertex_shader || !descriptor.fragment_shader)
|
if(!descriptor.vertex_shader || !descriptor.fragment_shader)
|
||||||
FatalError("Vulkan : invalid shaders");
|
FatalError("Vulkan : invalid shaders");
|
||||||
|
|
||||||
@@ -62,6 +63,7 @@ namespace mlx
|
|||||||
|
|
||||||
bool GraphicPipeline::BindPipeline(VkCommandBuffer command_buffer, std::size_t framebuffer_index, std::array<float, 4> clear) noexcept
|
bool GraphicPipeline::BindPipeline(VkCommandBuffer command_buffer, std::size_t framebuffer_index, std::array<float, 4> clear) noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
TransitionAttachments(command_buffer);
|
TransitionAttachments(command_buffer);
|
||||||
VkFramebuffer fb = m_framebuffers[framebuffer_index];
|
VkFramebuffer fb = m_framebuffers[framebuffer_index];
|
||||||
VkExtent2D fb_extent = kvfGetFramebufferSize(fb);
|
VkExtent2D fb_extent = kvfGetFramebufferSize(fb);
|
||||||
@@ -98,11 +100,13 @@ namespace mlx
|
|||||||
|
|
||||||
void GraphicPipeline::EndPipeline(VkCommandBuffer command_buffer) noexcept
|
void GraphicPipeline::EndPipeline(VkCommandBuffer command_buffer) noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
RenderCore::Get().vkCmdEndRenderPass(command_buffer);
|
RenderCore::Get().vkCmdEndRenderPass(command_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicPipeline::Destroy() noexcept
|
void GraphicPipeline::Destroy() noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
p_vertex_shader.reset();
|
p_vertex_shader.reset();
|
||||||
p_fragment_shader.reset();
|
p_fragment_shader.reset();
|
||||||
for(auto& fb : m_framebuffers)
|
for(auto& fb : m_framebuffers)
|
||||||
@@ -124,6 +128,7 @@ namespace mlx
|
|||||||
|
|
||||||
void GraphicPipeline::CreateFramebuffers(const std::vector<NonOwningPtr<Texture>>& render_targets, bool clear_attachments)
|
void GraphicPipeline::CreateFramebuffers(const std::vector<NonOwningPtr<Texture>>& render_targets, bool clear_attachments)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
std::vector<VkAttachmentDescription> attachments;
|
std::vector<VkAttachmentDescription> attachments;
|
||||||
std::vector<VkImageView> attachment_views;
|
std::vector<VkImageView> attachment_views;
|
||||||
if(p_renderer)
|
if(p_renderer)
|
||||||
@@ -167,6 +172,7 @@ namespace mlx
|
|||||||
|
|
||||||
void GraphicPipeline::TransitionAttachments(VkCommandBuffer cmd)
|
void GraphicPipeline::TransitionAttachments(VkCommandBuffer cmd)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
if(p_depth)
|
if(p_depth)
|
||||||
p_depth->TransitionLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, cmd);
|
p_depth->TransitionLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, cmd);
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ namespace mlx
|
|||||||
{
|
{
|
||||||
Shader::Shader(const std::vector<std::uint8_t>& bytecode, ShaderType type, ShaderLayout layout) : m_layout(std::move(layout)), m_bytecode(bytecode)
|
Shader::Shader(const std::vector<std::uint8_t>& bytecode, ShaderType type, ShaderLayout layout) : m_layout(std::move(layout)), m_bytecode(bytecode)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case ShaderType::Vertex : m_stage = VK_SHADER_STAGE_VERTEX_BIT; break;
|
case ShaderType::Vertex : m_stage = VK_SHADER_STAGE_VERTEX_BIT; break;
|
||||||
@@ -22,6 +23,7 @@ namespace mlx
|
|||||||
|
|
||||||
void Shader::GeneratePipelineLayout(ShaderLayout layout)
|
void Shader::GeneratePipelineLayout(ShaderLayout layout)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
for(auto& [n, set] : layout.set_layouts)
|
for(auto& [n, set] : layout.set_layouts)
|
||||||
{
|
{
|
||||||
std::vector<VkDescriptorSetLayoutBinding> bindings(set.binds.size());
|
std::vector<VkDescriptorSetLayoutBinding> bindings(set.binds.size());
|
||||||
@@ -55,6 +57,7 @@ namespace mlx
|
|||||||
|
|
||||||
Shader::~Shader()
|
Shader::~Shader()
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
kvfDestroyShaderModule(RenderCore::Get().GetDevice(), m_module);
|
kvfDestroyShaderModule(RenderCore::Get().GetDevice(), m_module);
|
||||||
DebugLog("Vulkan : shader module destroyed");
|
DebugLog("Vulkan : shader module destroyed");
|
||||||
for(auto& layout : m_set_layouts)
|
for(auto& layout : m_set_layouts)
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ namespace mlx
|
|||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ValidationWarningCallback(const char* message) noexcept
|
void WarningCallback(const char* message) noexcept
|
||||||
{
|
{
|
||||||
Logs::Report(LogType::Warning, 0, "", "", message);
|
Logs::Report(LogType::Warning, 0, "", "", message);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
@@ -54,8 +54,9 @@ namespace mlx
|
|||||||
LoadKVFGlobalVulkanFunctionPointers();
|
LoadKVFGlobalVulkanFunctionPointers();
|
||||||
|
|
||||||
kvfSetErrorCallback(&ErrorCallback);
|
kvfSetErrorCallback(&ErrorCallback);
|
||||||
|
kvfSetWarningCallback(&WarningCallback);
|
||||||
kvfSetValidationErrorCallback(&ValidationErrorCallback);
|
kvfSetValidationErrorCallback(&ValidationErrorCallback);
|
||||||
kvfSetValidationWarningCallback(&ValidationWarningCallback);
|
kvfSetValidationWarningCallback(&WarningCallback);
|
||||||
|
|
||||||
//kvfAddLayer("VK_LAYER_MESA_overlay");
|
//kvfAddLayer("VK_LAYER_MESA_overlay");
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ namespace mlx
|
|||||||
|
|
||||||
void Render2DPass::Init()
|
void Render2DPass::Init()
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
ShaderLayout vertex_shader_layout(
|
ShaderLayout vertex_shader_layout(
|
||||||
{
|
{
|
||||||
{ 0,
|
{ 0,
|
||||||
@@ -64,7 +65,7 @@ namespace mlx
|
|||||||
p_texture_set = std::make_shared<DescriptorSet>(p_fragment_shader->GetShaderLayout().set_layouts[0].second, p_fragment_shader->GetPipelineLayout().set_layouts[0], ShaderType::Fragment);
|
p_texture_set = std::make_shared<DescriptorSet>(p_fragment_shader->GetShaderLayout().set_layouts[0].second, p_fragment_shader->GetPipelineLayout().set_layouts[0], ShaderType::Fragment);
|
||||||
|
|
||||||
p_viewer_data_buffer = std::make_shared<UniformBuffer>();
|
p_viewer_data_buffer = std::make_shared<UniformBuffer>();
|
||||||
p_viewer_data_buffer->Init(sizeof(ViewerData));
|
p_viewer_data_buffer->Init(sizeof(ViewerData), "mlx_2d_pass_viewer_data");
|
||||||
for(std::size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
for(std::size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
||||||
{
|
{
|
||||||
p_viewer_data_set->SetUniformBuffer(i, 0, p_viewer_data_buffer->Get(i));
|
p_viewer_data_set->SetUniformBuffer(i, 0, p_viewer_data_buffer->Get(i));
|
||||||
@@ -74,6 +75,7 @@ namespace mlx
|
|||||||
|
|
||||||
void Render2DPass::Pass(Scene& scene, Renderer& renderer, Texture& render_target)
|
void Render2DPass::Pass(Scene& scene, Renderer& renderer, Texture& render_target)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
if(m_pipeline.GetPipeline() == VK_NULL_HANDLE)
|
if(m_pipeline.GetPipeline() == VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
GraphicPipelineDescriptor pipeline_descriptor;
|
GraphicPipelineDescriptor pipeline_descriptor;
|
||||||
@@ -115,6 +117,7 @@ namespace mlx
|
|||||||
|
|
||||||
void Render2DPass::Destroy()
|
void Render2DPass::Destroy()
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
m_pipeline.Destroy();
|
m_pipeline.Destroy();
|
||||||
p_vertex_shader.reset();
|
p_vertex_shader.reset();
|
||||||
p_fragment_shader.reset();
|
p_fragment_shader.reset();
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ namespace mlx
|
|||||||
{
|
{
|
||||||
void FinalPass::Init()
|
void FinalPass::Init()
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
ShaderLayout vertex_shader_layout(
|
ShaderLayout vertex_shader_layout(
|
||||||
{}, {}
|
{}, {}
|
||||||
);
|
);
|
||||||
@@ -44,6 +45,7 @@ namespace mlx
|
|||||||
|
|
||||||
void FinalPass::Pass([[maybe_unused]] Scene& scene, Renderer& renderer, Texture& render_target)
|
void FinalPass::Pass([[maybe_unused]] Scene& scene, Renderer& renderer, Texture& render_target)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
if(m_pipeline.GetPipeline() == VK_NULL_HANDLE)
|
if(m_pipeline.GetPipeline() == VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
GraphicPipelineDescriptor pipeline_descriptor;
|
GraphicPipelineDescriptor pipeline_descriptor;
|
||||||
@@ -70,6 +72,7 @@ namespace mlx
|
|||||||
|
|
||||||
void FinalPass::Destroy()
|
void FinalPass::Destroy()
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
m_pipeline.Destroy();
|
m_pipeline.Destroy();
|
||||||
p_vertex_shader.reset();
|
p_vertex_shader.reset();
|
||||||
p_fragment_shader.reset();
|
p_fragment_shader.reset();
|
||||||
|
|||||||
@@ -21,13 +21,21 @@ namespace mlx
|
|||||||
{
|
{
|
||||||
m_main_render_texture.Destroy();
|
m_main_render_texture.Destroy();
|
||||||
auto extent = kvfGetSwapchainImagesSize(renderer.GetSwapchain());
|
auto extent = kvfGetSwapchainImagesSize(renderer.GetSwapchain());
|
||||||
m_main_render_texture.Init({}, extent.width, extent.height);
|
#ifdef DEBUG
|
||||||
|
m_main_render_texture.Init({}, extent.width, extent.height, VK_FORMAT_R8G8B8A8_SRGB, false, "mlx_renderpasses_target");
|
||||||
|
#else
|
||||||
|
m_main_render_texture.Init({}, extent.width, extent.height, VK_FORMAT_R8G8B8A8_SRGB, false, {});
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
EventBus::RegisterListener({ functor, "__MlxRenderPasses" });
|
EventBus::RegisterListener({ functor, "__MlxRenderPasses" });
|
||||||
auto extent = kvfGetSwapchainImagesSize(renderer.GetSwapchain());
|
auto extent = kvfGetSwapchainImagesSize(renderer.GetSwapchain());
|
||||||
|
|
||||||
m_main_render_texture.Init({}, extent.width, extent.height);
|
#ifdef DEBUG
|
||||||
|
m_main_render_texture.Init({}, extent.width, extent.height, VK_FORMAT_R8G8B8A8_SRGB, false, "mlx_renderpasses_target");
|
||||||
|
#else
|
||||||
|
m_main_render_texture.Init({}, extent.width, extent.height, VK_FORMAT_R8G8B8A8_SRGB, false, {});
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
m_main_render_texture.Clear(renderer.GetActiveCommandBuffer(), Vec4f{ 0.0f, 0.0f, 0.0f, 1.0f });
|
m_main_render_texture.Clear(renderer.GetActiveCommandBuffer(), Vec4f{ 0.0f, 0.0f, 0.0f, 1.0f });
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ namespace mlx
|
|||||||
|
|
||||||
void Renderer::Init(NonOwningPtr<Window> window)
|
void Renderer::Init(NonOwningPtr<Window> window)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
func::function<void(const EventBase&)> functor = [this](const EventBase& event)
|
func::function<void(const EventBase&)> functor = [this](const EventBase& event)
|
||||||
{
|
{
|
||||||
if(event.What() == Event::ResizeEventCode)
|
if(event.What() == Event::ResizeEventCode)
|
||||||
@@ -56,6 +57,7 @@ namespace mlx
|
|||||||
|
|
||||||
bool Renderer::BeginFrame()
|
bool Renderer::BeginFrame()
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
kvfWaitForFence(RenderCore::Get().GetDevice(), m_cmd_fences[m_current_frame_index]);
|
kvfWaitForFence(RenderCore::Get().GetDevice(), m_cmd_fences[m_current_frame_index]);
|
||||||
VkResult result = RenderCore::Get().vkAcquireNextImageKHR(RenderCore::Get().GetDevice(), m_swapchain, UINT64_MAX, m_image_available_semaphores[m_current_frame_index], VK_NULL_HANDLE, &m_swapchain_image_index);
|
VkResult result = RenderCore::Get().vkAcquireNextImageKHR(RenderCore::Get().GetDevice(), m_swapchain, UINT64_MAX, m_image_available_semaphores[m_current_frame_index], VK_NULL_HANDLE, &m_swapchain_image_index);
|
||||||
if(result == VK_ERROR_OUT_OF_DATE_KHR)
|
if(result == VK_ERROR_OUT_OF_DATE_KHR)
|
||||||
@@ -78,6 +80,7 @@ namespace mlx
|
|||||||
|
|
||||||
void Renderer::EndFrame()
|
void Renderer::EndFrame()
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
VkPipelineStageFlags wait_stages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
VkPipelineStageFlags wait_stages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
||||||
kvfEndCommandBuffer(m_cmd_buffers[m_current_frame_index]);
|
kvfEndCommandBuffer(m_cmd_buffers[m_current_frame_index]);
|
||||||
kvfSubmitCommandBuffer(RenderCore::Get().GetDevice(), m_cmd_buffers[m_current_frame_index], KVF_GRAPHICS_QUEUE, m_render_finished_semaphores[m_current_frame_index], m_image_available_semaphores[m_current_frame_index], m_cmd_fences[m_current_frame_index], wait_stages);
|
kvfSubmitCommandBuffer(RenderCore::Get().GetDevice(), m_cmd_buffers[m_current_frame_index], KVF_GRAPHICS_QUEUE, m_render_finished_semaphores[m_current_frame_index], m_image_available_semaphores[m_current_frame_index], m_cmd_fences[m_current_frame_index], wait_stages);
|
||||||
@@ -95,6 +98,7 @@ namespace mlx
|
|||||||
|
|
||||||
void Renderer::CreateSwapchain()
|
void Renderer::CreateSwapchain()
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
Vec2ui drawable_size = p_window->GetVulkanDrawableSize();
|
Vec2ui drawable_size = p_window->GetVulkanDrawableSize();
|
||||||
VkExtent2D extent = { drawable_size.x, drawable_size.y };
|
VkExtent2D extent = { drawable_size.x, drawable_size.y };
|
||||||
m_swapchain = kvfCreateSwapchainKHR(RenderCore::Get().GetDevice(), RenderCore::Get().GetPhysicalDevice(), m_surface, extent, false);
|
m_swapchain = kvfCreateSwapchainKHR(RenderCore::Get().GetDevice(), RenderCore::Get().GetPhysicalDevice(), m_surface, extent, false);
|
||||||
@@ -105,7 +109,11 @@ namespace mlx
|
|||||||
RenderCore::Get().vkGetSwapchainImagesKHR(RenderCore::Get().GetDevice(), m_swapchain, &images_count, tmp.data());
|
RenderCore::Get().vkGetSwapchainImagesKHR(RenderCore::Get().GetDevice(), m_swapchain, &images_count, tmp.data());
|
||||||
for(std::size_t i = 0; i < images_count; i++)
|
for(std::size_t i = 0; i < images_count; i++)
|
||||||
{
|
{
|
||||||
m_swapchain_images[i].Init(tmp[i], kvfGetSwapchainImagesFormat(m_swapchain), extent.width, extent.height);
|
#ifdef DEBUG
|
||||||
|
m_swapchain_images[i].Init(tmp[i], kvfGetSwapchainImagesFormat(m_swapchain), extent.width, extent.height, VK_IMAGE_LAYOUT_UNDEFINED, "mlx_swapchain_image_" + std::to_string(i));
|
||||||
|
#else
|
||||||
|
m_swapchain_images[i].Init(tmp[i], kvfGetSwapchainImagesFormat(m_swapchain), extent.width, extent.height, VK_IMAGE_LAYOUT_UNDEFINED, {});
|
||||||
|
#endif
|
||||||
m_swapchain_images[i].TransitionLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
m_swapchain_images[i].TransitionLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||||
m_swapchain_images[i].CreateImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT);
|
m_swapchain_images[i].CreateImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
}
|
}
|
||||||
@@ -114,6 +122,7 @@ namespace mlx
|
|||||||
|
|
||||||
void Renderer::DestroySwapchain()
|
void Renderer::DestroySwapchain()
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
RenderCore::Get().WaitDeviceIdle();
|
RenderCore::Get().WaitDeviceIdle();
|
||||||
for(Image& img : m_swapchain_images)
|
for(Image& img : m_swapchain_images)
|
||||||
img.DestroyImageView();
|
img.DestroyImageView();
|
||||||
@@ -123,6 +132,7 @@ namespace mlx
|
|||||||
|
|
||||||
void Renderer::Destroy() noexcept
|
void Renderer::Destroy() noexcept
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
RenderCore::Get().WaitDeviceIdle();
|
RenderCore::Get().WaitDeviceIdle();
|
||||||
|
|
||||||
for(std::size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
for(std::size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
||||||
|
|||||||
@@ -8,16 +8,19 @@ namespace mlx
|
|||||||
{
|
{
|
||||||
void SceneRenderer::Init()
|
void SceneRenderer::Init()
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
m_passes.Init();
|
m_passes.Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneRenderer::Render(Scene& scene, Renderer& renderer)
|
void SceneRenderer::Render(Scene& scene, Renderer& renderer)
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
m_passes.Pass(scene, renderer);
|
m_passes.Pass(scene, renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneRenderer::Destroy()
|
void SceneRenderer::Destroy()
|
||||||
{
|
{
|
||||||
|
MLX_PROFILE_FUNCTION();
|
||||||
m_passes.Destroy();
|
m_passes.Destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
20
third_party/kvf.h
vendored
20
third_party/kvf.h
vendored
@@ -93,6 +93,7 @@ typedef void (*KvfErrorCallback)(const char* message);
|
|||||||
typedef struct KvfGraphicsPipelineBuilder KvfGraphicsPipelineBuilder;
|
typedef struct KvfGraphicsPipelineBuilder KvfGraphicsPipelineBuilder;
|
||||||
|
|
||||||
void kvfSetErrorCallback(KvfErrorCallback callback);
|
void kvfSetErrorCallback(KvfErrorCallback callback);
|
||||||
|
void kvfSetWarningCallback(KvfErrorCallback callback);
|
||||||
void kvfSetValidationErrorCallback(KvfErrorCallback callback);
|
void kvfSetValidationErrorCallback(KvfErrorCallback callback);
|
||||||
void kvfSetValidationWarningCallback(KvfErrorCallback callback);
|
void kvfSetValidationWarningCallback(KvfErrorCallback callback);
|
||||||
|
|
||||||
@@ -469,6 +470,7 @@ size_t __kvf_internal_framebuffers_capacity = 0;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
KvfErrorCallback __kvf_error_callback = NULL;
|
KvfErrorCallback __kvf_error_callback = NULL;
|
||||||
|
KvfErrorCallback __kvf_warning_callback = NULL;
|
||||||
KvfErrorCallback __kvf_validation_error_callback = NULL;
|
KvfErrorCallback __kvf_validation_error_callback = NULL;
|
||||||
KvfErrorCallback __kvf_validation_warning_callback = NULL;
|
KvfErrorCallback __kvf_validation_warning_callback = NULL;
|
||||||
|
|
||||||
@@ -479,7 +481,7 @@ KvfErrorCallback __kvf_validation_warning_callback = NULL;
|
|||||||
|
|
||||||
void __kvfCheckVk(VkResult result, const char* function)
|
void __kvfCheckVk(VkResult result, const char* function)
|
||||||
{
|
{
|
||||||
if(result != VK_SUCCESS)
|
if(result < VK_SUCCESS)
|
||||||
{
|
{
|
||||||
if(__kvf_error_callback != NULL)
|
if(__kvf_error_callback != NULL)
|
||||||
{
|
{
|
||||||
@@ -493,6 +495,17 @@ void __kvfCheckVk(VkResult result, const char* function)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
else if(result > VK_SUCCESS)
|
||||||
|
{
|
||||||
|
if(__kvf_warning_callback != NULL)
|
||||||
|
{
|
||||||
|
char buffer[1024];
|
||||||
|
snprintf(buffer, 1024, "KVF Vulkan warning in '%s': %s", function, kvfVerbaliseVkResult(result));
|
||||||
|
__kvf_warning_callback(buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf("KVF Vulkan warning in '%s': %s\n", function, kvfVerbaliseVkResult(result));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef __kvfCheckVk
|
#undef __kvfCheckVk
|
||||||
@@ -817,6 +830,11 @@ void kvfSetErrorCallback(KvfErrorCallback callback)
|
|||||||
__kvf_error_callback = callback;
|
__kvf_error_callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kvfSetWarningCallback(KvfErrorCallback callback)
|
||||||
|
{
|
||||||
|
__kvf_warning_callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
void kvfSetValidationErrorCallback(KvfErrorCallback callback)
|
void kvfSetValidationErrorCallback(KvfErrorCallback callback)
|
||||||
{
|
{
|
||||||
__kvf_validation_error_callback = callback;
|
__kvf_validation_error_callback = callback;
|
||||||
|
|||||||
Reference in New Issue
Block a user