[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