[Bug 29137] [r300g] troubles with wine and "r300: Max size of the constant buffer is 256*4 floats."

bugzilla-daemon at freedesktop.org bugzilla-daemon at freedesktop.org
Sat Aug 21 06:02:32 PDT 2010


https://bugs.freedesktop.org/show_bug.cgi?id=29137

--- Comment #13 from Henri Verbeet <hverbeet at gmail.com> 2010-08-21 06:02:33 PDT ---
(In reply to comment #12)
> Henri,
> 
> I was thinking about this issue and realized that the way you allocate constant
> space in wine is wrong. The problem is you create one large array "uniform vec4
> VC[256]". If this array is addressed indirectly, that is using e.g.
> VC[index+20] where "index" cannot be evaluated at compile time, we must assume
> *any* element in the array may potentially be used and therefore we cannot
> eliminate unused elements, because there appears to be none.
>
Yes, but that's because of the way d3d9 works. I.e., you just have one big
block of 256 float constants (in SM2 and SM3, SM1 only requires 96). Direct3D
10 and 11 constant buffers are much nicer in that regard. The problem is that
wined3d needs a couple of extra constants for its own fixups, and often the
driver needs a couple as well.

For shaders where no relative addressing is used, wined3d could declare
separate uniforms instead of one big array. We'll probably make that change in
the near/medium future, unless changes in Mesa make it a non-issue for us. I
nevertheless think it would be a valid enhancement to the Mesa GLSL compiler to
make that observation on its own.

> We can do the optimization if there is no indirect addressing, but we cannot do
> this for all cases and say "it's fixed once and for all".
Similarly, wined3d can't split up the d3d9 constant array when relative
addressing is used. This is not just a problem with Mesa for us, it affects
e.g. fglrx and pre-GF8 nvidia hardware as well. The reason this isn't much of
an issue on GF8+ nvidia hardware is that it simply reports 4096 uniforms as
being available. Extensions like NV_shader_buffer_load suggest GF8+ hardware
can simply access arbitrary buffer objects / video memory from a shader.

The workaround we use when relative addressing is used by a shader is to simply
subtract our internal constants, in addition to our (most likely flawed)
estimate of what the driver itself needs, from the number of constants
available to the application. This breaks down when applications allocate from
the end of the range of available constants. I.e., using c[255] while at the
same time using relative addressing for e.g. vertex blending.
http://bugs.winehq.org/show_bug.cgi?id=17818 is an example of a bug caused by
this.

In short, I don't expect Mesa to be able to do much, if anything, to help solve
this. There may be some things we can try on the Wine side though. For example,
on hardware the supports immediate constants like r600 we could take advantage
of that and just hardcode our fixups into the shaders, and have multiple
versions of the shader instead. These fixups are things like compensating for
differences in pixel center between d3d9 and GL, or texture origin when
rendering to an FBO, which at least some drivers will have to do themselves
anyway, but the other way around. If we get lucky they may even cancel out and
get optimized away. The y-flip when rendering to FBO is especially sad, because
it ends up being a multiplication by -1.0, which would often be free as a
negate. The other way out is that while we can't determine which uniforms are
read by the shader, we can determine which ones are set by the application.
Constants that are never set would be our best bet for stuffing our own fixups
in, although that strategy depends on the application really treating those as
undefined, rather than relying on them being set to e.g. 0.0.

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.


More information about the dri-devel mailing list