mirror of https://github.com/PCSX2/pcsx2.git
gsdx-ogl:
* Properly allocate/delete opengl object * Request a debug context in SDL, add some code to log opengl error * Fix context creation. For the moment only request ogl4.1 (AMD does not support yet 4.2 and it needs libglew1.7 too...) git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl@4973 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
6125baa578
commit
133847e8a2
|
@ -410,6 +410,9 @@ X11_GL_CreateContext(_THIS, SDL_Window * window)
|
|||
_this->gl_config.major_version,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB,
|
||||
_this->gl_config.minor_version,
|
||||
//FIXME GREGORY
|
||||
// Request a debug context to ease opengl development
|
||||
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
|
||||
0
|
||||
};
|
||||
|
||||
|
|
|
@ -56,6 +56,8 @@
|
|||
GSDeviceOGL::GSDeviceOGL()
|
||||
: m_free_window(false)
|
||||
, m_window(NULL)
|
||||
//, m_context(0)
|
||||
, m_dummy_renderer(NULL)
|
||||
, m_vb(0)
|
||||
, m_pipeline(0)
|
||||
, m_srv_changed(false)
|
||||
|
@ -71,10 +73,42 @@ GSDeviceOGL::GSDeviceOGL()
|
|||
|
||||
GSDeviceOGL::~GSDeviceOGL()
|
||||
{
|
||||
// Clean m_merge
|
||||
for (uint i = 0; i < 2; i++)
|
||||
glDeleteProgram(m_merge.ps[i]);
|
||||
delete (m_merge.cb);
|
||||
delete (m_merge.bs);
|
||||
|
||||
// Clean m_interlace
|
||||
for (uint i = 0; i < 2; i++)
|
||||
glDeleteProgram(m_interlace.ps[i]);
|
||||
delete (m_interlace.cb);
|
||||
|
||||
// Clean m_convert
|
||||
glDeleteProgram(m_convert.vs);
|
||||
for (uint i = 0; i < 2; i++)
|
||||
glDeleteProgram(m_convert.ps[i]);
|
||||
glDeleteSamplers(1, &m_convert.ln);
|
||||
glDeleteSamplers(1, &m_convert.pt);
|
||||
delete m_convert.dss;
|
||||
delete m_convert.bs;
|
||||
|
||||
// Clean m_date
|
||||
delete m_date.dss;
|
||||
delete m_date.bs;
|
||||
|
||||
// Clean various opengl allocation
|
||||
glDeleteBuffers(1, &m_vb);
|
||||
glDeleteProgramPipelines(1, &m_pipeline);
|
||||
glDeleteFramebuffers(1, &m_fbo);
|
||||
|
||||
// if(m_context)
|
||||
// SDL_GL_DeleteContext(m_context);
|
||||
if(m_dummy_renderer)
|
||||
SDL_DestroyRenderer(m_dummy_renderer);
|
||||
|
||||
if(m_window != NULL && m_free_window)
|
||||
{
|
||||
SDL_DestroyWindow(m_window);
|
||||
}
|
||||
}
|
||||
|
||||
GSTexture* GSDeviceOGL::CreateSurface(int type, int w, int h, bool msaa, int format)
|
||||
|
@ -110,6 +144,8 @@ GSTexture* GSDeviceOGL::FetchSurface(int type, int w, int h, bool msaa, int form
|
|||
return GSDevice::FetchSurface(type, w, h, msaa, format);
|
||||
}
|
||||
|
||||
PFNGLTEXSTORAGE2DPROC glTexStorage2D_glew17 = NULL;
|
||||
|
||||
bool GSDeviceOGL::Create(GSWnd* wnd)
|
||||
{
|
||||
if (m_window == NULL) {
|
||||
|
@ -119,6 +155,51 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
|||
assert(0);
|
||||
#endif
|
||||
m_free_window = true;
|
||||
|
||||
// If the user request OpenGL acceleration, we take recent OGL version (4.2)
|
||||
// We keep the default 2.1 version in SW mode (only DX11 capable card, are compatible with OGL4) if ( theApp.GetConfig("renderer", 0) / 3 == 4 ) {
|
||||
// Setup visual attribute
|
||||
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
|
||||
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
|
||||
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
|
||||
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 32 );
|
||||
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
|
||||
SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 );
|
||||
// Ask for an advance opengl version
|
||||
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 4 );
|
||||
// FIXME AMD does not support yet 4.2...
|
||||
//SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 1 );
|
||||
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 1 );
|
||||
|
||||
// Window must be recreated to gain Opengl feature...
|
||||
//SDL_RecreateWindow(m_window, SDL_GetWindowFlags(m_window) | SDL_WINDOW_OPENGL );
|
||||
// Well actually you need to generate a full renderer to only have a context...
|
||||
m_dummy_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_ACCELERATED); // SDL_RENDERER_PRESENTVSYNC
|
||||
// At least create the opengl context
|
||||
// m_context = SDL_GL_CreateContext(m_window);
|
||||
|
||||
|
||||
// FIXME......
|
||||
// GLEW's problem is that it calls glGetString(GL_EXTENSIONS) which causes GL_INVALID_ENUM on GL 3.2 forward compatible context as soon as glewInit() is called. It also doesn't fetch the function pointers. The solution is for GLEW to use glGetStringi instead.
|
||||
// The current version of GLEW is 1.7.0 but they still haven't corrected it. The only fix is to use glewExperimental for now :
|
||||
//NOTE: I'm not sure experimental work on 1.6 ...
|
||||
glewExperimental=true;
|
||||
const int glew_ok = glewInit();
|
||||
if (glew_ok != GLEW_OK)
|
||||
{
|
||||
// FIXME:proper logging
|
||||
fprintf(stderr, "Error: Failed to init glew :%s\n", glewGetErrorString(glew_ok));
|
||||
return false;
|
||||
}
|
||||
// FIXME upgrade to 4.2 when AMD drivers are ready
|
||||
// Note need glew 1.7 too
|
||||
if (!GLEW_VERSION_4_1) {
|
||||
fprintf(stderr, "4.1 is not supported!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Not yet supported by glew1.6
|
||||
glTexStorage2D_glew17 = (PFNGLTEXSTORAGE2DPROC)glXGetProcAddressARB((const GLubyte*)"glTexStorage2D");
|
||||
}
|
||||
|
||||
#ifdef __LINUX__
|
||||
|
@ -127,6 +208,9 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
|||
wnd->SetWindow(m_window);
|
||||
#endif
|
||||
|
||||
// FIXME disable it when code is ready
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
|
||||
|
||||
// ****************************************************************
|
||||
// Various object
|
||||
// ****************************************************************
|
||||
|
@ -199,12 +283,15 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
|||
glSamplerParameteri(m_convert.pt, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||
glSamplerParameteri(m_convert.pt, GL_TEXTURE_COMPARE_FUNC, GL_NEVER);
|
||||
|
||||
m_convert.dss = new GSDepthStencilOGL();
|
||||
m_convert.bs = new GSBlendStateOGL();
|
||||
|
||||
// ****************************************************************
|
||||
// merge
|
||||
// ****************************************************************
|
||||
|
||||
m_merge.cb->index = 1;
|
||||
m_merge.cb->byte_size = sizeof(MergeConstantBuffer);
|
||||
m_merge.cb = new GSUniformBufferOGL(1, sizeof(MergeConstantBuffer));
|
||||
//m_merge.cb->index = 1;
|
||||
//m_merge.cb->byte_size = sizeof(MergeConstantBuffer);
|
||||
glGenBuffers(1, &m_merge.cb->buffer);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, m_merge.cb->buffer);
|
||||
glBufferData(GL_UNIFORM_BUFFER, m_merge.cb->byte_size, NULL, GL_DYNAMIC_DRAW);
|
||||
|
@ -212,6 +299,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
|||
for(int i = 0; i < countof(m_merge.ps); i++)
|
||||
CompileShaderFromSource("merge.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_merge.ps[i]);
|
||||
|
||||
m_merge.bs = new GSBlendStateOGL();
|
||||
m_merge.bs->m_enable = true;
|
||||
m_merge.bs->m_equation_RGB = GL_FUNC_ADD;
|
||||
m_merge.bs->m_equation_ALPHA = GL_FUNC_ADD;
|
||||
|
@ -223,8 +311,9 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
|||
// ****************************************************************
|
||||
// interlace
|
||||
// ****************************************************************
|
||||
m_interlace.cb->index = 2;
|
||||
m_interlace.cb->byte_size = sizeof(InterlaceConstantBuffer);
|
||||
m_interlace.cb = new GSUniformBufferOGL(2, sizeof(InterlaceConstantBuffer));
|
||||
//m_interlace.cb->index = 2;
|
||||
//m_interlace.cb->byte_size = sizeof(InterlaceConstantBuffer);
|
||||
glGenBuffers(1, &m_interlace.cb->buffer);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, m_interlace.cb->buffer);
|
||||
glBufferData(GL_UNIFORM_BUFFER, m_interlace.cb->byte_size, NULL, GL_DYNAMIC_DRAW);
|
||||
|
@ -251,6 +340,13 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
|||
rd.AntialiasedLineEnable = false;
|
||||
#endif
|
||||
|
||||
|
||||
// ****************************************************************
|
||||
// Finish window setup and backbuffer
|
||||
// ****************************************************************
|
||||
if(!GSDevice::Create(wnd))
|
||||
return false;
|
||||
|
||||
GSVector4i rect = wnd->GetClientRect();
|
||||
Reset(rect.z, rect.w);
|
||||
|
||||
|
@ -431,6 +527,8 @@ bool GSDeviceOGL::Reset(int w, int h)
|
|||
|
||||
void GSDeviceOGL::Flip()
|
||||
{
|
||||
// FIXME: disable it when code is working
|
||||
CheckDebugLog();
|
||||
// Warning it is not OGL dependent but application dependant (glx and so not portable)
|
||||
#if SDL_VERSION_ATLEAST(1,3,0)
|
||||
SDL_GL_SwapWindow(m_window);
|
||||
|
@ -1048,3 +1146,82 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st
|
|||
|
||||
free(sources);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::CheckDebugLog()
|
||||
{
|
||||
unsigned int count = 64; // max. num. of messages that will be read from the log
|
||||
int bufsize = 2048;
|
||||
unsigned int* sources = new unsigned int[count];
|
||||
unsigned int* types = new unsigned int[count];
|
||||
unsigned int* ids = new unsigned int[count];
|
||||
unsigned int* severities = new unsigned int[count];
|
||||
int* lengths = new int[count];
|
||||
char* messageLog = new char[bufsize];
|
||||
|
||||
unsigned int retVal = glGetDebugMessageLogARB(count, bufsize, sources, types, ids, severities, lengths, messageLog);
|
||||
|
||||
if(retVal > 0)
|
||||
{
|
||||
unsigned int pos = 0;
|
||||
for(unsigned int i=0; i<retVal; i++)
|
||||
{
|
||||
DebugOutputToFile(sources[i], types[i], ids[i], severities[i],
|
||||
&messageLog[pos]);
|
||||
pos += lengths[i];
|
||||
}
|
||||
}
|
||||
|
||||
delete [] sources;
|
||||
delete [] types;
|
||||
delete [] ids;
|
||||
delete [] severities;
|
||||
delete [] lengths;
|
||||
delete [] messageLog;
|
||||
}
|
||||
|
||||
void GSDeviceOGL::DebugOutputToFile(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, const char* message)
|
||||
{
|
||||
FILE* f;
|
||||
// FIXME properly log error
|
||||
f = fopen("Debug.txt","a");
|
||||
if(f)
|
||||
{
|
||||
char debSource[16], debType[20], debSev[5];
|
||||
if(source == GL_DEBUG_SOURCE_API_ARB)
|
||||
strcpy(debSource, "OpenGL");
|
||||
else if(source == GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB)
|
||||
strcpy(debSource, "Windows");
|
||||
else if(source == GL_DEBUG_SOURCE_SHADER_COMPILER_ARB)
|
||||
strcpy(debSource, "Shader Compiler");
|
||||
else if(source == GL_DEBUG_SOURCE_THIRD_PARTY_ARB)
|
||||
strcpy(debSource, "Third Party");
|
||||
else if(source == GL_DEBUG_SOURCE_APPLICATION_ARB)
|
||||
strcpy(debSource, "Application");
|
||||
else if(source == GL_DEBUG_SOURCE_OTHER_ARB)
|
||||
strcpy(debSource, "Other");
|
||||
|
||||
if(type == GL_DEBUG_TYPE_ERROR_ARB)
|
||||
strcpy(debType, "Error");
|
||||
else if(type == GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB)
|
||||
strcpy(debType, "Deprecated behavior");
|
||||
else if(type == GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB)
|
||||
strcpy(debType, "Undefined behavior");
|
||||
else if(type == GL_DEBUG_TYPE_PORTABILITY_ARB)
|
||||
strcpy(debType, "Portability");
|
||||
else if(type == GL_DEBUG_TYPE_PERFORMANCE_ARB)
|
||||
strcpy(debType, "Performance");
|
||||
else if(type == GL_DEBUG_TYPE_OTHER_ARB)
|
||||
strcpy(debType, "Other");
|
||||
|
||||
if(severity == GL_DEBUG_SEVERITY_HIGH_ARB)
|
||||
strcpy(debSev, "High");
|
||||
else if(severity == GL_DEBUG_SEVERITY_MEDIUM_ARB)
|
||||
strcpy(debSev, "Med");
|
||||
else if(severity == GL_DEBUG_SEVERITY_LOW_ARB)
|
||||
strcpy(debSev, "Low");
|
||||
|
||||
//fprintf(stderr,"Source:%s\tType:%s\tID:%d\tSeverity:%s\tMessage:%s\n", debSource,debType,id,debSev,message);
|
||||
fprintf(f,"Source:%s\tType:%s\tID:%d\tSeverity:%s\tMessage:%s\n", debSource,debType,id,debSev,message);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,16 @@ struct GSBlendStateOGL {
|
|||
GLenum m_func_dRGB;
|
||||
GLenum m_func_sALPHA;
|
||||
GLenum m_func_dALPHA;
|
||||
|
||||
GSBlendStateOGL() : m_enable(false)
|
||||
, m_equation_RGB(0)
|
||||
, m_equation_ALPHA(0)
|
||||
, m_func_sRGB(0)
|
||||
, m_func_dRGB(0)
|
||||
, m_func_sALPHA(0)
|
||||
, m_func_dALPHA(0)
|
||||
{}
|
||||
|
||||
};
|
||||
|
||||
struct GSDepthStencilOGL {
|
||||
|
@ -51,12 +61,34 @@ struct GSDepthStencilOGL {
|
|||
GLuint m_stencil_sfail_op;
|
||||
GLuint m_stencil_spass_dfail_op;
|
||||
GLuint m_stencil_spass_dpass_op;
|
||||
|
||||
GSDepthStencilOGL() : m_depth_enable(false)
|
||||
, m_depth_func(0)
|
||||
, m_depth_mask(0)
|
||||
, m_stencil_enable(false)
|
||||
, m_stencil_mask(0)
|
||||
, m_stencil_func(0)
|
||||
, m_stencil_ref(0)
|
||||
, m_stencil_sfail_op(0)
|
||||
, m_stencil_spass_dfail_op(0)
|
||||
, m_stencil_spass_dpass_op(0)
|
||||
{}
|
||||
};
|
||||
|
||||
struct GSUniformBufferOGL {
|
||||
GLuint buffer; // data object
|
||||
GLuint index; // GLSL slot
|
||||
uint byte_size; // size of the data
|
||||
|
||||
GSUniformBufferOGL(GLuint index, uint byte_size) : buffer(0)
|
||||
, index(index)
|
||||
, byte_size(byte_size)
|
||||
{}
|
||||
|
||||
~GSUniformBufferOGL() {
|
||||
if (buffer)
|
||||
glDeleteBuffers(1, &buffer);
|
||||
}
|
||||
};
|
||||
|
||||
struct GSInputLayout {
|
||||
|
@ -73,6 +105,8 @@ class GSDeviceOGL : public GSDevice
|
|||
|
||||
bool m_free_window;
|
||||
SDL_Window* m_window; // pointer to the SDL window
|
||||
//SDL_GLContext m_context; // current opengl context
|
||||
SDL_Renderer* m_dummy_renderer; // ... crappy API ...
|
||||
|
||||
GLuint m_vb; // vertex buffer object
|
||||
GLuint m_pipeline; // pipeline to attach program shader
|
||||
|
@ -197,6 +231,9 @@ class GSDeviceOGL : public GSDevice
|
|||
#endif
|
||||
|
||||
|
||||
void CheckDebugLog();
|
||||
void DebugOutputToFile(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, const char* message);
|
||||
|
||||
protected:
|
||||
GSTexture* CreateSurface(int type, int w, int h, bool msaa, int format);
|
||||
GSTexture* FetchSurface(int type, int w, int h, bool msaa, int format);
|
||||
|
|
|
@ -352,8 +352,6 @@ void GSWnd::Detach()
|
|||
}
|
||||
}
|
||||
|
||||
PFNGLTEXSTORAGE2DPROC glTexStorage2D_glew17 = NULL;
|
||||
|
||||
bool GSWnd::Create(const string& title, int w, int h)
|
||||
{
|
||||
if(m_window != NULL) return false;
|
||||
|
@ -379,21 +377,6 @@ bool GSWnd::Create(const string& title, int w, int h)
|
|||
|
||||
m_managed = true;
|
||||
|
||||
// If the user request OpenGL acceleration, we take recent OGL version (4.2)
|
||||
// We keep the default 2.1 version in SW mode (only DX11 capable card, are compatible with OGL4)
|
||||
if ( theApp.GetConfig("renderer", 0) / 3 == 4 ) {
|
||||
// Setup visual attribute
|
||||
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
|
||||
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
|
||||
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
|
||||
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 32 );
|
||||
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
|
||||
SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 );
|
||||
// Ask for an advance opengl version
|
||||
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 4 );
|
||||
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 2 );
|
||||
}
|
||||
|
||||
m_window = SDL_CreateWindow(title.c_str(), 100, 100, w, h, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
|
||||
|
||||
// Get the X window from the newly created window
|
||||
|
@ -407,23 +390,6 @@ bool GSWnd::Create(const string& title, int w, int h)
|
|||
SDL_GetWindowWMInfo(m_window, &wminfo);
|
||||
m_Xwindow = wminfo.info.x11.window;
|
||||
|
||||
// OpenGL mode
|
||||
// FIXME : be sure that the window is map
|
||||
if ( theApp.GetConfig("renderer", 0) / 3 == 4 ) {
|
||||
// FIXME......
|
||||
// GLEW's problem is that it calls glGetString(GL_EXTENSIONS) which causes GL_INVALID_ENUM on GL 3.2 forward compatible context as soon as glewInit() is called. It also doesn't fetch the function pointers. The solution is for GLEW to use glGetStringi instead.
|
||||
// The current version of GLEW is 1.7.0 but they still haven't corrected it. The only fix is to use glewExperimental for now :
|
||||
glewExperimental=true;
|
||||
const int glew_ok = glewInit();
|
||||
if (glew_ok != GLEW_OK)
|
||||
{
|
||||
// FIXME:proper logging
|
||||
fprintf(stderr, "Failed to init glew\n");
|
||||
return false;
|
||||
}
|
||||
glTexStorage2D_glew17 = (PFNGLTEXSTORAGE2DPROC)glXGetProcAddressARB((const GLubyte*)"glTexStorage2D");
|
||||
}
|
||||
|
||||
return (m_window != NULL);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue