Cache shader uniform locations instead of looking them up every frame (1-2 fps boost yay?)

This commit is contained in:
parax0 2016-04-29 15:59:26 -06:00
parent e781908205
commit 420f483b56
4 changed files with 46 additions and 28 deletions

View File

@ -159,6 +159,7 @@ bool CShader::LinkShaders()
mLightBlockIndex = GetUniformBlockIndex("LightBlock"); mLightBlockIndex = GetUniformBlockIndex("LightBlock");
mBoneTransformBlockIndex = GetUniformBlockIndex("BoneTransformBlock"); mBoneTransformBlockIndex = GetUniformBlockIndex("BoneTransformBlock");
CacheCommonUniforms();
mProgramExists = true; mProgramExists = true;
return true; return true;
} }
@ -183,6 +184,17 @@ GLuint CShader::GetUniformBlockIndex(const char* pkUniformBlock)
return glGetUniformBlockIndex(mProgram, pkUniformBlock); return glGetUniformBlockIndex(mProgram, pkUniformBlock);
} }
void CShader::SetTextureUniforms(u32 NumTextures)
{
for (u32 iTex = 0; iTex < NumTextures; iTex++)
glUniform1i(mTextureUniforms[iTex], iTex);
}
void CShader::SetNumLights(u32 NumLights)
{
glUniform1i(mNumLightsUniform, NumLights);
}
void CShader::SetCurrent() void CShader::SetCurrent()
{ {
if (spCurrentShader != this) if (spCurrentShader != this)
@ -238,6 +250,17 @@ void CShader::KillCachedShader()
} }
// ************ PRIVATE ************ // ************ PRIVATE ************
void CShader::CacheCommonUniforms()
{
for (u32 iTex = 0; iTex < 8; iTex++)
{
TString TexUniform = "Texture" + TString::FromInt32(iTex);
mTextureUniforms[iTex] = glGetUniformLocation(mProgram, *TexUniform);
}
mNumLightsUniform = glGetUniformLocation(mProgram, "NumLights");
}
void CShader::DumpShaderSource(GLuint Shader, const TString& rkOut) void CShader::DumpShaderSource(GLuint Shader, const TString& rkOut)
{ {
GLint SourceLen; GLint SourceLen;

View File

@ -19,6 +19,10 @@ class CShader
GLuint mLightBlockIndex; GLuint mLightBlockIndex;
GLuint mBoneTransformBlockIndex; GLuint mBoneTransformBlockIndex;
// Cached uniform locations
GLint mTextureUniforms[8];
GLint mNumLightsUniform;
static CShader* spCurrentShader; static CShader* spCurrentShader;
public: public:
@ -32,6 +36,8 @@ public:
GLuint GetProgramID(); GLuint GetProgramID();
GLuint GetUniformLocation(const char* pkUniform); GLuint GetUniformLocation(const char* pkUniform);
GLuint GetUniformBlockIndex(const char* pkUniformBlock); GLuint GetUniformBlockIndex(const char* pkUniformBlock);
void SetTextureUniforms(u32 NumTextures);
void SetNumLights(u32 NumLights);
void SetCurrent(); void SetCurrent();
// Static // Static
@ -40,6 +46,7 @@ public:
static void KillCachedShader(); static void KillCachedShader();
private: private:
void CacheCommonUniforms();
void DumpShaderSource(GLuint Shader, const TString& rkOut); void DumpShaderSource(GLuint Shader, const TString& rkOut);
}; };

View File

@ -229,10 +229,10 @@ void CDrawUtil::DrawBillboard(CTexture* pTexture, const CVector3f& Position, con
// Set uniforms // Set uniforms
mpBillboardShader->SetCurrent(); mpBillboardShader->SetCurrent();
GLuint ScaleLoc = mpBillboardShader->GetUniformLocation("BillboardScale"); static GLuint ScaleLoc = mpBillboardShader->GetUniformLocation("BillboardScale");
glUniform2f(ScaleLoc, Scale.X, Scale.Y); glUniform2f(ScaleLoc, Scale.X, Scale.Y);
GLuint TintLoc = mpBillboardShader->GetUniformLocation("TintColor"); static GLuint TintLoc = mpBillboardShader->GetUniformLocation("TintColor");
glUniform4f(TintLoc, Tint.R, Tint.G, Tint.B, Tint.A); glUniform4f(TintLoc, Tint.R, Tint.G, Tint.B, Tint.A);
pTexture->Bind(0); pTexture->Bind(0);
@ -258,13 +258,13 @@ void CDrawUtil::DrawLightBillboard(ELightType Type, const CColor& LightColor, co
// Set uniforms // Set uniforms
mpLightBillboardShader->SetCurrent(); mpLightBillboardShader->SetCurrent();
GLuint ScaleLoc = mpLightBillboardShader->GetUniformLocation("BillboardScale"); static GLuint ScaleLoc = mpLightBillboardShader->GetUniformLocation("BillboardScale");
glUniform2f(ScaleLoc, Scale.X, Scale.Y); glUniform2f(ScaleLoc, Scale.X, Scale.Y);
GLuint ColorLoc = mpLightBillboardShader->GetUniformLocation("LightColor"); static GLuint ColorLoc = mpLightBillboardShader->GetUniformLocation("LightColor");
glUniform4f(ColorLoc, LightColor.R, LightColor.G, LightColor.B, LightColor.A); glUniform4f(ColorLoc, LightColor.R, LightColor.G, LightColor.B, LightColor.A);
GLuint TintLoc = mpLightBillboardShader->GetUniformLocation("TintColor"); static GLuint TintLoc = mpLightBillboardShader->GetUniformLocation("TintColor");
glUniform4f(TintLoc, Tint.R, Tint.G, Tint.B, Tint.A); glUniform4f(TintLoc, Tint.R, Tint.G, Tint.B, Tint.A);
CTexture *pTexA = GetLightTexture(Type); CTexture *pTexA = GetLightTexture(Type);
@ -272,8 +272,8 @@ void CDrawUtil::DrawLightBillboard(ELightType Type, const CColor& LightColor, co
pTexA->Bind(0); pTexA->Bind(0);
pTexB->Bind(1); pTexB->Bind(1);
GLuint TextureLoc = mpLightBillboardShader->GetUniformLocation("Texture"); static GLuint TextureLoc = mpLightBillboardShader->GetUniformLocation("Texture");
GLuint MaskLoc = mpLightBillboardShader->GetUniformLocation("LightMask"); static GLuint MaskLoc = mpLightBillboardShader->GetUniformLocation("LightMask");
glUniform1i(TextureLoc, 0); glUniform1i(TextureLoc, 0);
glUniform1i(MaskLoc, 1); glUniform1i(MaskLoc, 1);
@ -293,7 +293,7 @@ void CDrawUtil::UseColorShader(const CColor& kColor)
Init(); Init();
mpColorShader->SetCurrent(); mpColorShader->SetCurrent();
GLuint ColorLoc = mpColorShader->GetUniformLocation("ColorIn"); static GLuint ColorLoc = mpColorShader->GetUniformLocation("ColorIn");
glUniform4f(ColorLoc, kColor.R, kColor.G, kColor.B, kColor.A); glUniform4f(ColorLoc, kColor.R, kColor.G, kColor.B, kColor.A);
CMaterial::KillCachedMaterial(); CMaterial::KillCachedMaterial();
@ -304,10 +304,10 @@ void CDrawUtil::UseColorShaderLighting(const CColor& kColor)
Init(); Init();
mpColorShaderLighting->SetCurrent(); mpColorShaderLighting->SetCurrent();
GLuint NumLightsLoc = mpColorShaderLighting->GetUniformLocation("NumLights"); static GLuint NumLightsLoc = mpColorShaderLighting->GetUniformLocation("NumLights");
glUniform1i(NumLightsLoc, CGraphics::sNumLights); glUniform1i(NumLightsLoc, CGraphics::sNumLights);
GLuint ColorLoc = mpColorShaderLighting->GetUniformLocation("ColorIn"); static GLuint ColorLoc = mpColorShaderLighting->GetUniformLocation("ColorIn");
glUniform4f(ColorLoc, kColor.R, kColor.G, kColor.B, kColor.A); glUniform4f(ColorLoc, kColor.R, kColor.G, kColor.B, kColor.A);
CMaterial::KillCachedMaterial(); CMaterial::KillCachedMaterial();
@ -323,7 +323,7 @@ void CDrawUtil::UseTextureShader(const CColor& TintColor)
Init(); Init();
mpTextureShader->SetCurrent(); mpTextureShader->SetCurrent();
GLuint TintColorLoc = mpTextureShader->GetUniformLocation("TintColor"); static GLuint TintColorLoc = mpTextureShader->GetUniformLocation("TintColor");
glUniform4f(TintColorLoc, TintColor.R, TintColor.G, TintColor.B, TintColor.A); glUniform4f(TintColorLoc, TintColor.R, TintColor.G, TintColor.B, TintColor.A);
CMaterial::KillCachedMaterial(); CMaterial::KillCachedMaterial();
@ -335,7 +335,7 @@ void CDrawUtil::UseCollisionShader(const CColor& TintColor /*= CColor::skWhite*/
mpCollisionShader->SetCurrent(); mpCollisionShader->SetCurrent();
LoadCheckerboardTexture(0); LoadCheckerboardTexture(0);
GLuint TintColorLoc = mpCollisionShader->GetUniformLocation("TintColor"); static GLuint TintColorLoc = mpCollisionShader->GetUniformLocation("TintColor");
glUniform4f(TintColorLoc, TintColor.R, TintColor.G, TintColor.B, TintColor.A); glUniform4f(TintColorLoc, TintColor.R, TintColor.G, TintColor.B, TintColor.A);
CMaterial::KillCachedMaterial(); CMaterial::KillCachedMaterial();

View File

@ -105,12 +105,6 @@ void CMaterial::GenerateShader(bool AllowRegen /*= true*/)
bool CMaterial::SetCurrent(FRenderOptions Options) bool CMaterial::SetCurrent(FRenderOptions Options)
{ {
// Bind textures
const char *skpSamplers[8] = {
"Texture0", "Texture1", "Texture2", "Texture3",
"Texture4", "Texture5", "Texture6", "Texture7"
};
// Skip material setup if the currently bound material is identical // Skip material setup if the currently bound material is identical
if (sCurrentMaterial != HashParameters()) if (sCurrentMaterial != HashParameters())
{ {
@ -177,19 +171,13 @@ bool CMaterial::SetCurrent(FRenderOptions Options)
} }
} }
// Bind textures // Set up shader uniforms
CShader *pShader = CShader::CurrentShader();
for (u32 iPass = 0; iPass < mPasses.size(); iPass++) for (u32 iPass = 0; iPass < mPasses.size(); iPass++)
{
mPasses[iPass]->LoadTexture(iPass); mPasses[iPass]->LoadTexture(iPass);
GLint sampler = pShader->GetUniformLocation(skpSamplers[iPass]);
glUniform1i(sampler, iPass);
}
// Bind num lights CShader *pShader = CShader::CurrentShader();
GLuint NumLightsLoc = pShader->GetUniformLocation("NumLights"); pShader->SetTextureUniforms(mPasses.size());
glUniform1i(NumLightsLoc, CGraphics::sNumLights); pShader->SetNumLights(CGraphics::sNumLights);
// Update shader blocks // Update shader blocks
CGraphics::UpdateVertexBlock(); CGraphics::UpdateVertexBlock();