mirror of
https://github.com/slendidev/lunar.git
synced 2025-12-08 10:29:52 +02:00
@@ -21,6 +21,8 @@
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
glslang
|
||||
shaderc
|
||||
];
|
||||
buildInputs = with pkgs; [
|
||||
vulkan-loader
|
||||
|
||||
24
meson.build
24
meson.build
@@ -1,7 +1,7 @@
|
||||
project('vr-compositor', 'cpp',
|
||||
version: '0.1',
|
||||
default_options: [
|
||||
'cpp_std=c++23',
|
||||
'cpp_std=c++26',
|
||||
'warning_level=everything',
|
||||
'werror=true',
|
||||
]
|
||||
@@ -28,17 +28,30 @@ vkbootstrap_dep = cc.find_library(
|
||||
required: true,
|
||||
)
|
||||
|
||||
add_project_arguments('-Wpedantic', language : ['c', 'cpp'])
|
||||
add_project_arguments(
|
||||
'-Wpedantic',
|
||||
language : ['c', 'cpp']
|
||||
[
|
||||
'-Wno-c++98-compat',
|
||||
'-Wno-c++98-compat-pedantic',
|
||||
'-Wno-covered-switch-default',
|
||||
'-Wno-undef',
|
||||
'-Wno-padded',
|
||||
'-Wno-unsafe-buffer-usage',
|
||||
'-Wno-c23-extensions',
|
||||
],
|
||||
language : 'cpp'
|
||||
)
|
||||
|
||||
subdir('shaders')
|
||||
|
||||
exe = executable('vr-compositor',
|
||||
[
|
||||
'src/main.cpp',
|
||||
'src/Impls.cpp',
|
||||
'src/Util.cpp',
|
||||
'src/Logger.cpp',
|
||||
'src/DescriptorLayoutBuilder.cpp',
|
||||
'src/DescriptorAllocator.cpp',
|
||||
'src/Application.cpp',
|
||||
],
|
||||
include_directories: vkbootstrap_inc,
|
||||
@@ -49,5 +62,8 @@ exe = executable('vr-compositor',
|
||||
vkbootstrap_dep,
|
||||
zlib_dep,
|
||||
sdl3_dep,
|
||||
]
|
||||
],
|
||||
cpp_args: [
|
||||
'--embed-dir=' + join_paths(meson.project_build_root(), 'shaders')
|
||||
],
|
||||
)
|
||||
|
||||
23
shaders/gradient.comp
Normal file
23
shaders/gradient.comp
Normal file
@@ -0,0 +1,23 @@
|
||||
#version 460
|
||||
|
||||
layout (local_size_x = 16, local_size_y = 16) in;
|
||||
layout(rgba16f, set = 0, binding = 0) uniform image2D image;
|
||||
|
||||
void main() {
|
||||
ivec2 texelCoord = ivec2(gl_GlobalInvocationID.xy);
|
||||
ivec2 size = imageSize(image);
|
||||
|
||||
if (texelCoord.x >= size.x || texelCoord.y >= size.y)
|
||||
return;
|
||||
|
||||
vec2 uv = (vec2(texelCoord) + 0.5) / vec2(size);
|
||||
|
||||
float v = sin(uv.x * 10.0) + cos(uv.y * 10.0);
|
||||
|
||||
float r = 0.5 + 0.5 * cos(6.2831 * (uv.x + v));
|
||||
float g = 0.5 + 0.5 * cos(6.2831 * (uv.y + v + 0.33));
|
||||
float b = 0.5 + 0.5 * cos(6.2831 * (uv.x - uv.y + 0.66));
|
||||
|
||||
vec4 color = vec4(r, g, b, 1.0);
|
||||
imageStore(image, texelCoord, color);
|
||||
}
|
||||
30
shaders/meson.build
Normal file
30
shaders/meson.build
Normal file
@@ -0,0 +1,30 @@
|
||||
fs = import('fs')
|
||||
|
||||
glslc = find_program('glslc', required : false)
|
||||
glslang = find_program('glslangValidator', required : false)
|
||||
|
||||
if glslc.found()
|
||||
shader_compiler = glslc
|
||||
shader_compile_cmd = [shader_compiler, '-o', '@OUTPUT@', '@INPUT@']
|
||||
elif glslang.found()
|
||||
shader_compiler = glslang
|
||||
shader_compile_cmd = [shader_compiler, '-V', '@INPUT@', '-o', '@OUTPUT@']
|
||||
else
|
||||
error('Either glslc or glslangValidator is required to build shaders')
|
||||
endif
|
||||
|
||||
shader_sources = files(
|
||||
'gradient.comp',
|
||||
)
|
||||
|
||||
spirv_shaders = []
|
||||
foreach shader : shader_sources
|
||||
shader_name = fs.stem(shader)
|
||||
spirv_shaders += custom_target(
|
||||
shader_name + '_spv',
|
||||
input : shader,
|
||||
output : shader_name + '.spv',
|
||||
command : shader_compile_cmd,
|
||||
build_by_default : true,
|
||||
)
|
||||
endforeach
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include "Util.h"
|
||||
#include "src/DescriptorLayoutBuilder.h"
|
||||
|
||||
namespace Lunar {
|
||||
|
||||
@@ -34,6 +35,8 @@ Application::Application()
|
||||
swapchain_init();
|
||||
commands_init();
|
||||
sync_init();
|
||||
descriptors_init();
|
||||
pipelines_init();
|
||||
|
||||
m_logger.info("App init done!");
|
||||
}
|
||||
@@ -156,7 +159,7 @@ auto Application::swapchain_init() -> void
|
||||
{
|
||||
int w, h;
|
||||
SDL_GetWindowSize(m_window, &w, &h);
|
||||
create_swapchain(w, h);
|
||||
create_swapchain(static_cast<uint32_t>(w), static_cast<uint32_t>(h));
|
||||
create_draw_image(static_cast<uint32_t>(w), static_cast<uint32_t>(h));
|
||||
}
|
||||
|
||||
@@ -210,12 +213,85 @@ auto Application::sync_init() -> void
|
||||
}
|
||||
}
|
||||
|
||||
auto Application::descriptors_init() -> void
|
||||
{
|
||||
std::vector<DescriptorAllocator::PoolSizeRatio> sizes {
|
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1 },
|
||||
};
|
||||
m_vk.descriptor_allocator.init_pool(m_vkb.dev, 10, sizes);
|
||||
|
||||
m_vk.draw_image_descriptor_layout
|
||||
= DescriptorLayoutBuilder()
|
||||
.add_binding(0, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
|
||||
.build(m_logger, m_vkb.dev, VK_SHADER_STAGE_COMPUTE_BIT);
|
||||
|
||||
m_vk.draw_image_descriptors = m_vk.descriptor_allocator.allocate(
|
||||
m_logger, m_vkb.dev, m_vk.draw_image_descriptor_layout);
|
||||
|
||||
update_draw_image_descriptor();
|
||||
|
||||
m_vk.deletion_queue.emplace([&]() {
|
||||
m_vk.descriptor_allocator.destroy_pool(m_vkb.dev);
|
||||
vkDestroyDescriptorSetLayout(
|
||||
m_vkb.dev, m_vk.draw_image_descriptor_layout, nullptr);
|
||||
});
|
||||
}
|
||||
|
||||
auto Application::pipelines_init() -> void { background_pipelines_init(); }
|
||||
|
||||
auto Application::background_pipelines_init() -> void
|
||||
{
|
||||
VkPipelineLayoutCreateInfo layout_ci {};
|
||||
layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
layout_ci.pNext = nullptr;
|
||||
layout_ci.pSetLayouts = &m_vk.draw_image_descriptor_layout;
|
||||
layout_ci.setLayoutCount = 1;
|
||||
|
||||
VK_CHECK(m_logger,
|
||||
vkCreatePipelineLayout(
|
||||
m_vkb.dev, &layout_ci, nullptr, &m_vk.gradient_pipeline_layout));
|
||||
|
||||
uint8_t compute_draw_shader_data[] {
|
||||
#embed "gradient.spv"
|
||||
};
|
||||
VkShaderModule compute_draw_shader {};
|
||||
if (!vkutil::load_shader_module(std::span<uint8_t>(compute_draw_shader_data,
|
||||
sizeof(compute_draw_shader_data)),
|
||||
m_vkb.dev, &compute_draw_shader)) {
|
||||
m_logger.err("Failed to load gradient compute shader");
|
||||
}
|
||||
|
||||
VkPipelineShaderStageCreateInfo stage_ci {};
|
||||
stage_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
stage_ci.pNext = nullptr;
|
||||
stage_ci.stage = VK_SHADER_STAGE_COMPUTE_BIT;
|
||||
stage_ci.module = compute_draw_shader;
|
||||
stage_ci.pName = "main";
|
||||
|
||||
VkComputePipelineCreateInfo compute_pip_ci {};
|
||||
compute_pip_ci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
|
||||
compute_pip_ci.pNext = nullptr;
|
||||
compute_pip_ci.layout = m_vk.gradient_pipeline_layout;
|
||||
compute_pip_ci.stage = stage_ci;
|
||||
|
||||
VK_CHECK(m_logger,
|
||||
vkCreateComputePipelines(m_vkb.dev, VK_NULL_HANDLE, 1, &compute_pip_ci,
|
||||
nullptr, &m_vk.gradient_pipeline));
|
||||
|
||||
vkDestroyShaderModule(m_vkb.dev, compute_draw_shader, nullptr);
|
||||
m_vk.deletion_queue.emplace([&]() {
|
||||
vkDestroyPipelineLayout(
|
||||
m_vkb.dev, m_vk.gradient_pipeline_layout, nullptr);
|
||||
vkDestroyPipeline(m_vkb.dev, m_vk.gradient_pipeline, nullptr);
|
||||
});
|
||||
}
|
||||
|
||||
auto Application::render() -> void
|
||||
{
|
||||
defer(m_vk.frame_number++);
|
||||
|
||||
if (m_vk.swapchain == VK_NULL_HANDLE
|
||||
|| m_vk.swapchain_extent.width == 0 || m_vk.swapchain_extent.height == 0) {
|
||||
if (m_vk.swapchain == VK_NULL_HANDLE || m_vk.swapchain_extent.width == 0
|
||||
|| m_vk.swapchain_extent.height == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -319,20 +395,14 @@ auto Application::render() -> void
|
||||
|
||||
auto Application::draw_background(VkCommandBuffer cmd) -> void
|
||||
{
|
||||
VkClearColorValue clear_value;
|
||||
float flash { std::abs(std::sin(m_vk.frame_number / 60.f)) };
|
||||
clear_value = { { 0x64 / 255.0f * flash, 0x95 / 255.0f * flash,
|
||||
0xED / 255.0f * flash, 1.0f } };
|
||||
|
||||
VkImageSubresourceRange clear_range {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
};
|
||||
vkCmdClearColorImage(cmd, m_vk.draw_image.image, VK_IMAGE_LAYOUT_GENERAL,
|
||||
&clear_value, 1, &clear_range);
|
||||
vkCmdBindPipeline(
|
||||
cmd, VK_PIPELINE_BIND_POINT_COMPUTE, m_vk.gradient_pipeline);
|
||||
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_COMPUTE,
|
||||
m_vk.gradient_pipeline_layout, 0, 1, &m_vk.draw_image_descriptors, 0,
|
||||
nullptr);
|
||||
vkCmdDispatch(cmd,
|
||||
static_cast<uint32_t>(std::ceil(m_vk.draw_extent.width / 16.0)),
|
||||
static_cast<uint32_t>(std::ceil(m_vk.draw_extent.height / 16.0)), 1);
|
||||
}
|
||||
|
||||
auto Application::create_swapchain(uint32_t width, uint32_t height) -> void
|
||||
@@ -404,6 +474,25 @@ auto Application::create_draw_image(uint32_t width, uint32_t height) -> void
|
||||
m_vkb.dev, &rview_ci, nullptr, &m_vk.draw_image.image_view));
|
||||
}
|
||||
|
||||
auto Application::update_draw_image_descriptor() -> void
|
||||
{
|
||||
// Point the storage image descriptor at the current draw image view
|
||||
VkDescriptorImageInfo img_info {};
|
||||
img_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
img_info.imageView = m_vk.draw_image.image_view;
|
||||
|
||||
VkWriteDescriptorSet draw_img_write {};
|
||||
draw_img_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
draw_img_write.pNext = nullptr;
|
||||
draw_img_write.dstBinding = 0;
|
||||
draw_img_write.dstSet = m_vk.draw_image_descriptors;
|
||||
draw_img_write.descriptorCount = 1;
|
||||
draw_img_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||
draw_img_write.pImageInfo = &img_info;
|
||||
|
||||
vkUpdateDescriptorSets(m_vkb.dev, 1, &draw_img_write, 0, nullptr);
|
||||
}
|
||||
|
||||
auto Application::destroy_draw_image() -> void
|
||||
{
|
||||
if (m_vk.draw_image.image_view != VK_NULL_HANDLE) {
|
||||
@@ -435,6 +524,7 @@ auto Application::recreate_swapchain(uint32_t width, uint32_t height) -> void
|
||||
|
||||
create_swapchain(width, height);
|
||||
create_draw_image(width, height);
|
||||
update_draw_image_descriptor();
|
||||
}
|
||||
|
||||
auto Application::destroy_swapchain() -> void
|
||||
@@ -496,8 +586,8 @@ auto Application::run() -> void
|
||||
} else if (e.type == SDL_EVENT_WINDOW_RESIZED) {
|
||||
int width {}, height {};
|
||||
SDL_GetWindowSize(m_window, &width, &height);
|
||||
recreate_swapchain(
|
||||
static_cast<uint32_t>(width), static_cast<uint32_t>(height));
|
||||
recreate_swapchain(static_cast<uint32_t>(width),
|
||||
static_cast<uint32_t>(height));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "AllocatedImage.h"
|
||||
#include "DeletionQueue.h"
|
||||
#include "Logger.h"
|
||||
#include "src/DescriptorAllocator.h"
|
||||
|
||||
namespace Lunar {
|
||||
|
||||
@@ -35,12 +36,16 @@ private:
|
||||
auto swapchain_init() -> void;
|
||||
auto commands_init() -> void;
|
||||
auto sync_init() -> void;
|
||||
auto descriptors_init() -> void;
|
||||
auto pipelines_init() -> void;
|
||||
auto background_pipelines_init() -> void;
|
||||
|
||||
auto draw_background(VkCommandBuffer cmd) -> void;
|
||||
auto render() -> void;
|
||||
|
||||
auto create_swapchain(uint32_t width, uint32_t height) -> void;
|
||||
auto create_draw_image(uint32_t width, uint32_t height) -> void;
|
||||
auto update_draw_image_descriptor() -> void;
|
||||
auto destroy_draw_image() -> void;
|
||||
auto recreate_swapchain(uint32_t width, uint32_t height) -> void;
|
||||
auto destroy_swapchain() -> void;
|
||||
@@ -54,11 +59,11 @@ private:
|
||||
|
||||
struct {
|
||||
VkSwapchainKHR swapchain { VK_NULL_HANDLE };
|
||||
VkFormat swapchain_image_format;
|
||||
VkSurfaceKHR surface { nullptr };
|
||||
VkFormat swapchain_image_format;
|
||||
|
||||
VkQueue graphics_queue { nullptr };
|
||||
uint32_t graphics_queue_family { 0 };
|
||||
VkQueue graphics_queue { nullptr };
|
||||
|
||||
std::vector<VkImage> swapchain_images;
|
||||
std::vector<VkImageView> swapchain_image_views;
|
||||
@@ -75,6 +80,13 @@ private:
|
||||
VkExtent2D draw_extent {};
|
||||
|
||||
VmaAllocator allocator;
|
||||
DescriptorAllocator descriptor_allocator;
|
||||
|
||||
VkDescriptorSet draw_image_descriptors;
|
||||
VkDescriptorSetLayout draw_image_descriptor_layout;
|
||||
|
||||
VkPipeline gradient_pipeline {};
|
||||
VkPipelineLayout gradient_pipeline_layout {};
|
||||
|
||||
DeletionQueue deletion_queue;
|
||||
|
||||
|
||||
57
src/DescriptorAllocator.cpp
Normal file
57
src/DescriptorAllocator.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
#include "DescriptorAllocator.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Util.h"
|
||||
|
||||
namespace Lunar {
|
||||
|
||||
auto DescriptorAllocator::init_pool(VkDevice dev, uint32_t max_sets,
|
||||
std::span<PoolSizeRatio> pool_ratios) -> void
|
||||
{
|
||||
std::vector<VkDescriptorPoolSize> pool_sizes;
|
||||
for (auto const &ratio : pool_ratios) {
|
||||
pool_sizes.emplace_back(VkDescriptorPoolSize {
|
||||
.type = ratio.type,
|
||||
.descriptorCount = static_cast<uint32_t>(ratio.ratio * max_sets),
|
||||
});
|
||||
}
|
||||
|
||||
VkDescriptorPoolCreateInfo ci {};
|
||||
ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||
ci.pNext = nullptr;
|
||||
ci.flags = 0;
|
||||
ci.maxSets = max_sets;
|
||||
ci.poolSizeCount = static_cast<uint32_t>(pool_sizes.size());
|
||||
ci.pPoolSizes = pool_sizes.data();
|
||||
|
||||
vkCreateDescriptorPool(dev, &ci, nullptr, &pool);
|
||||
}
|
||||
|
||||
auto DescriptorAllocator::clear_descriptors(VkDevice dev) -> void
|
||||
{
|
||||
vkResetDescriptorPool(dev, pool, 0);
|
||||
}
|
||||
|
||||
auto DescriptorAllocator::destroy_pool(VkDevice dev) -> void
|
||||
{
|
||||
vkDestroyDescriptorPool(dev, pool, nullptr);
|
||||
}
|
||||
|
||||
auto DescriptorAllocator::allocate(Logger &logger, VkDevice dev,
|
||||
VkDescriptorSetLayout layout) -> VkDescriptorSet
|
||||
{
|
||||
VkDescriptorSetAllocateInfo ai {};
|
||||
ai.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
ai.pNext = nullptr;
|
||||
ai.descriptorPool = pool;
|
||||
ai.descriptorSetCount = 1;
|
||||
ai.pSetLayouts = &layout;
|
||||
|
||||
VkDescriptorSet ds;
|
||||
VK_CHECK(logger, vkAllocateDescriptorSets(dev, &ai, &ds));
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
} // namespace Lunar
|
||||
28
src/DescriptorAllocator.h
Normal file
28
src/DescriptorAllocator.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <span>
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include "Logger.h"
|
||||
|
||||
namespace Lunar {
|
||||
|
||||
struct DescriptorAllocator {
|
||||
struct PoolSizeRatio {
|
||||
VkDescriptorType type;
|
||||
float ratio;
|
||||
};
|
||||
|
||||
VkDescriptorPool pool;
|
||||
|
||||
auto init_pool(VkDevice dev, uint32_t max_sets,
|
||||
std::span<PoolSizeRatio> pool_ratios) -> void;
|
||||
auto clear_descriptors(VkDevice dev) -> void;
|
||||
auto destroy_pool(VkDevice dev) -> void;
|
||||
|
||||
auto allocate(Logger &logger, VkDevice dev, VkDescriptorSetLayout layout)
|
||||
-> VkDescriptorSet;
|
||||
};
|
||||
|
||||
} // namespace Lunar
|
||||
42
src/DescriptorLayoutBuilder.cpp
Normal file
42
src/DescriptorLayoutBuilder.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "DescriptorLayoutBuilder.h"
|
||||
|
||||
#include "Util.h"
|
||||
|
||||
namespace Lunar {
|
||||
|
||||
auto DescriptorLayoutBuilder::add_binding(
|
||||
uint32_t binding, VkDescriptorType type) -> DescriptorLayoutBuilder &
|
||||
{
|
||||
VkDescriptorSetLayoutBinding b {};
|
||||
b.binding = binding;
|
||||
b.descriptorCount = 1;
|
||||
b.descriptorType = type;
|
||||
|
||||
bindings.emplace_back(b);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto DescriptorLayoutBuilder::build(Logger &logger, VkDevice dev,
|
||||
VkShaderStageFlags shader_stages, void *pNext,
|
||||
VkDescriptorSetLayoutCreateFlags flags) -> VkDescriptorSetLayout
|
||||
{
|
||||
for (auto &&b : bindings) {
|
||||
b.stageFlags |= shader_stages;
|
||||
}
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo ci {};
|
||||
ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||
ci.pNext = pNext;
|
||||
|
||||
ci.pBindings = bindings.data();
|
||||
ci.bindingCount = static_cast<uint32_t>(bindings.size());
|
||||
ci.flags = flags;
|
||||
|
||||
VkDescriptorSetLayout set;
|
||||
VK_CHECK(logger, vkCreateDescriptorSetLayout(dev, &ci, nullptr, &set));
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
} // namespace Lunar
|
||||
22
src/DescriptorLayoutBuilder.h
Normal file
22
src/DescriptorLayoutBuilder.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include "Logger.h"
|
||||
|
||||
namespace Lunar {
|
||||
|
||||
struct DescriptorLayoutBuilder {
|
||||
std::vector<VkDescriptorSetLayoutBinding> bindings;
|
||||
|
||||
auto add_binding(uint32_t binding, VkDescriptorType type)
|
||||
-> DescriptorLayoutBuilder &;
|
||||
auto clear() -> void { bindings.clear(); }
|
||||
auto build(Logger &logger, VkDevice dev, VkShaderStageFlags shader_stages,
|
||||
void *pNext = nullptr, VkDescriptorSetLayoutCreateFlags flags = 0)
|
||||
-> VkDescriptorSetLayout;
|
||||
};
|
||||
|
||||
} // namespace Lunar
|
||||
@@ -31,7 +31,7 @@
|
||||
#define FG_GRAY "\033[90m"
|
||||
#define ANSI_RESET "\033[0m"
|
||||
|
||||
std::filesystem::path get_log_path(std::string_view app_name)
|
||||
static std::filesystem::path get_log_path(std::string_view app_name)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
PWSTR path = nullptr;
|
||||
@@ -53,7 +53,7 @@ std::filesystem::path get_log_path(std::string_view app_name)
|
||||
}
|
||||
|
||||
#ifndef __EMSCRIPTEN__
|
||||
int compress_file(std::filesystem::path const &input_path,
|
||||
static int compress_file(std::filesystem::path const &input_path,
|
||||
std::filesystem::path const &output_path)
|
||||
{
|
||||
size_t const chunk_size = 4096;
|
||||
@@ -69,7 +69,7 @@ int compress_file(std::filesystem::path const &input_path,
|
||||
|
||||
std::vector<char> buffer(chunk_size);
|
||||
while (in) {
|
||||
in.read(buffer.data(), buffer.size());
|
||||
in.read(buffer.data(), static_cast<std::streamsize>(buffer.size()));
|
||||
std::streamsize bytes = in.gcount();
|
||||
if (bytes > 0)
|
||||
gzwrite(out, buffer.data(), static_cast<unsigned int>(bytes));
|
||||
@@ -99,12 +99,14 @@ Logger::Logger(std::string_view app_name)
|
||||
if (!file.is_regular_file())
|
||||
continue;
|
||||
|
||||
int v;
|
||||
if (std::sscanf(
|
||||
file.path().filename().stem().string().c_str(), "log_%d", &v)
|
||||
!= 1) {
|
||||
auto name = file.path().filename().stem().string();
|
||||
constexpr std::string_view prefix = "log_";
|
||||
|
||||
if (name.rfind(prefix, 0) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int v = std::stoi(name.substr(prefix.size()));
|
||||
if (v > max)
|
||||
max = v;
|
||||
|
||||
@@ -139,7 +141,7 @@ auto Logger::err(std::string_view msg) -> void
|
||||
log(Logger::Level::Error, msg);
|
||||
}
|
||||
|
||||
std::string get_current_time_string()
|
||||
static std::string get_current_time_string()
|
||||
{
|
||||
auto now { std::chrono::system_clock::now() };
|
||||
auto now_c { std::chrono::system_clock::to_time_t(now) };
|
||||
|
||||
28
src/Util.cpp
28
src/Util.cpp
@@ -1,5 +1,7 @@
|
||||
#include "Util.h"
|
||||
|
||||
#include <span>
|
||||
|
||||
namespace vkutil {
|
||||
|
||||
auto transition_image(VkCommandBuffer cmd, VkImage image,
|
||||
@@ -75,6 +77,32 @@ auto copy_image_to_image(VkCommandBuffer cmd, VkImage source,
|
||||
vkCmdBlitImage2(cmd, &blit_info);
|
||||
}
|
||||
|
||||
auto load_shader_module(std::span<uint8_t> spirv_data, VkDevice device,
|
||||
VkShaderModule *out_shader_module) -> bool
|
||||
{
|
||||
if (!device || !out_shader_module)
|
||||
return false;
|
||||
|
||||
if (spirv_data.empty() || (spirv_data.size() % 4) != 0)
|
||||
return false;
|
||||
|
||||
VkShaderModuleCreateInfo create_info {};
|
||||
create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
create_info.pNext = nullptr;
|
||||
create_info.flags = 0;
|
||||
create_info.codeSize = spirv_data.size();
|
||||
create_info.pCode = reinterpret_cast<uint32_t const *>(spirv_data.data());
|
||||
|
||||
VkResult const res = vkCreateShaderModule(
|
||||
device, &create_info, nullptr, out_shader_module);
|
||||
if (res != VK_SUCCESS) {
|
||||
*out_shader_module = VK_NULL_HANDLE;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace vkutil
|
||||
|
||||
namespace vkinit {
|
||||
|
||||
10
src/Util.h
10
src/Util.h
@@ -1,16 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
#include <span>
|
||||
|
||||
#include <vulkan/vk_enum_string_helper.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
using namespace std::string_view_literals;
|
||||
|
||||
template<typename F> struct privDefer {
|
||||
F f;
|
||||
privDefer(F f)
|
||||
: f(f)
|
||||
privDefer(F f_)
|
||||
: f(f_)
|
||||
{
|
||||
}
|
||||
~privDefer() { f(); }
|
||||
@@ -44,6 +42,8 @@ auto transition_image(VkCommandBuffer cmd, VkImage image,
|
||||
VkImageLayout current_layout, VkImageLayout new_layout) -> void;
|
||||
auto copy_image_to_image(VkCommandBuffer cmd, VkImage source,
|
||||
VkImage destination, VkExtent2D src_size, VkExtent2D dst_size) -> void;
|
||||
auto load_shader_module(std::span<uint8_t> spirv_data, VkDevice device,
|
||||
VkShaderModule *out_shader_module) -> bool;
|
||||
|
||||
} // namespace vkutil
|
||||
|
||||
|
||||
Reference in New Issue
Block a user