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:
@@ -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();
|
||||
|
||||
@@ -8,4 +8,9 @@
|
||||
|
||||
namespace Nova {
|
||||
enum class WindowAPI { WAYLAND, WINDOWS, X11 };
|
||||
|
||||
class WindowDriver;
|
||||
|
||||
struct Window;
|
||||
using WindowID = Window*;
|
||||
} // namespace Nova
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -8,4 +8,10 @@
|
||||
|
||||
namespace Nova {
|
||||
enum class RenderAPI { DX12, VULKAN };
|
||||
|
||||
class RenderDriver;
|
||||
struct RenderDevice;
|
||||
|
||||
struct Surface;
|
||||
using SurfaceID = Surface*;
|
||||
} // namespace Nova
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include <nova/core/debug.h>
|
||||
#include <nova/render/render_driver.h>
|
||||
#include <nova/render/renderer.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
Reference in New Issue
Block a user