diff options
| author | degasus <wickmarkus@web.de> | 2013-10-13 14:14:32 +0200 |
|---|---|---|
| committer | degasus <wickmarkus@web.de> | 2013-10-13 14:14:32 +0200 |
| commit | 4dc1881f58f0b3c1276c5fde26fcabcdf114903f (patch) | |
| tree | 0f6d7b78dbacb983cf7c49a75bac437f618bf3e4 /Source/Core/VideoBackends/OGL/Src/ProgramShaderCache.cpp | |
| parent | 0753ce5bdaf756b144ec6003e1df01388b9c3e8f (diff) | |
| parent | 2754c1132ee1f3e4cf1045bd50b77425cd308411 (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.cpp | 104 |
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; } } |
