Redefine ID types to be actual pointers

Redefined various ID types to be aliases of pointers instead of casting
a uintptr_t to the needed pointer.

e.g. SurfaceID = Surface*
This commit is contained in:
2025-04-16 23:46:00 +10:00
parent 546c485e1e
commit 4c6712e2fe
11 changed files with 77 additions and 73 deletions

View File

@@ -7,17 +7,13 @@
#pragma once
#include <nova/api.h>
#include <nova/platform/window_api.h>
#include <nova/platform/window_fwd.h>
#include <nova/render/render_fwd.h>
#include <nova/types.h>
#include <string_view>
namespace Nova {
using WindowID = uptr;
using SurfaceID = uptr;
class RenderDriver;
class NOVA_API WindowDriver {
public:
static WindowDriver* create();

View File

@@ -8,4 +8,9 @@
namespace Nova {
enum class WindowAPI { WAYLAND, WINDOWS, X11 };
class WindowDriver;
struct Window;
using WindowID = Window*;
} // namespace Nova

View File

@@ -7,6 +7,7 @@
#pragma once
#include <nova/api.h>
#include <nova/render/render_fwd.h>
#include <nova/types.h>
#include <initializer_list>
@@ -14,10 +15,6 @@
#include <string>
namespace Nova {
using SurfaceID = uptr;
class RenderDriver;
struct NOVA_API RenderDevice {
enum class Vendor { UNKNOWN = 0, INTEL = 0x8086, AMD = 0x1002, NVIDIA = 0x10de };
enum class Type { OTHER = 0, INTEGRATED = 1, DISCRETE = 2, VIRTUAL = 3, CPU = 4 };
@@ -29,7 +26,7 @@ namespace Nova {
void* handle;
static u32 choose_device(RenderDriver* driver, std::span<const SurfaceID> surfaces = {});
static u32 choose_device(RenderDriver* driver, std::initializer_list<SurfaceID> surfaces) {
static u32 choose_device(RenderDriver* driver, std::initializer_list<const SurfaceID> surfaces) {
return choose_device(driver, {surfaces.begin(), surfaces.end()});
}
static u32 choose_device(RenderDriver* driver, SurfaceID surface) {

View File

@@ -7,18 +7,13 @@
#pragma once
#include <nova/api.h>
#include <nova/render/render_api.h>
#include <nova/platform/window_fwd.h>
#include <nova/render/render_fwd.h>
#include <nova/types.h>
#include <string>
namespace Nova {
using WindowID = uptr;
using SurfaceID = uptr;
struct RenderDevice;
class WindowDriver;
class NOVA_API RenderDriver {
public:
static RenderDriver* create(RenderAPI api, WindowDriver* window_driver = nullptr);

View File

@@ -8,4 +8,10 @@
namespace Nova {
enum class RenderAPI { DX12, VULKAN };
class RenderDriver;
struct RenderDevice;
struct Surface;
using SurfaceID = Surface*;
} // namespace Nova

View File

@@ -7,8 +7,7 @@
#pragma once
#include <nova/api.h>
#include <nova/render/render_api.h>
#include <nova/render/render_driver.h>
#include <nova/render/render_fwd.h>
namespace Nova {
class NOVA_API Renderer {

View File

@@ -74,19 +74,18 @@ const RenderDevice& VulkanRenderDriver::get_device(const u32 p_index) const {
return m_devices[p_index];
}
bool VulkanRenderDriver::get_device_supports_surface(const u32 p_index, const SurfaceID p_surface) const {
bool VulkanRenderDriver::get_device_supports_surface(const u32 p_index, SurfaceID p_surface) const {
NOVA_AUTO_TRACE();
NOVA_ASSERT(p_index < m_devices.size());
NOVA_ASSERT(p_surface);
// TODO: Check other queue families?
SurfaceData* data = reinterpret_cast<SurfaceData*>(p_surface);
VkBool32 supported = false;
if (vkGetPhysicalDeviceSurfaceSupportKHR(
static_cast<VkPhysicalDevice>(m_devices[p_index].handle),
0,
data->handle,
p_surface->handle,
&supported
)
!= VK_SUCCESS) {
@@ -95,7 +94,7 @@ bool VulkanRenderDriver::get_device_supports_surface(const u32 p_index, const Su
return supported;
}
void VulkanRenderDriver::select_device(u32 p_index) {
void VulkanRenderDriver::select_device(const u32 p_index) {
NOVA_AUTO_TRACE();
NOVA_ASSERT(!m_device);
NOVA_ASSERT(p_index < m_devices.size());
@@ -112,17 +111,16 @@ void VulkanRenderDriver::select_device(u32 p_index) {
_init_device(queues);
}
SurfaceID VulkanRenderDriver::create_surface(const WindowID p_window) {
SurfaceID VulkanRenderDriver::create_surface(WindowID p_window) {
NOVA_AUTO_TRACE();
NOVA_ASSERT(m_window_driver);
return m_window_driver->create_surface(p_window, this);
}
void VulkanRenderDriver::destroy_surface(const SurfaceID p_surface) {
void VulkanRenderDriver::destroy_surface(SurfaceID p_surface) {
NOVA_AUTO_TRACE();
SurfaceData* data = reinterpret_cast<SurfaceData*>(p_surface);
vkDestroySurfaceKHR(m_instance, data->handle, get_allocator(VK_OBJECT_TYPE_SURFACE_KHR));
delete data;
vkDestroySurfaceKHR(m_instance, p_surface->handle, get_allocator(VK_OBJECT_TYPE_SURFACE_KHR));
delete p_surface;
}
VkInstance VulkanRenderDriver::get_instance() const {

View File

@@ -14,9 +14,8 @@
#include <vector>
namespace Nova {
struct SurfaceData {
struct Surface {
VkSurfaceKHR handle = VK_NULL_HANDLE;
// TODO: Add stuff here
};
class VulkanRenderDriver final : public RenderDriver {

View File

@@ -36,7 +36,7 @@ X11WindowDriver::X11WindowDriver() {
X11WindowDriver::~X11WindowDriver() {
NOVA_AUTO_TRACE();
for (const auto window : std::views::keys(m_windows)) {
for (X11::Window window : std::views::keys(m_windows)) {
XDestroyWindow(m_display, window);
}
@@ -59,15 +59,15 @@ void X11WindowDriver::poll_events() {
XEvent event;
XNextEvent(m_display, &event);
const WindowID window = event.xany.window;
WindowData& data = m_windows[window];
X11::Window handle = event.xany.window;
Nova::Window& window = m_windows[handle];
switch (event.type) {
case ConfigureNotify: {
XConfigureEvent xce = event.xconfigure;
if (xce.width != data.width || xce.height != data.height) {
data.width = xce.width;
data.height = xce.height;
if (xce.width != window.width || xce.height != window.height) {
window.width = xce.width;
window.height = xce.height;
NOVA_DEBUG("Window event: RESIZED ({}x{})", xce.width, xce.height);
}
break;
@@ -75,10 +75,12 @@ void X11WindowDriver::poll_events() {
case ClientMessage: {
if (event.xclient.data.l[0] == static_cast<long>(m_window_close_atom)) {
NOVA_DEBUG("Window event: CLOSED");
destroy_window(window);
destroy_window(&window);
}
break;
}
case DestroyNotify:
case UnmapNotify:
case MapNotify:
case ReparentNotify:
// Ignore these events
@@ -101,45 +103,45 @@ u32 X11WindowDriver::get_window_count() const {
WindowID X11WindowDriver::create_window(const std::string_view p_title, const u32 p_width, const u32 p_height) {
NOVA_AUTO_TRACE();
const WindowID window = XCreateSimpleWindow(m_display, DefaultRootWindow(m_display), 0, 0, p_width, p_height, 0, 0, 0);
WindowData& data = m_windows[window];
data.width = p_width;
data.height = p_height;
X11::Window handle = XCreateSimpleWindow(m_display, DefaultRootWindow(m_display), 0, 0, p_width, p_height, 0, 0, 0);
XSetWMProtocols(m_display, window, &m_window_close_atom, 1);
XSelectInput(m_display, window, StructureNotifyMask);
XStoreName(m_display, window, p_title.data());
XMapWindow(m_display, window);
Nova::Window& window = m_windows[handle];
window.width = p_width;
window.height = p_height;
window.handle = handle;
XSetWMProtocols(m_display, handle, &m_window_close_atom, 1);
XSelectInput(m_display, handle, StructureNotifyMask);
XStoreName(m_display, handle, p_title.data());
XMapWindow(m_display, handle);
XFlush(m_display);
return window;
return &window;
}
void X11WindowDriver::destroy_window(const WindowID p_window) {
void X11WindowDriver::destroy_window(WindowID p_window) {
NOVA_AUTO_TRACE();
if (!m_windows.contains(p_window)) {
return;
}
XDestroyWindow(m_display, p_window);
m_windows.erase(p_window);
NOVA_ASSERT(p_window);
XDestroyWindow(m_display, p_window->handle);
m_windows.erase(p_window->handle);
}
void X11WindowDriver::set_window_title(const WindowID p_window, const std::string_view p_title) {
void X11WindowDriver::set_window_title(WindowID p_window, const std::string_view p_title) {
NOVA_AUTO_TRACE();
NOVA_ASSERT(m_windows.contains(p_window));
XStoreName(m_display, p_window, p_title.data());
NOVA_ASSERT(p_window);
XStoreName(m_display, p_window->handle, p_title.data());
}
void X11WindowDriver::set_window_size(const WindowID p_window, const u32 p_width, const u32 p_height) {
void X11WindowDriver::set_window_size(WindowID p_window, const u32 p_width, const u32 p_height) {
NOVA_AUTO_TRACE();
NOVA_ASSERT(m_windows.contains(p_window));
XResizeWindow(m_display, p_window, p_width, p_height);
NOVA_ASSERT(p_window);
XResizeWindow(m_display, p_window->handle, p_width, p_height);
}
void X11WindowDriver::set_window_position(const WindowID p_window, const i32 p_x, const i32 p_y) {
void X11WindowDriver::set_window_position(WindowID p_window, const i32 p_x, const i32 p_y) {
NOVA_AUTO_TRACE();
NOVA_ASSERT(m_windows.contains(p_window));
XMoveWindow(m_display, p_window, p_x, p_y);
NOVA_ASSERT(p_window);
XMoveWindow(m_display, p_window->handle, p_x, p_y);
}
const char* X11WindowDriver::get_surface_extension() const {
@@ -150,9 +152,9 @@ const char* X11WindowDriver::get_surface_extension() const {
#endif
}
SurfaceID X11WindowDriver::create_surface(const WindowID p_window, RenderDriver* p_driver) {
SurfaceID X11WindowDriver::create_surface(WindowID p_window, RenderDriver* p_driver) {
NOVA_AUTO_TRACE();
NOVA_ASSERT(m_windows.contains(p_window));
NOVA_ASSERT(p_window);
NOVA_ASSERT(p_driver);
NOVA_ASSERT(p_driver->get_api() == RenderAPI::VULKAN);
@@ -160,19 +162,19 @@ SurfaceID X11WindowDriver::create_surface(const WindowID p_window, RenderDriver*
VkXlibSurfaceCreateInfoKHR create {};
create.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
create.dpy = m_display;
create.window = static_cast<Window>(p_window);
create.window = p_window->handle;
const auto vkrd = static_cast<VulkanRenderDriver*>(p_driver);
SurfaceData* surface = new SurfaceData();
Surface* surface = new Surface();
if (vkCreateXlibSurfaceKHR(vkrd->get_instance(), &create, vkrd->get_allocator(VK_OBJECT_TYPE_SURFACE_KHR), &surface->handle)
!= VK_SUCCESS) {
throw std::runtime_error("Failed to create Vulkan surface");
}
return SurfaceID(surface);
return surface;
#else
return SurfaceID(nullptr);
return nullptr;
#endif
}

View File

@@ -13,8 +13,15 @@
#include <unordered_map>
namespace X11 {
using Window = ::Window;
using Display = ::Display;
using Atom = ::Atom;
} // namespace X11
namespace Nova {
struct WindowData {
struct Window {
X11::Window handle = 0;
int width = 0;
int height = 0;
};
@@ -42,10 +49,9 @@ namespace Nova {
[[nodiscard]] SurfaceID create_surface(WindowID window, RenderDriver* driver) override;
private:
Display* m_display = nullptr;
std::unordered_map<WindowID, WindowData> m_windows;
Atom m_window_close_atom = 0;
X11::Display* m_display = nullptr;
X11::Atom m_window_close_atom = 0;
std::unordered_map<X11::Window, Nova::Window> m_windows;
};
} // namespace Nova

View File

@@ -5,6 +5,7 @@
*/
#include <nova/core/debug.h>
#include <nova/render/render_driver.h>
#include <nova/render/renderer.h>
#include <memory>