[Mesa-dev] [RFC PATCH] Add support for ARB_vertex_type_2_10_10_10_rev on i965

Kenneth Graunke kenneth at whitecape.org
Sun Oct 14 11:29:10 PDT 2012

On 10/14/2012 01:12 AM, Chris Forbes wrote:
>> On Sun, Oct 14, 2012 at 8:52 PM, Kenneth Graunke <kenneth at whitecape.org> wrote:
> Right, suspected as much -- although hoped the situation was better
> than that, since the Sandybridge PRM mentions a lot of these in the
> format conversion table.
> OK, so I need to hack the shader compiler to emit swizzles to handle
> BGRA, and scaling for a bunch of the other cases?
> -- Chris

Yeah, sadly.  Take a look at how we handle GL_FIXED rescaling for 
ES1---it's a similar case where the hardware doesn't support the 
incoming attribute format, so we need to do emit extra instructions at 
the top of shaders to convert it.

This should involve a few steps:

1. Pick a supported format in brw_draw_upload.c/get_surface_type().

I'd focus on using R10G10B10A2_UINT.

2. Flag the need for a shader workaround in the VS program key.

You'll need to add some new flags to struct brw_vs_prog_key in brw_vs.h, 
and set them in brw_vs.c's brw_upload_vs_prog() function.
There's already code there for GL_FIXED handling...you'll probably need 
something similar.  You might need fancier/multiple flags, though, since 
you're trying to fix-up BGRA/RGBA, signed/unsigned issues, and 

3. Emit shader code to fix up attributes.

Unfortunately, we still have separate VS backends for GLSL and 
fixed-function/ARB programs, so you'll need to do this in two places. 
(I'm working on killing the old one, but haven't finished it yet...)

Piglit's draw-vertices-2101010 test doesn't use GLSL, so to see any 
changes there, you'll need to update the old backend in brw_vs_emit.c. 
See the brw_vs_rescale_gl_fixed() function.

Once you have that working, you could port it to the new backend.  The 
code for that is in brw_vec4_visitor.cpp, in the 
vec4_visitor::visit(ir_variable *ir) method.  Again, look for GL_FIXED.

Suggestions for the shader code:

If you upload data as R10G10B10A2_UINT, then it should show up as four, 
32-bit unsigned integer values in the .x, y, z, and w components of your 
vec4 attribute.  The top 22 bits (or 30 bits for .w) should be zero.

When you need signed data, you can recover it via:

MOV temp.xyz:ud 22u
MOV temp.w:ud 30u
SHL reg.xyzw:ud reg.xyzw:ud temp.xyzw:ud
ASR reg.xyzw:d reg.xyzw:d temp.xyzw:ud

This moves your 10-bit value 22 bits to the left (or 2-bit value 30 bits 
left) so that the top bit is in the sign bit position, reinterprets it 
as a signed integer, and then shifts it back to its original position, 
doing sign extensions.

Fixing up BGRA should be a simple MOV:
MOV reg.xyzw:ud reg.zyxw:ud // swap x and z (reg type is irrelevant)

You'll need to then convert it to SCALED/NORM.

To reinterpret a register's bits as a float, you can simply refer to it 
with BRW_REGISTER_TYPE_F.  If you want to actually convert the integer 
value to a float (i.e. 200 -> 200.0f), you can do a MOV:

MOV reg.xyzw:f reg.xyzw:d // or maybe ud

I imagine normalization could be handled with MUL and ADD.

Picking formats

I did a bit of reverse engineering of what the other driver does for the 
subcases of the Piglit draw-vertices-2101010 test:

Int vertices - 2/10/10/10:
- R10G10B10A2_UINT format
- shl/asr hack in shaders

Unsigned Int vertices - 2/10/10/10:
- R10G10B10A2_UINT format
- a simple MOV reg.xyzw:f reg.xyzw:ud (no shl/asr hack needed).

Int Color - 2/10/10/10

They're doing something really bizarre here...it almost looks like 
they're uploading it as both R10G10B10A2_UINT and 
R10G10B10_SNORM_A2_UNORM, trying to use the former to recover the sign 
bits on the A component.  They still have the shl/asr hack, but also a 
bunch of other stuff.  The assembly is still puzzling me.

I'm not sure why they don't just normalize the values in the shader 
doing MUL/ADD.  That seems simpler.

Unsigned Int Color - 2/10/10/10

Looks like they're uploading both R10G10B10A2_UINT and 
R10G10B10A2_UNORM.  Still use the shl/asr hack, but without nearly the 
shenanigans from the last case.

Still, this seems strange: just using UNORM ought to work fine!

Int BGRA Color - 2/10/10/10
Unsigned Int BGRA Color - 2/10/10/10

Exactly the same as the former two, but with a MOV to swap the z/x 

Int 2/10/10/10 - test ABI
Unsigned 2/10/10/10 - test ABI

I didn't get around to testing these.


Looks like this simple project got a lot more complicated. :(  Thanks 
for taking a look at it, Chris.  Don't hesitate to ask for help if you 
need anything.  I'll be offline the 17th through the 20th, but Eric 
should be able to help.


More information about the mesa-dev mailing list