gsdx-ogl: clean the blending management

Intially GSBlendStateOGL was an alias of the m_blendMapD3D9 array

The object was replaced by an index in the array. Save 2k of memory duplication.
And too much useless code.

v2: push/pop blending state in DATE stuff
v3: remove m_state which is useless now
This commit is contained in:
Gregory Hainaut 2015-07-31 20:28:54 +02:00
parent 717f0fcb4d
commit b7e16b5989
5 changed files with 51 additions and 183 deletions

View File

@ -59,7 +59,6 @@ GSDeviceOGL::GSDeviceOGL()
memset(&m_fxaa, 0, sizeof(m_fxaa));
memset(&m_shaderfx, 0, sizeof(m_shaderfx));
memset(&m_date, 0, sizeof(m_date));
memset(&m_state, 0, sizeof(m_state));
GLState::Clear();
// Reset the debug file
@ -90,7 +89,6 @@ GSDeviceOGL::~GSDeviceOGL()
for (size_t i = 0; i < countof(m_merge_obj.ps); i++)
m_shader->Delete(m_merge_obj.ps[i]);
delete (m_merge_obj.cb);
delete (m_merge_obj.bs);
// Clean m_interlace
for (size_t i = 0; i < countof(m_interlace.ps); i++)
@ -103,7 +101,6 @@ GSDeviceOGL::~GSDeviceOGL()
m_shader->Delete(m_convert.ps[i]);
delete m_convert.dss;
delete m_convert.dss_write;
delete m_convert.bs;
delete m_convert.cb;
// Clean m_fxaa
@ -116,7 +113,6 @@ GSDeviceOGL::~GSDeviceOGL()
// Clean m_date
delete m_date.dss;
delete m_date.bs;
// Clean shadeboost
delete m_shadeboost.cb;
@ -143,9 +139,6 @@ GSDeviceOGL::~GSDeviceOGL()
for (uint32 key = 0; key < countof(m_om_dss); key++) delete m_om_dss[key];
for (auto it = m_om_bs.begin(); it != m_om_bs.end(); it++) delete it->second;
m_om_bs.clear();
PboPool::Destroy();
// Must be done after the destruction of all shader/program objects
@ -255,10 +248,6 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
for(size_t i = 0; i < countof(m_convert.ps); i++)
m_convert.ps[i] = m_shader->Compile("convert.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, convert_glsl);
// Note the following object are initialized to 0 so disabled.
// Note: maybe enable blend with a factor of 1
// m_convert.dss, m_convert.bs
PSSamplerSelector point;
m_convert.pt = GetSamplerID(point);
@ -266,7 +255,6 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
bilinear.ltf = true;
m_convert.ln = GetSamplerID(bilinear);
m_convert.bs = new GSBlendStateOGL();
m_convert.dss = new GSDepthStencilOGL();
m_convert.dss_write = new GSDepthStencilOGL();
m_convert.dss_write->EnableDepth();
@ -280,10 +268,6 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
for(size_t i = 0; i < countof(m_merge_obj.ps); i++)
m_merge_obj.ps[i] = m_shader->Compile("merge.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, merge_glsl);
m_merge_obj.bs = new GSBlendStateOGL();
m_merge_obj.bs->EnableBlend();
m_merge_obj.bs->SetRGB(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// ****************************************************************
// interlace
// ****************************************************************
@ -327,8 +311,6 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
m_date.dss->EnableStencil();
m_date.dss->SetStencil(GL_ALWAYS, GL_REPLACE);
m_date.bs = new GSBlendStateOGL();
// ****************************************************************
// Use DX coordinate convention
// ****************************************************************
@ -502,13 +484,18 @@ void GSDeviceOGL::ClearRenderTarget_i(GSTexture* t, int32 c)
OMAttachRt(T);
// Blending is not supported when you render to an Integer texture
GLState::blend = false;
glDisable(GL_BLEND);
if (GLState::blend) {
glDisable(GL_BLEND);
}
gl_ClearBufferiv(GL_COLOR, 0, col);
OMSetColorMaskState(OMColorMaskSelector(old_color_mask));
if (GLState::blend) {
glEnable(GL_BLEND);
}
GL_POP();
}
@ -937,10 +924,10 @@ void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture
void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, GLuint ps, bool linear)
{
StretchRect(sTex, sRect, dTex, dRect, ps, m_convert.bs, linear);
StretchRect(sTex, sRect, dTex, dRect, ps, m_NO_BLEND, linear);
}
void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, GLuint ps, GSBlendStateOGL* bs, bool linear)
void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, GLuint ps, int bs, bool linear)
{
if(!sTex || !dTex)
{
@ -981,11 +968,12 @@ void GSDeviceOGL::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture
else
OMSetDepthStencilState(m_convert.dss, 0);
OMSetBlendState(bs, 0);
if (draw_in_depth)
OMSetRenderTargets(NULL, dTex);
else
OMSetRenderTargets(dTex, NULL);
OMSetBlendState(bs);
OMSetColorMaskState();
// ************************************
@ -1071,7 +1059,7 @@ void GSDeviceOGL::DoMerge(GSTexture* sTex[2], GSVector4* sRect, GSTexture* dTex,
{
m_merge_obj.cb->upload(&c.v);
StretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge_obj.ps[mmod ? 1 : 0], m_merge_obj.bs);
StretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge_obj.ps[mmod ? 1 : 0], m_MERGE_BLEND);
}
GL_POP();
@ -1223,7 +1211,9 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
// om
OMSetDepthStencilState(m_date.dss, 1);
OMSetBlendState(m_date.bs, 0);
if (GLState::blend) {
glDisable(GL_BLEND);
}
// normally ok without any RT if GL_ARB_framebuffer_no_attachments is supported (minus driver bug)
OMSetRenderTargets(NULL, ds, &GLState::scissor);
OMSetColorMaskState(); // TODO: likely useless
@ -1246,6 +1236,10 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
DrawPrimitive();
if (GLState::blend) {
glEnable(GL_BLEND);
}
EndScene();
GL_POP();
@ -1343,13 +1337,8 @@ void GSDeviceOGL::OMSetWriteBuffer(GLenum buffer)
void GSDeviceOGL::OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref)
{
// State is checkd inside the object but worst case is 11 comparaisons !
if (m_state.dss != dss) {
m_state.dss = dss;
dss->SetupDepth();
dss->SetupStencil();
}
dss->SetupDepth();
dss->SetupStencil();
}
void GSDeviceOGL::OMSetColorMaskState(OMColorMaskSelector sel)
@ -1403,24 +1392,6 @@ void GSDeviceOGL::OMSetBlendState(int blend_index, float blend_factor, bool is_b
}
}
void GSDeviceOGL::OMSetBlendState(GSBlendStateOGL* bs, float bf)
{
// SW date might change the enable state without updating the object
// Time to remove this micro-optimization
#if 0
// State is checkd inside the object but worst case is 8 comparaisons
if (m_state.bs != bs || m_state.bf != bf)
{
m_state.bs = bs;
m_state.bf = bf;
bs->SetupBlend(bf);
}
#else
bs->SetupBlend(bf);
#endif
}
void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor)
{
GSTextureOGL* RT = static_cast<GSTextureOGL*>(rt);
@ -1573,8 +1544,10 @@ void GSDeviceOGL::DebugOutputToFile(GLenum gl_source, GLenum gl_type, GLuint id,
#define D3DBLEND_SRCALPHA GL_SRC1_ALPHA
#define D3DBLEND_INVSRCALPHA GL_ONE_MINUS_SRC1_ALPHA
const int GSDeviceOGL::m_NO_BLEND = 0;
const int GSDeviceOGL::m_MERGE_BLEND = 3*3*3*3;
const GSDeviceOGL::D3D9Blend GSDeviceOGL::m_blendMapD3D9[3*3*3*3] =
const GSDeviceOGL::D3D9Blend GSDeviceOGL::m_blendMapD3D9[3*3*3*3 + 1] =
{
{ BLEND_NO_BAR , D3DBLENDOP_ADD , D3DBLEND_ONE , D3DBLEND_ZERO} , // 0000: (Cs - Cs)*As + Cs ==> Cs
{ 0 , D3DBLENDOP_ADD , D3DBLEND_ZERO , D3DBLEND_ONE} , // 0001: (Cs - Cs)*As + Cd ==> Cd
@ -1657,4 +1630,5 @@ const GSDeviceOGL::D3D9Blend GSDeviceOGL::m_blendMapD3D9[3*3*3*3] =
{ BLEND_NO_BAR , D3DBLENDOP_ADD , D3DBLEND_ONE , D3DBLEND_ZERO} , // 2220: (0 - 0)*F + Cs ==> Cs
{ 0 , D3DBLENDOP_ADD , D3DBLEND_ZERO , D3DBLEND_ONE} , // 2221: (0 - 0)*F + Cd ==> Cd
{ BLEND_NO_BAR , D3DBLENDOP_ADD , D3DBLEND_ZERO , D3DBLEND_ZERO} , // 2222: (0 - 0)*F + 0 ==> 0
{ 0 , D3DBLENDOP_ADD , GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA} , // extra for merge operation
};

View File

@ -40,75 +40,6 @@ extern uint64 g_real_texture_upload_byte;
extern uint64 g_vertex_upload_byte;
#endif
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;
GLenum m_equation_RGB;
GLenum m_func_sRGB;
GLenum m_func_dRGB;
bool m_constant_factor;
public:
GSBlendStateOGL() : m_enable(false)
, m_equation_RGB(0)
, m_func_sRGB(0)
, m_func_dRGB(0)
, m_constant_factor(false)
{}
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)) m_constant_factor = true;
}
void EnableBlend() { m_enable = true;}
bool IsConstant(GLenum factor) { return ((factor == GL_CONSTANT_COLOR) || (factor == GL_ONE_MINUS_CONSTANT_COLOR)); }
bool HasConstantFactor() { return m_constant_factor; }
void SetupBlend(float factor)
{
if (GLState::blend != m_enable) {
GLState::blend = m_enable;
if (m_enable)
glEnable(GL_BLEND);
else
glDisable(GL_BLEND);
}
if (m_enable) {
if (HasConstantFactor()) {
if (GLState::bf != factor) {
GLState::bf = factor;
gl_BlendColor(factor, factor, factor, 0);
}
}
if (GLState::eq_RGB != m_equation_RGB) {
GLState::eq_RGB = m_equation_RGB;
if (gl_BlendEquationSeparateiARB)
gl_BlendEquationSeparateiARB(0, m_equation_RGB, GL_FUNC_ADD);
else
gl_BlendEquationSeparate(m_equation_RGB, GL_FUNC_ADD);
}
if (GLState::f_sRGB != m_func_sRGB || GLState::f_dRGB != m_func_dRGB) {
GLState::f_sRGB = m_func_sRGB;
GLState::f_dRGB = m_func_dRGB;
if (gl_BlendFuncSeparateiARB)
gl_BlendFuncSeparateiARB(0, m_func_sRGB, m_func_dRGB, GL_ONE, GL_ZERO);
else
gl_BlendFuncSeparate(m_func_sRGB, m_func_dRGB, GL_ONE, GL_ZERO);
}
}
}
};
class GSDepthStencilOGL {
bool m_depth_enable;
GLenum m_depth_func;
@ -484,7 +415,9 @@ class GSDeviceOGL : public GSDevice
};
struct D3D9Blend {int bogus, op, src, dst;};
static const D3D9Blend m_blendMapD3D9[3*3*3*3];
static const D3D9Blend m_blendMapD3D9[3*3*3*3 + 1];
static const int m_NO_BLEND;
static const int m_MERGE_BLEND;
static int s_n;
@ -505,7 +438,6 @@ class GSDeviceOGL : public GSDevice
struct {
GLuint ps[2]; // program object
GSUniformBufferOGL* cb; // uniform buffer object
GSBlendStateOGL* bs;
} m_merge_obj;
struct {
@ -520,7 +452,6 @@ class GSDeviceOGL : public GSDevice
GLuint pt; // sampler object
GSDepthStencilOGL* dss;
GSDepthStencilOGL* dss_write;
GSBlendStateOGL* bs;
GSUniformBufferOGL* cb;
} m_convert;
@ -536,7 +467,6 @@ class GSDeviceOGL : public GSDevice
struct {
GSDepthStencilOGL* dss;
GSBlendStateOGL* bs;
GSTexture* t;
} m_date;
@ -545,18 +475,11 @@ class GSDeviceOGL : public GSDevice
GSUniformBufferOGL *cb;
} m_shadeboost;
struct {
GSDepthStencilOGL* dss;
GSBlendStateOGL* bs;
float bf; // blend factor
} m_state;
GLuint m_vs[1<<5];
GLuint m_gs[1<<2];
GLuint m_ps_ss[1<<3];
GSDepthStencilOGL* m_om_dss[1<<4];
hash_map<uint64, GLuint > m_ps;
hash_map<uint32, GSBlendStateOGL* > m_om_bs;
GLuint m_apitrace;
GLuint m_palette_ss;
@ -624,7 +547,7 @@ class GSDeviceOGL : public GSDevice
void CopyRectConv(GSTexture* sTex, GSTexture* dTex, const GSVector4i& r, bool at_origin);
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, int shader = 0, bool linear = true);
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, GLuint ps, bool linear = true);
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, GLuint ps, GSBlendStateOGL* bs, bool linear = true);
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, GLuint ps, int bs, bool linear = true);
void SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vertices, bool datm);
@ -639,7 +562,6 @@ class GSDeviceOGL : public GSDevice
void PSSetSamplerState(GLuint ss);
void OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref);
void OMSetBlendState(GSBlendStateOGL* bs, float bf);
void OMSetBlendState(int blend_index = 0, float blend_factor = 0.0f, bool is_blend_constant = false);
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor = NULL);
void OMSetWriteBuffer(GLenum buffer = GL_COLOR_ATTACHMENT0);
@ -653,7 +575,6 @@ class GSDeviceOGL : public GSDevice
GLuint CreateSampler(bool bilinear, bool tau, bool tav);
GLuint CreateSampler(PSSamplerSelector sel);
GSDepthStencilOGL* CreateDepthStencil(OMDepthStencilSelector dssel);
GSBlendStateOGL* CreateBlend(OMBlendSelector bsel, float afix);
void SelfShaderTest();
@ -664,7 +585,7 @@ class GSDeviceOGL : public GSDevice
void SetupPS(PSSelector sel);
void SetupCB(const VSConstantBuffer* vs_cb, const PSConstantBuffer* ps_cb);
void SetupSampler(PSSamplerSelector ssel);
void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, float afix);
void SetupOM(OMDepthStencilSelector dssel);
GLuint GetSamplerID(PSSamplerSelector ssel);
GLuint GetPaletteSamplerID();

View File

@ -301,10 +301,13 @@ bool GSRendererOGL::EmulateTextureShuffleAndFbmask(GSDeviceOGL::PSSelector& ps_s
return require_barrier;
}
bool GSRendererOGL::EmulateBlending(GSDeviceOGL::PSSelector& ps_sel, GSDeviceOGL::OMBlendSelector& om_bsel, GSDeviceOGL::PSConstantBuffer& ps_cb, float afix, bool DATE_GL42)
bool GSRendererOGL::EmulateBlending(GSDeviceOGL::PSSelector& ps_sel, GSDeviceOGL::PSConstantBuffer& ps_cb, bool DATE_GL42)
{
const GIFRegALPHA& ALPHA = m_context->ALPHA;
bool require_barrier = false;
bool require_barrier = false;
GSDeviceOGL* dev = (GSDeviceOGL*)m_dev;
float afix = (float)m_context->ALPHA.FIX / 0x80;
GSDeviceOGL::OMBlendSelector om_bsel;
om_bsel.abe = PRIM->ABE || PRIM->AA1 && m_vt.m_primclass == GS_LINE_CLASS;
@ -331,8 +334,10 @@ bool GSRendererOGL::EmulateBlending(GSDeviceOGL::PSSelector& ps_sel, GSDeviceOGL
}
// No blending so early exit
if (!om_bsel.abe)
if (!om_bsel.abe) {
dev->OMSetBlendState();
return require_barrier;
}
// Compute the blending equation to detect special case
int blend_sel = ((om_bsel.a * 3 + om_bsel.b) * 3 + om_bsel.c) * 3 + om_bsel.d;
@ -402,12 +407,13 @@ bool GSRendererOGL::EmulateBlending(GSDeviceOGL::PSSelector& ps_sel, GSDeviceOGL
if (accumulation_blend) {
// Keep HW blending to do the addition
dev->OMSetBlendState(blend_sel);
om_bsel.abe = 1;
// Remove the addition from the SW blending
ps_sel.blend_d = 2;
} else {
// Disable HW blending
om_bsel.abe = 0;
dev->OMSetBlendState();
}
// Require the fix alpha vlaue
@ -421,8 +427,10 @@ bool GSRendererOGL::EmulateBlending(GSDeviceOGL::PSSelector& ps_sel, GSDeviceOGL
ps_sel.clr1 = om_bsel.IsCLR1();
if (ps_sel.dfmt == 1 && ALPHA.C == 1) {
// 24 bits doesn't have an alpha channel so use 1.0f fix factor as equivalent
om_bsel.c = 2;
afix = 1.0f;
int hacked_blend_sel = blend_sel + 3; // +3 <=> +1 on C
dev->OMSetBlendState(hacked_blend_sel, 1.0f, true);
} else {
dev->OMSetBlendState(blend_sel, afix, (ALPHA.C == 2));
}
}
@ -581,7 +589,6 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
GSDeviceOGL::PSConstantBuffer ps_cb;
GSDeviceOGL::PSSamplerSelector ps_ssel;
GSDeviceOGL::OMBlendSelector om_bsel;
GSDeviceOGL::OMColorMaskSelector om_csel;
GSDeviceOGL::OMDepthStencilSelector om_dssel;
@ -624,10 +631,10 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
// Blend
float afix = (float)m_context->ALPHA.FIX / 0x80;
if (!IsOpaque() && rt) {
require_barrier |= EmulateBlending(ps_sel, om_bsel, ps_cb, afix, DATE_GL42);
require_barrier |= EmulateBlending(ps_sel, ps_cb, DATE_GL42);
} else {
dev->OMSetBlendState(); // No blending please
}
if (ps_sel.dfmt == 1) {
@ -927,7 +934,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
GL_POP();
dev->OMSetColorMaskState(om_csel);
dev->SetupOM(om_dssel, om_bsel, afix);
dev->SetupOM(om_dssel);
dev->SetupCB(&vs_cb, &ps_cb);
@ -1016,7 +1023,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
om_csel.wa = a;
dev->OMSetColorMaskState(om_csel);
dev->SetupOM(om_dssel, om_bsel, afix);
dev->SetupOM(om_dssel);
SendDraw(require_barrier);
}

View File

@ -60,7 +60,7 @@ class GSRendererOGL : public GSRendererHW
void EmulateGS();
void SetupIA();
bool EmulateTextureShuffleAndFbmask(GSDeviceOGL::PSSelector& ps_sel, GSDeviceOGL::OMColorMaskSelector& om_csel, GSDeviceOGL::PSConstantBuffer& ps_cb);
bool EmulateBlending(GSDeviceOGL::PSSelector& ps_sel, GSDeviceOGL::OMBlendSelector& om_bsel, GSDeviceOGL::PSConstantBuffer& ps_cb, float afix, bool DATE_GL42);
bool EmulateBlending(GSDeviceOGL::PSSelector& ps_sel, GSDeviceOGL::PSConstantBuffer& ps_cb, bool DATE_GL42);
public:
GSRendererOGL();

View File

@ -97,21 +97,6 @@ GSDepthStencilOGL* GSDeviceOGL::CreateDepthStencil(OMDepthStencilSelector dssel)
return dss;
}
GSBlendStateOGL* GSDeviceOGL::CreateBlend(OMBlendSelector bsel, float afix)
{
GSBlendStateOGL* bs = new GSBlendStateOGL();
if(bsel.abe)
{
int i = ((bsel.a * 3 + bsel.b) * 3 + bsel.c) * 3 + bsel.d;
bs->SetRGB(m_blendMapD3D9[i].op, m_blendMapD3D9[i].src, m_blendMapD3D9[i].dst);
bs->EnableBlend();
}
return bs;
}
void GSDeviceOGL::SetupCB(const VSConstantBuffer* vs_cb, const PSConstantBuffer* ps_cb)
{
GL_PUSH("UBO");
@ -171,28 +156,9 @@ GLuint GSDeviceOGL::GetPaletteSamplerID()
return m_palette_ss;
}
void GSDeviceOGL::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, float afix)
void GSDeviceOGL::SetupOM(OMDepthStencilSelector dssel)
{
GSDepthStencilOGL* dss = m_om_dss[dssel];
OMSetDepthStencilState(dss, 1);
// *************************************************************
// Static
// *************************************************************
auto j = m_om_bs.find(bsel);
GSBlendStateOGL* bs;
if(j == m_om_bs.end())
{
bs = CreateBlend(bsel, afix);
m_om_bs[bsel] = bs;
} else {
bs = j->second;
}
// *************************************************************
// Dynamic
// *************************************************************
OMSetBlendState(bs, afix);
}