Merge pull request 'Enhancements & Fixes' (#78) from enhancements into master

Reviewed-on: https://git.madvoxel.net/OpenVulkano/OpenVulkano/pulls/78
This commit is contained in:
Georg Hagen
2024-07-24 16:06:01 +02:00
45 changed files with 442 additions and 110 deletions

View File

@@ -19,4 +19,6 @@ PUGIXML_REPO=https://git.madvoxel.net/Mirrors/pugixml.git
YAMLCPP_REPO=https://git.madvoxel.net/Mirrors/yaml-cpp.git YAMLCPP_REPO=https://git.madvoxel.net/Mirrors/yaml-cpp.git
UTFCPP_REPO=https://git.madvoxel.net/Mirrors/utfcpp.git UTFCPP_REPO=https://git.madvoxel.net/Mirrors/utfcpp.git
TRACY_REPO=https://git.madvoxel.net/Mirrors/tracy.git TRACY_REPO=https://git.madvoxel.net/Mirrors/tracy.git
STB_REPO=https://git.madvoxel.net/Mirrors/stb.git STB_REPO=https://git.madvoxel.net/Mirrors/stb.git
UNITS_REPO=https://git.madvoxel.net/Mirrors/units.git
ANKERLUD_REPO=https://git.madvoxel.net/Mirrors/ankerl_unordered_dense.git

View File

@@ -20,8 +20,9 @@ add_subdirectory(tracy)
add_subdirectory(libstud-uuid) add_subdirectory(libstud-uuid)
add_subdirectory(rapidyaml) add_subdirectory(rapidyaml)
add_subdirectory(libarchive) add_subdirectory(libarchive)
add_subdirectory(libjpeg-turbo)
add_subdirectory(boost) add_subdirectory(boost)
add_subdirectory(units)
if (NOT IOS) if (NOT IOS)
add_subdirectory(libjpeg-turbo)
add_subdirectory(curl) add_subdirectory(curl)
endif() endif()

View File

@@ -29,6 +29,7 @@ if (glfw_FOUND)
target_link_libraries(imgui_internal PUBLIC glfw) target_link_libraries(imgui_internal PUBLIC glfw)
endif () endif ()
set(NO_SHADERC ON)
SetupVulkan(imgui_internal) SetupVulkan(imgui_internal)
target_include_directories(imgui_internal PUBLIC ${Vulkan_INCLUDE_DIR}) target_include_directories(imgui_internal PUBLIC ${Vulkan_INCLUDE_DIR})

15
3rdParty/units/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,15 @@
include(FetchContent)
if(NOT DEFINED UNITS_REPO)
set(UNITS_REPO https://github.com/nholthaus/units.git)
endif ()
FetchContent_Declare(
units
EXCLUDE_FROM_ALL
GIT_REPOSITORY ${UNITS_REPO}
GIT_TAG v2.3.3
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(units)

View File

@@ -109,7 +109,7 @@ endif()
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR}/deps/INSTALL) list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR}/deps/INSTALL)
target_link_libraries(openVulkanoCpp PRIVATE magic_enum yaml-cpp fmt spdlog glm pugixml stb eigen utf8cpp imgui_internal TracyClient stud-uuid ryml unordered_dense Boost::regex) target_link_libraries(openVulkanoCpp PRIVATE magic_enum yaml-cpp fmt spdlog glm pugixml stb eigen utf8cpp imgui_internal TracyClient stud-uuid ryml unordered_dense Boost::regex units)
LinkCurl(openVulkanoCpp) LinkCurl(openVulkanoCpp)
add_compile_definitions(LIBARCHIVE_STATIC) add_compile_definitions(LIBARCHIVE_STATIC)

View File

@@ -5,10 +5,14 @@ function(SetupVulkan TARGET)
else () else ()
find_package(Vulkan REQUIRED) find_package(Vulkan REQUIRED)
target_link_libraries(${TARGET} PRIVATE Vulkan::Vulkan) target_link_libraries(${TARGET} PRIVATE Vulkan::Vulkan)
find_package(Vulkan OPTIONAL_COMPONENTS shaderc_combined) if (NO_SHADERC)
if (Vulkan_shaderc_combined_FOUND) message("Disable shaderc linking")
target_link_libraries(${TARGET} PRIVATE Vulkan::shaderc_combined) else()
target_compile_definitions(${TARGET} PRIVATE HAS_SHADERC) find_package(Vulkan OPTIONAL_COMPONENTS shaderc_combined)
if (Vulkan_shaderc_combined_FOUND)
target_link_libraries(${TARGET} PRIVATE Vulkan::shaderc_combined)
target_compile_definitions(${TARGET} PRIVATE HAS_SHADERC)
endif ()
endif () endif ()
endif () endif ()
target_include_directories(${TARGET} PUBLIC ${Vulkan_INCLUDE_DIR}) target_include_directories(${TARGET} PUBLIC ${Vulkan_INCLUDE_DIR})

2
doc

Submodule doc updated: 88fb9e13fc...25bfd5114c

View File

@@ -45,6 +45,11 @@ namespace OpenVulkano::AR
Math::CameraIntrinsic intrinsic; Math::CameraIntrinsic intrinsic;
Format format = Format::NV12; Format format = Format::NV12;
[[nodiscard]] Math::Vector4uc Sample(float nx, float ny, bool asRgb = true) const
{
return Sample(static_cast<uint32_t>(nx * luminescenceOrColor.resolution.x), static_cast<uint32_t>(ny * luminescenceOrColor.resolution.y), asRgb);
}
[[nodiscard]] Math::Vector4uc Sample(uint32_t x, uint32_t y, bool asRgb = true) const [[nodiscard]] Math::Vector4uc Sample(uint32_t x, uint32_t y, bool asRgb = true) const
{ {
const uint8_t* lumColBuffer = static_cast<const uint8_t*>(luminescenceOrColor.data); const uint8_t* lumColBuffer = static_cast<const uint8_t*>(luminescenceOrColor.data);

View File

@@ -10,6 +10,8 @@
#include "Scene/Texture.hpp" #include "Scene/Texture.hpp"
#include <filesystem> #include <filesystem>
using namespace std::chrono_literals;
namespace OpenVulkano::AR::Playback namespace OpenVulkano::AR::Playback
{ {
ArSessionPlayback::ArSessionPlayback(const std::string& recordingPath, bool autoAdvance) ArSessionPlayback::ArSessionPlayback(const std::string& recordingPath, bool autoAdvance)
@@ -60,6 +62,7 @@ namespace OpenVulkano::AR::Playback
void ArSessionPlayback::ReadWorker() void ArSessionPlayback::ReadWorker()
{ {
std::this_thread::sleep_for(128ms); // Delay startup of playback
while (playbackReader.HasNext() && IsRunning()) while (playbackReader.HasNext() && IsRunning())
{ {
while (!m_frameConsumed) { std::this_thread::yield(); } while (!m_frameConsumed) { std::this_thread::yield(); }

View File

@@ -6,6 +6,7 @@
#pragma once #pragma once
#include "IResourceManager.hpp"
#include "Base/ITickable.hpp" #include "Base/ITickable.hpp"
#include "Base/ICloseable.hpp" #include "Base/ICloseable.hpp"
#include "Scene/Scene.hpp" #include "Scene/Scene.hpp"
@@ -32,5 +33,7 @@ namespace OpenVulkano
virtual void SetActiveUi(Scene::UI::Ui* ui) = 0; virtual void SetActiveUi(Scene::UI::Ui* ui) = 0;
virtual Scene::UI::Ui* GetActiveUi() = 0; virtual Scene::UI::Ui* GetActiveUi() = 0;
virtual IResourceManager* GetIResourceManager() = 0;
}; };
} }

View File

@@ -0,0 +1,25 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "Base/Wrapper.hpp"
#include "Math/Math.hpp"
#include "Scene/DataFormat.hpp"
namespace OpenVulkano
{
namespace Scene
{
class Texture;
}
class IResourceManager
{
public:
[[nodiscard]] virtual Unique<Scene::Texture> CreateSharedMemoryTexture(const Math::Vector3ui& resolution, DataFormat format) = 0;
};
}

View File

@@ -37,7 +37,7 @@ namespace OpenVulkano
[[nodiscard]] uint32_t Patch() const { return GetComponent(2); } [[nodiscard]] uint32_t Patch() const { return GetComponent(2); }
[[nodiscard]] uint32_t Build() const { return m_buildNumber; } [[nodiscard]] uint64_t Build() const { return m_buildNumber; }
[[nodiscard]] bool IsPreRelease() const { return m_preRelease; } [[nodiscard]] bool IsPreRelease() const { return m_preRelease; }

View File

@@ -30,7 +30,7 @@ namespace OpenVulkano
[[nodiscard]] bool IsInitialized() const { return initialized; } [[nodiscard]] bool IsInitialized() const { return initialized; }
void Init(); void Init() override;
void Tick() override; void Tick() override;

View File

@@ -149,8 +149,7 @@ namespace OpenVulkano::GLFW
void WindowGLFW::SetSize(uint32_t width, uint32_t height) void WindowGLFW::SetSize(uint32_t width, uint32_t height)
{ {
windowConfig.size.x = width; currentSize = { width, height };
windowConfig.size.y = height;
if (window) if (window)
{ {
glfwSetWindowSize(window, width, height); glfwSetWindowSize(window, width, height);
@@ -169,9 +168,9 @@ namespace OpenVulkano::GLFW
Math::Vector2ui WindowGLFW::GetSize() Math::Vector2ui WindowGLFW::GetSize()
{ {
Math::Vector2i size; if (currentSize.x == 0 || currentSize.y == 0)
glfwGetWindowSize(window, &size.x, &size.y); glfwGetWindowSize(window, reinterpret_cast<int*>(&currentSize.x), reinterpret_cast<int*>(&currentSize.y));
return size; return currentSize;
} }
Math::Vector2i WindowGLFW::GetPosition() Math::Vector2i WindowGLFW::GetPosition()
@@ -269,6 +268,11 @@ namespace OpenVulkano::GLFW
void WindowGLFW::OnResize(const uint32_t newWidth, const uint32_t newHeight) void WindowGLFW::OnResize(const uint32_t newWidth, const uint32_t newHeight)
{ {
Logger::WINDOW->debug("Window (id: {0}) resized (width: {1}, height: {2})", GetWindowId(), newWidth, newHeight); Logger::WINDOW->debug("Window (id: {0}) resized (width: {1}, height: {2})", GetWindowId(), newWidth, newHeight);
currentSize = { newWidth, newHeight };
if (GetWindowMode() == WINDOWED || GetWindowMode() == BORDERLESS)
{
windowConfig.size = currentSize;
}
handler->OnWindowResize(this, newWidth, newHeight); handler->OnWindowResize(this, newWidth, newHeight);
} }

View File

@@ -23,6 +23,7 @@ namespace OpenVulkano::GLFW
InputProviderGLFW& inputProvider; InputProviderGLFW& inputProvider;
GLFWwindow* window = nullptr; GLFWwindow* window = nullptr;
IWindowHandler* handler = nullptr; IWindowHandler* handler = nullptr;
Math::Vector2ui currentSize = {};
public: public:
WindowGLFW(InputProviderGLFW& inputProvider); WindowGLFW(InputProviderGLFW& inputProvider);

View File

@@ -29,6 +29,12 @@ namespace OpenVulkano::Math
constexpr T CONVERSION = std::numbers::pi_v<T> / 180.0; constexpr T CONVERSION = std::numbers::pi_v<T> / 180.0;
return degree * CONVERSION; return degree * CONVERSION;
} }
template<typename T>
constexpr T Square(T val)
{
return val * val;
}
} }
template<typename T> using Matrix2_SIMD = glm::tmat2x2<T, glm::aligned>; template<typename T> using Matrix2_SIMD = glm::tmat2x2<T, glm::aligned>;

View File

@@ -0,0 +1,46 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "Math/Math.hpp"
namespace OpenVulkano::Math
{
class RGB565
{
uint16_t Make5(uint8_t val)
{
return val * 31.0f / 255.0f;
}
uint16_t Make6(uint8_t val)
{
return val * 63.0f / 255.0f;
}
public:
union
{
uint16_t value;
struct
{
uint16_t b : 5;
uint16_t g : 6;
uint16_t r : 5;
};
};
RGB565(Math::Vector4uc color = {0, 0, 0, 1})
: b(Make5(color.b))
, g(Make6(color.g))
, r(Make5(color.r))
{
}
};
static_assert(sizeof(RGB565) == 2);
}

View File

@@ -97,8 +97,6 @@ namespace OpenVulkano::Scene
void UpdateViewProjectionMatrix() void UpdateViewProjectionMatrix()
{ {
//TODO this should be done based on the clipspace used by the rendering api
// In vulkan the screen space is defined as y=0=top and y=1=bottom and thus the coordinate have to be flipped
m_viewProjection = m_projection * m_view; m_viewProjection = m_projection * m_view;
} }
@@ -115,6 +113,14 @@ namespace OpenVulkano::Scene
SetMatrix(Math::Utils::inverse(view)); SetMatrix(Math::Utils::inverse(view));
} }
void SetProjectionMatrix(const Math::Matrix4f& projection)
{
//TODO this should be done based on the clipspace used by the rendering api
// In vulkan the screen space is defined as y=0=top and y=1=bottom and thus the coordinate have to be flipped
m_projection = projection * Math::Matrix4f(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
UpdateViewProjectionMatrix();
}
[[nodiscard]] const Math::Matrix4f& GetViewProjectionMatrix() const [[nodiscard]] const Math::Matrix4f& GetViewProjectionMatrix() const
{ {
return m_viewProjection; return m_viewProjection;
@@ -251,9 +257,7 @@ namespace OpenVulkano::Scene
void UpdateProjectionMatrix() override void UpdateProjectionMatrix() override
{ {
m_projection = Math::Utils::perspectiveRH_ZO(m_fov, m_aspect, m_nearPlane, m_farPlane); SetProjectionMatrix(Math::Utils::perspectiveRH_ZO(m_fov, m_aspect, m_nearPlane, m_farPlane));
m_projection *= Math::Matrix4f(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
UpdateViewProjectionMatrix();
} }
[[nodiscard]] bool IsPerspective() const override { return true; } [[nodiscard]] bool IsPerspective() const override { return true; }
@@ -266,11 +270,9 @@ namespace OpenVulkano::Scene
{ {
const float scale = 0.5f * m_contentScaleFactor * m_zoom; const float scale = 0.5f * m_contentScaleFactor * m_zoom;
const float widthHalf = m_width * scale, heightHalf = m_height * scale; const float widthHalf = m_width * scale, heightHalf = m_height * scale;
m_projection = Math::Utils::orthoRH_ZO(-widthHalf, widthHalf, -heightHalf, heightHalf, m_nearPlane, m_farPlane); SetProjectionMatrix(Math::Utils::orthoRH_ZO(-widthHalf, widthHalf, -heightHalf, heightHalf, m_nearPlane, m_farPlane));
UpdateViewProjectionMatrix();
} }
[[nodiscard]] bool IsOrtho() const override { return true; } [[nodiscard]] bool IsOrtho() const override { return true; }
}; };
} }

View File

@@ -5,10 +5,50 @@
*/ */
#include "DataFormat.hpp" #include "DataFormat.hpp"
#include "Base/Logger.hpp"
#include <magic_enum.hpp> #include <magic_enum.hpp>
namespace OpenVulkano namespace OpenVulkano
{ {
namespace
{
std::unordered_map<DataFormat::Format, uint32_t> MakeFormatSizeMap()
{
std::unordered_map<DataFormat::Format, uint32_t> map;
for (auto format : magic_enum::enum_values<DataFormat::Format>())
{
uint32_t size = 0;
if (format == DataFormat::R4G4_UNORM_PACK8 || format == DataFormat::S8_UINT) size = 1;
else if (format >= DataFormat::R4G4B4A4_UNORM_PACK16 && format <= DataFormat::A1R5G5B5_UNORM_PACK16) size = 2;
else if (format >= DataFormat::R8_UNORM && format <= DataFormat::R8_SRGB) size = 1;
else if (format >= DataFormat::R8G8_UNORM && format <= DataFormat::R8G8_SRGB) size = 2;
else if (format >= DataFormat::R8G8B8_UNORM && format <= DataFormat::B8G8R8_SRGB) size = 3;
else if (format >= DataFormat::R8G8B8A8_UNORM && format <= DataFormat::A2B10G10R10_SINT_PACK32) size = 4;
else if (format >= DataFormat::R16_UNORM && format <= DataFormat::R16_SFLOAT) size = 2;
else if (format >= DataFormat::R16G16_UNORM && format <= DataFormat::R16G16_SFLOAT) size = 4;
else if (format >= DataFormat::R16G16B16_UNORM && format <= DataFormat::R16G16B16_SFLOAT) size = 6;
else if (format >= DataFormat::R16G16B16A16_UNORM && format <= DataFormat::R16G16B16A16_SFLOAT) size = 8;
else if (format >= DataFormat::R32_UINT && format <= DataFormat::R32_SFLOAT) size = 4;
else if (format >= DataFormat::R32G32_UINT && format <= DataFormat::R32G32_SFLOAT) size = 8;
else if (format >= DataFormat::R32G32B32_UINT && format <= DataFormat::R32G32B32_SFLOAT) size = 12;
else if (format >= DataFormat::R32G32B32A32_UINT && format <= DataFormat::R32G32B32A32_SFLOAT) size = 16;
else if (format >= DataFormat::R64_UINT && format <= DataFormat::R64_SFLOAT) size = 8;
else if (format >= DataFormat::R64G64_UINT && format <= DataFormat::R64G64_SFLOAT) size = 16;
else if (format >= DataFormat::R64G64B64_UINT && format <= DataFormat::R64G64B64_SFLOAT) size = 24;
else if (format >= DataFormat::R64G64B64A64_UINT && format <= DataFormat::R64G64B64A64_SFLOAT) size = 32;
else if (format == DataFormat::B10G11R11_UFLOAT_PACK32 || format == DataFormat::E5B9G9R9_UFLOAT_PACK32 ||
format == DataFormat::X8_D24_UNORM_PACK32 || format == DataFormat::D32_SFLOAT || format == DataFormat::D24_UNORM_S8_UINT) size = 4;
else if (format == DataFormat::D16_UNORM) size = 2;
else if (format == DataFormat::D16_UNORM_S8_UINT) size = 3;
else if (format == DataFormat::D32_SFLOAT_S8_UINT) size = 5;
map[format] = size;
}
return map;
}
const std::unordered_map<DataFormat::Format, uint32_t> FORMAT_SIZE_MAP = MakeFormatSizeMap();
}
std::string_view DataFormat::GetName() const std::string_view DataFormat::GetName() const
{ {
return magic_enum::enum_name(m_format); return magic_enum::enum_name(m_format);
@@ -20,4 +60,22 @@ namespace OpenVulkano
if (result.has_value()) return { result.value() }; if (result.has_value()) return { result.value() };
return { UNDEFINED }; return { UNDEFINED };
} }
uint32_t DataFormat::GetBytesPerPixel()
{
auto size = FORMAT_SIZE_MAP.find(m_format);
if (size == FORMAT_SIZE_MAP.end() || size->second == 0) [[unlikely]]
{
Logger::RENDER->warn("Failed to get pixel size for format: {}", GetName());
return 0;
}
return size->second;
}
#ifndef __APPLE__
DataFormat DataFormat::GetFromMetalPixelFormat(int formatId)
{
return UNDEFINED;
}
#endif
} }

View File

@@ -371,9 +371,12 @@ namespace OpenVulkano
return reinterpret_cast<const vk::Format&>(m_format); return reinterpret_cast<const vk::Format&>(m_format);
} }
uint32_t GetBytesPerPixel();
static DataFormat GetFromName(std::string_view name); static DataFormat GetFromName(std::string_view name);
static DataFormat GetFromMetalPixelFormat(int formatId); static DataFormat GetFromMetalPixelFormat(int formatId);
private: private:
Format m_format; Format m_format;
}; };

View File

@@ -22,21 +22,21 @@ namespace OpenVulkano::Scene
} }
void MorphableCamera::UpdateProjectionMatrix() void MorphableCamera::UpdateProjectionMatrix()
{ {
PerspectiveCamera::UpdateProjectionMatrix(); if (m_morphState == 0) PerspectiveCamera::UpdateProjectionMatrix();
if (m_morphState != 0) if (m_morphState != 0)
{ {
const float scale = 0.5f * m_contentScaleFactor * m_zoom; const float scale = 0.5f * m_contentScaleFactor * m_zoom;
const float widthHalf = m_width * scale, heightHalf = m_height * scale; const float widthHalf = m_width * scale, heightHalf = m_height * scale;
m_orthoMatrix = Math::Utils::orthoRH_ZO(-widthHalf, widthHalf, -heightHalf, heightHalf, m_nearPlane, m_farPlane); Math::Matrix4f orthoMatrix = Math::Utils::orthoRH_ZO(-widthHalf, widthHalf, -heightHalf, heightHalf, m_nearPlane, m_farPlane);
if (m_morphState == 1) if (m_morphState == 1)
{ {
m_projection = m_orthoMatrix; SetProjectionMatrix(orthoMatrix);
} }
else else
{ {
m_projection = BlendMatrices(m_projection, m_orthoMatrix, m_morphState); Math::Matrix4f projection = Math::Utils::perspectiveRH_ZO(m_fov, m_aspect, m_nearPlane, m_farPlane);
SetProjectionMatrix(BlendMatrices(projection, orthoMatrix, m_morphState));
} }
UpdateViewProjectionMatrix();
} }
} }
} }

View File

@@ -13,7 +13,6 @@ namespace OpenVulkano::Scene
class MorphableCamera : public PerspectiveCamera class MorphableCamera : public PerspectiveCamera
{ {
float m_morphState; float m_morphState;
Math::Matrix4f m_orthoMatrix;
public: public:
MorphableCamera(float fovDegrees, float nearPlane = 0.1f, float farPlane = 1000.0f, float width = 16, float height = 9) MorphableCamera(float fovDegrees, float nearPlane = 0.1f, float farPlane = 1000.0f, float width = 16, float height = 9)
@@ -33,4 +32,4 @@ namespace OpenVulkano::Scene
[[nodiscard]] bool IsPerspective() const override { return m_morphState == 0; } [[nodiscard]] bool IsPerspective() const override { return m_morphState == 0; }
[[nodiscard]] bool IsOrtho() const override { return m_morphState == 1; } [[nodiscard]] bool IsOrtho() const override { return m_morphState == 1; }
}; };
} }

View File

@@ -14,6 +14,10 @@ namespace OpenVulkano::Scene
Node::Node() Node::Node()
: localMat(1), worldMat(1), enabled(true) : localMat(1), worldMat(1), enabled(true)
{} {}
Node::Node(const Math::Matrix4f& pose)
: localMat(pose), worldMat(pose), enabled(true)
{}
Node::~Node() noexcept Node::~Node() noexcept
{ {

View File

@@ -28,16 +28,18 @@ namespace OpenVulkano::Scene
static constexpr DescriptorSetLayoutBinding DESCRIPTOR_SET_LAYOUT_BINDING = { 0, DescriptorSetLayoutBinding::Type::TYPE_UNIFORM_BUFFER_DYNAMIC, 1, ShaderProgramType::ALL_GRAPHICS }; static constexpr DescriptorSetLayoutBinding DESCRIPTOR_SET_LAYOUT_BINDING = { 0, DescriptorSetLayoutBinding::Type::TYPE_UNIFORM_BUFFER_DYNAMIC, 1, ShaderProgramType::ALL_GRAPHICS };
Math::Matrix4f localMat, worldMat; Math::Matrix4f localMat, worldMat;
bool enabled = true;
Node* parent = nullptr; Node* parent = nullptr;
Scene* scene = nullptr; Scene* scene = nullptr;
std::vector<Node*> children; std::vector<Node*> children;
std::vector<Drawable*> drawables; std::vector<Drawable*> drawables;
UpdateFrequency matrixUpdateFrequency = UpdateFrequency::Never; UpdateFrequency matrixUpdateFrequency = UpdateFrequency::Never;
ICloseable* renderNode = nullptr; ICloseable* renderNode = nullptr;
bool enabled = true;
public: public:
Node(); Node();
Node(const Math::Matrix4f& pose);
~Node() noexcept override; ~Node() noexcept override;
@@ -80,6 +82,8 @@ namespace OpenVulkano::Scene
void Enable() { enabled = true; } void Enable() { enabled = true; }
void Disable() { enabled = false; } void Disable() { enabled = false; }
void SetEnabled(bool enable) { enabled = enable; }
[[nodiscard]] Node* GetParent() const { return parent; } [[nodiscard]] Node* GetParent() const { return parent; }

View File

@@ -34,6 +34,7 @@ namespace OpenVulkano::Scene
PlaneCameraController(Camera* camera = nullptr); PlaneCameraController(Camera* camera = nullptr);
void Init(Camera* camera) override { Init(camera, DefaultAxis::OXZ); }
void Init(Camera* camera, const Math::Vector3f& planeNormal); void Init(Camera* camera, const Math::Vector3f& planeNormal);
void Init(Camera* camera, DefaultAxis axis); void Init(Camera* camera, DefaultAxis axis);
void Tick() override; void Tick() override;

View File

@@ -46,7 +46,8 @@ namespace OpenVulkano::Scene
void ArBackgroundDrawable::Close() void ArBackgroundDrawable::Close()
{ {
m_arSession->OnNewFrame -= EventHandler(this, &ArBackgroundDrawable::OnNewArFrame); if (m_arSession) m_arSession->OnNewFrame -= EventHandler(this, &ArBackgroundDrawable::OnNewArFrame);
m_arSession = nullptr;
m_nextFrame = nullptr; m_nextFrame = nullptr;
Drawable::Close(); Drawable::Close();
} }
@@ -70,4 +71,4 @@ namespace OpenVulkano::Scene
} }
if (!m_texture) m_texture = &Texture::PLACEHOLDER; if (!m_texture) m_texture = &Texture::PLACEHOLDER;
} }
} }

View File

@@ -0,0 +1,39 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "ShaderProgramType.hpp"
namespace OpenVulkano
{
struct PushConstantRange
{
ShaderProgramType::Type stageFlags;
uint32_t offset, size;
PushConstantRange(ShaderProgramType::Type stages, uint32_t offset, uint32_t size)
: stageFlags(stages), offset(offset), size(size)
{}
PushConstantRange(uint32_t size, uint32_t offset = 0, ShaderProgramType::Type stages = ShaderProgramType::ALL_GRAPHICS)
: stageFlags(stages), offset(offset), size(size)
{}
};
struct PushConstant : PushConstantRange
{
const void* data;
PushConstant(ShaderProgramType::Type stages, uint32_t offset, uint32_t size, const void* data)
: PushConstantRange(stages, offset, size), data(data)
{}
PushConstant(const void* data, uint32_t size, uint32_t offset = 0, ShaderProgramType::Type stages = ShaderProgramType::ALL_GRAPHICS)
: PushConstantRange(stages, offset, size), data(data)
{}
};
}

View File

@@ -11,6 +11,7 @@
#include "VertexInputDescription.hpp" #include "VertexInputDescription.hpp"
#include "ShaderProgramType.hpp" #include "ShaderProgramType.hpp"
#include "DescriptorInputDescription.hpp" #include "DescriptorInputDescription.hpp"
#include "PushConstant.hpp"
#include <string> #include <string>
#include <stdexcept> #include <stdexcept>
@@ -72,10 +73,13 @@ namespace OpenVulkano::Scene
std::vector<ShaderProgram> shaderPrograms{}; std::vector<ShaderProgram> shaderPrograms{};
std::vector<VertexInputDescription> vertexInputDescriptions{}; std::vector<VertexInputDescription> vertexInputDescriptions{};
std::vector<std::vector<DescriptorSetLayoutBinding>> descriptorSets; std::vector<std::vector<DescriptorSetLayoutBinding>> descriptorSets;
std::vector<PushConstantRange> pushConstantRanges;
Topology topology = Topology::TRIANGLE_LIST; Topology topology = Topology::TRIANGLE_LIST;
CullMode cullMode = CullMode::BACK; CullMode cullMode = CullMode::BACK;
ICloseable* renderShader = nullptr; ICloseable* renderShader = nullptr;
bool alphaBlend = false; // TODO allow fine control over blending bool alphaBlend = false; // TODO allow fine control over blending
bool depthTest = true;
bool depthWrite = true;
Shader() = default; Shader() = default;
~Shader() override { /*if (renderShader) Shader::Close();*/ } ~Shader() override { /*if (renderShader) Shader::Close();*/ }
@@ -138,6 +142,11 @@ namespace OpenVulkano::Scene
} }
#pragma clang diagnostic pop #pragma clang diagnostic pop
void AddPushConstantRange(const PushConstantRange& pushConstantRange)
{
pushConstantRanges.push_back(pushConstantRange);
}
void Close() override void Close() override
{ {
renderShader->Close(); renderShader->Close();

View File

@@ -21,10 +21,12 @@ namespace OpenVulkano::Scene
UniformBuffer* m_uniBuffer = nullptr; UniformBuffer* m_uniBuffer = nullptr;
public: public:
SimpleDrawable() : Drawable(DrawEncoder::GetDrawEncoder<SimpleDrawable>()) {} SimpleDrawable(const DrawPhase phase = DrawPhase::MAIN)
: Drawable(DrawEncoder::GetDrawEncoder<SimpleDrawable>(), phase)
{}
explicit SimpleDrawable(const SimpleDrawable* toCopy) explicit SimpleDrawable(const SimpleDrawable* toCopy)
: Drawable(DrawEncoder::GetDrawEncoder<SimpleDrawable>()) : Drawable(DrawEncoder::GetDrawEncoder<SimpleDrawable>(), toCopy->GetDrawPhase())
, m_mesh(toCopy->m_mesh) , m_mesh(toCopy->m_mesh)
, m_material(toCopy->m_material) , m_material(toCopy->m_material)
, m_uniBuffer(toCopy->m_uniBuffer) , m_uniBuffer(toCopy->m_uniBuffer)

View File

@@ -14,22 +14,36 @@
namespace OpenVulkano::Scene namespace OpenVulkano::Scene
{ {
class Texture;
struct RenderTexture
{
Texture* m_texture = nullptr;
};
class Texture class Texture
{ {
public: public:
static Texture PLACEHOLDER; static Texture PLACEHOLDER;
static constexpr inline DescriptorSetLayoutBinding DESCRIPTOR_SET_LAYOUT_BINDING = { 0, DescriptorSetLayoutBinding::Type::TYPE_COMBINED_IMAGE_SAMPLER, 1, ShaderProgramType::ALL_GRAPHICS }; static constexpr inline DescriptorSetLayoutBinding DESCRIPTOR_SET_LAYOUT_BINDING = { 0, DescriptorSetLayoutBinding::Type::TYPE_COMBINED_IMAGE_SAMPLER, 1, ShaderProgramType::ALL_GRAPHICS };
Texture(bool placeholder = false) { if (placeholder) MakePlaceholder(); } RenderTexture* renderTexture = nullptr;
ICloseable* renderTexture = nullptr;
void* textureBuffer = nullptr; void* textureBuffer = nullptr;
Math::Vector3ui resolution = {0,0,0};
size_t size = 0; size_t size = 0;
Math::Vector3ui resolution = {0,0,0};
DataFormat format = DataFormat::B8G8R8A8_UNORM; DataFormat format = DataFormat::B8G8R8A8_UNORM;
bool updated = true; bool updated = true;
UpdateFrequency updateFrequency = UpdateFrequency::Never; UpdateFrequency updateFrequency = UpdateFrequency::Never;
Texture(bool placeholder = false) { if (placeholder) MakePlaceholder(); }
~Texture()
{
if (renderTexture)
{
renderTexture->m_texture = nullptr;
}
}
void MakePlaceholder(uint32_t width = 32, uint32_t height = 32, void MakePlaceholder(uint32_t width = 32, uint32_t height = 32,
Math::Vector4uc color1 = {248, 123, 255, 255}, Math::Vector4uc color2 = {250, 19, 255, 255}); Math::Vector4uc color1 = {248, 123, 255, 255}, Math::Vector4uc color2 = {250, 19, 255, 255});
@@ -43,4 +57,4 @@ namespace OpenVulkano::Scene
operator bool() const { return setId >= 0 && texture; } operator bool() const { return setId >= 0 && texture; }
}; };
} }

View File

@@ -7,6 +7,8 @@
#pragma once #pragma once
#include "Base/ICloseable.hpp" #include "Base/ICloseable.hpp"
#include "Scene/Shader/DescriptorInputDescription.hpp"
#include "Scene/UpdateFrequency.hpp"
namespace OpenVulkano::Scene namespace OpenVulkano::Scene
{ {

View File

@@ -1,13 +1,14 @@
#version 450 #version 450
layout (set = 3, binding = 0) uniform sampler2D camTexture; layout(set = 3, binding = 0) uniform sampler2D camTexture;
#ifdef ENABLE_DEPTH_WRITE #ifdef ENABLE_DEPTH_WRITE
layout (set = 2, binding = 1) uniform sampler2D depthMap; layout(set = 2, binding = 1) uniform sampler2D depthMap;
#endif #endif
layout (location = 0) in vec2 texCoords; layout(location = 0) in vec2 texCoords;
layout (location = 0) out vec4 fragColor; layout(location = 1) in float scale;
layout(location = 0) out vec4 fragColor;
layout(set = 1, binding = 0) uniform CameraData layout(set = 1, binding = 0) uniform CameraData
{ {
@@ -21,8 +22,14 @@ layout(set = 1, binding = 0) uniform CameraData
void main() void main()
{ {
vec2 rm = (texCoords - 0.5) * 2;
float intensity = rm.x * rm.x + rm.y * rm.y;
intensity = (intensity / 1.4) * scale / 2;
fragColor = texture(camTexture, texCoords); fragColor = texture(camTexture, texCoords);
fragColor.rgb = fragColor.rgb - intensity;
#ifdef ENABLE_DEPTH_WRITE #ifdef ENABLE_DEPTH_WRITE
gl_FragDepth = (texture(depthMap, texCoords).r - cam.near) / (cam.far - cam.near); gl_FragDepth = (texture(depthMap, texCoords).r - cam.near) / (cam.far - cam.near);
#endif #endif
} }

View File

@@ -3,56 +3,58 @@
layout(set = 1, binding = 0) uniform CameraData layout(set = 1, binding = 0) uniform CameraData
{ {
mat4 viewProjection; mat4 viewProjection;
mat4 view; mat4 view;
mat4 projection; mat4 projection;
vec4 camPos; vec4 camPos;
float nearPlane; float nearPlane;
float farPlane; float farPlane;
float width; float width;
float height; float height;
float fov; float fov;
float aspect; float aspect;
float scaleFactor; float scaleFactor;
float pixelScaleFactor; float pixelScaleFactor;
} cam; } cam;
layout(set = 2, binding = 0) uniform RealCameraData layout(set = 2, binding = 0) uniform RealCameraData
{ {
mat3 intrinsic; mat3 intrinsic;
int width; int width;
int height; int height;
} realCam; } realCam;
layout(location = 0) out vec2 textureCoordinates; layout(location = 0) out vec2 textureCoordinates;
layout(location = 1) out float scaleOut;
const float FLOAT_MAX_LESS_THAN_1 = 0.999999940395355224609; const float FLOAT_MAX_LESS_THAN_1 = 0.999999940395355224609;
// Background plane positions are in clipped space // Background plane positions are in clipped space
const vec4 PLANE[4] = vec4[] ( const vec4 PLANE[4] = vec4[](
vec4(1, -1, FLOAT_MAX_LESS_THAN_1, 1), vec4(-1, -1, FLOAT_MAX_LESS_THAN_1, 1), vec4(1, 1, FLOAT_MAX_LESS_THAN_1, 1), vec4(-1, 1, FLOAT_MAX_LESS_THAN_1, 1) vec4(1, -1, FLOAT_MAX_LESS_THAN_1, 1), vec4(-1, -1, FLOAT_MAX_LESS_THAN_1, 1), vec4(1, 1, FLOAT_MAX_LESS_THAN_1, 1), vec4(-1, 1, FLOAT_MAX_LESS_THAN_1, 1)
); );
const vec2 TEX_COORDS[4] = vec2[] ( const vec2 TEX_COORDS[4] = vec2[](
vec2(1, 0), vec2(0, 0), vec2(1, 1), vec2(0, 1) vec2(1, 0), vec2(0, 0), vec2(1, 1), vec2(0, 1)
); );
void main() { void main() {
vec4 position = PLANE[gl_VertexIndex]; vec4 position = PLANE[gl_VertexIndex];
// Calculate the scaling factors for width and height // Calculate the scaling factors for width and height
float height = realCam.height; float height = realCam.height;
float realScale = realCam.intrinsic[1][1] / height; float realScale = realCam.intrinsic[1][1] / height;
float realAspect = height / realCam.width; float realAspect = height / realCam.width;
float scaleY = realScale / cam.scaleFactor; float scaleY = realScale / cam.scaleFactor;
float scaleX = scaleY / (cam.aspect * realAspect); float scaleX = scaleY / (cam.aspect * realAspect);
// Scale the quad's position // Handle center
position.xy *= vec2(scaleX, scaleY); vec2 centerOffset = realCam.intrinsic[2].xy / vec2(realCam.width, realCam.height);
centerOffset -= 0.5;
position.xy -= centerOffset * vec2(2, 2);
// Handle center // Scale the quad's position
vec2 centerOffset = realCam.intrinsic[2].xy / vec2(realCam.width, realCam.height); position.xy *= vec2(scaleX, scaleY);
centerOffset -= 0.5;
position.xy -= centerOffset;
gl_Position = position; scaleOut = 1 / scaleY;
textureCoordinates = TEX_COORDS[gl_VertexIndex]; gl_Position = position;
textureCoordinates = TEX_COORDS[gl_VertexIndex];
} }

View File

@@ -202,7 +202,7 @@ namespace OpenVulkano::Vulkan
bool Device::GetMemoryType(uint32_t typeBits, const vk::MemoryPropertyFlags& properties, uint32_t* typeIndex) const bool Device::GetMemoryType(uint32_t typeBits, const vk::MemoryPropertyFlags& properties, uint32_t* typeIndex) const
{ {
for (uint32_t i = 0; i < 32; i++) for (uint32_t i = 0; i < 32 && typeBits; i++)
{ {
if ((typeBits & 1) == 1) if ((typeBits & 1) == 1)
{ {

View File

@@ -35,14 +35,22 @@ namespace OpenVulkano::Vulkan
cmdBuffer.pipelineBarrier(/*VulkanUtils::GetPipelineStageForLayout(oldLayout)*/vk::PipelineStageFlagBits::eTopOfPipe, /*VulkanUtils::GetPipelineStageForLayout(newLayout)*/ vk::PipelineStageFlagBits::eTransfer, {}, nullptr, nullptr, imgMemBarrier); cmdBuffer.pipelineBarrier(/*VulkanUtils::GetPipelineStageForLayout(oldLayout)*/vk::PipelineStageFlagBits::eTopOfPipe, /*VulkanUtils::GetPipelineStageForLayout(newLayout)*/ vk::PipelineStageFlagBits::eTransfer, {}, nullptr, nullptr, imgMemBarrier);
} }
void Image::Init(const Device* device, const DataFormat& format, const vk::Extent3D& resolution) void Image::Init(const Device* device, const DataFormat& format, const vk::Extent3D& resolution, const vk::MemoryPropertyFlags& memoryPropertyFlags)
{ {
vk::ImageCreateInfo imgCreateInfo { {}, vk::ImageType::e2D, format, resolution, 1, 1 }; vk::ImageCreateInfo imgCreateInfo { {}, vk::ImageType::e2D, format, resolution, 1, 1 };
imgCreateInfo.usage = vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled; imgCreateInfo.usage = vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled;
imgCreateInfo.tiling = vk::ImageTiling::eOptimal; if (memoryPropertyFlags & vk::MemoryPropertyFlagBits::eHostVisible)
{
imgCreateInfo.tiling = vk::ImageTiling::eLinear;
imgCreateInfo.initialLayout = vk::ImageLayout::ePreinitialized;
}
else
{
imgCreateInfo.tiling = vk::ImageTiling::eOptimal;
imgCreateInfo.initialLayout = vk::ImageLayout::eUndefined;
}
imgCreateInfo.sharingMode = vk::SharingMode::eExclusive; imgCreateInfo.sharingMode = vk::SharingMode::eExclusive;
imgCreateInfo.initialLayout = vk::ImageLayout::eUndefined;
vk::ImageViewCreateInfo imgViewCreateInfo { {}, image, vk::ImageViewType::e2D, imgCreateInfo.format }; vk::ImageViewCreateInfo imgViewCreateInfo { {}, image, vk::ImageViewType::e2D, imgCreateInfo.format };
imgViewCreateInfo.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor; imgViewCreateInfo.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor;
@@ -51,7 +59,7 @@ namespace OpenVulkano::Vulkan
imgViewCreateInfo.subresourceRange.baseArrayLayer = 0; imgViewCreateInfo.subresourceRange.baseArrayLayer = 0;
imgViewCreateInfo.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; imgViewCreateInfo.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
Init(device, imgCreateInfo, imgViewCreateInfo); Init(device, imgCreateInfo, imgViewCreateInfo, true, memoryPropertyFlags);
} }
void Image::Close() void Image::Close()

View File

@@ -38,7 +38,7 @@ namespace OpenVulkano::Vulkan
*/ */
void Init(const Device* device, const vk::ImageCreateInfo& imageCreateInfo, vk::ImageViewCreateInfo imageViewCreateInfo, bool allocateMem = true, const vk::MemoryPropertyFlags& memoryPropertyFlags = vk::MemoryPropertyFlagBits::eDeviceLocal); void Init(const Device* device, const vk::ImageCreateInfo& imageCreateInfo, vk::ImageViewCreateInfo imageViewCreateInfo, bool allocateMem = true, const vk::MemoryPropertyFlags& memoryPropertyFlags = vk::MemoryPropertyFlagBits::eDeviceLocal);
void Init(const Device* device, const DataFormat& format, const vk::Extent3D& resolution); void Init(const Device* device, const DataFormat& format, const vk::Extent3D& resolution, const vk::MemoryPropertyFlags& memoryPropertyFlags = vk::MemoryPropertyFlagBits::eDeviceLocal);
void SetLayout(vk::CommandBuffer& cmdBuffer, const vk::ImageSubresourceRange& subResourceRange, vk::ImageLayout newLayout, vk::ImageLayout oldLayout = vk::ImageLayout::eUndefined) const; void SetLayout(vk::CommandBuffer& cmdBuffer, const vk::ImageSubresourceRange& subResourceRange, vk::ImageLayout newLayout, vk::ImageLayout oldLayout = vk::ImageLayout::eUndefined) const;

View File

@@ -64,7 +64,7 @@ namespace OpenVulkano::Vulkan
void MetalBackedTexture::Close() void MetalBackedTexture::Close()
{ {
m_vulkanTexture.Close(); if (m_vulkanTexture) m_vulkanTexture.Close();
if (m_metalTexture) if (m_metalTexture)
{ {
[m_metalTexture release]; [m_metalTexture release];

View File

@@ -84,5 +84,7 @@ namespace OpenVulkano::Vulkan
void RegisterCloseable(ICloseable* closeable) { closeables.push_back(closeable); } void RegisterCloseable(ICloseable* closeable) { closeables.push_back(closeable); }
void UnregisterCloseable(ICloseable* closeable) { Utils::Remove(closeables, closeable); } void UnregisterCloseable(ICloseable* closeable) { Utils::Remove(closeables, closeable); }
IResourceManager* GetIResourceManager() override { return &resourceManager; }
}; };
} }

View File

@@ -133,7 +133,11 @@ namespace OpenVulkano::Vulkan
{ {
GetCmdBuffer().end(); GetCmdBuffer().end();
vk::SubmitInfo si = { 0, nullptr, nullptr, 1, &frameResources[currentBuffer].cmdBuffer, 1, &frameResources[currentBuffer].semaphore }; vk::SubmitInfo si = { 0, nullptr, nullptr, 1, &frameResources[currentBuffer].cmdBuffer, 1, &frameResources[currentBuffer].semaphore };
transferQueue.submit(1, &si, vk::Fence()); vk::Result result = transferQueue.submit(1, &si, vk::Fence());
if (result != vk::Result::eSuccess) [[unlikely]]
{
Logger::RENDER->error("Failed to submit resource manager transfer queue");
}
return frameResources[currentBuffer].semaphore; return frameResources[currentBuffer].semaphore;
} }
@@ -222,12 +226,22 @@ namespace OpenVulkano::Vulkan
return static_cast<VulkanCamera*>(camera->renderCamera); return static_cast<VulkanCamera*>(camera->renderCamera);
} }
UniformBuffer* ResourceManager::CreateUniformBuffer(const DescriptorSetLayoutBinding& binding, size_t size, void* data, uint32_t setId) UniformBuffer* ResourceManager::CreateUniformBuffer(const DescriptorSetLayoutBinding& binding, size_t size, void* data, uint32_t setId, bool hostVis)
{ {
const std::unique_lock lock(mutex); const std::unique_lock lock(mutex);
const vk::DeviceSize allocSize = Utils::Align(size, uniformBufferAlignment); const vk::DeviceSize allocSize = Utils::Align(size, uniformBufferAlignment);
auto buffer = CreateDeviceOnlyBufferWithData(allocSize, vk::BufferUsageFlagBits::eUniformBuffer, data); MemoryPool::ManagedBufferPtr buffer;
if (hostVis)
{
buffer = memPool.CreateBuffer(allocSize, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible);
buffer->Map();
buffer->Copy(data, size, 0);
}
else
{
buffer = CreateDeviceOnlyBufferWithData(allocSize, vk::BufferUsageFlagBits::eUniformBuffer, data);
}
UniformBuffer* uBuffer = new UniformBuffer(); UniformBuffer* uBuffer = new UniformBuffer();
uBuffer->Init(std::move(buffer), 0, allocSize, GetDescriptorLayoutSet(binding), binding, setId); uBuffer->Init(std::move(buffer), 0, allocSize, GetDescriptorLayoutSet(binding), binding, setId);
@@ -322,10 +336,8 @@ namespace OpenVulkano::Vulkan
VulkanUniformBuffer* vkBuffer; VulkanUniformBuffer* vkBuffer;
ManagedBuffer::Ptr mBuffer; ManagedBuffer::Ptr mBuffer;
const vk::DeviceSize allocSize = Utils::Align(buffer->size, uniformBufferAlignment); const vk::DeviceSize allocSize = Utils::Align(buffer->size, uniformBufferAlignment);
vk::DeviceSize frameSize = 0;
if (buffer->GetUpdateFrequency() != Scene::UpdateFrequency::Never) if (buffer->GetUpdateFrequency() != Scene::UpdateFrequency::Never)
{ {
frameSize = allocSize;
vkBuffer = new VulkanUniformBufferDynamic(); vkBuffer = new VulkanUniformBufferDynamic();
const uint32_t imgs = context->swapChain.GetImageCount(); const uint32_t imgs = context->swapChain.GetImageCount();
mBuffer = memPool.CreateBuffer(imgs * allocSize, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible); mBuffer = memPool.CreateBuffer(imgs * allocSize, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible);
@@ -354,4 +366,19 @@ namespace OpenVulkano::Vulkan
if (!sampler) sampler = device.createSampler(samplerConfig); if (!sampler) sampler = device.createSampler(samplerConfig);
return sampler; return sampler;
} }
Unique<Scene::Texture> ResourceManager::CreateSharedMemoryTexture(const Math::Vector3ui& resolution, DataFormat format)
{
const std::unique_lock lock(mutex);
Unique<Scene::Texture> texture = std::make_unique<Scene::Texture>();
texture->resolution = resolution;
texture->format = format;
texture->size = resolution.x * resolution.y * resolution.z * format.GetBytesPerPixel();
VulkanTexture* vkTexture = new VulkanTexture();
vkTexture->InitSharedMem(this, texture.get(), GetDescriptorLayoutSet(Scene::Texture::DESCRIPTOR_SET_LAYOUT_BINDING), Scene::Texture::DESCRIPTOR_SET_LAYOUT_BINDING);
textures.emplace_back(vkTexture);
return texture;
}
} }

View File

@@ -14,6 +14,7 @@
#include "IShaderOwner.hpp" #include "IShaderOwner.hpp"
#include "MemoryPool.hpp" #include "MemoryPool.hpp"
#include "Base/Wrapper.hpp" #include "Base/Wrapper.hpp"
#include "Base/Render/IResourceManager.hpp"
#include "Vulkan/Image.hpp" #include "Vulkan/Image.hpp"
#include "Scene/Shader/DescriptorInputDescription.hpp" #include "Scene/Shader/DescriptorInputDescription.hpp"
#include <vulkan/vulkan.hpp> #include <vulkan/vulkan.hpp>
@@ -47,7 +48,7 @@ namespace OpenVulkano
class ManagedBuffer; class ManagedBuffer;
class MemoryAllocation; class MemoryAllocation;
class ResourceManager : public IShaderOwner class ResourceManager : public IShaderOwner, public IResourceManager
{ {
friend UniformBuffer; friend UniformBuffer;
friend VulkanTexture; friend VulkanTexture;
@@ -114,10 +115,12 @@ namespace OpenVulkano
[[nodiscard]] vk::Device GetDevice() const { return device; } [[nodiscard]] vk::Device GetDevice() const { return device; }
UniformBuffer* CreateUniformBuffer(const DescriptorSetLayoutBinding& binding, size_t size, void* data, uint32_t setId = 2); UniformBuffer* CreateUniformBuffer(const DescriptorSetLayoutBinding& binding, size_t size, void* data, uint32_t setId = 2, bool hostVis = false);
vk::Sampler CreateSampler(const vk::SamplerCreateInfo& samplerConfig); vk::Sampler CreateSampler(const vk::SamplerCreateInfo& samplerConfig);
[[nodiscard]] Unique<Scene::Texture> CreateSharedMemoryTexture(const Math::Vector3ui& resolution, DataFormat format) override;
protected: // Allocation management protected: // Allocation management
MemoryPool::ManagedBufferPtr CreateDeviceOnlyBufferWithData(vk::DeviceSize size, vk::BufferUsageFlagBits usage, const void* data); MemoryPool::ManagedBufferPtr CreateDeviceOnlyBufferWithData(vk::DeviceSize size, vk::BufferUsageFlagBits usage, const void* data);

View File

@@ -7,6 +7,7 @@
#pragma once #pragma once
#include "Base/ICloseable.hpp" #include "Base/ICloseable.hpp"
#include "Scene/Camera.hpp"
#include "IRecordable.hpp" #include "IRecordable.hpp"
#include "Vulkan/Resources/UniformBuffer.hpp" #include "Vulkan/Resources/UniformBuffer.hpp"
@@ -39,5 +40,7 @@ namespace OpenVulkano::Vulkan
m_camera = nullptr; m_camera = nullptr;
delete m_buffer; delete m_buffer;
} }
[[nodiscard]] Scene::Camera* GetCamera() const { return m_camera; }
}; };
} }

View File

@@ -13,6 +13,7 @@
namespace OpenVulkano::Vulkan namespace OpenVulkano::Vulkan
{ {
static_assert(sizeof(vk::DescriptorSetLayoutBinding) == sizeof(DescriptorSetLayoutBinding)); static_assert(sizeof(vk::DescriptorSetLayoutBinding) == sizeof(DescriptorSetLayoutBinding));
static_assert(sizeof(vk::PushConstantRange) == sizeof(PushConstantRange));
VulkanShader::~VulkanShader() VulkanShader::~VulkanShader()
{ {
@@ -79,7 +80,7 @@ namespace OpenVulkano::Vulkan
vk::PipelineRasterizationStateCreateInfo rasterizer = {}; vk::PipelineRasterizationStateCreateInfo rasterizer = {};
rasterizer.cullMode = static_cast<vk::CullModeFlagBits>(shader->cullMode); rasterizer.cullMode = static_cast<vk::CullModeFlagBits>(shader->cullMode);
vk::PipelineMultisampleStateCreateInfo msaa = {}; vk::PipelineMultisampleStateCreateInfo msaa = {};
vk::PipelineDepthStencilStateCreateInfo depth = { {}, 1, 1, vk::CompareOp::eLess }; vk::PipelineDepthStencilStateCreateInfo depth = { {}, shader->depthTest, shader->depthWrite, vk::CompareOp::eLess };
depth.maxDepthBounds = 1; depth.maxDepthBounds = 1;
vk::PipelineColorBlendAttachmentState colorBlendAttachment = {}; vk::PipelineColorBlendAttachmentState colorBlendAttachment = {};
colorBlendAttachment.colorWriteMask = vk::ColorComponentFlagBits::eA | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eR; colorBlendAttachment.colorWriteMask = vk::ColorComponentFlagBits::eA | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eR;
@@ -148,9 +149,8 @@ namespace OpenVulkano::Vulkan
vk::DescriptorSetLayoutCreateInfo createInfo { {}, static_cast<uint32_t>(set.size()), reinterpret_cast<const vk::DescriptorSetLayoutBinding*>(set.data()) }; vk::DescriptorSetLayoutCreateInfo createInfo { {}, static_cast<uint32_t>(set.size()), reinterpret_cast<const vk::DescriptorSetLayoutBinding*>(set.data()) };
descriptorSetLayouts.push_back(device.createDescriptorSetLayout(createInfo)); descriptorSetLayouts.push_back(device.createDescriptorSetLayout(createInfo));
} }
vk::PushConstantRange* pcRanges = reinterpret_cast<vk::PushConstantRange*>(shader->pushConstantRanges.data());
vk::PipelineLayoutCreateInfo plci = {{}, static_cast<uint32_t>(descriptorSetLayouts.size()), descriptorSetLayouts.data(), static_cast<uint32_t>(shader->pushConstantRanges.size()), pcRanges };
vk::PipelineLayoutCreateInfo plci = { {}, static_cast<uint32_t>(descriptorSetLayouts.size()), descriptorSetLayouts.data(), 0, nullptr };
pipelineLayout = this->device.createPipelineLayout(plci); pipelineLayout = this->device.createPipelineLayout(plci);
} }
} }

View File

@@ -16,11 +16,10 @@
namespace OpenVulkano::Vulkan namespace OpenVulkano::Vulkan
{ {
class VulkanTexture : public IRecordable, public Image class VulkanTexture : public Scene::RenderTexture, public IRecordable, public Image
{ {
public: public:
static inline vk::SamplerCreateInfo DEFAULT_SAMPLER_CONFIG {}; static inline vk::SamplerCreateInfo DEFAULT_SAMPLER_CONFIG {};
Scene::Texture* m_texture = nullptr;
vk::Sampler m_sampler; vk::Sampler m_sampler;
vk::DescriptorSet m_descriptorSet; vk::DescriptorSet m_descriptorSet;
@@ -37,9 +36,22 @@ namespace OpenVulkano::Vulkan
texture->renderTexture = this; texture->renderTexture = this;
} }
void InitSharedMem(ResourceManager* resManager, Scene::Texture* texture, vk::DescriptorSetLayout* descriptorSetLayout, const DescriptorSetLayoutBinding& binding)
{
m_texture = texture;
Image::Init(resManager->GetContext()->device.get(), texture->format, { texture->resolution.x, texture->resolution.y, texture->resolution.z }, vk::MemoryPropertyFlagBits::eDeviceLocal | vk::MemoryPropertyFlagBits::eHostVisible);
texture->updated = false;
texture->textureBuffer = Map();
m_sampler = resManager->CreateSampler(DEFAULT_SAMPLER_CONFIG);
SetDescriptorSet(resManager, descriptorSetLayout, binding);
texture->renderTexture = this;
}
virtual ~VulkanTexture() override virtual ~VulkanTexture() override
{ {
if (m_texture) Close(); if (m_sampler) Close();
} }
void Close() override void Close() override
@@ -125,4 +137,4 @@ namespace OpenVulkano::Vulkan
VulkanTexture::Record(context, setId); VulkanTexture::Record(context, setId);
} }
}; };
} }

View File

@@ -50,13 +50,25 @@ namespace OpenVulkano::Vulkan
{ {
currentSemaphoreId = (currentSemaphoreId + 1) % imageAvailableSemaphores.size(); currentSemaphoreId = (currentSemaphoreId + 1) % imageAvailableSemaphores.size();
const auto resultValue = device->device.acquireNextImageKHR(swapChain, UINT64_MAX, imageAvailableSemaphores[currentSemaphoreId], fence); const auto resultValue = device->device.acquireNextImageKHR(swapChain, UINT64_MAX, imageAvailableSemaphores[currentSemaphoreId], fence);
const vk::Result result = resultValue.result; vk::Result result = resultValue.result;
if (result != vk::Result::eSuccess && result != vk::Result::eSuboptimalKHR) throw std::error_code(result); if (result != vk::Result::eSuccess && result != vk::Result::eSuboptimalKHR) [[unlikely]]
{
Logger::RENDER->error("Failed to acquire next swapchain image: {}", vk::to_string(result));
throw std::error_code(result);
}
SetCurrentFrameId(resultValue.value); SetCurrentFrameId(resultValue.value);
vk::Fence submitFence = GetCurrentSubmitFence(); vk::Fence submitFence = GetCurrentSubmitFence();
device->device.waitForFences(1, &submitFence, true, -1); result = device->device.waitForFences(1, &submitFence, true, -1);
device->device.resetFences(1, &submitFence); if (result != vk::Result::eSuccess) [[unlikely]]
{
Logger::RENDER->error("Failed to wait for fence: {}", vk::to_string(result));
}
result = device->device.resetFences(1, &submitFence);
if (result != vk::Result::eSuccess) [[unlikely]]
{
Logger::RENDER->error("Failed to reset fence: {}", vk::to_string(result));
}
return currentFrameBufferId; return currentFrameBufferId;
} }

View File

@@ -35,6 +35,8 @@ namespace OpenVulkano::Vulkan
void SetCamera(Scene::Camera* camera); void SetCamera(Scene::Camera* camera);
VulkanShader* GetShader() const { return m_lastShader; } [[nodiscard]] VulkanShader* GetShader() const { return m_lastShader; }
[[nodiscard]] VulkanCamera* GetCamera() const { return m_lastCamera; }
}; };
} }