GL3: Optimize VP switching

--HG--
branch : opengl3
hg/feature/opengl3
kaetemi 11 years ago
parent 5d80073c0f
commit b25747b2ef

@ -387,7 +387,10 @@ bool CDriverGL3::setupDisplay()
// All User Light are disabled by Default // All User Light are disabled by Default
for (uint i = 0; i < MaxLight; ++i) for (uint i = 0; i < MaxLight; ++i)
{
_UserLightEnable[i] = false; _UserLightEnable[i] = false;
touchLightVP(i);
}
// init _DriverGLStates // init _DriverGLStates
_DriverGLStates.init(); _DriverGLStates.init();
@ -1029,8 +1032,8 @@ bool CDriverGL3::fogEnabled()
void CDriverGL3::enableFog(bool enable) void CDriverGL3::enableFog(bool enable)
{ {
H_AUTO_OGL(CDriverGL3_enableFog) H_AUTO_OGL(CDriverGL3_enableFog)
_DriverGLStates.enableFog(enable);
_FogEnabled = enable; _FogEnabled = enable;
enableFogVP(enable);
} }
// *************************************************************************** // ***************************************************************************

@ -398,7 +398,11 @@ public:
bool setupUniforms(); bool setupUniforms();
void setupUniforms(TProgram program); void setupUniforms(TProgram program);
CVertexProgram *generateBuiltinVertexProgram(); void generateBuiltinVertexProgram();
void enableFogVP(bool enable);
void enableLightingVP(bool enable);
void touchLightVP(int i);
void touchVertexFormatVP();
virtual void startSpecularBatch(); virtual void startSpecularBatch();
virtual void endSpecularBatch(); virtual void endSpecularBatch();
@ -1356,6 +1360,8 @@ private:
CPixelProgram *m_DriverPixelProgram; CPixelProgram *m_DriverPixelProgram;
std::set<CVPBuiltin> m_VPBuiltinCache; std::set<CVPBuiltin> m_VPBuiltinCache;
CVPBuiltin m_VPBuiltinCurrent;
bool m_VPBuiltinTouched;
// init EMBM settings (set each stage to modify the next) // init EMBM settings (set each stage to modify the next)
void initEMBM(); void initEMBM();

@ -74,8 +74,8 @@ void CDriverGL3::setLightInternal(uint8 num, const CLight& light)
// Copy the mode // Copy the mode
_LightMode[num] = mode; _LightMode[num] = mode;
_UserLight[num] = light; _UserLight[num] = light;
touchLightVP(num);
// Set the position // Set the position
if ((mode == CLight::DirectionalLight) || (mode == CLight::SpotLight)) if ((mode == CLight::DirectionalLight) || (mode == CLight::SpotLight))
@ -136,6 +136,7 @@ void CDriverGL3::enableLightInternal(uint8 num, bool enable)
{ {
// _DriverGLStates.enableLight(num, enable); // FIXME GL3 VERTEX PROGRAM // _DriverGLStates.enableLight(num, enable); // FIXME GL3 VERTEX PROGRAM
_UserLightEnable[num] = enable; _UserLightEnable[num] = enable;
touchLightVP(num);
} }
} }
@ -201,9 +202,10 @@ void CDriverGL3::setupLightMapDynamicLighting(bool enable)
void CDriverGL3::disableAllLights() void CDriverGL3::disableAllLights()
{ {
for (int i = 0; i < MaxLight; i++) for (int i = 0; i < MaxLight; ++i)
{ {
_UserLightEnable[i] = false; _UserLightEnable[i] = false;
touchLightVP(i);
} }
} }

@ -437,7 +437,7 @@ bool CDriverGL3::setupMaterial(CMaterial& mat)
// Light Part. // Light Part.
_DriverGLStates.enableLighting(mat.getFlags() & IDRV_MAT_LIGHTING); enableLightingVP(mat.getFlags() & IDRV_MAT_LIGHTING);
if ((mat.getFlags() & IDRV_MAT_LIGHTING) == 0) if ((mat.getFlags() & IDRV_MAT_LIGHTING) == 0)
disableAllLights(); disableAllLights();
@ -463,12 +463,12 @@ bool CDriverGL3::setupMaterial(CMaterial& mat)
// Disable fog if dest blend is ONE // Disable fog if dest blend is ONE
if (blend && (pShader->DstBlend == GL_ONE)) if (blend && (pShader->DstBlend == GL_ONE))
{ {
_DriverGLStates.enableFog(false); enableFogVP(false);
} }
else else
{ {
// Restaure fog state to its current value // Restaure fog state to its current value
_DriverGLStates.enableFog(_FogEnabled); enableFogVP(_FogEnabled);
} }
@ -781,7 +781,7 @@ sint CDriverGL3::beginLightMapMultiPass ()
computeLightMapInfos (mat); computeLightMapInfos (mat);
// always enable lighting for lightmap (because of dynamic light) // always enable lighting for lightmap (because of dynamic light)
_DriverGLStates.enableLighting(true); enableLightingVP(true);
// if the dynamic lightmap light has changed since the last render (should not happen), resetup // if the dynamic lightmap light has changed since the last render (should not happen), resetup
// normal way is that setupLightMapDynamicLighting() is called in setupMaterial() if shader different from prec // normal way is that setupLightMapDynamicLighting() is called in setupMaterial() if shader different from prec

@ -151,6 +151,9 @@ namespace NL3D
{ {
if (driver) nlassert(m_UserVertexProgram == NULL); if (driver) nlassert(m_UserVertexProgram == NULL);
if (m_DriverVertexProgram == program)
return true;
if (program == NULL) if (program == NULL)
{ {
nglUseProgramStages(ppoId, GL_VERTEX_SHADER_BIT, 0); nglUseProgramStages(ppoId, GL_VERTEX_SHADER_BIT, 0);
@ -249,6 +252,9 @@ namespace NL3D
{ {
if (driver) nlassert(m_UserPixelProgram == NULL); if (driver) nlassert(m_UserPixelProgram == NULL);
if (m_DriverPixelProgram == program)
return true;
if (program == NULL) if (program == NULL)
{ {
nglUseProgramStages(ppoId, GL_FRAGMENT_SHADER_BIT, 0); nglUseProgramStages(ppoId, GL_FRAGMENT_SHADER_BIT, 0);
@ -601,10 +607,15 @@ namespace NL3D
{ {
if (m_UserVertexProgram) return true; if (m_UserVertexProgram) return true;
CVertexProgram *vertexProgram = generateBuiltinVertexProgram(); touchVertexFormatVP(); // TODO
nlassert(vertexProgram);
if (m_VPBuiltinTouched)
{
generateBuiltinVertexProgram();
nlassert(m_VPBuiltinCurrent.VertexProgram);
}
if (!activeVertexProgram(vertexProgram, true)) if (!activeVertexProgram(m_VPBuiltinCurrent.VertexProgram, true))
return false; return false;
// GL3 TODO: Here we set the uniforms of the vertex program! // GL3 TODO: Here we set the uniforms of the vertex program!

@ -72,11 +72,9 @@ void CDriverGLStates3::forceDefaults(uint nbStages)
H_AUTO_OGL(CDriverGLStates3_forceDefaults); H_AUTO_OGL(CDriverGLStates3_forceDefaults);
// Enable / disable. // Enable / disable.
_CurFog = false;
_CurBlend = false; _CurBlend = false;
_CurCullFace = true; _CurCullFace = true;
_CurAlphaTest = false; _CurAlphaTest = false;
_CurLighting = false;
_CurZWrite = true; _CurZWrite = true;
_CurStencilTest =false; _CurStencilTest =false;
@ -229,14 +227,6 @@ void CDriverGLStates3::enableAlphaTest(uint enable)
} }
} }
// ***************************************************************************
void CDriverGLStates3::enableLighting(uint enable)
{
H_AUTO_OGL(CDriverGLStates3_enableLighting)
_CurLighting = (enable != 0);
}
// *************************************************************************** // ***************************************************************************
void CDriverGLStates3::enableZWrite(uint enable) void CDriverGLStates3::enableZWrite(uint enable)
{ {
@ -583,21 +573,6 @@ void CDriverGLStates3::enableVertexAttribArrayARB(uint glIndex,bool enable)
} }
// ***************************************************************************
void CDriverGLStates3::enableFog(uint enable)
{
H_AUTO_OGL(CDriverGLStates3_enableFog)
// If different from current setup, update.
bool enabled= (enable!=0);
#ifndef NL3D_GLSTATE_DISABLE_CACHE
if (enabled != _CurFog)
#endif
{
// new state.
_CurFog= enabled;
}
}
// *************************************************************************** // ***************************************************************************
void CDriverGLStates3::forceBindARBVertexBuffer(uint objectID) void CDriverGLStates3::forceBindARBVertexBuffer(uint objectID)
{ {

@ -84,15 +84,10 @@ public:
/// \name enable if !0 /// \name enable if !0
// @{ // @{
void enableBlend(uint enable); void enableBlend(uint enable);
void enableFog(uint enable);
bool isFogEnabled() const { return _CurFog; }
void enableCullFace(uint enable); void enableCullFace(uint enable);
/// enable and set good AlphaFunc. /// enable and set good AlphaFunc.
void enableAlphaTest(uint enable); void enableAlphaTest(uint enable);
void enableZWrite(uint enable); void enableZWrite(uint enable);
// overall lighting enabled
void enableLighting(uint enable);
bool isLightingEnabled() const { return _CurLighting; }
/// enable/disable stencil test /// enable/disable stencil test
void enableStencilTest(bool enable); void enableStencilTest(bool enable);
bool isStencilTestEnabled() const { return _CurStencilTest; } bool isStencilTestEnabled() const { return _CurStencilTest; }
@ -165,10 +160,8 @@ public:
private: private:
bool _CurBlend; bool _CurBlend;
bool _CurFog;
bool _CurCullFace; bool _CurCullFace;
bool _CurAlphaTest; bool _CurAlphaTest;
bool _CurLighting;
bool _CurZWrite; bool _CurZWrite;
bool _CurStencilTest; bool _CurStencilTest;

@ -355,23 +355,17 @@ namespace
} }
} }
CVertexProgram *CDriverGL3::generateBuiltinVertexProgram() void CDriverGL3::generateBuiltinVertexProgram()
{ {
CVPBuiltin desc; std::set<CVPBuiltin>::iterator it = m_VPBuiltinCache.find(m_VPBuiltinCurrent);
desc.VertexFormat = _CurrentVertexBufferHard->VB->getVertexFormat();
desc.Fog = _DriverGLStates.isFogEnabled();
desc.Lighting = _DriverGLStates.isLightingEnabled();
if (desc.Lighting)
for (sint i = 0; i < MaxLight; ++i)
desc.LightMode[i] = _UserLightEnable[i] ? _LightMode[i] : -1;
desc.VertexColorLighted = false; // _DriverGLStates._VertexColorLighted;
std::set<CVPBuiltin>::iterator it = m_VPBuiltinCache.find(desc);
if (it != m_VPBuiltinCache.end()) if (it != m_VPBuiltinCache.end())
return it->VertexProgram; {
m_VPBuiltinCurrent.VertexProgram = it->VertexProgram;
return;
}
std::string result; std::string result;
vpGenerate(result, desc); vpGenerate(result, m_VPBuiltinCurrent);
CVertexProgram *vertexProgram = new CVertexProgram(); CVertexProgram *vertexProgram = new CVertexProgram();
IProgram::CSource *src = new IProgram::CSource(); IProgram::CSource *src = new IProgram::CSource();
@ -387,10 +381,50 @@ CVertexProgram *CDriverGL3::generateBuiltinVertexProgram()
delete vertexProgram; vertexProgram = NULL; delete vertexProgram; vertexProgram = NULL;
} }
desc.VertexProgram = vertexProgram; m_VPBuiltinCurrent.VertexProgram = vertexProgram;
m_VPBuiltinCache.insert(desc); m_VPBuiltinCache.insert(m_VPBuiltinCurrent);
}
void CDriverGL3::enableFogVP(bool enable)
{
H_AUTO_OGL(CDriverGL3_enableFogInternal)
if (m_VPBuiltinCurrent.Fog != enable)
{
m_VPBuiltinCurrent.Fog = enable;
m_VPBuiltinTouched = true;
}
}
return desc.VertexProgram; void CDriverGL3::enableLightingVP(bool enable)
{
H_AUTO_OGL(CDriverGL3_enableLightingVP)
if (m_VPBuiltinCurrent.Lighting != enable)
{
m_VPBuiltinCurrent.Lighting = enable;
m_VPBuiltinTouched = true;
}
}
void CDriverGL3::touchLightVP(int i)
{
H_AUTO_OGL(CDriverGL3_touchLightVP)
sint mode = _UserLightEnable[i] ? _LightMode[i] : -1;
if (m_VPBuiltinCurrent.LightMode[i] != mode)
{
m_VPBuiltinCurrent.LightMode[i] = mode;
m_VPBuiltinTouched = true;
}
}
void CDriverGL3::touchVertexFormatVP()
{
H_AUTO_OGL(CDriverGL3_touchLightVP)
uint16 format = _CurrentVertexBufferHard->VB->getVertexFormat();
if (m_VPBuiltinCurrent.VertexFormat != format)
{
m_VPBuiltinCurrent.VertexFormat = format;
m_VPBuiltinTouched = true;
}
} }
#ifdef NL_STATIC #ifdef NL_STATIC

Loading…
Cancel
Save