mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-23 05:45:51 +12:00
Fix typo
This commit is contained in:
parent
42cbcc1380
commit
5d9ded47da
35 changed files with 37343 additions and 21800 deletions
328
third_party/duckstation/gl/context_glx.cpp
vendored
Normal file
328
third_party/duckstation/gl/context_glx.cpp
vendored
Normal file
|
@ -0,0 +1,328 @@
|
|||
#include "context_glx.h"
|
||||
#include "duckstation_compat.h"
|
||||
#include "duckstation_log.h"
|
||||
#include <dlfcn.h>
|
||||
Log_SetChannel(GL::ContextGLX);
|
||||
|
||||
namespace GL {
|
||||
ContextGLX::ContextGLX(const WindowInfo& wi) : Context(wi) {}
|
||||
|
||||
ContextGLX::~ContextGLX()
|
||||
{
|
||||
if (glXGetCurrentContext() == m_context)
|
||||
glXMakeCurrent(GetDisplay(), None, nullptr);
|
||||
|
||||
if (m_context)
|
||||
glXDestroyContext(GetDisplay(), m_context);
|
||||
|
||||
if (m_vi)
|
||||
XFree(m_vi);
|
||||
|
||||
if (m_libGL_handle)
|
||||
dlclose(m_libGL_handle);
|
||||
}
|
||||
|
||||
std::unique_ptr<Context> ContextGLX::Create(const WindowInfo& wi, const Version* versions_to_try,
|
||||
size_t num_versions_to_try)
|
||||
{
|
||||
std::unique_ptr<ContextGLX> context = std::make_unique<ContextGLX>(wi);
|
||||
if (!context->Initialize(versions_to_try, num_versions_to_try))
|
||||
return nullptr;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
bool ContextGLX::Initialize(const Version* versions_to_try, size_t num_versions_to_try)
|
||||
{
|
||||
// We need libGL loaded, because GLAD loads its own, then releases it.
|
||||
m_libGL_handle = dlopen("libGL.so.1", RTLD_NOW | RTLD_GLOBAL);
|
||||
if (!m_libGL_handle)
|
||||
{
|
||||
m_libGL_handle = dlopen("libGL.so", RTLD_NOW | RTLD_GLOBAL);
|
||||
if (!m_libGL_handle)
|
||||
{
|
||||
Log_ErrorPrintf("Failed to load libGL.so: %s", dlerror());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const int screen = DefaultScreen(GetDisplay());
|
||||
if (!gladLoadGLX(GetDisplay(), screen))
|
||||
{
|
||||
Log_ErrorPrintf("Loading GLAD GLX functions failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_wi.type == WindowInfo::Type::X11)
|
||||
{
|
||||
if (!CreateWindow(screen))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Panic("Create pbuffer");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < num_versions_to_try; i++)
|
||||
{
|
||||
const Version& cv = versions_to_try[i];
|
||||
if (cv.profile == Profile::NoProfile && CreateAnyContext(nullptr, true))
|
||||
{
|
||||
m_version = cv;
|
||||
return true;
|
||||
}
|
||||
else if (cv.profile != Profile::NoProfile && CreateVersionContext(cv, nullptr, true))
|
||||
{
|
||||
m_version = cv;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void* ContextGLX::GetProcAddress(const char* name)
|
||||
{
|
||||
return reinterpret_cast<void*>(glXGetProcAddress(reinterpret_cast<const GLubyte*>(name)));
|
||||
}
|
||||
|
||||
bool ContextGLX::ChangeSurface(const WindowInfo& new_wi)
|
||||
{
|
||||
const bool was_current = (glXGetCurrentContext() == m_context);
|
||||
if (was_current)
|
||||
glXMakeCurrent(GetDisplay(), None, nullptr);
|
||||
|
||||
m_window.Destroy();
|
||||
m_wi = new_wi;
|
||||
|
||||
if (new_wi.type == WindowInfo::Type::X11)
|
||||
{
|
||||
const int screen = DefaultScreen(GetDisplay());
|
||||
if (!CreateWindow(screen))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (was_current && !glXMakeCurrent(GetDisplay(), GetDrawable(), m_context))
|
||||
{
|
||||
Log_ErrorPrintf("Failed to make context current again after surface change");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ContextGLX::ResizeSurface(u32 new_surface_width /*= 0*/, u32 new_surface_height /*= 0*/)
|
||||
{
|
||||
m_window.Resize(new_surface_width, new_surface_height);
|
||||
m_wi.surface_width = m_window.GetWidth();
|
||||
m_wi.surface_height = m_window.GetHeight();
|
||||
}
|
||||
|
||||
bool ContextGLX::SwapBuffers()
|
||||
{
|
||||
glXSwapBuffers(GetDisplay(), GetDrawable());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContextGLX::MakeCurrent()
|
||||
{
|
||||
return (glXMakeCurrent(GetDisplay(), GetDrawable(), m_context) == True);
|
||||
}
|
||||
|
||||
bool ContextGLX::DoneCurrent()
|
||||
{
|
||||
return (glXMakeCurrent(GetDisplay(), None, nullptr) == True);
|
||||
}
|
||||
|
||||
bool ContextGLX::SetSwapInterval(s32 interval)
|
||||
{
|
||||
if (GLAD_GLX_EXT_swap_control)
|
||||
{
|
||||
glXSwapIntervalEXT(GetDisplay(), GetDrawable(), interval);
|
||||
return true;
|
||||
}
|
||||
else if (GLAD_GLX_MESA_swap_control)
|
||||
{
|
||||
return (glXSwapIntervalMESA(static_cast<u32>(std::max(interval, 0))) != 0);
|
||||
}
|
||||
else if (GLAD_GLX_SGI_swap_control)
|
||||
{
|
||||
return (glXSwapIntervalSGI(interval) != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Context> ContextGLX::CreateSharedContext(const WindowInfo& wi)
|
||||
{
|
||||
std::unique_ptr<ContextGLX> context = std::make_unique<ContextGLX>(wi);
|
||||
if (wi.type == WindowInfo::Type::X11)
|
||||
{
|
||||
const int screen = DefaultScreen(context->GetDisplay());
|
||||
if (!context->CreateWindow(screen))
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
Panic("Create pbuffer");
|
||||
}
|
||||
|
||||
if (m_version.profile == Profile::NoProfile)
|
||||
{
|
||||
if (!context->CreateAnyContext(m_context, false))
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!context->CreateVersionContext(m_version, m_context, false))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
context->m_version = m_version;
|
||||
return context;
|
||||
}
|
||||
|
||||
bool ContextGLX::CreateWindow(int screen)
|
||||
{
|
||||
int attribs[32] = {GLX_X_RENDERABLE, True, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
||||
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_DOUBLEBUFFER, True};
|
||||
int nattribs = 8;
|
||||
|
||||
switch (m_wi.surface_format)
|
||||
{
|
||||
case WindowInfo::SurfaceFormat::RGB8:
|
||||
attribs[nattribs++] = GLX_RED_SIZE;
|
||||
attribs[nattribs++] = 8;
|
||||
attribs[nattribs++] = GLX_GREEN_SIZE;
|
||||
attribs[nattribs++] = 8;
|
||||
attribs[nattribs++] = GLX_BLUE_SIZE;
|
||||
attribs[nattribs++] = 8;
|
||||
break;
|
||||
|
||||
case WindowInfo::SurfaceFormat::RGBA8:
|
||||
attribs[nattribs++] = GLX_RED_SIZE;
|
||||
attribs[nattribs++] = 8;
|
||||
attribs[nattribs++] = GLX_GREEN_SIZE;
|
||||
attribs[nattribs++] = 8;
|
||||
attribs[nattribs++] = GLX_BLUE_SIZE;
|
||||
attribs[nattribs++] = 8;
|
||||
attribs[nattribs++] = GLX_ALPHA_SIZE;
|
||||
attribs[nattribs++] = 8;
|
||||
break;
|
||||
|
||||
case WindowInfo::SurfaceFormat::RGB565:
|
||||
attribs[nattribs++] = GLX_RED_SIZE;
|
||||
attribs[nattribs++] = 5;
|
||||
attribs[nattribs++] = GLX_GREEN_SIZE;
|
||||
attribs[nattribs++] = 6;
|
||||
attribs[nattribs++] = GLX_BLUE_SIZE;
|
||||
attribs[nattribs++] = 5;
|
||||
break;
|
||||
|
||||
case WindowInfo::SurfaceFormat::Auto:
|
||||
break;
|
||||
|
||||
default:
|
||||
UnreachableCode();
|
||||
break;
|
||||
}
|
||||
|
||||
attribs[nattribs++] = None;
|
||||
attribs[nattribs++] = 0;
|
||||
|
||||
int fbcount = 0;
|
||||
GLXFBConfig* fbc = glXChooseFBConfig(GetDisplay(), screen, attribs, &fbcount);
|
||||
if (!fbc || !fbcount)
|
||||
{
|
||||
Log_ErrorPrintf("glXChooseFBConfig() failed");
|
||||
return false;
|
||||
}
|
||||
m_fb_config = *fbc;
|
||||
XFree(fbc);
|
||||
|
||||
if (!GLAD_GLX_VERSION_1_3)
|
||||
{
|
||||
Log_ErrorPrintf("GLX Version 1.3 is required");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_vi = glXGetVisualFromFBConfig(GetDisplay(), m_fb_config);
|
||||
if (!m_vi)
|
||||
{
|
||||
Log_ErrorPrintf("glXGetVisualFromFBConfig() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_window.Create(GetDisplay(), static_cast<Window>(reinterpret_cast<uintptr_t>(m_wi.window_handle)), m_vi);
|
||||
}
|
||||
|
||||
bool ContextGLX::CreateAnyContext(GLXContext share_context, bool make_current)
|
||||
{
|
||||
X11InhibitErrors ie;
|
||||
|
||||
m_context = glXCreateContext(GetDisplay(), m_vi, share_context, True);
|
||||
if (!m_context || ie.HadError())
|
||||
{
|
||||
Log_ErrorPrintf("glxCreateContext() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (make_current)
|
||||
{
|
||||
if (!glXMakeCurrent(GetDisplay(), GetDrawable(), m_context))
|
||||
{
|
||||
Log_ErrorPrintf("glXMakeCurrent() failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContextGLX::CreateVersionContext(const Version& version, GLXContext share_context, bool make_current)
|
||||
{
|
||||
// we need create context attribs
|
||||
if (!GLAD_GLX_VERSION_1_3)
|
||||
{
|
||||
Log_ErrorPrint("Missing GLX version 1.3.");
|
||||
return false;
|
||||
}
|
||||
|
||||
int attribs[32];
|
||||
int nattribs = 0;
|
||||
attribs[nattribs++] = GLX_CONTEXT_PROFILE_MASK_ARB;
|
||||
attribs[nattribs++] =
|
||||
((version.profile == Profile::ES) ?
|
||||
((version.major_version >= 2) ? GLX_CONTEXT_ES2_PROFILE_BIT_EXT : GLX_CONTEXT_ES_PROFILE_BIT_EXT) :
|
||||
GLX_CONTEXT_CORE_PROFILE_BIT_ARB);
|
||||
attribs[nattribs++] = GLX_CONTEXT_MAJOR_VERSION_ARB;
|
||||
attribs[nattribs++] = version.major_version;
|
||||
attribs[nattribs++] = GLX_CONTEXT_MINOR_VERSION_ARB;
|
||||
attribs[nattribs++] = version.minor_version;
|
||||
attribs[nattribs++] = None;
|
||||
attribs[nattribs++] = 0;
|
||||
|
||||
X11InhibitErrors ie;
|
||||
m_context = glXCreateContextAttribsARB(GetDisplay(), m_fb_config, share_context, True, attribs);
|
||||
XSync(GetDisplay(), False);
|
||||
if (ie.HadError())
|
||||
m_context = nullptr;
|
||||
if (!m_context)
|
||||
return false;
|
||||
|
||||
if (make_current)
|
||||
{
|
||||
if (!glXMakeCurrent(GetDisplay(), GetDrawable(), m_context))
|
||||
{
|
||||
Log_ErrorPrint("glXMakeCurrent() failed");
|
||||
glXDestroyContext(GetDisplay(), m_context);
|
||||
m_context = nullptr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace GL
|
Loading…
Add table
Add a link
Reference in a new issue