adding profiler

This commit is contained in:
2024-01-10 18:32:40 +01:00
parent c3ffb80a10
commit fb6bda24a6
23 changed files with 1325 additions and 535 deletions

View File

@@ -6,7 +6,7 @@
# By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2022/10/04 16:43:41 by maldavid #+# #+# #
# Updated: 2023/12/31 01:09:30 by maldavid ### ########.fr #
# Updated: 2024/01/10 14:20:30 by maldavid ### ########.fr #
# #
# **************************************************************************** #
@@ -26,6 +26,7 @@ TOOLCHAIN ?= clang
IMAGES_OPTIMIZED ?= true
FORCE_INTEGRATED_GPU ?= false
GRAPHICS_MEMORY_DUMP ?= false
PROFILER ?= false
MODE = "release"
@@ -66,6 +67,10 @@ ifeq ($(GRAPHICS_MEMORY_DUMP), true)
CXXFLAGS += -D GRAPHICS_MEMORY_DUMP
endif
ifeq ($(PROFILER), true)
CXXFLAGS += -D PROFILER
endif
RM = rm -rf
$(OBJ_DIR)/%.o: %.cpp

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/04 22:10:52 by maldavid #+# #+# */
/* Updated: 2023/12/27 21:30:10 by maldavid ### ########.fr */
/* Updated: 2024/01/10 16:44:14 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -48,6 +48,7 @@ namespace mlx::core
void* Application::newTexture(int w, int h)
{
MLX_PROFILE_FUNCTION();
#ifdef DEBUG
_textures.emplace_front().create(nullptr, w, h, VK_FORMAT_R8G8B8A8_UNORM, "__mlx_unamed_user_texture");
#else
@@ -58,12 +59,14 @@ namespace mlx::core
void* Application::newStbTexture(char* file, int* w, int* h)
{
MLX_PROFILE_FUNCTION();
_textures.emplace_front(stbTextureLoad(file, w, h));
return &_textures.front();
}
void Application::destroyTexture(void* ptr)
{
MLX_PROFILE_FUNCTION();
vkDeviceWaitIdle(Render_Core::get().getDevice().get()); // TODO : synchronize with another method than stopping all the GPU process
Texture* texture = static_cast<Texture*>(ptr);
texture->destroy();

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/04 21:49:46 by maldavid #+# #+# */
/* Updated: 2023/12/22 21:04:48 by kbz_8 ### ########.fr */
/* Updated: 2024/01/10 14:17:24 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -25,6 +25,7 @@
#include <core/graphics.h>
#include <platform/inputs.h>
#include <mlx_profile.h>
#include <core/profiler.h>
namespace mlx::core
{

View File

@@ -56,6 +56,7 @@ namespace mlx::core
void* Application::newGraphicsSuport(std::size_t w, std::size_t h, const char* title)
{
MLX_PROFILE_FUNCTION();
auto it = std::find_if(_textures.begin(), _textures.end(), [=](const Texture& texture)
{
return &texture == reinterpret_cast<Texture*>(const_cast<char*>(title));
@@ -77,24 +78,28 @@ namespace mlx::core
void Application::clearGraphicsSupport(void* win)
{
MLX_PROFILE_FUNCTION();
CHECK_WINDOW_PTR(win);
_graphics[*static_cast<int*>(win)]->clearRenderData();
}
void Application::destroyGraphicsSupport(void* win)
{
MLX_PROFILE_FUNCTION();
CHECK_WINDOW_PTR(win);
_graphics[*static_cast<int*>(win)].reset();
}
void Application::pixelPut(void* win, int x, int y, uint32_t color) const noexcept
{
MLX_PROFILE_FUNCTION();
CHECK_WINDOW_PTR(win);
_graphics[*static_cast<int*>(win)]->pixelPut(x, y, color);
}
void Application::stringPut(void* win, int x, int y, int color, char* str)
{
MLX_PROFILE_FUNCTION();
CHECK_WINDOW_PTR(win);
if(str == nullptr)
{
@@ -111,12 +116,14 @@ namespace mlx::core
void Application::loadFont(void* win, const std::filesystem::path& filepath, float scale)
{
MLX_PROFILE_FUNCTION();
CHECK_WINDOW_PTR(win);
_graphics[*static_cast<int*>(win)]->loadFont(filepath, scale);
}
void Application::texturePut(void* win, void* img, int x, int y)
{
MLX_PROFILE_FUNCTION();
CHECK_WINDOW_PTR(win);
if(img == nullptr)
{
@@ -132,6 +139,7 @@ namespace mlx::core
int Application::getTexturePixel(void* img, int x, int y)
{
MLX_PROFILE_FUNCTION();
if(img == nullptr)
{
core::error::report(e_kind::error, "wrong texture (NULL)");
@@ -148,6 +156,7 @@ namespace mlx::core
void Application::setTexturePixel(void* img, int x, int y, uint32_t color)
{
MLX_PROFILE_FUNCTION();
if(img == nullptr)
{
core::error::report(e_kind::error, "wrong texture (NULL)");

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/02 15:13:55 by maldavid #+# #+# */
/* Updated: 2023/12/27 21:27:48 by maldavid ### ########.fr */
/* Updated: 2024/01/10 18:23:26 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -22,6 +22,7 @@ namespace mlx
_height(h),
_id(id)
{
MLX_PROFILE_FUNCTION();
_renderer->setWindow(nullptr);
_renderer->init(render_target);
_pixel_put_pipeline.init(w, h, *_renderer);
@@ -36,6 +37,7 @@ namespace mlx
_height(h),
_id(id)
{
MLX_PROFILE_FUNCTION();
_renderer->setWindow(_window.get());
_renderer->init(nullptr);
_pixel_put_pipeline.init(w, h, *_renderer);
@@ -44,6 +46,7 @@ namespace mlx
void GraphicsSupport::render() noexcept
{
MLX_PROFILE_FUNCTION();
if(!_renderer->beginFrame())
return;
_proj = glm::ortho<float>(0, _width, 0, _height);
@@ -71,11 +74,12 @@ namespace mlx
}
_pixel_put_pipeline.present();
sets[1] = _pixel_put_pipeline.getDescriptorSet();
vkCmdBindDescriptorSets(cmd_buff, VK_PIPELINE_BIND_POINT_GRAPHICS, _renderer->getPipeline().getPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr);
_pixel_put_pipeline.render(*_renderer);
_text_put_pipeline->render(sets);
_renderer->endFrame();
for(auto& data : _textures_to_render)
@@ -94,6 +98,7 @@ namespace mlx
GraphicsSupport::~GraphicsSupport()
{
MLX_PROFILE_FUNCTION();
vkDeviceWaitIdle(Render_Core::get().getDevice().get());
_text_put_pipeline->destroy();
_pixel_put_pipeline.destroy();

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/02 14:49:49 by maldavid #+# #+# */
/* Updated: 2024/01/07 01:27:09 by maldavid ### ########.fr */
/* Updated: 2024/01/10 14:18:48 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -27,6 +27,7 @@
#include <utils/non_copyable.h>
#include <renderer/images/texture.h>
#include <mlx_profile.h>
#include <core/profiler.h>
namespace mlx
{

View File

@@ -20,6 +20,7 @@ namespace mlx
void GraphicsSupport::clearRenderData() noexcept
{
MLX_PROFILE_FUNCTION();
_textures_to_render.clear();
_pixel_put_pipeline.clear();
_text_put_pipeline->clear();
@@ -27,16 +28,19 @@ namespace mlx
void GraphicsSupport::pixelPut(int x, int y, uint32_t color) noexcept
{
MLX_PROFILE_FUNCTION();
_pixel_put_pipeline.setPixel(x, y, color);
}
void GraphicsSupport::stringPut(int x, int y, int color, std::string str)
{
MLX_PROFILE_FUNCTION();
_text_put_pipeline->put(x, y, color, str);
}
void GraphicsSupport::texturePut(Texture* texture, int x, int y)
{
MLX_PROFILE_FUNCTION();
_textures_to_render.emplace_back(texture, x, y);
auto it = std::find(_textures_to_render.begin(), _textures_to_render.end() - 1, _textures_to_render.back());
if(it != _textures_to_render.end() - 1)
@@ -45,6 +49,7 @@ namespace mlx
void GraphicsSupport::loadFont(const std::filesystem::path& filepath, float scale)
{
MLX_PROFILE_FUNCTION();
_text_put_pipeline->loadFont(filepath, scale);
}
}

79
src/core/profiler.cpp git.filemode.normal_file
View File

@@ -0,0 +1,79 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* profiler.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/10 13:56:21 by maldavid #+# #+# */
/* Updated: 2024/01/10 18:17:35 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <core/profiler.h>
#include <core/errors.h>
#include <iostream>
namespace mlx
{
void Profiler::beginRuntimeSession()
{
std::lock_guard lock(_mutex);
if(_runtime_session_began)
return;
_output_stream.open("./runtime_profile.mlx.json", std::ofstream::out | std::ofstream::trunc);
if(_output_stream.is_open())
writeHeader();
else
core::error::report(e_kind::error, "Profiler : cannot open runtime profile file");
_runtime_session_began = true;
}
void Profiler::appendProfileData(ProfileResult&& result)
{
std::lock_guard lock(_mutex);
auto it = _profile_data.find(result.name);
if(it != _profile_data.end())
{
result.elapsed_time = (result.elapsed_time + it->second.second.elapsed_time) / it->second.first;
_profile_data[result.name].first++;
_profile_data[result.name].second = result;
}
else
_profile_data[result.name] = std::make_pair(1, result);
}
void Profiler::writeProfile(const ProfileResult& result)
{
std::stringstream json;
json << std::setprecision(9) << std::fixed;
json << ",\n{\n";
json << "\t\"type\" : \"function\"," << '\n';
json << "\t\"name\" : \"" << result.name << "\"," << '\n';
json << "\t\"thread id\" : " << result.thread_id << "," << '\n';
json << "\t\"average duration\" : \"" << result.elapsed_time.count() << "ms\"\n";
json << "}";
_output_stream << json.str();
}
void Profiler::endRuntimeSession()
{
std::lock_guard lock(_mutex);
if(!_runtime_session_began)
return;
for(auto& [_, pair] : _profile_data)
writeProfile(pair.second);
writeFooter();
_output_stream.close();
_profile_data.clear();
_runtime_session_began = false;
}
Profiler::~Profiler()
{
if(!_runtime_session_began)
return;
endRuntimeSession();
}
}

146
src/core/profiler.h git.filemode.normal_file
View File

@@ -0,0 +1,146 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* profiler.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/10 13:35:45 by maldavid #+# #+# */
/* Updated: 2024/01/10 18:16:47 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef __MLX_PROFILER__
#define __MLX_PROFILER__
#include <utils/singleton.h>
#include <mlx_profile.h>
#include <chrono>
#include <string>
#include <thread>
#include <mutex>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <unordered_map>
namespace mlx
{
using FloatingPointMilliseconds = std::chrono::duration<double, std::milli>;
struct ProfileResult
{
std::string name;
FloatingPointMilliseconds elapsed_time;
std::thread::id thread_id;
};
class Profiler : public Singleton<Profiler>
{
friend class Singleton;
public:
Profiler(const Profiler&) = delete;
Profiler(Profiler&&) = delete;
void appendProfileData(ProfileResult&& result);
private:
Profiler() { beginRuntimeSession(); }
~Profiler();
void beginRuntimeSession();
void writeProfile(const ProfileResult& result);
void endRuntimeSession();
inline void writeHeader()
{
_output_stream << "{\"profileData\":[{}";
_output_stream.flush();
}
inline void writeFooter()
{
_output_stream << "]}";
_output_stream.flush();
}
private:
std::unordered_map<std::string, std::pair<std::size_t, ProfileResult>> _profile_data;
std::ofstream _output_stream;
std::mutex _mutex;
bool _runtime_session_began = false;
};
class ProfilerTimer
{
public:
ProfilerTimer(const char* name) : _name(name)
{
_start_timepoint = std::chrono::steady_clock::now();
}
inline void stop()
{
auto end_timepoint = std::chrono::steady_clock::now();
auto high_res_start = FloatingPointMilliseconds{ _start_timepoint.time_since_epoch() };
auto elapsed_time = std::chrono::time_point_cast<std::chrono::milliseconds>(end_timepoint).time_since_epoch() - std::chrono::time_point_cast<std::chrono::milliseconds>(_start_timepoint).time_since_epoch();
Profiler::get().appendProfileData({ _name, elapsed_time, std::this_thread::get_id() });
_stopped = true;
}
~ProfilerTimer()
{
if(!_stopped)
stop();
}
private:
std::chrono::time_point<std::chrono::steady_clock> _start_timepoint;
const char* _name;
bool _stopped = false;
};
namespace ProfilerUtils
{
template <std::size_t N>
struct ChangeResult
{
char data[N];
};
template <std::size_t N, std::size_t K>
constexpr auto cleanupOutputString(const char(&expr)[N], const char(&remove)[K])
{
ChangeResult<N> result = {};
std::size_t srcIndex = 0;
std::size_t dstIndex = 0;
while(srcIndex < N)
{
std::size_t matchIndex = 0;
while(matchIndex < K - 1 && srcIndex + matchIndex < N - 1 && expr[srcIndex + matchIndex] == remove[matchIndex])
matchIndex++;
if(matchIndex == K - 1)
srcIndex += matchIndex;
result.data[dstIndex++] = expr[srcIndex] == '"' ? '\'' : expr[srcIndex];
srcIndex++;
}
return result;
}
}
}
#ifdef PROFILER
#define MLX_PROFILE_SCOPE_LINE2(name, line) constexpr auto fixedName##line = ::mlx::ProfilerUtils::cleanupOutputString(name, "__cdecl ");\
::mlx::ProfilerTimer timer##line(fixedName##line.data)
#define MLX_PROFILE_SCOPE_LINE(name, line) MLX_PROFILE_SCOPE_LINE2(name, line)
#define MLX_PROFILE_SCOPE(name) MLX_PROFILE_SCOPE_LINE(name, __LINE__)
#define MLX_PROFILE_FUNCTION() MLX_PROFILE_SCOPE(MLX_FUNC_SIG)
#else
#define MLX_PROFILE_SCOPE(name)
#define MLX_PROFILE_FUNCTION()
#endif
#endif

View File

@@ -6,18 +6,20 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/05 16:30:19 by maldavid #+# #+# */
/* Updated: 2023/12/11 19:01:14 by kbz_8 ### ########.fr */
/* Updated: 2024/01/10 18:31:13 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include "inputs.h"
#include <mlx.h>
#include <cstring>
#include <core/profiler.h>
namespace mlx
{
void Input::update()
{
MLX_PROFILE_FUNCTION();
_xRel = 0;
_yRel = 0;

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 18:55:57 by maldavid #+# #+# */
/* Updated: 2024/01/07 01:18:35 by maldavid ### ########.fr */
/* Updated: 2024/01/10 18:30:31 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -14,6 +14,7 @@
#include <renderer/command/vk_cmd_pool.h>
#include <renderer/command/vk_cmd_buffer.h>
#include <renderer/core/render_core.h>
#include <core/profiler.h>
#include <vma.h>
#include <cstring>
#include <iostream>
@@ -22,6 +23,7 @@ namespace mlx
{
void Buffer::create(Buffer::kind type, VkDeviceSize size, VkBufferUsageFlags usage, const char* name, const void* data)
{
MLX_PROFILE_FUNCTION();
_usage = usage;
if(type == Buffer::kind::constant || type == Buffer::kind::dynamic_device_local)
{
@@ -52,6 +54,7 @@ namespace mlx
void Buffer::destroy() noexcept
{
MLX_PROFILE_FUNCTION();
// not creating destroyer in `create` as some image may be copied (and so `this` will be invalid)
CmdResource::setDestroyer([this]()
{
@@ -66,6 +69,7 @@ namespace mlx
void Buffer::createBuffer(VkBufferUsageFlags usage, VmaAllocationCreateInfo info, VkDeviceSize size, [[maybe_unused]] const char* name)
{
MLX_PROFILE_FUNCTION();
VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = size;
@@ -90,6 +94,7 @@ namespace mlx
bool Buffer::copyFromBuffer(const Buffer& buffer) noexcept
{
MLX_PROFILE_FUNCTION();
if(!(_usage & VK_BUFFER_USAGE_TRANSFER_DST_BIT))
{
core::error::report(e_kind::error, "Vulkan : buffer cannot be the destination of a copy because it does not have the correct usage flag");
@@ -114,6 +119,7 @@ namespace mlx
void Buffer::pushToGPU() noexcept
{
MLX_PROFILE_FUNCTION();
VmaAllocationCreateInfo alloc_info{};
alloc_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;

View File

@@ -6,18 +6,20 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:45:52 by maldavid #+# #+# */
/* Updated: 2023/12/10 22:22:28 by kbz_8 ### ########.fr */
/* Updated: 2024/01/10 18:30:57 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include "vk_ubo.h"
#include <cstring>
#include <renderer/renderer.h>
#include <core/profiler.h>
namespace mlx
{
void UBO::create(Renderer* renderer, uint32_t size, [[maybe_unused]] const char* name)
{
MLX_PROFILE_FUNCTION();
_renderer = renderer;
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
@@ -37,11 +39,13 @@ namespace mlx
void UBO::setData(uint32_t size, const void* data)
{
MLX_PROFILE_FUNCTION();
std::memcpy(_maps[_renderer->getActiveImageIndex()], data, static_cast<size_t>(size));
}
void UBO::setDynamicData(uint32_t size, const void* data)
{
MLX_PROFILE_FUNCTION();
std::memcpy(_maps[_renderer->getActiveImageIndex()], data, static_cast<size_t>(size));
_buffers[_renderer->getActiveImageIndex()].flush();
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:26:06 by maldavid #+# #+# */
/* Updated: 2024/01/07 01:07:07 by maldavid ### ########.fr */
/* Updated: 2024/01/10 18:30:04 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -17,6 +17,7 @@
#include <renderer/core/vk_semaphore.h>
#include <renderer/buffers/vk_buffer.h>
#include <renderer/images/vk_image.h>
#include <core/profiler.h>
namespace mlx
{
@@ -42,6 +43,7 @@ namespace mlx
void CmdBuffer::init(kind type, CmdPool* pool)
{
MLX_PROFILE_FUNCTION();
_type = type;
_pool = pool;
@@ -64,6 +66,7 @@ namespace mlx
void CmdBuffer::beginRecord(VkCommandBufferUsageFlags usage)
{
MLX_PROFILE_FUNCTION();
if(!isInit())
core::error::report(e_kind::fatal_error, "Vulkan : begenning record on un uninit command buffer");
if(_state == state::recording)
@@ -80,6 +83,7 @@ namespace mlx
void CmdBuffer::bindVertexBuffer(Buffer& buffer) noexcept
{
MLX_PROFILE_FUNCTION();
if(!isRecording())
{
core::error::report(e_kind::warning, "Vulkan : trying to bind a vertex buffer to a non recording command buffer");
@@ -94,6 +98,7 @@ namespace mlx
void CmdBuffer::bindIndexBuffer(Buffer& buffer) noexcept
{
MLX_PROFILE_FUNCTION();
if(!isRecording())
{
core::error::report(e_kind::warning, "Vulkan : trying to bind a index buffer to a non recording command buffer");
@@ -107,6 +112,7 @@ namespace mlx
void CmdBuffer::copyBuffer(Buffer& dst, Buffer& src) noexcept
{
MLX_PROFILE_FUNCTION();
if(!isRecording())
{
core::error::report(e_kind::warning, "Vulkan : trying to do a buffer to buffer copy in a non recording command buffer");
@@ -129,6 +135,7 @@ namespace mlx
void CmdBuffer::copyBufferToImage(Buffer& buffer, Image& image) noexcept
{
MLX_PROFILE_FUNCTION();
if(!isRecording())
{
core::error::report(e_kind::warning, "Vulkan : trying to do a buffer to image copy in a non recording command buffer");
@@ -160,6 +167,7 @@ namespace mlx
void CmdBuffer::copyImagetoBuffer(Image& image, Buffer& buffer) noexcept
{
MLX_PROFILE_FUNCTION();
if(!isRecording())
{
core::error::report(e_kind::warning, "Vulkan : trying to do an image to buffer copy in a non recording command buffer");
@@ -191,6 +199,7 @@ namespace mlx
void CmdBuffer::transitionImageLayout(Image& image, VkImageLayout new_layout) noexcept
{
MLX_PROFILE_FUNCTION();
if(!isRecording())
{
core::error::report(e_kind::warning, "Vulkan : trying to do an image layout transition in a non recording command buffer");
@@ -238,6 +247,7 @@ namespace mlx
void CmdBuffer::endRecord()
{
MLX_PROFILE_FUNCTION();
if(!isInit())
core::error::report(e_kind::fatal_error, "Vulkan : ending record on un uninit command buffer");
if(_state != state::recording)
@@ -250,6 +260,7 @@ namespace mlx
void CmdBuffer::submitIdle(bool shouldWaitForExecution) noexcept
{
MLX_PROFILE_FUNCTION();
if(_type != kind::single_time)
{
core::error::report(e_kind::error, "Vulkan : try to perform an idle submit on a command buffer that is not single-time, this is not allowed");
@@ -274,6 +285,7 @@ namespace mlx
void CmdBuffer::submit(Semaphore* semaphores) noexcept
{
MLX_PROFILE_FUNCTION();
std::array<VkSemaphore, 1> signalSemaphores;
std::array<VkSemaphore, 1> waitSemaphores;
@@ -309,6 +321,7 @@ namespace mlx
void CmdBuffer::updateSubmitState() noexcept
{
MLX_PROFILE_FUNCTION();
if(!_fence.isReady())
return;
@@ -320,6 +333,7 @@ namespace mlx
void CmdBuffer::preTransferBarrier() noexcept
{
MLX_PROFILE_FUNCTION();
VkMemoryBarrier memoryBarrier{};
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memoryBarrier.pNext = nullptr;
@@ -331,6 +345,7 @@ namespace mlx
void CmdBuffer::postTransferBarrier() noexcept
{
MLX_PROFILE_FUNCTION();
VkMemoryBarrier memoryBarrier{};
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memoryBarrier.pNext = nullptr;
@@ -342,6 +357,7 @@ namespace mlx
void CmdBuffer::destroy() noexcept
{
MLX_PROFILE_FUNCTION();
_fence.destroy();
_cmd_buffer = VK_NULL_HANDLE;
_state = state::uninit;

View File

@@ -6,12 +6,13 @@
/* By: kbz_8 <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/10/20 22:02:37 by kbz_8 #+# #+# */
/* Updated: 2024/01/07 00:09:18 by maldavid ### ########.fr */
/* Updated: 2024/01/10 18:29:07 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <mlx_profile.h>
#include <core/errors.h>
#include <core/profiler.h>
#include <cstdio>
#define VMA_STATIC_VULKAN_FUNCTIONS 0
@@ -86,6 +87,7 @@ namespace mlx
VmaAllocation GPUallocator::createBuffer(const VkBufferCreateInfo* binfo, const VmaAllocationCreateInfo* vinfo, VkBuffer& buffer, const char* name) noexcept
{
MLX_PROFILE_FUNCTION();
VmaAllocation allocation;
VkResult res = vmaCreateBuffer(_allocator, binfo, vinfo, &buffer, &allocation, nullptr);
if(res != VK_SUCCESS)
@@ -104,6 +106,7 @@ namespace mlx
void GPUallocator::destroyBuffer(VmaAllocation allocation, VkBuffer buffer) noexcept
{
MLX_PROFILE_FUNCTION();
vkDeviceWaitIdle(Render_Core::get().getDevice().get());
vmaDestroyBuffer(_allocator, buffer, allocation);
#ifdef DEBUG
@@ -114,6 +117,7 @@ namespace mlx
VmaAllocation GPUallocator::createImage(const VkImageCreateInfo* iminfo, const VmaAllocationCreateInfo* vinfo, VkImage& image, const char* name) noexcept
{
MLX_PROFILE_FUNCTION();
VmaAllocation allocation;
VkResult res = vmaCreateImage(_allocator, iminfo, vinfo, &image, &allocation, nullptr);
if(res != VK_SUCCESS)
@@ -132,6 +136,7 @@ namespace mlx
void GPUallocator::destroyImage(VmaAllocation allocation, VkImage image) noexcept
{
MLX_PROFILE_FUNCTION();
vkDeviceWaitIdle(Render_Core::get().getDevice().get());
vmaDestroyImage(_allocator, image, allocation);
#ifdef DEBUG
@@ -142,6 +147,7 @@ namespace mlx
void GPUallocator::mapMemory(VmaAllocation allocation, void** data) noexcept
{
MLX_PROFILE_FUNCTION();
VkResult res = vmaMapMemory(_allocator, allocation, data);
if(res != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Graphics allocator : unable to map GPU memory to CPU memory, %s", RCore::verbaliseResultVk(res));
@@ -149,6 +155,7 @@ namespace mlx
void GPUallocator::unmapMemory(VmaAllocation allocation) noexcept
{
MLX_PROFILE_FUNCTION();
vmaUnmapMemory(_allocator, allocation);
}
@@ -173,6 +180,7 @@ namespace mlx
void GPUallocator::flush(VmaAllocation allocation, VkDeviceSize size, VkDeviceSize offset) noexcept
{
MLX_PROFILE_FUNCTION();
vmaFlushAllocation(_allocator, allocation, offset, size);
}

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/01/03 13:14:24 by maldavid ### ########.fr */
/* Updated: 2024/01/10 18:28:34 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -17,11 +17,13 @@
#include <renderer/buffers/vk_ubo.h>
#include <renderer/renderer.h>
#include <renderer/images/vk_image.h>
#include <core/profiler.h>
namespace mlx
{
void DescriptorSet::init(Renderer* renderer, DescriptorPool* pool, DescriptorSetLayout* layout)
{
MLX_PROFILE_FUNCTION();
_renderer = renderer;
_layout = layout;
_pool = pool;
@@ -47,6 +49,7 @@ namespace mlx
void DescriptorSet::writeDescriptor(int binding, UBO* ubo) const noexcept
{
MLX_PROFILE_FUNCTION();
auto device = Render_Core::get().getDevice().get();
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
@@ -71,6 +74,7 @@ namespace mlx
void DescriptorSet::writeDescriptor(int binding, const Image& image) const noexcept
{
MLX_PROFILE_FUNCTION();
auto device = Render_Core::get().getDevice().get();
VkDescriptorImageInfo imageInfo{};
@@ -92,6 +96,7 @@ namespace mlx
DescriptorSet DescriptorSet::duplicate()
{
MLX_PROFILE_FUNCTION();
DescriptorSet set;
set.init(_renderer, _pool, _layout);
return set;

View File

@@ -6,12 +6,13 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/12/11 22:06:09 by kbz_8 #+# #+# */
/* Updated: 2023/12/14 19:11:41 by maldavid ### ########.fr */
/* Updated: 2024/01/10 18:27:14 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <renderer/font.h>
#include <renderer/renderer.h>
#include <core/profiler.h>
#include <fstream>
constexpr const int RANGE = 1024;
@@ -20,6 +21,7 @@ namespace mlx
{
Font::Font(Renderer& renderer, const std::filesystem::path& path, float scale) : non_copyable(), _name(path.string()), _scale(scale)
{
MLX_PROFILE_FUNCTION();
std::vector<uint8_t> tmp_bitmap(RANGE * RANGE);
std::vector<uint8_t> vulkan_bitmap(RANGE * RANGE * 4);
@@ -56,6 +58,7 @@ namespace mlx
Font::Font(class Renderer& renderer, const std::string& name, const std::vector<uint8_t>& ttf_data, float scale) : non_copyable(), _name(name), _scale(scale)
{
MLX_PROFILE_FUNCTION();
std::vector<uint8_t> tmp_bitmap(RANGE * RANGE);
std::vector<uint8_t> vulkan_bitmap(RANGE * RANGE * 4);
stbtt_pack_context pc;
@@ -79,6 +82,7 @@ namespace mlx
Font::~Font()
{
MLX_PROFILE_FUNCTION();
_atlas.destroy();
}
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/03/31 18:03:35 by maldavid #+# #+# */
/* Updated: 2023/12/31 00:49:16 by maldavid ### ########.fr */
/* Updated: 2024/01/10 18:28:11 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -14,6 +14,7 @@
#include <renderer/images/texture.h>
#include <renderer/buffers/vk_buffer.h>
#include <renderer/renderer.h>
#include <core/profiler.h>
#include <cstring>
#define STB_IMAGE_IMPLEMENTATION
@@ -31,6 +32,7 @@ namespace mlx
{
void Texture::create(uint8_t* pixels, uint32_t width, 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();
@@ -79,6 +81,7 @@ namespace mlx
void Texture::setPixel(int x, int y, uint32_t color) noexcept
{
MLX_PROFILE_FUNCTION();
if(x < 0 || y < 0 || static_cast<uint32_t>(x) > getWidth() || static_cast<uint32_t>(y) > getHeight())
return;
if(_map == nullptr)
@@ -89,6 +92,7 @@ namespace mlx
int Texture::getPixel(int x, int y) noexcept
{
MLX_PROFILE_FUNCTION();
if(x < 0 || y < 0 || static_cast<uint32_t>(x) > getWidth() || static_cast<uint32_t>(y) > getHeight())
return 0;
if(_map == nullptr)
@@ -99,6 +103,7 @@ namespace mlx
void Texture::openCPUmap()
{
MLX_PROFILE_FUNCTION();
if(_map != nullptr)
return;
@@ -123,6 +128,7 @@ namespace mlx
void Texture::render(Renderer& renderer, int x, int y)
{
MLX_PROFILE_FUNCTION();
if(_has_been_modified)
{
std::memcpy(_map, _cpu_map.data(), _cpu_map.size() * formatSize(getFormat()));
@@ -139,6 +145,7 @@ namespace mlx
void Texture::destroy() noexcept
{
MLX_PROFILE_FUNCTION();
Image::destroy();
if(_buf_map.has_value())
_buf_map->destroy();
@@ -148,6 +155,7 @@ namespace mlx
Texture stbTextureLoad(std::filesystem::path file, int* w, int* h)
{
MLX_PROFILE_FUNCTION();
Texture texture;
int channels;
uint8_t* data = nullptr;

View File

@@ -6,17 +6,19 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/03/31 15:14:50 by maldavid #+# #+# */
/* Updated: 2023/12/23 19:34:30 by kbz_8 ### ########.fr */
/* Updated: 2024/01/10 18:26:59 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <renderer/pixel_put.h>
#include <cstring>
#include <core/profiler.h>
namespace mlx
{
void PixelPutPipeline::init(uint32_t width, uint32_t height, Renderer& renderer) noexcept
{
MLX_PROFILE_FUNCTION();
_texture.create(nullptr, width, height, VK_FORMAT_R8G8B8A8_UNORM, "__mlx_pixel_put_pipeline_texture", true);
_texture.setDescriptor(renderer.getFragDescriptorSet().duplicate());
@@ -29,6 +31,7 @@ namespace mlx
void PixelPutPipeline::setPixel(int x, int y, uint32_t color) noexcept
{
MLX_PROFILE_FUNCTION();
if(x < 0 || y < 0 || x > static_cast<int>(_width) || y > static_cast<int>(_height))
return;
_cpu_map[(y * _width) + x] = color;
@@ -37,12 +40,14 @@ namespace mlx
void PixelPutPipeline::clear()
{
MLX_PROFILE_FUNCTION();
_cpu_map.assign(_width * _height, 0);
_has_been_modified = true;
}
void PixelPutPipeline::present() noexcept
{
MLX_PROFILE_FUNCTION();
if(_has_been_modified)
{
std::memcpy(_buffer_map, _cpu_map.data(), sizeof(uint32_t) * _cpu_map.size());
@@ -54,11 +59,13 @@ namespace mlx
void PixelPutPipeline::render(Renderer& renderer) noexcept
{
MLX_PROFILE_FUNCTION();
_texture.render(renderer, 0, 0);
}
void PixelPutPipeline::destroy() noexcept
{
MLX_PROFILE_FUNCTION();
_buffer.destroy();
_texture.destroy();
}

View File

@@ -6,18 +6,20 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/18 17:25:16 by maldavid #+# #+# */
/* Updated: 2024/01/07 01:00:18 by maldavid ### ########.fr */
/* Updated: 2024/01/10 14:18:35 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <renderer/renderer.h>
#include <renderer/images/texture.h>
#include <renderer/core/render_core.h>
#include <core/profiler.h>
namespace mlx
{
void Renderer::init(Texture* render_target)
{
MLX_PROFILE_FUNCTION();
if(render_target == nullptr)
{
_surface.create(*this);
@@ -70,6 +72,7 @@ namespace mlx
bool Renderer::beginFrame()
{
MLX_PROFILE_FUNCTION();
auto device = Render_Core::get().getDevice().get();
if(_render_target == nullptr)
@@ -118,6 +121,7 @@ namespace mlx
void Renderer::endFrame()
{
MLX_PROFILE_FUNCTION();
_pass.end(getActiveCmdBuffer());
_cmd.getCmdBuffer(_current_frame_index).endRecord();
@@ -156,6 +160,7 @@ namespace mlx
void Renderer::destroy()
{
MLX_PROFILE_FUNCTION();
vkDeviceWaitIdle(Render_Core::get().getDevice().get());
_pipeline.destroy();

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:21:36 by maldavid #+# #+# */
/* Updated: 2024/01/03 13:17:56 by maldavid ### ########.fr */
/* Updated: 2024/01/10 18:27:43 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -14,6 +14,7 @@
#include <renderer/core/render_core.h>
#include <renderer/renderer.h>
#include <renderer/renderpass/vk_framebuffer.h>
#include <core/profiler.h>
namespace mlx
{
@@ -80,6 +81,7 @@ namespace mlx
void RenderPass::begin(class CmdBuffer& cmd, class FrameBuffer& fb)
{
MLX_PROFILE_FUNCTION();
if(_is_running)
return;
@@ -99,6 +101,7 @@ namespace mlx
void RenderPass::end(class CmdBuffer& cmd)
{
MLX_PROFILE_FUNCTION();
if(!_is_running)
return;
vkCmdEndRenderPass(cmd.get());

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/10 11:59:57 by maldavid #+# #+# */
/* Updated: 2023/12/12 23:03:33 by kbz_8 ### ########.fr */
/* Updated: 2024/01/10 18:26:44 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -14,11 +14,13 @@
#include <core/errors.h>
#include <renderer/renderer.h>
#include <algorithm>
#include <core/profiler.h>
namespace mlx
{
void TextData::init(std::string text, Font const* font, std::vector<Vertex> vbo_data, std::vector<uint16_t> ibo_data)
{
MLX_PROFILE_FUNCTION();
_text = std::move(text);
_font = font;
#ifdef DEBUG
@@ -34,17 +36,20 @@ namespace mlx
void TextData::bind(Renderer& renderer) noexcept
{
MLX_PROFILE_FUNCTION();
_vbo[renderer.getActiveImageIndex()].bind(renderer);
_ibo.bind(renderer);
}
void TextData::updateVertexData(int frame, std::vector<Vertex> vbo_data)
{
MLX_PROFILE_FUNCTION();
_vbo[frame].setData(sizeof(Vertex) * vbo_data.size(), static_cast<const void*>(vbo_data.data()));
}
void TextData::destroy() noexcept
{
MLX_PROFILE_FUNCTION();
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
_vbo[i].destroy();
_ibo.destroy();
@@ -52,6 +57,7 @@ namespace mlx
std::shared_ptr<TextData> TextLibrary::getTextData(TextID id)
{
MLX_PROFILE_FUNCTION();
if(!_cache.count(id))
core::error::report(e_kind::fatal_error, "Text Library : wrong text ID '%d'", id);
return _cache[id];
@@ -59,6 +65,7 @@ namespace mlx
TextID TextLibrary::addTextToLibrary(std::shared_ptr<TextData> text)
{
MLX_PROFILE_FUNCTION();
auto it = std::find_if(_cache.begin(), _cache.end(), [=](const std::pair<TextID, std::shared_ptr<TextData>>& v)
{
return v.second->getText() == text->getText();
@@ -72,6 +79,7 @@ namespace mlx
void TextLibrary::removeTextFromLibrary(TextID id)
{
MLX_PROFILE_FUNCTION();
if(_cache.count(id))
{
_cache[id]->destroy();
@@ -81,6 +89,7 @@ namespace mlx
void TextLibrary::clearLibrary()
{
MLX_PROFILE_FUNCTION();
for(auto [id, text] : _cache)
text->destroy();
_cache.clear();

View File

@@ -6,11 +6,12 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/06 16:41:13 by maldavid #+# #+# */
/* Updated: 2024/01/08 21:42:15 by maldavid ### ########.fr */
/* Updated: 2024/01/10 18:26:24 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <renderer/text_pipeline.h>
#include <core/profiler.h>
#include <fstream>
#include <utils/dogica_ttf.h>
@@ -38,6 +39,7 @@ namespace mlx
void TextDrawData::init(TextLibrary& library, Font* const font) noexcept
{
MLX_PROFILE_FUNCTION();
std::vector<Vertex> vertexData;
std::vector<uint16_t> indexData;
@@ -77,12 +79,14 @@ namespace mlx
void TextPutPipeline::init(Renderer* renderer) noexcept
{
MLX_PROFILE_FUNCTION();
_renderer = renderer;
_font_in_use = &const_cast<Font&>(*_font_set.emplace(*_renderer, "default", dogica_ttf, 6.0f).first);
}
void TextPutPipeline::loadFont(const std::filesystem::path& filepath, float scale)
{
MLX_PROFILE_FUNCTION();
if(filepath.string() == "default") // we're sure it is already loaded
_font_in_use = &const_cast<Font&>(*_font_set.emplace(*_renderer, "default", dogica_ttf, scale).first);
else
@@ -91,6 +95,7 @@ namespace mlx
void TextPutPipeline::put(int x, int y, int color, std::string str)
{
MLX_PROFILE_FUNCTION();
auto res = _drawlist.emplace(std::move(str), color, x, y);
if(res.second)
const_cast<TextDrawData&>(*res.first).init(_library, _font_in_use);
@@ -107,6 +112,7 @@ namespace mlx
void TextPutPipeline::render(std::array<VkDescriptorSet, 2>& sets)
{
MLX_PROFILE_FUNCTION();
for(auto& draw : _drawlist)
{
std::shared_ptr<TextData> draw_data = _library.getTextData(draw.id);
@@ -131,6 +137,7 @@ namespace mlx
void TextPutPipeline::destroy() noexcept
{
MLX_PROFILE_FUNCTION();
_library.clearLibrary();
_drawlist.clear();
_font_set.clear();