diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp index f4d2b731e..b3537619c 100644 --- a/plugins/GSdx/GSDeviceOGL.cpp +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -54,8 +54,8 @@ //#define LOUD_DEBUGGING #define SHADER_DEBUG -//#define DUMP_START (70) -//#define DUMP_LENGTH (130) +#define DUMP_START (70) +#define DUMP_LENGTH (130) //#define DUMP_ONLY_FRAME (112) #ifdef DUMP_START @@ -302,13 +302,8 @@ bool GSDeviceOGL::Create(GSWnd* wnd) 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; - m_merge.bs->m_func_sRGB = GL_SRC_ALPHA; - m_merge.bs->m_func_dRGB = GL_ONE_MINUS_SRC_ALPHA; - m_merge.bs->m_func_sALPHA = GL_ONE; - m_merge.bs->m_func_dALPHA = GL_ZERO; + m_merge.bs->EnableBlend(); + m_merge.bs->SetRGB(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // **************************************************************** // interlace @@ -352,9 +347,8 @@ bool GSDeviceOGL::Create(GSWnd* wnd) // **************************************************************** m_date.dss = new GSDepthStencilOGL(); - m_date.dss->m_stencil_enable = true; - m_date.dss->m_stencil_func = GL_ALWAYS; - m_date.dss->m_stencil_spass_dpass_op = GL_REPLACE; + m_date.dss->EnableStencil(); + m_date.dss->SetStencil(GL_ALWAYS, GL_REPLACE); //memset(&dsd, 0, sizeof(dsd)); //dsd.DepthEnable = false; @@ -541,11 +535,10 @@ void GSDeviceOGL::DrawPrimitive() case GL_POINTS: topo = "point"; break; default: topo = "!!!!"; } - fprintf(stderr, "Draw %d (Frame %d), %d elem of %s\n", g_draw_count, g_frame_count, /*m_state.vb_state->count*/ 0, topo.c_str() ); + fprintf(stderr, "Draw %d (Frame %d), %d elem of %s\n", g_draw_count, g_frame_count, m_state.vb_state->get_count(), topo.c_str() ); fprintf(stderr, "vs: %d ; gs: %d ; ps: %d\n", m_state.vs, m_state.gs, m_state.ps); - fprintf(stderr, "Blend: %d, Depth: %d, Stencil: %d \n",m_state.bs->m_enable, m_state.dss->m_depth_enable, m_state.dss->m_stencil_enable); m_state.bs->debug(); - m_state.dss->debug_depth(); + m_state.dss->debug(); } #endif @@ -1095,50 +1088,28 @@ void GSDeviceOGL::OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref) { uint ref = sref; - if(m_state.dss != dss || m_state.sref != sref) - { + if(m_state.dss != dss) { m_state.dss = dss; m_state.sref = sref; - if (dss->m_depth_enable) { - glEnable(GL_DEPTH_TEST); - glDepthFunc(dss->m_depth_func); - glDepthMask(dss->m_depth_mask); - } else - glDisable(GL_DEPTH_TEST); + dss->SetupDepth(); + dss->SetupStencil(sref); - if (dss->m_stencil_enable) { - glEnable(GL_STENCIL_TEST); - glStencilFunc(dss->m_stencil_func, ref, dss->m_stencil_mask); - glStencilOp(dss->m_stencil_sfail_op, dss->m_stencil_spass_dfail_op, dss->m_stencil_spass_dpass_op); - } else - glDisable(GL_STENCIL_TEST); + } else if (m_state.sref != sref) { + m_state.sref = sref; + + dss->SetupStencil(sref); } } void GSDeviceOGL::OMSetBlendState(GSBlendStateOGL* bs, float bf) { - // DX:Blend factor D3D11_BLEND_BLEND_FACTOR | D3D11_BLEND_INV_BLEND_FACTOR - // OPENGL: GL_CONSTANT_COLOR | GL_ONE_MINUS_CONSTANT_COLOR - // Note factor must be set before by glBlendColor - if(m_state.bs != bs || m_state.bf != bf) + if( m_state.bs != bs || (m_state.bf != bf && bs->HasConstantFactor()) ) { m_state.bs = bs; m_state.bf = bf; - glColorMask(bs->m_r_msk, bs->m_g_msk, bs->m_b_msk, bs->m_a_msk); - - if (bs->m_enable) { - glEnable(GL_BLEND); - // FIXME: double check when blend stuff is complete - if (bs->m_func_sRGB == GL_CONSTANT_COLOR || bs->m_func_sRGB == GL_ONE_MINUS_CONSTANT_COLOR - || bs->m_func_dRGB == GL_CONSTANT_COLOR || bs->m_func_dRGB == GL_ONE_MINUS_CONSTANT_COLOR) - glBlendColor(bf, bf, bf, 0); - - glBlendEquationSeparate(bs->m_equation_RGB, bs->m_equation_ALPHA); - glBlendFuncSeparate(bs->m_func_sRGB, bs->m_func_dRGB, bs->m_func_sALPHA, bs->m_func_dALPHA); - } else - glDisable(GL_BLEND); + bs->SetupBlend(bf); } } diff --git a/plugins/GSdx/GSDeviceOGL.h b/plugins/GSdx/GSDeviceOGL.h index dcc3de9a8..cab27d0ce 100644 --- a/plugins/GSdx/GSDeviceOGL.h +++ b/plugins/GSdx/GSDeviceOGL.h @@ -26,7 +26,7 @@ #include "GSTextureOGL.h" #include "GSdx.h" -struct GSBlendStateOGL { +class GSBlendStateOGL { // Note: You can also select the index of the draw buffer for which to set the blend setting // We will keep basic the first try bool m_enable; @@ -40,6 +40,9 @@ struct GSBlendStateOGL { bool m_b_msk; bool m_g_msk; bool m_a_msk; + bool constant_factor; + +public: GSBlendStateOGL() : m_enable(false) , m_equation_RGB(0) @@ -52,18 +55,89 @@ struct GSBlendStateOGL { , m_b_msk(GL_TRUE) , m_g_msk(GL_TRUE) , m_a_msk(GL_TRUE) + , constant_factor(true) {} + void SetRGB(GLenum op, GLenum src, GLenum dst) + { + m_equation_RGB = op; + m_func_sRGB = src; + m_func_dRGB = dst; + if (IsConstant(src) || IsConstant(dst)) constant_factor = true; + } + + void SetALPHA(GLenum op, GLenum src, GLenum dst) + { + m_equation_ALPHA = op; + m_func_sALPHA = src; + m_func_dALPHA = dst; + } + + void SetMask(bool r, bool g, bool b, bool a) { m_r_msk = r; m_g_msk = g; m_b_msk = b; m_a_msk = a; } + + void RevertOp() + { + if(m_equation_RGB == GL_FUNC_ADD) + m_equation_RGB = GL_FUNC_REVERSE_SUBTRACT; + else if(m_equation_RGB == GL_FUNC_REVERSE_SUBTRACT) + m_equation_RGB = GL_FUNC_ADD; + } + + void EnableBlend() { m_enable = true;} + + bool IsConstant(GLenum factor) { return ((factor == GL_CONSTANT_COLOR) || (factor == GL_ONE_MINUS_CONSTANT_COLOR)); } + + bool HasConstantFactor() { return constant_factor; } + + void SetupColorMask() + { + glColorMask(m_r_msk, m_g_msk, m_b_msk, m_a_msk); + } + + void SetupBlend(float factor) + { + SetupColorMask(); + + if (m_enable) { + glEnable(GL_BLEND); + if (HasConstantFactor()) glBlendColor(factor, factor, factor, 0); + + glBlendEquationSeparate(m_equation_RGB, m_equation_ALPHA); + glBlendFuncSeparate(m_func_sRGB, m_func_dRGB, m_func_sALPHA, m_func_dALPHA); + } else { + glDisable(GL_BLEND); + } + } + + char* NameOfParam(GLenum p) + { + switch (p) { + case GL_FUNC_ADD: return "ADD"; + case GL_FUNC_SUBTRACT: return "SUB"; + case GL_FUNC_REVERSE_SUBTRACT: return "REV SUB"; + case GL_ONE: return "ONE"; + case GL_ZERO: return "ZERO"; + case GL_SRC1_ALPHA: return "SRC1 ALPHA"; + case GL_ONE_MINUS_DST_ALPHA: return "1 - DST ALPHA"; + case GL_DST_ALPHA: return "DST ALPHA"; + case GL_DST_COLOR: return "DST COLOR"; + case GL_ONE_MINUS_SRC1_ALPHA: return "1 - SRC1 ALPHA"; + case GL_CONSTANT_COLOR: return "CST"; + case GL_ONE_MINUS_CONSTANT_COLOR: return "1 - CST"; + default: return "UKN"; + } + return "UKN"; + } + void debug() { if (!m_enable) return; - fprintf(stderr,"Blend RGB: %x src:%x dst:%x\n", m_equation_RGB, m_func_sRGB, m_func_dRGB); - fprintf(stderr,"Blend ALPHA: %x src:%x dst:%x\n", m_equation_ALPHA, m_func_sALPHA, m_func_dALPHA); + fprintf(stderr,"Blend op: %s; src:%s; dst:%s\n", NameOfParam(m_equation_RGB), NameOfParam(m_func_sRGB), NameOfParam(m_func_dRGB)); fprintf(stderr,"Mask. R:%d B:%d G:%d A:%d\n", m_r_msk, m_b_msk, m_g_msk, m_a_msk); } }; -struct GSDepthStencilOGL { +class GSDepthStencilOGL { bool m_depth_enable; GLenum m_depth_func; GLboolean m_depth_mask; @@ -76,6 +150,23 @@ struct GSDepthStencilOGL { GLuint m_stencil_spass_dfail_op; GLuint m_stencil_spass_dpass_op; + char* NameOfParam(GLenum p) + { + switch(p) { + case GL_NEVER: return "NEVER"; + case GL_ALWAYS: return "ALWAYS"; + case GL_GEQUAL: return "GEQUAL"; + case GL_GREATER: return "GREATER"; + case GL_KEEP: return "KEEP"; + case GL_EQUAL: return "EQUAL"; + case GL_REPLACE: return "REPLACE"; + default: return "UKN"; + } + return "UKN"; + } + +public: + GSDepthStencilOGL() : m_depth_enable(false) , m_depth_func(0) , m_depth_mask(0) @@ -88,10 +179,45 @@ struct GSDepthStencilOGL { , m_stencil_spass_dpass_op(GL_KEEP) {} + void EnableDepth() { m_depth_enable = true; } + void EnableStencil() { m_stencil_enable = true; } + + void SetDepth(GLenum func, GLboolean mask) { m_depth_func = func; m_depth_mask = mask; } + void SetStencil(GLuint func, GLuint pass) { m_stencil_func = func; m_stencil_spass_dpass_op = pass; } + + void SetupDepth() + { + if (m_depth_enable) { + glEnable(GL_DEPTH_TEST); + glDepthFunc(m_depth_func); + glDepthMask(m_depth_mask); + } else + glDisable(GL_DEPTH_TEST); + } + + void SetupStencil(uint8 sref) + { + uint ref = sref; + if (m_stencil_enable) { + glEnable(GL_STENCIL_TEST); + glStencilFunc(m_stencil_func, ref, m_stencil_mask); + glStencilOp(m_stencil_sfail_op, m_stencil_spass_dfail_op, m_stencil_spass_dpass_op); + } else + glDisable(GL_STENCIL_TEST); + } + + void debug() { debug_depth(); debug_stencil(); } + void debug_depth() { if (!m_depth_enable) return; - fprintf(stderr, "Depth %x, %x\n", m_depth_func, m_depth_mask); + fprintf(stderr, "Depth %s. Mask %x\n", NameOfParam(m_depth_func), m_depth_mask); + } + + void debug_stencil() + { + if (!m_stencil_enable) return; + fprintf(stderr, "Stencil %s. Both pass op %s\n", NameOfParam(m_stencil_func), NameOfParam(m_stencil_spass_dpass_op)); } }; @@ -244,6 +370,8 @@ public: m_count = 0; } + uint32 get_count() { return m_count; } + ~GSVertexBufferStateOGL() { glDeleteBuffers(1, &m_vb); diff --git a/plugins/GSdx/GSTextureFXOGL.cpp b/plugins/GSdx/GSTextureFXOGL.cpp index 642cef238..0e61c2b7b 100644 --- a/plugins/GSdx/GSTextureFXOGL.cpp +++ b/plugins/GSdx/GSTextureFXOGL.cpp @@ -265,9 +265,8 @@ void GSDeviceOGL::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, ui if (dssel.date) { - dss->m_stencil_enable = true; - dss->m_stencil_func = GL_EQUAL; - dss->m_stencil_spass_dpass_op = GL_KEEP; + dss->EnableStencil(); + dss->SetStencil(GL_EQUAL, GL_KEEP); } if(dssel.ztst != ZTST_ALWAYS || dssel.zwe) @@ -279,9 +278,8 @@ void GSDeviceOGL::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, ui GL_GEQUAL, GL_GREATER }; - dss->m_depth_enable = true; - dss->m_depth_mask = dssel.zwe ? GL_TRUE : GL_FALSE; - dss->m_depth_func = ztst[dssel.ztst]; + dss->EnableDepth(); + dss->SetDepth(ztst[dssel.ztst], dssel.zwe); } m_om_dss[dssel] = dss; @@ -302,32 +300,19 @@ void GSDeviceOGL::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, ui { GSBlendStateOGL* bs = new GSBlendStateOGL(); - bs->m_enable = bsel.abe; - if(bsel.abe) { int i = ((bsel.a * 3 + bsel.b) * 3 + bsel.c) * 3 + bsel.d; - bs->m_equation_RGB = m_blendMapD3D9[i].op; - bs->m_func_sRGB = m_blendMapD3D9[i].src; - bs->m_func_dRGB = m_blendMapD3D9[i].dst; - // Not very good but I don't wanna write another 81 row table - if(bsel.negative) - { - if(bs->m_equation_RGB == GL_FUNC_ADD) - bs->m_equation_RGB = GL_FUNC_REVERSE_SUBTRACT; - else if(bs->m_equation_RGB == GL_FUNC_REVERSE_SUBTRACT) - bs->m_equation_RGB = GL_FUNC_ADD; - else - ; // god knows, best just not to mess with it for now - } + bs->EnableBlend(); + bs->SetRGB(m_blendMapD3D9[i].op, m_blendMapD3D9[i].src, m_blendMapD3D9[i].dst); if(m_blendMapD3D9[i].bogus == 1) { if (bsel.a == 0) - bs->m_func_sRGB = GL_ONE; + bs->SetRGB(m_blendMapD3D9[i].op, GL_ONE, m_blendMapD3D9[i].dst); else - bs->m_func_dRGB = GL_ONE; + bs->SetRGB(m_blendMapD3D9[i].op, m_blendMapD3D9[i].src, GL_ONE); const string afixstr = format("%d >> 7", afix); const char *col[3] = {"Cs", "Cd", "0"}; @@ -337,13 +322,11 @@ void GSDeviceOGL::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, ui fprintf(stderr, "Impossible blend for D3D: (%s - %s) * %s + %s\n", col[bsel.a], col[bsel.b], alpha[bsel.c], col[bsel.d]); } - + // Not very good but I don't wanna write another 81 row table + if(bsel.negative) bs->RevertOp(); } - bs->m_r_msk = bsel.wr; - bs->m_g_msk = bsel.wg; - bs->m_b_msk = bsel.wb; - bs->m_a_msk = bsel.wa; + bs->SetMask(bsel.wr, bsel.wg, bsel.wb, bsel.wa); m_om_bs[bsel] = bs; j = m_om_bs.find(bsel);