gsdx-ogl-wnd:

* Emulate Geometry Shader from the CPU.
* add some option to override opengl extension detection
* redo shader interface (again) to compile on the free driver

SW renderer is now working on the free driver.

To test it on your linux box use this cmake option -DEGL_API=TRUE
Note: (need opengl 3.0) I test mesa 9.2 git



git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl-wnd@5646 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gregory.hainaut 2013-05-27 16:53:38 +00:00
parent aafa7a088a
commit 75418aba43
17 changed files with 328 additions and 90 deletions

View File

@ -21,6 +21,7 @@
#include "stdafx.h"
#include "GLLoader.h"
#include "GSdx.h"
PFNGLACTIVETEXTUREPROC gl_ActiveTexture = NULL;
PFNGLBLENDCOLORPROC gl_BlendColor = NULL;
@ -99,6 +100,9 @@ namespace GLLoader {
bool found_GL_ARB_separate_shader_objects = false;
bool found_GL_ARB_shading_language_420pack = false;
bool found_GL_ARB_texture_storage = false;
bool found_geometry_shader = true;
bool found_GL_NV_copy_image = false;
bool found_GL_ARB_copy_image = false;
bool check_gl_version(uint32 major, uint32 minor) {
@ -117,11 +121,21 @@ namespace GLLoader {
GLuint major_gl = s[dot-1]-'0';
GLuint minor_gl = s[dot+1]-'0';
if ( (major_gl < 3) || ( major_gl == 3 && minor_gl < 2 ) ) {
fprintf(stderr, "Geometry shaders are not supported. Required openGL3.2\n");
found_geometry_shader = false;
}
if (theApp.GetConfig("override_geometry_shader", -1) != -1) {
found_geometry_shader = !!theApp.GetConfig("override_geometry_shader", -1);
fprintf(stderr, "Override geometry shaders detection\n");
}
if ( (major_gl < major) || ( major_gl == major && minor_gl < minor ) ) {
fprintf(stderr, "OPENGL %d.%d is not supported\n", major, minor);
return false;
}
return true;
}
@ -216,6 +230,13 @@ namespace GLLoader {
if (ext.compare("GL_ARB_texture_storage") == 0) {
found_GL_ARB_texture_storage = true;
}
if (ext.compare("GL_NV_copy_image") == 0) {
found_GL_NV_copy_image = true;
}
// Replace previous extensions (when driver will be updated)
if (ext.compare("GL_ARB_copy_image") == 0) {
found_GL_ARB_copy_image = true;
}
fprintf(stderr, "EXT: %s\n", ext.c_str());
}
}
@ -233,9 +254,15 @@ namespace GLLoader {
return false;
}
// REMOVE ME: Emulate open source driver
// found_GL_ARB_shading_language_420pack = false;
// found_GL_ARB_separate_shader_objects = true;
if (theApp.GetConfig("override_GL_ARB_shading_language_420pack", -1) != -1) {
found_GL_ARB_shading_language_420pack = !!theApp.GetConfig("override_GL_ARB_shading_language_420pack", -1);
fprintf(stderr, "Override GL_ARB_shading_language_420pack detection\n");
}
if (theApp.GetConfig("override_GL_ARB_separate_shader_objects", -1) != -1) {
found_GL_ARB_separate_shader_objects = !!theApp.GetConfig("override_GL_ARB_separate_shader_objects", -1);
fprintf(stderr, "Override GL_ARB_separate_shader_objects detection\n");
}
return true;
}

View File

@ -129,5 +129,8 @@ namespace GLLoader {
extern bool found_GL_ARB_separate_shader_objects;
extern bool found_GL_ARB_shading_language_420pack;
extern bool found_GL_ARB_texture_storage;
extern bool found_GL_ARB_copy_image;
extern bool found_GL_NV_copy_image;
extern bool found_geometry_shader;
extern bool fglrx_buggy_driver;
}

View File

@ -868,11 +868,24 @@ void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
// uint32 srcName, enum srcTarget, int srcLevel, int srcX, int srcY, int srcZ,
// uint32 dstName, enum dstTarget, int dstLevel, int dstX, int dstY, int dstZ,
// sizei width, sizei height, sizei depth);
gl_CopyImageSubDataNV( static_cast<GSTextureOGL*>(st)->GetID(), static_cast<GSTextureOGL*>(st)->GetTarget(),
0, r.x, r.y, 0,
static_cast<GSTextureOGL*>(dt)->GetID(), static_cast<GSTextureOGL*>(dt)->GetTarget(),
0, r.x, r.y, 0,
r.width(), r.height(), 1);
if (GLLoader::found_GL_NV_copy_image) {
gl_CopyImageSubDataNV( static_cast<GSTextureOGL*>(st)->GetID(), static_cast<GSTextureOGL*>(st)->GetTarget(),
0, r.x, r.y, 0,
static_cast<GSTextureOGL*>(dt)->GetID(), static_cast<GSTextureOGL*>(dt)->GetTarget(),
0, r.x, r.y, 0,
r.width(), r.height(), 1);
} else if (GLLoader::found_GL_ARB_copy_image) {
// Would need an update of GL definition. For the moment it isn't supported by driver anyway.
#if 0
gl_CopyImageSubData( static_cast<GSTextureOGL*>(st)->GetID(), static_cast<GSTextureOGL*>(st)->GetTarget(),
0, r.x, r.y, 0,
static_cast<GSTextureOGL*>(dt)->GetID(), static_cast<GSTextureOGL*>(dt)->GetTarget(),
0, r.x, r.y, 0,
r.width(), r.height(), 1);
#endif
} else {
// FIXME fallback for open source driver
}
#if 0
D3D11_BOX box = {r.left, r.top, 0, r.right, r.bottom, 1};
@ -1349,6 +1362,10 @@ void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const st
//if (!GLLoader::found_GL_ARB_shading_language_420pack) {
// version += "#define NO_STRUCT 1\n";
//}
} else {
#ifdef OGL_FREE_DRIVER
version += "#define DISABLE_SSO\n";
#endif
}
#ifdef OGL_FREE_DRIVER
version += "#extension GL_ARB_explicit_attrib_location : require\n";

View File

@ -47,10 +47,113 @@ bool GSRendererOGL::CreateDevice(GSDevice* dev)
return true;
}
void GSRendererOGL::EmulateGS()
{
switch(m_vt.m_primclass)
{
case GS_LINE_CLASS:
if(PRIM->IIP == 0)
{
for(size_t i = 0, j = m_index.tail; i < j; i += 2)
{
uint32 tmp = m_index.buff[i + 0];
m_index.buff[i + 0] = m_index.buff[i + 1];
m_index.buff[i + 1] = tmp;
}
}
break;
case GS_TRIANGLE_CLASS:
if(PRIM->IIP == 0)
{
for(size_t i = 0, j = m_index.tail; i < j; i += 3)
{
uint32 tmp = m_index.buff[i + 0];
m_index.buff[i + 0] = m_index.buff[i + 2];
m_index.buff[i + 2] = tmp;
}
}
break;
case GS_SPRITE_CLASS:
// each sprite converted to quad needs twice the space
while(m_vertex.tail * 2 > m_vertex.maxcount)
{
GrowVertexBuffer();
}
// assume vertices are tightly packed and sequentially indexed (it should be the case)
if(m_vertex.next >= 2)
{
size_t count = m_vertex.next;
int i = (int)count * 2 - 4;
GSVertex* s = &m_vertex.buff[count - 2];
GSVertex* q = &m_vertex.buff[count * 2 - 4];
uint32* RESTRICT index = &m_index.buff[count * 3 - 6];
for(; i >= 0; i -= 4, s -= 2, q -= 4, index -= 6)
{
GSVertex v0 = s[0];
GSVertex v1 = s[1];
v0.RGBAQ = v1.RGBAQ;
v0.XYZ.Z = v1.XYZ.Z;
v0.FOG = v1.FOG;
q[0] = v0;
q[3] = v1;
// swap x, s, u
uint16 x = v0.XYZ.X;
v0.XYZ.X = v1.XYZ.X;
v1.XYZ.X = x;
float s = v0.ST.S;
v0.ST.S = v1.ST.S;
v1.ST.S = s;
uint16 u = v0.U;
v0.U = v1.U;
v1.U = u;
q[1] = v0;
q[2] = v1;
index[0] = i + 0;
index[1] = i + 1;
index[2] = i + 2;
index[3] = i + 1;
index[4] = i + 2;
index[5] = i + 3;
}
m_vertex.head = m_vertex.tail = m_vertex.next = count * 2;
m_index.tail = count * 3;
}
break;
default:
__assume(0);
}
}
void GSRendererOGL::SetupIA()
{
GSDeviceOGL* dev = (GSDeviceOGL*)m_dev;
if (!GLLoader::found_geometry_shader)
EmulateGS();
void* ptr = NULL;
dev->IASetVertexState();
@ -81,9 +184,14 @@ void GSRendererOGL::SetupIA()
t = GL_POINTS;
break;
case GS_LINE_CLASS:
case GS_SPRITE_CLASS:
t = GL_LINES;
break;
case GS_SPRITE_CLASS:
if (GLLoader::found_geometry_shader)
t = GL_LINES;
else
t = GL_TRIANGLES;
break;
case GS_TRIANGLE_CLASS:
t = GL_TRIANGLES;
break;
@ -421,7 +529,8 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
dev->SetupOM(om_dssel, om_bsel, afix);
dev->SetupVS(vs_sel, &vs_cb);
dev->SetupGS(gs_sel);
if (GLLoader::found_geometry_shader)
dev->SetupGS(gs_sel);
dev->SetupPS(ps_sel, &ps_cb, ps_ssel);
// draw

View File

@ -44,6 +44,7 @@ class GSRendererOGL : public GSRendererHW
float UserHacks_TCO_x, UserHacks_TCO_y;
protected:
void EmulateGS();
void SetupIA();
public:

View File

@ -70,7 +70,8 @@ void GSDeviceOGL::CreateTextureFX()
GLuint dummy;
std::string macro = "\n";
CompileShaderFromSource("tfx.glsl", "vs_main", GL_VERTEX_SHADER, &dummy, tfx_glsl, macro);
CompileShaderFromSource("tfx.glsl", "gs_main", GL_GEOMETRY_SHADER, &dummy, tfx_glsl, macro);
if (GLLoader::found_geometry_shader)
CompileShaderFromSource("tfx.glsl", "gs_main", GL_GEOMETRY_SHADER, &dummy, tfx_glsl, macro);
CompileShaderFromSource("tfx.glsl", "ps_main", GL_FRAGMENT_SHADER, &dummy, tfx_glsl, macro);
#endif
}

View File

@ -41,4 +41,6 @@
#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
#ifdef EGL_API
#define OGL_FREE_DRIVER
#endif

View File

@ -33,10 +33,15 @@ layout(location = 0) out vertex_basic VSout;
#define VSout_p (VSout.p)
#define VSout_t (VSout.t)
#else
layout(location = 0) out vec4 p;
layout(location = 1) out vec2 t;
#define VSout_p p
#define VSout_t t
#ifdef DISABLE_SSO
out vec4 SHADERp;
out vec2 SHADERt;
#else
layout(location = 0) out vec4 SHADERp;
layout(location = 1) out vec2 SHADERt;
#endif
#define VSout_p SHADERp
#define VSout_t SHADERt
#endif
void vs_main()
@ -51,15 +56,20 @@ void vs_main()
#ifdef FRAGMENT_SHADER
// NOTE: pixel can be clip with "discard"
#if __VERSION__ > 140
#if __VERSION__ > 140 && !(defined(NO_STRUCT))
layout(location = 0) in vertex_basic PSin;
#define PSin_p (PSin.p)
#define PSin_t (PSin.t)
#else
layout(location = 0) in vec4 p;
layout(location = 1) in vec2 t;
#define PSin_p p
#define PSin_t t
#ifdef DISABLE_SSO
in vec4 SHADERp;
in vec2 SHADERt;
#else
layout(location = 0) in vec4 SHADERp;
layout(location = 1) in vec2 SHADERt;
#endif
#define PSin_p SHADERp
#define PSin_t SHADERt
#endif
layout(location = 0) out vec4 SV_Target0;

View File

@ -61,10 +61,15 @@ static const char* convert_glsl =
"#define VSout_p (VSout.p)\n"
"#define VSout_t (VSout.t)\n"
"#else\n"
"layout(location = 0) out vec4 p;\n"
"layout(location = 1) out vec2 t;\n"
"#define VSout_p p\n"
"#define VSout_t t\n"
"#ifdef DISABLE_SSO\n"
"out vec4 SHADERp;\n"
"out vec2 SHADERt;\n"
"#else\n"
"layout(location = 0) out vec4 SHADERp;\n"
"layout(location = 1) out vec2 SHADERt;\n"
"#endif\n"
"#define VSout_p SHADERp\n"
"#define VSout_t SHADERt\n"
"#endif\n"
"\n"
"void vs_main()\n"
@ -79,15 +84,20 @@ static const char* convert_glsl =
"#ifdef FRAGMENT_SHADER\n"
"// NOTE: pixel can be clip with \"discard\"\n"
"\n"
"#if __VERSION__ > 140\n"
"#if __VERSION__ > 140 && !(defined(NO_STRUCT))\n"
"layout(location = 0) in vertex_basic PSin;\n"
"#define PSin_p (PSin.p)\n"
"#define PSin_t (PSin.t)\n"
"#else\n"
"layout(location = 0) in vec4 p;\n"
"layout(location = 1) in vec2 t;\n"
"#define PSin_p p\n"
"#define PSin_t t\n"
"#ifdef DISABLE_SSO\n"
"in vec4 SHADERp;\n"
"in vec2 SHADERt;\n"
"#else\n"
"layout(location = 0) in vec4 SHADERp;\n"
"layout(location = 1) in vec2 SHADERt;\n"
"#endif\n"
"#define PSin_p SHADERp\n"
"#define PSin_t SHADERt\n"
"#endif\n"
"\n"
"layout(location = 0) out vec4 SV_Target0;\n"

View File

@ -6,17 +6,22 @@ struct vertex_basic
vec2 t;
};
#ifdef FRAGMENT_SHADER
#if __VERSION__ > 140 && !(defined(NO_STRUCT))
layout(location = 0) in vertex_basic PSin;
#define PSin_p (PSin.p)
#define PSin_t (PSin.t)
#else
layout(location = 0) in vec4 p;
layout(location = 1) in vec2 t;
#define PSin_p p
#define PSin_t t
#ifdef DISABLE_SSO
in vec4 SHADERp;
in vec2 SHADERt;
#else
layout(location = 0) in vec4 SHADERp;
layout(location = 1) in vec2 SHADERt;
#endif
#define PSin_p SHADERp
#define PSin_t SHADERt
#endif
#ifdef FRAGMENT_SHADER
layout(location = 0) out vec4 SV_Target0;

View File

@ -34,17 +34,22 @@ static const char* interlace_glsl =
" vec2 t;\n"
"};\n"
"\n"
"#ifdef FRAGMENT_SHADER\n"
"#if __VERSION__ > 140 && !(defined(NO_STRUCT))\n"
"layout(location = 0) in vertex_basic PSin;\n"
"#define PSin_p (PSin.p)\n"
"#define PSin_t (PSin.t)\n"
"#else\n"
"layout(location = 0) in vec4 p;\n"
"layout(location = 1) in vec2 t;\n"
"#define PSin_p p\n"
"#define PSin_t t\n"
"#ifdef DISABLE_SSO\n"
"in vec4 SHADERp;\n"
"in vec2 SHADERt;\n"
"#else\n"
"layout(location = 0) in vec4 SHADERp;\n"
"layout(location = 1) in vec2 SHADERt;\n"
"#endif\n"
"#define PSin_p SHADERp\n"
"#define PSin_t SHADERt\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"\n"
"layout(location = 0) out vec4 SV_Target0;\n"
"\n"

View File

@ -6,17 +6,22 @@ struct vertex_basic
vec2 t;
};
#ifdef FRAGMENT_SHADER
#if __VERSION__ > 140 && !(defined(NO_STRUCT))
layout(location = 0) in vertex_basic PSin;
#define PSin_p (PSin.p)
#define PSin_t (PSin.t)
#else
layout(location = 0) in vec4 p;
layout(location = 1) in vec2 t;
#define PSin_p p
#define PSin_t t
#ifdef DISABLE_SSO
in vec4 SHADERp;
in vec2 SHADERt;
#else
layout(location = 0) in vec4 SHADERp;
layout(location = 1) in vec2 SHADERt;
#endif
#define PSin_p SHADERp
#define PSin_t SHADERt
#endif
#ifdef FRAGMENT_SHADER
layout(location = 0) out vec4 SV_Target0;

View File

@ -34,17 +34,22 @@ static const char* merge_glsl =
" vec2 t;\n"
"};\n"
"\n"
"#ifdef FRAGMENT_SHADER\n"
"#if __VERSION__ > 140 && !(defined(NO_STRUCT))\n"
"layout(location = 0) in vertex_basic PSin;\n"
"#define PSin_p (PSin.p)\n"
"#define PSin_t (PSin.t)\n"
"#else\n"
"layout(location = 0) in vec4 p;\n"
"layout(location = 1) in vec2 t;\n"
"#define PSin_p p\n"
"#define PSin_t t\n"
"#ifdef DISABLE_SSO\n"
"in vec4 SHADERp;\n"
"in vec2 SHADERt;\n"
"#else\n"
"layout(location = 0) in vec4 SHADERp;\n"
"layout(location = 1) in vec2 SHADERt;\n"
"#endif\n"
"#define PSin_p SHADERp\n"
"#define PSin_t SHADERt\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"\n"
"layout(location = 0) out vec4 SV_Target0;\n"
"\n"

View File

@ -19,10 +19,15 @@ layout(location = 0) in vertex_basic PSin;
#define PSin_p (PSin.p)
#define PSin_t (PSin.t)
#else
layout(location = 0) in vec4 p;
layout(location = 1) in vec2 t;
#define PSin_p p
#define PSin_t t
#ifdef DISABLE_SSO
in vec4 SHADERp;
in vec2 SHADERt;
#else
layout(location = 0) in vec4 SHADERp;
layout(location = 1) in vec2 SHADERt;
#endif
#define PSin_p SHADERp
#define PSin_t SHADERt
#endif
layout(location = 0) out vec4 SV_Target0;

View File

@ -47,10 +47,15 @@ static const char* shadeboost_glsl =
"#define PSin_p (PSin.p)\n"
"#define PSin_t (PSin.t)\n"
"#else\n"
"layout(location = 0) in vec4 p;\n"
"layout(location = 1) in vec2 t;\n"
"#define PSin_p p\n"
"#define PSin_t t\n"
"#ifdef DISABLE_SSO\n"
"in vec4 SHADERp;\n"
"in vec2 SHADERt;\n"
"#else\n"
"layout(location = 0) in vec4 SHADERp;\n"
"layout(location = 1) in vec2 SHADERt;\n"
"#endif\n"
"#define PSin_p SHADERp\n"
"#define PSin_t SHADERt\n"
"#endif\n"
"\n"
"layout(location = 0) out vec4 SV_Target0;\n"

View File

@ -68,14 +68,21 @@ layout(location = 0) out vertex VSout;
#define VSout_tp (VSout.tp)
#define VSout_c (VSout.c)
#else
layout(location = 0) out vec4 p;
layout(location = 1) out vec4 t;
layout(location = 2) out vec4 tp;
layout(location = 3) out vec4 c;
#define VSout_p p
#define VSout_t t
#define VSout_tp tp
#define VSout_c c
#ifdef DISABLE_SSO
out vec4 SHADERp;
out vec4 SHADERt;
out vec4 SHADERtp;
out vec4 SHADERc;
#else
layout(location = 0) out vec4 SHADERp;
layout(location = 1) out vec4 SHADERt;
layout(location = 2) out vec4 SHADERtp;
layout(location = 3) out vec4 SHADERc;
#endif
#define VSout_p SHADERp
#define VSout_t SHADERt
#define VSout_tp SHADERtp
#define VSout_c SHADERc
#endif
#if __VERSION__ > 140
@ -293,14 +300,21 @@ layout(location = 0) in vertex PSin;
#define PSin_tp (PSin.tp)
#define PSin_c (PSin.c)
#else
layout(location = 0) in vec4 PSinp;
layout(location = 1) in vec4 PSint;
layout(location = 2) in vec4 PSintp;
layout(location = 3) in vec4 PSinc;
#define PSin_p PSinp
#define PSin_t PSint
#define PSin_tp PSintp
#define PSin_c PSinc
#ifdef DISABLE_SSO
in vec4 SHADERp;
in vec4 SHADERt;
in vec4 SHADERtp;
in vec4 SHADERc;
#else
layout(location = 0) in vec4 SHADERp;
layout(location = 1) in vec4 SHADERt;
layout(location = 2) in vec4 SHADERtp;
layout(location = 3) in vec4 SHADERc;
#endif
#define PSin_p SHADERp
#define PSin_t SHADERt
#define PSin_tp SHADERtp
#define PSin_c SHADERc
#endif
// Same buffer but 2 colors for dual source blending

View File

@ -96,14 +96,21 @@ static const char* tfx_glsl =
"#define VSout_tp (VSout.tp)\n"
"#define VSout_c (VSout.c)\n"
"#else\n"
"layout(location = 0) out vec4 p;\n"
"layout(location = 1) out vec4 t;\n"
"layout(location = 2) out vec4 tp;\n"
"layout(location = 3) out vec4 c;\n"
"#define VSout_p p\n"
"#define VSout_t t\n"
"#define VSout_tp tp\n"
"#define VSout_c c\n"
"#ifdef DISABLE_SSO\n"
"out vec4 SHADERp;\n"
"out vec4 SHADERt;\n"
"out vec4 SHADERtp;\n"
"out vec4 SHADERc;\n"
"#else\n"
"layout(location = 0) out vec4 SHADERp;\n"
"layout(location = 1) out vec4 SHADERt;\n"
"layout(location = 2) out vec4 SHADERtp;\n"
"layout(location = 3) out vec4 SHADERc;\n"
"#endif\n"
"#define VSout_p SHADERp\n"
"#define VSout_t SHADERt\n"
"#define VSout_tp SHADERtp\n"
"#define VSout_c SHADERc\n"
"#endif\n"
"\n"
"#if __VERSION__ > 140\n"
@ -321,14 +328,21 @@ static const char* tfx_glsl =
"#define PSin_tp (PSin.tp)\n"
"#define PSin_c (PSin.c)\n"
"#else\n"
"layout(location = 0) in vec4 PSinp;\n"
"layout(location = 1) in vec4 PSint;\n"
"layout(location = 2) in vec4 PSintp;\n"
"layout(location = 3) in vec4 PSinc;\n"
"#define PSin_p PSinp\n"
"#define PSin_t PSint\n"
"#define PSin_tp PSintp\n"
"#define PSin_c PSinc\n"
"#ifdef DISABLE_SSO\n"
"in vec4 SHADERp;\n"
"in vec4 SHADERt;\n"
"in vec4 SHADERtp;\n"
"in vec4 SHADERc;\n"
"#else\n"
"layout(location = 0) in vec4 SHADERp;\n"
"layout(location = 1) in vec4 SHADERt;\n"
"layout(location = 2) in vec4 SHADERtp;\n"
"layout(location = 3) in vec4 SHADERc;\n"
"#endif\n"
"#define PSin_p SHADERp\n"
"#define PSin_t SHADERt\n"
"#define PSin_tp SHADERtp\n"
"#define PSin_c SHADERc\n"
"#endif\n"
"\n"
"// Same buffer but 2 colors for dual source blending\n"