merge indev to master (#35)

This commit is contained in:
2024-01-11 05:32:13 +01:00
committed by GitHub
114 changed files with 9525 additions and 6182 deletions
+3 -2
View File
@@ -12,10 +12,11 @@
*.ilk
*.pdb
*.exe
.gdb_history
.vs/
.xmake/
.cache/
objs/
build/
test/.gdb_history
test/Test
example/.gdb_history
example/Test
+6 -1
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
+968 -516
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+4
View File
@@ -1,5 +1,9 @@
#!/bin/bash
if [ -e a.out ]; then
rm a.out
fi
if [ $(uname -s) = 'Darwin' ]; then
clang main.c ../libmlx.dylib -L /opt/homebrew/lib -lSDL2 -g;
else
+5 -4
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/04 17:55:21 by maldavid #+# #+# */
/* Updated: 2024/01/03 12:29:31 by maldavid ### ########.fr */
/* Updated: 2024/01/10 20:36:57 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -30,6 +30,7 @@ int update(void *param)
t_mlx *mlx;
mlx = (t_mlx *)param;
mlx_string_put(mlx->mlx, mlx->win, 160, 120, 0xFFFF2066, "this text should be hidden");
mlx_put_image_to_window(mlx->mlx, mlx->win, mlx->logo, 100, 100);
mlx_put_image_to_window(mlx->mlx, mlx->win, mlx->img, 150, 60);
if (i == 0)
@@ -93,7 +94,7 @@ int window_hook(int event, void *param)
return (0);
}
int main(int argc, char* argv[])
int main(int argc, char **argv)
{
t_mlx mlx;
void *img;
@@ -110,12 +111,12 @@ int main(int argc, char* argv[])
mlx_pixel_put(mlx.mlx, mlx.win, 200, 10, 0xFFFF00FF);
mlx_put_image_to_window(mlx.mlx, mlx.win, mlx.logo, 10, 190);
mlx.img = create_image(&mlx);
mlx_string_put(mlx.mlx, mlx.win, 20, 20, 0xFFFF2000, \
mlx_string_put(mlx.mlx, mlx.win, 20, 20, 0xFF0020FF, \
"that text will disappear");
mlx_loop_hook(mlx.mlx, update, &mlx);
mlx_loop(mlx.mlx);
mlx_destroy_image(mlx.mlx, mlx.img);
mlx_destroy_image(mlx.mlx, mlx.logo);
mlx_destroy_image(mlx.mlx, mlx.img);
mlx_destroy_window(mlx.mlx, mlx.win);
mlx_destroy_display(mlx.mlx);
return (0);
+7 -6
View File
@@ -6,11 +6,12 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/04 16:56:35 by maldavid #+# #+# */
/* Updated: 2023/12/27 17:19:50 by maldavid ### ########.fr */
/* Updated: 2024/01/05 19:53:13 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
// MacroLibX official repo https://github.com/seekrs/MacroLibX
// MacroLibX official website https://macrolibx.kbz8.me/
#ifndef __MACRO_LIB_X_H__
#define __MACRO_LIB_X_H__
@@ -147,10 +148,10 @@ MLX_API int mlx_on_event(void* mlx, void* win, mlx_event_type event, int (*f)(in
* @param win Internal window
* @param x X coordinate
* @param y Y coordinate
* @param color Color of the pixel (coded on 3 bytes in an int, 0x00RRGGBB)
* @param color Color of the pixel (coded on 4 bytes in an int, 0xAARRGGBB)
*
* Note : If your're reading pixel colors from an image, don't forget to shift them
* one byte to the right as image pixels are encoded as 0xRRGGBBAA and pixel put takes 0x00RRGGBB.
* one byte to the right as image pixels are encoded as 0xRRGGBBAA and pixel put takes 0xAARRGGBB.
*
* @return (int) Always return 0, made this to copy the behaviour of the original MLX
*/
@@ -283,7 +284,7 @@ MLX_API void* mlx_bmp_file_to_image(void* mlx, char* filename, int* width, int*
* @param win Internal window
* @param x X coordinate
* @param y Y coordinate
* @param color Color of the pixel (coded on 3 bytes in an int, 0x00RRGGBB)
* @param color Color of the pixel (coded on 4 bytes in an int, 0xAARRGGBB)
* @param str Text to put
*
* @return (int) Always return 0, made this to copy the behaviour of the original MLX
@@ -351,8 +352,8 @@ MLX_API int mlx_destroy_display(void* mlx);
* @brief Get screen size
*
* @param mlx Internal MLX application
* @param x Get X size
* @param y Get Y size
* @param w Get width size
* @param h Get height size
*
* @return (int) Always return 0, made this to copy the behaviour of the original MLX
*/
+25
View File
@@ -0,0 +1,25 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* UUID.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/06 11:26:37 by maldavid #+# #+# */
/* Updated: 2024/01/06 11:28:15 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <core/UUID.h>
#include <random>
#include <unordered_map>
namespace mlx
{
static std::random_device random_device;
static std::mt19937_64 engine(random_device());
static std::uniform_int_distribution<uint64_t> uniform_distribution;
UUID::UUID() : _uuid(uniform_distribution(engine)) {}
UUID::UUID(uint64_t uuid) : _uuid(uuid) {}
}
+33
View File
@@ -0,0 +1,33 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* UUID.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/06 11:13:23 by maldavid #+# #+# */
/* Updated: 2024/01/07 01:44:21 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef __MLX_UUID__
#define __MLX_UUID__
#include <cstdint>
namespace mlx
{
class UUID
{
public:
UUID();
UUID(uint64_t uuid);
inline operator uint64_t() const { return _uuid; }
private:
uint64_t _uuid;
};
}
#endif
+14 -1
View File
@@ -6,11 +6,12 @@
/* 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/11 05:08:42 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include "application.h"
#include <renderer/texts/text_library.h>
#include <SDL2/SDL.h>
#include <renderer/images/texture.h>
#include <renderer/core/render_core.h>
@@ -44,10 +45,19 @@ namespace mlx::core
for(auto& gs : _graphics)
gs->render();
}
Render_Core::get().getSingleTimeCmdManager().updateSingleTimesCmdBuffersSubmitState();
for(auto& gs : _graphics)
{
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
gs->getRenderer().getCmdBuffer(i).waitForExecution();
}
}
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 +68,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();
@@ -71,6 +83,7 @@ namespace mlx::core
Application::~Application()
{
TextLibrary::get().clearLibrary();
if(__drop_sdl_responsability)
return;
SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTS);
+3 -2
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 19:57:12 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
{
@@ -45,7 +46,7 @@ namespace mlx::core
inline void destroyGraphicsSupport(void* win);
inline void pixelPut(void* win, int x, int y, uint32_t color) const noexcept;
inline void stringPut(void* win, int x, int y, int color, char* str);
inline void stringPut(void* win, int x, int y, uint32_t color, char* str);
void* newTexture(int w, int h);
void* newStbTexture(char* file, int* w, int* h); // stb textures are format managed by stb image (png, jpg, bpm, ...)
+35 -1
View File
@@ -35,6 +35,11 @@ namespace mlx::core
void Application::mouseMove(void* win, int x, int y) noexcept
{
CHECK_WINDOW_PTR(win);
if(!_graphics[*static_cast<int*>(win)]->hasWindow())
{
error::report(e_kind::warning, "trying to move the mouse relative to a window that is targeting an image and not a real window, this is not allowed (move ignored)");
return;
}
SDL_WarpMouseInWindow(_graphics[*static_cast<int*>(win)]->getWindow()->getNativeWindow(), x, y);
SDL_PumpEvents();
SDL_FlushEvent(SDL_MOUSEMOTION);
@@ -43,6 +48,11 @@ namespace mlx::core
void Application::onEvent(void* win, int event, int (*funct_ptr)(int, void*), void* param) noexcept
{
CHECK_WINDOW_PTR(win);
if(!_graphics[*static_cast<int*>(win)]->hasWindow())
{
error::report(e_kind::warning, "trying to add event hook for a window that is targeting an image and not a real window, this is not allowed (hook ignored)");
return;
}
_in->onEvent(_graphics[*static_cast<int*>(win)]->getWindow()->getID(), event, funct_ptr, param);
}
@@ -56,6 +66,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));
@@ -64,6 +75,11 @@ namespace mlx::core
_graphics.emplace_back(std::make_unique<GraphicsSupport>(w, h, reinterpret_cast<Texture*>(const_cast<char*>(title)), _graphics.size()));
else
{
if(title == NULL)
{
core::error::report(e_kind::fatal_error, "invalid window title (NULL)");
return nullptr;
}
_graphics.emplace_back(std::make_unique<GraphicsSupport>(w, h, title, _graphics.size()));
_in->addWindow(_graphics.back()->getWindow());
}
@@ -72,36 +88,52 @@ 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)
void Application::stringPut(void* win, int x, int y, uint32_t color, char* str)
{
MLX_PROFILE_FUNCTION();
CHECK_WINDOW_PTR(win);
if(str == nullptr)
{
core::error::report(e_kind::error, "wrong text (NULL)");
return;
}
if(std::strlen(str) == 0)
{
core::error::report(e_kind::warning, "trying to put an empty text");
return;
}
_graphics[*static_cast<int*>(win)]->stringPut(x, y, color, str);
}
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)
{
@@ -117,6 +149,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)");
@@ -133,6 +166,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)");
+3 -3
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/04 17:35:20 by maldavid #+# #+# */
/* Updated: 2023/12/31 00:22:58 by maldavid ### ########.fr */
/* Updated: 2024/01/10 19:54:51 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -193,8 +193,8 @@ extern "C"
unsigned char color_bits[4];
color_bits[0] = (color & 0x00FF0000) >> 16;
color_bits[1] = (color & 0x0000FF00) >> 8;
color_bits[2] = color & 0x000000FF;
color_bits[3] = 0xFF;
color_bits[2] = (color & 0x000000FF);
color_bits[3] = (color & 0xFF000000) >> 24;
static_cast<mlx::core::Application*>(mlx)->stringPut(win, x, y, *reinterpret_cast<unsigned int*>(color_bits), str);
return 0;
}
+1 -1
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/04 17:48:06 by maldavid #+# #+# */
/* Updated: 2023/11/14 07:14:57 by maldavid ### ########.fr */
/* Updated: 2024/01/05 20:41:17 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
+17 -30
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/11 04:38:53 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -16,70 +16,56 @@ namespace mlx
{
GraphicsSupport::GraphicsSupport(std::size_t w, std::size_t h, Texture* render_target, int id) :
_window(nullptr),
_text_put_pipeline(std::make_unique<TextPutPipeline>()),
_renderer(std::make_unique<Renderer>()),
_width(w),
_height(h),
_id(id)
_id(id),
_has_window(false)
{
MLX_PROFILE_FUNCTION();
_renderer->setWindow(nullptr);
_renderer->init(render_target);
_pixel_put_pipeline.init(w, h, *_renderer);
_text_put_pipeline->init(_renderer.get());
_text_manager.init(*_renderer);
}
GraphicsSupport::GraphicsSupport(std::size_t w, std::size_t h, std::string title, int id) :
_window(std::make_shared<MLX_Window>(w, h, title)),
_text_put_pipeline(std::make_unique<TextPutPipeline>()),
_renderer(std::make_unique<Renderer>()),
_width(w),
_height(h),
_id(id)
_id(id),
_has_window(true)
{
MLX_PROFILE_FUNCTION();
_renderer->setWindow(_window.get());
_renderer->init(nullptr);
_pixel_put_pipeline.init(w, h, *_renderer);
_text_put_pipeline->init(_renderer.get());
_text_manager.init(*_renderer);
}
void GraphicsSupport::render() noexcept
{
MLX_PROFILE_FUNCTION();
if(!_renderer->beginFrame())
return;
_proj = glm::ortho<float>(0, _width, 0, _height);
_renderer->getUniformBuffer()->setData(sizeof(_proj), &_proj);
auto cmd_buff = _renderer->getActiveCmdBuffer().get();
static std::array<VkDescriptorSet, 2> sets = {
_renderer->getVertDescriptorSet().get(),
VK_NULL_HANDLE
};
for(auto& data : _textures_to_render)
{
if(!data.texture->isInit())
continue;
if(data.texture->getSet() == VK_NULL_HANDLE)
data.texture->setDescriptor(_renderer->getFragDescriptorSet().duplicate());
if(data.texture->getLayout() != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
data.texture->transitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
if(!data.texture->hasBeenUpdated())
data.texture->updateSet(0);
sets[1] = data.texture->getSet();
vkCmdBindDescriptorSets(cmd_buff, VK_PIPELINE_BIND_POINT_GRAPHICS, _renderer->getPipeline().getPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr);
data.texture->render(*_renderer, data.x, data.y);
}
for(auto& data : _drawlist)
data->render(sets, *_renderer);
_pixel_put_pipeline.present();
_pixel_put_pipeline.render(sets, *_renderer);
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)
data.texture->resetUpdate();
for(auto& data : _drawlist)
data->resetUpdate();
#ifdef GRAPHICS_MEMORY_DUMP
// dump memory to file every two seconds
@@ -94,8 +80,9 @@ namespace mlx
GraphicsSupport::~GraphicsSupport()
{
MLX_PROFILE_FUNCTION();
vkDeviceWaitIdle(Render_Core::get().getDevice().get());
_text_put_pipeline->destroy();
_text_manager.destroy();
_pixel_put_pipeline.destroy();
_renderer->destroy();
if(_window)
+21 -5
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/02 14:49:49 by maldavid #+# #+# */
/* Updated: 2023/12/24 08:56:14 by kbz_8 ### ########.fr */
/* Updated: 2024/01/11 04:39:23 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -23,10 +23,13 @@
#include <platform/window.h>
#include <renderer/renderer.h>
#include <renderer/pixel_put.h>
#include <renderer/text_pipeline.h>
#include <renderer/core/drawable_resource.h>
#include <renderer/images/texture_manager.h>
#include <renderer/texts/text_manager.h>
#include <utils/non_copyable.h>
#include <renderer/images/texture.h>
#include <mlx_profile.h>
#include <core/profiler.h>
namespace mlx
{
@@ -43,22 +46,35 @@ namespace mlx
inline void clearRenderData() noexcept;
inline void pixelPut(int x, int y, uint32_t color) noexcept;
inline void stringPut(int x, int y, int color, std::string str);
inline void stringPut(int x, int y, uint32_t color, std::string str);
inline void texturePut(Texture* texture, int x, int y);
inline void loadFont(const std::filesystem::path& filepath, float scale);
inline bool hasWindow() const noexcept { return _has_window; }
inline Renderer& getRenderer() { return *_renderer; }
~GraphicsSupport();
private:
std::vector<TextureRenderData> _textures_to_render;
std::vector<DrawableResource*> _drawlist;
PixelPutPipeline _pixel_put_pipeline;
TextManager _text_manager;
TextureManager _texture_manager;
glm::mat4 _proj = glm::mat4(1.0);
std::shared_ptr<MLX_Window> _window;
std::unique_ptr<TextPutPipeline> _text_put_pipeline; // unique_ptr because of the size of the class
std::unique_ptr<Renderer> _renderer;
std::size_t _width = 0;
std::size_t _height = 0;
int _id;
bool _has_window;
};
}
+27 -10
View File
@@ -11,7 +11,7 @@
/* ************************************************************************** */
#include <core/graphics.h>
#include <type_traits>
#include <iostream>
namespace mlx
{
@@ -20,31 +20,48 @@ namespace mlx
void GraphicsSupport::clearRenderData() noexcept
{
_textures_to_render.clear();
MLX_PROFILE_FUNCTION();
_drawlist.clear();
_pixel_put_pipeline.clear();
_text_put_pipeline->clear();
_text_manager.clear();
_texture_manager.clear();
}
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)
void GraphicsSupport::stringPut(int x, int y, uint32_t color, std::string str)
{
_text_put_pipeline->put(x, y, color, str);
MLX_PROFILE_FUNCTION();
std::pair<DrawableResource*, bool> res = _text_manager.registerText(x, y, color, str);
if(!res.second) // if this is not a completly new text draw
{
auto it = std::find(_drawlist.begin(), _drawlist.end(), res.first);
if(it != _drawlist.end())
_drawlist.erase(it);
}
_drawlist.push_back(res.first);
}
void GraphicsSupport::texturePut(Texture* texture, int x, int y)
{
_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)
_textures_to_render.erase(it);
MLX_PROFILE_FUNCTION();
auto res = _texture_manager.registerTexture(texture, x, y);
if(!res.second) // if this is not a completly new texture draw
{
auto it = std::find(_drawlist.begin(), _drawlist.end(), res.first);
if(it != _drawlist.end())
_drawlist.erase(it);
}
_drawlist.push_back(res.first);
}
void GraphicsSupport::loadFont(const std::filesystem::path& filepath, float scale)
{
_text_put_pipeline->loadFont(filepath, scale);
MLX_PROFILE_FUNCTION();
_text_manager.loadFont(*_renderer, filepath, scale);
}
}
-1
View File
@@ -13,7 +13,6 @@
#include <core/memory.h>
#include <core/errors.h>
#include <algorithm>
#include <stdlib.h>
namespace mlx
{
+79
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
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:36:46 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<Profiler>;
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
+3 -1
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;
+1 -1
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/05 16:27:35 by maldavid #+# #+# */
/* Updated: 2023/12/11 19:47:20 by kbz_8 ### ########.fr */
/* Updated: 2023/12/11 19:47:20 by vavaas ### ########.fr */
/* */
/* ************************************************************************** */
+20 -7
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 18:55:57 by maldavid #+# #+# */
/* Updated: 2023/12/16 17:10:17 by maldavid ### ########.fr */
/* Updated: 2024/01/11 05:21:20 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -14,14 +14,15 @@
#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>
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,15 +53,22 @@ 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]()
//{
if(_is_mapped)
unmapMem();
if(_buffer != VK_NULL_HANDLE)
Render_Core::get().getAllocator().destroyBuffer(_allocation, _buffer);
_buffer = VK_NULL_HANDLE;
//});
//CmdResource::requireDestroy();
}
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;
@@ -85,6 +93,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");
@@ -96,13 +105,10 @@ namespace mlx
return false;
}
// TODO, use global cmd buffer pool to manage resources
CmdBuffer& cmd = Render_Core::get().getSingleTimeCmdBuffer();
cmd.beginRecord();
VkBufferCopy copyRegion{};
copyRegion.size = _size;
vkCmdCopyBuffer(cmd.get(), buffer._buffer, _buffer, 1, &copyRegion);
cmd.copyBuffer(*this, const_cast<Buffer&>(buffer));
cmd.endRecord();
cmd.submitIdle();
@@ -112,6 +118,7 @@ namespace mlx
void Buffer::pushToGPU() noexcept
{
MLX_PROFILE_FUNCTION();
VmaAllocationCreateInfo alloc_info{};
alloc_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
@@ -124,7 +131,7 @@ namespace mlx
newBuffer.createBuffer(newBuffer._usage, alloc_info, _size, nullptr);
#endif
if(newBuffer.copyFromBuffer(*this)) // if the copy succeded we swap the buffers, else the new one is deleted
if(newBuffer.copyFromBuffer(*this)) // if the copy succeded we swap the buffers, otherwise the new one is deleted
this->swap(newBuffer);
newBuffer.destroy();
}
@@ -150,6 +157,12 @@ namespace mlx
VkBufferUsageFlags temp_u = _usage;
_usage = buffer._usage;
buffer._usage = temp_u;
#ifdef DEBUG
std::string temp_n = _name;
_name = buffer._name;
buffer._name = temp_n;
#endif
}
void Buffer::flush(VkDeviceSize size, VkDeviceSize offset)
+3 -2
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 23:18:52 by maldavid #+# #+# */
/* Updated: 2024/01/03 15:26:56 by maldavid ### ########.fr */
/* Updated: 2024/01/11 05:16:58 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -16,10 +16,11 @@
#include <mlx_profile.h>
#include <volk.h>
#include <renderer/core/render_core.h>
#include <renderer/core/cmd_resource.h>
namespace mlx
{
class Buffer
class Buffer : public CmdResource
{
public:
enum class kind { dynamic, dynamic_device_local, uniform, constant };
+2 -2
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/01/25 15:05:05 by maldavid #+# #+# */
/* Updated: 2024/01/03 15:27:02 by maldavid ### ########.fr */
/* Updated: 2024/01/10 23:05:15 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -24,7 +24,7 @@ namespace mlx
{
public:
inline void create(uint32_t size, const uint16_t* data, const char* name) { Buffer::create(Buffer::kind::constant, size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, name, data); }
inline void bind(Renderer& renderer) noexcept { vkCmdBindIndexBuffer(renderer.getActiveCmdBuffer().get(), _buffer, _offset, VK_INDEX_TYPE_UINT16); }
inline void bind(Renderer& renderer) noexcept { renderer.getActiveCmdBuffer().bindIndexBuffer(*this); }
};
}
+5 -1
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();
}
+4 -4
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:27:38 by maldavid #+# #+# */
/* Updated: 2023/12/12 22:46:21 by kbz_8 ### ########.fr */
/* Updated: 2024/01/10 23:04:40 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -24,7 +24,7 @@ namespace mlx
public:
inline void create(uint32_t size, const void* data, const char* name) { Buffer::create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, name, data); }
void setData(uint32_t size, const void* data);
inline void bind(Renderer& renderer) noexcept { vkCmdBindVertexBuffers(renderer.getActiveCmdBuffer().get(), 0, 1, &_buffer, &_offset); }
inline void bind(Renderer& renderer) noexcept { renderer.getActiveCmdBuffer().bindVertexBuffer(*this); }
};
class D_VBO : public Buffer
@@ -32,14 +32,14 @@ namespace mlx
public:
inline void create(uint32_t size, const void* data, const char* name) { Buffer::create(Buffer::kind::dynamic_device_local, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, name, data); }
void setData(uint32_t size, const void* data);
inline void bind(Renderer& renderer) noexcept { vkCmdBindVertexBuffers(renderer.getActiveCmdBuffer().get(), 0, 1, &_buffer, &_offset); }
inline void bind(Renderer& renderer) noexcept { renderer.getActiveCmdBuffer().bindVertexBuffer(*this); }
};
class C_VBO : public Buffer
{
public:
inline void create(uint32_t size, const void* data, const char* name) { Buffer::create(Buffer::kind::constant, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, name, data); }
inline void bind(Renderer& renderer) noexcept { vkCmdBindVertexBuffers(renderer.getActiveCmdBuffer().get(), 0, 1, &_buffer, &_offset); }
inline void bind(Renderer& renderer) noexcept { renderer.getActiveCmdBuffer().bindVertexBuffer(*this); }
};
}
+2 -2
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/02 17:50:52 by maldavid #+# #+# */
/* Updated: 2023/04/02 17:51:46 by maldavid ### ########.fr */
/* Updated: 2023/12/17 20:10:45 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -18,7 +18,7 @@ namespace mlx
{
_cmd_pool.init();
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
_cmd_buffers[i].init(this);
_cmd_buffers[i].init(CmdBuffer::kind::long_time, this);
}
void CmdManager::beginRecord(int active_image_index)
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/12/15 19:57:49 by maldavid #+# #+# */
/* Updated: 2023/12/16 18:46:26 by maldavid ### ########.fr */
/* Updated: 2024/01/11 03:13:21 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -16,15 +16,13 @@
namespace mlx
{
SingleTimeCmdManager::SingleTimeCmdManager() : _buffers(MIN_POOL_SIZE) {}
void SingleTimeCmdManager::init() noexcept
{
_pool.init();
for(int i = 0; i < MIN_POOL_SIZE; i++)
for(int i = 0; i < BASE_POOL_SIZE; i++)
{
_buffers.emplace_back();
_buffers.back().init(&_pool);
_buffers.back().init(CmdBuffer::kind::single_time, &_pool);
}
}
@@ -38,10 +36,22 @@ namespace mlx
return buf;
}
}
_buffers.emplace_back().init(&_pool);
_buffers.emplace_back().init(CmdBuffer::kind::single_time, &_pool);
return _buffers.back();
}
void SingleTimeCmdManager::updateSingleTimesCmdBuffersSubmitState() noexcept
{
for(CmdBuffer& cmd : _buffers)
cmd.updateSubmitState();
}
void SingleTimeCmdManager::waitForAllExecutions() noexcept
{
for(CmdBuffer& cmd : _buffers)
cmd.waitForExecution();
}
void SingleTimeCmdManager::destroy() noexcept
{
std::for_each(_buffers.begin(), _buffers.end(), [](CmdBuffer& buf)
+11 -7
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/12/15 18:25:57 by maldavid #+# #+# */
/* Updated: 2023/12/16 18:09:56 by maldavid ### ########.fr */
/* Updated: 2024/01/07 01:30:19 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -14,28 +14,32 @@
#define __MLX_SINGLE_TIME_CMD_MANAGER__
#include <vector>
#include <renderer/command/vk_cmd_pool.h>
#include <renderer/command/vk_cmd_buffer.h>
#include <renderer/command/vk_cmd_pool.h>
namespace mlx
{
class CmdBuffer;
class SingleTimeCmdManager
{
friend class Render_Core;
public:
SingleTimeCmdManager();
SingleTimeCmdManager() = default;
void init() noexcept;
void destroy() noexcept;
void updateSingleTimesCmdBuffersSubmitState() noexcept;
void waitForAllExecutions() noexcept;
inline CmdPool& getCmdPool() noexcept { return _pool; }
CmdBuffer& getCmdBuffer() noexcept;
~SingleTimeCmdManager() = default;
inline static constexpr const uint8_t MIN_POOL_SIZE = 8;
private:
inline static constexpr const uint8_t BASE_POOL_SIZE = 16;
private:
std::vector<CmdBuffer> _buffers;
+250 -19
View File
@@ -6,24 +6,45 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:26:06 by maldavid #+# #+# */
/* Updated: 2024/01/03 13:12:58 by maldavid ### ########.fr */
/* Updated: 2024/01/10 18:30:04 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include "vk_cmd_buffer.h"
#include <renderer/core/cmd_resource.h>
#include <renderer/core/render_core.h>
#include <renderer/command/cmd_manager.h>
#include <renderer/core/vk_semaphore.h>
#include <renderer/buffers/vk_buffer.h>
#include <renderer/images/vk_image.h>
#include <core/profiler.h>
namespace mlx
{
void CmdBuffer::init(CmdManager* manager)
bool vector_push_back_if_not_found(std::vector<CmdResource*>& vector, CmdResource* res)
{
init(&manager->getCmdPool());
auto it = std::find_if(vector.begin(), vector.end(), [=](const CmdResource* vres)
{
return vres->getUUID() == res->getUUID();
});
if(it == vector.end())
{
vector.push_back(res);
return true;
}
return false;
}
void CmdBuffer::init(CmdPool* pool)
void CmdBuffer::init(kind type, CmdManager* manager)
{
init(type, &manager->getCmdPool());
}
void CmdBuffer::init(kind type, CmdPool* pool)
{
MLX_PROFILE_FUNCTION();
_type = type;
_pool = pool;
VkCommandBufferAllocateInfo allocInfo{};
@@ -45,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)
@@ -59,8 +81,173 @@ namespace mlx
_state = state::recording;
}
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");
return;
}
VkDeviceSize offset[] = { buffer.getOffset() };
vkCmdBindVertexBuffers(_cmd_buffer, 0, 1, &buffer.get(), offset);
buffer.recordedInCmdBuffer();
vector_push_back_if_not_found(_cmd_resources, &buffer);
}
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");
return;
}
vkCmdBindIndexBuffer(_cmd_buffer, buffer.get(), buffer.getOffset(), VK_INDEX_TYPE_UINT16);
buffer.recordedInCmdBuffer();
vector_push_back_if_not_found(_cmd_resources, &buffer);
}
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");
return;
}
preTransferBarrier();
VkBufferCopy copyRegion{};
copyRegion.size = src.getSize();
vkCmdCopyBuffer(_cmd_buffer, src.get(), dst.get(), 1, &copyRegion);
postTransferBarrier();
dst.recordedInCmdBuffer();
src.recordedInCmdBuffer();
vector_push_back_if_not_found(_cmd_resources, &dst);
vector_push_back_if_not_found(_cmd_resources, &src);
}
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");
return;
}
preTransferBarrier();
VkBufferImageCopy region{};
region.bufferOffset = 0;
region.bufferRowLength = 0;
region.bufferImageHeight = 0;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageOffset = { 0, 0, 0 };
region.imageExtent = { image.getWidth(), image.getHeight(), 1 };
vkCmdCopyBufferToImage(_cmd_buffer, buffer.get(), image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
postTransferBarrier();
image.recordedInCmdBuffer();
buffer.recordedInCmdBuffer();
vector_push_back_if_not_found(_cmd_resources, &image);
vector_push_back_if_not_found(_cmd_resources, &buffer);
}
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");
return;
}
preTransferBarrier();
VkBufferImageCopy region{};
region.bufferOffset = 0;
region.bufferRowLength = 0;
region.bufferImageHeight = 0;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageOffset = { 0, 0, 0 };
region.imageExtent = { image.getWidth(), image.getHeight(), 1 };
vkCmdCopyImageToBuffer(_cmd_buffer, image.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer.get(), 1, &region);
postTransferBarrier();
image.recordedInCmdBuffer();
buffer.recordedInCmdBuffer();
vector_push_back_if_not_found(_cmd_resources, &buffer);
vector_push_back_if_not_found(_cmd_resources, &image);
}
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");
return;
}
VkImageMemoryBarrier barrier{};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.oldLayout = image.getLayout();
barrier.newLayout = new_layout;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = image.get();
barrier.subresourceRange.aspectMask = isDepthFormat(image.getFormat()) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.levelCount = 1;
barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.layerCount = 1;
barrier.srcAccessMask = layoutToAccessMask(image.getLayout(), false);
barrier.dstAccessMask = layoutToAccessMask(new_layout, true);
if(isStencilFormat(image.getFormat()))
barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
VkPipelineStageFlags sourceStage = 0;
if(barrier.oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
sourceStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
else if(barrier.srcAccessMask != 0)
sourceStage = RCore::accessFlagsToPipelineStage(barrier.srcAccessMask, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
else
sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
VkPipelineStageFlags destinationStage = 0;
if(barrier.newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
destinationStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
else if(barrier.dstAccessMask != 0)
destinationStage = RCore::accessFlagsToPipelineStage(barrier.dstAccessMask, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
else
destinationStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
vkCmdPipelineBarrier(_cmd_buffer, sourceStage, destinationStage, 0, 0, nullptr, 0, nullptr, 1, &barrier);
image.recordedInCmdBuffer();
vector_push_back_if_not_found(_cmd_resources, &image);
}
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)
@@ -71,32 +258,34 @@ namespace mlx
_state = state::idle;
}
void CmdBuffer::submitIdle() noexcept
void CmdBuffer::submitIdle(bool shouldWaitForExecution) noexcept
{
auto device = Render_Core::get().getDevice().get();
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");
return;
}
VkSubmitInfo submitInfo = {};
_fence.reset();
VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &_cmd_buffer;
VkFenceCreateInfo fenceCreateInfo = {};
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
VkFence fence;
vkCreateFence(device, &fenceCreateInfo, nullptr, &fence);
vkResetFences(device, 1, &fence);
VkResult res = vkQueueSubmit(Render_Core::get().getQueue().getGraphic(), 1, &submitInfo, fence);
VkResult res = vkQueueSubmit(Render_Core::get().getQueue().getGraphic(), 1, &submitInfo, _fence.get());
if(res != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan error : failed to submit a single time command buffer, %s", RCore::verbaliseResultVk(res));
_state = state::submitted;
vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX);
vkDestroyFence(device, fence, nullptr);
_state = state::ready;
if(shouldWaitForExecution)
waitForExecution();
}
void CmdBuffer::submit(Semaphore* semaphores) noexcept
{
MLX_PROFILE_FUNCTION();
std::array<VkSemaphore, 1> signalSemaphores;
std::array<VkSemaphore, 1> waitSemaphores;
@@ -107,11 +296,13 @@ namespace mlx
}
else
{
signalSemaphores[0] = nullptr;
waitSemaphores[0] = nullptr;
signalSemaphores[0] = VK_NULL_HANDLE;
waitSemaphores[0] = VK_NULL_HANDLE;
}
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
_fence.reset();
VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.waitSemaphoreCount = (semaphores == nullptr ? 0 : waitSemaphores.size());
@@ -128,10 +319,50 @@ namespace mlx
_state = state::submitted;
}
void CmdBuffer::updateSubmitState() noexcept
{
MLX_PROFILE_FUNCTION();
if(!_fence.isReady())
return;
for(CmdResource* res : _cmd_resources)
res->removedFromCmdBuffer();
_cmd_resources.clear();
_state = state::ready;
}
void CmdBuffer::preTransferBarrier() noexcept
{
MLX_PROFILE_FUNCTION();
VkMemoryBarrier memoryBarrier{};
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memoryBarrier.pNext = nullptr;
memoryBarrier.srcAccessMask = 0U;
memoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
vkCmdPipelineBarrier(_cmd_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &memoryBarrier, 0, nullptr, 0, nullptr);
}
void CmdBuffer::postTransferBarrier() noexcept
{
MLX_PROFILE_FUNCTION();
VkMemoryBarrier memoryBarrier{};
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memoryBarrier.pNext = nullptr;
memoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
memoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_UNIFORM_READ_BIT;
vkCmdPipelineBarrier(_cmd_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 1, &memoryBarrier, 0, nullptr, 0, nullptr);
}
void CmdBuffer::destroy() noexcept
{
MLX_PROFILE_FUNCTION();
_fence.destroy();
_cmd_buffer = VK_NULL_HANDLE;
_state = state::uninit;
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : destroyed command buffer");
#endif
}
}
+29 -5
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:25:42 by maldavid #+# #+# */
/* Updated: 2024/01/03 15:27:20 by maldavid ### ########.fr */
/* Updated: 2024/01/07 01:25:50 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -16,9 +16,13 @@
#include <mlx_profile.h>
#include <volk.h>
#include <renderer/core/vk_fence.h>
#include <vector>
namespace mlx
{
class Buffer;
class Image;
class CmdBuffer
{
public:
@@ -31,18 +35,32 @@ namespace mlx
submitted, // buffer has been submitted
};
enum class kind
{
single_time = 0,
long_time
};
public:
void init(class CmdManager* manager);
void init(class CmdPool* pool);
void init(kind type, class CmdManager* manager);
void init(kind type, class CmdPool* pool);
void destroy() noexcept;
void beginRecord(VkCommandBufferUsageFlags usage = 0);
void submit(class Semaphore* semaphores) noexcept;
void submitIdle() noexcept;
inline void waitForExecution() noexcept { _fence.waitAndReset(); _state = state::ready; }
void submitIdle(bool shouldWaitForExecution = true) noexcept; // TODO : handle `shouldWaitForExecution` as false by default (needs to modify CmdResources lifetimes to do so)
void updateSubmitState() noexcept;
inline void waitForExecution() noexcept { _fence.wait(); updateSubmitState(); _state = state::ready; }
inline void reset() noexcept { vkResetCommandBuffer(_cmd_buffer, 0); }
void endRecord();
void bindVertexBuffer(Buffer& buffer) noexcept;
void bindIndexBuffer(Buffer& buffer) noexcept;
void copyBuffer(Buffer& dst, Buffer& src) noexcept;
void copyBufferToImage(Buffer& buffer, Image& image) noexcept;
void copyImagetoBuffer(Image& image, Buffer& buffer) noexcept;
void transitionImageLayout(Image& image, VkImageLayout new_layout) noexcept;
inline bool isInit() const noexcept { return _state != state::uninit; }
inline bool isReadyToBeUsed() const noexcept { return _state == state::ready; }
inline bool isRecording() const noexcept { return _state == state::recording; }
@@ -54,10 +72,16 @@ namespace mlx
inline Fence& getFence() noexcept { return _fence; }
private:
void preTransferBarrier() noexcept;
void postTransferBarrier() noexcept;
private:
std::vector<class CmdResource*> _cmd_resources;
Fence _fence;
VkCommandBuffer _cmd_buffer = VK_NULL_HANDLE;
class CmdPool* _pool = nullptr;
state _state = state::uninit;
kind _type;
};
}
+62
View File
@@ -0,0 +1,62 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* cmd_resource.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/12/16 20:44:29 by maldavid #+# #+# */
/* Updated: 2024/01/11 05:12:42 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef __MLX_COMMAND_RESOURCE__
#define __MLX_COMMAND_RESOURCE__
#include <function.h>
#include <core/UUID.h>
namespace mlx
{
class CmdResource
{
friend class SingleTimeCmdManager;
public:
enum class state
{
in_cmd_buffer = 0,
out_cmd_buffer,
};
public:
CmdResource() : _uuid() {}
inline void recordedInCmdBuffer() noexcept { _state = state::in_cmd_buffer; }
inline void removedFromCmdBuffer() noexcept
{
_state = state::out_cmd_buffer;
if(_destroy_required && _destroyer)
{
_destroyer();
_destroy_required = false;
}
}
inline void setDestroyer(func::function<void(void)> functor) { _destroyer = functor; }
inline void requireDestroy() noexcept
{
if(_state == state::out_cmd_buffer && _destroyer)
_destroyer();
else
_destroy_required = true;
}
inline UUID getUUID() const noexcept { return _uuid; }
virtual ~CmdResource() = default;
private:
UUID _uuid;
state _state = state::out_cmd_buffer;
func::function<void(void)> _destroyer;
bool _destroy_required = false;
};
}
#endif
+32
View File
@@ -0,0 +1,32 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* drawable_resource.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/10 21:00:37 by maldavid #+# #+# */
/* Updated: 2024/01/11 01:21:15 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef __MLX_DRAWABLE_RESOURCE__
#define __MLX_DRAWABLE_RESOURCE__
#include <mlx_profile.h>
#include <volk.h>
#include <array>
namespace mlx
{
class DrawableResource
{
public:
DrawableResource() = default;
virtual void render(std::array<VkDescriptorSet, 2>& sets, class Renderer& renderer) = 0;
virtual void resetUpdate() {}
virtual ~DrawableResource() = default;
};
}
#endif
+18 -1
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/03 13:09:40 by maldavid ### ########.fr */
/* Updated: 2024/01/10 21:54:35 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <mlx_profile.h>
#include <core/errors.h>
#include <core/profiler.h>
#include <cstdio>
#define VMA_STATIC_VULKAN_FUNCTIONS 0
@@ -86,12 +87,16 @@ 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)
core::error::report(e_kind::fatal_error, "Graphics allocator : failed to allocate a buffer, %s", RCore::verbaliseResultVk(res));
if(name != nullptr)
{
Render_Core::get().getLayers().setDebugUtilsObjectNameEXT(VK_OBJECT_TYPE_BUFFER, (uint64_t)buffer, name);
vmaSetAllocationName(_allocator, allocation, name);
}
#ifdef DEBUG
core::error::report(e_kind::message, "Graphics Allocator : created new buffer");
#endif
@@ -101,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
@@ -111,12 +117,16 @@ 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)
core::error::report(e_kind::fatal_error, "Graphics allocator : failed to allocate an image, %s", RCore::verbaliseResultVk(res));
if(name != nullptr)
{
Render_Core::get().getLayers().setDebugUtilsObjectNameEXT(VK_OBJECT_TYPE_IMAGE, (uint64_t)image, name);
vmaSetAllocationName(_allocator, allocation, name);
}
#ifdef DEBUG
core::error::report(e_kind::message, "Graphics Allocator : created new image");
#endif
@@ -126,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
@@ -136,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));
@@ -143,6 +155,7 @@ namespace mlx
void GPUallocator::unmapMemory(VmaAllocation allocation) noexcept
{
MLX_PROFILE_FUNCTION();
vmaUnmapMemory(_allocator, allocation);
}
@@ -167,6 +180,7 @@ namespace mlx
void GPUallocator::flush(VmaAllocation allocation, VkDeviceSize size, VkDeviceSize offset) noexcept
{
MLX_PROFILE_FUNCTION();
vmaFlushAllocation(_allocator, allocation, offset, size);
}
@@ -179,5 +193,8 @@ namespace mlx
vmaDestroyAllocator(_allocator);
_active_buffers_allocations = 0;
_active_images_allocations = 0;
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : destroyed a graphics allocator");
#endif
}
}
+39 -1
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/17 23:33:34 by maldavid #+# #+# */
/* Updated: 2024/01/03 15:22:38 by maldavid ### ########.fr */
/* Updated: 2024/01/07 01:29:31 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -14,6 +14,7 @@
#include <mlx_profile.h>
#include <renderer/core/render_core.h>
#include <renderer/command/vk_cmd_buffer.h>
#include <mutex>
#ifdef DEBUG
@@ -75,6 +76,43 @@ namespace mlx
}
return nullptr;
}
VkPipelineStageFlags accessFlagsToPipelineStage(VkAccessFlags accessFlags, VkPipelineStageFlags stageFlags)
{
VkPipelineStageFlags stages = 0;
while(accessFlags != 0)
{
VkAccessFlagBits AccessFlag = static_cast<VkAccessFlagBits>(accessFlags & (~(accessFlags - 1)));
if(AccessFlag == 0 || (AccessFlag & (AccessFlag - 1)) != 0)
core::error::report(e_kind::fatal_error, "Vulkan : an error has been caught during access flag to pipeline stage operation");
accessFlags &= ~AccessFlag;
switch(AccessFlag)
{
case VK_ACCESS_INDIRECT_COMMAND_READ_BIT: stages |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; break;
case VK_ACCESS_INDEX_READ_BIT: stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; break;
case VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT: stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; break;
case VK_ACCESS_UNIFORM_READ_BIT: stages |= stageFlags | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; break;
case VK_ACCESS_INPUT_ATTACHMENT_READ_BIT: stages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; break;
case VK_ACCESS_SHADER_READ_BIT: stages |= stageFlags | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; break;
case VK_ACCESS_SHADER_WRITE_BIT: stages |= stageFlags | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; break;
case VK_ACCESS_COLOR_ATTACHMENT_READ_BIT: stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; break;
case VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT: stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; break;
case VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT: stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; break;
case VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT: stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; break;
case VK_ACCESS_TRANSFER_READ_BIT: stages |= VK_PIPELINE_STAGE_TRANSFER_BIT; break;
case VK_ACCESS_TRANSFER_WRITE_BIT: stages |= VK_PIPELINE_STAGE_TRANSFER_BIT; break;
case VK_ACCESS_HOST_READ_BIT: stages |= VK_PIPELINE_STAGE_HOST_BIT; break;
case VK_ACCESS_HOST_WRITE_BIT: stages |= VK_PIPELINE_STAGE_HOST_BIT; break;
case VK_ACCESS_MEMORY_READ_BIT: break;
case VK_ACCESS_MEMORY_WRITE_BIT: break;
default: core::error::report(e_kind::error, "Vulkan : unknown access flag"); break;
}
}
return stages;
}
}
void Render_Core::init()
+8 -3
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 19:16:32 by maldavid #+# #+# */
/* Updated: 2024/01/03 15:26:08 by maldavid ### ########.fr */
/* Updated: 2024/01/11 05:14:03 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -33,6 +33,7 @@ namespace mlx
{
std::optional<uint32_t> findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties, bool error = true);
const char* verbaliseResultVk(VkResult result);
VkPipelineStageFlags accessFlagsToPipelineStage(VkAccessFlags accessFlags, VkPipelineStageFlags stageFlags);
}
#ifdef DEBUG
@@ -47,19 +48,23 @@ namespace mlx
class Render_Core : public Singleton<Render_Core>
{
public:
Render_Core() = default;
friend class Singleton<Render_Core>;
public:
void init();
void destroy();
inline bool isInit() const noexcept { return _is_init; }
inline Instance& getInstance() noexcept { return _instance; }
inline Device& getDevice() noexcept { return _device; }
inline Queues& getQueue() noexcept { return _queues; }
inline GPUallocator& getAllocator() noexcept { return _allocator; }
inline ValidationLayers& getLayers() noexcept { return _layers; }
inline CmdBuffer& getSingleTimeCmdBuffer() noexcept { return _cmd_manager.getCmdBuffer(); }
inline SingleTimeCmdManager& getSingleTimeCmdManager() noexcept { return _cmd_manager; }
private:
Render_Core() = default;
~Render_Core() = default;
private:
+7 -4
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 19:14:29 by maldavid #+# #+# */
/* Updated: 2023/12/30 23:29:41 by maldavid ### ########.fr */
/* Updated: 2024/01/10 21:54:17 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -91,9 +91,6 @@ namespace mlx
return std::make_pair(deviceScore(device, surface), device);
});
vkDestroySurfaceKHR(Render_Core::get().getInstance().get(), surface, nullptr);
SDL_DestroyWindow(window);
using device_pair = std::pair<int, VkPhysicalDevice>;
std::sort(devices_score.begin(), devices_score.end(), [](const device_pair& a, const device_pair& b)
{
@@ -110,6 +107,9 @@ namespace mlx
vkGetPhysicalDeviceProperties(_physicalDevice, &props);
core::error::report(e_kind::message, "Vulkan : picked a physical device, %s", props.deviceName);
#endif
Render_Core::get().getQueue().findQueueFamilies(_physicalDevice, surface); // update queue indicies to current physical device
vkDestroySurfaceKHR(Render_Core::get().getInstance().get(), surface, nullptr);
SDL_DestroyWindow(window);
}
int Device::deviceScore(VkPhysicalDevice device, VkSurfaceKHR surface)
@@ -159,5 +159,8 @@ namespace mlx
{
vkDestroyDevice(_device, nullptr);
_device = VK_NULL_HANDLE;
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : destroyed a logical device");
#endif
}
}
+4 -1
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/02 17:53:06 by maldavid #+# #+# */
/* Updated: 2023/12/16 18:47:36 by maldavid ### ########.fr */
/* Updated: 2024/01/06 16:57:26 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -49,5 +49,8 @@ namespace mlx
if(_fence != VK_NULL_HANDLE)
vkDestroyFence(Render_Core::get().getDevice().get(), _fence, nullptr);
_fence = VK_NULL_HANDLE;
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : destroyed fence");
#endif
}
}
+4 -1
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 19:04:21 by maldavid #+# #+# */
/* Updated: 2023/12/31 00:40:10 by maldavid ### ########.fr */
/* Updated: 2024/01/10 21:54:06 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -84,5 +84,8 @@ namespace mlx
{
vkDestroyInstance(_instance, nullptr);
_instance = VK_NULL_HANDLE;
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : destroyed an instance");
#endif
}
}
+5 -2
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 19:02:42 by maldavid #+# #+# */
/* Updated: 2022/12/18 22:52:04 by maldavid ### ########.fr */
/* Updated: 2024/01/10 21:54:54 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -38,7 +38,7 @@ namespace mlx
_families->presentFamily = i;
if(_families->isComplete())
break;
return *_families;
i++;
}
@@ -64,5 +64,8 @@ namespace mlx
}
vkGetDeviceQueue(Render_Core::get().getDevice().get(), _families->graphicsFamily.value(), 0, &_graphicsQueue);
vkGetDeviceQueue(Render_Core::get().getDevice().get(), _families->presentFamily.value(), 0, &_presentQueue);
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : got graphics and present queues");
#endif
}
}
+9 -2
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 19:01:49 by maldavid #+# #+# */
/* Updated: 2024/01/03 15:26:31 by maldavid ### ########.fr */
/* Updated: 2024/01/08 23:46:23 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -17,6 +17,7 @@
#include <volk.h>
#include <optional>
#include <cstdint>
#include <core/errors.h>
namespace mlx
{
@@ -37,7 +38,13 @@ namespace mlx
inline VkQueue& getGraphic() noexcept { return _graphicsQueue; }
inline VkQueue& getPresent() noexcept { return _presentQueue; }
inline QueueFamilyIndices getFamilies() noexcept { return *_families; }
inline QueueFamilyIndices getFamilies() noexcept
{
if(_families.has_value())
return *_families;
core::error::report(e_kind::fatal_error, "Vulkan : cannot get queue families, not init");
return {}; // just to avoid warnings
}
private:
VkQueue _graphicsQueue;
+5 -2
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 19:01:08 by maldavid #+# #+# */
/* Updated: 2023/12/16 18:47:29 by maldavid ### ########.fr */
/* Updated: 2024/01/10 21:55:12 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -26,7 +26,7 @@ namespace mlx
(res = vkCreateSemaphore(Render_Core::get().getDevice().get(), &semaphoreInfo, nullptr, &_renderFinishedSemaphores)) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a synchronization object (semaphore), %s", RCore::verbaliseResultVk(res));
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : created new semaphore");
core::error::report(e_kind::message, "Vulkan : created new semaphores");
#endif
}
@@ -36,5 +36,8 @@ namespace mlx
_renderFinishedSemaphores = VK_NULL_HANDLE;
vkDestroySemaphore(Render_Core::get().getDevice().get(), _imageAvailableSemaphores, nullptr);
_imageAvailableSemaphores = VK_NULL_HANDLE;
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : destroyed semaphores");
#endif
}
}
+4 -1
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 18:58:49 by maldavid #+# #+# */
/* Updated: 2023/12/30 23:14:54 by maldavid ### ########.fr */
/* Updated: 2024/01/10 21:55:21 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -42,5 +42,8 @@ namespace mlx
{
vkDestroySurfaceKHR(Render_Core::get().getInstance().get(), _surface, nullptr);
_surface = VK_NULL_HANDLE;
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : destroyed a surface");
#endif
}
}
+40 -12
View File
@@ -6,12 +6,12 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/19 14:05:25 by maldavid #+# #+# */
/* Updated: 2024/01/03 13:11:27 by maldavid ### ########.fr */
/* Updated: 2024/01/10 21:55:54 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include "vk_validation_layers.h"
#include "render_core.h"
#include "vulkan/vulkan_core.h"
#include <core/errors.h>
#include <iostream>
@@ -25,6 +25,16 @@ namespace mlx
if constexpr(!enableValidationLayers)
return;
uint32_t extensionCount;
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
std::vector<VkExtensionProperties> extensions(extensionCount);
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data());
if(!std::any_of(extensions.begin(), extensions.end(), [=](VkExtensionProperties ext) { return std::strcmp(ext.extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0; }))
{
core::error::report(e_kind::warning , "Vulkan : %s not present, debug utils are disabled", VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
return;
}
VkDebugUtilsMessengerCreateInfoEXT createInfo{};
populateDebugMessengerCreateInfo(createInfo);
VkResult res = createDebugUtilsMessengerEXT(&createInfo, nullptr);
@@ -34,6 +44,14 @@ namespace mlx
else
core::error::report(e_kind::message, "Vulkan : enabled validation layers");
#endif
real_vkSetDebugUtilsObjectNameEXT = (PFN_vkSetDebugUtilsObjectNameEXT)vkGetInstanceProcAddr(Render_Core::get().getInstance().get(), "vkSetDebugUtilsObjectNameEXT");
if(!real_vkSetDebugUtilsObjectNameEXT)
core::error::report(e_kind::warning, "Vulkan : failed to set up debug object names, %s", RCore::verbaliseResultVk(VK_ERROR_EXTENSION_NOT_PRESENT));
#ifdef DEBUG
else
core::error::report(e_kind::message, "Vulkan : enabled debug object names");
#endif
}
bool ValidationLayers::checkValidationLayerSupport()
@@ -55,6 +73,19 @@ namespace mlx
});
}
VkResult ValidationLayers::setDebugUtilsObjectNameEXT(VkObjectType object_type, uint64_t object_handle, const char* object_name)
{
if(!real_vkSetDebugUtilsObjectNameEXT)
return VK_ERROR_EXTENSION_NOT_PRESENT;
VkDebugUtilsObjectNameInfoEXT name_info{};
name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
name_info.objectType = object_type;
name_info.objectHandle = object_handle;
name_info.pObjectName = object_name;
return real_vkSetDebugUtilsObjectNameEXT(Render_Core::get().getDevice().get(), &name_info);
}
void ValidationLayers::populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& createInfo)
{
createInfo = {};
@@ -64,11 +95,15 @@ namespace mlx
createInfo.pfnUserCallback = ValidationLayers::debugCallback;
}
void ValidationLayers::destroy()
{
if constexpr(enableValidationLayers)
{
destroyDebugUtilsMessengerEXT(nullptr);
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : destroyed validation layers");
#endif
}
}
VkResult ValidationLayers::createDebugUtilsMessengerEXT(const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator)
@@ -80,16 +115,9 @@ namespace mlx
VKAPI_ATTR VkBool32 VKAPI_CALL ValidationLayers::debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, [[maybe_unused]] VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, [[maybe_unused]] void* pUserData)
{
if(messageSeverity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
{
std::cout << '\n';
core::error::report(e_kind::error, std::string("Vulkan layer error: ") + pCallbackData->pMessage);
}
core::error::report(e_kind::error, pCallbackData->pMessage);
else if(messageSeverity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)
{
std::cout << '\n';
core::error::report(e_kind::warning, std::string("Vulkan layer warning: ") + pCallbackData->pMessage);
}
core::error::report(e_kind::warning, pCallbackData->pMessage);
return VK_FALSE;
}
+8 -2
View File
@@ -6,7 +6,7 @@
/* By: maldavid <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/19 14:04:25 by maldavid #+# #+# */
/* Updated: 2024/01/03 15:26:49 by maldavid ### ########.fr */
/* Updated: 2024/01/07 00:21:42 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -22,10 +22,15 @@ namespace mlx
{
public:
ValidationLayers() = default;
void init();
void destroy();
bool checkValidationLayerSupport();
void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& createInfo);
void destroy();
VkResult setDebugUtilsObjectNameEXT(VkObjectType object_type, uint64_t object_handle, const char* object_name);
~ValidationLayers() = default;
private:
@@ -35,6 +40,7 @@ namespace mlx
private:
VkDebugUtilsMessengerEXT _debugMessenger;
PFN_vkSetDebugUtilsObjectNameEXT real_vkSetDebugUtilsObjectNameEXT = nullptr;
};
}
@@ -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;
+18 -2
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/11 01:20:29 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;
@@ -121,24 +126,34 @@ namespace mlx
#endif
}
void Texture::render(Renderer& renderer, int x, int y)
void Texture::render(std::array<VkDescriptorSet, 2>& sets, Renderer& renderer, int x, int y)
{
MLX_PROFILE_FUNCTION();
if(_has_been_modified)
{
std::memcpy(_map, _cpu_map.data(), _cpu_map.size() * formatSize(getFormat()));
Image::copyFromBuffer(*_buf_map);
_has_been_modified = false;
}
if(!_set.isInit())
_set = renderer.getFragDescriptorSet().duplicate();
if(getLayout() != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
transitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
if(!_has_set_been_updated)
updateSet(0);
auto cmd = renderer.getActiveCmdBuffer();
_vbo.bind(renderer);
_ibo.bind(renderer);
glm::vec2 translate(x, y);
vkCmdPushConstants(cmd.get(), renderer.getPipeline().getPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(translate), &translate);
sets[1] = _set.get();
vkCmdBindDescriptorSets(renderer.getActiveCmdBuffer().get(), VK_PIPELINE_BIND_POINT_GRAPHICS, renderer.getPipeline().getPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr);
vkCmdDrawIndexed(cmd.get(), static_cast<uint32_t>(_ibo.getSize() / sizeof(uint16_t)), 1, 0, 0, 0);
}
void Texture::destroy() noexcept
{
MLX_PROFILE_FUNCTION();
Image::destroy();
if(_buf_map.has_value())
_buf_map->destroy();
@@ -148,6 +163,7 @@ namespace mlx
Texture stbTextureLoad(std::filesystem::path file, int* w, int* h)
{
MLX_PROFILE_FUNCTION();
Texture texture;
int channels;
uint8_t* data = nullptr;
+7 -17
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/03/08 02:24:58 by maldavid #+# #+# */
/* Updated: 2023/12/23 18:49:12 by kbz_8 ### ########.fr */
/* Updated: 2024/01/11 01:18:25 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -32,17 +32,17 @@ namespace mlx
Texture() = default;
void create(uint8_t* pixels, uint32_t width, uint32_t height, VkFormat format, const char* name, bool dedicated_memory = false);
void render(class Renderer& renderer, int x, int y);
void render(std::array<VkDescriptorSet, 2>& sets, class Renderer& renderer, int x, int y);
void destroy() noexcept override;
void setPixel(int x, int y, uint32_t color) noexcept;
int getPixel(int x, int y) noexcept;
inline void setDescriptor(DescriptorSet set) noexcept { _set = std::move(set); }
inline void setDescriptor(DescriptorSet&& set) noexcept { _set = set; }
inline VkDescriptorSet getSet() noexcept { return _set.isInit() ? _set.get() : VK_NULL_HANDLE; }
inline void updateSet(int binding) noexcept { _set.writeDescriptor(binding, *this); _has_been_updated = true; }
inline bool hasBeenUpdated() const noexcept { return _has_been_updated; }
inline constexpr void resetUpdate() noexcept { _has_been_updated = false; }
inline void updateSet(int binding) noexcept { _set.writeDescriptor(binding, *this); _has_set_been_updated = true; }
inline bool hasBeenUpdated() const noexcept { return _has_set_been_updated; }
inline constexpr void resetUpdate() noexcept { _has_set_been_updated = false; }
~Texture() = default;
@@ -60,20 +60,10 @@ namespace mlx
std::optional<Buffer> _buf_map = std::nullopt;
void* _map = nullptr;
bool _has_been_modified = false;
bool _has_been_updated = false;
bool _has_set_been_updated = false;
};
Texture stbTextureLoad(std::filesystem::path file, int* w, int* h);
struct TextureRenderData
{
Texture* texture;
int x;
int y;
TextureRenderData(Texture* _texture, int _x, int _y) : texture(_texture), x(_x), y(_y) {}
bool operator==(const TextureRenderData& rhs) const { return texture == rhs.texture && x == rhs.x && y == rhs.y; }
};
}
#endif
+5 -2
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/07 16:36:33 by maldavid #+# #+# */
/* Updated: 2023/12/23 18:49:25 by kbz_8 ### ########.fr */
/* Updated: 2024/01/08 21:42:31 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -31,12 +31,15 @@ namespace mlx
inline void setDescriptor(DescriptorSet&& set) noexcept { _set = set; }
inline VkDescriptorSet getSet() noexcept { return _set.isInit() ? _set.get() : VK_NULL_HANDLE; }
inline void updateSet(int binding) const noexcept { _set.writeDescriptor(binding, *this); }
inline void updateSet(int binding) noexcept { _set.writeDescriptor(binding, *this); _has_been_updated = true; }
inline bool hasBeenUpdated() const noexcept { return _has_been_updated; }
inline constexpr void resetUpdate() noexcept { _has_been_updated = false; }
~TextureAtlas() = default;
private:
DescriptorSet _set;
bool _has_been_updated = false;
};
}
+59
View File
@@ -0,0 +1,59 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* texture_descriptor.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/11 01:00:13 by maldavid #+# #+# */
/* Updated: 2024/01/11 01:21:52 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef __MLX_TEXTURE_DESCRIPTOR__
#define __MLX_TEXTURE_DESCRIPTOR__
#include <renderer/images/texture.h>
#include <renderer/core/drawable_resource.h>
#include <utils/combine_hash.h>
namespace mlx
{
struct TextureRenderDescriptor : public DrawableResource
{
Texture* texture;
int x;
int y;
TextureRenderDescriptor(Texture* _texture, int _x, int _y) : texture(_texture), x(_x), y(_y) {}
inline bool operator==(const TextureRenderDescriptor& rhs) const { return texture == rhs.texture && x == rhs.x && y == rhs.y; }
inline void render(std::array<VkDescriptorSet, 2>& sets, class Renderer& renderer) override
{
if(!texture->isInit())
return;
texture->render(sets, renderer, x, y);
}
inline void resetUpdate() override
{
if(!texture->isInit())
return;
texture->resetUpdate();
}
};
}
namespace std
{
template <>
struct hash<mlx::TextureRenderDescriptor>
{
std::size_t operator()(const mlx::TextureRenderDescriptor& d) const noexcept
{
std::size_t hash = 0;
mlx::hashCombine(hash, d.texture, d.x, d.y);
return hash;
}
};
}
#endif
+43
View File
@@ -0,0 +1,43 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* texture_manager.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/11 00:56:15 by maldavid #+# #+# */
/* Updated: 2024/01/11 01:49:12 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef __MLX_TEXTURE_MANAGER__
#define __MLX_TEXTURE_MANAGER__
#include <unordered_set>
#include <renderer/images/texture_descriptor.h>
#include <core/profiler.h>
#include <utility>
namespace mlx
{
class TextureManager
{
public:
TextureManager() = default;
inline void clear() { _texture_descriptors.clear(); }
inline std::pair<DrawableResource*, bool> registerTexture(Texture* texture, int x, int y)
{
MLX_PROFILE_FUNCTION();
auto res = _texture_descriptors.emplace(texture, x, y);
return std::make_pair(static_cast<DrawableResource*>(&const_cast<TextureRenderDescriptor&>(*res.first)), res.second);
}
~TextureManager() = default;
private:
std::unordered_set<TextureRenderDescriptor> _texture_descriptors;
};
}
#endif
+21 -97
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/01/25 11:59:07 by maldavid #+# #+# */
/* Updated: 2024/01/03 13:16:21 by maldavid ### ########.fr */
/* Updated: 2024/01/07 01:17:54 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -99,43 +99,6 @@ namespace mlx
return accessMask;
}
VkPipelineStageFlags accessFlagsToPipelineStage(VkAccessFlags accessFlags, VkPipelineStageFlags stageFlags)
{
VkPipelineStageFlags stages = 0;
while(accessFlags != 0)
{
VkAccessFlagBits AccessFlag = static_cast<VkAccessFlagBits>(accessFlags & (~(accessFlags - 1)));
if(AccessFlag == 0 || (AccessFlag & (AccessFlag - 1)) != 0)
core::error::report(e_kind::fatal_error, "Vulkan : an error has been caught during access flag to pipeline stage operation");
accessFlags &= ~AccessFlag;
switch(AccessFlag)
{
case VK_ACCESS_INDIRECT_COMMAND_READ_BIT: stages |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; break;
case VK_ACCESS_INDEX_READ_BIT: stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; break;
case VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT: stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; break;
case VK_ACCESS_UNIFORM_READ_BIT: stages |= stageFlags | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; break;
case VK_ACCESS_INPUT_ATTACHMENT_READ_BIT: stages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; break;
case VK_ACCESS_SHADER_READ_BIT: stages |= stageFlags | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; break;
case VK_ACCESS_SHADER_WRITE_BIT: stages |= stageFlags | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; break;
case VK_ACCESS_COLOR_ATTACHMENT_READ_BIT: stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; break;
case VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT: stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; break;
case VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT: stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; break;
case VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT: stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; break;
case VK_ACCESS_TRANSFER_READ_BIT: stages |= VK_PIPELINE_STAGE_TRANSFER_BIT; break;
case VK_ACCESS_TRANSFER_WRITE_BIT: stages |= VK_PIPELINE_STAGE_TRANSFER_BIT; break;
case VK_ACCESS_HOST_READ_BIT: stages |= VK_PIPELINE_STAGE_HOST_BIT; break;
case VK_ACCESS_HOST_WRITE_BIT: stages |= VK_PIPELINE_STAGE_HOST_BIT; break;
case VK_ACCESS_MEMORY_READ_BIT: break;
case VK_ACCESS_MEMORY_WRITE_BIT: break;
default: core::error::report(e_kind::error, "Vulkan : unknown access flag"); break;
}
}
return stages;
}
void Image::create(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, const char* name, bool dedicated_memory)
{
_width = width;
@@ -167,6 +130,9 @@ namespace mlx
}
_allocation = Render_Core::get().getAllocator().createImage(&imageInfo, &alloc_info, _image, name);
#ifdef DEBUG
_name = name;
#endif
}
void Image::createImageView(VkImageViewType type, VkImageAspectFlags aspectFlags) noexcept
@@ -185,6 +151,10 @@ namespace mlx
VkResult res = vkCreateImageView(Render_Core::get().getDevice().get(), &viewInfo, nullptr, &_image_view);
if(res != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create an image view, %s", RCore::verbaliseResultVk(res));
#ifdef DEBUG
else
Render_Core::get().getLayers().setDebugUtilsObjectNameEXT(VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)_image_view, _name.c_str());
#endif
}
void Image::createSampler() noexcept
@@ -204,7 +174,11 @@ namespace mlx
VkResult res = vkCreateSampler(Render_Core::get().getDevice().get(), &info, nullptr, &_sampler);
if(res != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create an image, %s", RCore::verbaliseResultVk(res));
core::error::report(e_kind::fatal_error, "Vulkan : failed to create an image sampler, %s", RCore::verbaliseResultVk(res));
#ifdef DEBUG
else
Render_Core::get().getLayers().setDebugUtilsObjectNameEXT(VK_OBJECT_TYPE_SAMPLER, (uint64_t)_sampler, _name.c_str());
#endif
}
void Image::copyFromBuffer(Buffer& buffer)
@@ -215,18 +189,7 @@ namespace mlx
VkImageLayout layout_save = _layout;
transitionLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &cmd);
VkBufferImageCopy region{};
region.bufferOffset = 0;
region.bufferRowLength = 0;
region.bufferImageHeight = 0;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageOffset = { 0, 0, 0 };
region.imageExtent = { _width, _height, 1 };
vkCmdCopyBufferToImage(cmd.get(), buffer.get(), _image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
cmd.copyBufferToImage(buffer, *this);
transitionLayout(layout_save, &cmd);
@@ -242,18 +205,7 @@ namespace mlx
VkImageLayout layout_save = _layout;
transitionLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &cmd);
VkBufferImageCopy region{};
region.bufferOffset = 0;
region.bufferRowLength = 0;
region.bufferImageHeight = 0;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageOffset = { 0, 0, 0 };
region.imageExtent = { _width, _height, 1 };
vkCmdCopyImageToBuffer(cmd.get(), _image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer.get(), 1, &region);
cmd.copyImagetoBuffer(*this, buffer);
transitionLayout(layout_save, &cmd);
@@ -273,40 +225,7 @@ namespace mlx
cmd->beginRecord();
}
VkImageMemoryBarrier barrier{};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.oldLayout = _layout;
barrier.newLayout = new_layout;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = _image;
barrier.subresourceRange.aspectMask = isDepthFormat(_format) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.levelCount = 1;
barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.layerCount = 1;
barrier.srcAccessMask = layoutToAccessMask(_layout, false);
barrier.dstAccessMask = layoutToAccessMask(new_layout, true);
if(isStencilFormat(_format))
barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
VkPipelineStageFlags sourceStage = 0;
if(barrier.oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
sourceStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
else if(barrier.srcAccessMask != 0)
sourceStage = accessFlagsToPipelineStage(barrier.srcAccessMask, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
else
sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
VkPipelineStageFlags destinationStage = 0;
if(barrier.newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
destinationStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
else if(barrier.dstAccessMask != 0)
destinationStage = accessFlagsToPipelineStage(barrier.dstAccessMask, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
else
destinationStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
vkCmdPipelineBarrier(cmd->get(), sourceStage, destinationStage, 0, 0, nullptr, 0, nullptr, 1, &barrier);
cmd->transitionImageLayout(*this, new_layout);
if(singleTime)
{
@@ -331,6 +250,9 @@ namespace mlx
}
void Image::destroy() noexcept
{
// not creating destroyer in `create` as some image may be copied (and so `this` will be invalid)
CmdResource::setDestroyer([this]()
{
destroySampler();
destroyImageView();
@@ -338,6 +260,8 @@ namespace mlx
if(_image != VK_NULL_HANDLE)
Render_Core::get().getAllocator().destroyImage(_allocation, _image);
_image = VK_NULL_HANDLE;
});
CmdResource::requireDestroy();
}
uint32_t formatSize(VkFormat format)
+14 -2
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/01/25 11:54:21 by maldavid #+# #+# */
/* Updated: 2024/01/03 15:28:07 by maldavid ### ########.fr */
/* Updated: 2024/01/07 01:20:31 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -18,14 +18,23 @@
#include <cstddef>
#include <vector>
#include <vma.h>
#include <renderer/core/cmd_resource.h>
#include <renderer/command/vk_cmd_buffer.h>
#include <renderer/command/vk_cmd_pool.h>
#ifdef DEBUG
#include <string>
#endif
namespace mlx
{
uint32_t formatSize(VkFormat format);
bool isStencilFormat(VkFormat format);
bool isDepthFormat(VkFormat format);
VkFormat bitsToFormat(uint32_t bits);
VkPipelineStageFlags layoutToAccessMask(VkImageLayout layout, bool isDestination);
class Image
class Image : public CmdResource
{
friend class SwapChain;
@@ -70,6 +79,9 @@ namespace mlx
VkImage _image = VK_NULL_HANDLE;
VkImageView _image_view = VK_NULL_HANDLE;
VkSampler _sampler = VK_NULL_HANDLE;
#ifdef DEBUG
std::string _name;
#endif
VkFormat _format;
VkImageTiling _tiling;
VkImageLayout _layout = VK_IMAGE_LAYOUT_UNDEFINED;
+5 -1
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/18 21:27:38 by maldavid #+# #+# */
/* Updated: 2024/01/03 13:16:57 by maldavid ### ########.fr */
/* Updated: 2024/01/10 21:53:38 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -320,5 +320,9 @@ namespace mlx
{
vkDestroyPipeline(Render_Core::get().getDevice().get(), _graphicsPipeline, nullptr);
vkDestroyPipelineLayout(Render_Core::get().getDevice().get(), _pipelineLayout, nullptr);
_graphicsPipeline = VK_NULL_HANDLE;
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : destroyed a graphics pipeline");
#endif
}
}
+9 -7
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/11 00:06:01 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
void PixelPutPipeline::render(std::array<VkDescriptorSet, 2>& sets, Renderer& renderer) noexcept
{
MLX_PROFILE_FUNCTION();
if(_has_been_modified)
{
std::memcpy(_buffer_map, _cpu_map.data(), sizeof(uint32_t) * _cpu_map.size());
@@ -50,15 +55,12 @@ namespace mlx
_has_been_modified = false;
}
_texture.updateSet(0);
}
void PixelPutPipeline::render(Renderer& renderer) noexcept
{
_texture.render(renderer, 0, 0);
_texture.render(sets, renderer, 0, 0);
}
void PixelPutPipeline::destroy() noexcept
{
MLX_PROFILE_FUNCTION();
_buffer.destroy();
_texture.destroy();
}
+2 -4
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/03/31 13:18:50 by maldavid #+# #+# */
/* Updated: 2023/12/14 18:24:58 by maldavid ### ########.fr */
/* Updated: 2024/01/11 00:06:05 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -27,9 +27,7 @@ namespace mlx
void init(uint32_t width, uint32_t height, class Renderer& renderer) noexcept;
void setPixel(int x, int y, uint32_t color) noexcept;
void present() noexcept;
void render(class Renderer& renderer) noexcept;
inline VkDescriptorSet getDescriptorSet() noexcept { return _texture.getSet(); }
void render(std::array<VkDescriptorSet, 2>& sets, class Renderer& renderer) noexcept;
void clear();
void destroy() noexcept;
+7 -3
View File
@@ -6,19 +6,20 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/18 17:25:16 by maldavid #+# #+# */
/* Updated: 2023/12/24 16:04:04 by kbz_8 ### ########.fr */
/* Updated: 2024/01/10 14:18:35 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <mutex>
#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);
@@ -71,6 +72,7 @@ namespace mlx
bool Renderer::beginFrame()
{
MLX_PROFILE_FUNCTION();
auto device = Render_Core::get().getDevice().get();
if(_render_target == nullptr)
@@ -119,6 +121,7 @@ namespace mlx
void Renderer::endFrame()
{
MLX_PROFILE_FUNCTION();
_pass.end(getActiveCmdBuffer());
_cmd.getCmdBuffer(_current_frame_index).endRecord();
@@ -150,13 +153,14 @@ namespace mlx
}
else
{
_cmd.getCmdBuffer(_current_frame_index).submitIdle();
_cmd.getCmdBuffer(_current_frame_index).submitIdle(true);
_current_frame_index = 0;
}
}
void Renderer::destroy()
{
MLX_PROFILE_FUNCTION();
vkDeviceWaitIdle(Render_Core::get().getDevice().get());
_pipeline.destroy();
-1
View File
@@ -13,7 +13,6 @@
#ifndef __RENDERER__
#define __RENDERER__
#include <array>
#include <vector>
#include <memory>
+4 -1
View File
@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:18:06 by maldavid #+# #+# */
/* Updated: 2024/01/03 13:17:27 by maldavid ### ########.fr */
/* Updated: 2024/01/10 21:52:51 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -45,5 +45,8 @@ namespace mlx
{
vkDestroyFramebuffer(Render_Core::get().getDevice().get(), _framebuffer, nullptr);
_framebuffer = VK_NULL_HANDLE;
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : destroyed a framebuffer");
#endif
}
}
+7 -1
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 21:53:03 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());
@@ -109,5 +112,8 @@ namespace mlx
{
vkDestroyRenderPass(Render_Core::get().getDevice().get(), _renderPass, nullptr);
_renderPass = VK_NULL_HANDLE;
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : destroyed a renderpass");
#endif
}
}
-128
View File
@@ -1,128 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* text_pipeline.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/06 16:41:13 by maldavid #+# #+# */
/* Updated: 2023/12/14 17:49:37 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <renderer/text_pipeline.h>
#include <fstream>
#include <utils/dogica_ttf.h>
#include <iostream>
#include <cstdio>
#define STB_RECT_PACK_IMPLEMENTATION
#include <stb_rect_pack.h>
#include <core/memory.h>
#define STB_TRUETYPE_IMPLEMENTATION
#define STB_malloc(x, u) ((void)(u), MemManager::malloc(x))
#define STB_free(x, u) ((void)(u), MemManager::free(x))
#include <stb_truetype.h>
constexpr const int RANGE = 1024;
namespace mlx
{
TextDrawData::TextDrawData(std::string _text, int _color, int _x, int _y) :
x(_x), y(_y), color(_color),
text(std::move(_text))
{}
void TextDrawData::init(TextLibrary& library, Font* const font) noexcept
{
std::vector<Vertex> vertexData;
std::vector<uint16_t> indexData;
float stb_x = 0.0f;
float stb_y = 0.0f;
for(char c : text)
{
if(c < 32)
continue;
stbtt_aligned_quad q;
stbtt_GetPackedQuad(font->getCharData().data(), RANGE, RANGE, c - 32, &stb_x, &stb_y, &q, 1);
std::size_t index = vertexData.size();
vertexData.emplace_back(glm::vec2{q.x0, q.y0}, glm::vec4{color & 0x00FF0000, color & 0x0000FF00, color & 0x000000FF, 0xFFFFFFFF}, glm::vec2{q.s0, q.t0});
vertexData.emplace_back(glm::vec2{q.x1, q.y0}, glm::vec4{color & 0x00FF0000, color & 0x0000FF00, color & 0x000000FF, 0xFFFFFFFF}, glm::vec2{q.s1, q.t0});
vertexData.emplace_back(glm::vec2{q.x1, q.y1}, glm::vec4{color & 0x00FF0000, color & 0x0000FF00, color & 0x000000FF, 0xFFFFFFFF}, glm::vec2{q.s1, q.t1});
vertexData.emplace_back(glm::vec2{q.x0, q.y1}, glm::vec4{color & 0x00FF0000, color & 0x0000FF00, color & 0x000000FF, 0xFFFFFFFF}, glm::vec2{q.s0, q.t1});
indexData.emplace_back(index + 0);
indexData.emplace_back(index + 1);
indexData.emplace_back(index + 2);
indexData.emplace_back(index + 2);
indexData.emplace_back(index + 3);
indexData.emplace_back(index + 0);
}
std::shared_ptr<TextData> text_data = std::make_shared<TextData>();
text_data->init(text, font, std::move(vertexData), std::move(indexData));
id = library.addTextToLibrary(text_data);
#ifdef DEBUG
core::error::report(e_kind::message, "Text put : registered new text to render");
#endif
}
void TextPutPipeline::init(Renderer* renderer) noexcept
{
_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)
{
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
_font_in_use = &const_cast<Font&>(*_font_set.emplace(*_renderer, filepath, scale).first);
}
void TextPutPipeline::put(int x, int y, int color, std::string str)
{
auto res = _drawlist.emplace(std::move(str), color, x, y);
if(res.second)
const_cast<TextDrawData&>(*res.first).init(_library, _font_in_use);
else
{
auto text_ptr = _library.getTextData(res.first->id);
if(*_font_in_use != text_ptr->getFontInUse())
{
_library.removeTextFromLibrary(res.first->id);
const_cast<TextDrawData&>(*res.first).init(_library, _font_in_use);
}
}
}
void TextPutPipeline::render(std::array<VkDescriptorSet, 2>& sets)
{
for(auto& draw : _drawlist)
{
std::shared_ptr<TextData> draw_data = _library.getTextData(draw.id);
const TextureAtlas& atlas = draw_data->getFontInUse().getAtlas();
draw_data->bind(*_renderer);
atlas.updateSet(0);
sets[1] = const_cast<TextureAtlas&>(atlas).getSet();
vkCmdBindDescriptorSets(_renderer->getActiveCmdBuffer().get(), VK_PIPELINE_BIND_POINT_GRAPHICS, _renderer->getPipeline().getPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr);
atlas.render(*_renderer, draw.x, draw.y, draw_data->getIBOsize());
}
}
void TextPutPipeline::destroy() noexcept
{
_library.clearLibrary();
_drawlist.clear();
_font_set.clear();
}
}
-82
View File
@@ -1,82 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* text_pipeline.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/06 16:24:11 by maldavid #+# #+# */
/* Updated: 2023/12/14 17:39:51 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef __MLX_TEXT_PIPELINE__
#define __MLX_TEXT_PIPELINE__
#include <renderer/renderer.h>
#include <renderer/images/texture_atlas.h>
#include <string>
#include <stb_truetype.h>
#include <cstdint>
#include <unordered_set>
#include <renderer/text_library.h>
#include <mlx_profile.h>
#include <utils/combine_hash.h>
namespace mlx
{
struct TextDrawData
{
TextID id;
int x;
int y;
int color;
std::string text;
TextDrawData(std::string text, int _color, int _x, int _y);
void init(TextLibrary& library, Font* const font) noexcept;
bool operator==(const TextDrawData& rhs) const { return text == rhs.text && x == rhs.x && y == rhs.y && color == rhs.color; }
TextDrawData() = default;
};
}
namespace std
{
template <>
struct hash<mlx::TextDrawData>
{
std::size_t operator()(const mlx::TextDrawData& d) const noexcept
{
std::size_t hash = 0;
mlx::hashCombine(hash, d.text, d.x, d.y, d.color);
return hash;
}
};
}
namespace mlx
{
class TextPutPipeline
{
public:
TextPutPipeline() = default;
void init(Renderer* renderer) noexcept;
void put(int x, int y, int color, std::string str);
inline void clear() { _drawlist.clear(); _library.clearLibrary(); }
void loadFont(const std::filesystem::path& filepath, float scale);
void render(std::array<VkDescriptorSet, 2>& sets);
void destroy() noexcept;
~TextPutPipeline() = default;
private:
std::unordered_set<Font> _font_set;
TextLibrary _library;
std::unordered_set<TextDrawData> _drawlist;
Renderer* _renderer = nullptr;
Font* _font_in_use = nullptr;
};
}
#endif
@@ -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/11 01:23:20 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <renderer/font.h>
#include <renderer/texts/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();
}
}
@@ -1,24 +1,24 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* text_library.cpp :+: :+: :+: */
/* text.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* 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 */
/* Created: 2024/01/11 00:11:56 by maldavid #+# #+# */
/* Updated: 2024/01/11 03:31:57 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <renderer/text_library.h>
#include <core/errors.h>
#include <core/profiler.h>
#include <renderer/texts/text.h>
#include <renderer/renderer.h>
#include <algorithm>
namespace mlx
{
void TextData::init(std::string text, Font const* font, std::vector<Vertex> vbo_data, std::vector<uint16_t> ibo_data)
void Text::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
@@ -32,57 +32,24 @@ namespace mlx
#endif
}
void TextData::bind(Renderer& renderer) noexcept
void Text::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)
void Text::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
void Text::destroy() noexcept
{
MLX_PROFILE_FUNCTION();
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
_vbo[i].destroy();
_ibo.destroy();
}
std::shared_ptr<TextData> TextLibrary::getTextData(TextID id)
{
if(!_cache.count(id))
core::error::report(e_kind::fatal_error, "Text Library : wrong text ID '%d'", id);
return _cache[id];
}
TextID TextLibrary::addTextToLibrary(std::shared_ptr<TextData> text)
{
auto it = std::find_if(_cache.begin(), _cache.end(), [=](const std::pair<TextID, std::shared_ptr<TextData>>& v)
{
return v.second->getText() == text->getText();
});
if(it != _cache.end())
return it->first;
_cache[_current_id] = text;
_current_id++;
return _current_id - 1;
}
void TextLibrary::removeTextFromLibrary(TextID id)
{
if(_cache.count(id))
{
_cache[id]->destroy();
_cache.erase(id);
}
}
void TextLibrary::clearLibrary()
{
for(auto [id, text] : _cache)
text->destroy();
_cache.clear();
}
}
@@ -1,38 +1,30 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* text_library.h :+: :+: :+: */
/* text.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/10 11:52:30 by maldavid #+# #+# */
/* Updated: 2023/12/12 23:07:13 by kbz_8 ### ########.fr */
/* Created: 2024/01/11 00:09:04 by maldavid #+# #+# */
/* Updated: 2024/01/11 00:13:25 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef __MLX_TEXT_LIBRARY__
#define __MLX_TEXT_LIBRARY__
#ifndef __MLX_TEXT__
#define __MLX_TEXT__
#include <renderer/buffers/vk_vbo.h>
#include <renderer/buffers/vk_ibo.h>
#include <string>
#include <unordered_map>
#include <memory>
#include <vector>
#include <cstdint>
#include <mlx_profile.h>
#include <renderer/font.h>
#include <renderer/core/render_core.h>
#include <renderer/texts/font.h>
#include <renderer/buffers/vk_ibo.h>
#include <renderer/buffers/vk_vbo.h>
namespace mlx
{
using TextID = uint32_t;
constexpr TextID nulltext = 0;
class TextData
class Text
{
public:
TextData() = default;
Text() = default;
void init(std::string text, Font const* font, std::vector<Vertex> vbo_data, std::vector<uint16_t> ibo_data);
void bind(class Renderer& renderer) noexcept;
@@ -42,7 +34,7 @@ namespace mlx
inline const std::string& getText() const { return _text; }
void destroy() noexcept;
~TextData() = default;
~Text() = default;
private:
std::array<D_VBO, MAX_FRAMES_IN_FLIGHT> _vbo;
@@ -50,24 +42,6 @@ namespace mlx
std::string _text;
Font const* _font = nullptr;
};
class TextLibrary
{
public:
TextLibrary() = default;
std::shared_ptr<TextData> getTextData(TextID id);
TextID addTextToLibrary(std::shared_ptr<TextData> text);
void removeTextFromLibrary(TextID id);
void clearLibrary();
~TextLibrary() = default;
private:
std::unordered_map<TextID, std::shared_ptr<TextData>> _cache;
TextID _current_id = 1;
};
}
#endif
+104
View File
@@ -0,0 +1,104 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* text_descriptor.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/11 00:23:11 by maldavid #+# #+# */
/* Updated: 2024/01/11 03:40:54 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <core/profiler.h>
#include <renderer/texts/text_descriptor.h>
#include <renderer/images/texture_atlas.h>
#include <renderer/texts/font.h>
#include <renderer/texts/text.h>
#define STB_RECT_PACK_IMPLEMENTATION
#include <stb_rect_pack.h>
#include <core/memory.h>
#define STB_TRUETYPE_IMPLEMENTATION
#define STB_malloc(x, u) ((void)(u), MemManager::malloc(x))
#define STB_free(x, u) ((void)(u), MemManager::free(x))
#include <stb_truetype.h>
constexpr const int RANGE = 1024;
namespace mlx
{
TextDrawDescriptor::TextDrawDescriptor(std::string text, uint32_t _color, int _x, int _y) : color(_color), x(_x), y(_y), _text(std::move(text))
{}
void TextDrawDescriptor::init(Font* const font) noexcept
{
MLX_PROFILE_FUNCTION();
std::vector<Vertex> vertexData;
std::vector<uint16_t> indexData;
float stb_x = 0.0f;
float stb_y = 0.0f;
for(char c : _text)
{
if(c < 32)
continue;
stbtt_aligned_quad q;
stbtt_GetPackedQuad(font->getCharData().data(), RANGE, RANGE, c - 32, &stb_x, &stb_y, &q, 1);
std::size_t index = vertexData.size();
glm::vec4 vertex_color = {
static_cast<float>((color & 0x000000FF)) / 255.f,
static_cast<float>((color & 0x0000FF00) >> 8) / 255.f,
static_cast<float>((color & 0x00FF0000) >> 16) / 255.f,
static_cast<float>((color & 0xFF000000) >> 24) / 255.f
};
vertexData.emplace_back(glm::vec2{q.x0, q.y0}, vertex_color, glm::vec2{q.s0, q.t0});
vertexData.emplace_back(glm::vec2{q.x1, q.y0}, vertex_color, glm::vec2{q.s1, q.t0});
vertexData.emplace_back(glm::vec2{q.x1, q.y1}, vertex_color, glm::vec2{q.s1, q.t1});
vertexData.emplace_back(glm::vec2{q.x0, q.y1}, vertex_color, glm::vec2{q.s0, q.t1});
indexData.emplace_back(index + 0);
indexData.emplace_back(index + 1);
indexData.emplace_back(index + 2);
indexData.emplace_back(index + 2);
indexData.emplace_back(index + 3);
indexData.emplace_back(index + 0);
}
std::shared_ptr<Text> text_data = std::make_shared<Text>();
text_data->init(_text, font, std::move(vertexData), std::move(indexData));
id = TextLibrary::get().addTextToLibrary(text_data);
#ifdef DEBUG
core::error::report(e_kind::message, "Text put : registered new text to render");
#endif
}
void TextDrawDescriptor::render(std::array<VkDescriptorSet, 2>& sets, Renderer& renderer)
{
MLX_PROFILE_FUNCTION();
std::shared_ptr<Text> draw_data = TextLibrary::get().getTextData(id);
TextureAtlas& atlas = const_cast<TextureAtlas&>(draw_data->getFontInUse().getAtlas());
draw_data->bind(renderer);
if(atlas.getSet() == VK_NULL_HANDLE)
atlas.setDescriptor(renderer.getFragDescriptorSet().duplicate());
if(!atlas.hasBeenUpdated())
atlas.updateSet(0);
sets[1] = const_cast<TextureAtlas&>(atlas).getSet();
vkCmdBindDescriptorSets(renderer.getActiveCmdBuffer().get(), VK_PIPELINE_BIND_POINT_GRAPHICS, renderer.getPipeline().getPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr);
atlas.render(renderer, x, y, draw_data->getIBOsize());
}
void TextDrawDescriptor::resetUpdate()
{
std::shared_ptr<Text> draw_data = TextLibrary::get().getTextData(id);
TextureAtlas& atlas = const_cast<TextureAtlas&>(draw_data->getFontInUse().getAtlas());
atlas.resetUpdate();
}
}
+65
View File
@@ -0,0 +1,65 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* text_descriptor.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/11 00:13:34 by maldavid #+# #+# */
/* Updated: 2024/01/11 04:28:58 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef __MLX_TEXT_DESCRIPTOR__
#define __MLX_TEXT_DESCRIPTOR__
#include <string>
#include <mlx_profile.h>
#include <volk.h>
#include <utils/combine_hash.h>
#include <renderer/core/drawable_resource.h>
#include <renderer/texts/text_library.h>
#include <array>
namespace mlx
{
class TextDrawDescriptor : public DrawableResource
{
friend class std::hash<TextDrawDescriptor>;
public:
TextID id;
uint32_t color;
int x;
int y;
public:
TextDrawDescriptor(std::string text, uint32_t _color, int _x, int _y);
void init(Font* const font) noexcept;
bool operator==(const TextDrawDescriptor& rhs) const { return _text == rhs._text && x == rhs.x && y == rhs.y && color == rhs.color; }
void render(std::array<VkDescriptorSet, 2>& sets, Renderer& renderer) override;
void resetUpdate() override;
TextDrawDescriptor() = default;
private:
std::string _text;
};
}
namespace std
{
template <>
struct hash<mlx::TextDrawDescriptor>
{
std::size_t operator()(const mlx::TextDrawDescriptor& d) const noexcept
{
std::size_t hash = 0;
mlx::hashCombine(hash, d.x, d.y, d.color, d._text);
return hash;
}
};
}
#endif
+67
View File
@@ -0,0 +1,67 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* text_library.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/10 11:59:57 by maldavid #+# #+# */
/* Updated: 2024/01/11 05:19:24 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <iostream>
#include <renderer/texts/text_library.h>
#include <renderer/texts/text.h>
#include <core/errors.h>
#include <renderer/renderer.h>
#include <algorithm>
#include <core/profiler.h>
namespace mlx
{
std::shared_ptr<Text> TextLibrary::getTextData(TextID id)
{
MLX_PROFILE_FUNCTION();
if(!_cache.count(id) || std::find(_invalid_ids.begin(), _invalid_ids.end(), id) != _invalid_ids.end())
core::error::report(e_kind::fatal_error, "Text Library : wrong text ID '%d'", id);
return _cache[id];
}
TextID TextLibrary::addTextToLibrary(std::shared_ptr<Text> text)
{
MLX_PROFILE_FUNCTION();
auto it = std::find_if(_cache.begin(), _cache.end(), [&](const std::pair<TextID, std::shared_ptr<Text>>& v)
{
return v.second->getText() == text->getText() && std::find(_invalid_ids.begin(), _invalid_ids.end(), v.first) == _invalid_ids.end();
});
if(it != _cache.end())
return it->first;
_cache[_current_id] = text;
_current_id++;
return _current_id - 1;
}
void TextLibrary::removeTextFromLibrary(TextID id)
{
MLX_PROFILE_FUNCTION();
if(!_cache.count(id) || std::find(_invalid_ids.begin(), _invalid_ids.end(), id) != _invalid_ids.end())
{
core::error::report(e_kind::warning, "Text Library : trying to remove a text with an unkown or invalid ID '%d'", id);
return;
}
_cache[id]->destroy();
_invalid_ids.push_back(id);
}
void TextLibrary::clearLibrary()
{
MLX_PROFILE_FUNCTION();
for(auto& [id, text] : _cache)
{
text->destroy();
_invalid_ids.push_back(id);
}
// do not `_cache.clear();` as it releases the texts and may not destroy Vertex and Index buffers that are in use by command buffers
}
}
+55
View File
@@ -0,0 +1,55 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* text_library.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/10 11:52:30 by maldavid #+# #+# */
/* Updated: 2024/01/11 05:08:04 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef __MLX_TEXT_LIBRARY__
#define __MLX_TEXT_LIBRARY__
#include <renderer/buffers/vk_vbo.h>
#include <renderer/buffers/vk_ibo.h>
#include <string>
#include <unordered_map>
#include <memory>
#include <vector>
#include <cstdint>
#include <mlx_profile.h>
#include <renderer/texts/font.h>
#include <renderer/core/render_core.h>
#include <utils/singleton.h>
namespace mlx
{
using TextID = uint32_t;
constexpr TextID nulltext = 0;
class TextLibrary : public Singleton<TextLibrary>
{
friend class Singleton<TextLibrary>;
public:
std::shared_ptr<class Text> getTextData(TextID id);
TextID addTextToLibrary(std::shared_ptr<Text> text);
void removeTextFromLibrary(TextID id);
void clearLibrary();
private:
TextLibrary() = default;
~TextLibrary() = default;
private:
std::unordered_map<TextID, std::shared_ptr<class Text>> _cache;
std::vector<TextID> _invalid_ids;
TextID _current_id = 1;
};
}
#endif
+66
View File
@@ -0,0 +1,66 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* text_manager.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/06 16:41:13 by maldavid #+# #+# */
/* Updated: 2024/01/11 04:54:16 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <renderer/texts/text_descriptor.h>
#include <renderer/texts/text_library.h>
#include <renderer/texts/text.h>
#include <renderer/texts/text_manager.h>
#include <array>
#include <core/profiler.h>
#include <fstream>
#include <utils/dogica_ttf.h>
#include <cstdio>
namespace mlx
{
void TextManager::init(Renderer& renderer) noexcept
{
MLX_PROFILE_FUNCTION();
_font_in_use = &const_cast<Font&>(*_font_set.emplace(renderer, "default", dogica_ttf, 6.0f).first);
}
void TextManager::loadFont(Renderer& renderer, 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
_font_in_use = &const_cast<Font&>(*_font_set.emplace(renderer, filepath, scale).first);
}
std::pair<DrawableResource*, bool> TextManager::registerText(int x, int y, uint32_t color, std::string str)
{
MLX_PROFILE_FUNCTION();
auto res = _text_descriptors.emplace(std::move(str), color, x, y);
if(res.second)
{
const_cast<TextDrawDescriptor&>(*res.first).init(_font_in_use);
return std::make_pair(static_cast<DrawableResource*>(&const_cast<TextDrawDescriptor&>(*res.first)), true);
}
auto text_ptr = TextLibrary::get().getTextData(res.first->id);
if(*_font_in_use != text_ptr->getFontInUse())
{
TextLibrary::get().removeTextFromLibrary(res.first->id);
const_cast<TextDrawDescriptor&>(*res.first).init(_font_in_use);
}
return std::make_pair(static_cast<DrawableResource*>(&const_cast<TextDrawDescriptor&>(*res.first)), false);
}
void TextManager::destroy() noexcept
{
MLX_PROFILE_FUNCTION();
_text_descriptors.clear();
_font_set.clear();
}
}
+48
View File
@@ -0,0 +1,48 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* text_manager.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/06 16:24:11 by maldavid #+# #+# */
/* Updated: 2024/01/11 05:18:42 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef __MLX_TEXT_MANAGER__
#define __MLX_TEXT_MANAGER__
#include <renderer/renderer.h>
#include <renderer/images/texture_atlas.h>
#include <string>
#include <stb_truetype.h>
#include <cstdint>
#include <unordered_set>
#include <mlx_profile.h>
#include <renderer/texts/text_descriptor.h>
#include <renderer/texts/text_library.h>
namespace mlx
{
class TextManager
{
public:
TextManager() = default;
void init(Renderer& renderer) noexcept;
std::pair<DrawableResource*, bool> registerText(int x, int y, uint32_t color, std::string str);
inline void clear() { _text_descriptors.clear(); TextLibrary::get().clearLibrary(); }
void loadFont(Renderer& renderer, const std::filesystem::path& filepath, float scale);
void destroy() noexcept;
~TextManager() = default;
private:
std::unordered_set<TextDrawDescriptor> _text_descriptors;
std::unordered_set<Font> _font_set;
Font* _font_in_use = nullptr;
};
}
#endif
+630
View File
@@ -0,0 +1,630 @@
/*
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
*/
// despite that it would be nice if you give credit to Malte Skarupke
#pragma once
#include <utility>
#include <type_traits>
#include <functional>
#include <exception>
#include <typeinfo>
#include <memory>
#ifdef _MSC_VER
#define FUNC_NOEXCEPT
#define FUNC_TEMPLATE_NOEXCEPT(FUNCTOR, ALLOCATOR)
#define FUNC_CONSTEXPR const
#else
#define FUNC_NOEXCEPT noexcept
#define FUNC_TEMPLATE_NOEXCEPT(FUNCTOR, ALLOCATOR) noexcept(detail::is_inplace_allocated<FUNCTOR, ALLOCATOR>::value)
#define FUNC_CONSTEXPR constexpr
#endif
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
#define FUNC_MOVE(value) static_cast<typename std::remove_reference<decltype(value)>::type &&>(value)
#define FUNC_FORWARD(type, value) static_cast<type &&>(value)
namespace func
{
#ifndef FUNC_NO_EXCEPTIONS
struct bad_function_call : std::exception
{
const char * what() const FUNC_NOEXCEPT override
{
return "Bad function call";
}
};
#endif
template<typename>
struct force_function_heap_allocation
: std::false_type
{
};
template<typename>
class function;
namespace detail
{
struct manager_storage_type;
struct function_manager;
struct functor_padding
{
protected:
size_t padding_first;
size_t padding_second;
};
struct empty_struct
{
};
# ifndef FUNC_NO_EXCEPTIONS
template<typename Result, typename... Arguments>
Result empty_call(const functor_padding &, Arguments...)
{
throw bad_function_call();
}
# endif
template<typename T, typename Allocator>
struct is_inplace_allocated
{
static const bool value
// so that it fits
= sizeof(T) <= sizeof(functor_padding)
// so that it will be aligned
&& std::alignment_of<functor_padding>::value % std::alignment_of<T>::value == 0
// so that we can offer noexcept move
&& std::is_nothrow_move_constructible<T>::value
// so that the user can override it
&& !force_function_heap_allocation<T>::value;
};
template<typename T>
T to_functor(T && func)
{
return FUNC_FORWARD(T, func);
}
template<typename Result, typename Class, typename... Arguments>
auto to_functor(Result (Class::*func)(Arguments...)) -> decltype(std::mem_fn(func))
{
return std::mem_fn(func);
}
template<typename Result, typename Class, typename... Arguments>
auto to_functor(Result (Class::*func)(Arguments...) const) -> decltype(std::mem_fn(func))
{
return std::mem_fn(func);
}
template<typename T>
struct functor_type
{
typedef decltype(to_functor(std::declval<T>())) type;
};
template<typename T>
bool is_null(const T &)
{
return false;
}
template<typename Result, typename... Arguments>
bool is_null(Result (* const & function_pointer)(Arguments...))
{
return function_pointer == nullptr;
}
template<typename Result, typename Class, typename... Arguments>
bool is_null(Result (Class::* const & function_pointer)(Arguments...))
{
return function_pointer == nullptr;
}
template<typename Result, typename Class, typename... Arguments>
bool is_null(Result (Class::* const & function_pointer)(Arguments...) const)
{
return function_pointer == nullptr;
}
template<typename, typename>
struct is_valid_function_argument
{
static const bool value = false;
};
template<typename Result, typename... Arguments>
struct is_valid_function_argument<function<Result (Arguments...)>, Result (Arguments...)>
{
static const bool value = false;
};
template<typename T, typename Result, typename... Arguments>
struct is_valid_function_argument<T, Result (Arguments...)>
{
# ifdef _MSC_VER
// as of january 2013 visual studio doesn't support the SFINAE below
static const bool value = true;
# else
template<typename U>
static decltype(to_functor(std::declval<U>())(std::declval<Arguments>()...)) check(U *);
template<typename>
static empty_struct check(...);
static const bool value = std::is_convertible<decltype(check<T>(nullptr)), Result>::value;
# endif
};
typedef const function_manager * manager_type;
struct manager_storage_type
{
template<typename Allocator>
Allocator & get_allocator() FUNC_NOEXCEPT
{
return reinterpret_cast<Allocator &>(manager);
}
template<typename Allocator>
const Allocator & get_allocator() const FUNC_NOEXCEPT
{
return reinterpret_cast<const Allocator &>(manager);
}
functor_padding functor;
manager_type manager;
};
template<typename T, typename Allocator, typename Enable = void>
struct function_manager_inplace_specialization
{
template<typename Result, typename... Arguments>
static Result call(const functor_padding & storage, Arguments... arguments)
{
// do not call get_functor_ref because I want this function to be fast
// in debug when nothing gets inlined
return const_cast<T &>(reinterpret_cast<const T &>(storage))(FUNC_FORWARD(Arguments, arguments)...);
}
static void store_functor(manager_storage_type & storage, T to_store)
{
new (&get_functor_ref(storage)) T(FUNC_FORWARD(T, to_store));
}
static void move_functor(manager_storage_type & lhs, manager_storage_type && rhs) FUNC_NOEXCEPT
{
new (&get_functor_ref(lhs)) T(FUNC_MOVE(get_functor_ref(rhs)));
}
static void destroy_functor(Allocator &, manager_storage_type & storage) FUNC_NOEXCEPT
{
get_functor_ref(storage).~T();
}
static T & get_functor_ref(const manager_storage_type & storage) FUNC_NOEXCEPT
{
return const_cast<T &>(reinterpret_cast<const T &>(storage.functor));
}
};
template<typename T, typename Allocator>
struct function_manager_inplace_specialization<T, Allocator, typename std::enable_if<!is_inplace_allocated<T, Allocator>::value>::type>
{
template<typename Result, typename... Arguments>
static Result call(const functor_padding & storage, Arguments... arguments)
{
// do not call get_functor_ptr_ref because I want this function to be fast
// in debug when nothing gets inlined
return (*reinterpret_cast<const typename std::allocator_traits<Allocator>::pointer &>(storage))(FUNC_FORWARD(Arguments, arguments)...);
}
static void store_functor(manager_storage_type & self, T to_store)
{
Allocator & allocator = self.get_allocator<Allocator>();;
static_assert(sizeof(typename std::allocator_traits<Allocator>::pointer) <= sizeof(self.functor), "The allocator's pointer type is too big");
typename std::allocator_traits<Allocator>::pointer * ptr = new (&get_functor_ptr_ref(self)) typename std::allocator_traits<Allocator>::pointer(std::allocator_traits<Allocator>::allocate(allocator, 1));
std::allocator_traits<Allocator>::construct(allocator, *ptr, FUNC_FORWARD(T, to_store));
}
static void move_functor(manager_storage_type & lhs, manager_storage_type && rhs) FUNC_NOEXCEPT
{
static_assert(std::is_nothrow_move_constructible<typename std::allocator_traits<Allocator>::pointer>::value, "we can't offer a noexcept swap if the pointer type is not nothrow move constructible");
new (&get_functor_ptr_ref(lhs)) typename std::allocator_traits<Allocator>::pointer(FUNC_MOVE(get_functor_ptr_ref(rhs)));
// this next assignment makes the destroy function easier
get_functor_ptr_ref(rhs) = nullptr;
}
static void destroy_functor(Allocator & allocator, manager_storage_type & storage) FUNC_NOEXCEPT
{
typename std::allocator_traits<Allocator>::pointer & pointer = get_functor_ptr_ref(storage);
if (!pointer) return;
std::allocator_traits<Allocator>::destroy(allocator, pointer);
std::allocator_traits<Allocator>::deallocate(allocator, pointer, 1);
}
static T & get_functor_ref(const manager_storage_type & storage) FUNC_NOEXCEPT
{
return *get_functor_ptr_ref(storage);
}
static typename std::allocator_traits<Allocator>::pointer & get_functor_ptr_ref(manager_storage_type & storage) FUNC_NOEXCEPT
{
return reinterpret_cast<typename std::allocator_traits<Allocator>::pointer &>(storage.functor);
}
static const typename std::allocator_traits<Allocator>::pointer & get_functor_ptr_ref(const manager_storage_type & storage) FUNC_NOEXCEPT
{
return reinterpret_cast<const typename std::allocator_traits<Allocator>::pointer &>(storage.functor);
}
};
template<typename T, typename Allocator>
static const function_manager & get_default_manager();
template<typename T, typename Allocator>
static void create_manager(manager_storage_type & storage, Allocator && allocator)
{
new (&storage.get_allocator<Allocator>()) Allocator(FUNC_MOVE(allocator));
storage.manager = &get_default_manager<T, Allocator>();
}
// this struct acts as a vtable. it is an optimization to prevent
// code-bloat from rtti. see the documentation of boost::function
struct function_manager
{
template<typename T, typename Allocator>
inline static FUNC_CONSTEXPR function_manager create_default_manager()
{
# ifdef _MSC_VER
function_manager result =
# else
return function_manager
# endif
{
&templated_call_move_and_destroy<T, Allocator>,
&templated_call_copy<T, Allocator>,
&templated_call_copy_functor_only<T, Allocator>,
&templated_call_destroy<T, Allocator>,
# ifndef FUNC_NO_RTTI
&templated_call_type_id<T, Allocator>,
&templated_call_target<T, Allocator>
# endif
};
# ifdef _MSC_VER
return result;
# endif
}
void (* const call_move_and_destroy)(manager_storage_type & lhs, manager_storage_type && rhs);
void (* const call_copy)(manager_storage_type & lhs, const manager_storage_type & rhs);
void (* const call_copy_functor_only)(manager_storage_type & lhs, const manager_storage_type & rhs);
void (* const call_destroy)(manager_storage_type & manager);
# ifndef FUNC_NO_RTTI
const std::type_info & (* const call_type_id)();
void * (* const call_target)(const manager_storage_type & manager, const std::type_info & type);
# endif
template<typename T, typename Allocator>
static void templated_call_move_and_destroy(manager_storage_type & lhs, manager_storage_type && rhs)
{
typedef function_manager_inplace_specialization<T, Allocator> specialization;
specialization::move_functor(lhs, FUNC_MOVE(rhs));
specialization::destroy_functor(rhs.get_allocator<Allocator>(), rhs);
create_manager<T, Allocator>(lhs, FUNC_MOVE(rhs.get_allocator<Allocator>()));
rhs.get_allocator<Allocator>().~Allocator();
}
template<typename T, typename Allocator>
static void templated_call_copy(manager_storage_type & lhs, const manager_storage_type & rhs)
{
typedef function_manager_inplace_specialization<T, Allocator> specialization;
create_manager<T, Allocator>(lhs, Allocator(rhs.get_allocator<Allocator>()));
specialization::store_functor(lhs, specialization::get_functor_ref(rhs));
}
template<typename T, typename Allocator>
static void templated_call_destroy(manager_storage_type & self)
{
typedef function_manager_inplace_specialization<T, Allocator> specialization;
specialization::destroy_functor(self.get_allocator<Allocator>(), self);
self.get_allocator<Allocator>().~Allocator();
}
template<typename T, typename Allocator>
static void templated_call_copy_functor_only(manager_storage_type & lhs, const manager_storage_type & rhs)
{
typedef function_manager_inplace_specialization<T, Allocator> specialization;
specialization::store_functor(lhs, specialization::get_functor_ref(rhs));
}
# ifndef FUNC_NO_RTTI
template<typename T, typename>
static const std::type_info & templated_call_type_id()
{
return typeid(T);
}
template<typename T, typename Allocator>
static void * templated_call_target(const manager_storage_type & self, const std::type_info & type)
{
typedef function_manager_inplace_specialization<T, Allocator> specialization;
if (type == typeid(T))
return &specialization::get_functor_ref(self);
else
return nullptr;
}
# endif
};
template<typename T, typename Allocator>
inline static const function_manager & get_default_manager()
{
static FUNC_CONSTEXPR function_manager default_manager = function_manager::create_default_manager<T, Allocator>();
return default_manager;
}
template<typename Result, typename...>
struct typedeffer
{
typedef Result result_type;
};
template<typename Result, typename Argument>
struct typedeffer<Result, Argument>
{
typedef Result result_type;
typedef Argument argument_type;
};
template<typename Result, typename First_Argument, typename Second_Argument>
struct typedeffer<Result, First_Argument, Second_Argument>
{
typedef Result result_type;
typedef First_Argument first_argument_type;
typedef Second_Argument second_argument_type;
};
}
template<typename Result, typename... Arguments>
class function<Result (Arguments...)>
: public detail::typedeffer<Result, Arguments...>
{
public:
function() FUNC_NOEXCEPT
{
initialize_empty();
}
function(std::nullptr_t) FUNC_NOEXCEPT
{
initialize_empty();
}
function(function && other) FUNC_NOEXCEPT
{
initialize_empty();
swap(other);
}
function(const function & other)
: call(other.call)
{
other.manager_storage.manager->call_copy(manager_storage, other.manager_storage);
}
template<typename T>
function(T functor,
typename std::enable_if<detail::is_valid_function_argument<T, Result (Arguments...)>::value, detail::empty_struct>::type = detail::empty_struct()) FUNC_TEMPLATE_NOEXCEPT(T, std::allocator<typename detail::functor_type<T>::type>)
{
if (detail::is_null(functor))
{
initialize_empty();
}
else
{
typedef typename detail::functor_type<T>::type functor_type;
initialize(detail::to_functor(FUNC_FORWARD(T, functor)), std::allocator<functor_type>());
}
}
template<typename Allocator>
function(std::allocator_arg_t, const Allocator &)
{
// ignore the allocator because I don't allocate
initialize_empty();
}
template<typename Allocator>
function(std::allocator_arg_t, const Allocator &, std::nullptr_t)
{
// ignore the allocator because I don't allocate
initialize_empty();
}
template<typename Allocator, typename T>
function(std::allocator_arg_t, const Allocator & allocator, T functor,
typename std::enable_if<detail::is_valid_function_argument<T, Result (Arguments...)>::value, detail::empty_struct>::type = detail::empty_struct())
FUNC_TEMPLATE_NOEXCEPT(T, Allocator)
{
if (detail::is_null(functor))
{
initialize_empty();
}
else
{
initialize(detail::to_functor(FUNC_FORWARD(T, functor)), Allocator(allocator));
}
}
template<typename Allocator>
function(std::allocator_arg_t, const Allocator & allocator, const function & other)
: call(other.call)
{
typedef typename std::allocator_traits<Allocator>::template rebind_alloc<function> MyAllocator;
// first try to see if the allocator matches the target type
detail::manager_type manager_for_allocator = &detail::get_default_manager<typename std::allocator_traits<Allocator>::value_type, Allocator>();
if (other.manager_storage.manager == manager_for_allocator)
{
detail::create_manager<typename std::allocator_traits<Allocator>::value_type, Allocator>(manager_storage, Allocator(allocator));
manager_for_allocator->call_copy_functor_only(manager_storage, other.manager_storage);
}
// if it does not, try to see if the target contains my type. this
// breaks the recursion of the last case. otherwise repeated copies
// would allocate more and more memory
else
{
detail::manager_type manager_for_function = &detail::get_default_manager<function, MyAllocator>();
if (other.manager_storage.manager == manager_for_function)
{
detail::create_manager<function, MyAllocator>(manager_storage, MyAllocator(allocator));
manager_for_function->call_copy_functor_only(manager_storage, other.manager_storage);
}
else
{
// else store the other function as my target
initialize(other, MyAllocator(allocator));
}
}
}
template<typename Allocator>
function(std::allocator_arg_t, const Allocator &, function && other) FUNC_NOEXCEPT
{
// ignore the allocator because I don't allocate
initialize_empty();
swap(other);
}
function & operator=(function other) FUNC_NOEXCEPT
{
swap(other);
return *this;
}
~function() FUNC_NOEXCEPT
{
manager_storage.manager->call_destroy(manager_storage);
}
Result operator()(Arguments... arguments) const
{
return call(manager_storage.functor, FUNC_FORWARD(Arguments, arguments)...);
}
template<typename T, typename Allocator>
void assign(T && functor, const Allocator & allocator) FUNC_TEMPLATE_NOEXCEPT(T, Allocator)
{
function(std::allocator_arg, allocator, functor).swap(*this);
}
void swap(function & other) FUNC_NOEXCEPT
{
detail::manager_storage_type temp_storage;
other.manager_storage.manager->call_move_and_destroy(temp_storage, FUNC_MOVE(other.manager_storage));
manager_storage.manager->call_move_and_destroy(other.manager_storage, FUNC_MOVE(manager_storage));
temp_storage.manager->call_move_and_destroy(manager_storage, FUNC_MOVE(temp_storage));
std::swap(call, other.call);
}
# ifndef FUNC_NO_RTTI
const std::type_info & target_type() const FUNC_NOEXCEPT
{
return manager_storage.manager->call_type_id();
}
template<typename T>
T * target() FUNC_NOEXCEPT
{
return static_cast<T *>(manager_storage.manager->call_target(manager_storage, typeid(T)));
}
template<typename T>
const T * target() const FUNC_NOEXCEPT
{
return static_cast<const T *>(manager_storage.manager->call_target(manager_storage, typeid(T)));
}
# endif
operator bool() const FUNC_NOEXCEPT
{
# ifdef FUNC_NO_EXCEPTIONS
return call != nullptr;
# else
return call != &detail::empty_call<Result, Arguments...>;
# endif
}
private:
detail::manager_storage_type manager_storage;
Result (*call)(const detail::functor_padding &, Arguments...);
template<typename T, typename Allocator>
void initialize(T functor, Allocator && allocator)
{
call = &detail::function_manager_inplace_specialization<T, Allocator>::template call<Result, Arguments...>;
detail::create_manager<T, Allocator>(manager_storage, FUNC_FORWARD(Allocator, allocator));
detail::function_manager_inplace_specialization<T, Allocator>::store_functor(manager_storage, FUNC_FORWARD(T, functor));
}
typedef Result(*Empty_Function_Type)(Arguments...);
void initialize_empty() FUNC_NOEXCEPT
{
typedef std::allocator<Empty_Function_Type> Allocator;
static_assert(detail::is_inplace_allocated<Empty_Function_Type, Allocator>::value, "The empty function should benefit from small functor optimization");
detail::create_manager<Empty_Function_Type, Allocator>(manager_storage, Allocator());
detail::function_manager_inplace_specialization<Empty_Function_Type, Allocator>::store_functor(manager_storage, nullptr);
# ifdef FUNC_NO_EXCEPTIONS
call = nullptr;
# else
call = &detail::empty_call<Result, Arguments...>;
# endif
}
};
template<typename T>
bool operator==(std::nullptr_t, const function<T> & rhs) FUNC_NOEXCEPT
{
return !rhs;
}
template<typename T>
bool operator==(const function<T> & lhs, std::nullptr_t) FUNC_NOEXCEPT
{
return !lhs;
}
template<typename T>
bool operator!=(std::nullptr_t, const function<T> & rhs) FUNC_NOEXCEPT
{
return rhs;
}
template<typename T>
bool operator!=(const function<T> & lhs, std::nullptr_t) FUNC_NOEXCEPT
{
return lhs;
}
template<typename T>
void swap(function<T> & lhs, function<T> & rhs)
{
lhs.swap(rhs);
}
} // end namespace func
namespace std
{
template<typename Result, typename... Arguments, typename Allocator>
struct uses_allocator<func::function<Result (Arguments...)>, Allocator>
: std::true_type
{
};
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#undef FUNC_NOEXCEPT
#undef FUNC_TEMPLATE_NOEXCEPT
#undef FUNC_FORWARD
#undef FUNC_MOVE
#undef FUNC_CONSTEXPR
+1 -1
View File
@@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODEC_H264STD_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
+1 -1
View File
@@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODEC_H264STD_DECODE_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
+1 -1
View File
@@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODEC_H264STD_ENCODE_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
+1 -1
View File
@@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODEC_H265STD_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
+1 -1
View File
@@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODEC_H265STD_DECODE_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
+1 -1
View File
@@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODEC_H265STD_ENCODE_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
+1 -1
View File
@@ -2,7 +2,7 @@
#define VULKAN_VIDEO_CODECS_COMMON_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
+1 -1
View File
@@ -2,7 +2,7 @@
// File: vk_platform.h
//
/*
** Copyright 2014-2023 The Khronos Group Inc.
** Copyright 2014-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
+2 -2
View File
@@ -1,4 +1,4 @@
// Copyright 2015-2023 The Khronos Group Inc.
// Copyright 2015-2024 The Khronos Group Inc.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
@@ -4616,7 +4616,7 @@ export namespace VULKAN_HPP_NAMESPACE
using VULKAN_HPP_NAMESPACE::isObsoletedExtension;
using VULKAN_HPP_NAMESPACE::isPromotedExtension;
#if !defined( VULKAN_HPP_DISABLE_ENHANCED_MODE ) && !defined( VULKAN_HPP_NO_EXCEPTIONS )
#if !defined( VULKAN_HPP_DISABLE_ENHANCED_MODE )
namespace VULKAN_HPP_RAII_NAMESPACE
{
//======================
+1 -1
View File
@@ -2,7 +2,7 @@
#define VULKAN_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
+7 -3
View File
@@ -1,4 +1,4 @@
// Copyright 2015-2023 The Khronos Group Inc.
// Copyright 2015-2024 The Khronos Group Inc.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
@@ -16,7 +16,7 @@
#include <vulkan/vulkan_hpp_macros.hpp>
#if 17 <= VULKAN_HPP_CPP_VERSION
# include <string_view> // std::string_view
# include <string_view>
#endif
#if !defined( VULKAN_HPP_DISABLE_ENHANCED_MODE )
@@ -56,7 +56,7 @@ extern "C" __declspec( dllimport ) FARPROC __stdcall GetProcAddress( HINSTANCE h
# include <span>
#endif
static_assert( VK_HEADER_VERSION == 274, "Wrong VK_HEADER_VERSION!" );
static_assert( VK_HEADER_VERSION == 275, "Wrong VK_HEADER_VERSION!" );
// <tuple> includes <sys/sysmacros.h> through some other header
// this results in major(x) being resolved to gnu_dev_major(x)
@@ -16302,6 +16302,10 @@ namespace VULKAN_HPP_NAMESPACE
}
# elif defined( __APPLE__ )
m_library = dlopen( "libvulkan.dylib", RTLD_NOW | RTLD_LOCAL );
if ( m_library == nullptr )
{
m_library = dlopen( "libvulkan.1.dylib", RTLD_NOW | RTLD_LOCAL );
}
# elif defined( _WIN32 )
m_library = ::LoadLibraryA( "vulkan-1.dll" );
# else
+1 -1
View File
@@ -2,7 +2,7 @@
#define VULKAN_ANDROID_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
+1 -1
View File
@@ -2,7 +2,7 @@
#define VULKAN_BETA_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
+4 -4
View File
@@ -2,7 +2,7 @@
#define VULKAN_CORE_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
@@ -69,7 +69,7 @@ extern "C" {
#define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)// Patch version should always be set to 0
// Version of this file
#define VK_HEADER_VERSION 274
#define VK_HEADER_VERSION 275
// Complete version of this file
#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 3, VK_HEADER_VERSION)
@@ -15334,7 +15334,7 @@ typedef VkPhysicalDeviceTexelBufferAlignmentProperties VkPhysicalDeviceTexelBuff
// VK_QCOM_render_pass_transform is a preprocessor guard. Do not pass it to API calls.
#define VK_QCOM_render_pass_transform 1
#define VK_QCOM_RENDER_PASS_TRANSFORM_SPEC_VERSION 3
#define VK_QCOM_RENDER_PASS_TRANSFORM_SPEC_VERSION 4
#define VK_QCOM_RENDER_PASS_TRANSFORM_EXTENSION_NAME "VK_QCOM_render_pass_transform"
typedef struct VkRenderPassTransformBeginInfoQCOM {
VkStructureType sType;
@@ -16174,7 +16174,7 @@ typedef struct VkPhysicalDeviceFragmentDensityMap2PropertiesEXT {
// VK_QCOM_rotated_copy_commands is a preprocessor guard. Do not pass it to API calls.
#define VK_QCOM_rotated_copy_commands 1
#define VK_QCOM_ROTATED_COPY_COMMANDS_SPEC_VERSION 1
#define VK_QCOM_ROTATED_COPY_COMMANDS_SPEC_VERSION 2
#define VK_QCOM_ROTATED_COPY_COMMANDS_EXTENSION_NAME "VK_QCOM_rotated_copy_commands"
typedef struct VkCopyCommandTransformInfoQCOM {
VkStructureType sType;
+1 -1
View File
@@ -2,7 +2,7 @@
#define VULKAN_DIRECTFB_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2015-2023 The Khronos Group Inc.
// Copyright 2015-2024 The Khronos Group Inc.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
+2 -9
View File
@@ -1,4 +1,4 @@
// Copyright 2015-2023 The Khronos Group Inc.
// Copyright 2015-2024 The Khronos Group Inc.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
@@ -1422,12 +1422,6 @@ namespace VULKAN_HPP_NAMESPACE
"VK_KHR_get_physical_device_properties2",
} } },
{ "VK_VERSION_1_1", { {} } } } },
{ "VK_QCOM_render_pass_transform",
{ { "VK_VERSION_1_0",
{ {
"VK_KHR_swapchain",
"VK_KHR_surface",
} } } } },
{ "VK_EXT_depth_bias_control",
{ { "VK_VERSION_1_0",
{ {
@@ -1555,7 +1549,6 @@ namespace VULKAN_HPP_NAMESPACE
{ "VK_QCOM_rotated_copy_commands",
{ { "VK_VERSION_1_0",
{ {
"VK_KHR_swapchain",
"VK_KHR_copy_commands2",
} } } } },
{ "VK_EXT_image_robustness",
@@ -2062,7 +2055,7 @@ namespace VULKAN_HPP_NAMESPACE
"VK_KHR_get_physical_device_properties2",
} } },
{ "VK_VERSION_1_1", { {} } } } },
{ "VK_KHR_maintenance6", { { "VK_VERSION_1_0", { {} } } } },
{ "VK_KHR_maintenance6", { { "VK_VERSION_1_1", { {} } } } },
{ "VK_NV_descriptor_pool_overallocation", { { "VK_VERSION_1_1", { {} } } } }
};
auto depIt = dependencies.find( extension );
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2015-2023 The Khronos Group Inc.
// Copyright 2015-2024 The Khronos Group Inc.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
+1 -1
View File
@@ -2,7 +2,7 @@
#define VULKAN_FUCHSIA_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
+2225 -2114
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -2,7 +2,7 @@
#define VULKAN_GGP_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
+72 -71
View File
@@ -1,4 +1,4 @@
// Copyright 2015-2023 The Khronos Group Inc.
// Copyright 2015-2024 The Khronos Group Inc.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
@@ -8680,7 +8680,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename CheckpointDataNVAllocator = std::allocator<VULKAN_HPP_NAMESPACE::CheckpointDataNV>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = CheckpointDataNVAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, CheckpointDataNV>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::CheckpointDataNV>::value, int>::type = 0>
VULKAN_HPP_NODISCARD std::vector<VULKAN_HPP_NAMESPACE::CheckpointDataNV, CheckpointDataNVAllocator>
getCheckpointDataNV( CheckpointDataNVAllocator & checkpointDataNVAllocator, Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
#endif /* VULKAN_HPP_DISABLE_ENHANCED_MODE */
@@ -8725,7 +8725,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename CheckpointData2NVAllocator = std::allocator<VULKAN_HPP_NAMESPACE::CheckpointData2NV>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = CheckpointData2NVAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, CheckpointData2NV>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::CheckpointData2NV>::value, int>::type = 0>
VULKAN_HPP_NODISCARD std::vector<VULKAN_HPP_NAMESPACE::CheckpointData2NV, CheckpointData2NVAllocator>
getCheckpointData2NV( CheckpointData2NVAllocator & checkpointData2NVAllocator, Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
#endif /* VULKAN_HPP_DISABLE_ENHANCED_MODE */
@@ -9019,7 +9019,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename SparseImageMemoryRequirementsAllocator = std::allocator<VULKAN_HPP_NAMESPACE::SparseImageMemoryRequirements>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = SparseImageMemoryRequirementsAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, SparseImageMemoryRequirements>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::SparseImageMemoryRequirements>::value, int>::type = 0>
VULKAN_HPP_NODISCARD std::vector<VULKAN_HPP_NAMESPACE::SparseImageMemoryRequirements, SparseImageMemoryRequirementsAllocator>
getImageSparseMemoryRequirements( VULKAN_HPP_NAMESPACE::Image image,
SparseImageMemoryRequirementsAllocator & sparseImageMemoryRequirementsAllocator,
@@ -9599,7 +9599,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename PipelineAllocator = std::allocator<VULKAN_HPP_NAMESPACE::Pipeline>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B0 = PipelineAllocator,
typename std::enable_if<std::is_same<typename B0::value_type, Pipeline>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B0::value_type, VULKAN_HPP_NAMESPACE::Pipeline>::value, int>::type = 0>
VULKAN_HPP_NODISCARD ResultValue<std::vector<VULKAN_HPP_NAMESPACE::Pipeline, PipelineAllocator>>
createGraphicsPipelines( VULKAN_HPP_NAMESPACE::PipelineCache pipelineCache,
VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::GraphicsPipelineCreateInfo> const & createInfos,
@@ -9623,7 +9623,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename PipelineAllocator = std::allocator<UniqueHandle<VULKAN_HPP_NAMESPACE::Pipeline, Dispatch>>,
typename B0 = PipelineAllocator,
typename std::enable_if<std::is_same<typename B0::value_type, UniqueHandle<Pipeline, Dispatch>>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B0::value_type, UniqueHandle<VULKAN_HPP_NAMESPACE::Pipeline, Dispatch>>::value, int>::type = 0>
VULKAN_HPP_NODISCARD ResultValue<std::vector<UniqueHandle<VULKAN_HPP_NAMESPACE::Pipeline, Dispatch>, PipelineAllocator>>
createGraphicsPipelinesUnique( VULKAN_HPP_NAMESPACE::PipelineCache pipelineCache,
VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::GraphicsPipelineCreateInfo> const & createInfos,
@@ -9656,7 +9656,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename PipelineAllocator = std::allocator<VULKAN_HPP_NAMESPACE::Pipeline>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B0 = PipelineAllocator,
typename std::enable_if<std::is_same<typename B0::value_type, Pipeline>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B0::value_type, VULKAN_HPP_NAMESPACE::Pipeline>::value, int>::type = 0>
VULKAN_HPP_NODISCARD ResultValue<std::vector<VULKAN_HPP_NAMESPACE::Pipeline, PipelineAllocator>>
createComputePipelines( VULKAN_HPP_NAMESPACE::PipelineCache pipelineCache,
VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::ComputePipelineCreateInfo> const & createInfos,
@@ -9680,7 +9680,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename PipelineAllocator = std::allocator<UniqueHandle<VULKAN_HPP_NAMESPACE::Pipeline, Dispatch>>,
typename B0 = PipelineAllocator,
typename std::enable_if<std::is_same<typename B0::value_type, UniqueHandle<Pipeline, Dispatch>>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B0::value_type, UniqueHandle<VULKAN_HPP_NAMESPACE::Pipeline, Dispatch>>::value, int>::type = 0>
VULKAN_HPP_NODISCARD ResultValue<std::vector<UniqueHandle<VULKAN_HPP_NAMESPACE::Pipeline, Dispatch>, PipelineAllocator>>
createComputePipelinesUnique( VULKAN_HPP_NAMESPACE::PipelineCache pipelineCache,
VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::ComputePipelineCreateInfo> const & createInfos,
@@ -9910,7 +9910,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename DescriptorSetAllocator = std::allocator<VULKAN_HPP_NAMESPACE::DescriptorSet>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B0 = DescriptorSetAllocator,
typename std::enable_if<std::is_same<typename B0::value_type, DescriptorSet>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B0::value_type, VULKAN_HPP_NAMESPACE::DescriptorSet>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::DescriptorSet, DescriptorSetAllocator>>::type
allocateDescriptorSets( const VULKAN_HPP_NAMESPACE::DescriptorSetAllocateInfo & allocateInfo,
DescriptorSetAllocator & descriptorSetAllocator,
@@ -9924,7 +9924,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename DescriptorSetAllocator = std::allocator<UniqueHandle<VULKAN_HPP_NAMESPACE::DescriptorSet, Dispatch>>,
typename B0 = DescriptorSetAllocator,
typename std::enable_if<std::is_same<typename B0::value_type, UniqueHandle<DescriptorSet, Dispatch>>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B0::value_type, UniqueHandle<VULKAN_HPP_NAMESPACE::DescriptorSet, Dispatch>>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<UniqueHandle<VULKAN_HPP_NAMESPACE::DescriptorSet, Dispatch>, DescriptorSetAllocator>>::type
allocateDescriptorSetsUnique( const VULKAN_HPP_NAMESPACE::DescriptorSetAllocateInfo & allocateInfo,
DescriptorSetAllocator & descriptorSetAllocator,
@@ -10130,7 +10130,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename CommandBufferAllocator = std::allocator<VULKAN_HPP_NAMESPACE::CommandBuffer>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B0 = CommandBufferAllocator,
typename std::enable_if<std::is_same<typename B0::value_type, CommandBuffer>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B0::value_type, VULKAN_HPP_NAMESPACE::CommandBuffer>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::CommandBuffer, CommandBufferAllocator>>::type
allocateCommandBuffers( const VULKAN_HPP_NAMESPACE::CommandBufferAllocateInfo & allocateInfo,
CommandBufferAllocator & commandBufferAllocator,
@@ -10144,7 +10144,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename CommandBufferAllocator = std::allocator<UniqueHandle<VULKAN_HPP_NAMESPACE::CommandBuffer, Dispatch>>,
typename B0 = CommandBufferAllocator,
typename std::enable_if<std::is_same<typename B0::value_type, UniqueHandle<CommandBuffer, Dispatch>>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B0::value_type, UniqueHandle<VULKAN_HPP_NAMESPACE::CommandBuffer, Dispatch>>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<UniqueHandle<VULKAN_HPP_NAMESPACE::CommandBuffer, Dispatch>, CommandBufferAllocator>>::type
allocateCommandBuffersUnique( const VULKAN_HPP_NAMESPACE::CommandBufferAllocateInfo & allocateInfo,
CommandBufferAllocator & commandBufferAllocator,
@@ -10259,7 +10259,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename SparseImageMemoryRequirements2Allocator = std::allocator<VULKAN_HPP_NAMESPACE::SparseImageMemoryRequirements2>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = SparseImageMemoryRequirements2Allocator,
typename std::enable_if<std::is_same<typename B1::value_type, SparseImageMemoryRequirements2>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::SparseImageMemoryRequirements2>::value, int>::type = 0>
VULKAN_HPP_NODISCARD std::vector<VULKAN_HPP_NAMESPACE::SparseImageMemoryRequirements2, SparseImageMemoryRequirements2Allocator>
getImageSparseMemoryRequirements2( const VULKAN_HPP_NAMESPACE::ImageSparseMemoryRequirementsInfo2 & info,
SparseImageMemoryRequirements2Allocator & sparseImageMemoryRequirements2Allocator,
@@ -10596,7 +10596,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename SparseImageMemoryRequirements2Allocator = std::allocator<VULKAN_HPP_NAMESPACE::SparseImageMemoryRequirements2>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = SparseImageMemoryRequirements2Allocator,
typename std::enable_if<std::is_same<typename B1::value_type, SparseImageMemoryRequirements2>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::SparseImageMemoryRequirements2>::value, int>::type = 0>
VULKAN_HPP_NODISCARD std::vector<VULKAN_HPP_NAMESPACE::SparseImageMemoryRequirements2, SparseImageMemoryRequirements2Allocator>
getImageSparseMemoryRequirements( const VULKAN_HPP_NAMESPACE::DeviceImageMemoryRequirements & info,
SparseImageMemoryRequirements2Allocator & sparseImageMemoryRequirements2Allocator,
@@ -10659,7 +10659,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename ImageAllocator = std::allocator<VULKAN_HPP_NAMESPACE::Image>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = ImageAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, Image>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::Image>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::Image, ImageAllocator>>::type getSwapchainImagesKHR(
VULKAN_HPP_NAMESPACE::SwapchainKHR swapchain, ImageAllocator & imageAllocator, Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
#endif /* VULKAN_HPP_DISABLE_ENHANCED_MODE */
@@ -10726,7 +10726,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename SwapchainKHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::SwapchainKHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B0 = SwapchainKHRAllocator,
typename std::enable_if<std::is_same<typename B0::value_type, SwapchainKHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B0::value_type, VULKAN_HPP_NAMESPACE::SwapchainKHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::SwapchainKHR, SwapchainKHRAllocator>>::type
createSharedSwapchainsKHR( VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::SwapchainCreateInfoKHR> const & createInfos,
Optional<const VULKAN_HPP_NAMESPACE::AllocationCallbacks> allocator,
@@ -10747,7 +10747,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename SwapchainKHRAllocator = std::allocator<UniqueHandle<VULKAN_HPP_NAMESPACE::SwapchainKHR, Dispatch>>,
typename B0 = SwapchainKHRAllocator,
typename std::enable_if<std::is_same<typename B0::value_type, UniqueHandle<SwapchainKHR, Dispatch>>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B0::value_type, UniqueHandle<VULKAN_HPP_NAMESPACE::SwapchainKHR, Dispatch>>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<UniqueHandle<VULKAN_HPP_NAMESPACE::SwapchainKHR, Dispatch>, SwapchainKHRAllocator>>::type
createSharedSwapchainsKHRUnique( VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::SwapchainCreateInfoKHR> const & createInfos,
Optional<const VULKAN_HPP_NAMESPACE::AllocationCallbacks> allocator,
@@ -10842,7 +10842,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename VideoSessionMemoryRequirementsKHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::VideoSessionMemoryRequirementsKHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = VideoSessionMemoryRequirementsKHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, VideoSessionMemoryRequirementsKHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::VideoSessionMemoryRequirementsKHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD
typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::VideoSessionMemoryRequirementsKHR, VideoSessionMemoryRequirementsKHRAllocator>>::type
getVideoSessionMemoryRequirementsKHR( VULKAN_HPP_NAMESPACE::VideoSessionKHR videoSession,
@@ -11328,7 +11328,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename PastPresentationTimingGOOGLEAllocator = std::allocator<VULKAN_HPP_NAMESPACE::PastPresentationTimingGOOGLE>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = PastPresentationTimingGOOGLEAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, PastPresentationTimingGOOGLE>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::PastPresentationTimingGOOGLE>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::PastPresentationTimingGOOGLE, PastPresentationTimingGOOGLEAllocator>>::type
getPastPresentationTimingGOOGLE( VULKAN_HPP_NAMESPACE::SwapchainKHR swapchain,
PastPresentationTimingGOOGLEAllocator & pastPresentationTimingGOOGLEAllocator,
@@ -11516,7 +11516,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename PipelineAllocator = std::allocator<VULKAN_HPP_NAMESPACE::Pipeline>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B0 = PipelineAllocator,
typename std::enable_if<std::is_same<typename B0::value_type, Pipeline>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B0::value_type, VULKAN_HPP_NAMESPACE::Pipeline>::value, int>::type = 0>
VULKAN_HPP_NODISCARD ResultValue<std::vector<VULKAN_HPP_NAMESPACE::Pipeline, PipelineAllocator>>
createExecutionGraphPipelinesAMDX( VULKAN_HPP_NAMESPACE::PipelineCache pipelineCache,
VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::ExecutionGraphPipelineCreateInfoAMDX> const & createInfos,
@@ -11541,7 +11541,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename PipelineAllocator = std::allocator<UniqueHandle<VULKAN_HPP_NAMESPACE::Pipeline, Dispatch>>,
typename B0 = PipelineAllocator,
typename std::enable_if<std::is_same<typename B0::value_type, UniqueHandle<Pipeline, Dispatch>>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B0::value_type, UniqueHandle<VULKAN_HPP_NAMESPACE::Pipeline, Dispatch>>::value, int>::type = 0>
VULKAN_HPP_NODISCARD ResultValue<std::vector<UniqueHandle<VULKAN_HPP_NAMESPACE::Pipeline, Dispatch>, PipelineAllocator>>
createExecutionGraphPipelinesAMDXUnique(
VULKAN_HPP_NAMESPACE::PipelineCache pipelineCache,
@@ -11630,7 +11630,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename SparseImageMemoryRequirements2Allocator = std::allocator<VULKAN_HPP_NAMESPACE::SparseImageMemoryRequirements2>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = SparseImageMemoryRequirements2Allocator,
typename std::enable_if<std::is_same<typename B1::value_type, SparseImageMemoryRequirements2>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::SparseImageMemoryRequirements2>::value, int>::type = 0>
VULKAN_HPP_NODISCARD std::vector<VULKAN_HPP_NAMESPACE::SparseImageMemoryRequirements2, SparseImageMemoryRequirements2Allocator>
getImageSparseMemoryRequirements2KHR( const VULKAN_HPP_NAMESPACE::ImageSparseMemoryRequirementsInfo2 & info,
SparseImageMemoryRequirements2Allocator & sparseImageMemoryRequirements2Allocator,
@@ -11813,7 +11813,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename PipelineAllocator = std::allocator<VULKAN_HPP_NAMESPACE::Pipeline>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B0 = PipelineAllocator,
typename std::enable_if<std::is_same<typename B0::value_type, Pipeline>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B0::value_type, VULKAN_HPP_NAMESPACE::Pipeline>::value, int>::type = 0>
VULKAN_HPP_NODISCARD ResultValue<std::vector<VULKAN_HPP_NAMESPACE::Pipeline, PipelineAllocator>>
createRayTracingPipelinesKHR( VULKAN_HPP_NAMESPACE::DeferredOperationKHR deferredOperation,
VULKAN_HPP_NAMESPACE::PipelineCache pipelineCache,
@@ -11840,7 +11840,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename PipelineAllocator = std::allocator<UniqueHandle<VULKAN_HPP_NAMESPACE::Pipeline, Dispatch>>,
typename B0 = PipelineAllocator,
typename std::enable_if<std::is_same<typename B0::value_type, UniqueHandle<Pipeline, Dispatch>>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B0::value_type, UniqueHandle<VULKAN_HPP_NAMESPACE::Pipeline, Dispatch>>::value, int>::type = 0>
VULKAN_HPP_NODISCARD ResultValue<std::vector<UniqueHandle<VULKAN_HPP_NAMESPACE::Pipeline, Dispatch>, PipelineAllocator>>
createRayTracingPipelinesKHRUnique( VULKAN_HPP_NAMESPACE::DeferredOperationKHR deferredOperation,
VULKAN_HPP_NAMESPACE::PipelineCache pipelineCache,
@@ -12137,7 +12137,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename PipelineAllocator = std::allocator<VULKAN_HPP_NAMESPACE::Pipeline>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B0 = PipelineAllocator,
typename std::enable_if<std::is_same<typename B0::value_type, Pipeline>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B0::value_type, VULKAN_HPP_NAMESPACE::Pipeline>::value, int>::type = 0>
VULKAN_HPP_NODISCARD ResultValue<std::vector<VULKAN_HPP_NAMESPACE::Pipeline, PipelineAllocator>>
createRayTracingPipelinesNV( VULKAN_HPP_NAMESPACE::PipelineCache pipelineCache,
VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::RayTracingPipelineCreateInfoNV> const & createInfos,
@@ -12161,7 +12161,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename PipelineAllocator = std::allocator<UniqueHandle<VULKAN_HPP_NAMESPACE::Pipeline, Dispatch>>,
typename B0 = PipelineAllocator,
typename std::enable_if<std::is_same<typename B0::value_type, UniqueHandle<Pipeline, Dispatch>>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B0::value_type, UniqueHandle<VULKAN_HPP_NAMESPACE::Pipeline, Dispatch>>::value, int>::type = 0>
VULKAN_HPP_NODISCARD ResultValue<std::vector<UniqueHandle<VULKAN_HPP_NAMESPACE::Pipeline, Dispatch>, PipelineAllocator>>
createRayTracingPipelinesNVUnique( VULKAN_HPP_NAMESPACE::PipelineCache pipelineCache,
VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::RayTracingPipelineCreateInfoNV> const & createInfos,
@@ -12567,7 +12567,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename PipelineExecutablePropertiesKHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::PipelineExecutablePropertiesKHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = PipelineExecutablePropertiesKHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, PipelineExecutablePropertiesKHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::PipelineExecutablePropertiesKHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD
typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::PipelineExecutablePropertiesKHR, PipelineExecutablePropertiesKHRAllocator>>::type
getPipelineExecutablePropertiesKHR( const VULKAN_HPP_NAMESPACE::PipelineInfoKHR & pipelineInfo,
@@ -12590,7 +12590,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename PipelineExecutableStatisticKHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::PipelineExecutableStatisticKHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = PipelineExecutableStatisticKHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, PipelineExecutableStatisticKHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::PipelineExecutableStatisticKHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD
typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::PipelineExecutableStatisticKHR, PipelineExecutableStatisticKHRAllocator>>::type
getPipelineExecutableStatisticsKHR( const VULKAN_HPP_NAMESPACE::PipelineExecutableInfoKHR & executableInfo,
@@ -12611,10 +12611,11 @@ namespace VULKAN_HPP_NAMESPACE
std::vector<VULKAN_HPP_NAMESPACE::PipelineExecutableInternalRepresentationKHR, PipelineExecutableInternalRepresentationKHRAllocator>>::type
getPipelineExecutableInternalRepresentationsKHR( const VULKAN_HPP_NAMESPACE::PipelineExecutableInfoKHR & executableInfo,
Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
template <typename PipelineExecutableInternalRepresentationKHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::PipelineExecutableInternalRepresentationKHR>,
template <
typename PipelineExecutableInternalRepresentationKHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::PipelineExecutableInternalRepresentationKHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = PipelineExecutableInternalRepresentationKHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, PipelineExecutableInternalRepresentationKHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::PipelineExecutableInternalRepresentationKHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<
std::vector<VULKAN_HPP_NAMESPACE::PipelineExecutableInternalRepresentationKHR, PipelineExecutableInternalRepresentationKHRAllocator>>::type
getPipelineExecutableInternalRepresentationsKHR(
@@ -13484,7 +13485,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename SparseImageMemoryRequirements2Allocator = std::allocator<VULKAN_HPP_NAMESPACE::SparseImageMemoryRequirements2>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = SparseImageMemoryRequirements2Allocator,
typename std::enable_if<std::is_same<typename B1::value_type, SparseImageMemoryRequirements2>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::SparseImageMemoryRequirements2>::value, int>::type = 0>
VULKAN_HPP_NODISCARD std::vector<VULKAN_HPP_NAMESPACE::SparseImageMemoryRequirements2, SparseImageMemoryRequirements2Allocator>
getImageSparseMemoryRequirementsKHR( const VULKAN_HPP_NAMESPACE::DeviceImageMemoryRequirements & info,
SparseImageMemoryRequirements2Allocator & sparseImageMemoryRequirements2Allocator,
@@ -13688,7 +13689,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename ShaderEXTAllocator = std::allocator<VULKAN_HPP_NAMESPACE::ShaderEXT>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B0 = ShaderEXTAllocator,
typename std::enable_if<std::is_same<typename B0::value_type, ShaderEXT>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B0::value_type, VULKAN_HPP_NAMESPACE::ShaderEXT>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::ShaderEXT, ShaderEXTAllocator>>::type
createShadersEXT( VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::ShaderCreateInfoEXT> const & createInfos,
Optional<const VULKAN_HPP_NAMESPACE::AllocationCallbacks> allocator,
@@ -13709,7 +13710,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename ShaderEXTAllocator = std::allocator<UniqueHandle<VULKAN_HPP_NAMESPACE::ShaderEXT, Dispatch>>,
typename B0 = ShaderEXTAllocator,
typename std::enable_if<std::is_same<typename B0::value_type, UniqueHandle<ShaderEXT, Dispatch>>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B0::value_type, UniqueHandle<VULKAN_HPP_NAMESPACE::ShaderEXT, Dispatch>>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<UniqueHandle<VULKAN_HPP_NAMESPACE::ShaderEXT, Dispatch>, ShaderEXTAllocator>>::type
createShadersEXTUnique( VULKAN_HPP_NAMESPACE::ArrayProxy<const VULKAN_HPP_NAMESPACE::ShaderCreateInfoEXT> const & createInfos,
Optional<const VULKAN_HPP_NAMESPACE::AllocationCallbacks> allocator,
@@ -13777,7 +13778,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename TilePropertiesQCOMAllocator = std::allocator<VULKAN_HPP_NAMESPACE::TilePropertiesQCOM>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = TilePropertiesQCOMAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, TilePropertiesQCOM>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::TilePropertiesQCOM>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::TilePropertiesQCOM, TilePropertiesQCOMAllocator>>::type
getFramebufferTilePropertiesQCOM( VULKAN_HPP_NAMESPACE::Framebuffer framebuffer,
TilePropertiesQCOMAllocator & tilePropertiesQCOMAllocator,
@@ -14118,7 +14119,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename QueueFamilyPropertiesAllocator = std::allocator<VULKAN_HPP_NAMESPACE::QueueFamilyProperties>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = QueueFamilyPropertiesAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, QueueFamilyProperties>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::QueueFamilyProperties>::value, int>::type = 0>
VULKAN_HPP_NODISCARD std::vector<VULKAN_HPP_NAMESPACE::QueueFamilyProperties, QueueFamilyPropertiesAllocator>
getQueueFamilyProperties( QueueFamilyPropertiesAllocator & queueFamilyPropertiesAllocator,
Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
@@ -14167,7 +14168,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename ExtensionPropertiesAllocator = std::allocator<VULKAN_HPP_NAMESPACE::ExtensionProperties>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = ExtensionPropertiesAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, ExtensionProperties>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::ExtensionProperties>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::ExtensionProperties, ExtensionPropertiesAllocator>>::type
enumerateDeviceExtensionProperties( Optional<const std::string> layerName,
ExtensionPropertiesAllocator & extensionPropertiesAllocator,
@@ -14185,7 +14186,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename LayerPropertiesAllocator = std::allocator<VULKAN_HPP_NAMESPACE::LayerProperties>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = LayerPropertiesAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, LayerProperties>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::LayerProperties>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::LayerProperties, LayerPropertiesAllocator>>::type
enumerateDeviceLayerProperties( LayerPropertiesAllocator & layerPropertiesAllocator, Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
#endif /* VULKAN_HPP_DISABLE_ENHANCED_MODE */
@@ -14212,7 +14213,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename SparseImageFormatPropertiesAllocator = std::allocator<VULKAN_HPP_NAMESPACE::SparseImageFormatProperties>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = SparseImageFormatPropertiesAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, SparseImageFormatProperties>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::SparseImageFormatProperties>::value, int>::type = 0>
VULKAN_HPP_NODISCARD std::vector<VULKAN_HPP_NAMESPACE::SparseImageFormatProperties, SparseImageFormatPropertiesAllocator>
getSparseImageFormatProperties( VULKAN_HPP_NAMESPACE::Format format,
VULKAN_HPP_NAMESPACE::ImageType type,
@@ -14289,7 +14290,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename QueueFamilyProperties2Allocator = std::allocator<VULKAN_HPP_NAMESPACE::QueueFamilyProperties2>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = QueueFamilyProperties2Allocator,
typename std::enable_if<std::is_same<typename B1::value_type, QueueFamilyProperties2>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::QueueFamilyProperties2>::value, int>::type = 0>
VULKAN_HPP_NODISCARD std::vector<VULKAN_HPP_NAMESPACE::QueueFamilyProperties2, QueueFamilyProperties2Allocator>
getQueueFamilyProperties2( QueueFamilyProperties2Allocator & queueFamilyProperties2Allocator,
Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
@@ -14333,7 +14334,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename SparseImageFormatProperties2Allocator = std::allocator<VULKAN_HPP_NAMESPACE::SparseImageFormatProperties2>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = SparseImageFormatProperties2Allocator,
typename std::enable_if<std::is_same<typename B1::value_type, SparseImageFormatProperties2>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::SparseImageFormatProperties2>::value, int>::type = 0>
VULKAN_HPP_NODISCARD std::vector<VULKAN_HPP_NAMESPACE::SparseImageFormatProperties2, SparseImageFormatProperties2Allocator>
getSparseImageFormatProperties2( const VULKAN_HPP_NAMESPACE::PhysicalDeviceSparseImageFormatInfo2 & formatInfo,
SparseImageFormatProperties2Allocator & sparseImageFormatProperties2Allocator,
@@ -14387,7 +14388,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename PhysicalDeviceToolPropertiesAllocator = std::allocator<VULKAN_HPP_NAMESPACE::PhysicalDeviceToolProperties>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = PhysicalDeviceToolPropertiesAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, PhysicalDeviceToolProperties>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::PhysicalDeviceToolProperties>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::PhysicalDeviceToolProperties, PhysicalDeviceToolPropertiesAllocator>>::type
getToolProperties( PhysicalDeviceToolPropertiesAllocator & physicalDeviceToolPropertiesAllocator,
Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
@@ -14430,7 +14431,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename SurfaceFormatKHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::SurfaceFormatKHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = SurfaceFormatKHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, SurfaceFormatKHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::SurfaceFormatKHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::SurfaceFormatKHR, SurfaceFormatKHRAllocator>>::type
getSurfaceFormatsKHR( VULKAN_HPP_NAMESPACE::SurfaceKHR surface,
SurfaceFormatKHRAllocator & surfaceFormatKHRAllocator,
@@ -14450,7 +14451,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename PresentModeKHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::PresentModeKHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = PresentModeKHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, PresentModeKHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::PresentModeKHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::PresentModeKHR, PresentModeKHRAllocator>>::type
getSurfacePresentModesKHR( VULKAN_HPP_NAMESPACE::SurfaceKHR surface,
PresentModeKHRAllocator & presentModeKHRAllocator,
@@ -14471,7 +14472,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename Rect2DAllocator = std::allocator<VULKAN_HPP_NAMESPACE::Rect2D>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = Rect2DAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, Rect2D>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::Rect2D>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::Rect2D, Rect2DAllocator>>::type getPresentRectanglesKHR(
VULKAN_HPP_NAMESPACE::SurfaceKHR surface, Rect2DAllocator & rect2DAllocator, Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
#endif /* VULKAN_HPP_DISABLE_ENHANCED_MODE */
@@ -14490,7 +14491,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename DisplayPropertiesKHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::DisplayPropertiesKHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = DisplayPropertiesKHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, DisplayPropertiesKHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::DisplayPropertiesKHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::DisplayPropertiesKHR, DisplayPropertiesKHRAllocator>>::type
getDisplayPropertiesKHR( DisplayPropertiesKHRAllocator & displayPropertiesKHRAllocator,
Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
@@ -14508,7 +14509,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename DisplayPlanePropertiesKHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::DisplayPlanePropertiesKHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = DisplayPlanePropertiesKHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, DisplayPlanePropertiesKHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::DisplayPlanePropertiesKHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::DisplayPlanePropertiesKHR, DisplayPlanePropertiesKHRAllocator>>::type
getDisplayPlanePropertiesKHR( DisplayPlanePropertiesKHRAllocator & displayPlanePropertiesKHRAllocator,
Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
@@ -14526,7 +14527,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename DisplayKHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::DisplayKHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = DisplayKHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, DisplayKHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::DisplayKHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::DisplayKHR, DisplayKHRAllocator>>::type getDisplayPlaneSupportedDisplaysKHR(
uint32_t planeIndex, DisplayKHRAllocator & displayKHRAllocator, Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
#endif /* VULKAN_HPP_DISABLE_ENHANCED_MODE */
@@ -14544,7 +14545,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename DisplayModePropertiesKHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::DisplayModePropertiesKHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = DisplayModePropertiesKHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, DisplayModePropertiesKHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::DisplayModePropertiesKHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::DisplayModePropertiesKHR, DisplayModePropertiesKHRAllocator>>::type
getDisplayModePropertiesKHR( VULKAN_HPP_NAMESPACE::DisplayKHR display,
DisplayModePropertiesKHRAllocator & displayModePropertiesKHRAllocator,
@@ -14672,7 +14673,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename VideoFormatPropertiesKHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::VideoFormatPropertiesKHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = VideoFormatPropertiesKHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, VideoFormatPropertiesKHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::VideoFormatPropertiesKHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::VideoFormatPropertiesKHR, VideoFormatPropertiesKHRAllocator>>::type
getVideoFormatPropertiesKHR( const VULKAN_HPP_NAMESPACE::PhysicalDeviceVideoFormatInfoKHR & videoFormatInfo,
VideoFormatPropertiesKHRAllocator & videoFormatPropertiesKHRAllocator,
@@ -14768,7 +14769,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename QueueFamilyProperties2Allocator = std::allocator<VULKAN_HPP_NAMESPACE::QueueFamilyProperties2>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = QueueFamilyProperties2Allocator,
typename std::enable_if<std::is_same<typename B1::value_type, QueueFamilyProperties2>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::QueueFamilyProperties2>::value, int>::type = 0>
VULKAN_HPP_NODISCARD std::vector<VULKAN_HPP_NAMESPACE::QueueFamilyProperties2, QueueFamilyProperties2Allocator>
getQueueFamilyProperties2KHR( QueueFamilyProperties2Allocator & queueFamilyProperties2Allocator,
Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
@@ -14812,7 +14813,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename SparseImageFormatProperties2Allocator = std::allocator<VULKAN_HPP_NAMESPACE::SparseImageFormatProperties2>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = SparseImageFormatProperties2Allocator,
typename std::enable_if<std::is_same<typename B1::value_type, SparseImageFormatProperties2>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::SparseImageFormatProperties2>::value, int>::type = 0>
VULKAN_HPP_NODISCARD std::vector<VULKAN_HPP_NAMESPACE::SparseImageFormatProperties2, SparseImageFormatProperties2Allocator>
getSparseImageFormatProperties2KHR( const VULKAN_HPP_NAMESPACE::PhysicalDeviceSparseImageFormatInfo2 & formatInfo,
SparseImageFormatProperties2Allocator & sparseImageFormatProperties2Allocator,
@@ -14932,8 +14933,8 @@ namespace VULKAN_HPP_NAMESPACE
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = PerformanceCounterKHRAllocator,
typename B2 = PerformanceCounterDescriptionKHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, PerformanceCounterKHR>::value &&
std::is_same<typename B2::value_type, PerformanceCounterDescriptionKHR>::value,
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::PerformanceCounterKHR>::value &&
std::is_same<typename B2::value_type, VULKAN_HPP_NAMESPACE::PerformanceCounterDescriptionKHR>::value,
int>::type = 0>
VULKAN_HPP_NODISCARD
typename ResultValueType<std::pair<std::vector<VULKAN_HPP_NAMESPACE::PerformanceCounterKHR, PerformanceCounterKHRAllocator>,
@@ -14986,7 +14987,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename SurfaceFormat2KHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::SurfaceFormat2KHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = SurfaceFormat2KHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, SurfaceFormat2KHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::SurfaceFormat2KHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::SurfaceFormat2KHR, SurfaceFormat2KHRAllocator>>::type
getSurfaceFormats2KHR( const VULKAN_HPP_NAMESPACE::PhysicalDeviceSurfaceInfo2KHR & surfaceInfo,
SurfaceFormat2KHRAllocator & surfaceFormat2KHRAllocator,
@@ -15022,7 +15023,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename DisplayProperties2KHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::DisplayProperties2KHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = DisplayProperties2KHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, DisplayProperties2KHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::DisplayProperties2KHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::DisplayProperties2KHR, DisplayProperties2KHRAllocator>>::type
getDisplayProperties2KHR( DisplayProperties2KHRAllocator & displayProperties2KHRAllocator,
Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
@@ -15040,7 +15041,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename DisplayPlaneProperties2KHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::DisplayPlaneProperties2KHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = DisplayPlaneProperties2KHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, DisplayPlaneProperties2KHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::DisplayPlaneProperties2KHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::DisplayPlaneProperties2KHR, DisplayPlaneProperties2KHRAllocator>>::type
getDisplayPlaneProperties2KHR( DisplayPlaneProperties2KHRAllocator & displayPlaneProperties2KHRAllocator,
Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
@@ -15059,7 +15060,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename DisplayModeProperties2KHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::DisplayModeProperties2KHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = DisplayModeProperties2KHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, DisplayModeProperties2KHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::DisplayModeProperties2KHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::DisplayModeProperties2KHR, DisplayModeProperties2KHRAllocator>>::type
getDisplayModeProperties2KHR( VULKAN_HPP_NAMESPACE::DisplayKHR display,
DisplayModeProperties2KHRAllocator & displayModeProperties2KHRAllocator,
@@ -15103,7 +15104,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename TimeDomainKHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::TimeDomainKHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = TimeDomainKHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, TimeDomainKHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::TimeDomainKHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::TimeDomainKHR, TimeDomainKHRAllocator>>::type
getCalibrateableTimeDomainsEXT( TimeDomainKHRAllocator & timeDomainKHRAllocator, Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
#endif /* VULKAN_HPP_DISABLE_ENHANCED_MODE */
@@ -15123,7 +15124,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename PhysicalDeviceFragmentShadingRateKHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::PhysicalDeviceFragmentShadingRateKHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = PhysicalDeviceFragmentShadingRateKHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, PhysicalDeviceFragmentShadingRateKHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::PhysicalDeviceFragmentShadingRateKHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD
typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::PhysicalDeviceFragmentShadingRateKHR, PhysicalDeviceFragmentShadingRateKHRAllocator>>::type
getFragmentShadingRatesKHR( PhysicalDeviceFragmentShadingRateKHRAllocator & physicalDeviceFragmentShadingRateKHRAllocator,
@@ -15144,7 +15145,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename PhysicalDeviceToolPropertiesAllocator = std::allocator<VULKAN_HPP_NAMESPACE::PhysicalDeviceToolProperties>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = PhysicalDeviceToolPropertiesAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, PhysicalDeviceToolProperties>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::PhysicalDeviceToolProperties>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::PhysicalDeviceToolProperties, PhysicalDeviceToolPropertiesAllocator>>::type
getToolPropertiesEXT( PhysicalDeviceToolPropertiesAllocator & physicalDeviceToolPropertiesAllocator,
Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
@@ -15165,7 +15166,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename CooperativeMatrixPropertiesNVAllocator = std::allocator<VULKAN_HPP_NAMESPACE::CooperativeMatrixPropertiesNV>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = CooperativeMatrixPropertiesNVAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, CooperativeMatrixPropertiesNV>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::CooperativeMatrixPropertiesNV>::value, int>::type = 0>
VULKAN_HPP_NODISCARD
typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::CooperativeMatrixPropertiesNV, CooperativeMatrixPropertiesNVAllocator>>::type
getCooperativeMatrixPropertiesNV( CooperativeMatrixPropertiesNVAllocator & cooperativeMatrixPropertiesNVAllocator,
@@ -15188,7 +15189,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename FramebufferMixedSamplesCombinationNVAllocator = std::allocator<VULKAN_HPP_NAMESPACE::FramebufferMixedSamplesCombinationNV>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = FramebufferMixedSamplesCombinationNVAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, FramebufferMixedSamplesCombinationNV>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::FramebufferMixedSamplesCombinationNV>::value, int>::type = 0>
VULKAN_HPP_NODISCARD
typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::FramebufferMixedSamplesCombinationNV, FramebufferMixedSamplesCombinationNVAllocator>>::type
getSupportedFramebufferMixedSamplesCombinationsNV( FramebufferMixedSamplesCombinationNVAllocator & framebufferMixedSamplesCombinationNVAllocator,
@@ -15211,7 +15212,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename PresentModeKHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::PresentModeKHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = PresentModeKHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, PresentModeKHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::PresentModeKHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::PresentModeKHR, PresentModeKHRAllocator>>::type
getSurfacePresentModes2EXT( const VULKAN_HPP_NAMESPACE::PhysicalDeviceSurfaceInfo2KHR & surfaceInfo,
PresentModeKHRAllocator & presentModeKHRAllocator,
@@ -15342,7 +15343,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename OpticalFlowImageFormatPropertiesNVAllocator = std::allocator<VULKAN_HPP_NAMESPACE::OpticalFlowImageFormatPropertiesNV>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = OpticalFlowImageFormatPropertiesNVAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, OpticalFlowImageFormatPropertiesNV>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::OpticalFlowImageFormatPropertiesNV>::value, int>::type = 0>
VULKAN_HPP_NODISCARD
typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::OpticalFlowImageFormatPropertiesNV, OpticalFlowImageFormatPropertiesNVAllocator>>::type
getOpticalFlowImageFormatsNV( const VULKAN_HPP_NAMESPACE::OpticalFlowImageFormatInfoNV & opticalFlowImageFormatInfo,
@@ -15365,7 +15366,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename CooperativeMatrixPropertiesKHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::CooperativeMatrixPropertiesKHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = CooperativeMatrixPropertiesKHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, CooperativeMatrixPropertiesKHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::CooperativeMatrixPropertiesKHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD
typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::CooperativeMatrixPropertiesKHR, CooperativeMatrixPropertiesKHRAllocator>>::type
getCooperativeMatrixPropertiesKHR( CooperativeMatrixPropertiesKHRAllocator & cooperativeMatrixPropertiesKHRAllocator,
@@ -15385,7 +15386,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename TimeDomainKHRAllocator = std::allocator<VULKAN_HPP_NAMESPACE::TimeDomainKHR>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = TimeDomainKHRAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, TimeDomainKHR>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::TimeDomainKHR>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::TimeDomainKHR, TimeDomainKHRAllocator>>::type
getCalibrateableTimeDomainsKHR( TimeDomainKHRAllocator & timeDomainKHRAllocator, Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
#endif /* VULKAN_HPP_DISABLE_ENHANCED_MODE */
@@ -15497,7 +15498,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename PhysicalDeviceAllocator = std::allocator<VULKAN_HPP_NAMESPACE::PhysicalDevice>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = PhysicalDeviceAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, PhysicalDevice>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::PhysicalDevice>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::PhysicalDevice, PhysicalDeviceAllocator>>::type
enumeratePhysicalDevices( PhysicalDeviceAllocator & physicalDeviceAllocator, Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
#endif /* VULKAN_HPP_DISABLE_ENHANCED_MODE */
@@ -15524,7 +15525,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename PhysicalDeviceGroupPropertiesAllocator = std::allocator<VULKAN_HPP_NAMESPACE::PhysicalDeviceGroupProperties>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = PhysicalDeviceGroupPropertiesAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, PhysicalDeviceGroupProperties>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::PhysicalDeviceGroupProperties>::value, int>::type = 0>
VULKAN_HPP_NODISCARD
typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::PhysicalDeviceGroupProperties, PhysicalDeviceGroupPropertiesAllocator>>::type
enumeratePhysicalDeviceGroups( PhysicalDeviceGroupPropertiesAllocator & physicalDeviceGroupPropertiesAllocator,
@@ -15825,7 +15826,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename PhysicalDeviceGroupPropertiesAllocator = std::allocator<VULKAN_HPP_NAMESPACE::PhysicalDeviceGroupProperties>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = PhysicalDeviceGroupPropertiesAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, PhysicalDeviceGroupProperties>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::PhysicalDeviceGroupProperties>::value, int>::type = 0>
VULKAN_HPP_NODISCARD
typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::PhysicalDeviceGroupProperties, PhysicalDeviceGroupPropertiesAllocator>>::type
enumeratePhysicalDeviceGroupsKHR( PhysicalDeviceGroupPropertiesAllocator & physicalDeviceGroupPropertiesAllocator,
@@ -16128,7 +16129,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename ExtensionPropertiesAllocator = std::allocator<VULKAN_HPP_NAMESPACE::ExtensionProperties>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = ExtensionPropertiesAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, ExtensionProperties>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::ExtensionProperties>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::ExtensionProperties, ExtensionPropertiesAllocator>>::type
enumerateInstanceExtensionProperties( Optional<const std::string> layerName,
ExtensionPropertiesAllocator & extensionPropertiesAllocator,
@@ -16146,7 +16147,7 @@ namespace VULKAN_HPP_NAMESPACE
template <typename LayerPropertiesAllocator = std::allocator<VULKAN_HPP_NAMESPACE::LayerProperties>,
typename Dispatch = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE,
typename B1 = LayerPropertiesAllocator,
typename std::enable_if<std::is_same<typename B1::value_type, LayerProperties>::value, int>::type = 0>
typename std::enable_if<std::is_same<typename B1::value_type, VULKAN_HPP_NAMESPACE::LayerProperties>::value, int>::type = 0>
VULKAN_HPP_NODISCARD typename ResultValueType<std::vector<VULKAN_HPP_NAMESPACE::LayerProperties, LayerPropertiesAllocator>>::type
enumerateInstanceLayerProperties( LayerPropertiesAllocator & layerPropertiesAllocator, Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT );
#endif /* VULKAN_HPP_DISABLE_ENHANCED_MODE */
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2015-2023 The Khronos Group Inc.
// Copyright 2015-2024 The Khronos Group Inc.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
+18 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2015-2023 The Khronos Group Inc.
// Copyright 2015-2024 The Khronos Group Inc.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
@@ -277,4 +277,21 @@ namespace VULKAN_HPP_NAMESPACE
# define VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT = VULKAN_HPP_DEFAULT_DISPATCHER
#endif
#if !defined( VULKAN_HPP_EXPECTED ) && ( 23 <= VULKAN_HPP_CPP_VERSION ) && defined( __cpp_lib_expected )
# include <expected>
# define VULKAN_HPP_EXPECTED std::expected
# define VULKAN_HPP_UNEXPECTED std::unexpected
#endif
#if !defined( VULKAN_HPP_RAII_NAMESPACE )
# define VULKAN_HPP_RAII_NAMESPACE raii
#endif
#if defined( VULKAN_HPP_NO_EXCEPTIONS ) && defined( VULKAN_HPP_EXPECTED )
# define VULKAN_HPP_RAII_NO_EXCEPTIONS
# define VULKAN_HPP_RAII_CREATE_NOEXCEPT noexcept
#else
# define VULKAN_HPP_RAII_CREATE_NOEXCEPT
#endif
#endif
+1 -1
View File
@@ -2,7 +2,7 @@
#define VULKAN_IOS_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/
+1 -1
View File
@@ -2,7 +2,7 @@
#define VULKAN_MACOS_H_ 1
/*
** Copyright 2015-2023 The Khronos Group Inc.
** Copyright 2015-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/

Some files were not shown because too many files have changed in this diff Show More