Compare commits
2 commits
2f60b837c9
...
a2efc487c4
| Author | SHA1 | Date | |
|---|---|---|---|
| a2efc487c4 | |||
| 018d19335d |
35 changed files with 1734 additions and 1814 deletions
248
.clang-tidy
248
.clang-tidy
|
|
@ -1,248 +0,0 @@
|
||||||
---
|
|
||||||
Checks: "-*,
|
|
||||||
|
|
||||||
performance-unnecessary-value-param,
|
|
||||||
performance-unnecessary-copy-initialization,
|
|
||||||
performance-type-promotion-in-math-fn,
|
|
||||||
performance-trivially-destructible,
|
|
||||||
performance-noexcept-swap,
|
|
||||||
performance-noexcept-move-constructor,
|
|
||||||
performance-noexcept-destructor,
|
|
||||||
performance-no-int-to-ptr,
|
|
||||||
performance-no-automatic-move,
|
|
||||||
performance-move-constructor-init,
|
|
||||||
performance-move-const-arg,
|
|
||||||
performance-inefficient-vector-operation,
|
|
||||||
performance-inefficient-string-concatenation,
|
|
||||||
performance-inefficient-algorithm,
|
|
||||||
performance-implicit-conversion-in-loop,
|
|
||||||
performance-for-range-copy,
|
|
||||||
performance-faster-string-find,
|
|
||||||
performance-enum-size,
|
|
||||||
performance-avoid-endl,
|
|
||||||
|
|
||||||
readability-avoid-const-params-in-decls,
|
|
||||||
readability-avoid-nested-conditional-operator,
|
|
||||||
readability-avoid-return-with-void-value,
|
|
||||||
readability-avoid-unconditional-preprocessor-if,
|
|
||||||
readability-braces-around-statements,
|
|
||||||
readability-const-return-type,
|
|
||||||
readability-container-contains,
|
|
||||||
readability-container-data-pointdr,
|
|
||||||
readability-container-size-empty,
|
|
||||||
readability-delete-null-pointer,
|
|
||||||
readability-duplicate-include,
|
|
||||||
readability-else-after-return,
|
|
||||||
readability-inconsistent-declaration-parameter-name,
|
|
||||||
readability-isolate-declaration,
|
|
||||||
readability-make-member-function-const,
|
|
||||||
readability-misleading-indentation,
|
|
||||||
readability-misplaced-array-index,
|
|
||||||
readability-named-parameter,
|
|
||||||
readability-non-const-parameter,
|
|
||||||
readability-qualified-auto,
|
|
||||||
readability-redundant-access-specifiers,
|
|
||||||
readability-redundant-casting,
|
|
||||||
readability-redundant-control-flow,
|
|
||||||
readability-redundant-declaration,
|
|
||||||
readability-redundant-function-ptr-dereference,
|
|
||||||
readability-redundant-inline-specifier,
|
|
||||||
readability-redundant-member-init,
|
|
||||||
readability-redundant-preprocessor,
|
|
||||||
readability-redundant-smartptr-get,
|
|
||||||
readability-redundant-string-cstr,
|
|
||||||
readability-reference-to-constructed-temporary,
|
|
||||||
readability-simplify-boolean-expr,
|
|
||||||
readability-simplify-subscript-expr,
|
|
||||||
readability-static-accessed-through-instance,
|
|
||||||
readability-static-definition-in-anonymous-namespace,
|
|
||||||
readability-string-compare,
|
|
||||||
readability-suspicious-call-argument,
|
|
||||||
readability-uniqueptr-delete-release,
|
|
||||||
readability-use-anyofallof
|
|
||||||
readability-use-std-min-max,
|
|
||||||
readability-function-cognitive-complexity
|
|
||||||
readability-function-size
|
|
||||||
readability-identifier-naming
|
|
||||||
readability-identifier-length
|
|
||||||
readability-magic-numbers
|
|
||||||
|
|
||||||
modernize-avoid-bind,
|
|
||||||
modernize-avoid-c-arrays,
|
|
||||||
modernize-concat-nested-namespaces,
|
|
||||||
modernize-deprecated-headers,
|
|
||||||
modernize-deprecated-ios-base-aliases,
|
|
||||||
modernize-loop-convert,
|
|
||||||
modernize-macro-to-enum,
|
|
||||||
modernize-make-shared,
|
|
||||||
modernize-make-unique,
|
|
||||||
modernize-pass-by-value,
|
|
||||||
modernize-raw-string-literal,
|
|
||||||
modernize-redundant-void-arg,
|
|
||||||
modernize-replace-auto-ptr,
|
|
||||||
modernize-replace-disallow-copy-and-assign-macro,
|
|
||||||
modernize-replace-random-shuffle,
|
|
||||||
modernize-return-braced-init-list,
|
|
||||||
modernize-shrink-to-fit,
|
|
||||||
modernize-type-traits,
|
|
||||||
modernize-unary-static-assert,
|
|
||||||
modernize-use-auto,
|
|
||||||
modernize-use-bool-literals,
|
|
||||||
modernize-use-constraints,
|
|
||||||
modernize-use-default-member-init,
|
|
||||||
modernize-use-designated-initializers,
|
|
||||||
modernize-use-emplace,
|
|
||||||
modernize-use-equals-default,
|
|
||||||
modernize-use-equals-delete,
|
|
||||||
modernize-use-nodiscard,
|
|
||||||
modernize-use-noexcept,
|
|
||||||
modernize-use-nullptr,
|
|
||||||
modernize-use-override,
|
|
||||||
modernize-use-starts-ends-with,
|
|
||||||
modernize-use-std-numbers,
|
|
||||||
modernize-use-std-print,
|
|
||||||
modernize-use-transparent-functors,
|
|
||||||
modernize-use-uncaught-exceptions,
|
|
||||||
modernize-use-using
|
|
||||||
modernize-min-max-use-initializer-list,
|
|
||||||
|
|
||||||
cppcoreguidelines-avoid-capturing-lambda-coroutines,
|
|
||||||
cppcoreguidelines-avoid-const-or-ref-data-members,
|
|
||||||
cppcoreguidelines-avoid-do-while,
|
|
||||||
cppcoreguidelines-avoid-goto,
|
|
||||||
cppcoreguidelines-avoid-non-const-global-variables,
|
|
||||||
cppcoreguidelines-avoid-reference-coroutine-parameters,
|
|
||||||
cppcoreguidelines-init-variables,
|
|
||||||
cppcoreguidelines-interfaces-global-init,
|
|
||||||
cppcoreguidelines-macro-usage,
|
|
||||||
cppcoreguidelines-misleading-capture-default-by-value,
|
|
||||||
cppcoreguidelines-missing-std-forward,
|
|
||||||
cppcoreguidelines-narrowing-conversions,
|
|
||||||
cppcoreguidelines-no-malloc,
|
|
||||||
cppcoreguidelines-no-suspend-with-lock,
|
|
||||||
cppcoreguidelines-owning-memory,
|
|
||||||
cppcoreguidelines-prefer-member-initializer,
|
|
||||||
cppcoreguidelines-pro-bounds-array-to-pointer-decay,
|
|
||||||
cppcoreguidelines-pro-bounds-pointer-arithmetic,
|
|
||||||
cppcoreguidelines-pro-type-const-cast,
|
|
||||||
cppcoreguidelines-pro-type-cstyle-cast,
|
|
||||||
cppcoreguidelines-pro-type-member-init,
|
|
||||||
cppcoreguidelines-pro-type-reinterpret-cast,
|
|
||||||
cppcoreguidelines-pro-type-static-cast-downcast,
|
|
||||||
cppcoreguidelines-pro-type-vararg,
|
|
||||||
cppcoreguidelines-rvalue-reference-param-not-moved,
|
|
||||||
cppcoreguidelines-slicing,
|
|
||||||
cppcoreguidelines-special-member-functions,
|
|
||||||
cppcoreguidelines-virtual-class-destructor,
|
|
||||||
|
|
||||||
bugprone-argument-comment,
|
|
||||||
bugprone-assert-side-effect,
|
|
||||||
bugprone-assignment-in-if-condition,
|
|
||||||
bugprone-bad-signal-to-kill-thread,
|
|
||||||
bugprone-bool-pointer-implicit-conversion,
|
|
||||||
bugprone-branch-clone,
|
|
||||||
bugprone-casting-through-void,
|
|
||||||
bugprone-chained-comparison,
|
|
||||||
bugprone-compare-pointer-to-member-virtual-function,
|
|
||||||
bugprone-copy-constructor-init,
|
|
||||||
bugprone-crtp-constructor-accessibility,
|
|
||||||
bugprone-dangling-handle,
|
|
||||||
bugprone-empty-catch,
|
|
||||||
bugprone-exception-escape,
|
|
||||||
bugprone-fold-init-type,
|
|
||||||
bugprone-forward-declaration-namespace,
|
|
||||||
bugprone-forwarding-reference-overload,
|
|
||||||
bugprone-implicit-widening-of-multiplication-result,
|
|
||||||
bugprone-inaccurate-erase,
|
|
||||||
bugprone-inc-dec-in-conditions,
|
|
||||||
bugprone-incorrect-enable-if,
|
|
||||||
bugprone-incorrect-roundings,
|
|
||||||
bugprone-infinite-loop,
|
|
||||||
bugprone-integer-division,
|
|
||||||
bugprone-lambda-function-name,
|
|
||||||
bugprone-macro-parentheses,
|
|
||||||
bugprone-macro-repeated-side-effects,
|
|
||||||
bugprone-misplaced-operator-in-strlen-in-alloc,
|
|
||||||
bugprone-misplaced-pointer-arithmetic-in-alloc,
|
|
||||||
bugprone-misplaced-widening-cast,
|
|
||||||
bugprone-move-forwarding-reference,
|
|
||||||
bugprone-multi-level-implicit-pointer-conversion,
|
|
||||||
bugprone-multiple-new-in-one-expression,
|
|
||||||
bugprone-multiple-statement-macro,
|
|
||||||
bugprone-no-escape,
|
|
||||||
bugprone-non-zero-enum-to-bool-conversion,
|
|
||||||
bugprone-not-null-terminated-result,
|
|
||||||
bugprone-optional-value-conversion,
|
|
||||||
bugprone-parent-virtual-call,
|
|
||||||
bugprone-posix-return,
|
|
||||||
bugprone-redundant-branch-condition,
|
|
||||||
bugprone-reserved-identifier,
|
|
||||||
bugprone-return-const-ref-from-parameter,
|
|
||||||
bugprone-shared-ptr-array-mismatch,
|
|
||||||
bugprone-signal-handler,
|
|
||||||
bugprone-signed-char-misuse,
|
|
||||||
bugprone-sizeof-container,
|
|
||||||
bugprone-sizeof-expression,
|
|
||||||
bugprone-spuriously-wake-up-functions,
|
|
||||||
bugprone-standalone-empty,
|
|
||||||
bugprone-string-constructor,
|
|
||||||
bugprone-string-integer-assignment,
|
|
||||||
bugprone-string-literal-with-embedded-nul,
|
|
||||||
bugprone-stringview-nullptr,
|
|
||||||
bugprone-suspicious-enum-usage,
|
|
||||||
bugprone-suspicious-include,
|
|
||||||
bugprone-suspicious-memory-comparison,
|
|
||||||
bugprone-suspicious-memset-usage,
|
|
||||||
bugprone-suspicious-missing-comma,
|
|
||||||
bugprone-suspicious-realloc-usage,
|
|
||||||
bugprone-suspicious-semicolon,
|
|
||||||
bugprone-suspicious-string-compare,
|
|
||||||
bugprone-suspicious-stringview-data-usage,
|
|
||||||
bugprone-swapped-arguments,
|
|
||||||
bugprone-switch-missing-default-case,
|
|
||||||
bugprone-terminating-continue,
|
|
||||||
bugprone-throw-keyword-missing,
|
|
||||||
bugprone-too-small-loop-variable,
|
|
||||||
bugprone-unchecked-optional-access,
|
|
||||||
bugprone-undefined-memory-manipulation,
|
|
||||||
bugprone-undelegated-constructor,
|
|
||||||
bugprone-unhandled-exception-at-new,
|
|
||||||
bugprone-unhandled-self-assignment,
|
|
||||||
bugprone-unique-ptr-array-mismatch,
|
|
||||||
bugprone-unsafe-functions,
|
|
||||||
bugprone-unused-local-non-trivial-variable,
|
|
||||||
bugprone-unused-raii,
|
|
||||||
bugprone-unused-return-value,
|
|
||||||
bugprone-use-after-move,
|
|
||||||
bugprone-virtual-near-miss,
|
|
||||||
|
|
||||||
concurrency-mt-unsafe,
|
|
||||||
concurrency-thread-canceltype-asynchronous,
|
|
||||||
|
|
||||||
misc-use-anonymous-namespace,
|
|
||||||
misc-unused-using-decls,
|
|
||||||
misc-unused-parameters,
|
|
||||||
misc-unused-alias-decls,
|
|
||||||
misc-uniqueptr-reset-release,
|
|
||||||
misc-unconventional-assign-operator,
|
|
||||||
misc-throw-by-value-catch-by-reference,
|
|
||||||
misc-static-assert,
|
|
||||||
misc-redundant-expression,
|
|
||||||
misc-non-private-member-variables-in-classes,
|
|
||||||
misc-non-copyable-objects,
|
|
||||||
misc-no-recursion,
|
|
||||||
misc-new-delete-overloads,
|
|
||||||
misc-misplaced-const,
|
|
||||||
misc-misleading-identifier,
|
|
||||||
misc-misleading-bidirectional,
|
|
||||||
misc-header-include-cycle,
|
|
||||||
misc-definitions-in-headers,
|
|
||||||
misc-coroutine-hostile-raii,
|
|
||||||
misc-const-correctness,
|
|
||||||
|
|
||||||
hicpp-signed-bitwise,
|
|
||||||
hicpp-no-assembler,
|
|
||||||
hicpp-multiway-paths-covered,
|
|
||||||
hicpp-ignored-remove-result,
|
|
||||||
hicpp-exception-baseclass,
|
|
||||||
"
|
|
||||||
5
.clangd
5
.clangd
|
|
@ -1,5 +0,0 @@
|
||||||
CompileFlags:
|
|
||||||
DriverMode: cl
|
|
||||||
Add:
|
|
||||||
- /EHsc
|
|
||||||
- /std:c++latest
|
|
||||||
17
.cmake-format
Normal file
17
.cmake-format
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
# How wide to allow formatted cmake files
|
||||||
|
line_width: 80
|
||||||
|
|
||||||
|
# How many spaces to tab for indent
|
||||||
|
tab_size: 4
|
||||||
|
|
||||||
|
dangle_parens: true
|
||||||
|
|
||||||
|
# Additional FLAGS and KWARGS for custom commands
|
||||||
|
additional_commands:
|
||||||
|
foo:
|
||||||
|
flags: [BAR, BAZ]
|
||||||
|
kwargs:
|
||||||
|
HEADERS : '*'
|
||||||
|
SOURCES : '*'
|
||||||
|
DEPENDS : '*'
|
||||||
|
|
||||||
|
|
@ -1,4 +1,10 @@
|
||||||
cmake_minimum_required(VERSION 3.14)
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
|
set(CMAKE_EPXORT_COMPILE_COMMANDS TRUE)
|
||||||
|
set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444")
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
|
||||||
|
set(CMAKE_CXX_MODULE_STD 1)
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 4.1)
|
||||||
project(Light)
|
project(Light)
|
||||||
|
|
||||||
include(${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake/functions.cmake)
|
include(${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake/functions.cmake)
|
||||||
|
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
# How to contribute to Light Engine
|
|
||||||
|
|
||||||
Thanks for putting in the time to contribute to this project <3
|
|
||||||
|
|
||||||
## Coding conventions
|
|
||||||
|
|
||||||
For the time being, don't worry too much about the conventions...
|
|
||||||
|
|
||||||
Try to read other parts of the code and you'll get the hang of it
|
|
||||||
|
|
||||||
I have to learn clang-format, then everyone contributing can use it to format their code
|
|
||||||
|
|
||||||
|
|
||||||
###### happy coding-
|
|
||||||
36
data/test_assets/sprite.vert
Normal file
36
data/test_assets/sprite.vert
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
#version 450 core
|
||||||
|
|
||||||
|
layout(push_constant) uniform pc
|
||||||
|
{
|
||||||
|
mat4 view_projection;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct VertexData
|
||||||
|
{
|
||||||
|
vec3 position;
|
||||||
|
vec3 color;
|
||||||
|
};
|
||||||
|
|
||||||
|
// readonly SSBO containing the vertex data
|
||||||
|
layout(set = 0, binding = 0, std430) readonly buffer vertex_data {
|
||||||
|
VertexData data[];
|
||||||
|
};
|
||||||
|
|
||||||
|
vec3 position(int idx)
|
||||||
|
{
|
||||||
|
return data[idx].position;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 color(int idx)
|
||||||
|
{
|
||||||
|
return data[idx].color;
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(location = 0) out vec3 out_frag_color;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = view_projection * vec4(position(gl_VertexIndex), 1.0);
|
||||||
|
out_frag_color = color(gl_VertexIndex);
|
||||||
|
}
|
||||||
BIN
data/test_assets/sprite.vert.asset
Normal file
BIN
data/test_assets/sprite.vert.asset
Normal file
Binary file not shown.
|
|
@ -1,7 +1,7 @@
|
||||||
#version 450 core
|
#version 450 core
|
||||||
|
|
||||||
layout(push_constant ) uniform pc {
|
layout(push_constant ) uniform pc {
|
||||||
mat4 view_projection;
|
mat4 view_projection;
|
||||||
};
|
};
|
||||||
|
|
||||||
vec3 positions[3] = vec3[](
|
vec3 positions[3] = vec3[](
|
||||||
|
|
@ -23,4 +23,3 @@ void main()
|
||||||
gl_Position = view_projection * vec4(positions[gl_VertexIndex], 1.0);
|
gl_Position = view_projection * vec4(positions[gl_VertexIndex], 1.0);
|
||||||
out_frag_color = colors[gl_VertexIndex];
|
out_frag_color = colors[gl_VertexIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
1
docs/.gitignore
vendored
1
docs/.gitignore
vendored
|
|
@ -2,4 +2,3 @@ _build/
|
||||||
generated/
|
generated/
|
||||||
html/
|
html/
|
||||||
xml/
|
xml/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ add_library_module(
|
||||||
INTERFACES
|
INTERFACES
|
||||||
test.cppm
|
test.cppm
|
||||||
expects.cppm
|
expects.cppm
|
||||||
PRIVATE_INTERFACES
|
|
||||||
registry.cppm
|
registry.cppm
|
||||||
SOURCES
|
SOURCES
|
||||||
entrypoint.cpp
|
entrypoint.cpp
|
||||||
|
|
@ -151,7 +150,9 @@ add_library_module(
|
||||||
renderer
|
renderer
|
||||||
INTERFACES
|
INTERFACES
|
||||||
data.cppm
|
data.cppm
|
||||||
|
system.cppm
|
||||||
frontends.cppm
|
frontends.cppm
|
||||||
|
components.cppm
|
||||||
factory.cppm
|
factory.cppm
|
||||||
vk/api_wrapper.cppm
|
vk/api_wrapper.cppm
|
||||||
vk/device.cppm
|
vk/device.cppm
|
||||||
|
|
@ -161,6 +162,8 @@ add_library_module(
|
||||||
vk/swapchain.cppm
|
vk/swapchain.cppm
|
||||||
vk/buffer.cppm
|
vk/buffer.cppm
|
||||||
vk/pass.cppm
|
vk/pass.cppm
|
||||||
|
vk/renderer.cppm
|
||||||
|
vk/debugger.cppm
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
app
|
app
|
||||||
ecs
|
ecs
|
||||||
|
|
@ -173,4 +176,21 @@ add_library_module(
|
||||||
surface
|
surface
|
||||||
)
|
)
|
||||||
|
|
||||||
# add_subdirectory(./mirror)
|
add_library_module(
|
||||||
|
NAME
|
||||||
|
libmirror
|
||||||
|
ROOT_DIR
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/mirror
|
||||||
|
INTERFACES
|
||||||
|
system.cppm
|
||||||
|
DEPENDENCIES
|
||||||
|
app
|
||||||
|
time
|
||||||
|
input
|
||||||
|
surface
|
||||||
|
renderer
|
||||||
|
camera
|
||||||
|
)
|
||||||
|
|
||||||
|
# add_executable_module(mirror entrypoint/mirror.cpp)
|
||||||
|
# target_link_libraries(mirror PRIVATE libmirror input)
|
||||||
|
|
|
||||||
|
|
@ -1,162 +0,0 @@
|
||||||
#include <asset_parser/assets/text.hpp>
|
|
||||||
|
|
||||||
namespace Assets {
|
|
||||||
|
|
||||||
/* static */ void TextAsset::pack(const PackageData &data, const std::filesystem::path &out_path)
|
|
||||||
{
|
|
||||||
const auto &[metadata, text_metadata, text] = data;
|
|
||||||
|
|
||||||
auto stream = std::ofstream { out_path, std::ios::binary | std::ios::trunc };
|
|
||||||
if (!stream.is_open())
|
|
||||||
{
|
|
||||||
throw std::runtime_error {
|
|
||||||
std::format("Failed to open ofstream for packing Text at: {}", out_path.string())
|
|
||||||
};
|
|
||||||
}
|
|
||||||
stream.seekp(0);
|
|
||||||
|
|
||||||
// NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast)
|
|
||||||
stream.write((char *)¤t_version, sizeof(current_version));
|
|
||||||
stream.write((char *)&metadata, sizeof(metadata));
|
|
||||||
stream.write((char *)&text_metadata, sizeof(text_metadata));
|
|
||||||
|
|
||||||
constexpr auto number_of_blobs = uint32_t { 1 };
|
|
||||||
stream.write((char *)&number_of_blobs, sizeof(number_of_blobs));
|
|
||||||
|
|
||||||
auto textblob_metadata = BlobMetadata {
|
|
||||||
.tag = BlobMetadata::Tag::text,
|
|
||||||
.offset = static_cast<size_t>(stream.tellp()) + sizeof(BlobMetadata),
|
|
||||||
.compression_type = CompressionType::None,
|
|
||||||
.compressed_size = text.size(),
|
|
||||||
.uncompressed_size = text.size(),
|
|
||||||
};
|
|
||||||
|
|
||||||
stream.write((char *)&textblob_metadata, sizeof(textblob_metadata));
|
|
||||||
stream.write((char *)text.data(), static_cast<long>(text.size()));
|
|
||||||
// NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast)
|
|
||||||
}
|
|
||||||
|
|
||||||
TextAsset::TextAsset(const std::filesystem::path &path)
|
|
||||||
{
|
|
||||||
m_stream = std::ifstream { path, std::ios::binary };
|
|
||||||
if (!m_stream.is_open())
|
|
||||||
{
|
|
||||||
throw std::runtime_error {
|
|
||||||
std::format("Failed to open ifstream for loading Text asset at: {}", path.string())
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast)
|
|
||||||
m_stream.read((char *)&version, sizeof(version));
|
|
||||||
m_stream.read((char *)&m_asset_metadata, sizeof(m_asset_metadata));
|
|
||||||
m_stream.read((char *)&m_metadata, sizeof(m_metadata));
|
|
||||||
|
|
||||||
auto num_blobs = uint32_t {};
|
|
||||||
m_stream.read((char *)&num_blobs, sizeof(num_blobs));
|
|
||||||
if (num_blobs != 1)
|
|
||||||
{
|
|
||||||
throw std::runtime_error {
|
|
||||||
std::format("Failed to load Text asset: invalid number of blobs: {}", num_blobs)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
m_stream.read((char *)&m_text_blob_metadata, sizeof(m_text_blob_metadata));
|
|
||||||
if (m_text_blob_metadata.tag != BlobMetadata::Tag::text)
|
|
||||||
{
|
|
||||||
throw std::runtime_error {
|
|
||||||
std::format(
|
|
||||||
"Failed to load Text asset: invalid blob tag, expected {}, got {}",
|
|
||||||
std::to_underlying(BlobMetadata::Tag::text),
|
|
||||||
std::to_underlying(m_text_blob_metadata.tag)
|
|
||||||
),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast)
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextAsset::unpack_blob(
|
|
||||||
BlobMetadata::Tag tag,
|
|
||||||
std::byte *destination,
|
|
||||||
size_t destination_capacity
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
if (tag != BlobMetadata::Tag::text)
|
|
||||||
{
|
|
||||||
throw std::runtime_error {
|
|
||||||
std::format("Invalid tag for unpack_blob of TextAsset: {}", std::to_underlying(tag))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
m_stream.seekg(static_cast<long>(m_text_blob_metadata.offset));
|
|
||||||
switch (m_text_blob_metadata.compression_type)
|
|
||||||
{
|
|
||||||
case Assets::CompressionType::None:
|
|
||||||
if (m_text_blob_metadata.uncompressed_size != m_text_blob_metadata.compressed_size)
|
|
||||||
{
|
|
||||||
throw std::runtime_error(
|
|
||||||
"Failed to unpack blob from TextAsset: "
|
|
||||||
"compressed/uncompressed size mismatch for no compression "
|
|
||||||
"type"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_text_blob_metadata.uncompressed_size > destination_capacity)
|
|
||||||
{
|
|
||||||
throw std::runtime_error(
|
|
||||||
"Failed to unpack blob from TextAsset: "
|
|
||||||
"uncompressed_size > destination_capacity, unpacking "
|
|
||||||
"would result in segfault"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_stream.is_open())
|
|
||||||
{
|
|
||||||
throw std::runtime_error(
|
|
||||||
"Failed to unpack blob from TextAsset: ifstream is "
|
|
||||||
"closed"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_stream.read(
|
|
||||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
|
|
||||||
(char *)destination,
|
|
||||||
static_cast<long>(m_text_blob_metadata.uncompressed_size)
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw std::runtime_error(
|
|
||||||
std::format(
|
|
||||||
"Failed to unpack blob from TextAsset: unsupported "
|
|
||||||
"compression type: {}",
|
|
||||||
std::to_underlying(m_text_blob_metadata.compression_type)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto TextAsset::get_asset_metadata() const -> const Asset::Metadata &
|
|
||||||
{
|
|
||||||
return m_asset_metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto TextAsset::get_metadata() const -> const Metadata &
|
|
||||||
{
|
|
||||||
return m_metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto TextAsset::get_blob_metadata(BlobMetadata::Tag tag) const -> const BlobMetadata &
|
|
||||||
{
|
|
||||||
if (tag != BlobMetadata::Tag::text)
|
|
||||||
{
|
|
||||||
throw std::runtime_error { std::format(
|
|
||||||
"Invalid tag for get_blob_metadata of TextAsset: {}",
|
|
||||||
std::to_underlying(tag)
|
|
||||||
) };
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_text_blob_metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Assets
|
|
||||||
|
|
@ -12,7 +12,7 @@ import std;
|
||||||
|
|
||||||
namespace lt::input {
|
namespace lt::input {
|
||||||
|
|
||||||
class System: public app::ISystem
|
export class System: public app::ISystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
System(memory::Ref<ecs::Registry> registry);
|
System(memory::Ref<ecs::Registry> registry);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ export module math.algebra;
|
||||||
import math.mat4;
|
import math.mat4;
|
||||||
import std;
|
import std;
|
||||||
|
|
||||||
namespace lt::math {
|
export namespace lt::math {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* let...
|
* let...
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
export module math.trig;
|
export module math.trig;
|
||||||
|
|
||||||
namespace lt::math {
|
export namespace lt::math {
|
||||||
|
|
||||||
[[nodiscard]] constexpr auto radians(float degrees) -> float
|
[[nodiscard]] constexpr auto radians(float degrees) -> float
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ namespace lt::memory {
|
||||||
/** Holds an `Underlying_T`, assigns it to `null_value` when this object is moved.
|
/** Holds an `Underlying_T`, assigns it to `null_value` when this object is moved.
|
||||||
*
|
*
|
||||||
* @note For avoiding the need to explicitly implement the move constructor for objects that hold
|
* @note For avoiding the need to explicitly implement the move constructor for objects that hold
|
||||||
* Vulkan objects. But may serve other purposes, hence why I kept the implementation generic.
|
* Vulkan handles. But may serve other purposes, hence why I kept the implementation generic.
|
||||||
*/
|
*/
|
||||||
export template<typename Underlying_T, Underlying_T null_value = nullptr>
|
export template<typename Underlying_T, Underlying_T null_value = nullptr>
|
||||||
class NullOnMove
|
class NullOnMove
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,35 @@
|
||||||
#include <X11/keysym.h>
|
export module mirror.system;
|
||||||
#include <app/application.hpp>
|
import math.vec3;
|
||||||
#include <app/entrypoint.hpp>
|
import camera.components;
|
||||||
#include <app/system.hpp>
|
import surface.requests;
|
||||||
#include <camera/components.hpp>
|
import logger;
|
||||||
#include <ecs/entity.hpp>
|
import surface.system;
|
||||||
#include <input/components.hpp>
|
import math.vec2;
|
||||||
#include <input/system.hpp>
|
import math.vec4;
|
||||||
#include <math/components/transform.hpp>
|
import math.trig;
|
||||||
#include <math/trig.hpp>
|
import input.codes;
|
||||||
#include <math/vec2.hpp>
|
import input.events;
|
||||||
#include <memory/reference.hpp>
|
import input.system;
|
||||||
#include <memory/scope.hpp>
|
import math.components;
|
||||||
#include <renderer/components/messenger.hpp>
|
import memory.reference;
|
||||||
#include <renderer/components/sprite.hpp>
|
import memory.scope;
|
||||||
#include <renderer/system.hpp>
|
import renderer.components;
|
||||||
#include <surface/events/keyboard.hpp>
|
import renderer.system;
|
||||||
#include <surface/events/surface.hpp>
|
import renderer.frontend;
|
||||||
#include <surface/system.hpp>
|
import surface.events;
|
||||||
#include <time/timer.hpp>
|
import time;
|
||||||
|
import app;
|
||||||
|
import app.system;
|
||||||
|
import ecs.entity;
|
||||||
|
import ecs.registry;
|
||||||
|
import std;
|
||||||
|
|
||||||
namespace lt {
|
namespace lt {
|
||||||
|
|
||||||
void renderer_callback(
|
void renderer_callback(
|
||||||
renderer::IMessenger::MessageSeverity message_severity,
|
renderer::IDebugger::MessageSeverity message_severity,
|
||||||
renderer::IMessenger::MessageType message_type,
|
renderer::IDebugger::MessageType message_type,
|
||||||
renderer::IMessenger::MessageData data,
|
renderer::IDebugger::MessageData data,
|
||||||
std::any &user_data
|
std::any &user_data
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
@ -40,8 +45,8 @@ class MirrorSystem: public lt::app::ISystem
|
||||||
public:
|
public:
|
||||||
MirrorSystem(
|
MirrorSystem(
|
||||||
memory::Ref<ecs::Registry> registry,
|
memory::Ref<ecs::Registry> registry,
|
||||||
lt::input::InputAction::Key quit_action_key,
|
std::size_t quit_action_key,
|
||||||
std::array<lt::input::InputAction::Key, 4> debug_action_keys
|
std::array<std::size_t, 4ul> debug_action_keys
|
||||||
)
|
)
|
||||||
: m_registry(std::move(registry))
|
: m_registry(std::move(registry))
|
||||||
, m_quit_action_key(quit_action_key)
|
, m_quit_action_key(quit_action_key)
|
||||||
|
|
@ -70,7 +75,6 @@ public:
|
||||||
const auto &[x, y] = surface.get_position();
|
const auto &[x, y] = surface.get_position();
|
||||||
const auto &[width, height] = surface.get_resolution();
|
const auto &[width, height] = surface.get_resolution();
|
||||||
|
|
||||||
|
|
||||||
if (input.get_action(m_quit_action_key).state == State::active)
|
if (input.get_action(m_quit_action_key).state == State::active)
|
||||||
{
|
{
|
||||||
should_quit = true;
|
should_quit = true;
|
||||||
|
|
@ -124,10 +128,9 @@ public:
|
||||||
private:
|
private:
|
||||||
memory::Ref<ecs::Registry> m_registry;
|
memory::Ref<ecs::Registry> m_registry;
|
||||||
|
|
||||||
|
std::size_t m_quit_action_key;
|
||||||
|
|
||||||
lt::input::InputAction::Key m_quit_action_key;
|
std::array<std::size_t, 4ul> m_debug_action_keys {};
|
||||||
|
|
||||||
std::array<lt::input::InputAction::Key, 4> m_debug_action_keys {};
|
|
||||||
|
|
||||||
app::TickResult m_last_tick_result {};
|
app::TickResult m_last_tick_result {};
|
||||||
};
|
};
|
||||||
|
|
@ -176,36 +179,36 @@ public:
|
||||||
auto quit_action_key = input.add_action(
|
auto quit_action_key = input.add_action(
|
||||||
input::InputAction {
|
input::InputAction {
|
||||||
.name = "quit",
|
.name = "quit",
|
||||||
.trigger = input::Trigger { .mapped_keycode = XK_q },
|
.trigger = input::Trigger { .mapped_keycode = Key::Q },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
auto debug_action_keys = std::array<lt::input::InputAction::Key, 4> {};
|
auto debug_action_keys = std::array<std::size_t, 4ul> {};
|
||||||
debug_action_keys[0] = input.add_action(
|
debug_action_keys[0] = input.add_action(
|
||||||
input::InputAction {
|
input::InputAction {
|
||||||
.name = "debug_1",
|
.name = "debug_1",
|
||||||
.trigger = input::Trigger { .mapped_keycode = XK_1 },
|
.trigger = input::Trigger { .mapped_keycode = Key::D1 },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
debug_action_keys[1] = input.add_action(
|
debug_action_keys[1] = input.add_action(
|
||||||
input::InputAction {
|
input::InputAction {
|
||||||
.name = "debug_2",
|
.name = "debug_2",
|
||||||
.trigger = input::Trigger { .mapped_keycode = XK_2 },
|
.trigger = input::Trigger { .mapped_keycode = Key::D2 },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
debug_action_keys[2] = input.add_action(
|
debug_action_keys[2] = input.add_action(
|
||||||
input::InputAction {
|
input::InputAction {
|
||||||
.name = "debug_3",
|
.name = "debug_3",
|
||||||
.trigger = input::Trigger { .mapped_keycode = XK_3 },
|
.trigger = input::Trigger { .mapped_keycode = Key::D3 },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
debug_action_keys[3] = input.add_action(
|
debug_action_keys[3] = input.add_action(
|
||||||
input::InputAction {
|
input::InputAction {
|
||||||
.name = "debug_4",
|
.name = "debug_4",
|
||||||
.trigger = input::Trigger { .mapped_keycode = XK_4 },
|
.trigger = input::Trigger { .mapped_keycode = Key::D4 },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -222,9 +225,9 @@ public:
|
||||||
.config = { .target_api = renderer::Api::vulkan, .max_frames_in_flight = 3u },
|
.config = { .target_api = renderer::Api::vulkan, .max_frames_in_flight = 3u },
|
||||||
.registry = m_editor_registry,
|
.registry = m_editor_registry,
|
||||||
.surface_entity = entity,
|
.surface_entity = entity,
|
||||||
.debug_callback_info = renderer::IMessenger::CreateInfo {
|
.debug_callback_info = renderer::IDebugger::CreateInfo {
|
||||||
.severities = renderer::IMessenger::MessageSeverity::all,
|
.severities = renderer::IDebugger::MessageSeverity::all,
|
||||||
.types = renderer::IMessenger::MessageType::all,
|
.types = renderer::IDebugger::MessageType::all,
|
||||||
.callback = &renderer_callback,
|
.callback = &renderer_callback,
|
||||||
.user_data = this,
|
.user_data = this,
|
||||||
} });
|
} });
|
||||||
|
|
@ -233,7 +236,9 @@ public:
|
||||||
|
|
||||||
m_editor_registry->add(
|
m_editor_registry->add(
|
||||||
m_sprite_id,
|
m_sprite_id,
|
||||||
renderer::components::Sprite { .color = lt::math::vec3 { 1.0f, 0.0f, 0.0f } }
|
renderer::components::Sprite {
|
||||||
|
.color = lt::math::vec3 { 1.0f, 0.0f, 0.0f },
|
||||||
|
}
|
||||||
);
|
);
|
||||||
m_editor_registry->add(
|
m_editor_registry->add(
|
||||||
m_sprite_id,
|
m_sprite_id,
|
||||||
|
|
@ -4,21 +4,23 @@ import math.vec3;
|
||||||
import memory.reference;
|
import memory.reference;
|
||||||
import std;
|
import std;
|
||||||
|
|
||||||
namespace lt::renderer::components {
|
export namespace lt::renderer::components {
|
||||||
|
|
||||||
export enum class VertexFormat: std::uint8_t {
|
enum class VertexFormat : std::uint8_t
|
||||||
|
{
|
||||||
r32_g32_b32_sfloat,
|
r32_g32_b32_sfloat,
|
||||||
|
|
||||||
r32_g32_sfloat,
|
r32_g32_sfloat,
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum class VertexInputRate: std::uint8_t {
|
enum class VertexInputRate : std::uint8_t
|
||||||
|
{
|
||||||
per_vertex,
|
per_vertex,
|
||||||
|
|
||||||
per_instance,
|
per_instance,
|
||||||
};
|
};
|
||||||
|
|
||||||
export struct VertexInputAttributeDescriptipn
|
struct VertexInputAttributeDescriptipn
|
||||||
{
|
{
|
||||||
std::uint32_t location;
|
std::uint32_t location;
|
||||||
|
|
||||||
|
|
@ -29,7 +31,7 @@ export struct VertexInputAttributeDescriptipn
|
||||||
VertexFormat format;
|
VertexFormat format;
|
||||||
};
|
};
|
||||||
|
|
||||||
export struct VertexInputBindingDescription
|
struct VertexInputBindingDescription
|
||||||
{
|
{
|
||||||
std::uint32_t binding;
|
std::uint32_t binding;
|
||||||
|
|
||||||
|
|
@ -37,7 +39,7 @@ export struct VertexInputBindingDescription
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Requires a math::components::Transform component on the same entity to be functional. */
|
/** Requires a math::components::Transform component on the same entity to be functional. */
|
||||||
export struct Sprite
|
struct Sprite
|
||||||
{
|
{
|
||||||
struct Vertex
|
struct Vertex
|
||||||
{
|
{
|
||||||
|
|
@ -52,7 +54,7 @@ export struct Sprite
|
||||||
VertexInputAttributeDescriptipn {
|
VertexInputAttributeDescriptipn {
|
||||||
.location = 0u,
|
.location = 0u,
|
||||||
.binding = 0u,
|
.binding = 0u,
|
||||||
.offset = offsetof(Sprite::Vertex, position),
|
.offset = 0u,
|
||||||
.format = VertexFormat::r32_g32_b32_sfloat,
|
.format = VertexFormat::r32_g32_b32_sfloat,
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
@ -60,7 +62,7 @@ export struct Sprite
|
||||||
VertexInputAttributeDescriptipn {
|
VertexInputAttributeDescriptipn {
|
||||||
.location = 1u,
|
.location = 1u,
|
||||||
.binding = 0u,
|
.binding = 0u,
|
||||||
.offset = offsetof(Sprite::Vertex, color),
|
.offset = sizeof(math::vec3),
|
||||||
.format = VertexFormat::r32_g32_b32_sfloat,
|
.format = VertexFormat::r32_g32_b32_sfloat,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
export module renderer.factory;
|
export module renderer.factory;
|
||||||
import renderer.frontend;
|
import renderer.frontend;
|
||||||
import assets.shader;
|
import assets.shader;
|
||||||
import renderer.backend.vk.device;
|
import renderer.vk.device;
|
||||||
import renderer.vk.pass;
|
import renderer.vk.pass;
|
||||||
import renderer.backend.vk.instance;
|
import renderer.vk.instance;
|
||||||
import renderer.backend.vk.swapchain;
|
import renderer.vk.swapchain;
|
||||||
import renderer.backend.vk.buffer;
|
import renderer.vk.renderer;
|
||||||
import renderer.backend.vk.gpu;
|
import renderer.vk.buffer;
|
||||||
import renderer.backend.vk.surface;
|
import renderer.vk.gpu;
|
||||||
|
import renderer.vk.debugger;
|
||||||
|
import renderer.vk.surface;
|
||||||
import memory.scope;
|
import memory.scope;
|
||||||
import debug.assertions;
|
import debug.assertions;
|
||||||
import ecs.entity;
|
import ecs.entity;
|
||||||
|
|
@ -17,14 +19,20 @@ export namespace lt::renderer {
|
||||||
|
|
||||||
[[nodiscard]] auto get_instance(Api target_api) -> IInstance *;
|
[[nodiscard]] auto get_instance(Api target_api) -> IInstance *;
|
||||||
|
|
||||||
|
[[nodiscard]] auto create_debugger(Api target_api, IInstance *instance, IDebugger::CreateInfo info)
|
||||||
|
-> memory::Scope<IDebugger>;
|
||||||
|
|
||||||
[[nodiscard]] auto create_surface(
|
[[nodiscard]] auto create_surface(
|
||||||
Api target_api,
|
Api target_api,
|
||||||
IInstance *instance,
|
IInstance *instance,
|
||||||
const ecs::Entity &surface_entity
|
const ecs::Entity &surface_entity
|
||||||
);
|
) -> memory::Scope<ISurface>;
|
||||||
|
|
||||||
[[nodiscard]] auto create_gpu(Api target_api, IInstance *instance) -> memory::Scope<IGpu>;
|
[[nodiscard]] auto create_gpu(Api target_api, IInstance *instance) -> memory::Scope<IGpu>;
|
||||||
|
|
||||||
|
[[nodiscard]] auto create_device(Api target_api, IGpu *gpu, ISurface *surface)
|
||||||
|
-> memory::Scope<IDevice>;
|
||||||
|
|
||||||
[[nodiscard]] auto create_swapchain(Api target_api, ISurface *surface, IGpu *gpu, IDevice *device)
|
[[nodiscard]] auto create_swapchain(Api target_api, ISurface *surface, IGpu *gpu, IDevice *device)
|
||||||
-> memory::Scope<ISwapchain>;
|
-> memory::Scope<ISwapchain>;
|
||||||
|
|
||||||
|
|
@ -35,6 +43,14 @@ export namespace lt::renderer {
|
||||||
const lt::assets::ShaderAsset &fragment_shader
|
const lt::assets::ShaderAsset &fragment_shader
|
||||||
) -> memory::Scope<IPass>;
|
) -> memory::Scope<IPass>;
|
||||||
|
|
||||||
|
[[nodiscard]] auto create_renderer(
|
||||||
|
Api target_api,
|
||||||
|
IGpu *gpu,
|
||||||
|
IDevice *device,
|
||||||
|
ISwapchain *swapchain,
|
||||||
|
std::uint32_t max_frames_in_flight
|
||||||
|
) -> memory::Scope<IRenderer>;
|
||||||
|
|
||||||
} // namespace lt::renderer
|
} // namespace lt::renderer
|
||||||
|
|
||||||
module :private;
|
module :private;
|
||||||
|
|
@ -147,59 +163,61 @@ using namespace lt::renderer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// [[nodiscard]] /* static */ auto IRenderer::create(
|
[[nodiscard]] auto create_renderer(
|
||||||
// Api target_api,
|
Api target_api,
|
||||||
// IGpu *gpu,
|
IGpu *gpu,
|
||||||
// IDevice *device,
|
IDevice *device,
|
||||||
// ISwapchain *swapchain,
|
ISwapchain *swapchain,
|
||||||
// uint32_t max_frames_in_flight
|
std::uint32_t max_frames_in_flight
|
||||||
// ) -> memory::Scope<IRenderer>
|
) -> memory::Scope<IRenderer>
|
||||||
// {
|
{
|
||||||
// ensure(gpu, "Failed to create renderer::IRenderer: null gpu");
|
debug::ensure(gpu, "Failed to create renderer::IRenderer: null gpu");
|
||||||
// ensure(device, "Failed to create renderer::IRenderer: null device");
|
debug::ensure(device, "Failed to create renderer::IRenderer: null device");
|
||||||
// ensure(swapchain, "Failed to create renderer::IRenderer: null swapchain");
|
debug::ensure(swapchain, "Failed to create renderer::IRenderer: null swapchain");
|
||||||
// ensure(
|
debug::ensure(
|
||||||
// std::clamp(max_frames_in_flight, frames_in_flight_lower_limit, frames_in_flight_upper_limit)
|
std::clamp(
|
||||||
// == max_frames_in_flight,
|
max_frames_in_flight,
|
||||||
// "Failed to initialize renderer::System: max_frames_in_flight ({}) not within bounds ({} -> "
|
IRenderer::frames_in_flight_lower_limit,
|
||||||
// "{}) ",
|
IRenderer::frames_in_flight_upper_limit
|
||||||
// max_frames_in_flight,
|
) == max_frames_in_flight,
|
||||||
// frames_in_flight_lower_limit,
|
"Failed to initialize renderer::System: max_frames_in_flight ({}) not within bounds ({} -> "
|
||||||
// frames_in_flight_upper_limit
|
"{}) ",
|
||||||
// );
|
max_frames_in_flight,
|
||||||
//
|
IRenderer::frames_in_flight_lower_limit,
|
||||||
//
|
IRenderer::frames_in_flight_upper_limit
|
||||||
// switch (target_api)
|
);
|
||||||
// {
|
|
||||||
// case Api::vulkan:
|
|
||||||
// return memory::create_scope<vk::Renderer>(gpu, device, swapchain, max_frames_in_flight);
|
|
||||||
// case Api::none:
|
|
||||||
// case Api::metal:
|
|
||||||
// case Api::direct_x: throw std::runtime_error { "Invalid API" };
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// [[nodiscard]] /* static */ auto IDebugger::create(
|
switch (target_api)
|
||||||
// Api target_api,
|
{
|
||||||
// IInstance *instance,
|
case Api::vulkan:
|
||||||
// CreateInfo info
|
return memory::create_scope<vkb::Renderer>(gpu, device, swapchain, max_frames_in_flight);
|
||||||
// ) -> memory::Scope<IDebugger>
|
case Api::none:
|
||||||
// {
|
case Api::metal:
|
||||||
// debug::ensure(
|
case Api::direct_x: throw std::runtime_error { "Invalid API" };
|
||||||
// info.severities != MessageSeverity::none,
|
}
|
||||||
// "Failed to create vk::Messenger: severities == none"
|
}
|
||||||
// );
|
|
||||||
//
|
[[nodiscard]] auto create_debugger(Api target_api, IInstance *instance, IDebugger::CreateInfo info)
|
||||||
// debug::ensure(info.types != MessageType::none, "Failed to create vk::Messenger: types == none");
|
-> memory::Scope<IDebugger>
|
||||||
//
|
{
|
||||||
// debug::ensure(info.callback, "Failed to create vk::Messenger: null callback");
|
debug::ensure(
|
||||||
//
|
info.severities != IDebugger::MessageSeverity::none,
|
||||||
// switch (target_api)
|
"Failed to create renderer::IDebugger: severities == none"
|
||||||
// {
|
);
|
||||||
// case Api::vulkan: return memory::create_scope<vk::Messenger>(instance, std::move(info));
|
|
||||||
// case Api::none:
|
debug::ensure(
|
||||||
// case Api::metal:
|
info.types != IDebugger::MessageType::none,
|
||||||
// case Api::direct_x: throw std::runtime_error { "Invalid API" };
|
"Failed to create renderer::IDebugger: types == none"
|
||||||
// }
|
);
|
||||||
// }
|
|
||||||
|
debug::ensure(info.callback, "Failed to create vk::Messenger: null callback");
|
||||||
|
|
||||||
|
switch (target_api)
|
||||||
|
{
|
||||||
|
case Api::vulkan: return memory::create_scope<vkb::Debugger>(instance, std::move(info));
|
||||||
|
case Api::none:
|
||||||
|
case Api::metal:
|
||||||
|
case Api::direct_x: throw std::runtime_error { "Invalid API" };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
export module renderer.frontend;
|
export module renderer.frontend;
|
||||||
|
import renderer.data;
|
||||||
|
import renderer.components;
|
||||||
|
import bitwise;
|
||||||
|
import math.components;
|
||||||
import assets.shader;
|
import assets.shader;
|
||||||
import ecs.entity;
|
import ecs.entity;
|
||||||
import math.vec2;
|
import math.vec2;
|
||||||
|
|
@ -19,18 +23,9 @@ enum class Api : std::uint8_t
|
||||||
class IInstance
|
class IInstance
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// [[nodiscard]] static auto get(Api target_api) -> IInstance *;
|
|
||||||
IInstance() = default;
|
IInstance() = default;
|
||||||
|
|
||||||
virtual ~IInstance() = default;
|
virtual ~IInstance() = default;
|
||||||
|
|
||||||
IInstance(IInstance &&) = default;
|
|
||||||
|
|
||||||
IInstance(const IInstance &) = delete;
|
|
||||||
|
|
||||||
auto operator=(IInstance &&) -> IInstance & = default;
|
|
||||||
|
|
||||||
auto operator=(const IInstance &) -> IInstance & = delete;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class IGpu
|
class IGpu
|
||||||
|
|
@ -39,14 +34,6 @@ public:
|
||||||
IGpu() = default;
|
IGpu() = default;
|
||||||
|
|
||||||
virtual ~IGpu() = default;
|
virtual ~IGpu() = default;
|
||||||
|
|
||||||
IGpu(IGpu &&) = default;
|
|
||||||
|
|
||||||
IGpu(const IGpu &) = delete;
|
|
||||||
|
|
||||||
auto operator=(IGpu &&) -> IGpu & = default;
|
|
||||||
|
|
||||||
auto operator=(const IGpu &) -> IGpu & = delete;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class IDevice
|
class IDevice
|
||||||
|
|
@ -55,14 +42,6 @@ public:
|
||||||
IDevice() = default;
|
IDevice() = default;
|
||||||
|
|
||||||
virtual ~IDevice() = default;
|
virtual ~IDevice() = default;
|
||||||
|
|
||||||
IDevice(IDevice &&) = default;
|
|
||||||
|
|
||||||
IDevice(const IDevice &) = delete;
|
|
||||||
|
|
||||||
auto operator=(IDevice &&) -> IDevice & = default;
|
|
||||||
|
|
||||||
auto operator=(const IDevice &) -> IDevice & = delete;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ISurface
|
class ISurface
|
||||||
|
|
@ -72,14 +51,6 @@ public:
|
||||||
|
|
||||||
virtual ~ISurface() = default;
|
virtual ~ISurface() = default;
|
||||||
|
|
||||||
ISurface(ISurface &&) = default;
|
|
||||||
|
|
||||||
ISurface(const ISurface &) = delete;
|
|
||||||
|
|
||||||
auto operator=(ISurface &&) -> ISurface & = default;
|
|
||||||
|
|
||||||
auto operator=(const ISurface &) -> ISurface & = delete;
|
|
||||||
|
|
||||||
[[nodiscard]] virtual auto get_framebuffer_size() const -> math::uvec2 = 0;
|
[[nodiscard]] virtual auto get_framebuffer_size() const -> math::uvec2 = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -89,14 +60,6 @@ public:
|
||||||
ISwapchain() = default;
|
ISwapchain() = default;
|
||||||
|
|
||||||
virtual ~ISwapchain() = default;
|
virtual ~ISwapchain() = default;
|
||||||
|
|
||||||
ISwapchain(ISwapchain &&) = default;
|
|
||||||
|
|
||||||
ISwapchain(const ISwapchain &) = delete;
|
|
||||||
|
|
||||||
auto operator=(ISwapchain &&) -> ISwapchain & = default;
|
|
||||||
|
|
||||||
auto operator=(const ISwapchain &) -> ISwapchain & = delete;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class IBuffer
|
class IBuffer
|
||||||
|
|
@ -129,25 +92,10 @@ public:
|
||||||
std::size_t size;
|
std::size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] static auto create(
|
|
||||||
Api target_api,
|
|
||||||
class IDevice *device,
|
|
||||||
class IGpu *gpu,
|
|
||||||
const CreateInfo &info
|
|
||||||
) -> memory::Scope<IBuffer>;
|
|
||||||
|
|
||||||
IBuffer() = default;
|
IBuffer() = default;
|
||||||
|
|
||||||
virtual ~IBuffer() = default;
|
virtual ~IBuffer() = default;
|
||||||
|
|
||||||
IBuffer(IBuffer &&) = default;
|
|
||||||
|
|
||||||
IBuffer(const IBuffer &) = delete;
|
|
||||||
|
|
||||||
auto operator=(IBuffer &&) -> IBuffer & = default;
|
|
||||||
|
|
||||||
auto operator=(const IBuffer &) -> IBuffer & = delete;
|
|
||||||
|
|
||||||
[[nodiscard]] virtual auto map() -> std::span<std::byte> = 0;
|
[[nodiscard]] virtual auto map() -> std::span<std::byte> = 0;
|
||||||
|
|
||||||
virtual void unmap() = 0;
|
virtual void unmap() = 0;
|
||||||
|
|
@ -160,135 +108,92 @@ private:
|
||||||
class IPass
|
class IPass
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] static auto create(
|
|
||||||
lt::renderer::Api target_api,
|
|
||||||
class IDevice *device,
|
|
||||||
const class lt::assets::ShaderAsset &vertex_shader,
|
|
||||||
const class lt::assets::ShaderAsset &fragment_shader
|
|
||||||
) -> memory::Scope<IPass>;
|
|
||||||
|
|
||||||
IPass() = default;
|
IPass() = default;
|
||||||
|
|
||||||
virtual ~IPass() = default;
|
virtual ~IPass() = default;
|
||||||
|
|
||||||
IPass(IPass &&) = default;
|
|
||||||
|
|
||||||
IPass(const IPass &) = delete;
|
|
||||||
|
|
||||||
auto operator=(IPass &&) -> IPass & = default;
|
|
||||||
|
|
||||||
auto operator=(const IPass &) -> IPass & = delete;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// class IRenderer
|
class IRenderer
|
||||||
// {
|
{
|
||||||
// public:
|
public:
|
||||||
// static constexpr auto frames_in_flight_upper_limit = 5u;
|
static constexpr auto frames_in_flight_upper_limit = 5u;
|
||||||
//
|
|
||||||
// static constexpr auto frames_in_flight_lower_limit = 1u;
|
|
||||||
//
|
|
||||||
// enum class Result : uint8_t
|
|
||||||
// {
|
|
||||||
// success = 0,
|
|
||||||
// invalid_swapchain,
|
|
||||||
// error,
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// [[nodiscard]] static auto create(
|
|
||||||
// Api target_api,
|
|
||||||
// class IGpu *gpu,
|
|
||||||
// class IDevice *device,
|
|
||||||
// class ISwapchain *swapchain,
|
|
||||||
// uint32_t max_frames_in_flight
|
|
||||||
// ) -> memory::Scope<IRenderer>;
|
|
||||||
//
|
|
||||||
// IRenderer() = default;
|
|
||||||
//
|
|
||||||
// virtual ~IRenderer() = default;
|
|
||||||
//
|
|
||||||
// IRenderer(IRenderer &&) = default;
|
|
||||||
//
|
|
||||||
// IRenderer(const IRenderer &) = delete;
|
|
||||||
//
|
|
||||||
// auto operator=(IRenderer &&) -> IRenderer & = default;
|
|
||||||
//
|
|
||||||
// auto operator=(const IRenderer &) -> IRenderer & = delete;
|
|
||||||
//
|
|
||||||
// virtual auto frame(uint32_t frame_idx, std::function<void()> submit_scene) -> Result = 0;
|
|
||||||
//
|
|
||||||
// virtual void replace_swapchain(class ISwapchain *swapchain) = 0;
|
|
||||||
//
|
|
||||||
// virtual void set_frame_constants(FrameConstants constants) = 0;
|
|
||||||
//
|
|
||||||
// virtual void submit_sprite(
|
|
||||||
// const components::Sprite &sprite,
|
|
||||||
// const math::components::Transform &transform
|
|
||||||
// ) = 0;
|
|
||||||
// };
|
|
||||||
|
|
||||||
|
static constexpr auto frames_in_flight_lower_limit = 1u;
|
||||||
|
|
||||||
// class IDebugger
|
enum class Result : std::uint8_t
|
||||||
// {
|
{
|
||||||
// public:
|
success = 0,
|
||||||
// enum class MessageSeverity : std::uint8_t
|
invalid_swapchain,
|
||||||
// {
|
error,
|
||||||
// none = 0u,
|
};
|
||||||
//
|
|
||||||
// verbose = bitwise::bit(0u),
|
IRenderer() = default;
|
||||||
// info = bitwise::bit(1u),
|
|
||||||
// warning = bitwise::bit(2u),
|
virtual ~IRenderer() = default;
|
||||||
// error = bitwise::bit(3u),
|
|
||||||
//
|
virtual auto frame(std::uint32_t frame_idx, std::function<void()> submit_scene) -> Result = 0;
|
||||||
// all = verbose | info | warning | error,
|
|
||||||
// };
|
virtual void replace_swapchain(class ISwapchain *swapchain) = 0;
|
||||||
//
|
|
||||||
// enum class MessageType : std::uint8_t
|
virtual void set_frame_constants(FrameConstants constants) = 0;
|
||||||
// {
|
|
||||||
// none = 0u,
|
virtual void submit_sprite(
|
||||||
// general = bitwise::bit(0u),
|
const components::Sprite &sprite,
|
||||||
// validation = bitwise::bit(1u),
|
const math::components::Transform &transform
|
||||||
// performance = bitwise::bit(2u),
|
) = 0;
|
||||||
//
|
};
|
||||||
// all = general | validation | performance,
|
|
||||||
// };
|
class IDebugger
|
||||||
//
|
{
|
||||||
// struct MessageData
|
public:
|
||||||
// {
|
enum class MessageSeverity : std::uint8_t
|
||||||
// std::string message;
|
{
|
||||||
// };
|
none = 0u,
|
||||||
//
|
|
||||||
// using Callback_T = std::function<void(
|
verbose = bitwise::bit(0u),
|
||||||
// MessageSeverity message_severity,
|
info = bitwise::bit(1u),
|
||||||
// MessageType message_type,
|
warning = bitwise::bit(2u),
|
||||||
// const MessageData &data,
|
error = bitwise::bit(3u),
|
||||||
// std::any &user_data
|
|
||||||
// )>;
|
all = verbose | info | warning | error,
|
||||||
//
|
};
|
||||||
// struct CreateInfo
|
|
||||||
// {
|
enum class MessageType : std::uint8_t
|
||||||
// MessageSeverity severities;
|
{
|
||||||
//
|
none = 0u,
|
||||||
// MessageType types;
|
general = bitwise::bit(0u),
|
||||||
//
|
validation = bitwise::bit(1u),
|
||||||
// Callback_T callback;
|
performance = bitwise::bit(2u),
|
||||||
//
|
|
||||||
// std::any user_data;
|
all = general | validation | performance,
|
||||||
// };
|
};
|
||||||
//
|
|
||||||
// [[nodiscard]] static auto create(Api target_api, class IInstance *instance, CreateInfo info)
|
struct MessageData
|
||||||
// -> memory::Scope<IDebugger>;
|
{
|
||||||
//
|
std::string message;
|
||||||
// IDebugger() = default;
|
};
|
||||||
//
|
|
||||||
// virtual ~IDebugger() = default;
|
using Callback_T = std::function<void(
|
||||||
//
|
MessageSeverity message_severity,
|
||||||
// IDebugger(IDebugger &&) = default;
|
MessageType message_type,
|
||||||
//
|
const MessageData &data,
|
||||||
// IDebugger(const IDebugger &) = delete;
|
std::any &user_data
|
||||||
//
|
)>;
|
||||||
// auto operator=(IDebugger &&) -> IDebugger & = default;
|
|
||||||
//
|
struct CreateInfo
|
||||||
// auto operator=(const IDebugger &) -> IDebugger & = delete;
|
{
|
||||||
// };
|
MessageSeverity severities;
|
||||||
|
|
||||||
|
MessageType types;
|
||||||
|
|
||||||
|
Callback_T callback;
|
||||||
|
|
||||||
|
std::any user_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
IDebugger() = default;
|
||||||
|
|
||||||
|
virtual ~IDebugger() = default;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace lt::renderer
|
} // namespace lt::renderer
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,22 @@
|
||||||
#pragma once
|
export module renderer.system;
|
||||||
|
import logger;
|
||||||
#include <app/system.hpp>
|
import debug.assertions;
|
||||||
#include <ecs/entity.hpp>
|
import math.mat4;
|
||||||
#include <ecs/registry.hpp>
|
import renderer.factory;
|
||||||
#include <memory/reference.hpp>
|
import app.system;
|
||||||
#include <memory/scope.hpp>
|
import surface.events;
|
||||||
#include <renderer/api.hpp>
|
import ecs.entity;
|
||||||
#include <renderer/frontend/messenger.hpp>
|
import ecs.registry;
|
||||||
|
import memory.reference;
|
||||||
|
import memory.scope;
|
||||||
|
import renderer.frontend;
|
||||||
|
import camera.components;
|
||||||
|
import surface.system;
|
||||||
|
import renderer.components;
|
||||||
|
import math.components;
|
||||||
|
import math.algebra;
|
||||||
|
import math.trig;
|
||||||
|
import std;
|
||||||
|
|
||||||
namespace lt::renderer {
|
namespace lt::renderer {
|
||||||
|
|
||||||
|
|
@ -16,11 +26,8 @@ namespace lt::renderer {
|
||||||
* - Creating a rendering backend context (vk/dx/mt)
|
* - Creating a rendering backend context (vk/dx/mt)
|
||||||
* - Connecting the context to the physical devices (select gpu, create surface, logical device)
|
* - Connecting the context to the physical devices (select gpu, create surface, logical device)
|
||||||
* - Rendering the scene represented in registry via lt::renderer::components.
|
* - Rendering the scene represented in registry via lt::renderer::components.
|
||||||
*
|
|
||||||
* @todo(Light): Add DirectX12 support
|
|
||||||
* @todo(Light): Add Metal support
|
|
||||||
*/
|
*/
|
||||||
class System: public app::ISystem
|
export class System: public app::ISystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** config.max_frames_in_flight should not be higher than this value. */
|
/** config.max_frames_in_flight should not be higher than this value. */
|
||||||
|
|
@ -33,7 +40,7 @@ public:
|
||||||
{
|
{
|
||||||
Api target_api;
|
Api target_api;
|
||||||
|
|
||||||
uint32_t max_frames_in_flight;
|
std::uint32_t max_frames_in_flight;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CreateInfo
|
struct CreateInfo
|
||||||
|
|
@ -44,7 +51,7 @@ public:
|
||||||
|
|
||||||
ecs::Entity surface_entity;
|
ecs::Entity surface_entity;
|
||||||
|
|
||||||
IMessenger::CreateInfo debug_callback_info;
|
IDebugger::CreateInfo debug_callback_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
System(CreateInfo info);
|
System(CreateInfo info);
|
||||||
|
|
@ -83,25 +90,25 @@ private:
|
||||||
|
|
||||||
ecs::Entity m_surface_entity;
|
ecs::Entity m_surface_entity;
|
||||||
|
|
||||||
memory::Scope<class IMessenger> m_messenger;
|
memory::Scope<IDebugger> m_messenger;
|
||||||
|
|
||||||
class IInstance *m_instance;
|
IInstance *m_instance;
|
||||||
|
|
||||||
memory::Scope<class ISurface> m_surface;
|
memory::Scope<ISurface> m_surface;
|
||||||
|
|
||||||
memory::Scope<class IGpu> m_gpu;
|
memory::Scope<IGpu> m_gpu;
|
||||||
|
|
||||||
memory::Scope<class IDevice> m_device;
|
memory::Scope<IDevice> m_device;
|
||||||
|
|
||||||
memory::Scope<class ISwapchain> m_swapchain;
|
memory::Scope<ISwapchain> m_swapchain;
|
||||||
|
|
||||||
memory::Scope<class IRenderer> m_renderer;
|
memory::Scope<IRenderer> m_renderer;
|
||||||
|
|
||||||
app::TickResult m_last_tick_result {};
|
app::TickResult m_last_tick_result {};
|
||||||
|
|
||||||
uint32_t m_frame_idx {};
|
std::uint32_t m_frame_idx {};
|
||||||
|
|
||||||
uint32_t m_max_frames_in_flight {};
|
std::uint32_t m_max_frames_in_flight {};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace lt::renderer
|
} // namespace lt::renderer
|
||||||
|
|
@ -109,31 +116,15 @@ private:
|
||||||
module :private;
|
module :private;
|
||||||
using namespace lt::renderer;
|
using namespace lt::renderer;
|
||||||
|
|
||||||
#include <camera/components.hpp>
|
|
||||||
#include <math/algebra.hpp>
|
|
||||||
#include <math/components/transform.hpp>
|
|
||||||
#include <renderer/components/messenger.hpp>
|
|
||||||
#include <renderer/components/sprite.hpp>
|
|
||||||
#include <renderer/frontend/context/device.hpp>
|
|
||||||
#include <renderer/frontend/context/gpu.hpp>
|
|
||||||
#include <renderer/frontend/context/instance.hpp>
|
|
||||||
#include <renderer/frontend/context/surface.hpp>
|
|
||||||
#include <renderer/frontend/context/swapchain.hpp>
|
|
||||||
#include <renderer/frontend/messenger.hpp>
|
|
||||||
#include <renderer/frontend/renderer/pass.hpp>
|
|
||||||
#include <renderer/frontend/renderer/renderer.hpp>
|
|
||||||
#include <renderer/system.hpp>
|
|
||||||
#include <surface/components.hpp>
|
|
||||||
|
|
||||||
System::System(CreateInfo info)
|
System::System(CreateInfo info)
|
||||||
: m_surface_entity(info.surface_entity)
|
: m_surface_entity(info.surface_entity)
|
||||||
, m_api(info.config.target_api)
|
, m_api(info.config.target_api)
|
||||||
, m_registry(std::move(info.registry))
|
, m_registry(std::move(info.registry))
|
||||||
, m_instance(IInstance::get(m_api))
|
, m_instance(get_instance(m_api))
|
||||||
, m_max_frames_in_flight(info.config.max_frames_in_flight)
|
, m_max_frames_in_flight(info.config.max_frames_in_flight)
|
||||||
{
|
{
|
||||||
ensure(m_registry, "Failed to initialize renderer::System: null registry");
|
debug::ensure(m_registry, "Failed to initialize renderer::System: null registry");
|
||||||
ensure(
|
debug::ensure(
|
||||||
std::clamp(
|
std::clamp(
|
||||||
info.config.max_frames_in_flight,
|
info.config.max_frames_in_flight,
|
||||||
frames_in_flight_lower_limit,
|
frames_in_flight_lower_limit,
|
||||||
|
|
@ -146,12 +137,13 @@ System::System(CreateInfo info)
|
||||||
frames_in_flight_upper_limit
|
frames_in_flight_upper_limit
|
||||||
);
|
);
|
||||||
|
|
||||||
m_messenger = IMessenger::create(m_api, m_instance, info.debug_callback_info);
|
m_messenger = create_debugger(m_api, m_instance, info.debug_callback_info);
|
||||||
m_surface = ISurface::create(m_api, m_instance, m_surface_entity);
|
m_surface = create_surface(m_api, m_instance, m_surface_entity);
|
||||||
m_gpu = IGpu::create(m_api, m_instance);
|
m_gpu = create_gpu(m_api, m_instance);
|
||||||
m_device = IDevice::create(m_api, m_gpu.get(), m_surface.get());
|
|
||||||
m_swapchain = ISwapchain::create(m_api, m_surface.get(), m_gpu.get(), m_device.get());
|
m_device = create_device(m_api, m_gpu.get(), m_surface.get());
|
||||||
m_renderer = { IRenderer::create(
|
m_swapchain = create_swapchain(m_api, m_surface.get(), m_gpu.get(), m_device.get());
|
||||||
|
m_renderer = { create_renderer(
|
||||||
m_api,
|
m_api,
|
||||||
m_gpu.get(),
|
m_gpu.get(),
|
||||||
m_device.get(),
|
m_device.get(),
|
||||||
|
|
@ -191,7 +183,7 @@ void System::handle_surface_resized_events()
|
||||||
if (std::holds_alternative<surface::ResizedEvent>(event))
|
if (std::holds_alternative<surface::ResizedEvent>(event))
|
||||||
{
|
{
|
||||||
m_swapchain.reset();
|
m_swapchain.reset();
|
||||||
m_swapchain = ISwapchain::create(m_api, m_surface.get(), m_gpu.get(), m_device.get());
|
m_swapchain = create_swapchain(m_api, m_surface.get(), m_gpu.get(), m_device.get());
|
||||||
m_renderer->replace_swapchain(m_swapchain.get());
|
m_renderer->replace_swapchain(m_swapchain.get());
|
||||||
|
|
||||||
// No need to process multiple resize events
|
// No need to process multiple resize events
|
||||||
|
|
@ -230,6 +222,6 @@ void System::recreate_swapchain()
|
||||||
{
|
{
|
||||||
log::trace("Re-creating swapchaain");
|
log::trace("Re-creating swapchaain");
|
||||||
m_swapchain.reset();
|
m_swapchain.reset();
|
||||||
m_swapchain = ISwapchain::create(m_api, m_surface.get(), m_gpu.get(), m_device.get());
|
m_swapchain = create_swapchain(m_api, m_surface.get(), m_gpu.get(), m_device.get());
|
||||||
m_renderer->replace_swapchain(m_swapchain.get());
|
m_renderer->replace_swapchain(m_swapchain.get());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +1,7 @@
|
||||||
export module renderer.backend.vk.buffer;
|
export module renderer.vk.buffer;
|
||||||
import renderer.backend.vk.device;
|
import renderer.vk.device;
|
||||||
import renderer.backend.vk.gpu;
|
import renderer.vk.gpu;
|
||||||
import renderer.backend.vk.library_wrapper;
|
import renderer.vk.api_wrapper;
|
||||||
import renderer.frontend;
|
import renderer.frontend;
|
||||||
import std;
|
import std;
|
||||||
|
|
||||||
|
|
@ -21,6 +21,11 @@ public:
|
||||||
return m_size;
|
return m_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto vk() -> vk::Buffer &
|
||||||
|
{
|
||||||
|
return m_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] auto determine_allocation_info(Usage usage) const -> vk::Memory::AllocateInfo;
|
[[nodiscard]] auto determine_allocation_info(Usage usage) const -> vk::Memory::AllocateInfo;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,29 @@
|
||||||
export module renderer.backends.vk.messenger;
|
export module renderer.vk.debugger;
|
||||||
|
import renderer.vk.instance;
|
||||||
|
import renderer.frontend;
|
||||||
|
import renderer.vk.api_wrapper;
|
||||||
import memory.null_on_move;
|
import memory.null_on_move;
|
||||||
import renderer.backends.vk.instance;
|
import debug.assertions;
|
||||||
import renderer.backends.vk.raii;
|
import logger;
|
||||||
import renderer.backends.vk.library;
|
|
||||||
import std;
|
import std;
|
||||||
|
|
||||||
|
namespace lt::renderer::vkb {
|
||||||
|
|
||||||
namespace lt::renderer::vk {
|
export class Debugger: public IDebugger
|
||||||
|
|
||||||
class Messenger: public IMessenger
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Messenger(IInstance *instance, CreateInfo info);
|
Debugger(IInstance *instance, CreateInfo info);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static auto native_callback(
|
static void native_callback(
|
||||||
VkDebugUtilsMessageSeverityFlagBitsEXT severity,
|
vk::Flags severity,
|
||||||
VkDebugUtilsMessageTypeFlagsEXT type,
|
vk::Flags types,
|
||||||
const VkDebugUtilsMessengerCallbackDataEXT *callback_data,
|
vk::Messenger::MessageData data,
|
||||||
void *vulkan_user_data
|
void *user_data
|
||||||
) -> VkBool32;
|
);
|
||||||
|
|
||||||
[[nodiscard]] static auto to_native_severity(MessageSeverity severity)
|
vk::Messenger m_messenger;
|
||||||
-> VkDebugUtilsMessageSeverityFlagsEXT;
|
|
||||||
|
|
||||||
[[nodiscard]] static auto from_native_severity(VkDebugUtilsMessageSeverityFlagsEXT severity)
|
|
||||||
-> MessageSeverity;
|
|
||||||
|
|
||||||
[[nodiscard]] static auto to_native_type(MessageType type) -> VkDebugUtilsMessageTypeFlagsEXT;
|
|
||||||
|
|
||||||
[[nodiscard]] static auto from_native_type(VkDebugUtilsMessageTypeFlagsEXT type) -> MessageType;
|
|
||||||
|
|
||||||
class Instance *m_instance {};
|
|
||||||
|
|
||||||
raii::DebugMessenger m_debug_messenger;
|
|
||||||
|
|
||||||
MessageSeverity m_severities {};
|
MessageSeverity m_severities {};
|
||||||
|
|
||||||
|
|
@ -45,48 +34,137 @@ private:
|
||||||
std::any m_user_data;
|
std::any m_user_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace lt::renderer::vk
|
} // namespace lt::renderer::vkb
|
||||||
|
|
||||||
|
|
||||||
module :private;
|
module :private;
|
||||||
using namespace lt::renderer::vk;
|
using namespace lt::renderer;
|
||||||
|
using namespace lt::renderer::vkb;
|
||||||
|
|
||||||
import logger;
|
[[nodiscard]] auto to_native_severity(IDebugger::MessageSeverity severity) -> vk::Flags
|
||||||
|
|
||||||
Messenger::Messenger(IInstance *instance, CreateInfo info)
|
|
||||||
: m_instance(static_cast<Instance *>(instance))
|
|
||||||
, m_user_data(std::move(info.user_data))
|
|
||||||
, m_user_callback(std::move(info.callback))
|
|
||||||
, m_debug_messenger(
|
|
||||||
m_instance,
|
|
||||||
VkDebugUtilsMessengerCreateInfoEXT {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
|
|
||||||
.messageSeverity = to_native_severity(info.severities),
|
|
||||||
.messageType = to_native_type(info.types),
|
|
||||||
.pfnUserCallback = &native_callback,
|
|
||||||
.pUserData = this,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
|
const auto value = std::to_underlying(severity);
|
||||||
|
auto flags = vk::Flags {};
|
||||||
|
|
||||||
|
using enum IDebugger::MessageSeverity;
|
||||||
|
using NativeSeverity = vk::Messenger::SeverityFlagBits;
|
||||||
|
if (value & std::to_underlying(error))
|
||||||
|
{
|
||||||
|
flags |= NativeSeverity::error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value & std::to_underlying(warning))
|
||||||
|
{
|
||||||
|
flags |= NativeSeverity::warning;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value & std::to_underlying(info))
|
||||||
|
{
|
||||||
|
flags |= NativeSeverity::info;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value & std::to_underlying(verbose))
|
||||||
|
{
|
||||||
|
flags |= NativeSeverity::verbose;
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ auto Messenger::native_callback(
|
[[nodiscard]] /* static */ auto to_native_type(IDebugger::MessageType type) -> vk::Flags
|
||||||
VkDebugUtilsMessageSeverityFlagBitsEXT severity,
|
{
|
||||||
VkDebugUtilsMessageTypeFlagsEXT type,
|
const auto value = std::to_underlying(type);
|
||||||
const VkDebugUtilsMessengerCallbackDataEXT *callback_data,
|
auto flags = vk::Flags {};
|
||||||
void *vulkan_user_data
|
|
||||||
) -> VkBool32
|
using enum IDebugger::MessageType;
|
||||||
|
using NativeType = vk::Messenger::TypeFlagBits;
|
||||||
|
if (value & std::to_underlying(general))
|
||||||
|
{
|
||||||
|
flags |= NativeType::general;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value & std::to_underlying(validation))
|
||||||
|
{
|
||||||
|
flags |= NativeType::validation;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value & std::to_underlying(performance))
|
||||||
|
{
|
||||||
|
flags |= NativeType::performance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto from_native_type(vk::Flags type) -> IDebugger::MessageType
|
||||||
|
{
|
||||||
|
auto flags = std::underlying_type_t<IDebugger::MessageType> {};
|
||||||
|
|
||||||
|
using enum IDebugger::MessageType;
|
||||||
|
using NativeType = vk::Messenger::TypeFlagBits;
|
||||||
|
if (type & NativeType::general)
|
||||||
|
{
|
||||||
|
flags |= std::to_underlying(general);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type & NativeType::validation)
|
||||||
|
{
|
||||||
|
flags |= std::to_underlying(validation);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type & NativeType::performance)
|
||||||
|
{
|
||||||
|
flags |= std::to_underlying(performance);
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<IDebugger::MessageType>(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto from_native_severity(vk::Flags severity) -> IDebugger::MessageSeverity
|
||||||
|
{
|
||||||
|
auto flags = std::underlying_type_t<IDebugger::MessageSeverity> {};
|
||||||
|
|
||||||
|
using enum IDebugger::MessageSeverity;
|
||||||
|
using NativeSeverity = vk::Messenger::SeverityFlagBits;
|
||||||
|
if (severity & NativeSeverity::error)
|
||||||
|
{
|
||||||
|
flags |= std::to_underlying(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (severity & NativeSeverity::warning)
|
||||||
|
{
|
||||||
|
flags |= std::to_underlying(warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (severity & NativeSeverity::info)
|
||||||
|
{
|
||||||
|
flags |= std::to_underlying(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (severity & NativeSeverity::verbose)
|
||||||
|
{
|
||||||
|
flags |= std::to_underlying(verbose);
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<IDebugger::MessageSeverity>(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Debugger::native_callback(
|
||||||
|
vk::Flags severity,
|
||||||
|
vk::Flags types,
|
||||||
|
vk::Messenger::MessageData data,
|
||||||
|
void *user_data
|
||||||
|
)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ensure(vulkan_user_data, "Null vulkan_user_data received in messenger callback");
|
debug::ensure(user_data, "Null vulkan_user_data received in messenger callback");
|
||||||
|
|
||||||
auto *messenger = std::bit_cast<vk::Messenger *>(vulkan_user_data);
|
auto *messenger = std::bit_cast<Debugger *>(user_data);
|
||||||
messenger->m_user_callback(
|
messenger->m_user_callback(
|
||||||
from_native_severity(severity),
|
from_native_severity(severity),
|
||||||
from_native_type(type),
|
from_native_type(types),
|
||||||
{
|
{
|
||||||
.message = callback_data->pMessage,
|
.message = data.message,
|
||||||
},
|
},
|
||||||
messenger->m_user_data
|
messenger->m_user_data
|
||||||
);
|
);
|
||||||
|
|
@ -96,119 +174,19 @@ Messenger::Messenger(IInstance *instance, CreateInfo info)
|
||||||
log::error("Uncaught exception in messenger callback:");
|
log::error("Uncaught exception in messenger callback:");
|
||||||
log::error("\twhat: {}", exp.what());
|
log::error("\twhat: {}", exp.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
return VK_FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] /*static*/ auto Messenger::to_native_severity(MessageSeverity severity)
|
Debugger::Debugger(IInstance *instance, CreateInfo info)
|
||||||
-> VkDebugUtilsMessageSeverityFlagsEXT
|
: m_user_data(std::move(info.user_data))
|
||||||
|
, m_user_callback(std::move(info.callback))
|
||||||
|
, m_messenger(
|
||||||
|
static_cast<Instance *>(instance)->vk(),
|
||||||
|
vk::Messenger::CreateInfo {
|
||||||
|
.user_callback = &native_callback,
|
||||||
|
.user_data = this,
|
||||||
|
.enabled_types = to_native_type(info.types),
|
||||||
|
.enabled_severities = to_native_severity(info.severities),
|
||||||
|
}
|
||||||
|
)
|
||||||
{
|
{
|
||||||
using enum MessageSeverity;
|
|
||||||
|
|
||||||
const auto value = std::to_underlying(severity);
|
|
||||||
auto flags = VkDebugUtilsMessageSeverityFlagsEXT {};
|
|
||||||
|
|
||||||
if (value & std::to_underlying(error))
|
|
||||||
{
|
|
||||||
flags |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value & std::to_underlying(warning))
|
|
||||||
{
|
|
||||||
flags |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value & std::to_underlying(info))
|
|
||||||
{
|
|
||||||
flags |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value & std::to_underlying(verbose))
|
|
||||||
{
|
|
||||||
flags |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] /*static*/ auto Messenger::from_native_severity(
|
|
||||||
VkDebugUtilsMessageSeverityFlagsEXT severity
|
|
||||||
) -> MessageSeverity
|
|
||||||
{
|
|
||||||
using enum MessageSeverity;
|
|
||||||
|
|
||||||
auto flags = std::underlying_type_t<MessageSeverity> {};
|
|
||||||
|
|
||||||
if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
|
|
||||||
{
|
|
||||||
flags |= std::to_underlying(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)
|
|
||||||
{
|
|
||||||
flags |= std::to_underlying(warning);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT)
|
|
||||||
{
|
|
||||||
flags |= std::to_underlying(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT)
|
|
||||||
{
|
|
||||||
flags |= std::to_underlying(verbose);
|
|
||||||
}
|
|
||||||
|
|
||||||
return static_cast<MessageSeverity>(flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] /*static*/ auto Messenger::to_native_type(MessageType type)
|
|
||||||
-> VkDebugUtilsMessageTypeFlagsEXT
|
|
||||||
{
|
|
||||||
using enum MessageType;
|
|
||||||
|
|
||||||
const auto value = std::to_underlying(type);
|
|
||||||
auto flags = VkDebugUtilsMessageTypeFlagsEXT {};
|
|
||||||
|
|
||||||
if (value & std::to_underlying(general))
|
|
||||||
{
|
|
||||||
flags |= VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value & std::to_underlying(validation))
|
|
||||||
{
|
|
||||||
flags |= VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value & std::to_underlying(performance))
|
|
||||||
{
|
|
||||||
flags |= VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] /* static */ auto Messenger::from_native_type(VkDebugUtilsMessageTypeFlagsEXT type)
|
|
||||||
-> MessageType
|
|
||||||
{
|
|
||||||
using enum MessageType;
|
|
||||||
|
|
||||||
auto flags = std::underlying_type_t<MessageType> {};
|
|
||||||
|
|
||||||
if (type & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT)
|
|
||||||
{
|
|
||||||
flags |= std::to_underlying(general);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT)
|
|
||||||
{
|
|
||||||
flags |= std::to_underlying(validation);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT)
|
|
||||||
{
|
|
||||||
flags |= std::to_underlying(general);
|
|
||||||
}
|
|
||||||
|
|
||||||
return static_cast<MessageType>(flags);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
export module renderer.backend.vk.device;
|
export module renderer.vk.device;
|
||||||
import memory.null_on_move;
|
import memory.null_on_move;
|
||||||
import logger;
|
import logger;
|
||||||
import debug.assertions;
|
import debug.assertions;
|
||||||
import renderer.backend.vk.instance;
|
import renderer.vk.instance;
|
||||||
import renderer.frontend;
|
import renderer.frontend;
|
||||||
import renderer.backend.vk.library_wrapper;
|
import renderer.vk.api_wrapper;
|
||||||
import renderer.backend.vk.gpu;
|
import renderer.vk.gpu;
|
||||||
import renderer.backend.vk.surface;
|
import renderer.vk.surface;
|
||||||
import std;
|
import std;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -27,6 +27,16 @@ public:
|
||||||
return { m_graphics_queue_family_index, m_present_queue_family_index };
|
return { m_graphics_queue_family_index, m_present_queue_family_index };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto graphics_queue() -> vk::Queue &
|
||||||
|
{
|
||||||
|
return m_graphics_queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto present_queue() -> vk::Queue &
|
||||||
|
{
|
||||||
|
return m_present_queue;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initialize_physical_device();
|
void initialize_physical_device();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
export module renderer.backend.vk.gpu;
|
export module renderer.vk.gpu;
|
||||||
import renderer.backend.vk.library_wrapper;
|
import renderer.vk.api_wrapper;
|
||||||
import debug.assertions;
|
import debug.assertions;
|
||||||
import renderer.frontend;
|
import renderer.frontend;
|
||||||
import renderer.backend.vk.instance;
|
import renderer.vk.instance;
|
||||||
import memory.null_on_move;
|
import memory.null_on_move;
|
||||||
import std;
|
import std;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
export module renderer.backend.vk.instance;
|
export module renderer.vk.instance;
|
||||||
import debug.assertions;
|
import debug.assertions;
|
||||||
import renderer.frontend;
|
import renderer.frontend;
|
||||||
import renderer.backend.vk.library_wrapper;
|
import renderer.vk.api_wrapper;
|
||||||
// import renderer.backend.vk.library_loader;
|
|
||||||
import std;
|
import std;
|
||||||
|
|
||||||
namespace lt::renderer::vkb {
|
namespace lt::renderer::vkb {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
export module renderer.vk.pass;
|
export module renderer.vk.pass;
|
||||||
|
|
||||||
import renderer.data;
|
import renderer.data;
|
||||||
import renderer.backend.vk.library_wrapper;
|
import renderer.vk.api_wrapper;
|
||||||
import renderer.backend.vk.device;
|
import renderer.vk.device;
|
||||||
import renderer.backend.vk.swapchain;
|
import renderer.vk.swapchain;
|
||||||
import assets.shader;
|
import assets.shader;
|
||||||
import assets.metadata;
|
import assets.metadata;
|
||||||
import memory.null_on_move;
|
import memory.null_on_move;
|
||||||
|
|
|
||||||
|
|
@ -1,84 +0,0 @@
|
||||||
#include <memory/pointer_types/null_on_move.hpp>
|
|
||||||
#include <renderer/backend/vk/context/device.hpp>
|
|
||||||
#include <renderer/backend/vk/context/instance.hpp>
|
|
||||||
#include <renderer/backend/vk/vulkan.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
export namespace lt::renderer::vk::raii {
|
|
||||||
|
|
||||||
class DebugMessenger
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DebugMessenger(Instance *instance, VkDebugUtilsMessengerCreateInfoEXT info)
|
|
||||||
: m_instance(instance)
|
|
||||||
, m_object(m_instance->create_messenger(info))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~DebugMessenger()
|
|
||||||
{
|
|
||||||
if (m_instance)
|
|
||||||
{
|
|
||||||
m_instance->destroy_messenger(m_object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DebugMessenger(DebugMessenger &&) = default;
|
|
||||||
|
|
||||||
DebugMessenger(const DebugMessenger &) = delete;
|
|
||||||
|
|
||||||
auto operator=(DebugMessenger &&) -> DebugMessenger & = default;
|
|
||||||
|
|
||||||
auto operator=(const DebugMessenger &) -> DebugMessenger & = delete;
|
|
||||||
|
|
||||||
private:
|
|
||||||
memory::NullOnMove<Instance *> m_instance {};
|
|
||||||
|
|
||||||
VkDebugUtilsMessengerEXT m_object;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Memory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Memory(Device *device, VkBuffer buffer, VkMemoryAllocateInfo info)
|
|
||||||
: m_device(device)
|
|
||||||
, m_object(m_device->allocate_memory(info))
|
|
||||||
{
|
|
||||||
m_device->bind_memory(buffer, m_object);
|
|
||||||
}
|
|
||||||
|
|
||||||
~Memory()
|
|
||||||
{
|
|
||||||
if (m_device)
|
|
||||||
{
|
|
||||||
m_device->free_memory(m_object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Memory(Memory &&) = default;
|
|
||||||
|
|
||||||
Memory(const Memory &) = delete;
|
|
||||||
|
|
||||||
auto operator=(Memory &&) -> Memory & = default;
|
|
||||||
|
|
||||||
auto operator=(const Memory &) -> Memory & = delete;
|
|
||||||
|
|
||||||
[[nodiscard]] auto operator*() const -> VkDeviceMemory
|
|
||||||
{
|
|
||||||
return m_object;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] operator VkDeviceMemory() const
|
|
||||||
{
|
|
||||||
return m_object;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
memory::NullOnMove<Device *> m_device {};
|
|
||||||
|
|
||||||
VkDeviceMemory m_object = VK_NULL_HANDLE;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace lt::renderer::vk::raii
|
|
||||||
|
|
@ -1,38 +1,33 @@
|
||||||
#pragma once
|
export module renderer.vk.renderer;
|
||||||
|
import assets.shader;
|
||||||
|
import debug.assertions;
|
||||||
|
import renderer.vk.api_wrapper;
|
||||||
|
import memory.reference;
|
||||||
|
import memory.null_on_move;
|
||||||
|
import renderer.vk.device;
|
||||||
|
import math.vec2;
|
||||||
|
import math.components;
|
||||||
|
import renderer.vk.swapchain;
|
||||||
|
import renderer.components;
|
||||||
|
import renderer.vk.buffer;
|
||||||
|
import renderer.vk.pass;
|
||||||
|
import renderer.data;
|
||||||
|
import renderer.frontend;
|
||||||
|
import std;
|
||||||
|
|
||||||
#include <memory/reference.hpp>
|
namespace lt::renderer::vkb {
|
||||||
#include <ranges>
|
|
||||||
#include <renderer/backend/vk/context/device.hpp>
|
|
||||||
#include <renderer/backend/vk/data/buffer.hpp>
|
|
||||||
#include <renderer/backend/vk/renderer/pass.hpp>
|
|
||||||
#include <renderer/backend/vk/utils.hpp>
|
|
||||||
#include <renderer/frontend/data/buffer.hpp>
|
|
||||||
#include <renderer/frontend/renderer/pass.hpp>
|
|
||||||
#include <renderer/frontend/renderer/renderer.hpp>
|
|
||||||
|
|
||||||
namespace lt::renderer::vk {
|
export class Renderer: public IRenderer
|
||||||
|
|
||||||
class Renderer: public IRenderer
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Renderer(
|
Renderer(
|
||||||
class IGpu *gpu,
|
class IGpu *gpu,
|
||||||
class IDevice *device,
|
class IDevice *device,
|
||||||
class ISwapchain *swapchain,
|
class ISwapchain *swapchain,
|
||||||
uint32_t max_frames_in_flight
|
std::uint32_t max_frames_in_flight
|
||||||
);
|
);
|
||||||
|
|
||||||
~Renderer() override;
|
[[nodiscard]] auto frame(std::uint32_t frame_idx, std::function<void()> submit_scene)
|
||||||
|
|
||||||
Renderer(Renderer &&) = default;
|
|
||||||
|
|
||||||
Renderer(const Renderer &) = delete;
|
|
||||||
|
|
||||||
auto operator=(Renderer &&) -> Renderer & = default;
|
|
||||||
|
|
||||||
auto operator=(const Renderer &) -> Renderer & = delete;
|
|
||||||
|
|
||||||
[[nodiscard]] auto frame(uint32_t frame_idx, std::function<void()> submit_scene)
|
|
||||||
-> Result override;
|
-> Result override;
|
||||||
|
|
||||||
void replace_swapchain(ISwapchain *swapchain) override;
|
void replace_swapchain(ISwapchain *swapchain) override;
|
||||||
|
|
@ -48,33 +43,29 @@ public:
|
||||||
) override;
|
) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void record_cmd(VkCommandBuffer cmd, uint32_t image_idx);
|
void record_cmd(vk::CommandBuffer &cmd, std::uint32_t image_idx);
|
||||||
|
|
||||||
void map_buffers(uint32_t frame_idx);
|
void map_buffers(std::uint32_t frame_idx);
|
||||||
|
|
||||||
void flush_buffers(VkCommandBuffer cmd);
|
std::uint32_t m_max_frames_in_flight {};
|
||||||
|
|
||||||
memory::NullOnMove<class Device *> m_device {};
|
Device * m_device {};
|
||||||
|
|
||||||
class Swapchain *m_swapchain {};
|
Swapchain *m_swapchain {};
|
||||||
|
|
||||||
memory::Ref<class Pass> m_pass;
|
memory::Ref<Pass> m_pass;
|
||||||
|
|
||||||
VkCommandPool m_pool = VK_NULL_HANDLE;
|
vk::CommandPool m_pool;
|
||||||
|
|
||||||
VkCommandPool m_transient_pool = VK_NULL_HANDLE;
|
std::vector<vk::CommandBuffer> m_cmds;
|
||||||
|
|
||||||
std::vector<VkCommandBuffer> m_cmds;
|
std::vector<vk::Fence> m_frame_fences;
|
||||||
|
|
||||||
std::vector<VkFence> m_frame_fences;
|
std::vector<vk::Semaphore> m_acquire_image_semaphores;
|
||||||
|
|
||||||
std::vector<VkSemaphore> m_aquire_image_semaphores;
|
std::vector<vk::Semaphore> m_submit_semaphores;
|
||||||
|
|
||||||
std::vector<VkSemaphore> m_submit_semaphores;
|
math::uvec2 m_resolution;
|
||||||
|
|
||||||
VkExtent2D m_resolution;
|
|
||||||
|
|
||||||
uint32_t m_max_frames_in_flight {};
|
|
||||||
|
|
||||||
FrameConstants m_frame_constants;
|
FrameConstants m_frame_constants;
|
||||||
|
|
||||||
|
|
@ -82,26 +73,27 @@ private:
|
||||||
|
|
||||||
Buffer m_staging_buffer;
|
Buffer m_staging_buffer;
|
||||||
|
|
||||||
size_t m_staging_offset;
|
std::size_t m_staging_offset;
|
||||||
|
|
||||||
std::span<std::byte> m_staging_map;
|
std::span<std::byte> m_staging_map;
|
||||||
|
|
||||||
std::span<components::Sprite::Vertex> m_sprite_vertex_map;
|
std::span<components::Sprite::Vertex> m_sprite_vertex_map;
|
||||||
|
|
||||||
size_t m_current_sprite_idx;
|
std::size_t m_current_sprite_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace lt::renderer::vk
|
} // namespace lt::renderer::vkb
|
||||||
|
|
||||||
module :private;
|
module :private;
|
||||||
|
using namespace lt::renderer;
|
||||||
|
using namespace lt::renderer::vkb;
|
||||||
|
|
||||||
#include <memory/reference.hpp>
|
Renderer::Renderer(
|
||||||
#include <renderer/backend/vk/context/swapchain.hpp>
|
IGpu *gpu,
|
||||||
#include <renderer/backend/vk/renderer/renderer.hpp>
|
IDevice *device,
|
||||||
|
ISwapchain *swapchain,
|
||||||
namespace lt::renderer::vk {
|
std::uint32_t max_frames_in_flight
|
||||||
|
)
|
||||||
Renderer::Renderer(IGpu *gpu, IDevice *device, ISwapchain *swapchain, uint32_t max_frames_in_flight)
|
|
||||||
: m_device(static_cast<Device *>(device))
|
: m_device(static_cast<Device *>(device))
|
||||||
, m_swapchain(static_cast<Swapchain *>(swapchain))
|
, m_swapchain(static_cast<Swapchain *>(swapchain))
|
||||||
, m_resolution(m_swapchain->get_resolution())
|
, m_resolution(m_swapchain->get_resolution())
|
||||||
|
|
@ -110,7 +102,7 @@ Renderer::Renderer(IGpu *gpu, IDevice *device, ISwapchain *swapchain, uint32_t m
|
||||||
, m_vertex_buffer(
|
, m_vertex_buffer(
|
||||||
device,
|
device,
|
||||||
gpu,
|
gpu,
|
||||||
IBuffer::CreateInfo {
|
{
|
||||||
.usage = IBuffer::Usage::vertex,
|
.usage = IBuffer::Usage::vertex,
|
||||||
.size = 1'000'000,
|
.size = 1'000'000,
|
||||||
.debug_name = "vertex buffer",
|
.debug_name = "vertex buffer",
|
||||||
|
|
@ -119,91 +111,46 @@ Renderer::Renderer(IGpu *gpu, IDevice *device, ISwapchain *swapchain, uint32_t m
|
||||||
, m_staging_buffer(
|
, m_staging_buffer(
|
||||||
device,
|
device,
|
||||||
gpu,
|
gpu,
|
||||||
IBuffer::CreateInfo {
|
{
|
||||||
.usage = IBuffer::Usage::staging,
|
.usage = IBuffer::Usage::staging,
|
||||||
.size = 1'000'000,
|
.size = 1'000'000,
|
||||||
.debug_name = "staging buffer",
|
.debug_name = "staging buffer",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
, m_pass(
|
||||||
|
memory::create_ref<Pass>(
|
||||||
|
m_device,
|
||||||
|
assets::ShaderAsset { "./data/test_assets/sprite.vert.asset" },
|
||||||
|
assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
, m_pool(
|
||||||
|
m_device->vk(),
|
||||||
|
{
|
||||||
|
.flags = vk::CommandPool::CreateInfo::FlagBits::reset_command_buffer,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
, m_cmds(m_pool.allocate(m_max_frames_in_flight, vk::CommandPool::BufferLevel::primary))
|
||||||
|
, m_acquire_image_semaphores(m_max_frames_in_flight)
|
||||||
|
, m_frame_fences(m_max_frames_in_flight)
|
||||||
|
, m_submit_semaphores(m_swapchain->get_image_count())
|
||||||
{
|
{
|
||||||
ensure(m_device, "Failed to initialize renderer: null device");
|
for (auto [semaphore, fence] : std::views::zip(m_acquire_image_semaphores, m_frame_fences))
|
||||||
ensure(m_swapchain, "Failed to initialize renderer: null swapchain");
|
|
||||||
|
|
||||||
// TODO(Light): HARDCODED PASS!!!
|
|
||||||
m_pass = memory::create_ref<vk::Pass>(
|
|
||||||
m_device,
|
|
||||||
m_swapchain,
|
|
||||||
assets::ShaderAsset { "./data/test_assets/sprite.vert.asset" },
|
|
||||||
assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" }
|
|
||||||
);
|
|
||||||
|
|
||||||
m_pool = m_device->create_command_pool(
|
|
||||||
VkCommandPoolCreateInfo {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
|
||||||
.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
|
|
||||||
.queueFamilyIndex = m_device->get_family_indices()[0],
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
m_transient_pool = m_device->create_command_pool(
|
|
||||||
VkCommandPoolCreateInfo {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
|
||||||
.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,
|
|
||||||
.queueFamilyIndex = m_device->get_family_indices()[0],
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
m_cmds.resize(m_max_frames_in_flight);
|
|
||||||
m_cmds = m_device->allocate_command_buffers(
|
|
||||||
VkCommandBufferAllocateInfo {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
|
||||||
.commandPool = m_pool,
|
|
||||||
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
|
||||||
.commandBufferCount = static_cast<uint32_t>(m_cmds.size()),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
m_aquire_image_semaphores = m_device->create_semaphores(m_max_frames_in_flight);
|
|
||||||
m_frame_fences = m_device->create_fences(
|
|
||||||
VkFenceCreateInfo {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
|
|
||||||
.flags = VK_FENCE_CREATE_SIGNALED_BIT,
|
|
||||||
},
|
|
||||||
m_max_frames_in_flight
|
|
||||||
);
|
|
||||||
for (auto idx = 0u;
|
|
||||||
auto [semaphore, fence] : std::views::zip(m_aquire_image_semaphores, m_frame_fences))
|
|
||||||
{
|
{
|
||||||
m_device->name(semaphore, "acquire image semaphore {}", idx);
|
semaphore = vk::Semaphore(m_device->vk());
|
||||||
m_device->name(fence, "frame fence {}", idx);
|
fence = vk::Fence(m_device->vk(), { .signaled = true });
|
||||||
}
|
}
|
||||||
|
|
||||||
m_submit_semaphores = m_device->create_semaphores(m_swapchain->get_image_count());
|
for (auto &semaphore : m_submit_semaphores)
|
||||||
for (auto idx = 0u; auto &semaphore : m_submit_semaphores)
|
|
||||||
{
|
{
|
||||||
m_device->name(semaphore, "submit semaphore {}", idx);
|
semaphore = vk::Semaphore(m_device->vk());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Renderer::~Renderer()
|
[[nodiscard]] auto Renderer::frame(std::uint32_t frame_idx, std::function<void()> submit_scene)
|
||||||
|
-> Result
|
||||||
{
|
{
|
||||||
if (!m_device)
|
debug::ensure(
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_device->wait_idle();
|
|
||||||
m_device->destroy_semaphores(m_aquire_image_semaphores);
|
|
||||||
m_device->destroy_semaphores(m_submit_semaphores);
|
|
||||||
m_device->destroy_fences(m_frame_fences);
|
|
||||||
m_device->destroy_command_pool(m_pool);
|
|
||||||
m_device->destroy_command_pool(m_transient_pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto Renderer::frame(uint32_t frame_idx, std::function<void()> submit_scene) -> Result
|
|
||||||
{
|
|
||||||
ensure(
|
|
||||||
frame_idx < m_max_frames_in_flight,
|
frame_idx < m_max_frames_in_flight,
|
||||||
"Failed to draw: frame_idx >= max_frames_in_flight ({} >= {})",
|
"Failed to draw: frame_idx >= max_frames_in_flight ({} >= {})",
|
||||||
frame_idx,
|
frame_idx,
|
||||||
|
|
@ -211,50 +158,33 @@ Renderer::~Renderer()
|
||||||
);
|
);
|
||||||
|
|
||||||
auto &frame_fence = m_frame_fences[frame_idx];
|
auto &frame_fence = m_frame_fences[frame_idx];
|
||||||
auto &aquire_semaphore = m_aquire_image_semaphores[frame_idx];
|
auto &acquire_semaphore = m_acquire_image_semaphores[frame_idx];
|
||||||
auto &cmd = m_cmds[frame_idx];
|
auto &cmd = m_cmds[frame_idx];
|
||||||
|
|
||||||
m_device->wait_for_fence(frame_fence);
|
frame_fence.wait();
|
||||||
|
const auto image_idx = m_swapchain->vk().acquire_image(acquire_semaphore);
|
||||||
auto image_idx = m_device->acquire_image(m_swapchain->vk(), aquire_semaphore);
|
frame_fence.reset();
|
||||||
if (!image_idx.has_value())
|
|
||||||
{
|
|
||||||
return Result::invalid_swapchain;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_device->reset_fence(frame_fence);
|
|
||||||
|
|
||||||
map_buffers(frame_idx);
|
map_buffers(frame_idx);
|
||||||
submit_scene();
|
submit_scene();
|
||||||
record_cmd(cmd, *image_idx);
|
record_cmd(cmd, image_idx);
|
||||||
|
|
||||||
auto wait_stage = VkPipelineStageFlags { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
auto &submit_semaphore = m_submit_semaphores[image_idx];
|
||||||
auto &submit_semaphore = m_submit_semaphores[*image_idx];
|
m_device->graphics_queue().submit(
|
||||||
m_device->submit(
|
vk::Queue::SubmitInfo {
|
||||||
VkSubmitInfo {
|
.command_buffer = &cmd,
|
||||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
.wait_stages = vk::PipelineStageFlags::color_attachment_output_bit,
|
||||||
.waitSemaphoreCount = 1u,
|
.wait_semaphore = &acquire_semaphore,
|
||||||
.pWaitSemaphores = &aquire_semaphore,
|
.signal_semaphore = &submit_semaphore,
|
||||||
.pWaitDstStageMask = &wait_stage,
|
.signal_fence = &frame_fence,
|
||||||
.commandBufferCount = 1u,
|
}
|
||||||
.pCommandBuffers = &cmd,
|
|
||||||
.signalSemaphoreCount = 1u,
|
|
||||||
.pSignalSemaphores = &submit_semaphore,
|
|
||||||
},
|
|
||||||
frame_fence
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO(Light): handle result
|
m_device->present_queue().present(
|
||||||
auto result = VkResult {};
|
vk::Queue::PresentInfo {
|
||||||
m_device->present(
|
.wait_semaphore = &submit_semaphore,
|
||||||
VkPresentInfoKHR {
|
.swapchain = &m_swapchain->vk(),
|
||||||
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
.image_idx = image_idx,
|
||||||
.waitSemaphoreCount = 1u,
|
|
||||||
.pWaitSemaphores = &submit_semaphore,
|
|
||||||
.swapchainCount = 1u,
|
|
||||||
.pSwapchains = m_swapchain->vk_ptr(),
|
|
||||||
.pImageIndices = &image_idx.value(),
|
|
||||||
.pResults = &result,
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -263,13 +193,12 @@ Renderer::~Renderer()
|
||||||
|
|
||||||
void Renderer::replace_swapchain(ISwapchain *swapchain)
|
void Renderer::replace_swapchain(ISwapchain *swapchain)
|
||||||
{
|
{
|
||||||
m_device->wait_idle();
|
m_device->vk().wait_idle();
|
||||||
m_swapchain = static_cast<Swapchain *>(swapchain);
|
m_swapchain = static_cast<Swapchain *>(swapchain);
|
||||||
m_resolution = m_swapchain->get_resolution();
|
m_resolution = m_swapchain->get_resolution();
|
||||||
m_pass->replace_swapchain(*swapchain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::map_buffers(uint32_t frame_idx)
|
void Renderer::map_buffers(std::uint32_t frame_idx)
|
||||||
{
|
{
|
||||||
using components::Sprite;
|
using components::Sprite;
|
||||||
|
|
||||||
|
|
@ -286,140 +215,188 @@ void Renderer::map_buffers(uint32_t frame_idx)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::flush_buffers(VkCommandBuffer cmd)
|
void Renderer::record_cmd(vk::CommandBuffer &cmd, std::uint32_t image_idx)
|
||||||
{
|
{
|
||||||
|
// const auto cmd_begin_info = VkCommandBufferBeginInfo {
|
||||||
|
// .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||||
|
// .flags = {},
|
||||||
|
// .pInheritanceInfo = nullptr,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// vk_reset_command_buffer(cmd, {});
|
||||||
|
// vkc(vk_begin_command_buffer(cmd, &cmd_begin_info));
|
||||||
|
// const auto begin_frame_barrier = VkImageMemoryBarrier {
|
||||||
|
// .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||||
|
// .srcAccessMask = {},
|
||||||
|
// .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
|
// .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
// .newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||||
|
// .image = m_swapchain->get_image(image_idx),
|
||||||
|
// .range = vk::Image::full_color_range,
|
||||||
|
// .subresourceRange = VkImageSubresourceRange{
|
||||||
|
// .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
// .baseMipLevel = 0u,
|
||||||
|
// .levelCount = VK_REMAINING_MIP_LEVELS,
|
||||||
|
// .baseArrayLayer = 0u,
|
||||||
|
// .layerCount = VK_REMAINING_ARRAY_LAYERS,
|
||||||
|
// },
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// vk_cmd_pipeline_barrier(
|
||||||
|
// cmd,
|
||||||
|
// VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
|
// VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
|
// 0,
|
||||||
|
// 0,
|
||||||
|
// nullptr,
|
||||||
|
// 0,
|
||||||
|
// nullptr,
|
||||||
|
// 1,
|
||||||
|
// &begin_frame_barrier
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// const auto end_frame_barrier = VkImageMemoryBarrier {
|
||||||
|
// .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||||
|
// .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
|
||||||
|
// VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, .dstAccessMask = {}, .oldLayout =
|
||||||
|
// VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||||
|
// .image = m_swapchain->get_image(image_idx),
|
||||||
|
//
|
||||||
|
// .subresourceRange = VkImageSubresourceRange{
|
||||||
|
// .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
// .baseMipLevel = 0u,
|
||||||
|
// .levelCount = VK_REMAINING_MIP_LEVELS,
|
||||||
|
// .baseArrayLayer = 0u,
|
||||||
|
// .layerCount = VK_REMAINING_ARRAY_LAYERS,
|
||||||
|
// },
|
||||||
|
// };
|
||||||
|
// vk_cmd_pipeline_barrier(
|
||||||
|
// cmd,
|
||||||
|
// VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
|
// VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
||||||
|
// 0,
|
||||||
|
// 0,
|
||||||
|
// nullptr,
|
||||||
|
// 0,
|
||||||
|
// nullptr,
|
||||||
|
// 1,
|
||||||
|
// &end_frame_barrier
|
||||||
|
// );
|
||||||
|
|
||||||
|
// const auto scissor = VkRect2D {
|
||||||
|
// .offset = { .x = 0u, .y = 0u },
|
||||||
|
// .extent = m_resolution,
|
||||||
|
// };
|
||||||
|
// const auto viewport = VkViewport {
|
||||||
|
// .x = 0.0f,
|
||||||
|
// .y = 0.0f,
|
||||||
|
// .width = static_cast<float>(m_resolution.width),
|
||||||
|
// .height = static_cast<float>(m_resolution.height),
|
||||||
|
// .minDepth = 0.0f,
|
||||||
|
// .maxDepth = 1.0f,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const auto color_attachment_info = VkRenderingAttachmentInfoKHR {
|
||||||
|
// .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||||
|
// .imageView = m_swapchain->get_image_view(image_idx),
|
||||||
|
// .imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||||
|
// .resolveMode = VK_RESOLVE_MODE_NONE,
|
||||||
|
// .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||||
|
// .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
|
// .clearValue = VkClearValue { .color = { 0.93, 0.93, 0.93, 1.0 } },
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const auto rendering_info = VkRenderingInfoKHR {
|
||||||
|
// .sType = VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
|
||||||
|
// .renderArea = scissor,
|
||||||
|
// .layerCount = 1,
|
||||||
|
// .colorAttachmentCount = 1,
|
||||||
|
// .pColorAttachments = &color_attachment_info,
|
||||||
|
//
|
||||||
|
// };
|
||||||
|
|
||||||
m_staging_map = {};
|
m_staging_map = {};
|
||||||
m_sprite_vertex_map = {};
|
m_sprite_vertex_map = {};
|
||||||
|
cmd.begin({});
|
||||||
|
|
||||||
m_staging_buffer.unmap();
|
m_staging_buffer.unmap();
|
||||||
const auto buffer_copy_info = VkBufferCopy {
|
cmd.copy(
|
||||||
|
{
|
||||||
.srcOffset = m_staging_offset,
|
.src_buffer = &m_staging_buffer.vk(),
|
||||||
.dstOffset = m_staging_offset,
|
.dst_buffer = &m_vertex_buffer.vk(),
|
||||||
.size = m_current_sprite_idx * sizeof(components::Sprite::Vertex),
|
.src_offset = m_staging_offset,
|
||||||
};
|
.dst_offset = m_staging_offset,
|
||||||
|
.size = m_current_sprite_idx * sizeof(components::Sprite::Vertex),
|
||||||
vk_cmd_copy_buffer(cmd, m_staging_buffer.vk(), m_vertex_buffer.vk(), 1u, &buffer_copy_info);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::record_cmd(VkCommandBuffer cmd, uint32_t image_idx)
|
|
||||||
{
|
|
||||||
const auto cmd_begin_info = VkCommandBufferBeginInfo {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
|
||||||
.flags = {},
|
|
||||||
.pInheritanceInfo = nullptr,
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto begin_frame_barrier = VkImageMemoryBarrier {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
||||||
.srcAccessMask = {},
|
|
||||||
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
|
||||||
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
|
||||||
.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
|
||||||
.image = m_swapchain->get_image(image_idx),
|
|
||||||
.subresourceRange = VkImageSubresourceRange{
|
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
||||||
.baseMipLevel = 0u,
|
|
||||||
.levelCount = VK_REMAINING_MIP_LEVELS,
|
|
||||||
.baseArrayLayer = 0u,
|
|
||||||
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
|
||||||
},
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto end_frame_barrier = VkImageMemoryBarrier {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
|
||||||
.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
|
||||||
.dstAccessMask = {},
|
|
||||||
.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
|
||||||
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
|
||||||
.image = m_swapchain->get_image(image_idx),
|
|
||||||
|
|
||||||
.subresourceRange = VkImageSubresourceRange{
|
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
|
||||||
.baseMipLevel = 0u,
|
|
||||||
.levelCount = VK_REMAINING_MIP_LEVELS,
|
|
||||||
.baseArrayLayer = 0u,
|
|
||||||
.layerCount = VK_REMAINING_ARRAY_LAYERS,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto scissor = VkRect2D {
|
|
||||||
.offset = { .x = 0u, .y = 0u },
|
|
||||||
.extent = m_resolution,
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto viewport = VkViewport {
|
|
||||||
.x = 0.0f,
|
|
||||||
.y = 0.0f,
|
|
||||||
.width = static_cast<float>(m_resolution.width),
|
|
||||||
.height = static_cast<float>(m_resolution.height),
|
|
||||||
.minDepth = 0.0f,
|
|
||||||
.maxDepth = 1.0f,
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto color_attachment_info = VkRenderingAttachmentInfoKHR {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
|
||||||
.imageView = m_swapchain->get_image_view(image_idx),
|
|
||||||
.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
|
||||||
.resolveMode = VK_RESOLVE_MODE_NONE,
|
|
||||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
|
||||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
|
||||||
.clearValue = VkClearValue { .color = { 0.93, 0.93, 0.93, 1.0 } },
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto rendering_info = VkRenderingInfoKHR {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
|
|
||||||
.renderArea = scissor,
|
|
||||||
.layerCount = 1,
|
|
||||||
.colorAttachmentCount = 1,
|
|
||||||
.pColorAttachments = &color_attachment_info,
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
vk_reset_command_buffer(cmd, {});
|
|
||||||
vkc(vk_begin_command_buffer(cmd, &cmd_begin_info));
|
|
||||||
flush_buffers(cmd);
|
|
||||||
|
|
||||||
vk_cmd_push_constants(
|
|
||||||
cmd,
|
|
||||||
m_pass->get_layout(),
|
|
||||||
VK_SHADER_STAGE_VERTEX_BIT,
|
|
||||||
0u,
|
|
||||||
sizeof(FrameConstants),
|
|
||||||
&m_frame_constants
|
|
||||||
);
|
);
|
||||||
vk_cmd_pipeline_barrier(
|
cmd.push_constants(
|
||||||
cmd,
|
{
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
.layout = &m_pass->get_layout(),
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
.shader_stages = vk::ShaderStageFlags::vertex_bit,
|
||||||
0,
|
.offset = 0u,
|
||||||
0,
|
.size = sizeof(FrameConstants),
|
||||||
nullptr,
|
.data = &m_frame_constants,
|
||||||
0,
|
}
|
||||||
nullptr,
|
|
||||||
1,
|
|
||||||
&begin_frame_barrier
|
|
||||||
);
|
);
|
||||||
vk_cmd_begin_rendering(cmd, &rendering_info);
|
|
||||||
vk_cmd_bind_pipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pass->get_pipeline());
|
using AccessFlagBits = vk::CommandBuffer::ImageBarrierInfo::AccessFlagBits;
|
||||||
vk_cmd_set_viewport(cmd, 0, 1, &viewport);
|
cmd.image_barrier(
|
||||||
vk_cmd_set_scissors(cmd, 0, 1, &scissor);
|
{
|
||||||
vk_cmd_draw(cmd, m_current_sprite_idx, 1, 0, 0);
|
.image = &m_swapchain->get_image(image_idx),
|
||||||
vk_cmd_end_rendering(cmd);
|
.range = vk::Image::full_color_range,
|
||||||
vk_cmd_pipeline_barrier(
|
.src_stages = vk::PipelineStageFlags::color_attachment_output_bit,
|
||||||
cmd,
|
.dst_stages = vk::PipelineStageFlags::color_attachment_output_bit,
|
||||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
.src_accesses = AccessFlagBits::none,
|
||||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
.dst_accesses = AccessFlagBits::color_attachment_write,
|
||||||
0,
|
.src_layout = vk::Image::Layout::undefined,
|
||||||
0,
|
.dst_layout = vk::Image::Layout::color_attachment_optimal,
|
||||||
nullptr,
|
}
|
||||||
0,
|
|
||||||
nullptr,
|
|
||||||
1,
|
|
||||||
&end_frame_barrier
|
|
||||||
);
|
);
|
||||||
vkc(vk_end_command_buffer(cmd));
|
|
||||||
|
using Attachment = vk::CommandBuffer::RenderingInfo::AttachmentInfo;
|
||||||
|
cmd.begin_rendering(
|
||||||
|
{
|
||||||
|
.area_offset = {0u, 0u,},
|
||||||
|
.area_extent = m_resolution,
|
||||||
|
.color_attachments = std::vector<Attachment> {
|
||||||
|
Attachment{
|
||||||
|
.view= &m_swapchain->get_image_view(image_idx),
|
||||||
|
.layout = vk::Image::Layout::color_attachment_optimal,
|
||||||
|
.load_operation = Attachment::LoadOperation::load,
|
||||||
|
.store_operation = Attachment::StoreOperation::store,
|
||||||
|
.color_clear_values = {.5f, .5f, .5f, 1.f}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
cmd.bind_pipeline(m_pass->get_pipeline(), vk::Pipeline::BindPoint::graphics);
|
||||||
|
// cmd.set_viewport();
|
||||||
|
// cmd.set_scissors();
|
||||||
|
cmd.draw(
|
||||||
|
{
|
||||||
|
.vertex_count = static_cast<std::uint32_t>(m_current_sprite_idx),
|
||||||
|
.instance_count = 1u,
|
||||||
|
.first_vertex = 0u,
|
||||||
|
.first_instance = 0u,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
cmd.end_rendering();
|
||||||
|
cmd.image_barrier(
|
||||||
|
{
|
||||||
|
.image = &m_swapchain->get_image(image_idx),
|
||||||
|
.src_stages = vk::PipelineStageFlags::color_attachment_output_bit,
|
||||||
|
.dst_stages = vk::PipelineStageFlags::bottom_of_pipe_bit,
|
||||||
|
.src_accesses = AccessFlagBits::color_attachment_read
|
||||||
|
| AccessFlagBits::color_attachment_write,
|
||||||
|
.dst_accesses = {},
|
||||||
|
.src_layout = vk::Image::Layout::color_attachment_optimal,
|
||||||
|
.dst_layout = vk::Image::Layout::present_src,
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
cmd.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::submit_sprite(
|
void Renderer::submit_sprite(
|
||||||
|
|
@ -462,5 +439,3 @@ void Renderer::submit_sprite(
|
||||||
.color = sprite.color,
|
.color = sprite.color,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace lt::renderer::vk
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
export module renderer.backend.vk.surface;
|
export module renderer.vk.surface;
|
||||||
import debug.assertions;
|
import debug.assertions;
|
||||||
import ecs.entity;
|
import ecs.entity;
|
||||||
import ecs.registry;
|
import ecs.registry;
|
||||||
|
|
@ -6,8 +6,8 @@ import memory.null_on_move;
|
||||||
import math.vec2;
|
import math.vec2;
|
||||||
import surface.system;
|
import surface.system;
|
||||||
import renderer.frontend;
|
import renderer.frontend;
|
||||||
import renderer.backend.vk.instance;
|
import renderer.vk.instance;
|
||||||
import renderer.backend.vk.library_wrapper;
|
import renderer.vk.api_wrapper;
|
||||||
|
|
||||||
namespace lt::renderer::vkb {
|
namespace lt::renderer::vkb {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
export module renderer.backend.vk.swapchain;
|
export module renderer.vk.swapchain;
|
||||||
import renderer.backend.vk.library_wrapper;
|
import renderer.vk.api_wrapper;
|
||||||
import renderer.backend.vk.surface;
|
import renderer.vk.surface;
|
||||||
import renderer.backend.vk.device;
|
import renderer.vk.device;
|
||||||
import renderer.backend.vk.instance;
|
import renderer.vk.instance;
|
||||||
import renderer.backend.vk.gpu;
|
import renderer.vk.gpu;
|
||||||
import renderer.frontend;
|
import renderer.frontend;
|
||||||
import math.vec2;
|
import math.vec2;
|
||||||
import memory.null_on_move;
|
import memory.null_on_move;
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ private:
|
||||||
Timepoint m_start;
|
Timepoint m_start;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace lt
|
} // namespace lt::time
|
||||||
|
|
||||||
module :private;
|
module :private;
|
||||||
using namespace lt::time;
|
using namespace lt::time;
|
||||||
|
|
|
||||||
|
|
@ -310,6 +310,14 @@ export CXXFLAGS="\
|
||||||
-D CMAKE_INSTALL_PREFIX=/opt/llvm-msan \
|
-D CMAKE_INSTALL_PREFIX=/opt/llvm-msan \
|
||||||
&& ninja -C $build_path install
|
&& ninja -C $build_path install
|
||||||
|
|
||||||
|
|
||||||
|
# Cache debuginfo symbols downloaded when running valgrind
|
||||||
|
RUN \
|
||||||
|
git clone https://git.light7734.com/light7734/light.git --depth=1 \
|
||||||
|
&& cd ./light/tools/ci/amd64/gcc/ \
|
||||||
|
&& ./valgrind.sh
|
||||||
|
|
||||||
|
|
||||||
# && cmake \
|
# && cmake \
|
||||||
# -G Ninja \
|
# -G Ninja \
|
||||||
# -S $llvm/llvm \
|
# -S $llvm/llvm \
|
||||||
|
|
@ -335,52 +343,52 @@ export CXXFLAGS="\
|
||||||
# \
|
# \
|
||||||
# && ninja -C $build_clang
|
# && ninja -C $build_clang
|
||||||
|
|
||||||
RUN \
|
# RUN \
|
||||||
cd /mesa \
|
# cd /mesa \
|
||||||
&& export CXX='clang++' \
|
# && export CXX='clang++' \
|
||||||
&& export CC='clang' \
|
# && export CC='clang' \
|
||||||
&& export CFLAGS="-fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -g" \
|
# && export CFLAGS="-fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -g" \
|
||||||
&& export CXXFLAGS="-fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -g -nostdinc++ -isystem /libcxx_msan/include/c++/v1/" \
|
# && export CXXFLAGS="-fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -g -nostdinc++ -isystem /libcxx_msan/include/c++/v1/" \
|
||||||
&& export LDFLAGS="-fsanitize=memory -fsanitize-memory-track-origins -g -L/libcxx_msan/lib -Wl,-rpath,/libcxx_msan/lib -L/msan/lib -Wl,-rpath,/msan/lib -lc++ -lc++abi" \
|
# && export LDFLAGS="-fsanitize=memory -fsanitize-memory-track-origins -g -L/libcxx_msan/lib -Wl,-rpath,/libcxx_msan/lib -L/msan/lib -Wl,-rpath,/msan/lib -lc++ -lc++abi" \
|
||||||
&& export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH" \
|
# && export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH" \
|
||||||
&& meson setup ./ _build \
|
# && meson setup ./ _build \
|
||||||
-D build-tests=false \
|
# -D build-tests=false \
|
||||||
-D enable-glcpp-tests=false \
|
# -D enable-glcpp-tests=false \
|
||||||
-D build-radv-tests=false \
|
# -D build-radv-tests=false \
|
||||||
-D build-aco-tests=false \
|
# -D build-aco-tests=false \
|
||||||
-D install-intel-gpu-tests=false \
|
# -D install-intel-gpu-tests=false \
|
||||||
-D gallium-mediafoundation-test=false \
|
# -D gallium-mediafoundation-test=false \
|
||||||
-D android-libbacktrace=disabled \
|
# -D android-libbacktrace=disabled \
|
||||||
-D split-debug=disabled \
|
# -D split-debug=disabled \
|
||||||
-D b_ndebug=true \
|
# -D b_ndebug=true \
|
||||||
-D b_lto=false \
|
# -D b_lto=false \
|
||||||
-D egl=enabled \
|
# -D egl=enabled \
|
||||||
-D gallium-drivers=r300,r600,radeonsi,nouveau,virgl,svga,softpipe,llvmpipe,i915,iris,crocus,zink \
|
# -D gallium-drivers=r300,r600,radeonsi,nouveau,virgl,svga,softpipe,llvmpipe,i915,iris,crocus,zink \
|
||||||
-D gallium-extra-hud=true \
|
# -D gallium-extra-hud=true \
|
||||||
-D gallium-rusticl=true \
|
# -D gallium-rusticl=true \
|
||||||
-D gallium-va=enabled \
|
# -D gallium-va=enabled \
|
||||||
-D gbm=enabled \
|
# -D gbm=enabled \
|
||||||
-D gles1=disabled \
|
# -D gles1=disabled \
|
||||||
-D gles2=enabled \
|
# -D gles2=enabled \
|
||||||
-D glvnd=enabled \
|
# -D glvnd=enabled \
|
||||||
-D glx=dri \
|
# -D glx=dri \
|
||||||
-D libunwind=enabled \
|
# -D libunwind=enabled \
|
||||||
-D llvm=enabled \
|
# -D llvm=enabled \
|
||||||
-D lmsensors=disabled \
|
# -D lmsensors=disabled \
|
||||||
-D microsoft-clc=disabled \
|
# -D microsoft-clc=disabled \
|
||||||
-D platforms=x11,wayland \
|
# -D platforms=x11,wayland \
|
||||||
-D valgrind=disabled \
|
# -D valgrind=disabled \
|
||||||
-D video-codecs=all \
|
# -D video-codecs=all \
|
||||||
-D vulkan-drivers=amd,intel,intel_hasvk,swrast,virtio,nouveau \
|
# -D vulkan-drivers=amd,intel,intel_hasvk,swrast,virtio,nouveau \
|
||||||
-D vulkan-layers=device-select,intel-nullhw,overlay \
|
# -D vulkan-layers=device-select,intel-nullhw,overlay \
|
||||||
-D tools='' \
|
# -D tools='' \
|
||||||
-D zstd=enabled \
|
# -D zstd=enabled \
|
||||||
-D buildtype=plain \
|
# -D buildtype=plain \
|
||||||
-D prefix=/usr \
|
# -D prefix=/usr \
|
||||||
-D sysconfdir=/etc \
|
# -D sysconfdir=/etc \
|
||||||
--wrap-mode=nofallback \
|
# --wrap-mode=nofallback \
|
||||||
--force-fallback-for=syn,paste,rustc-hash \
|
# --force-fallback-for=syn,paste,rustc-hash \
|
||||||
&& ninja -C _build
|
# && ninja -C _build
|
||||||
|
|
||||||
# RUN cd mesa/ \
|
# RUN cd mesa/ \
|
||||||
# && source '/1.4.328.1/setup-env.sh' \
|
# && source '/1.4.328.1/setup-env.sh' \
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,55 @@
|
||||||
function(add_library_module libname)
|
function(add_library_module)
|
||||||
set(PUBLIC_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/public_includes")
|
cmake_parse_arguments(
|
||||||
file(MAKE_DIRECTORY "${PUBLIC_INCLUDE_DIR}")
|
ARGS
|
||||||
file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/public/"
|
""
|
||||||
"${PUBLIC_INCLUDE_DIR}/${libname}" SYMBOLIC)
|
"NAME"
|
||||||
|
"INTERFACES;ROOT_DIR;PRIVATE_INTERFACES;SOURCES;DEPENDENCIES;PRIVATE_DEPENDENCIES"
|
||||||
|
${ARGN}
|
||||||
|
)
|
||||||
|
|
||||||
if("${ARGN}" STREQUAL "") # Header only library
|
if(NOT ARGS_NAME)
|
||||||
message("Adding INTERFACE library ${libname}")
|
message(FATAL_ERROR "You must provide a name")
|
||||||
add_library(${libname} INTERFACE)
|
|
||||||
target_include_directories(${libname} INTERFACE ${PUBLIC_INCLUDE_DIR})
|
|
||||||
|
|
||||||
target_link_libraries(${libname} INTERFACE std)
|
|
||||||
|
|
||||||
else() # Compiled library
|
|
||||||
set(source_files)
|
|
||||||
set(source_directory "${CMAKE_CURRENT_SOURCE_DIR}/private")
|
|
||||||
foreach(source_file ${ARGN})
|
|
||||||
list(APPEND source_files "${source_directory}/${source_file}")
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
message("Adding library ${libname} with source files: ${source_files}")
|
|
||||||
add_library(${libname} ${source_files})
|
|
||||||
|
|
||||||
set(PRIVATE_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/private_includes")
|
|
||||||
file(MAKE_DIRECTORY "${PRIVATE_INCLUDE_DIR}")
|
|
||||||
file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/private/"
|
|
||||||
"${PRIVATE_INCLUDE_DIR}/${libname}" SYMBOLIC)
|
|
||||||
|
|
||||||
target_include_directories(
|
|
||||||
${libname}
|
|
||||||
PUBLIC ${PUBLIC_INCLUDE_DIR}
|
|
||||||
PRIVATE ${PRIVATE_INCLUDE_DIR})
|
|
||||||
|
|
||||||
target_link_libraries(${libname} PUBLIC std)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_library(${ARGS_NAME})
|
||||||
|
|
||||||
|
set(module_directory "${CMAKE_CURRENT_SOURCE_DIR}/${ARGS_NAME}")
|
||||||
|
if(ARGS_ROOT_DIR)
|
||||||
|
set(module_directory "${ARGS_ROOT_DIR}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ARGS_SOURCES)
|
||||||
|
set(files)
|
||||||
|
foreach(file ${ARGS_SOURCES})
|
||||||
|
list(APPEND files "${module_directory}/${file}")
|
||||||
|
endforeach()
|
||||||
|
target_sources(${ARGS_NAME} PRIVATE ${files})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ARGS_INTERFACES)
|
||||||
|
set(files)
|
||||||
|
foreach(file ${ARGS_INTERFACES})
|
||||||
|
list(APPEND files "${module_directory}/${file}")
|
||||||
|
endforeach()
|
||||||
|
target_sources(
|
||||||
|
${ARGS_NAME} PUBLIC FILE_SET public_cxx_modules TYPE CXX_MODULES
|
||||||
|
FILES ${files}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ARGS_PRIVATE_INTERFACES)
|
||||||
|
set(files)
|
||||||
|
foreach(file ${ARGS_PRIVATE_INTERFACES})
|
||||||
|
list(APPEND files "${module_directory}/${file}")
|
||||||
|
endforeach()
|
||||||
|
target_sources(
|
||||||
|
${ARGS_NAME} PRIVATE FILE_SET private_cxx_modules TYPE CXX_MODULES
|
||||||
|
FILES ${files}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(${ARGS_NAME} PUBLIC ${ARGS_DEPENDENCIES})
|
||||||
|
target_link_libraries(${ARGS_NAME} PRIVATE ${ARGS_PRIVATE_DEPENDENCIES})
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(add_executable_module exename)
|
function(add_executable_module exename)
|
||||||
|
|
@ -48,22 +64,28 @@ function(add_executable_module exename)
|
||||||
set(PUBLIC_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/public_includes")
|
set(PUBLIC_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/public_includes")
|
||||||
file(MAKE_DIRECTORY "${PUBLIC_INCLUDE_DIR}")
|
file(MAKE_DIRECTORY "${PUBLIC_INCLUDE_DIR}")
|
||||||
file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/public/"
|
file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/public/"
|
||||||
"${PUBLIC_INCLUDE_DIR}/${exename}" SYMBOLIC)
|
"${PUBLIC_INCLUDE_DIR}/${exename}" SYMBOLIC
|
||||||
|
)
|
||||||
set(PRIVATE_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/private_includes")
|
set(PRIVATE_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/private_includes")
|
||||||
file(MAKE_DIRECTORY "${PRIVATE_INCLUDE_DIR}")
|
file(MAKE_DIRECTORY "${PRIVATE_INCLUDE_DIR}")
|
||||||
file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/private/"
|
file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/private/"
|
||||||
"${PRIVATE_INCLUDE_DIR}${exename}" SYMBOLIC)
|
"${PRIVATE_INCLUDE_DIR}${exename}" SYMBOLIC
|
||||||
|
)
|
||||||
|
|
||||||
add_executable(${exename} ${source_files})
|
|
||||||
target_link_libraries(${exename} PRIVATE std)
|
|
||||||
target_include_directories(${exename} PRIVATE ${PUBLIC_INCLUDE_DIR}
|
|
||||||
${PRIVATE_INCLUDE_DIR})
|
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(add_test_module target_lib_name)
|
function(add_test_module target_lib_name)
|
||||||
if(NOT ${ENABLE_UNIT_TESTS})
|
# if(NOT ${ENABLE_UNIT_TESTS}) return() endif()
|
||||||
return()
|
|
||||||
endif()
|
add_executable(${target_lib_name}_tests ${ARGN})
|
||||||
|
target_link_libraries(
|
||||||
|
${target_lib_name}_tests
|
||||||
|
PRIVATE ${target_lib_name}
|
||||||
|
#
|
||||||
|
test
|
||||||
|
)
|
||||||
|
|
||||||
|
return()
|
||||||
|
|
||||||
set(source_files)
|
set(source_files)
|
||||||
set(source_directory "${CMAKE_CURRENT_SOURCE_DIR}/private")
|
set(source_directory "${CMAKE_CURRENT_SOURCE_DIR}/private")
|
||||||
|
|
@ -78,19 +100,23 @@ function(add_test_module target_lib_name)
|
||||||
set(PUBLIC_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/public_includes")
|
set(PUBLIC_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/public_includes")
|
||||||
file(MAKE_DIRECTORY "${PUBLIC_INCLUDE_DIR}")
|
file(MAKE_DIRECTORY "${PUBLIC_INCLUDE_DIR}")
|
||||||
file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/public/"
|
file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/public/"
|
||||||
"${PUBLIC_INCLUDE_DIR}/${target_lib_name}" SYMBOLIC)
|
"${PUBLIC_INCLUDE_DIR}/${target_lib_name}" SYMBOLIC
|
||||||
|
)
|
||||||
set(PRIVATE_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/private_includes")
|
set(PRIVATE_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/private_includes")
|
||||||
file(MAKE_DIRECTORY "${PRIVATE_INCLUDE_DIR}")
|
file(MAKE_DIRECTORY "${PRIVATE_INCLUDE_DIR}")
|
||||||
file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/private/"
|
file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/private/"
|
||||||
"${PRIVATE_INCLUDE_DIR}/${target_lib_name}" SYMBOLIC)
|
"${PRIVATE_INCLUDE_DIR}/${target_lib_name}" SYMBOLIC
|
||||||
|
)
|
||||||
|
|
||||||
add_executable(${target_lib_name}_tests ${source_files})
|
add_executable(${target_lib_name}_tests ${source_files})
|
||||||
target_link_libraries(${target_lib_name}_tests PRIVATE ${target_lib_name}
|
target_link_libraries(
|
||||||
std test)
|
${target_lib_name}_tests PRIVATE ${target_lib_name} std test
|
||||||
|
)
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
${target_lib_name}_tests
|
${target_lib_name}_tests
|
||||||
PRIVATE ${PUBLIC_INCLUDE_DIR}
|
PRIVATE ${PUBLIC_INCLUDE_DIR}
|
||||||
PRIVATE ${PRIVATE_INCLUDE_DIR})
|
PRIVATE ${PRIVATE_INCLUDE_DIR}
|
||||||
|
)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(add_fuzz_module target_lib_name)
|
function(add_fuzz_module target_lib_name)
|
||||||
|
|
@ -111,21 +137,25 @@ function(add_fuzz_module target_lib_name)
|
||||||
set(PUBLIC_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/public_includes")
|
set(PUBLIC_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/public_includes")
|
||||||
file(MAKE_DIRECTORY "${PUBLIC_INCLUDE_DIR}")
|
file(MAKE_DIRECTORY "${PUBLIC_INCLUDE_DIR}")
|
||||||
file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/public/"
|
file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/public/"
|
||||||
"${PUBLIC_INCLUDE_DIR}/${target_lib_name}" SYMBOLIC)
|
"${PUBLIC_INCLUDE_DIR}/${target_lib_name}" SYMBOLIC
|
||||||
|
)
|
||||||
set(PRIVATE_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/private_includes")
|
set(PRIVATE_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/private_includes")
|
||||||
file(MAKE_DIRECTORY "${PRIVATE_INCLUDE_DIR}")
|
file(MAKE_DIRECTORY "${PRIVATE_INCLUDE_DIR}")
|
||||||
file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/private/"
|
file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/private/"
|
||||||
"${PRIVATE_INCLUDE_DIR}/${target_lib_name}" SYMBOLIC)
|
"${PRIVATE_INCLUDE_DIR}/${target_lib_name}" SYMBOLIC
|
||||||
|
)
|
||||||
|
|
||||||
add_executable(${target_lib_name}_fuzz ${source_files})
|
add_executable(${target_lib_name}_fuzz ${source_files})
|
||||||
target_link_libraries(${target_lib_name}_fuzz PRIVATE ${target_lib_name}
|
target_link_libraries(
|
||||||
std fuzz_test)
|
${target_lib_name}_fuzz PRIVATE ${target_lib_name} std fuzz_test
|
||||||
|
)
|
||||||
target_link_options(${target_lib_name}_fuzz PRIVATE -fsanitize=fuzzer)
|
target_link_options(${target_lib_name}_fuzz PRIVATE -fsanitize=fuzzer)
|
||||||
target_compile_options(${target_lib_name}_fuzz PRIVATE -fsanitize=fuzzer)
|
target_compile_options(${target_lib_name}_fuzz PRIVATE -fsanitize=fuzzer)
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
${target_lib_name}_fuzz
|
${target_lib_name}_fuzz
|
||||||
PRIVATE ${PUBLIC_INCLUDE_DIR}
|
PRIVATE ${PUBLIC_INCLUDE_DIR}
|
||||||
PRIVATE ${PRIVATE_INCLUDE_DIR})
|
PRIVATE ${PRIVATE_INCLUDE_DIR}
|
||||||
|
)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(add_option option help)
|
function(add_option option help)
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,17 @@
|
||||||
add_option(ENABLE_UNIT_TESTS "Enables the building of the unit test modules")
|
add_option(ENABLE_UNIT_TESTS "Enables the building of the unit test modules")
|
||||||
add_option(ENABLE_FUZZ_TESTS "Enables the building of the fuzz test modules")
|
add_option(ENABLE_FUZZ_TESTS "Enables the building of the fuzz test modules")
|
||||||
add_option(ENABLE_STATIC_ANALYSIS
|
add_option(
|
||||||
"Makes the clang-tidy checks mandatory for compilation")
|
ENABLE_STATIC_ANALYSIS
|
||||||
add_option(ENABLE_LLVM_COVERAGE
|
"Makes the clang-tidy checks mandatory for compilation"
|
||||||
"Enables the code coverage instrumentation for clang")
|
)
|
||||||
|
add_option(
|
||||||
|
ENABLE_LLVM_COVERAGE "Enables the code coverage instrumentation for clang"
|
||||||
|
)
|
||||||
|
|
||||||
if(ENABLE_STATIC_ANALYSIS)
|
if(ENABLE_STATIC_ANALYSIS)
|
||||||
set(CMAKE_CXX_CLANG_TIDY
|
set(CMAKE_CXX_CLANG_TIDY
|
||||||
"clang-tidy;--warnings-as-errors=*;--allow-no-checks")
|
"clang-tidy;--warnings-as-errors=*;--allow-no-checks"
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(ENABLE_LLVM_COVERAGE)
|
if(ENABLE_LLVM_COVERAGE)
|
||||||
|
|
@ -15,7 +19,8 @@ if(ENABLE_LLVM_COVERAGE)
|
||||||
|
|
||||||
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||||
message(
|
message(
|
||||||
FATAL_ERROR "ENABLE_LLVM_COVERAGE only supports the clang compiler")
|
FATAL_ERROR "ENABLE_LLVM_COVERAGE only supports the clang compiler"
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Check for libc++
|
# Check for libc++
|
||||||
|
|
@ -28,7 +33,8 @@ if(ENABLE_LLVM_COVERAGE)
|
||||||
#error Not using libc++
|
#error Not using libc++
|
||||||
#endif
|
#endif
|
||||||
"
|
"
|
||||||
USING_LIBCXX)
|
USING_LIBCXX
|
||||||
|
)
|
||||||
if(NOT USING_LIBCXX)
|
if(NOT USING_LIBCXX)
|
||||||
message(
|
message(
|
||||||
FATAL_ERROR
|
FATAL_ERROR
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue