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
|
#pragma once
|
||||||
|
|
||||||
#include <nova/api.h>
|
#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 <nova/types.h>
|
||||||
|
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
namespace Nova {
|
namespace Nova {
|
||||||
using WindowID = uptr;
|
|
||||||
using SurfaceID = uptr;
|
|
||||||
|
|
||||||
class RenderDriver;
|
|
||||||
|
|
||||||
class NOVA_API WindowDriver {
|
class NOVA_API WindowDriver {
|
||||||
public:
|
public:
|
||||||
static WindowDriver* create();
|
static WindowDriver* create();
|
||||||
|
|||||||
@@ -8,4 +8,9 @@
|
|||||||
|
|
||||||
namespace Nova {
|
namespace Nova {
|
||||||
enum class WindowAPI { WAYLAND, WINDOWS, X11 };
|
enum class WindowAPI { WAYLAND, WINDOWS, X11 };
|
||||||
|
|
||||||
|
class WindowDriver;
|
||||||
|
|
||||||
|
struct Window;
|
||||||
|
using WindowID = Window*;
|
||||||
} // namespace Nova
|
} // namespace Nova
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <nova/api.h>
|
#include <nova/api.h>
|
||||||
|
#include <nova/render/render_fwd.h>
|
||||||
#include <nova/types.h>
|
#include <nova/types.h>
|
||||||
|
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
@@ -14,10 +15,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace Nova {
|
namespace Nova {
|
||||||
using SurfaceID = uptr;
|
|
||||||
|
|
||||||
class RenderDriver;
|
|
||||||
|
|
||||||
struct NOVA_API RenderDevice {
|
struct NOVA_API RenderDevice {
|
||||||
enum class Vendor { UNKNOWN = 0, INTEL = 0x8086, AMD = 0x1002, NVIDIA = 0x10de };
|
enum class Vendor { UNKNOWN = 0, INTEL = 0x8086, AMD = 0x1002, NVIDIA = 0x10de };
|
||||||
enum class Type { OTHER = 0, INTEGRATED = 1, DISCRETE = 2, VIRTUAL = 3, CPU = 4 };
|
enum class Type { OTHER = 0, INTEGRATED = 1, DISCRETE = 2, VIRTUAL = 3, CPU = 4 };
|
||||||
@@ -29,7 +26,7 @@ namespace Nova {
|
|||||||
void* handle;
|
void* handle;
|
||||||
|
|
||||||
static u32 choose_device(RenderDriver* driver, std::span<const SurfaceID> surfaces = {});
|
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()});
|
return choose_device(driver, {surfaces.begin(), surfaces.end()});
|
||||||
}
|
}
|
||||||
static u32 choose_device(RenderDriver* driver, SurfaceID surface) {
|
static u32 choose_device(RenderDriver* driver, SurfaceID surface) {
|
||||||
|
|||||||
@@ -7,18 +7,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <nova/api.h>
|
#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 <nova/types.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace Nova {
|
namespace Nova {
|
||||||
using WindowID = uptr;
|
|
||||||
using SurfaceID = uptr;
|
|
||||||
|
|
||||||
struct RenderDevice;
|
|
||||||
class WindowDriver;
|
|
||||||
|
|
||||||
class NOVA_API RenderDriver {
|
class NOVA_API RenderDriver {
|
||||||
public:
|
public:
|
||||||
static RenderDriver* create(RenderAPI api, WindowDriver* window_driver = nullptr);
|
static RenderDriver* create(RenderAPI api, WindowDriver* window_driver = nullptr);
|
||||||
|
|||||||
@@ -8,4 +8,10 @@
|
|||||||
|
|
||||||
namespace Nova {
|
namespace Nova {
|
||||||
enum class RenderAPI { DX12, VULKAN };
|
enum class RenderAPI { DX12, VULKAN };
|
||||||
|
|
||||||
|
class RenderDriver;
|
||||||
|
struct RenderDevice;
|
||||||
|
|
||||||
|
struct Surface;
|
||||||
|
using SurfaceID = Surface*;
|
||||||
} // namespace Nova
|
} // namespace Nova
|
||||||
@@ -7,8 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <nova/api.h>
|
#include <nova/api.h>
|
||||||
#include <nova/render/render_api.h>
|
#include <nova/render/render_fwd.h>
|
||||||
#include <nova/render/render_driver.h>
|
|
||||||
|
|
||||||
namespace Nova {
|
namespace Nova {
|
||||||
class NOVA_API Renderer {
|
class NOVA_API Renderer {
|
||||||
|
|||||||
@@ -74,19 +74,18 @@ const RenderDevice& VulkanRenderDriver::get_device(const u32 p_index) const {
|
|||||||
return m_devices[p_index];
|
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_AUTO_TRACE();
|
||||||
NOVA_ASSERT(p_index < m_devices.size());
|
NOVA_ASSERT(p_index < m_devices.size());
|
||||||
NOVA_ASSERT(p_surface);
|
NOVA_ASSERT(p_surface);
|
||||||
|
|
||||||
// TODO: Check other queue families?
|
// TODO: Check other queue families?
|
||||||
|
|
||||||
SurfaceData* data = reinterpret_cast<SurfaceData*>(p_surface);
|
|
||||||
VkBool32 supported = false;
|
VkBool32 supported = false;
|
||||||
if (vkGetPhysicalDeviceSurfaceSupportKHR(
|
if (vkGetPhysicalDeviceSurfaceSupportKHR(
|
||||||
static_cast<VkPhysicalDevice>(m_devices[p_index].handle),
|
static_cast<VkPhysicalDevice>(m_devices[p_index].handle),
|
||||||
0,
|
0,
|
||||||
data->handle,
|
p_surface->handle,
|
||||||
&supported
|
&supported
|
||||||
)
|
)
|
||||||
!= VK_SUCCESS) {
|
!= VK_SUCCESS) {
|
||||||
@@ -95,7 +94,7 @@ bool VulkanRenderDriver::get_device_supports_surface(const u32 p_index, const Su
|
|||||||
return supported;
|
return supported;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanRenderDriver::select_device(u32 p_index) {
|
void VulkanRenderDriver::select_device(const u32 p_index) {
|
||||||
NOVA_AUTO_TRACE();
|
NOVA_AUTO_TRACE();
|
||||||
NOVA_ASSERT(!m_device);
|
NOVA_ASSERT(!m_device);
|
||||||
NOVA_ASSERT(p_index < m_devices.size());
|
NOVA_ASSERT(p_index < m_devices.size());
|
||||||
@@ -112,17 +111,16 @@ void VulkanRenderDriver::select_device(u32 p_index) {
|
|||||||
_init_device(queues);
|
_init_device(queues);
|
||||||
}
|
}
|
||||||
|
|
||||||
SurfaceID VulkanRenderDriver::create_surface(const WindowID p_window) {
|
SurfaceID VulkanRenderDriver::create_surface(WindowID p_window) {
|
||||||
NOVA_AUTO_TRACE();
|
NOVA_AUTO_TRACE();
|
||||||
NOVA_ASSERT(m_window_driver);
|
NOVA_ASSERT(m_window_driver);
|
||||||
return m_window_driver->create_surface(p_window, this);
|
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();
|
NOVA_AUTO_TRACE();
|
||||||
SurfaceData* data = reinterpret_cast<SurfaceData*>(p_surface);
|
vkDestroySurfaceKHR(m_instance, p_surface->handle, get_allocator(VK_OBJECT_TYPE_SURFACE_KHR));
|
||||||
vkDestroySurfaceKHR(m_instance, data->handle, get_allocator(VK_OBJECT_TYPE_SURFACE_KHR));
|
delete p_surface;
|
||||||
delete data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VkInstance VulkanRenderDriver::get_instance() const {
|
VkInstance VulkanRenderDriver::get_instance() const {
|
||||||
|
|||||||
@@ -14,9 +14,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace Nova {
|
namespace Nova {
|
||||||
struct SurfaceData {
|
struct Surface {
|
||||||
VkSurfaceKHR handle = VK_NULL_HANDLE;
|
VkSurfaceKHR handle = VK_NULL_HANDLE;
|
||||||
// TODO: Add stuff here
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class VulkanRenderDriver final : public RenderDriver {
|
class VulkanRenderDriver final : public RenderDriver {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ X11WindowDriver::X11WindowDriver() {
|
|||||||
X11WindowDriver::~X11WindowDriver() {
|
X11WindowDriver::~X11WindowDriver() {
|
||||||
NOVA_AUTO_TRACE();
|
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);
|
XDestroyWindow(m_display, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,15 +59,15 @@ void X11WindowDriver::poll_events() {
|
|||||||
XEvent event;
|
XEvent event;
|
||||||
XNextEvent(m_display, &event);
|
XNextEvent(m_display, &event);
|
||||||
|
|
||||||
const WindowID window = event.xany.window;
|
X11::Window handle = event.xany.window;
|
||||||
WindowData& data = m_windows[window];
|
Nova::Window& window = m_windows[handle];
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case ConfigureNotify: {
|
case ConfigureNotify: {
|
||||||
XConfigureEvent xce = event.xconfigure;
|
XConfigureEvent xce = event.xconfigure;
|
||||||
if (xce.width != data.width || xce.height != data.height) {
|
if (xce.width != window.width || xce.height != window.height) {
|
||||||
data.width = xce.width;
|
window.width = xce.width;
|
||||||
data.height = xce.height;
|
window.height = xce.height;
|
||||||
NOVA_DEBUG("Window event: RESIZED ({}x{})", xce.width, xce.height);
|
NOVA_DEBUG("Window event: RESIZED ({}x{})", xce.width, xce.height);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -75,10 +75,12 @@ void X11WindowDriver::poll_events() {
|
|||||||
case ClientMessage: {
|
case ClientMessage: {
|
||||||
if (event.xclient.data.l[0] == static_cast<long>(m_window_close_atom)) {
|
if (event.xclient.data.l[0] == static_cast<long>(m_window_close_atom)) {
|
||||||
NOVA_DEBUG("Window event: CLOSED");
|
NOVA_DEBUG("Window event: CLOSED");
|
||||||
destroy_window(window);
|
destroy_window(&window);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DestroyNotify:
|
||||||
|
case UnmapNotify:
|
||||||
case MapNotify:
|
case MapNotify:
|
||||||
case ReparentNotify:
|
case ReparentNotify:
|
||||||
// Ignore these events
|
// 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) {
|
WindowID X11WindowDriver::create_window(const std::string_view p_title, const u32 p_width, const u32 p_height) {
|
||||||
NOVA_AUTO_TRACE();
|
NOVA_AUTO_TRACE();
|
||||||
|
|
||||||
const WindowID window = XCreateSimpleWindow(m_display, DefaultRootWindow(m_display), 0, 0, p_width, p_height, 0, 0, 0);
|
X11::Window handle = 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;
|
|
||||||
|
|
||||||
XSetWMProtocols(m_display, window, &m_window_close_atom, 1);
|
Nova::Window& window = m_windows[handle];
|
||||||
XSelectInput(m_display, window, StructureNotifyMask);
|
window.width = p_width;
|
||||||
XStoreName(m_display, window, p_title.data());
|
window.height = p_height;
|
||||||
XMapWindow(m_display, window);
|
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);
|
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();
|
NOVA_AUTO_TRACE();
|
||||||
if (!m_windows.contains(p_window)) {
|
NOVA_ASSERT(p_window);
|
||||||
return;
|
XDestroyWindow(m_display, p_window->handle);
|
||||||
}
|
m_windows.erase(p_window->handle);
|
||||||
XDestroyWindow(m_display, p_window);
|
|
||||||
m_windows.erase(p_window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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_AUTO_TRACE();
|
||||||
NOVA_ASSERT(m_windows.contains(p_window));
|
NOVA_ASSERT(p_window);
|
||||||
XStoreName(m_display, p_window, p_title.data());
|
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_AUTO_TRACE();
|
||||||
NOVA_ASSERT(m_windows.contains(p_window));
|
NOVA_ASSERT(p_window);
|
||||||
XResizeWindow(m_display, p_window, p_width, p_height);
|
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_AUTO_TRACE();
|
||||||
NOVA_ASSERT(m_windows.contains(p_window));
|
NOVA_ASSERT(p_window);
|
||||||
XMoveWindow(m_display, p_window, p_x, p_y);
|
XMoveWindow(m_display, p_window->handle, p_x, p_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* X11WindowDriver::get_surface_extension() const {
|
const char* X11WindowDriver::get_surface_extension() const {
|
||||||
@@ -150,9 +152,9 @@ const char* X11WindowDriver::get_surface_extension() const {
|
|||||||
#endif
|
#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_AUTO_TRACE();
|
||||||
NOVA_ASSERT(m_windows.contains(p_window));
|
NOVA_ASSERT(p_window);
|
||||||
NOVA_ASSERT(p_driver);
|
NOVA_ASSERT(p_driver);
|
||||||
NOVA_ASSERT(p_driver->get_api() == RenderAPI::VULKAN);
|
NOVA_ASSERT(p_driver->get_api() == RenderAPI::VULKAN);
|
||||||
|
|
||||||
@@ -160,19 +162,19 @@ SurfaceID X11WindowDriver::create_surface(const WindowID p_window, RenderDriver*
|
|||||||
VkXlibSurfaceCreateInfoKHR create {};
|
VkXlibSurfaceCreateInfoKHR create {};
|
||||||
create.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
|
create.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
|
||||||
create.dpy = m_display;
|
create.dpy = m_display;
|
||||||
create.window = static_cast<Window>(p_window);
|
create.window = p_window->handle;
|
||||||
|
|
||||||
const auto vkrd = static_cast<VulkanRenderDriver*>(p_driver);
|
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)
|
if (vkCreateXlibSurfaceKHR(vkrd->get_instance(), &create, vkrd->get_allocator(VK_OBJECT_TYPE_SURFACE_KHR), &surface->handle)
|
||||||
!= VK_SUCCESS) {
|
!= VK_SUCCESS) {
|
||||||
throw std::runtime_error("Failed to create Vulkan surface");
|
throw std::runtime_error("Failed to create Vulkan surface");
|
||||||
}
|
}
|
||||||
|
|
||||||
return SurfaceID(surface);
|
return surface;
|
||||||
#else
|
#else
|
||||||
return SurfaceID(nullptr);
|
return nullptr;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,15 @@
|
|||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace X11 {
|
||||||
|
using Window = ::Window;
|
||||||
|
using Display = ::Display;
|
||||||
|
using Atom = ::Atom;
|
||||||
|
} // namespace X11
|
||||||
|
|
||||||
namespace Nova {
|
namespace Nova {
|
||||||
struct WindowData {
|
struct Window {
|
||||||
|
X11::Window handle = 0;
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
};
|
};
|
||||||
@@ -42,10 +49,9 @@ namespace Nova {
|
|||||||
[[nodiscard]] SurfaceID create_surface(WindowID window, RenderDriver* driver) override;
|
[[nodiscard]] SurfaceID create_surface(WindowID window, RenderDriver* driver) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Display* m_display = nullptr;
|
X11::Display* m_display = nullptr;
|
||||||
std::unordered_map<WindowID, WindowData> m_windows;
|
X11::Atom m_window_close_atom = 0;
|
||||||
|
std::unordered_map<X11::Window, Nova::Window> m_windows;
|
||||||
Atom m_window_close_atom = 0;
|
|
||||||
};
|
};
|
||||||
} // namespace Nova
|
} // namespace Nova
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <nova/core/debug.h>
|
#include <nova/core/debug.h>
|
||||||
|
#include <nova/render/render_driver.h>
|
||||||
#include <nova/render/renderer.h>
|
#include <nova/render/renderer.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|||||||
Reference in New Issue
Block a user