Cleanup & incomplete Vulkan.
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 1m31s
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 1m31s
This commit is contained in:
@@ -69,8 +69,7 @@ target_include_directories(ReWindow PUBLIC ${Event_SOURCE_DIR}/include)
|
||||
set_target_properties(ReWindow PROPERTIES LINKER_LANGUAGE CXX)
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
find_package(Vulkan REQUIRED)
|
||||
target_link_libraries(ReWindow PUBLIC X11 Event jlog Vulkan::Vulkan)
|
||||
target_link_libraries(ReWindow PUBLIC X11 Event jlog)
|
||||
target_link_libraries(ReWindow PUBLIC)
|
||||
|
||||
add_executable(ReWindowDemo main.cpp)
|
||||
|
@@ -356,7 +356,7 @@ public:
|
||||
|
||||
/// This function instructs the operating system to create the actual window, and give it to us to control.
|
||||
/// Calling this function, therefore, creates the real 'window' object on the operating system.
|
||||
virtual void Open() = 0;
|
||||
[[nodiscard]] virtual bool Open() = 0;
|
||||
};
|
||||
|
||||
// TODO in the event that we can't find OpenGL or the Open() fails, have a way to say so without throwing an exception.
|
||||
@@ -367,14 +367,16 @@ public:
|
||||
void SwapBuffers() override;
|
||||
void SetVsyncEnabled(bool state) override;
|
||||
std::string GetGraphicsDriverVendor() override;
|
||||
void Open() override;
|
||||
[[nodiscard]] bool Open() override;
|
||||
public:
|
||||
OpenGLWindow(const std::string& title, int width, int height, uint8_t gl_major, uint8_t gl_minor);
|
||||
};
|
||||
|
||||
class ReWindow::VulkanWindow : public RWindow {
|
||||
public:
|
||||
void SwapBuffers() override;
|
||||
void SetVsyncEnabled(bool state) override;
|
||||
std::string GetGraphicsDriverVendor() override;
|
||||
void Open() override;
|
||||
[[nodiscard]] bool Open() override;
|
||||
VulkanWindow(const std::string& title, int width, int height);
|
||||
};
|
@@ -5,6 +5,7 @@ namespace ReWindow::Logger {
|
||||
using namespace Colors;
|
||||
|
||||
GenericLogger Info {"ReWindow", GlobalLogFile, Gray, Gray, Gray, Gray};
|
||||
GenericLogger Fatal {"ReWindow::fatal", GlobalLogFile, Reds::Crimson, Gray, Gray, Reds::Crimson, White};
|
||||
GenericLogger Debug {"ReWindow::debug", GlobalLogFile, Purples::Purple, Gray, Gray, Purples::Purple, White};
|
||||
GenericLogger Fatal {"ReWindow::Fatal", GlobalLogFile, Reds::Crimson, Gray, Gray, Reds::Crimson, White};
|
||||
GenericLogger Debug {"ReWindow::Debug", GlobalLogFile, Purples::Purple, Gray, Gray, Purples::Purple, White};
|
||||
GenericLogger Error {"ReWindow::Error", GlobalLogFile, Red, Gray, Gray, Gray};
|
||||
}
|
||||
|
@@ -8,48 +8,57 @@ using namespace ReWindow;
|
||||
void* glx_lib = nullptr;
|
||||
void* opengl_lib = nullptr;
|
||||
|
||||
typedef const GLubyte* (*glGetString_t)(GLenum name);
|
||||
glGetString_t func_glGetString = nullptr;
|
||||
namespace OpenGL {
|
||||
bool constructor_success = false;
|
||||
|
||||
typedef Bool (*glXMakeCurrent_t)(Display *dpy, GLXDrawable drawable, GLXContext ctx);
|
||||
glXMakeCurrent_t func_glXMakeCurrent = nullptr;
|
||||
typedef const GLubyte *(*glGetString_t)(GLenum name);
|
||||
glGetString_t glGetString = nullptr;
|
||||
|
||||
typedef void* (*glXGetProcAddressARB_t)(const GLubyte *procname);
|
||||
glXGetProcAddressARB_t func_glXGetProcAddressARB = nullptr;
|
||||
typedef Bool (*glXMakeCurrent_t)(Display *dpy, GLXDrawable drawable, GLXContext ctx);
|
||||
glXMakeCurrent_t glXMakeCurrent = nullptr;
|
||||
|
||||
typedef void (*glXSwapBuffers_t)(Display *dpy, GLXDrawable drawable);
|
||||
glXSwapBuffers_t func_glXSwapBuffers = nullptr;
|
||||
typedef void *(*glXGetProcAddressARB_t)(const GLubyte *procname);
|
||||
glXGetProcAddressARB_t glXGetProcAddressARB = nullptr;
|
||||
|
||||
typedef GLXContext (*glXCreateContext_t)(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct);
|
||||
glXCreateContext_t func_glXCreateContext = nullptr;
|
||||
typedef void (*glXSwapBuffers_t)(Display *dpy, GLXDrawable drawable);
|
||||
glXSwapBuffers_t glXSwapBuffers = nullptr;
|
||||
|
||||
typedef GLXFBConfig *(*glXChooseFBConfig_t)(Display *dpy, int screen, const int *attribList, int *nItems);
|
||||
glXChooseFBConfig_t func_glXChooseFBConfig = nullptr;
|
||||
typedef GLXContext (*glXCreateContext_t)(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct);
|
||||
glXCreateContext_t glXCreateContext = nullptr;
|
||||
|
||||
typedef XVisualInfo* (*glXGetVisualFromFBConfig_t)(Display *dpy, GLXFBConfig config);
|
||||
glXGetVisualFromFBConfig_t func_glXGetVisualFromFBConfig = nullptr;
|
||||
typedef GLXFBConfig *(*glXChooseFBConfig_t)(Display *dpy, int screen, const int *attribList, int *nItems);
|
||||
glXChooseFBConfig_t glXChooseFBConfig = nullptr;
|
||||
|
||||
typedef XVisualInfo* (*glXChooseVisual_t)(Display *dpy, int screen, const int *attribList);
|
||||
glXChooseVisual_t func_glXChooseVisual = nullptr;
|
||||
typedef XVisualInfo *(*glXGetVisualFromFBConfig_t)(Display *dpy, GLXFBConfig config);
|
||||
glXGetVisualFromFBConfig_t glXGetVisualFromFBConfig = nullptr;
|
||||
|
||||
typedef XVisualInfo *(*glXChooseVisual_t)(Display *dpy, int screen, const int *attribList);
|
||||
glXChooseVisual_t glXChooseVisual = nullptr;
|
||||
|
||||
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display *, GLXFBConfig, GLXContext, Bool, const int *);
|
||||
}
|
||||
|
||||
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
|
||||
GLXContext gl_context;
|
||||
|
||||
|
||||
void OpenGLWindow::SwapBuffers() {
|
||||
func_glXSwapBuffers(xVars.display,xVars.window);
|
||||
OpenGL::glXSwapBuffers(xVars.display,xVars.window);
|
||||
}
|
||||
|
||||
void OpenGLWindow::SetVsyncEnabled(bool state) {
|
||||
PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT;
|
||||
glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) func_glXGetProcAddressARB((const GLubyte *) "glXSwapIntervalEXT");
|
||||
glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) OpenGL::glXGetProcAddressARB((const GLubyte *) "glXSwapIntervalEXT");
|
||||
glXSwapIntervalEXT(xVars.display, xVars.window, state);
|
||||
}
|
||||
|
||||
std::string OpenGLWindow::GetGraphicsDriverVendor() {
|
||||
return std::string((const char*) func_glGetString(GL_VENDOR));
|
||||
return std::string((const char*) OpenGL::glGetString(GL_VENDOR));
|
||||
}
|
||||
|
||||
void OpenGLWindow::Open() {
|
||||
bool OpenGLWindow::Open() {
|
||||
if (!OpenGL::constructor_success)
|
||||
return false;
|
||||
|
||||
xVars.display = XOpenDisplay(nullptr);
|
||||
xVars.defaultScreen = DefaultScreen(xVars.display);
|
||||
|
||||
@@ -58,18 +67,22 @@ void OpenGLWindow::Open() {
|
||||
xVars.xSetWindowAttributes.override_redirect = True;
|
||||
xVars.xSetWindowAttributes.event_mask = ExposureMask;
|
||||
|
||||
auto glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)func_glXGetProcAddressARB((const GLubyte*)"glXCreateContextAttribsARB");
|
||||
auto glXCreateContextAttribsARB = (OpenGL::glXCreateContextAttribsARBProc) OpenGL::glXGetProcAddressARB((const GLubyte*)"glXCreateContextAttribsARB");
|
||||
XVisualInfo* vi = nullptr;
|
||||
|
||||
// Fallback to the old way if you somehow don't have this.
|
||||
if (!glXCreateContextAttribsARB) {
|
||||
GLint glAttributes[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None};
|
||||
xVars.visual = func_glXChooseVisual(xVars.display, xVars.defaultScreen, glAttributes);
|
||||
gl_context = func_glXCreateContext(xVars.display, xVars.visual, nullptr, GL_TRUE);
|
||||
xVars.visual = OpenGL::glXChooseVisual(xVars.display, xVars.defaultScreen, glAttributes);
|
||||
gl_context = OpenGL::glXCreateContext(xVars.display, xVars.visual, nullptr, GL_TRUE);
|
||||
xVars.window = XCreateWindow(xVars.display, RootWindow(xVars.display, xVars.defaultScreen), 0, 0, width, height, 0, xVars.visual->depth,
|
||||
InputOutput, xVars.visual->visual, CWBackPixel | CWColormap | CWBorderPixel | NoEventMask, &xVars.xSetWindowAttributes);
|
||||
ReWindow::Logger::Debug("Created OpenGL Context with glXCreateContext.");
|
||||
Logger::Debug("Created OpenGL Context with glXCreateContext.");
|
||||
|
||||
if (!xVars.window)
|
||||
return false;
|
||||
}
|
||||
|
||||
else {
|
||||
static int visual_attributes[]
|
||||
{
|
||||
@@ -81,15 +94,15 @@ void OpenGLWindow::Open() {
|
||||
};
|
||||
|
||||
int fb_count;
|
||||
GLXFBConfig* fb_configurations = func_glXChooseFBConfig(xVars.display, xVars.defaultScreen, visual_attributes, &fb_count);
|
||||
GLXFBConfig* fb_configurations = OpenGL::glXChooseFBConfig(xVars.display, xVars.defaultScreen, visual_attributes, &fb_count);
|
||||
if (!fb_configurations || fb_count == 0)
|
||||
throw std::runtime_error("Couldn't get framebuffer configuration.");
|
||||
return false;
|
||||
|
||||
GLXFBConfig best_fbc = fb_configurations[0];
|
||||
vi = func_glXGetVisualFromFBConfig(xVars.display, best_fbc);
|
||||
vi = OpenGL::glXGetVisualFromFBConfig(xVars.display, best_fbc);
|
||||
|
||||
if (!vi)
|
||||
throw std::runtime_error("Couldn't visual info from framebuffer configuration.");
|
||||
return false;
|
||||
|
||||
xVars.xSetWindowAttributes.colormap = XCreateColormap(xVars.display, RootWindow(xVars.display, vi->screen), vi->visual, AllocNone);
|
||||
xVars.window = XCreateWindow(xVars.display, RootWindow(xVars.display, vi->screen), 0, 0, width, height, 0, vi->depth, InputOutput,
|
||||
@@ -99,13 +112,13 @@ void OpenGLWindow::Open() {
|
||||
int context_attributes[] { GLX_CONTEXT_MAJOR_VERSION_ARB, gl_major, GLX_CONTEXT_MINOR_VERSION_ARB, gl_minor, None };
|
||||
gl_context = glXCreateContextAttribsARB(xVars.display, best_fbc, nullptr, True, context_attributes);
|
||||
XFree(fb_configurations);
|
||||
ReWindow::Logger::Debug("Created OpenGL Context with glXCreateContextAttribsARB");
|
||||
Logger::Debug("Created OpenGL Context with glXCreateContextAttribsARB");
|
||||
}
|
||||
|
||||
if (!gl_context)
|
||||
throw std::runtime_error("Couldn't create the OpenGL context.");
|
||||
if (!func_glXMakeCurrent(xVars.display, xVars.window, gl_context))
|
||||
throw std::runtime_error("Couldn't change OpenGL context to current.");
|
||||
return false;
|
||||
if (!OpenGL::glXMakeCurrent(xVars.display, xVars.window, gl_context))
|
||||
return false;
|
||||
|
||||
if (vi)
|
||||
XFree(vi);
|
||||
@@ -128,12 +141,13 @@ void OpenGLWindow::Open() {
|
||||
|
||||
open = true;
|
||||
processOnOpen();
|
||||
return true;
|
||||
}
|
||||
|
||||
OpenGLWindow::OpenGLWindow(const std::string& title, int width, int height, uint8_t gl_major, uint8_t gl_minor)
|
||||
: gl_major(gl_major), gl_minor(gl_minor), RWindow(title, width, height) {
|
||||
|
||||
// Try this first so that in the event we have more than one window we don't double-load the library.
|
||||
// Try this first.
|
||||
glx_lib = dlopen("libGLX.so", RTLD_NOLOAD);
|
||||
opengl_lib = dlopen("libOpenGL.so", RTLD_NOLOAD);
|
||||
|
||||
@@ -143,16 +157,20 @@ OpenGLWindow::OpenGLWindow(const std::string& title, int width, int height, uint
|
||||
opengl_lib = dlopen("libOpenGL.so", RTLD_LAZY);
|
||||
|
||||
if (!opengl_lib)
|
||||
throw std::runtime_error("libOpenGL.so couldn't be found in your LD_LIBRARY_PATH.");
|
||||
if (!glx_lib)
|
||||
throw std::runtime_error("libGLX.so couldn't be found in your LD_LIBRARY_PATH.");
|
||||
Logger::Error("libOpenGL.so couldn't be found in your LD_LIBRARY_PATH."),
|
||||
OpenGL::constructor_success = false;
|
||||
|
||||
func_glGetString = (glGetString_t) dlsym(opengl_lib, "glGetString");
|
||||
func_glXMakeCurrent = (glXMakeCurrent_t) dlsym(glx_lib, "glXMakeCurrent");
|
||||
func_glXGetProcAddressARB = (glXGetProcAddressARB_t) dlsym(glx_lib, "glXGetProcAddressARB");
|
||||
func_glXSwapBuffers = (glXSwapBuffers_t) dlsym(glx_lib, "glXSwapBuffers");
|
||||
func_glXCreateContext = (glXCreateContext_t) dlsym(glx_lib, "glXCreateContext");
|
||||
func_glXChooseFBConfig = (glXChooseFBConfig_t) dlsym(glx_lib, "glXChooseFBConfig");
|
||||
func_glXGetVisualFromFBConfig = (glXGetVisualFromFBConfig_t) dlsym(glx_lib, "glXGetVisualFromFBConfig");
|
||||
func_glXChooseVisual = (glXChooseVisual_t) dlsym(glx_lib, "glXChooseVisual");
|
||||
if (!glx_lib)
|
||||
Logger::Error("libGLX.so couldn't be found in your LD_LIBRARY_PATH."),
|
||||
OpenGL::constructor_success = false;
|
||||
|
||||
OpenGL::glGetString = (OpenGL::glGetString_t) dlsym(opengl_lib, "glGetString");
|
||||
OpenGL::glXMakeCurrent = (OpenGL::glXMakeCurrent_t) dlsym(glx_lib, "glXMakeCurrent");
|
||||
OpenGL::glXGetProcAddressARB = (OpenGL::glXGetProcAddressARB_t) dlsym(glx_lib, "glXGetProcAddressARB");
|
||||
OpenGL::glXSwapBuffers = (OpenGL::glXSwapBuffers_t) dlsym(glx_lib, "glXSwapBuffers");
|
||||
OpenGL::glXCreateContext = (OpenGL::glXCreateContext_t) dlsym(glx_lib, "glXCreateContext");
|
||||
OpenGL::glXChooseFBConfig = (OpenGL::glXChooseFBConfig_t) dlsym(glx_lib, "glXChooseFBConfig");
|
||||
OpenGL::glXGetVisualFromFBConfig = (OpenGL::glXGetVisualFromFBConfig_t) dlsym(glx_lib, "glXGetVisualFromFBConfig");
|
||||
OpenGL::glXChooseVisual = (OpenGL::glXChooseVisual_t) dlsym(glx_lib, "glXChooseVisual");
|
||||
OpenGL::constructor_success = true;
|
||||
}
|
||||
|
@@ -1,11 +1,26 @@
|
||||
#include <ReWindow/types/Window.h>
|
||||
#include <ReWindow/Logger.h>
|
||||
#include <dlfcn.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <vulkan/vulkan_xlib.h>
|
||||
#include <set>
|
||||
|
||||
using namespace ReWindow;
|
||||
|
||||
namespace Vulkan {
|
||||
bool constructor_success = false;
|
||||
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = nullptr;
|
||||
PFN_vkCreateInstance vkCreateInstance = nullptr;
|
||||
PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties = nullptr;
|
||||
PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices = nullptr;
|
||||
PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties = nullptr;
|
||||
PFN_vkGetDeviceQueue vkGetDeviceQueue = nullptr;
|
||||
PFN_vkCreateDevice vkCreateDevice = nullptr;
|
||||
PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR = nullptr;
|
||||
PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR = nullptr;
|
||||
}
|
||||
|
||||
void* vulkan_lib = nullptr;
|
||||
VkInstance vulkan_context = nullptr;
|
||||
VkApplicationInfo vulkan_application_info{};
|
||||
VkSurfaceKHR vulkan_surface = nullptr;
|
||||
@@ -13,7 +28,21 @@ VkDevice vulkan_logical_device = nullptr;
|
||||
VkQueue vulkan_graphics_queue = nullptr;
|
||||
VkQueue vulkan_present_queue = nullptr;
|
||||
|
||||
void VulkanWindow::Open() {
|
||||
// Necessary because some functions aren't available until you have a context (Vulkan is weird).
|
||||
void LoadVulkanInstancedFunctions(VkInstance vulkan_ctx) {
|
||||
Vulkan::vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties) Vulkan::vkGetInstanceProcAddr(vulkan_ctx, "vkGetPhysicalDeviceProperties");
|
||||
Vulkan::vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) Vulkan::vkGetInstanceProcAddr(vulkan_ctx, "vkEnumeratePhysicalDevices");
|
||||
Vulkan::vkGetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties) Vulkan::vkGetInstanceProcAddr(vulkan_ctx, "vkGetPhysicalDeviceQueueFamilyProperties");
|
||||
Vulkan::vkGetDeviceQueue = (PFN_vkGetDeviceQueue) Vulkan::vkGetInstanceProcAddr(vulkan_ctx, "vkGetDeviceQueue");
|
||||
Vulkan::vkCreateDevice = (PFN_vkCreateDevice) Vulkan::vkGetInstanceProcAddr(vulkan_ctx, "vkCreateDevice");
|
||||
Vulkan::vkCreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR) Vulkan::vkGetInstanceProcAddr(vulkan_ctx, "vkCreateXlibSurfaceKHR");
|
||||
Vulkan::vkGetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR) Vulkan::vkGetInstanceProcAddr(vulkan_ctx, "vkGetPhysicalDeviceSurfaceSupportKHR");
|
||||
}
|
||||
|
||||
bool VulkanWindow::Open() {
|
||||
if (!Vulkan::constructor_success)
|
||||
return false;
|
||||
|
||||
xVars.display = XOpenDisplay(nullptr);
|
||||
xVars.defaultScreen = DefaultScreen(xVars.display);
|
||||
|
||||
@@ -37,16 +66,20 @@ void VulkanWindow::Open() {
|
||||
const char* extensions[] = { "VK_KHR_surface", "VK_KHR_xlib_surface" };
|
||||
create_info.enabledExtensionCount = 2;
|
||||
create_info.ppEnabledExtensionNames = extensions;
|
||||
if (vkCreateInstance(&create_info, nullptr, &vulkan_context) != VK_SUCCESS)
|
||||
throw std::runtime_error("Couldn't create Vulkan instance.");
|
||||
|
||||
if (Vulkan::vkCreateInstance(&create_info, nullptr, &vulkan_context) != VK_SUCCESS) {
|
||||
Logger::Error("Couldn't create Vulkan instance.");
|
||||
return false;
|
||||
}
|
||||
|
||||
LoadVulkanInstancedFunctions(vulkan_context);
|
||||
XVisualInfo visual_info_t{};
|
||||
visual_info_t.screen = xVars.defaultScreen;
|
||||
int visual_count;
|
||||
XVisualInfo* vi = XGetVisualInfo(xVars.display, VisualScreenMask, &visual_info_t, &visual_count);
|
||||
|
||||
if (!vi)
|
||||
throw std::runtime_error("Failed to get X11 visual info.");
|
||||
return false;
|
||||
|
||||
Colormap colormap = XCreateColormap(xVars.display, RootWindow(xVars.display, vi->screen), vi->visual, AllocNone);
|
||||
xVars.xSetWindowAttributes.colormap = colormap;
|
||||
@@ -55,8 +88,10 @@ void VulkanWindow::Open() {
|
||||
0, 0, width, height, 0, vi->depth, InputOutput,
|
||||
vi->visual, CWBackPixel | CWColormap | CWBorderPixel, &xVars.xSetWindowAttributes);
|
||||
|
||||
if (!xVars.window)
|
||||
throw std::runtime_error("Failed to create X11 window for Vulkan.");
|
||||
if (!xVars.window) {
|
||||
Logger::Error("Failed to create X11 window for Vulkan.");
|
||||
return false;
|
||||
}
|
||||
|
||||
XFree(vi);
|
||||
|
||||
@@ -65,17 +100,21 @@ void VulkanWindow::Open() {
|
||||
surface_create_info.dpy = xVars.display;
|
||||
surface_create_info.window = xVars. window;
|
||||
|
||||
if (vkCreateXlibSurfaceKHR(vulkan_context, &surface_create_info, nullptr, &vulkan_surface) != VK_SUCCESS)
|
||||
throw std::runtime_error("Failed to create Vulkan X11 surface.");
|
||||
if (Vulkan::vkCreateXlibSurfaceKHR(vulkan_context, &surface_create_info, nullptr, &vulkan_surface) != VK_SUCCESS) {
|
||||
Logger::Error("Failed to create Vulkan X11 surface.");
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int device_count = 0;
|
||||
vkEnumeratePhysicalDevices(vulkan_context, &device_count, nullptr);
|
||||
Vulkan::vkEnumeratePhysicalDevices(vulkan_context, &device_count, nullptr);
|
||||
|
||||
if (device_count == 0)
|
||||
throw std::runtime_error("Opening the window as Vulkan but there isn't a Vulkan compatible graphics card?");
|
||||
if (device_count == 0) {
|
||||
Logger::Error("Opening the window as Vulkan but there isn't a Vulkan compatible graphics card?");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<VkPhysicalDevice> vulkan_devices(device_count);
|
||||
vkEnumeratePhysicalDevices(vulkan_context, &device_count, vulkan_devices.data());
|
||||
Vulkan::vkEnumeratePhysicalDevices(vulkan_context, &device_count, vulkan_devices.data());
|
||||
|
||||
VkPhysicalDevice selected_device = VK_NULL_HANDLE;
|
||||
|
||||
@@ -83,10 +122,10 @@ void VulkanWindow::Open() {
|
||||
int present_family = -1;
|
||||
for (const auto& d : vulkan_devices) {
|
||||
unsigned int queue_family_count = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(d, &queue_family_count, nullptr);
|
||||
Vulkan::vkGetPhysicalDeviceQueueFamilyProperties(d, &queue_family_count, nullptr);
|
||||
|
||||
std::vector<VkQueueFamilyProperties> queue_families(queue_family_count);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(d, &queue_family_count, queue_families.data());
|
||||
Vulkan::vkGetPhysicalDeviceQueueFamilyProperties(d, &queue_family_count, queue_families.data());
|
||||
|
||||
bool has_graphics = false;
|
||||
bool has_present = false;
|
||||
@@ -94,7 +133,8 @@ void VulkanWindow::Open() {
|
||||
if (queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { has_graphics = true; graphics_family = i; }
|
||||
|
||||
VkBool32 present_support = false;
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR(d, i, vulkan_surface, &present_support);
|
||||
Vulkan::vkGetPhysicalDeviceSurfaceSupportKHR(d, i, vulkan_surface, &present_support);
|
||||
|
||||
if (present_support) { has_present = true; present_family = i; }
|
||||
|
||||
if (has_graphics && has_present) { selected_device = d; break; }
|
||||
@@ -103,11 +143,13 @@ void VulkanWindow::Open() {
|
||||
break;
|
||||
}
|
||||
|
||||
if (selected_device == VK_NULL_HANDLE)
|
||||
throw std::runtime_error("Opening the window using Vulkan but there isn't a Vulkan device which supports rendering & presenting?");
|
||||
if (selected_device == VK_NULL_HANDLE) {
|
||||
Logger::Error("There isn't a Vulkan device which supports rendering & presenting?");
|
||||
return false;
|
||||
}
|
||||
|
||||
VkPhysicalDeviceProperties device_properties;
|
||||
vkGetPhysicalDeviceProperties(selected_device, &device_properties);
|
||||
Vulkan::vkGetPhysicalDeviceProperties(selected_device, &device_properties);
|
||||
Logger::Debug("Vulkan continuing with selected device: " + std::string(device_properties.deviceName));
|
||||
|
||||
float queue_prio = 1.0f;
|
||||
@@ -137,11 +179,15 @@ void VulkanWindow::Open() {
|
||||
device_create_info.enabledExtensionCount = device_ext.size();
|
||||
device_create_info.ppEnabledExtensionNames = device_ext.data();
|
||||
|
||||
if (vkCreateDevice(selected_device, &device_create_info, nullptr, &vulkan_logical_device) != VK_SUCCESS)
|
||||
throw std::runtime_error("Couldn't create the Vulkan logical device.");
|
||||
if (Vulkan::vkCreateDevice(selected_device, &device_create_info, nullptr, &vulkan_logical_device) != VK_SUCCESS) {
|
||||
Logger::Error("Couldn't create the Vulkan logical device.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Vulkan::vkGetDeviceQueue(vulkan_logical_device, graphics_family, 0, &vulkan_graphics_queue);
|
||||
Vulkan::vkGetDeviceQueue(vulkan_logical_device, present_family, 0, &vulkan_present_queue);
|
||||
|
||||
|
||||
vkGetDeviceQueue(vulkan_logical_device, graphics_family, 0, &vulkan_graphics_queue);
|
||||
vkGetDeviceQueue(vulkan_logical_device, present_family, 0, &vulkan_present_queue);
|
||||
|
||||
|
||||
|
||||
@@ -162,4 +208,30 @@ void VulkanWindow::Open() {
|
||||
|
||||
open = true;
|
||||
processOnOpen();
|
||||
return true;
|
||||
}
|
||||
|
||||
void VulkanWindow::SwapBuffers() {
|
||||
|
||||
}
|
||||
|
||||
void VulkanWindow::SetVsyncEnabled(bool state) {
|
||||
|
||||
}
|
||||
|
||||
std::string VulkanWindow::GetGraphicsDriverVendor() {
|
||||
|
||||
}
|
||||
|
||||
VulkanWindow::VulkanWindow(const std::string& title, int width, int height) : RWindow(title, width, height) {
|
||||
vulkan_lib = dlopen("libvulkan.so", RTLD_NOW | RTLD_LOCAL);
|
||||
if (!vulkan_lib)
|
||||
vulkan_lib = dlopen("libvulkan.so.1", RTLD_NOW | RTLD_LOCAL);
|
||||
if (!vulkan_lib)
|
||||
Logger::Debug("libvulkan.so couldn't be found in your LD_LIBRARY_PATH."),
|
||||
Vulkan::constructor_success = false;
|
||||
|
||||
Vulkan::vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) dlsym(vulkan_lib,"vkGetInstanceProcAddr");
|
||||
Vulkan::vkCreateInstance = (PFN_vkCreateInstance) Vulkan::vkGetInstanceProcAddr(NULL, "vkCreateInstance");
|
||||
Vulkan::constructor_success = true;
|
||||
}
|
Reference in New Issue
Block a user