Bug 65416 - r300g does not eliminate unread varyings
Summary: r300g does not eliminate unread varyings
Status: RESOLVED FIXED
Alias: None
Product: Mesa
Classification: Unclassified
Component: Drivers/Gallium/r300 (show other bugs)
Version: git
Hardware: Other All
: medium normal
Assignee: Default DRI bug account
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-06-05 13:26 UTC by Stefan Dösinger
Modified: 2013-07-13 15:34 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments
Example shaders (1.92 KB, text/plain)
2013-06-05 13:26 UTC, Stefan Dösinger
Details

Description Stefan Dösinger 2013-06-05 13:26:04 UTC
Created attachment 80344 [details]
Example shaders

r300g tries to interpolate varyings written by the vertex shader even if the fragment shader does not read them. The attached program code illustrates this with two sample shaders.

The shaders in question were generated by Wine's fixed function pipeline replacement, generated from a fixed function setup set up by 3DMark 2000.

The visible issues caused by this are broken fog because the driver runs out of varyings and reduced performance due to the extra shader instructions.

An argument could be made that this is Wine's bug, and it should not generate such inefficient shaders. Doing this would be a major inconvenience though because the vertex and fragment shader are generated independently. As far as I can see the proprietary drivers optimize this inefficiency away.
Comment 1 Stefan Dösinger 2013-06-05 13:30:56 UTC
Fwiw, I don't know if r600g is affected. The HW has enough varyings to run the unoptimized shaders, and the applications affected by this performance wise are CPU limited on my r600g system.

Wine has some checks to prevent writing texture coordinates in the vertex shader when there is no input to generate them. Unfortunately 3DMark 2000 and Unreal Tournament 2004 use a strange vertex processing setup that breaks those checks(D3DTSS_TEXCOORDINDEX of all texture stages is 0, thus they're reading the first texture coordinate input, which does exist).
Comment 2 Alex Deucher 2013-06-05 13:43:03 UTC
Couldn't this be done in a device independent manner in mesa when linking shaders?  Drop outputs if there is no matching input in the subsequent shader stage?
Comment 3 Marek Olšák 2013-06-06 01:17:03 UTC
I think the GLSL compiler only eliminates unused user-defined varyings, unused legacy varyings are not eliminated. I'm taking this task.
Comment 4 Stefan Dösinger 2013-06-06 13:29:52 UTC
Cool, thanks!
Comment 5 Marek Olšák 2013-06-12 19:05:53 UTC
I have implemented it, but there is a problem. If I enable the optimization, EXT_separate_shader_objects must be disabled. Is it okay with you?

This is a valid sequence with EXT_sso:
glUseProgram(prog_with_vs_and_fs);
glUseShaderProgramEXT(prog_with_fs);

prog_with_vs_and_fs cannot be optimized, because the program object can be bound partially (in this case only the vertex shader from the program object is bound).

ARB_separate_shader_objects doesn't have this issue.
Comment 6 Stefan Dösinger 2013-06-13 08:31:41 UTC
I guess that's ok for wined3d's purposes. We don't use either extension right now, and if we ever use one of them we'll probably go with the ARB one anyway.
Comment 7 Marek Olšák 2013-07-13 15:34:36 UTC
Fixed by a commit series which starts here: http://cgit.freedesktop.org/mesa/mesa/commit/?id=74edd56927801e8c646c7d5cddba397c2f54b4ef


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.