Re: [Mesa-dev] glsl2: optimizing unused struct assignments
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Aras Pranckevicius wrote: >> By the way, it would be useful to get some examples of your shaders as >> shader_runner tests in piglit. That makes them easy to analyze for >> optimization opportunities, and they serve as regression tests to make >> sure we don't break your shaders. Would you be up for making some of >> those? > > I don't quite know what piglit or shader_runner is... I guess it's > stuff here: http://cgit.freedesktop.org/piglit/tree/tests/shaders ? Right. Shader runner is takes a simple .ini-style file with shaders, uniform values, draw calls, and pixel probes. Look at the *.shader_test files for examples. > I do have about 500 random shaders from Unity here: > http://github.com/aras-p/glsl-optimizer/tree/glsl2/src/glsl/optimizer-tests/ > (the *-in.txt files), but to prepare them for piglit I'd have to think > up some instructions to draw something and inspect the pixel values, > right? -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkxcjVUACgkQX1gOwKyEAw8ZJQCeLGOkpB5qcweZPG2uvqTAQrAq KdcAnjvgDMGC+PeDOPw8mbAzreiLBBdD =VrhY -END PGP SIGNATURE- ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] glsl2: optimizing unused struct assignments
On Fri, 6 Aug 2010 09:46:17 +0200, Aras Pranckevicius wrote: > > Pushed a change that cleans up the shader you pasted. Mostly. There's > > still some junk in it that we could do better at. Results below. > > Very nice, thanks! > > > > By the way, it would be useful to get some examples of your shaders as > > shader_runner tests in piglit. That makes them easy to analyze for > > optimization opportunities, and they serve as regression tests to make > > sure we don't break your shaders. Would you be up for making some of > > those? > > I don't quite know what piglit or shader_runner is... I guess it's > stuff here: http://cgit.freedesktop.org/piglit/tree/tests/shaders ? > > I do have about 500 random shaders from Unity here: > http://github.com/aras-p/glsl-optimizer/tree/glsl2/src/glsl/optimizer-tests/ > (the *-in.txt files), but to prepare them for piglit I'd have to think > up some instructions to draw something and inspect the pixel values, > right? Yeah. It's hard to make sure things are really correct without testing for actual pixel results. pgpC1JRQIw2JR.pgp Description: PGP signature ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] glsl2: optimizing unused struct assignments
> Pushed a change that cleans up the shader you pasted. Mostly. There's > still some junk in it that we could do better at. Results below. Very nice, thanks! > By the way, it would be useful to get some examples of your shaders as > shader_runner tests in piglit. That makes them easy to analyze for > optimization opportunities, and they serve as regression tests to make > sure we don't break your shaders. Would you be up for making some of > those? I don't quite know what piglit or shader_runner is... I guess it's stuff here: http://cgit.freedesktop.org/piglit/tree/tests/shaders ? I do have about 500 random shaders from Unity here: http://github.com/aras-p/glsl-optimizer/tree/glsl2/src/glsl/optimizer-tests/ (the *-in.txt files), but to prepare them for piglit I'd have to think up some instructions to draw something and inspect the pixel values, right? -- Aras Pranckevičius work: http://unity3d.com home: http://aras-p.info ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] glsl2: optimizing unused struct assignments
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Aras Pranckevicius wrote: >> We'll have similar issue with code like: >> uniform vec4 angles; >> void main() { >> vec4 v; >> v.x = sin(angles.x); >> v.y = cos(angles.y); >> v.z = tan(angles.z); >> v.w = 1/tan(angles.w); >> gl_Position = v.xyxy; >> } >> >> In this case v.zw is never used, and the (expensive) assignments should >> be killed. > > What's the plan for attacking this? Splitting up structures into > individual variables won't help with this case. We'll need to track setting and using of vector components individually. In the case above, we could detect that v.zw are never used. That information could be used to find (and kill) places that set them. -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkxbNF0ACgkQX1gOwKyEAw+eAgCdGHyCidnbyWkPHafEbvXfNJE0 HZ4An3KTNzRGoX0dZSlpVKhD0eSb/OKO =/WYU -END PGP SIGNATURE- ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] glsl2: optimizing unused struct assignments
On Thu, 5 Aug 2010 13:33:50 +0200, Aras Pranckevicius wrote: > > I believe the plan is to eventually break structures and arrays that are > > not variably indexed into individual variables. Your structure above > > would be broken into s_used and s_unused. The existing dead code paths > > would take care of s_unused. We'll need to do this break-up anyway to > > do proper register assignment. > > Ok, nice. If someone else is going to do that I don't have to worry > about it. Any idea on when that work is planned to be done? > > For the GLSL optimizer I'm working on this currently seems to be the > largest possible optimization left. On a certain mobile platform that > starts with 'i' a fragment shader like this: Pushed a change that cleans up the shader you pasted. Mostly. There's still some junk in it that we could do better at. Results below. By the way, it would be useful to get some examples of your shaders as shader_runner tests in piglit. That makes them easy to analyze for optimization opportunities, and they serve as regression tests to make sure we don't break your shaders. Would you be up for making some of those? GLSL IR for linked fragment program 3: ( (declare (out ) (array vec4 8) gl_fragd...@0x847b3a8) (declare (uniform ) vec4 _co...@0x83bcfe0) (declare (uniform ) sampler2D _det...@0x83bd098) (declare (uniform ) sampler2D _main...@0x83c35e8) (declare (in ) vec4 xlv_texcoo...@0x83c36a0) (declare (in ) vec4 xlv_texcoo...@0x83c3760) (function main (signature void (parameters ) ( (declare () vec4 c...@0x83df7c8) (assign (constant bool (1)) (xyzw) (var_ref c...@0x83df7c8) (expression vec4 * (var_ref _co...@0x83bcfe0) (tex (var_ref _main...@0x83c35e8) (swiz xy (var_ref xlv_texcoo...@0x83c36a0) ) (0 0 0) 1 () )) ) (declare (temporary ) vec4 assignment_...@0x83ee630) (assign (constant bool (1)) (xyzw) (var_ref assignment_...@0x83ee630) (expression vec4 * (expression vec4 * (var_ref c...@0x83df7c8) (tex (var_ref _det...@0x83bd098) (swiz xy (var_ref xlv_texcoo...@0x83c3760) ) (0 0 0) 1 () )) (constant float (2.00)) ) ) (assign (constant bool (1)) (xyzw) (var_ref c...@0x83df7c8) (var_ref assignment_...@0x83ee630) ) (assign (constant bool (1)) (xyzw) (array_ref (var_ref gl_fragd...@0x847b3a8) (constant int (0)) ) (swiz xyzw (var_ref assignment_...@0x83ee630) )) )) ) Mesa IR for linked fragment program 3: 0: (tex (var_ref _main...@0x83c35e8) (swiz xy (var_ref xlv_texcoo...@0x83c36a0) ) (0 0 0) 1 () ) MOV TEMP[1], INPUT[14].xyyy; This gets copy-propagated to the next instruction in Mesa IR and is just a result of laziness in ir_to_mesa.cpp. (Same goes for extra move of assignment rhs to lhs). 1: TEX TEMP[2], TEMP[1], texture[0], 2D; 2: (expression vec4 * (var_ref _co...@0x83bcfe0) (tex (var_ref _main...@0x83c35e8) (swiz xy (var_ref xlv_texcoo...@0x83c36a0) ) (0 0 0) 1 () )) MUL TEMP[3], UNIFORM[0], TEMP[2]; 3: (assign (constant bool (1)) (xyzw) (var_ref c...@0x83df7c8) (expression vec4 * (var_ref _co...@0x83bcfe0) (tex (var_ref _main...@0x83c35e8) (swiz xy (var_ref xlv_texcoo...@0x83c36a0) ) (0 0 0) 1 () )) ) MOV TEMP[4], TEMP[3]; 4: (tex (var_ref _det...@0x83bd098) (swiz xy (var_ref xlv_texcoo...@0x83c3760) ) (0 0 0) 1 () ) MOV TEMP[5], INPUT[15].xyyy; 5: TEX TEMP[6], TEMP[5], texture[1], 2D; 6: (expression vec4 * (var_ref c...@0x83df7c8) (tex (var_ref _det...@0x83bd098) (swiz xy (var_ref xlv_texcoo...@0x83c3760) ) (0 0 0) 1 () )) MUL TEMP[7], TEMP[4], TEMP[6]; 7: (expression vec4 * (expression vec4 * (var_ref c...@0x83df7c8) (tex (var_ref _det...@0x83bd098) (swiz xy (var_ref xlv_texcoo...@0x83c3760) ) (0 0 0) 1 () )) (constant float (2.00)) ) MUL TEMP[8], TEMP[7], CONST[3].; 8: (assign (constant bool (1)) (xyzw) (var_ref assignment_...@0x83ee630) (expression vec4 * (expression vec4 * (var_ref c...@0x83df7c8) (tex (var_ref _det...@0x83bd098) (swiz xy (var_ref xlv_texcoo...@0x83c3760) ) (0 0 0) 1 () )) (constant float (2.00)) ) ) MOV TEMP[9], TEMP[8]; 9: (assign (constant bool (1)) (xyzw) (var_ref c...@0x83df7c8) (var_ref assignment_...@0x83ee630) ) MOV TEMP[4], TEMP[9]; This move to "c" is junk, which gets dead-coded by Mesa IR but we ought to be able to kill it before then. (If we do GVN on functions, that would cover this, and we ought to do that). 10: (assign (constant bool (1)) (xyzw) (array_ref (var_ref gl_fragd...@0x847b3a8) (constant int (0)) ) (swiz xyzw (var_ref assignment_...@0x83ee630) )) MOV OUTPUT[2], TEMP[9]; 11: END pgpUY3IC3MGFS.pgp Description: PGP signature ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] glsl2: optimizing unused struct assignments
> I believe the plan is to eventually break structures and arrays that are > not variably indexed into individual variables. Your structure above > would be broken into s_used and s_unused. The existing dead code paths > would take care of s_unused. We'll need to do this break-up anyway to > do proper register assignment. Ok, nice. If someone else is going to do that I don't have to worry about it. Any idea on when that work is planned to be done? For the GLSL optimizer I'm working on this currently seems to be the largest possible optimization left. On a certain mobile platform that starts with 'i' a fragment shader like this: struct v2f { vec4 pos; vec2 uv0; vec2 uv1; }; uniform vec4 _Color; uniform sampler2D _Detail; uniform sampler2D _MainTex; varying vec4 xlv_TEXCOORD0; varying vec4 xlv_TEXCOORD1; void main () { v2f xlt_i; xlt_i.uv0 = xlv_TEXCOORD0.xy; xlt_i.uv1 = xlv_TEXCOORD1.xy; v2f i; i = xlt_i; vec4 c; vec4 tmpvar_10; tmpvar_10 = texture2D (_MainTex, i.uv0); c = (_Color * tmpvar_10); vec4 tmpvar_12; tmpvar_12 = texture2D (_Detail, i.uv1); vec4 tmpvar_13; tmpvar_13 = ((c * tmpvar_12) * 2.00); c = tmpvar_13; gl_FragData[0] = tmpvar_13.xyzw; } Is running about 2.5X slower than the one I hand-optimize by removing structure member moves: // ... void main () { vec4 c; vec4 tmpvar_10; tmpvar_10 = texture2D (_MainTex, xlv_TEXCOORD0.xy); c = (_Color * tmpvar_10); vec4 tmpvar_12; tmpvar_12 = texture2D (_Detail, xlv_TEXCOORD1.xy); vec4 tmpvar_13; tmpvar_13 = ((c * tmpvar_12) * 2.00); c = tmpvar_13; gl_FragData[0] = tmpvar_13.xyzw; } > We'll have similar issue with code like: > uniform vec4 angles; > void main() { > vec4 v; > v.x = sin(angles.x); > v.y = cos(angles.y); > v.z = tan(angles.z); > v.w = 1/tan(angles.w); > gl_Position = v.xyxy; > } > > In this case v.zw is never used, and the (expensive) assignments should > be killed. What's the plan for attacking this? Splitting up structures into individual variables won't help with this case. -- Aras Pranckevičius work: http://unity3d.com home: http://aras-p.info ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] glsl2: optimizing unused struct assignments
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Aras Pranckevicius wrote: > Hi, > > Currently GLSL2 optimizer can't remove assignments to struct members > that are never used. After inlining, the struct is often not passed to > any other functions as a whole; and some assignments to the members > might be useless. For example, in this fragment shader assignment to > s.unused could be optimized away. I guess then whole structure (of which > only s.used is left) could be replaced with just a float temporary: > > struct foo { > float used; > float unused; > }; > void main() { > float f = 1.0; > foo s; > s.used = f; > s.unused = f; > gl_FragColor = vec4(s.used); > } > > Right now GLSL2 optimizer optimizes the above into this (GLSL output): > > struct foo { > float used; > float unused; > }; > void main () > { > foo s; > s .used = 1.00; > s .unused = 1.00; > gl_FragColor = s .used .; > } > > > From the code, it seems that ir_variable_refcount only tracks references > to "whole variables" (in this case, whole struct), and not to individual > members. Any quick ideas / pitfalls how that can be extended, before I > try to figure it out myself? I believe the plan is to eventually break structures and arrays that are not variably indexed into individual variables. Your structure above would be broken into s_used and s_unused. The existing dead code paths would take care of s_unused. We'll need to do this break-up anyway to do proper register assignment. We'll have similar issue with code like: uniform vec4 angles; void main() { vec4 v; v.x = sin(angles.x); v.y = cos(angles.y); v.z = tan(angles.z); v.w = 1/tan(angles.w); gl_Position = v.xyxy; } In this case v.zw is never used, and the (expensive) assignments should be killed. -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkxYOXoACgkQX1gOwKyEAw+KMwCfU1z85ukV/HTvSsq3igqoRznG xC8AnjwjTtdb1glbmhzkNgARa3aZz/VA =Qerv -END PGP SIGNATURE- ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] glsl2: optimizing unused struct assignments
Hi, Currently GLSL2 optimizer can't remove assignments to struct members that are never used. After inlining, the struct is often not passed to any other functions as a whole; and some assignments to the members might be useless. For example, in this fragment shader assignment to s.unused could be optimized away. I guess then whole structure (of which only s.used is left) could be replaced with just a float temporary: struct foo { float used; float unused; }; void main() { float f = 1.0; foo s; s.used = f; s.unused = f; gl_FragColor = vec4(s.used); } Right now GLSL2 optimizer optimizes the above into this (GLSL output): struct foo { float used; float unused; }; void main () { foo s; s .used = 1.00; s .unused = 1.00; gl_FragColor = s .used .; } >From the code, it seems that ir_variable_refcount only tracks references to "whole variables" (in this case, whole struct), and not to individual members. Any quick ideas / pitfalls how that can be extended, before I try to figure it out myself? -- Aras Pranckevičius work: http://unity3d.com home: http://aras-p.info ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev