This commit is contained in:
xsl
2025-09-04 10:54:47 +08:00
commit 6bc8f61b18
1808 changed files with 208268 additions and 0 deletions
+77
View File
@@ -0,0 +1,77 @@
# Copyright (c) 2023-2025, Thomas Atkinson
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 the "License";
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
vkb__register_component(
NAME core
HEADERS
include/core/platform/context.hpp
include/core/platform/entrypoint.hpp
include/core/util/strings.hpp
include/core/util/error.hpp
include/core/util/hash.hpp
include/core/util/logging.hpp
include/core/util/profiling.hpp
SRC
src/strings.cpp
src/logging.cpp
src/profiling.cpp
LINK_LIBS
spdlog::spdlog
)
if (VKB_PROFILING)
target_link_libraries(vkb__core PUBLIC TracyClient)
target_compile_definitions(vkb__core PUBLIC TRACY_ENABLE)
endif()
if(ANDROID)
target_compile_definitions(vkb__core PUBLIC VK_USE_PLATFORM_ANDROID_KHR PLATFORM__ANDROID)
elseif(WIN32)
target_compile_definitions(vkb__core PUBLIC VK_USE_PLATFORM_WIN32_KHR PLATFORM__WINDOWS)
elseif(APPLE)
target_compile_definitions(vkb__core PUBLIC VK_USE_PLATFORM_METAL_EXT PLATFORM__MACOS)
elseif(UNIX)
target_compile_definitions(vkb__core PUBLIC PLATFORM__LINUX)
# Choose WSI based on VKB_WSI_SELECTION
if (VKB_WSI_SELECTION STREQUAL XCB OR VKB_WSI_SELECTION STREQUAL XLIB OR VKB_WSI_SELECTION STREQUAL WAYLAND)
find_package(PkgConfig REQUIRED)
endif()
if (VKB_WSI_SELECTION STREQUAL XCB)
pkg_check_modules(XCB xcb REQUIRED)
if (XCB_FOUND)
target_compile_definitions(vkb__core PUBLIC VK_USE_PLATFORM_XCB_KHR)
endif()
elseif (VKB_WSI_SELECTION STREQUAL XLIB)
pkg_check_modules(X11 x11 REQUIRED)
if (X11_FOUND)
target_compile_definitions(vkb__core PUBLIC VK_USE_PLATFORM_XLIB_KHR)
endif()
elseif (VKB_WSI_SELECTION STREQUAL WAYLAND)
pkg_check_modules(WAYLAND wayland-client REQUIRED)
if (WAYLAND_FOUND)
target_compile_definitions(vkb__core PUBLIC VK_USE_PLATFORM_WAYLAND_KHR)
endif()
elseif (VKB_WSI_SELECTION STREQUAL D2D)
set(DIRECT_TO_DISPLAY TRUE)
set(DIRECT_TO_DISPLAY TRUE PARENT_SCOPE)
target_compile_definitions(vkb__core PUBLIC VK_USE_PLATFORM_DISPLAY_KHR PLATFORM__LINUX_D2D)
else()
message(FATAL_ERROR "Unknown WSI")
endif()
endif()
+61
View File
@@ -0,0 +1,61 @@
////
- Copyright (c) 2023, Thomas Atkinson
-
- SPDX-License-Identifier: Apache-2.0
-
- Licensed under the Apache License, Version 2.0 the "License";
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
////
= Core
Core is a collection of pure interfaces or small utilities which are used across the project.
The core component is the only component which does not follow the component pattern in its entirety.
The only major difference between core and other components is the header prefix used is `core/<sub_dir>` instead of `components/core/<sub_dir>`.
== Platform
A Platform is the name we have given to the physical hardware and operating system that the project is executing on.
We support multiple platforms which can be identified by the following defines
* `PLATFORM__ANDROID`
* `PLATFORM__WINDOWS`
* `PLATFORM__LINUX_D2D`
* `PLATFORM__LINUX`
* `PLATFORM__MACOS`
Using these platforms should be as transparent as possible to a sample.
Components on the other hand may add platform specific code paths if required.
An application can create a cross platform entrypoint by using the `CUSTOM_MAIN(context_name)` macro
[,cpp]
----
#include <core/platform/entrypoint.hpp>
CUSTOM_MAIN(context)
{
context.arguments();
context.external_storage_directory();
context.temp_directory();
// Components using platform specific contexts
FileSystem fs = FileSystem::from_context(context);
}
----
== Utilities
* Error - A collection of error handling macros
* Hash - A collection of hashing functions
* Strings - A collection of string utilities
@@ -0,0 +1,71 @@
/* Copyright (c) 2023, Thomas Atkinson
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <memory>
#include <string>
#include <vector>
namespace vkb
{
class UnixPlatformContext;
class WindowsPlatformContext;
class AndroidPlatformContext;
/**
* @brief A platform context contains abstract platform specific operations
*
* A platform can be thought as the physical device and operating system configuration that the application
* is running on.
*
* Some platforms can be reused across different hardware configurations, such as Linux and Macos as both
* are POSIX compliant. However, some platforms are more specific such as Android and Windows
*/
class PlatformContext
{
// only allow platform contexts to be created by the platform specific implementations
friend class UnixPlatformContext;
friend class WindowsPlatformContext;
friend class AndroidPlatformContext;
public:
virtual ~PlatformContext() = default;
virtual const std::vector<std::string> &arguments() const
{
return _arguments;
}
virtual const std::string &external_storage_directory() const
{
return _external_storage_directory;
}
virtual const std::string &temp_directory() const
{
return _temp_directory;
}
protected:
std::vector<std::string> _arguments;
std::string _external_storage_directory;
std::string _temp_directory;
PlatformContext() = default;
};
} // namespace vkb
@@ -0,0 +1,74 @@
/* Copyright (c) 2023-2024, Thomas Atkinson
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "core/platform/context.hpp"
// Platform specific entrypoint definitions
// Applications should use CUSTOM_MAIN to define their own main function
// Definitions added by core/CMakeLists.txt
#if defined(PLATFORM__MACOS)
#include <TargetConditionals.h>
#endif
#if defined(PLATFORM__ANDROID)
# include <game-activity/native_app_glue/android_native_app_glue.h>
extern std::unique_ptr<vkb::PlatformContext> create_platform_context(android_app *state);
# define CUSTOM_MAIN(context_name) \
int platform_main(const vkb::PlatformContext &); \
void android_main(android_app *state) \
{ \
auto context = create_platform_context(state); \
platform_main(*context); \
} \
int platform_main(const vkb::PlatformContext &context_name)
#elif defined(PLATFORM__WINDOWS)
# include <Windows.h>
extern std::unique_ptr<vkb::PlatformContext> create_platform_context(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow);
# define CUSTOM_MAIN(context_name) \
int platform_main(const vkb::PlatformContext &); \
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow) \
{ \
auto context = create_platform_context(hInstance, hPrevInstance, lpCmdLine, nCmdShow); \
return platform_main(*context); \
} \
int platform_main(const vkb::PlatformContext &context_name)
#elif defined(PLATFORM__LINUX) || defined(PLATFORM__MACOS)
extern std::unique_ptr<vkb::PlatformContext> create_platform_context(int argc, char **argv);
# define CUSTOM_MAIN(context_name) \
int platform_main(const vkb::PlatformContext &); \
int main(int argc, char *argv[]) \
{ \
auto context = create_platform_context(argc, argv); \
return platform_main(*context); \
} \
int platform_main(const vkb::PlatformContext &context_name)
#else
# include <stdexcept>
# define CUSTOM_MAIN(context_name) \
int main(int argc, char *argv[]) \
{ \
throw std::runtime_error{"platform not supported"}; \
} \
int unused(const vkb::PlatformContext &context_name)
#endif
@@ -0,0 +1,69 @@
/* Copyright (c) 2023-2025, Thomas Atkinson
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER)
# define __GCC__ __GNUC__
#endif
#if defined(__clang__)
// CLANG ENABLE/DISABLE WARNING DEFINITION
# define VKBP_DISABLE_WARNINGS() \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wall\"") \
_Pragma("clang diagnostic ignored \"-Wextra\"") \
_Pragma("clang diagnostic ignored \"-Wtautological-compare\"") \
_Pragma("clang diagnostic ignored \"-Wnullability-completeness\"")
# define VKBP_ENABLE_WARNINGS() \
_Pragma("clang diagnostic pop")
#elif defined(__GNUC__) || defined(__GNUG__)
// GCC ENABLE/DISABLE WARNING DEFINITION
# define VKBP_DISABLE_WARNINGS() \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wall\"") \
_Pragma("GCC diagnostic ignored \"-Wextra\"") \
_Pragma("GCC diagnostic ignored \"-Wtautological-compare\"")
# define VKBP_ENABLE_WARNINGS() \
_Pragma("GCC diagnostic pop")
#elif defined(_MSC_VER)
// MSVC ENABLE/DISABLE WARNING DEFINITION
# define VKBP_DISABLE_WARNINGS() \
__pragma(warning(push, 0))
# define VKBP_ENABLE_WARNINGS() \
__pragma(warning(pop))
#endif
// TODO: replace with a direct fmt submodule
#include <fmt/format.h>
#include <stdexcept>
template <typename... Args>
inline void ERRORF(const std::string &format, Args &&...args)
{
throw std::runtime_error(fmt::vformat(format, fmt::make_format_args(args...)));
}
inline void ERRORF(const std::string &message)
{
throw std::runtime_error(message);
}
#define NOT_IMPLEMENTED() ERRORF("not implemented")
@@ -0,0 +1,41 @@
/* Copyright (c) 2023, Thomas Atkinson
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <functional>
namespace vkb
{
inline void hash_combine(size_t &seed, size_t hash)
{
hash += 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= hash;
}
/**
* @brief Helper function to combine a given hash
* with a generated hash for the input param.
*/
template <class T>
inline void hash_combine(size_t &seed, const T &v)
{
std::hash<T> hasher;
hash_combine(seed, hasher(v));
}
} // namespace vkb
@@ -0,0 +1,37 @@
/* Copyright (c) 2018-2024, Arm Limited and Contributors
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <spdlog/fmt/fmt.h>
#include <spdlog/spdlog.h>
#define LOGGER_FORMAT "[%^%l%$] %v"
#define PROJECT_NAME "VulkanSamples"
#define LOGI(...) spdlog::info(__VA_ARGS__);
#define LOGW(...) spdlog::warn(__VA_ARGS__);
#define LOGE(...) spdlog::error("{}", fmt::format(__VA_ARGS__));
#define LOGD(...) spdlog::debug(__VA_ARGS__);
namespace vkb
{
namespace logging
{
void init();
}
} // namespace vkb
@@ -0,0 +1,130 @@
/* Copyright (c) 2023-2024, Thomas Atkinson
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <cstdint>
#include <cstdio>
#include <unordered_map>
#include "core/util/error.hpp"
#ifdef TRACY_ENABLE
# include <tracy/Tracy.hpp>
#endif
#ifdef TRACY_ENABLE
// malloc and free are used by Tracy to provide memory profiling
void *operator new(size_t count);
void operator delete(void *ptr) noexcept;
// Tracy a scope
# define PROFILE_SCOPE(name) ZoneScopedN(name)
// Trace a function
# define PROFILE_FUNCTION() ZoneScoped
#else
# define PROFILE_SCOPE(name)
# define PROFILE_FUNCTION()
#endif
// The type of plot to use
enum class PlotType
{
Number,
Percentage,
Memory,
};
// tracy::PlotFormatType is not defined if TRACY_ENABLE is not defined
// so we need to define a function to convert our enum to the tracy enum
#ifdef TRACY_ENABLE
namespace
{
inline tracy::PlotFormatType to_tracy_plot_format(PlotType type)
{
switch (type)
{
case PlotType::Number:
return tracy::PlotFormatType::Number;
case PlotType::Percentage:
return tracy::PlotFormatType::Percentage;
case PlotType::Memory:
return tracy::PlotFormatType::Memory;
default:
return tracy::PlotFormatType::Number;
}
}
} // namespace
# define TO_TRACY_PLOT_FORMAT(name) to_tracy_plot_format(name)
#else
# define TO_TRACY_PLOT_FORMAT(name)
#endif
// Create plots
template <typename T, PlotType PT = PlotType::Number>
class Plot
{
public:
static void plot(const char *name, T value)
{
auto *p = get_instance();
p->plots[name] = value;
update_tracy_plot(name, value);
}
static void increment(const char *name, T amount)
{
auto *p = get_instance();
p->plots[name] += amount;
update_tracy_plot(name, p->plots[name]);
}
static void decrement(const char *name, T amount)
{
auto *p = get_instance();
p->plots[name] -= amount;
update_tracy_plot(name, p->plots[name]);
}
static void reset(const char *name)
{
auto *p = get_instance();
p->plots[name] = T{};
update_tracy_plot(name, p->plots[name]);
}
private:
static void update_tracy_plot(const char *name, T value)
{
#ifdef TRACY_ENABLE
TracyPlot(name, value);
TracyPlotConfig(name, TO_TRACY_PLOT_FORMAT(PT), true, true, 0);
#endif
}
static Plot *get_instance()
{
static_assert((std::is_same<T, int64_t>::value || std::is_same<T, double>::value || std::is_same<T, float>::value), "PlotStore only supports int64_t, double and float");
static Plot instance;
return &instance;
}
std::unordered_map<const char *, T> plots;
};
@@ -0,0 +1,38 @@
/* Copyright (c) 2023, Thomas Atkinson
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <string>
namespace vkb
{
/**
* @brief Replaces all occurrences of a substring with another substring.
*/
std::string replace_all(std::string str, const std::string &from, const std::string &to);
/**
* @brief Removes all occurrences of a set of characters from the end of a string.
*/
std::string trim_right(const std::string &str, const std::string &chars = " ");
/**
* @brief Removes all occurrences of a set of characters from the beginning of a string.
*/
std::string trim_left(const std::string &str, const std::string &chars = " ");
} // namespace vkb
+52
View File
@@ -0,0 +1,52 @@
/* Copyright (c) 2024, Thomas Atkinson
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "core/util/logging.hpp"
#include "spdlog/cfg/env.h"
#ifdef PLATFORM__ANDROID
# include "spdlog/sinks/android_sink.h"
#else
# include "spdlog/sinks/stdout_color_sinks.h"
#endif
namespace vkb
{
namespace logging
{
void init()
{
// Taken from "spdlog/cfg/env.h" and renamed SPDLOG_LEVEL to VKB_LOG_LEVEL
auto env_val = spdlog::details::os::getenv("VKB_LOG_LEVEL");
if (!env_val.empty())
{
spdlog::cfg::helpers::load_levels(env_val);
}
#ifdef PLATFORM__ANDROID
auto logger = spdlog::android_logger_mt("vkb", "VulkanSamples");
#else
auto logger = spdlog::stdout_color_mt("vkb");
#endif
logger->set_pattern(LOGGER_FORMAT);
logger->set_level(spdlog::level::trace);
spdlog::set_default_logger(logger);
}
} // namespace logging
} // namespace vkb
+35
View File
@@ -0,0 +1,35 @@
/* Copyright (c) 2023-2024, Thomas Atkinson
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "core/util/profiling.hpp"
#include <cstdlib>
#ifdef TRACY_ENABLE
void *operator new(size_t count)
{
auto ptr = malloc(count);
TracyAlloc(ptr, count);
return ptr;
}
void operator delete(void *ptr) noexcept
{
TracyFree(ptr);
free(ptr);
}
#endif
+46
View File
@@ -0,0 +1,46 @@
/* Copyright (c) 2023, Thomas Atkinson
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <core/util/strings.hpp>
namespace vkb
{
std::string replace_all(std::string str, const std::string &from, const std::string &to)
{
size_t start_pos = 0;
while ((start_pos = str.find(from, start_pos)) != std::string::npos)
{
str.replace(start_pos, from.length(), to);
start_pos += to.length() - 1;
}
return str;
}
std::string trim_right(const std::string &str, const std::string &chars)
{
std::string result = str;
result.erase(str.find_last_not_of(chars) + 1);
return result;
}
std::string trim_left(const std::string &str, const std::string &chars)
{
std::string result = str;
result.erase(0, str.find_first_not_of(chars));
return result;
}
} // namespace vkb