From 0154639e1900b95695e1eca89a7647cacfc67192 Mon Sep 17 00:00:00 2001 From: "gregory.hainaut" Date: Sun, 27 May 2012 15:34:48 +0000 Subject: [PATCH] zzogl glsl: optimize state change. With luck it would be less slower. At least GL trace is much smaller (Gow menu go down from 4600 to 3000!) git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5237 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/zzogl-pg/opengl/ZZoglShaders.h | 21 +++++--- plugins/zzogl-pg/opengl/ZZoglShadersGLSL4.cpp | 54 +++++++++++++------ plugins/zzogl-pg/opengl/ps2hw_gl4.glsl | 2 +- 3 files changed, 54 insertions(+), 23 deletions(-) diff --git a/plugins/zzogl-pg/opengl/ZZoglShaders.h b/plugins/zzogl-pg/opengl/ZZoglShaders.h index 02ae8957ce..32619e46d5 100644 --- a/plugins/zzogl-pg/opengl/ZZoglShaders.h +++ b/plugins/zzogl-pg/opengl/ZZoglShaders.h @@ -327,8 +327,9 @@ struct FRAGMENTSHADER #endif }; #else -const GLenum g_texture_target[10] = {GL_TEXTURE_RECTANGLE, GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_RECTANGLE, GL_TEXTURE_RECTANGLE, GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D}; +const GLenum g_texture_target[11] = {GL_TEXTURE_RECTANGLE, GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_RECTANGLE, GL_TEXTURE_RECTANGLE, GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE}; +extern int g_current_texture_bind[11]; struct SamplerParam { int unit; GLuint texid; @@ -337,17 +338,20 @@ struct SamplerParam { SamplerParam() : unit(-1), texid(0), target(0) {} void set_unit(int new_unit) { - assert(new_unit < 10); + assert(new_unit < 11); unit = new_unit; target = g_texture_target[new_unit]; } void enable_texture() { assert(unit >= 0); - assert(unit < 10); + assert(unit < 11); if (texid) { - glActiveTexture(GL_TEXTURE0 + unit); - glBindTexture(target, texid); + if (g_current_texture_bind[unit] != texid) { + glActiveTexture(GL_TEXTURE0 + unit); + glBindTexture(target, texid); + g_current_texture_bind[unit] = texid; + } } } @@ -392,8 +396,8 @@ struct FRAGMENTSHADER //sBitwiseANDY = 4; //sInterlace = 5; //sCLUT = 6; - samplers[sMemory].set_unit(0); - samplers[sMemory+1].set_unit(0); // Dual context. Use same unit + samplers[sMemory].set_unit(10); + samplers[sMemory+1].set_unit(10); // Dual context. Use same unit samplers[sFinal].set_unit(1); samplers[sBitwiseANDX].set_unit(6); samplers[sBitwiseANDY].set_unit(7); @@ -738,6 +742,9 @@ extern GSUniformBufferOGL *vertex_buffer; extern GSUniformBufferOGL *fragment_buffer; extern GSVertexBufferStateOGL *vertex_array; +extern GLenum g_current_vs; +extern GLenum g_current_ps; + extern void init_shader(); extern void PutParametersInProgram(VERTEXSHADER* vs, FRAGMENTSHADER* ps); extern void init_shader(); diff --git a/plugins/zzogl-pg/opengl/ZZoglShadersGLSL4.cpp b/plugins/zzogl-pg/opengl/ZZoglShadersGLSL4.cpp index b984d46e82..0f5de97c32 100644 --- a/plugins/zzogl-pg/opengl/ZZoglShadersGLSL4.cpp +++ b/plugins/zzogl-pg/opengl/ZZoglShadersGLSL4.cpp @@ -120,11 +120,19 @@ GSUniformBufferOGL *constant_buffer; GSUniformBufferOGL *common_buffer; GSUniformBufferOGL *vertex_buffer; GSUniformBufferOGL *fragment_buffer; +static bool dirty_common_buffer = true; +static bool dirty_vertex_buffer = true; +static bool dirty_fragment_buffer = true; + GSVertexBufferStateOGL *vertex_array; COMMONSHADER g_cs; static GLuint s_pipeline = 0; +int g_current_texture_bind[11] = {0}; +GLenum g_current_vs = NULL; +GLenum g_current_ps = NULL; + //FRAGMENTSHADER ppsDebug; //FRAGMENTSHADER ppsDebug2; @@ -260,9 +268,11 @@ void ZZshSetParameter4fv(ZZshShaderLink& prog, ZZshParameter param, const float* if (prog.isFragment) { FRAGMENTSHADER* shader = (FRAGMENTSHADER*)prog.link; shader->ZZshSetParameter4fv(param, v); + dirty_fragment_buffer = true; } else { VERTEXSHADER* shader = (VERTEXSHADER*)prog.link; shader->ZZshSetParameter4fv(param, v); + dirty_vertex_buffer = true; } #ifdef ENABLE_MARKER char* debug = new char[100]; @@ -273,6 +283,7 @@ void ZZshSetParameter4fv(ZZshShaderLink& prog, ZZshParameter param, const float* void ZZshSetParameter4fv(ZZshParameter param, const float* v, const char* name) { g_cs.ZZshSetParameter4fv(param, v); + dirty_common_buffer = true; #ifdef ENABLE_MARKER char* debug = new char[100]; sprintf(debug, "CS: uniform (%s) (%f)", name, *v); @@ -282,13 +293,7 @@ void ZZshSetParameter4fv(ZZshParameter param, const float* v, const char* name) // The same stuff, but also with retry of param, name should be USED name of param for prog. void ZZshSetParameter4fvWithRetry(ZZshParameter* param, ZZshShaderLink& prog, const float* v, const char* name) { - if (prog.isFragment) { - FRAGMENTSHADER* shader = (FRAGMENTSHADER*)prog.link; - shader->ZZshSetParameter4fv(*param, v); - } else { - VERTEXSHADER* shader = (VERTEXSHADER*)prog.link; - shader->ZZshSetParameter4fv(*param, v); - } + ZZshSetParameter4fv(prog, *param, v, name); } // Used sometimes for color 1. @@ -296,6 +301,7 @@ void ZZshDefaultOneColor( FRAGMENTSHADER& ptr ) { ShaderHandleName = "Set Default One colot"; float4 v = float4 ( 1, 1, 1, 1 ); ptr.ZZshSetParameter4fv(ptr.sOneColor, v); + dirty_fragment_buffer = true; } //------------------------------------------------------------------------------------- @@ -371,7 +377,10 @@ void ZZshSetVertexShader(ZZshShaderLink prog) { VERTEXSHADER* vs = (VERTEXSHADER*)g_vsprog.link; if (!vs) return; - glUseProgramStages(s_pipeline, GL_VERTEX_SHADER_BIT, vs->program); + if (vs->program != g_current_vs) { + glUseProgramStages(s_pipeline, GL_VERTEX_SHADER_BIT, vs->program); + g_current_ps = vs->program; + } } void ZZshSetPixelShader(ZZshShaderLink prog) { @@ -380,7 +389,10 @@ void ZZshSetPixelShader(ZZshShaderLink prog) { FRAGMENTSHADER* ps = (FRAGMENTSHADER*)g_psprog.link; if (!ps) return; - glUseProgramStages(s_pipeline, GL_FRAGMENT_SHADER_BIT, ps->program); + if (ps->program != g_current_ps) { + glUseProgramStages(s_pipeline, GL_FRAGMENT_SHADER_BIT, ps->program); + g_current_ps = ps->program; + } } //------------------------------------------------------------------------------------------------------------------ @@ -413,14 +425,23 @@ void init_shader() { void PutParametersInProgram(VERTEXSHADER* vs, FRAGMENTSHADER* ps) { - common_buffer->bind(); - common_buffer->upload((void*)&g_cs.uniform_buffer[g_cs.context]); + if (dirty_common_buffer) { + common_buffer->bind(); + common_buffer->upload((void*)&g_cs.uniform_buffer[g_cs.context]); + dirty_common_buffer = false; + } - vertex_buffer->bind(); - vertex_buffer->upload((void*)&vs->uniform_buffer[vs->context]); + if (dirty_vertex_buffer) { + vertex_buffer->bind(); + vertex_buffer->upload((void*)&vs->uniform_buffer[vs->context]); + dirty_vertex_buffer = false; + } - fragment_buffer->bind(); - fragment_buffer->upload((void*)&ps->uniform_buffer[ps->context]); + if (dirty_fragment_buffer) { + fragment_buffer->bind(); + fragment_buffer->upload((void*)&ps->uniform_buffer[ps->context]); + dirty_fragment_buffer = false; + } #ifdef ENABLE_MARKER char* debug = new char[100]; @@ -430,6 +451,9 @@ void PutParametersInProgram(VERTEXSHADER* vs, FRAGMENTSHADER* ps) { g_cs.enable_texture(); ps->enable_texture(); + // By default enable the unit 0, so I have the guarantee that any + // texture command won't change current binding of others unit + glActiveTexture(GL_TEXTURE0); } std::string BuildGlslMacro(bool writedepth, int texwrap = 3, bool testaem = false, bool exactcolor = false) diff --git a/plugins/zzogl-pg/opengl/ps2hw_gl4.glsl b/plugins/zzogl-pg/opengl/ps2hw_gl4.glsl index 9c12b47ec0..25514ddab0 100644 --- a/plugins/zzogl-pg/opengl/ps2hw_gl4.glsl +++ b/plugins/zzogl-pg/opengl/ps2hw_gl4.glsl @@ -145,7 +145,7 @@ layout(location = 1) out vec4 FragData1; // // used only on rare cases where the render target is PSMT8H // uniform sampler2D g_sCLUT; // main ps2 memory, each pixel is stored in 32bit color -layout(binding = 0) uniform sampler2DRect g_sMemory; // dual context +layout(binding = 10) uniform sampler2DRect g_sMemory; // dual context // used to get the tiled offset into a page given the linear offset layout(binding = 1) uniform sampler2DRect g_sSrcFinal;