light/modules/renderer/private/test/utils.hpp
light7734 847ad7dd74
Some checks failed
continuous-integration/drone/push Build is failing
ci(amd64/clang/lsan): fix leak sanitizer errors (#57)
Reviewed-on: #57
Co-authored-by: light7734 <light7734@tuta.io>
Co-committed-by: light7734 <light7734@tuta.io>
2025-10-09 14:08:14 +00:00

277 lines
7.3 KiB
C++

#pragma once
#include <memory/reference.hpp>
#include <renderer/components/messenger.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/system.hpp>
#include <surface/components.hpp>
#include <surface/system.hpp>
#include <test/test.hpp>
using ::lt::test::Case;
using ::lt::test::expect_eq;
using ::lt::test::expect_false;
using ::lt::test::expect_not_nullptr;
using ::lt::test::expect_throw;
using ::lt::test::expect_true;
using ::lt::test::Suite;
using ::std::ignore;
namespace constants {
constexpr auto api = lt::renderer::Api::vulkan;
constexpr auto resolution = lt::math::uvec2 { 800u, 600u };
constexpr auto frames_in_flight = uint32_t { 3u };
} // namespace constants
inline void noop_messenger_callback(
lt::renderer::IMessenger::MessageSeverity severity,
lt::renderer::IMessenger::MessageType type,
const lt::renderer::IMessenger::MessageData &data,
std::any &user_data
)
{
}
class Fixture_SurfaceSystem
{
public:
Fixture_SurfaceSystem()
{
m_system.create_surface_component(
m_entity.id(),
lt::surface::SurfaceComponent::CreateInfo {
.title = "",
.resolution = constants::resolution,
}
);
}
[[nodiscard]] auto renderer_system_create_info() -> lt::renderer::System::CreateInfo
{
return lt::renderer::System::CreateInfo{
.config = lt::renderer::System::Configuration{
.target_api = constants::api,
.max_frames_in_flight = constants::frames_in_flight,
},
.registry = registry(),
.surface_entity = surface_entity(),
.debug_callback_info = {
.severities = lt::renderer::IMessenger::MessageSeverity::all,
.types= lt::renderer::IMessenger::MessageType::all,
.callback = noop_messenger_callback,
.user_data = {},
}
} ;
}
[[nodiscard]] auto registry() -> lt::memory::Ref<lt::ecs::Registry> &
{
return m_registry;
}
[[nodiscard]] auto surface_entity() -> lt::ecs::Entity &
{
return m_entity;
}
[[nodiscard]] auto surface_system() -> lt::surface::System &
{
return m_system;
}
private:
lt::memory::Ref<lt::ecs::Registry> m_registry = lt::memory::create_ref<lt::ecs::Registry>();
lt::ecs::Entity m_entity { m_registry, m_registry->create_entity() };
lt::surface::System m_system = lt::surface::System(m_registry);
};
class Fixture_SurfaceGpu: public Fixture_SurfaceSystem
{
public:
Fixture_SurfaceGpu() = default;
[[nodiscard]] auto surface() -> lt::renderer::ISurface *
{
return m_surface.get();
}
[[nodiscard]] auto gpu() -> lt::renderer::IGpu *
{
return m_gpu.get();
}
private:
lt::memory::Scope<lt::renderer::ISurface> m_surface { lt::renderer::ISurface::create(
constants::api,
lt::renderer::IInstance::get(constants::api),
surface_entity()
) };
lt::memory::Scope<lt::renderer::IGpu> m_gpu {
lt::renderer::IGpu::create(constants::api, lt::renderer::IInstance::get(constants::api))
};
};
class FixtureDeviceSwapchain: public Fixture_SurfaceGpu
{
public:
FixtureDeviceSwapchain() = default;
[[nodiscard]] auto device() -> lt::renderer::IDevice *
{
return m_device.get();
}
[[nodiscard]] auto swapchain() -> lt::renderer::ISwapchain *
{
return m_swapchain.get();
}
void recreate_swapchain()
{
m_swapchain.reset();
m_swapchain = lt::renderer::ISwapchain::create(
constants::api,
surface(),
gpu(),
m_device.get()
);
}
[[nodiscard]] auto has_any_messages() const -> bool
{
return m_user_data->m_has_any_messages;
}
[[nodiscard]] auto has_any_messages_of(
lt::renderer::IMessenger ::MessageSeverity severity
) const -> uint32_t
{
return m_user_data->m_severity_counter.contains(severity);
}
private:
static void messenger_callback(
lt::renderer::IMessenger::MessageSeverity severity,
lt::renderer::IMessenger::MessageType type,
const lt::renderer::IMessenger::MessageData &data,
std::any &user_data
)
{
// I know this makes the tests too verbose...
// but makes it easier to figure out what the problem is when things fail on ci
log_trc("vulkan: {}", data.message);
std::ignore = data;
std::ignore = type;
auto *fixture = std::any_cast<UserData *>(user_data);
fixture->m_has_any_messages = true;
++fixture->m_severity_counter[severity];
}
struct UserData
{
std::unordered_map<lt::renderer::IMessenger::MessageSeverity, uint32_t> m_severity_counter;
bool m_has_any_messages {};
};
lt::memory::Scope<UserData> m_user_data = lt::memory::create_scope<UserData>();
lt::memory::Scope<lt::renderer::IMessenger> m_messenger = lt::renderer::IMessenger::create(
constants::api,
lt::renderer::IInstance::get(constants::api),
lt::renderer::IMessenger ::CreateInfo {
.severities = lt::renderer::IMessenger ::MessageSeverity::all,
.types = lt::renderer::IMessenger ::MessageType::all,
.callback = &messenger_callback,
.user_data = m_user_data.get(),
}
);
lt::memory::Scope<lt::renderer::IDevice> m_device {
lt::renderer::IDevice::create(constants::api, gpu(), surface())
};
lt::memory::Scope<lt::renderer::ISwapchain> m_swapchain {
lt::renderer::ISwapchain::create(constants::api, surface(), gpu(), m_device.get())
};
};
class Fixture_RendererSystem: public Fixture_SurfaceSystem
{
public:
Fixture_RendererSystem() = default;
[[nodiscard]] auto renderer_system() -> lt::renderer::System &
{
return m_system;
}
[[nodiscard]] auto has_any_messages() const -> bool
{
return m_user_data->m_has_any_messages;
}
[[nodiscard]] auto has_any_messages_of(
lt::renderer::IMessenger ::MessageSeverity severity
) const -> uint32_t
{
return m_user_data->m_severity_counter.contains(severity);
}
private:
static void messenger_callback(
lt::renderer::IMessenger::MessageSeverity severity,
lt::renderer::IMessenger::MessageType type,
const lt::renderer::IMessenger::MessageData &data,
std::any &user_data
)
{
// I know this makes the tests too verbose...
// but makes it easier to figure out what the problem is when things fail on ci
log_trc("vulkan: {}", data.message);
std::ignore = data;
std::ignore = type;
auto *fixture = std::any_cast<UserData *>(user_data);
fixture->m_has_any_messages = true;
++fixture->m_severity_counter[severity];
}
struct UserData
{
std::unordered_map<lt::renderer::IMessenger::MessageSeverity, uint32_t> m_severity_counter;
bool m_has_any_messages {};
};
lt::memory::Scope<UserData> m_user_data = lt::memory::create_scope<UserData>();
lt::renderer::System m_system = lt::renderer::System::CreateInfo {
.config = {
.target_api = constants::api,
.max_frames_in_flight = constants::frames_in_flight,
},
.registry = registry(),
.surface_entity = surface_entity(),
.debug_callback_info = lt::renderer::IMessenger ::CreateInfo {
.severities = lt::renderer::IMessenger ::MessageSeverity::all,
.types = lt::renderer::IMessenger ::MessageType::all,
.callback = &messenger_callback,
.user_data = m_user_data.get(),
}
};
};