On Fri, Jun 28, 2013 at 5:42 PM, Ian Romanick <i...@freedesktop.org> wrote: > On 06/13/2013 05:25 AM, Marek Olšák wrote: >> >> Hi everyone, >> >> this series adds a new GLSL compiler optimization pass which eliminates >> unused and set-but-unused built-in varyings and adds a few improvements to >> the GLSL linker in the process. >> >> Before I show you how it works, I wanna say that there are patches which >> are related to and will most probably conflict with the geometry shader >> work, but they are necessary because the linkage of varyings is largely >> suboptimal. >> >> Also, the GL_EXT_separate_shader_objects extension must be disabled >> for this optimization to be enabled. The reason is a program object with >> both a VS and FS can be bound partially, e.g. by >> glUseShaderProgramEXT(GL_VERTEX_SHADER, prog), so the extension makes >> every program object be just a set of "separate shaders". The extension >> is not important anyway. > > > Could you elaborate on this a bit? The problem already exists that shader > can be par-linked (e.g., just a vertex shader) and used with fixed-function. > A big part of the reason that I implemented EXT_sso back in the day was to > generate infrastructure, etc. for better using shaders with fixed function.
The only problem I have with EXT_sso is that you can link two programs, both having a vertex and fragment shader, and still mix-and-match their shaders independently as if all the shaders were separate/unlinked. For example: /* equivalent to glUseProgram(prog1); */ glUseShaderProgramEXT(GL_VERTEX_SHADER, prog1); glUseShaderProgramEXT(GL_FRAGMENT_SHADER, prog1); /* prog1 has its own fragment shader, but who cares! we don't have to bind it */ /* prog2 also has its own vertex shader */ glUseShaderProgramEXT(GL_VERTEX_SHADER, prog1); glUseShaderProgramEXT(GL_FRAGMENT_SHADER, prog2); /* more fun, we can put a geometry shader in between */ glUseShaderProgramEXT(GL_VERTEX_SHADER, prog1); glUseShaderProgramEXT(GL_GEOMETRY_SHADER, prog3); glUseShaderProgramEXT(GL_FRAGMENT_SHADER, prog1); /* assume prog3 has all 3 shaders, we can unbind the middle one */ glUseProgram(prog3); glUseShaderProgramEXT(GL_GEOMETRY_SHADER, NULL); I have no problem with linking program objects with a single shader and mixing and matching such program objects. However the ability to mix-and-match shaders no matter what program object they are part of is a real show-stopper for this optimization. Thankfully, this doesn't happen with fixed function and ARB_sso also forbids such usage. > > >> Now, to illustrate how the optimization works, consider these 2 shader IR >> dumps: >> >> >> Vertex shader (8 varyings): >> ... >> (declare (shader_out ) vec4 gl_FrontColor) >> (declare (shader_out ) vec4 gl_FrontSecondaryColor) >> (declare (shader_out ) (array vec4 6) gl_TexCoord) >> (function main >> (signature void >> (parameters >> ) >> ( >> ... >> (assign (xyzw) (var_ref gl_FrontColor) (var_ref gl_Color) ) >> (assign (xyzw) (var_ref gl_FrontSecondaryColor) (var_ref >> gl_SecondaryColor) ) >> (assign (xyzw) (array_ref (var_ref gl_TexCoord) (constant int (1)) >> ) (var_ref gl_MultiTexCoord1) ) >> (assign (xyzw) (array_ref (var_ref gl_TexCoord) (constant int (4)) >> ) (var_ref gl_MultiTexCoord4) ) >> (assign (xyzw) (array_ref (var_ref gl_TexCoord) (constant int (5)) >> ) (var_ref gl_MultiTexCoord5) ) >> )) >> ) >> >> Fragment shader (6 varyings): >> ... >> (declare (shader_in ) vec4 gl_SecondaryColor) >> (declare (shader_in ) (array vec4 5) gl_TexCoord) >> (function main >> (signature void >> (parameters >> ) >> ( >> (declare () vec4 r) >> (assign (xyzw) (var_ref r) ... (var_ref gl_SecondaryColor) ) ) >> (assign (xyzw) (var_ref r) ... (array_ref (var_ref gl_TexCoord) >> (constant int (1)) ) ) ) ) >> (assign (xyzw) (var_ref r) ... (array_ref (var_ref gl_TexCoord) >> (constant int (2)) ) ) ) ) >> (assign (xyzw) (var_ref r) ... (array_ref (var_ref gl_TexCoord) >> (constant int (3)) ) ) ) ) >> (declare (temporary ) vec4 assignment_tmp) >> (assign (xyzw) (var_ref assignment_tmp) ... (array_ref (var_ref >> gl_TexCoord) (constant int (4)) ) ) ) ) >> ... >> )) >> ) >> >> >> Note that only gl_TexCoord[1], gl_TexCoord[4], and gl_SecondaryColor >> are used by both shaders. The optimization replaces all occurences of >> varyings which are unused by the other stage by temporary variables. It >> also breaks down the gl_TexCoord array into separate vec4 variables if >> needed. Here's the result: > > > This sounds similar to the way Paul's varying packing works. Is there > synergy there? Also, since variables are renamed, does this interact with > transform feedback? The queries of GL_ARB_program_interface_query? I > suspect that it won't since this only affects built-in varyings, and > built-in varyings aren't usable with those interfaces. I haven't followed the varying packing work really, so I'm not sure, but it seemed to be only about user-defined varyings, while my work is only about built-in varyings. Concerning transform feedback, the optimization pass receives the list of TFB varyings and doesn't eliminate them. Concerning GL_ARB_program_interface_query, there doesn't seem to be any interaction with my work, like you say. Marek _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev