Skip to content

Commit

Permalink
Add WSL2 support, code improvements, bug fixes, refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
cfnptr committed Oct 5, 2024
1 parent 3f970a6 commit 31fd2b9
Show file tree
Hide file tree
Showing 16 changed files with 124 additions and 44 deletions.
8 changes: 4 additions & 4 deletions BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
## Operating Systems

* [Window (10/11)](BUILDING.md#windows-1011)
* [Ubuntu (22.04 LTS)](BUILDING.md#ubuntu-2204-lts)
* [macOS (Ventura 13)](BUILDING.md#macos-ventura-13)
* [Ubuntu (22.04/24.04)](BUILDING.md#ubuntu-22042404)
* [macOS (14/15)](BUILDING.md#macos-1415)
* [Build Project](BUILDING.md#build-project)

# Windows (10/11)
Expand Down Expand Up @@ -46,7 +46,7 @@ Better to choose C:\vcpkg path. Don't forget to add **vcpkg** to the System Envi

1. Run ```vcpkg install zlib:x64-windows-static openssl:x64-windows-static``` using **Terminal** or **CMD** app

# Ubuntu (22.04 LTS)
# Ubuntu (22.04/24.04)

## 1. Install Visual Studio Code (Or any other IDE)

Expand All @@ -65,7 +65,7 @@ Better to choose C:\vcpkg path. Don't forget to add **vcpkg** to the System Envi
Use "Ubuntu Packages" tab and "Latest Supported Release" instructions for that.


# macOS (Ventura 13)
# macOS (14/15)

## 1. Install Xcode (Or any other IDE)

Expand Down
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ extensible architecture, built-in editor, convenient creation of rendering pipel
shader language (GSL), and automatic placement of GPU memory barriers, which are necessary in recent
graphics APIs. See the [features](FEATURES.md) list.

See the [Voxfield](https://github.com/cfnptr/voxfield) game as an usage example.

## Supported operating systems

* Windows (10/11)
Expand Down
20 changes: 18 additions & 2 deletions include/garden/graphics/image.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class Image final : public Memory
SfloatR16G16B16A16, /**< 16-bit signed floating point (red, green, blue, alpha channel) format. */
SfloatR32G32B32A32, /**< 32-bit signed floating point (red, green, blue, alpha channel) format. */
UnormA2R10G10B10, /**< normalized uint as float (2-bit alpha, 10-bit red/green/blue channel) format. */
UnormA2B10G10R10, /**< normalized uint as float (2-bit alpha, 10-bit blue/green/red channel) format. */
UfloatB10G11R11, /**< Unsigned floating point (10-bit blue, 11-bit green, 10-bit red channel) format. */
UnormD16, /**< 16-bit normalized uint as float depth format. */
SfloatD32, /**< 32-bit signed floating point depth format. */
Expand Down Expand Up @@ -263,6 +264,19 @@ class Image final : public Memory
*/
bool hasDefaultView() const noexcept { return (bool)defaultView; }

/**
* @brief Returns true if specified image properties are supported by the GPU.
*
* @param type image dimensionality
* @param format image data format
* @param bind image bind type
* @param[in] size image size in pixels
* @param mipCount image mip level count
* @param layerCount image array layer count
*/
static bool isSupported(Type type, Format format, Bind bind,
const uint3& size, uint8 mipCount = 1, uint32 layerCount = 1);

#if GARDEN_DEBUG
/**
* @brief Sets image debug name. (Debug Only)
Expand Down Expand Up @@ -887,7 +901,9 @@ static psize toBinarySize(Image::Format imageFormat)
case Image::Format::SfloatR32G32: return 8;
case Image::Format::SfloatR16G16B16A16: return 8;
case Image::Format::SfloatR32G32B32A32: return 16;
case Image::Format::UnormA2R10G10B10: return 4;
case Image::Format::UnormA2R10G10B10:
case Image::Format::UnormA2B10G10R10:
return 4;
case Image::Format::UfloatB10G11R11: return 4;
case Image::Format::UnormD16: return 2;
case Image::Format::SfloatD32: return 4;
Expand Down Expand Up @@ -1009,7 +1025,7 @@ static const string_view imageFormatNames[(psize)Image::Format::Count] =
"Undefined", "UintR8", "UintR16", "UintR32",
"UnormR8", "UnormR8G8", "UnormR8G8B8A8", "UnormB8G8R8A8", "SrgbR8G8B8A8", "SrgbB8G8R8A8",
"SfloatR16G16", "SfloatR32G32", "SfloatR16G16B16A16", "SfloatR32G32B32A32",
"UnormA2R10G10B10", "UfloatB10G11R11",
"UnormA2R10G10B10", "UnormA2B10G10R10", "UfloatB10G11R11",
"UnormD16", "SfloatD32", "UnormD24UintS8", "SfloatD32Uint8S",
};

Expand Down
2 changes: 2 additions & 0 deletions include/garden/graphics/vulkan.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ static vk::Format toVkFormat(Image::Format formatType) noexcept
case Image::Format::SfloatR16G16B16A16: return vk::Format::eR16G16B16A16Sfloat;
case Image::Format::SfloatR32G32B32A32: return vk::Format::eR32G32B32A32Sfloat;
case Image::Format::UnormA2R10G10B10: return vk::Format::eA2R10G10B10UnormPack32;
case Image::Format::UnormA2B10G10R10: return vk::Format::eA2B10G10R10UnormPack32;
case Image::Format::UfloatB10G11R11: return vk::Format::eB10G11R11UfloatPack32;
case Image::Format::UnormD16: return vk::Format::eD16Unorm;
case Image::Format::SfloatD32: return vk::Format::eD32Sfloat;
Expand Down Expand Up @@ -151,6 +152,7 @@ static Image::Format toImageFormat(vk::Format formatType) noexcept
case vk::Format::eR16G16B16A16Sfloat: return Image::Format::SfloatR16G16B16A16;
case vk::Format::eR32G32B32A32Sfloat: return Image::Format::SfloatR32G32B32A32;
case vk::Format::eA2R10G10B10UnormPack32: return Image::Format::UnormA2R10G10B10;
case vk::Format::eA2B10G10R10UnormPack32: return Image::Format::UnormA2B10G10R10;
case vk::Format::eB10G11R11UfloatPack32: return Image::Format::UfloatB10G11R11;
case vk::Format::eD16Unorm: return Image::Format::UnormD16;
case vk::Format::eD32Sfloat: return Image::Format::SfloatD32;
Expand Down
2 changes: 1 addition & 1 deletion include/garden/main.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
* @brief Shows an OS error message with target C string.
* @param[in] cstr target error message C string
*/
#define GARDEN_MESSAGE_ERROR(cstr) MessageBoxA(NULL, cstr, "Error", MB_ICONERROR | MB_SYSTEMMODAL)
#define GARDEN_MESSAGE_ERROR(cstr) MessageBoxA(nullptr, cstr, "Error", MB_ICONERROR | MB_SYSTEMMODAL)
#else
/**
* @brief Declares application main function.
Expand Down
2 changes: 1 addition & 1 deletion include/garden/serialize.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ class DoNotSerializeSystem : public ComponentSystem<DoNotSerializeComponent, fal
/**
* @brief Destroys DoNotSerialize system instance.
*/
~DoNotSerializeSystem() final;
~DoNotSerializeSystem() override;

const string& getComponentName() const override;
friend class ecsm::Manager;
Expand Down
2 changes: 1 addition & 1 deletion include/garden/system/render/deferred.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
*
* G-Buffer structure:
* 0. SrgbR8G8B8A8 (Base Color, Metallic)
* 1. UnormR10G10B10A2 (Encoded Normal, Reflectance)
* 1. UnormA2B10G10R10 (Encoded Normal, Reflectance)
* 2. UnormR8G8B8A8 (Emissive, Roughness)
*/

Expand Down
2 changes: 1 addition & 1 deletion libraries/ecsm
Submodule ecsm updated 1 files
+2 −2 include/ecsm.hpp
2 changes: 1 addition & 1 deletion source/editor/system/render/deferred.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ void DeferredRenderEditorSystem::deferredRender()
{
if (drawMode != DrawMode::Lighting)
return;
return;

if (!lightingPipeline)
{
auto deferredSystem = DeferredRenderSystem::Instance::get();
Expand Down
34 changes: 34 additions & 0 deletions source/graphics/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,22 @@ Image::Image(Type type, Format format, Bind bind, Strategy strategy,

if (type == Type::Cubemap)
imageInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;

#if GARDEN_DEBUG
vk::PhysicalDeviceImageFormatInfo2 imageFormatInfo;
imageFormatInfo.format = vk::Format(imageInfo.format);
imageFormatInfo.type = vk::ImageType(imageInfo.imageType);
imageFormatInfo.tiling = vk::ImageTiling(imageInfo.tiling);
imageFormatInfo.usage = vk::ImageUsageFlags(imageInfo.usage);
imageFormatInfo.flags = vk::ImageCreateFlags(imageInfo.flags);
auto imageFormatProperties = Vulkan::physicalDevice.getImageFormatProperties2(imageFormatInfo);
GARDEN_ASSERT(size.x <= imageFormatProperties.imageFormatProperties.maxExtent.width);
GARDEN_ASSERT(size.y <= imageFormatProperties.imageFormatProperties.maxExtent.height);
GARDEN_ASSERT(size.z <= imageFormatProperties.imageFormatProperties.maxExtent.depth);
GARDEN_ASSERT(mipCount <= imageFormatProperties.imageFormatProperties.maxMipLevels);
GARDEN_ASSERT(layerCount <= imageFormatProperties.imageFormatProperties.maxArrayLayers);
GARDEN_ASSERT(imageInfo.samples <= (VkSampleCountFlags)imageFormatProperties.imageFormatProperties.sampleCounts);
#endif

VmaAllocationCreateInfo allocationCreateInfo = {};
allocationCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
Expand Down Expand Up @@ -216,6 +232,24 @@ ID<ImageView> Image::getDefaultView()
return defaultView;
}

bool Image::isSupported(Type type, Format format, Bind bind, const uint3& size, uint8 mipCount, uint32 layerCount)
{
vk::PhysicalDeviceImageFormatInfo2 imageFormatInfo;
imageFormatInfo.format = toVkFormat(format);
imageFormatInfo.type = toVkImageType(type);
imageFormatInfo.tiling = vk::ImageTiling::eOptimal;
imageFormatInfo.usage = toVkImageUsages(bind);
if (type == Type::Cubemap)
imageFormatInfo.flags |= vk::ImageCreateFlagBits::eCubeCompatible;

auto imageFormatProperties = Vulkan::physicalDevice.getImageFormatProperties2(imageFormatInfo);
return size.x <= imageFormatProperties.imageFormatProperties.maxExtent.width &&
size.y <= imageFormatProperties.imageFormatProperties.maxExtent.height &&
size.z <= imageFormatProperties.imageFormatProperties.maxExtent.depth &&
mipCount <= imageFormatProperties.imageFormatProperties.maxMipLevels &&
layerCount <= imageFormatProperties.imageFormatProperties.maxArrayLayers;
}

#if GARDEN_DEBUG
void Image::setDebugName(const string& name)
{
Expand Down
34 changes: 11 additions & 23 deletions source/graphics/vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ static vk::DebugUtilsMessengerEXT createVkDebugMessenger(
#endif

//**********************************************************************************************************************
static vk::PhysicalDevice getBestPhysicalDevice(vk::Instance instance, bool& isDeviceIntegrated)
static vk::PhysicalDevice getBestPhysicalDevice(vk::Instance instance)
{
auto devices = instance.enumeratePhysicalDevices();

Expand Down Expand Up @@ -272,20 +272,11 @@ static vk::PhysicalDevice getBestPhysicalDevice(vk::Instance instance, bool& isD
{
targetIndex = i;
targetScore = score;

isDeviceIntegrated = properties.deviceType ==
vk::PhysicalDeviceType::eIntegratedGpu;
}
}

return devices[targetIndex];
}
else
{
auto properties = devices[0].getProperties();
isDeviceIntegrated = properties.deviceType == vk::PhysicalDeviceType::eIntegratedGpu;
return devices[0];
}

return devices[targetIndex];
}

static vk::SurfaceKHR createVkSurface(vk::Instance instance, GLFWwindow* window)
Expand Down Expand Up @@ -411,13 +402,6 @@ static vk::Device createVkDevice(
else
transferQueueIndex = graphicsQueueIndex;
}
else if (transferQueueFamilyIndex == computeQueueFamilyIndex)
{
if (computeQueueCount < computeQueueMaxCount)
transferQueueIndex = computeQueueCount++;
else
transferQueueIndex = computeQueueIndex;
}
else
{
transferQueueCount = 1;
Expand Down Expand Up @@ -456,7 +440,7 @@ static vk::Device createVkDevice(
if (transferQueueCount > 0)
{
queueInfos.push_back(vk::DeviceQueueCreateInfo({},
transferQueueFamilyIndex, transferQueueCount, queuePriorities.data()));
transferQueueFamilyIndex, transferQueueCount, queuePriorities.data()));
}
if (computeQueueCount > 0)
{
Expand Down Expand Up @@ -827,7 +811,7 @@ void Vulkan::initialize(const string& appName, const string& appDataName, Versio

glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
auto window = glfwCreateWindow(windowSize.x, windowSize.y,
appName.c_str(), primaryMonitor, NULL);
appName.c_str(), primaryMonitor, nullptr);
if (!window)
throw runtime_error("Failed to create GLFW window.");
GraphicsAPI::window = window;
Expand Down Expand Up @@ -856,12 +840,16 @@ void Vulkan::initialize(const string& appName, const string& appDataName, Versio
dynamicLoader = vk::DispatchLoaderDynamic(instance, vkGetInstanceProcAddr);
#endif

physicalDevice = getBestPhysicalDevice(instance, GraphicsAPI::isDeviceIntegrated);
physicalDevice = getBestPhysicalDevice(instance);
deviceProperties = physicalDevice.getProperties2();
versionMajor = VK_API_VERSION_MAJOR(deviceProperties.properties.apiVersion);
versionMinor = VK_API_VERSION_MINOR(deviceProperties.properties.apiVersion);
GraphicsAPI::isDeviceIntegrated =
deviceProperties.properties.deviceType == vk::PhysicalDeviceType::eIntegratedGpu;
surface = createVkSurface(instance, window);
getVkQueueFamilyIndices(physicalDevice, surface, graphicsQueueFamilyIndex,
transferQueueFamilyIndex, computeQueueFamilyIndex, graphicsQueueMaxCount,
transferQueueMaxCount, computeQueueMaxCount);
deviceProperties = physicalDevice.getProperties2();
deviceFeatures = physicalDevice.getFeatures2();
device = createVkDevice(physicalDevice, versionMajor, versionMinor,
graphicsQueueFamilyIndex, transferQueueFamilyIndex, computeQueueFamilyIndex,
Expand Down
2 changes: 1 addition & 1 deletion source/system/graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ void GraphicsSystem::preInit()

GARDEN_LOG_INFO("GPU: " + string(Vulkan::deviceProperties.properties.deviceName.data()));
auto apiVersion = Vulkan::deviceProperties.properties.apiVersion;
GARDEN_LOG_INFO("Vulkan API: " + to_string(VK_API_VERSION_MAJOR(apiVersion)) + "." +
GARDEN_LOG_INFO("Device Vulkan API: " + to_string(VK_API_VERSION_MAJOR(apiVersion)) + "." +
to_string(VK_API_VERSION_MINOR(apiVersion)) + "." + to_string(VK_API_VERSION_PATCH(apiVersion)));
GARDEN_LOG_INFO("Framebuffer size: " + to_string(framebufferSize.x) + "x" + to_string(framebufferSize.y));

Expand Down
44 changes: 43 additions & 1 deletion source/system/log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,50 @@
#include "mpio/os.hpp"
#include <thread>

#if GARDEN_OS_LINUX || GARDEN_OS_MACOS
#include <sys/utsname.h>
#elif GARDEN_OS_WINDOWS
#include <windows.h>
#pragma comment(lib, "Version.lib")
#endif

using namespace mpio;
using namespace garden;

//**********************************************************************************************************************
static void logKernelInfo(LogSystem* logSystem)
{
#if GARDEN_OS_LINUX || GARDEN_OS_MACOS
struct utsname info;
memset(&info, 0, sizeof(struct utsname));
auto result = uname(&info);
if (result != 0)
throw runtime_error("Failed to get kernel information.");
logSystem->info("OS name: " + string(info.sysname));
logSystem->info("OS release: " + string(info.release));
logSystem->info("OS version: " + string(info.version));
logSystem->info("OS machine: " + string(info.machine));
#elif GARDEN_OS_WINDOWS
auto kernelDLL = L"kernel32.dll"; DWORD dummy;
auto infoSize = GetFileVersionInfoSizeExW(FILE_VER_GET_NEUTRAL, kernelDLL, &dummy);
vector<char> buffer(infoSize);
auto result = GetFileVersionInfoExW(FILE_VER_GET_NEUTRAL, kernelDLL, dummy, buffer.size(), buffer.data());
if (!result)
throw runtime_error("Failed to get kernel file version information.");
void* info = nullptr; UINT size = 0;
result = VerQueryValueW(buffer.data(), L"\\", &info, &size);
if (!result)
throw runtime_error("Failed to get kernel version.");
auto fileInfo = (const VS_FIXEDFILEINFO*)info;
auto osName = HIWORD(fileInfo->dwFileVersionMS) == 10 && HIWORD(fileInfo->dwFileVersionLS) >= 22000 ?
string("Windows 11") : "Windows " + to_string(HIWORD(fileInfo->dwFileVersionMS));
logSystem->info("OS name: " + osName);
logSystem->info("OS version: " +
to_string(HIWORD(fileInfo->dwFileVersionMS)) + "." + to_string(LOWORD(fileInfo->dwFileVersionMS)) + "." +
to_string(HIWORD(fileInfo->dwFileVersionLS)) + "." + to_string(LOWORD(fileInfo->dwFileVersionLS)));
#endif
}

//**********************************************************************************************************************
LogSystem::LogSystem(LogLevel level, double rotationTime, bool setSingleton) : Singleton(setSingleton)
{
Expand All @@ -48,7 +89,8 @@ LogSystem::LogSystem(LogLevel level, double rotationTime, bool setSingleton) : S
info("Started logging system. (UTC+0)");
info(appInfoSystem->getName() + " [v" + appInfoSystem->getVersion().toString3() + "]");
info(GARDEN_NAME_STRING " Engine [v" GARDEN_VERSION_STRING "]");
info("OS: " GARDEN_OS_NAME " (" GARDEN_ARCH ")");
info("Target OS: " GARDEN_OS_NAME " (" GARDEN_ARCH ")");
logKernelInfo(this);
info("SIMDs: " + string(GARDEN_SIMD_STRING));
info("CPU: " + string(OS::getCpuName()));
info("Thread count: " + to_string(thread::hardware_concurrency()));
Expand Down
2 changes: 1 addition & 1 deletion source/system/render/deferred.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ static void createGBuffers(ID<Image>* gBuffers)
auto framebufferSize = graphicsSystem->getScaledFramebufferSize();
gBuffers[0] = graphicsSystem->createImage(Image::Format::SrgbR8G8B8A8, binds, mips, framebufferSize, strategy);
SET_RESOURCE_DEBUG_NAME(gBuffers[0], "image.deferred.gBuffer0");
gBuffers[1] = graphicsSystem->createImage(Image::Format::UnormA2R10G10B10, binds, mips, framebufferSize, strategy);
gBuffers[1] = graphicsSystem->createImage(Image::Format::UnormA2B10G10R10, binds, mips, framebufferSize, strategy);
SET_RESOURCE_DEBUG_NAME(gBuffers[1], "image.deferred.gBuffer1");
gBuffers[2] = graphicsSystem->createImage(Image::Format::UnormR8G8B8A8, binds, mips, framebufferSize, strategy);
SET_RESOURCE_DEBUG_NAME(gBuffers[2], "image.deferred.gBuffer2");
Expand Down
2 changes: 1 addition & 1 deletion source/system/render/editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ void EditorRenderSystem::showAboutWindow()
auto apiString = to_string(VK_API_VERSION_MAJOR(apiVersion)) + "." +
to_string(VK_API_VERSION_MINOR(apiVersion)) + "." +
to_string(VK_API_VERSION_PATCH(apiVersion));
ImGui::Text("Vulkan API: %s", apiString.c_str());
ImGui::Text("Device Vulkan API: %s", apiString.c_str());

auto graphicsSystem = GraphicsSystem::Instance::tryGet();
if (graphicsSystem)
Expand Down
8 changes: 4 additions & 4 deletions source/system/watcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ void WatcherSystem::initialize()
FSEventStreamContext context;
context.version = 0;
context.info = this;
context.retain = NULL;
context.release = NULL;
context.copyDescription = NULL;
context.retain = nullptr;
context.release = nullptr;
context.copyDescription = nullptr;
auto stream = FSEventStreamCreate(NULL, &onChange, &context, pathsToWatch,
auto stream = FSEventStreamCreate(nullptr, &onChange, &context, pathsToWatch,
kFSEventStreamEventIdSinceNow, 1.0, kFSEventStreamCreateFlagFileEvents);
this->instance = stream;
Expand Down

0 comments on commit 31fd2b9

Please sign in to comment.