1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
/*
* Copyright (C) 2011-2011 Gregory hainaut
* Copyright (C) 2007-2009 Gabest
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
#include "stdafx.h"
#include "GSDeviceOGL.h"
#include "GSTables.h"
static const uint32 g_vs_cb_index = 20;
static const uint32 g_ps_cb_index = 21;
static const uint32 g_gs_cb_index = 22;
void GSDeviceOGL::CreateTextureFX()
{
m_vs_cb = new GSUniformBufferOGL(g_vs_cb_index, sizeof(VSConstantBuffer));
m_ps_cb = new GSUniformBufferOGL(g_ps_cb_index, sizeof(PSConstantBuffer));
// warning 1 sampler by image unit. So you cannot reuse m_ps_ss...
m_palette_ss = CreateSampler(false, false, false);
glBindSampler(1, m_palette_ss);
// Pre compile all Geometry & Vertex Shader
// It might cost a seconds at startup but it would reduce benchmark pollution
GL_PUSH("Compile GS");
for (uint32 key = 0; key < countof(m_gs); key++) {
GSSelector sel(key);
if (sel.point == sel.sprite)
m_gs[key] = 0;
else
m_gs[key] = CompileGS(GSSelector(key));
}
GL_POP();
GL_PUSH("Compile VS");
for (uint32 key = 0; key < countof(m_vs); key++) {
VSSelector sel(key);
m_vs[key] = CompileVS(sel, !GLLoader::found_GL_ARB_clip_control);
}
GL_POP();
// Enable all bits for stencil operations. Technically 1 bit is
// enough but buffer is polluted with noise. Clear will be limited
// to the mask.
glStencilMask(0xFF);
for (uint32 key = 0; key < countof(m_om_dss); key++) {
m_om_dss[key] = CreateDepthStencil(OMDepthStencilSelector(key));
}
// Help to debug FS in apitrace
m_apitrace = CompilePS(PSSelector());
}
GSDepthStencilOGL* GSDeviceOGL::CreateDepthStencil(OMDepthStencilSelector dssel)
{
GSDepthStencilOGL* dss = new GSDepthStencilOGL();
if (dssel.date)
{
dss->EnableStencil();
dss->SetStencil(GL_EQUAL, GL_KEEP);
}
if(dssel.ztst != ZTST_ALWAYS || dssel.zwe)
{
static const GLenum ztst[] =
{
GL_NEVER,
GL_ALWAYS,
GL_GEQUAL,
GL_GREATER
};
dss->EnableDepth();
dss->SetDepth(ztst[dssel.ztst], dssel.zwe);
}
return dss;
}
void GSDeviceOGL::SetupCB(const VSConstantBuffer* vs_cb, const PSConstantBuffer* ps_cb)
{
GL_PUSH("UBO");
if(m_vs_cb_cache.Update(vs_cb)) {
m_vs_cb->upload(vs_cb);
}
if(m_ps_cb_cache.Update(ps_cb)) {
m_ps_cb->upload(ps_cb);
}
GL_POP();
}
void GSDeviceOGL::SetupVS(VSSelector sel)
{
m_shader->VS(m_vs[sel]);
}
void GSDeviceOGL::SetupGS(GSSelector sel)
{
m_shader->GS(m_gs[sel]);
}
void GSDeviceOGL::SetupPS(PSSelector sel)
{
// *************************************************************
// Static
// *************************************************************
GLuint ps;
auto i = m_ps.find(sel);
if (i == m_ps.end()) {
ps = CompilePS(sel);
m_ps[sel] = ps;
} else {
ps = i->second;
}
// *************************************************************
// Dynamic
// *************************************************************
m_shader->PS(ps);
}
void GSDeviceOGL::SetupSampler(PSSamplerSelector ssel)
{
PSSetSamplerState(m_ps_ss[ssel]);
}
GLuint GSDeviceOGL::GetSamplerID(PSSamplerSelector ssel)
{
return m_ps_ss[ssel];
}
GLuint GSDeviceOGL::GetPaletteSamplerID()
{
return m_palette_ss;
}
void GSDeviceOGL::SetupOM(OMDepthStencilSelector dssel)
{
OMSetDepthStencilState(m_om_dss[dssel]);
}
|