summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/OGL/Src/ProgramShaderCache.cpp
diff options
context:
space:
mode:
authordegasus <wickmarkus@web.de>2013-10-13 14:14:32 +0200
committerdegasus <wickmarkus@web.de>2013-10-13 14:14:32 +0200
commit4dc1881f58f0b3c1276c5fde26fcabcdf114903f (patch)
tree0f6d7b78dbacb983cf7c49a75bac437f618bf3e4 /Source/Core/VideoBackends/OGL/Src/ProgramShaderCache.cpp
parent0753ce5bdaf756b144ec6003e1df01388b9c3e8f (diff)
parent2754c1132ee1f3e4cf1045bd50b77425cd308411 (diff)
Merge branch 'const_buffer_rework'
Diffstat (limited to 'Source/Core/VideoBackends/OGL/Src/ProgramShaderCache.cpp')
-rw-r--r--Source/Core/VideoBackends/OGL/Src/ProgramShaderCache.cpp104
1 files changed, 68 insertions, 36 deletions
diff --git a/Source/Core/VideoBackends/OGL/Src/ProgramShaderCache.cpp b/Source/Core/VideoBackends/OGL/Src/ProgramShaderCache.cpp
index 94b9502d2f..51f41c063b 100644
--- a/Source/Core/VideoBackends/OGL/Src/ProgramShaderCache.cpp
+++ b/Source/Core/VideoBackends/OGL/Src/ProgramShaderCache.cpp
@@ -10,18 +10,16 @@
#include "Statistics.h"
#include "ImageWrite.h"
#include "Render.h"
+#include "PixelShaderManager.h"
+#include "VertexShaderManager.h"
namespace OGL
{
static const u32 UBO_LENGTH = 32*1024*1024;
-GLintptr ProgramShaderCache::s_vs_data_size;
-GLintptr ProgramShaderCache::s_ps_data_size;
-GLintptr ProgramShaderCache::s_vs_data_offset;
-u8 *ProgramShaderCache::s_ubo_buffer;
u32 ProgramShaderCache::s_ubo_buffer_size;
-bool ProgramShaderCache::s_ubo_dirty;
+s32 ProgramShaderCache::s_ubo_align;
static StreamBuffer *s_buffer;
static int num_failures = 0;
@@ -36,6 +34,10 @@ UidChecker<VertexShaderUid,VertexShaderCode> ProgramShaderCache::vertex_uid_chec
static char s_glsl_header[1024] = "";
+
+
+// Annoying sure, can be removed once we drop our UBO workaround
+
const char *UniformNames[NUM_UNIFORMS] =
{
// PIXEL SHADER UNIFORMS
@@ -61,6 +63,33 @@ const char *UniformNames[NUM_UNIFORMS] =
I_DEPTHPARAMS,
};
+const static int PSVar_Loc[] = {
+ offsetof(PixelShaderConstants, colors)/16,
+ offsetof(PixelShaderConstants, kcolors)/16,
+ offsetof(PixelShaderConstants, alpha)/16,
+ offsetof(PixelShaderConstants, texdims)/16,
+ offsetof(PixelShaderConstants, zbias)/16,
+ offsetof(PixelShaderConstants, indtexscale)/16,
+ offsetof(PixelShaderConstants, indtexmtx)/16,
+ offsetof(PixelShaderConstants, fog)/16,
+ offsetof(PixelShaderConstants, plights)/16,
+ offsetof(PixelShaderConstants, pmaterials)/16,
+};
+
+const static int VSVar_Loc[] = {
+ offsetof(VertexShaderConstants, posnormalmatrix)/16,
+ offsetof(VertexShaderConstants, projection)/16,
+ offsetof(VertexShaderConstants, materials)/16,
+ offsetof(VertexShaderConstants, lights)/16,
+ offsetof(VertexShaderConstants, texmatrices)/16,
+ offsetof(VertexShaderConstants, transformmatrices)/16,
+ offsetof(VertexShaderConstants, normalmatrices)/16,
+ offsetof(VertexShaderConstants, posttransformmatrices)/16,
+ offsetof(VertexShaderConstants, depthparams)/16,
+};
+
+// End of UBO workaround
+
void SHADER::SetProgramVariables()
{
// glsl shader must be bind to set samplers
@@ -162,30 +191,43 @@ void SHADER::Bind()
}
}
-
-void ProgramShaderCache::SetMultiPSConstant4fv(unsigned int offset, const float *f, unsigned int count)
-{
- s_ubo_dirty = true;
- memcpy(s_ubo_buffer+(offset*4*sizeof(float)), f, count*4*sizeof(float));
-}
-
-void ProgramShaderCache::SetMultiVSConstant4fv(unsigned int offset, const float *f, unsigned int count)
-{
- s_ubo_dirty = true;
- memcpy(s_ubo_buffer+(offset*4*sizeof(float))+s_vs_data_offset, f, count*4*sizeof(float));
-}
-
void ProgramShaderCache::UploadConstants()
{
- if(s_ubo_dirty) {
- s_buffer->Alloc(s_ubo_buffer_size);
- size_t offset = s_buffer->Upload(s_ubo_buffer, s_ubo_buffer_size);
- glBindBufferRange(GL_UNIFORM_BUFFER, 1, s_buffer->getBuffer(), offset, s_ps_data_size);
- glBindBufferRange(GL_UNIFORM_BUFFER, 2, s_buffer->getBuffer(), offset + s_vs_data_offset, s_vs_data_size);
- s_ubo_dirty = false;
+ if(g_ActiveConfig.backend_info.bSupportsGLSLUBO)
+ {
+ if(PixelShaderManager::dirty || VertexShaderManager::dirty)
+ {
+ s_buffer->Alloc(s_ubo_buffer_size);
+
+ size_t offset = s_buffer->Upload((u8*)&PixelShaderManager::constants, ROUND_UP(sizeof(PixelShaderConstants), s_ubo_align));
+ glBindBufferRange(GL_UNIFORM_BUFFER, 1, s_buffer->getBuffer(), offset, sizeof(PixelShaderConstants));
+ offset = s_buffer->Upload((u8*)&VertexShaderManager::constants, ROUND_UP(sizeof(VertexShaderConstants), s_ubo_align));
+ glBindBufferRange(GL_UNIFORM_BUFFER, 2, s_buffer->getBuffer(), offset, sizeof(VertexShaderConstants));
+
+ PixelShaderManager::dirty = false;
+ VertexShaderManager::dirty = false;
+
+ ADDSTAT(stats.thisFrame.bytesUniformStreamed, s_ubo_buffer_size);
+ }
+ }
+ else
+ {
+ // UBO workaround
+ // this must be updated per shader switch, so also update it when it's not dirty
+ for (unsigned int a = 0; a < 10; ++a)
+ {
+ if(last_entry->shader.UniformSize[a] > 0)
+ glUniform4fv(last_entry->shader.UniformLocations[a], last_entry->shader.UniformSize[a], (float*) &PixelShaderManager::constants + 4*PSVar_Loc[a]);
+ }
+ for (unsigned int a = 0; a < 9; ++a)
+ {
+ if(last_entry->shader.UniformSize[a+10] > 0)
+ glUniform4fv(last_entry->shader.UniformLocations[a+10], last_entry->shader.UniformSize[a+10], (float*) &VertexShaderManager::constants + 4*VSVar_Loc[a]);
+ }
ADDSTAT(stats.thisFrame.bytesUniformStreamed, s_ubo_buffer_size);
}
+
}
GLuint ProgramShaderCache::GetCurrentProgram(void)
@@ -419,22 +461,14 @@ void ProgramShaderCache::Init(void)
// then the UBO will fail.
if (g_ActiveConfig.backend_info.bSupportsGLSLUBO)
{
- GLint Align;
- glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &Align);
+ glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &s_ubo_align);
- s_ps_data_size = C_PENVCONST_END * sizeof(float) * 4;
- s_vs_data_size = C_VENVCONST_END * sizeof(float) * 4;
- s_vs_data_offset = ROUND_UP(s_ps_data_size, Align);
- s_ubo_buffer_size = ROUND_UP(s_ps_data_size, Align) + ROUND_UP(s_vs_data_size, Align);
+ s_ubo_buffer_size = ROUND_UP(sizeof(PixelShaderConstants), s_ubo_align) + ROUND_UP(sizeof(VertexShaderConstants), s_ubo_align);
// We multiply by *4*4 because we need to get down to basic machine units.
// So multiply by four to get how many floats we have from vec4s
// Then once more to get bytes
s_buffer = new StreamBuffer(GL_UNIFORM_BUFFER, UBO_LENGTH);
-
- s_ubo_buffer = new u8[s_ubo_buffer_size];
- memset(s_ubo_buffer, 0, s_ubo_buffer_size);
- s_ubo_dirty = true;
}
// Read our shader cache, only if supported
@@ -509,8 +543,6 @@ void ProgramShaderCache::Shutdown(void)
{
delete s_buffer;
s_buffer = 0;
- delete [] s_ubo_buffer;
- s_ubo_buffer = 0;
}
}