[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 
scaled/normalized.

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 
components.

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.

--Ken


More information about the mesa-dev mailing list