gsdx-ogl: LINUX-ONLY

* rework a little the shader to be hopefully compatible with nvidia
* request a pure 4.2 context (all gpu 4.1 capable support 4.2 anyway)


git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl@5003 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gregory.hainaut 2011-12-21 23:09:36 +00:00
parent f604ba8d7f
commit a9927a6e33
7 changed files with 68 additions and 88 deletions

View File

@ -206,5 +206,6 @@ else(PACKAGE_MODE)
install(TARGETS ${Output} DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/convert.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/interlace.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/merge.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
install(FILES ${PROJECT_SOURCE_DIR}/plugins/GSdx/res/tfx.glsl DESTINATION ${CMAKE_SOURCE_DIR}/bin/plugins)
endif(PACKAGE_MODE)

View File

@ -170,12 +170,26 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
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;
}
// Note: don't rely on glew to avoid to pull glew1.7
// Instead we just copy/adapt the 10 lines of code
// if (!GLEW_VERSION_4_2) {
// fprintf(stderr, "4.2 is not supported!\n");
// return false;
// }
const GLubyte* s;
s = glGetString(GL_VERSION);
if (s == NULL) return false;
GLuint dot;
while (s[dot] != '\0' && s[dot] != '.') dot++;
if (dot == 0) return false;
GLuint major = s[dot-1]-'0';
GLuint minor = s[dot+1]-'0';
if ( (major < 4) || ( major == 4 && minor < 2 ) ) return false;
}
// FIXME disable it when code is ready
@ -465,7 +479,7 @@ bool GSDeviceOGL::Reset(int w, int h)
// Opengl allocate the backbuffer with the window. The render is done in the backbuffer when
// there isn't any FBO. Only a dummy texture is created to easily detect when the rendering is done
// in the backbuffer
m_backbuffer = new GSTextureOGL(0, w, h, false, 0);
m_backbuffer = new GSTextureOGL(0, w, h, false, GSTextureOGL::Backbuffer);
return true;
}
@ -484,8 +498,7 @@ void GSDeviceOGL::DrawPrimitive()
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
{
GSTextureOGL* t_ogl = (GSTextureOGL*)t;
if (t == m_backbuffer) {
if (static_cast<GSTextureOGL*>(t)->IsBackbuffer()) {
// FIXME I really not sure
OMSetFBO(0);
//glClearBufferfv(GL_COLOR, GL_LEFT, c.v);
@ -497,7 +510,7 @@ void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
// FIXME I need to clarify this FBO attachment stuff
// I would like to avoid FBO for a basic clean operation
OMSetFBO(m_fbo);
t_ogl->Attach(GL_COLOR_ATTACHMENT0);
static_cast<GSTextureOGL*>(t)->Attach(GL_COLOR_ATTACHMENT0);
glClearBufferfv(GL_COLOR, 0, c.v);
}
}
@ -544,6 +557,7 @@ GSTexture* GSDeviceOGL::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w
{
// I'm not sure about the object type for offscreen buffer
// TODO later;
assert(0);
// Need to find format equivalent. Then I think it will be straight forward
@ -680,7 +694,7 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
// 2/ in case some GSdx code expect thing in dx order.
// Only flipping the backbuffer is transparent (I hope)...
GSVector4 flip_sr = sr;
if (dt == m_backbuffer) {
if (static_cast<GSTextureOGL*>(dt)->IsBackbuffer()) {
flip_sr.y = 1.0f - sr.y;
flip_sr.w = 1.0f - sr.w;
}
@ -1073,20 +1087,17 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto
m_ctx->OMSetRenderTargets(1, &rtv, dsv);
}
#endif
GSTextureOGL* rt_ogl = (GSTextureOGL*)rt;
GSTextureOGL* ds_ogl = (GSTextureOGL*)ds;
if (m_backbuffer == rt_ogl) {
if (static_cast<GSTextureOGL*>(rt)->IsBackbuffer()) {
OMSetFBO(0);
assert(ds_ogl == NULL); // no depth-stencil without FBO
assert(ds == NULL); // no depth-stencil without FBO
} else {
OMSetFBO(m_fbo);
assert(rt_ogl != NULL); // a render target must exists
rt_ogl->Attach(GL_COLOR_ATTACHMENT0);
if (ds_ogl != NULL)
ds_ogl->Attach(GL_DEPTH_STENCIL_ATTACHMENT);
assert(rt != NULL); // a render target must exists
static_cast<GSTextureOGL*>(rt)->Attach(GL_COLOR_ATTACHMENT0);
if (ds != NULL)
static_cast<GSTextureOGL*>(ds)->Attach(GL_DEPTH_STENCIL_ATTACHMENT);
}
// Viewport -> glViewport
@ -1115,7 +1126,8 @@ 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
std::string version = "#version 410\n#extension GL_ARB_shading_language_420pack: enable\n";
//std::string version = "#version 410\n#extension GL_ARB_shading_language_420pack: enable\n";
std::string version = "#version 420\n";
// Allow to puts several shader in 1 files
std::string shader_type;

View File

@ -35,7 +35,7 @@ protected:
public:
struct GSMap {uint8* bits; int pitch;};
enum {RenderTarget = 1, DepthStencil, Texture, Offscreen};
enum {RenderTarget = 1, DepthStencil, Texture, Offscreen, Backbuffer};
public:
GSTexture();

View File

@ -58,26 +58,14 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format)
// glReadBuffer
// glBlitFramebuffer
// TODO: we can render directly into a texture so I'm not sure rendertarget are useful anymore !!!
// *************************************************************
// Doc
// It might need a texture structure to replace ID3D11Texture2D.
//
// == The function need to set (from parameter)
// : m_size.x
// : m_size.y
// : m_type
// : m_format
// : m_msaa
m_size.x = w;
m_size.y = h;
m_format = format;
m_type = type;
m_msaa = msaa;
// == Might be useful to save
// : m_texture_target (like GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE etc...)
// : m_texture_id (return by glGen*)
//
// == Then generate the texture or buffer.
// D3D11_BIND_RENDER_TARGET: Bind a texture as a render target for the output-merger stage.
// => glGenRenderbuffers with GL_COLOR_ATTACHMENTi (Hum glGenTextures might work too)

View File

@ -43,4 +43,6 @@ class GSTextureOGL : public GSTexture
void EnableUnit(uint unit);
void Attach(GLenum attachment);
bool IsBackbuffer() { return (m_type == GSTexture::Backbuffer); }
};

View File

@ -370,7 +370,7 @@ bool GSWnd::Attach(void* handle, bool managed)
int context_attribs[] =
{
GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
GLX_CONTEXT_MINOR_VERSION_ARB, 1,
GLX_CONTEXT_MINOR_VERSION_ARB, 2,
// FIXME : Request a debug context to ease opengl development
// Note: don't support deprecated feature (pre openg 3.1)
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,

View File

@ -39,6 +39,14 @@
#define PS_DATE 0
#endif
struct vertex
{
vec4 p;
vec4 t;
vec4 tp;
vec4 c;
};
#ifdef VERTEX_SHADER
layout(location = 0) in vec2 i_t;
layout(location = 1) in vec4 i_c;
@ -47,13 +55,7 @@ layout(location = 3) in uvec2 i_p;
layout(location = 4) in uint i_z;
layout(location = 5) in vec4 i_f;
layout(location = 0) out VSout
{
vec4 o_p;
vec4 o_t;
vec4 o_tp;
vec4 o_c;
};
layout(location = 0) out vertex OUT;
out gl_PerVertex {
vec4 gl_Position;
@ -87,9 +89,9 @@ void vs_main()
vec4 p = vec4(i_p, z, 0) - vec4(0.05f, 0.05f, 0, 0);
o_p = p * VertexScale - VertexOffset;
OUT.p = p * VertexScale - VertexOffset;
#if VS_RTCOPY
o_tp = (p * VertexScale - VertexOffset) * vec4(0.5, -0.5, 0, 0) + 0.5;
OUT.tp = (p * VertexScale - VertexOffset) * vec4(0.5, -0.5, 0, 0) + 0.5;
#endif
gl_Position = p; // NOTE I don't know if it is possible to merge POSITION_OUT and gl_Position
@ -97,23 +99,23 @@ void vs_main()
{
if(VS_FST != 0)
{
o_t.xy = i_t * TextureScale;
o_t.w = 1.0f;
OUT.t.xy = i_t * TextureScale;
OUT.t.w = 1.0f;
}
else
{
o_t.xy = i_t;
o_t.w = i_q;
OUT.t.xy = i_t;
OUT.t.w = i_q;
}
}
else
{
o_t.xy = vec2(0.0f, 0.0f);
o_t.w = 1.0f;
OUT.t.xy = vec2(0.0f, 0.0f);
OUT.t.w = 1.0f;
}
o_c = i_c;
o_t.z = i_f.a;
OUT.c = i_c;
OUT.t.z = i_f.a;
}
#endif
@ -131,21 +133,9 @@ out gl_PerVertex {
float gl_ClipDistance[];
};
layout(location = 0) in GSin
{
vec4 p;
vec4 t;
vec4 tp;
vec4 c;
} GSin[];
layout(location = 0) in vertex GSin[];
layout(location = 0) out GSout
{
vec4 p;
vec4 t;
vec4 tp;
vec4 c;
} GSout;
layout(location = 0) out vertex GSout;
#if GS_PRIM == 0
layout(points) in;
@ -201,14 +191,6 @@ void gs_main()
layout(lines) in;
layout(triangle_strip, max_vertices = 4) out;
void set_output(uint i)
{
GSout.p = GSin[i].p;
GSout.t = GSin[i].t;
GSout.tp = GSin[i].tp;
GSout.c = GSin[i].c;
}
void gs_main()
{
// left top => GSin[0];
@ -216,7 +198,7 @@ void gs_main()
// left top
set_output(0);
GSout = GSin[0];
GSout.p.z = GSin[1].p.z;
GSout.t.zw = GSin[1].t.zw;
@ -227,7 +209,7 @@ void gs_main()
EmitVertex();
// left bottom
set_output(1);
GSout = GSin[1];
gl_Position = gl_in[1].gl_Position; // FIXME is it useful
gl_Position.x = GSin[0].p.x;
GSout.p.x = GSin[0].p.x;
@ -235,7 +217,7 @@ void gs_main()
EmitVertex();
// rigth top
set_output(1);
GSout = GSin[1];
gl_Position = gl_in[1].gl_Position; // FIXME is it useful
gl_Position.y = GSin[0].p.y;
GSout.p.y = GSin[0].p.y;
@ -243,7 +225,7 @@ void gs_main()
EmitVertex();
// rigth bottom
set_output(1);
GSout = GSin[1];
gl_Position = GSin[1].p; // FIXME is it useful
EmitVertex();
@ -254,13 +236,7 @@ void gs_main()
#endif
#ifdef FRAGMENT_SHADER
layout(location = 0) in PSin
{
vec4 p;
vec4 t;
vec4 tp;
vec4 c;
} PSin;
layout(location = 0) in vertex PSin;
// Same buffer but 2 colors for dual source blending
layout(location = 0, index = 0) out vec4 SV_Target0;
@ -401,7 +377,7 @@ vec4 sample_color(vec2 st, float q)
}
vec4 t;
if(PS_FMT <= FMT_16 && PS_WMS < 3 && PS_WMT < 3)
if((PS_FMT <= FMT_16) && (PS_WMS < 3) && (PS_WMT < 3))
{
t = sample_c(clampuv(st));
}
@ -603,6 +579,8 @@ vec4 ps_color()
{
// FIXME !!!!
//c.rgb *= c.rgb < 128./255;
bvec3 factor = bvec3(128.0f/255.0f, 128.0f/255.0f, 128.0f/255.0f);
c.rgb *= vec3(factor);
}
if(PS_CLR1 != 0) // needed for Cd * (As/Ad/F + 1) blending modes
@ -619,7 +597,6 @@ void ps_main()
{
vec4 c = ps_color();
// FIXME: I'm not sure about the value of others field
// output.c1 = c.a * 2; // used for alpha blending
SV_Target1 = vec4(c.a*2, c.a*2, c.a*2, c.a * 2);