gsdx-ogl-wnd:

* fix wrong interaction when both GL41 or GL42 aren't supported
* Add a new define to downgrade opengl requirement to test the free driver and EGL
 => As far as I can tell, they only miss geometry shader& GLSL150 (got GLSL140)
* Found a way to avoid crash in AMD driver. Skip the upload of small texture but rendering is wrong now...


git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl-wnd@5643 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gregory.hainaut 2013-05-25 14:28:16 +00:00
parent 49cd9fd97d
commit c9b3dcf581
17 changed files with 180 additions and 61 deletions

View File

@ -90,6 +90,7 @@ PFNGLGETSHADERINFOLOGPROC gl_GetShaderInfoLog = NULL;
// NO GL4.2
PFNGLGETUNIFORMBLOCKINDEXPROC gl_GetUniformBlockIndex = NULL;
PFNGLUNIFORMBLOCKBINDINGPROC gl_UniformBlockBinding = NULL;
PFNGLGETUNIFORMLOCATIONPROC gl_GetUniformLocation = NULL;
namespace GLLoader {
@ -192,6 +193,7 @@ namespace GLLoader {
// NO GL4.2
GL_LOADFN(gl_GetUniformBlockIndex, glGetUniformBlockIndex);
GL_LOADFN(gl_UniformBlockBinding, glUniformBlockBinding);
GL_LOADFN(gl_GetUniformLocation, glGetUniformLocation);
}
bool check_gl_supported_extension() {

View File

@ -117,6 +117,7 @@ extern PFNGLGETSHADERINFOLOGPROC gl_GetShaderInfoLog;
// NO GL4.2
extern PFNGLGETUNIFORMBLOCKINDEXPROC gl_GetUniformBlockIndex;
extern PFNGLUNIFORMBLOCKBINDINGPROC gl_UniformBlockBinding;
extern PFNGLGETUNIFORMLOCATIONPROC gl_GetUniformLocation;
namespace GLLoader {

View File

@ -181,7 +181,11 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
if (m_window == NULL) {
GLLoader::init_gl_function();
#ifdef OGL_FREE_DRIVER
if (!GLLoader::check_gl_version(3, 0)) return false;
#else
if (!GLLoader::check_gl_version(3, 3)) return false;
#endif
if (!GLLoader::check_gl_supported_extension()) return false;
}
@ -471,7 +475,11 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
}
#endif
#ifdef OGL_FREE_DRIVER
return false;
#else
return true;
#endif
}
bool GSDeviceOGL::Reset(int w, int h)
@ -591,6 +599,13 @@ static void set_uniform_buffer_binding(GLuint prog, GLchar* name, GLuint binding
}
}
static void set_sampler_uniform_binding(GLuint prog, GLchar* name, GLuint binding) {
GLint loc = gl_GetUniformLocation(prog, name);
if (loc != -1) {
gl_Uniform1i(loc, binding);
}
}
GLuint GSDeviceOGL::link_prog()
{
GLuint single_prog = gl_CreateProgram();
@ -628,12 +643,14 @@ void GSDeviceOGL::BeforeDraw()
#ifdef ENABLE_OGL_DEBUG
DebugInput();
#endif
hash_map<uint64, GLuint >::iterator single_prog;
if (!GLLoader::found_GL_ARB_separate_shader_objects) {
// Note: shader are integer lookup pointer. They start from 1 and incr
// every time you create a new shader OR a new program.
uint64 sel = (uint64)m_state.vs << 40 | (uint64)m_state.gs << 20 | m_state.ps;
auto single_prog = m_single_prog.find(sel);
single_prog = m_single_prog.find(sel);
if (single_prog == m_single_prog.end()) {
m_single_prog[sel] = link_prog();
single_prog = m_single_prog.find(sel);
@ -643,13 +660,31 @@ void GSDeviceOGL::BeforeDraw()
}
if (!GLLoader::found_GL_ARB_shading_language_420pack) {
set_uniform_buffer_binding(m_state.vs, "cb20", 20);
set_uniform_buffer_binding(m_state.ps, "cb21", 21);
if (GLLoader::found_GL_ARB_separate_shader_objects) {
set_uniform_buffer_binding(m_state.vs, "cb20", 20);
set_uniform_buffer_binding(m_state.ps, "cb21", 21);
set_uniform_buffer_binding(m_state.ps, "cb10", 10);
set_uniform_buffer_binding(m_state.ps, "cb11", 11);
set_uniform_buffer_binding(m_state.ps, "cb12", 12);
set_uniform_buffer_binding(m_state.ps, "cb13", 13);
set_uniform_buffer_binding(m_state.ps, "cb10", 10);
set_uniform_buffer_binding(m_state.ps, "cb11", 11);
set_uniform_buffer_binding(m_state.ps, "cb12", 12);
set_uniform_buffer_binding(m_state.ps, "cb13", 13);
set_sampler_uniform_binding(m_state.ps, "TextureSampler", 0);
set_sampler_uniform_binding(m_state.ps, "PaletteSampler", 1);
set_sampler_uniform_binding(m_state.ps, "RTCopySampler", 2);
} else {
set_uniform_buffer_binding(single_prog->second, "cb20", 20);
set_uniform_buffer_binding(single_prog->second, "cb21", 21);
set_uniform_buffer_binding(single_prog->second, "cb10", 10);
set_uniform_buffer_binding(single_prog->second, "cb11", 11);
set_uniform_buffer_binding(single_prog->second, "cb12", 12);
set_uniform_buffer_binding(single_prog->second, "cb13", 13);
set_sampler_uniform_binding(single_prog->second, "TextureSampler", 0);
set_sampler_uniform_binding(single_prog->second, "PaletteSampler", 1);
set_sampler_uniform_binding(single_prog->second, "RTCopySampler", 2);
}
}
}
@ -1298,7 +1333,11 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st
// Build a header string
// *****************************************************
// First select the version (must be the first line so we need to generate it
#ifdef OGL_FREE_DRIVER
std::string version = "#version 130\n";
#else
std::string version = "#version 330\n";
#endif
if (GLLoader::found_GL_ARB_shading_language_420pack) {
version += "#extension GL_ARB_shading_language_420pack: require\n";
} else {
@ -1307,6 +1346,10 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st
if (GLLoader::found_GL_ARB_separate_shader_objects) {
version += "#extension GL_ARB_separate_shader_objects : require\n";
}
#ifdef OGL_FREE_DRIVER
version += "#extension GL_ARB_explicit_attrib_location : require\n";
version += "#extension GL_ARB_uniform_buffer_object : require\n";
#endif
// Allow to puts several shader in 1 files
std::string shader_type;

View File

@ -25,6 +25,10 @@
static int g_state_texture_unit = -1;
static int g_state_texture_id = -1;
// FIXME: check if it possible to always use those setup by default
// glPixelStorei(GL_PACK_ALIGNMENT, 1);
// glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format, GLuint fbo_read)
: m_pbo_id(0),
m_pbo_size(0)
@ -153,33 +157,56 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
EnableUnit(0);
// pitch could be different of width*element_size
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch>>2);
// FIXME : it crash on colin mcrae rally 3 (others game too) when the size is 16
//fprintf(stderr, "Texture %dx%d with a pitch of %d\n", m_size.x, m_size.y, pitch >>2);
//fprintf(stderr, "Box (%d,%d)x(%d,%d)\n", r.x, r.y, r.width(), r.height());
if (m_format == GL_RGBA8)
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), GL_RGBA, GL_UNSIGNED_BYTE, data);
else if (m_format == GL_R16UI)
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), GL_RED_INTEGER, GL_R16UI, data);
else if (m_format == GL_R8)
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), GL_RED, GL_R8, data);
else {
fprintf(stderr, "wrong texture pixel format :%x\n", m_format);
ASSERT(0);
// pitch is in byte wherease GL_UNPACK_ROW_LENGTH is in pixel
GLenum format;
GLenum type;
switch (m_format) {
case GL_RGBA8:
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch>>2);
format = GL_RGBA;
type = GL_UNSIGNED_BYTE;
break;
case GL_R16UI:
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch>>1);
format = GL_RED;
type = GL_UNSIGNED_SHORT;
break;
case GL_R8:
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch);
format = GL_RED;
type = GL_UNSIGNED_BYTE;
break;
default:
fprintf(stderr, "wrong texture pixel format :%x\n", m_format);
ASSERT(0);
}
#if 0
//if (m_size.x != 16)
if (r.width() > 16 && r.height() > 16)
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), GL_RGBA, GL_UNSIGNED_BYTE, data);
else {
fprintf(stderr, "skip texture upload\n");
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); // Restore default behavior
return false;
#ifdef _LINUX
if (GLLoader::fglrx_buggy_driver) {
// FIXME : it crash on colin mcrae rally 3 (others game too) when the texture is small
//if ((pitch >> 2) == 32 || r.width() < 32 || r.height() < 32) {
if ((r.width() < 32) || (pitch == 128 && r.width() == 32)) {
#ifdef ENABLE_OGL_DEBUG
fprintf(stderr, "Skip Texture %dx%d with a pitch of %d pixel. Type %x\n", m_size.x, m_size.y, pitch >>2, m_format);
fprintf(stderr, "Box (%d,%d)x(%d,%d)\n", r.x, r.y, r.width(), r.height());
#endif
//char *random = (char*)malloc(m_size.x*m_size.y*32);
//glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), GL_RGBA, GL_UNSIGNED_BYTE, random);
//return true;
//glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), GL_RGBA, GL_UNSIGNED_BYTE, data);
//glFinish();
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); // Restore default behavior
return false;
}
}
#endif
glTexSubImage2D(m_texture_target, 0, r.x, r.y, r.width(), r.height(), format, type, data);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); // Restore default behavior
return true;

View File

@ -55,12 +55,9 @@ bool GSWndEGL::CreateContext(int major, int minor)
EGL_CONTEXT_MAJOR_VERSION_KHR, major,
EGL_CONTEXT_MINOR_VERSION_KHR, minor,
// Keep compatibility for old cruft
EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR,
//EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR,
//EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR,
// FIXME : Request a debug context to ease opengl development
#if defined(ZEROGS_DEVBUILD) || defined(_DEBUG)
EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR,
#endif
EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR,
EGL_NONE
};
EGLint attrList[] = {
@ -76,22 +73,22 @@ bool GSWndEGL::CreateContext(int major, int minor)
if ( !eglChooseConfig(m_eglDisplay, attrList, &eglConfig, 1, &numConfigs) )
{
fprintf(stderr,"EGL: Failed to get a frame buffer config!");
fprintf(stderr,"EGL: Failed to get a frame buffer config!\n");
return EGL_FALSE;
}
m_eglSurface = eglCreateWindowSurface(m_eglDisplay, eglConfig, m_NativeWindow, NULL);
if ( m_eglSurface == EGL_NO_SURFACE )
{
fprintf(stderr,"EGL: Failed to get a window surface");
fprintf(stderr,"EGL: Failed to get a window surface\n");
return EGL_FALSE;
}
m_eglContext = eglCreateContext(m_eglDisplay, eglConfig, EGL_NO_CONTEXT, contextAttribs );
if ( m_eglContext == EGL_NO_CONTEXT )
{
fprintf(stderr,"EGL: Failed to create the context");
fprintf(stderr,"EGL STATUS: %x", eglGetError());
fprintf(stderr,"EGL: Failed to create the context\n");
fprintf(stderr,"EGL STATUS: %x\n", eglGetError());
return EGL_FALSE;
}
@ -123,8 +120,8 @@ void GSWndEGL::DetachContext()
void GSWndEGL::CheckContext()
{
fprintf(stderr,"EGL: %s : %s", eglQueryString(m_eglDisplay, EGL_VENDOR) , eglQueryString(m_eglDisplay, EGL_VERSION) );
fprintf(stderr,"EGL: extensions supported: %s", eglQueryString(m_eglDisplay, EGL_EXTENSIONS));
fprintf(stderr,"EGL: %s : %s\n", eglQueryString(m_eglDisplay, EGL_VENDOR) , eglQueryString(m_eglDisplay, EGL_VERSION) );
fprintf(stderr,"EGL: extensions supported: %s\n", eglQueryString(m_eglDisplay, EGL_EXTENSIONS));
}
bool GSWndEGL::Attach(void* handle, bool managed)

View File

@ -40,3 +40,5 @@
#ifdef _DEBUG
#define ENABLE_OGL_DEBUG // Create a debug context and check opengl command status. Allow also to dump various textures/states.
#endif
//#define OGL_FREE_DRIVER

View File

@ -21,12 +21,6 @@
#include "stdafx.h"
#include <dlfcn.h>
//typedef void* (ReplaysetSettingsDir)(const char*);
//typedef void* (ReplayReplay)(char*, int);
//ypedef void* (*GSsetSettingsDir)(const char* dir);
//void (*GSReplay)(char* lpszCmdLine, int renderer);
void help()
{
fprintf(stderr, "Loader gs file\n");
@ -46,10 +40,6 @@ int main ( int argc, char *argv[] )
help();
}
#if 0
ReplaysetSettingsDir GSsetSettingsDir_ptr;
ReplayReplay GSReplay_ptr;
#endif
void (*GSsetSettingsDir_ptr)(const char*);
void (*GSReplay_ptr)(char*, int);
@ -63,6 +53,7 @@ int main ( int argc, char *argv[] )
std::string home("HOME");
char * val = getenv( home.c_str() );
if (val == NULL) {
dlclose(handle);
fprintf(stderr, "Failed to get the home dir\n");
help();
}
@ -73,9 +64,11 @@ int main ( int argc, char *argv[] )
GSsetSettingsDir_ptr(ini_dir.c_str());
#else
fprintf(stderr, "default ini dir only supported on XDG\n");
dlclose(handle);
help();
#endif
}
GSReplay_ptr(argv[2], 12);
dlclose(handle);
}

View File

@ -9,11 +9,13 @@ struct vertex_basic
#ifdef VERTEX_SHADER
#if __VERSION__ > 140
out gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
};
#endif
layout(location = 0) in vec4 POSITION;
layout(location = 1) in vec2 TEXCOORD0;
@ -45,23 +47,28 @@ layout(location = 0) in vertex_basic PSin;
layout(location = 0) out vec4 SV_Target0;
layout(location = 1) out uint SV_Target1;
#ifdef DISABLE_GL42
uniform sampler2D TextureSampler;
#else
layout(binding = 0) uniform sampler2D TextureSampler;
#endif
vec4 sample_c()
{
return texture(TextureSampler, PSin.t );
}
vec4 ps_crt(uint i)
{
vec4 mask[4] =
{
uniform vec4 mask[4] = vec4[4]
(
vec4(1, 0, 0, 0),
vec4(0, 1, 0, 0),
vec4(0, 0, 1, 0),
vec4(1, 1, 1, 0)
};
);
vec4 ps_crt(uint i)
{
return sample_c() * clamp((mask[i] + 0.5f), 0.0f, 1.0f);
}

View File

@ -37,11 +37,13 @@ static const char* convert_glsl =
"\n"
"#ifdef VERTEX_SHADER\n"
"\n"
"#if __VERSION__ > 140\n"
"out gl_PerVertex {\n"
" vec4 gl_Position;\n"
" float gl_PointSize;\n"
" float gl_ClipDistance[];\n"
"};\n"
"#endif\n"
"\n"
"layout(location = 0) in vec4 POSITION;\n"
"layout(location = 1) in vec2 TEXCOORD0;\n"
@ -73,23 +75,28 @@ static const char* convert_glsl =
"layout(location = 0) out vec4 SV_Target0;\n"
"layout(location = 1) out uint SV_Target1;\n"
"\n"
"#ifdef DISABLE_GL42\n"
"uniform sampler2D TextureSampler;\n"
"#else\n"
"layout(binding = 0) uniform sampler2D TextureSampler;\n"
"#endif\n"
"\n"
"vec4 sample_c()\n"
"{\n"
" return texture(TextureSampler, PSin.t );\n"
"}\n"
"\n"
"vec4 ps_crt(uint i)\n"
"{\n"
" vec4 mask[4] =\n"
" {\n"
"uniform vec4 mask[4] = vec4[4]\n"
"(\n"
" vec4(1, 0, 0, 0),\n"
" vec4(0, 1, 0, 0),\n"
" vec4(0, 0, 1, 0),\n"
" vec4(1, 1, 1, 0)\n"
" };\n"
");\n"
"\n"
"\n"
"vec4 ps_crt(uint i)\n"
"{\n"
" return sample_c() * clamp((mask[i] + 0.5f), 0.0f, 1.0f);\n"
"}\n"
"\n"

View File

@ -21,7 +21,11 @@ layout(std140, binding = 11) uniform cb11
float hH;
};
#ifdef DISABLE_GL42
uniform sampler2D TextureSampler;
#else
layout(binding = 0) uniform sampler2D TextureSampler;
#endif
// TODO ensure that clip (discard) is < 0 and not <= 0 ???
void ps_main0()

View File

@ -49,7 +49,11 @@ static const char* interlace_glsl =
" float hH;\n"
"};\n"
"\n"
"#ifdef DISABLE_GL42\n"
"uniform sampler2D TextureSampler;\n"
"#else\n"
"layout(binding = 0) uniform sampler2D TextureSampler;\n"
"#endif\n"
"\n"
"// TODO ensure that clip (discard) is < 0 and not <= 0 ???\n"
"void ps_main0()\n"

View File

@ -20,7 +20,11 @@ layout(std140, binding = 10) uniform cb10
vec4 BGColor;
};
#ifdef DISABLE_GL42
uniform sampler2D TextureSampler;
#else
layout(binding = 0) uniform sampler2D TextureSampler;
#endif
void ps_main0()
{

View File

@ -48,7 +48,11 @@ static const char* merge_glsl =
" vec4 BGColor;\n"
"};\n"
"\n"
"#ifdef DISABLE_GL42\n"
"uniform sampler2D TextureSampler;\n"
"#else\n"
"layout(binding = 0) uniform sampler2D TextureSampler;\n"
"#endif\n"
"\n"
"void ps_main0()\n"
"{\n"

View File

@ -27,7 +27,11 @@ layout(std140, binding = 12) uniform cb12
vec4 BGColor;
};
#ifdef DISABLE_GL42
uniform sampler2D TextureSampler;
#else
layout(binding = 0) uniform sampler2D TextureSampler;
#endif
// For all settings: 1.0 = 100% 0.5=50% 1.5 = 150%
vec4 ContrastSaturationBrightness(vec4 color)

View File

@ -55,7 +55,11 @@ static const char* shadeboost_glsl =
" vec4 BGColor;\n"
"};\n"
"\n"
"#ifdef DISABLE_GL42\n"
"uniform sampler2D TextureSampler;\n"
"#else\n"
"layout(binding = 0) uniform sampler2D TextureSampler;\n"
"#endif\n"
"\n"
"// For all settings: 1.0 = 100\% 0.5=50\% 1.5 = 150\% \n"
"vec4 ContrastSaturationBrightness(vec4 color)\n"

View File

@ -63,11 +63,13 @@ layout(location = 6) in vec4 i_f;
layout(location = 0) out vertex VSout;
#if __VERSION__ > 140
out gl_PerVertex {
invariant vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
};
#endif
#ifdef DISABLE_GL42
layout(std140) uniform cb20
@ -275,9 +277,15 @@ layout(location = 0) in vertex PSin;
layout(location = 0, index = 0) out vec4 SV_Target0;
layout(location = 0, index = 1) out vec4 SV_Target1;
#ifdef DISABLE_GL42
uniform sampler2D TextureSampler;
uniform sampler2D PaletteSampler;
uniform sampler2D RTCopySampler;
#else
layout(binding = 0) uniform sampler2D TextureSampler;
layout(binding = 1) uniform sampler2D PaletteSampler;
layout(binding = 2) uniform sampler2D RTCopySampler;
#endif
#ifdef DISABLE_GL42
layout(std140) uniform cb21

View File

@ -91,11 +91,13 @@ static const char* tfx_glsl =
"\n"
"layout(location = 0) out vertex VSout;\n"
"\n"
"#if __VERSION__ > 140\n"
"out gl_PerVertex {\n"
" invariant vec4 gl_Position;\n"
" float gl_PointSize;\n"
" float gl_ClipDistance[];\n"
"};\n"
"#endif\n"
"\n"
"#ifdef DISABLE_GL42\n"
"layout(std140) uniform cb20\n"
@ -303,9 +305,15 @@ static const char* tfx_glsl =
"layout(location = 0, index = 0) out vec4 SV_Target0;\n"
"layout(location = 0, index = 1) out vec4 SV_Target1;\n"
"\n"
"#ifdef DISABLE_GL42\n"
"uniform sampler2D TextureSampler;\n"
"uniform sampler2D PaletteSampler;\n"
"uniform sampler2D RTCopySampler;\n"
"#else\n"
"layout(binding = 0) uniform sampler2D TextureSampler;\n"
"layout(binding = 1) uniform sampler2D PaletteSampler;\n"
"layout(binding = 2) uniform sampler2D RTCopySampler;\n"
"#endif\n"
"\n"
"#ifdef DISABLE_GL42\n"
"layout(std140) uniform cb21\n"