[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#423739: libgl1-mesa-dri: banding in rendering when using blending for transparency



Hi, Michel,

I think I may have a lead on the blending problems with the r200 DRI
driver.  The problem seems to go away if I apply the attached patch to
Mesa-6.5.3.  This seems to work when tested under gcc 4.1.3 or 4.2
(20070528).


Open questions include:

- Is the "0" usage in "asm" statements a gcc-specific extension?  If
so, would this break x86 r200 DRI on non-gcc compilers, if any such
are used?

- Lots of other DRI drivers use spantmp2.h, why wouldn't this have
shown up broken in these by now, if this were really the problem?



Here's the reasoning behind the patch, spelled out in case it is utterly wrong:

The patch is to make the 32-bit color buffer READ_RGBA macro, in its
x86-assembly variant, know that the input parameter of the "bswap"
instruction resides in the same register as the output parameter
(change the "r" to a "0" for the input).

Looking at the assembly code of r200ReadRGBAPixels_ARGB8888 (generated
by dri/r200/r200_span.c via dri/common/spantmp2.h) the patched code
generates something like:

mov    %eax,0xffffffd0(%ebp)
bswap  %eax
ror    $0x8,%eax

while the unpatched code, when compiled -O2, loses the initial "mov"
instruction and hence the %eax register is actually never even
initialized...  This would also explain why turning off register-move
optimizations is another way to fix the problem.

Which follows from the gcc docs:

Only a number in the constraint can guarantee that one operand will be
in the same place as another.  The mere fact that `foo' is the value of
both operands is not enough to guarantee that they will be in the same
place in the generated assembler code.


Thanks very much if this is of use...

Dan
--- src/mesa/drivers/dri/common/spantmp2.h.orig	2007-06-04 01:32:13.000000000 -0400
+++ src/mesa/drivers/dri/common/spantmp2.h	2007-06-04 01:36:36.000000000 -0400
@@ -114,7 +114,7 @@
     do {                                                                \
         GLuint p = *(volatile GLuint *) GET_PTR(_x, _y);                \
        __asm__ __volatile__( "bswap	%0; rorl $8, %0"                \
-				: "=r" (p) : "r" (p) );                 \
+				: "=r" (p) : "0" (p) );                 \
        ((GLuint *)rgba)[0] = p;                                         \
     } while (0)
 # elif defined( MESA_BIG_ENDIAN )

Reply to: