[Mesa-dev] [PATCH-RFC] draw: Rewrite primitive decomposer

Chia-I Wu olvaffe at gmail.com
Tue Aug 3 08:41:02 PDT 2010


On Tue, Aug 3, 2010 at 9:40 PM, Zack Rusin <zackr at vmware.com> wrote:
> On Tuesday 03 August 2010 01:34:46 Chia-I Wu wrote:
>> On Tue, Aug 3, 2010 at 6:48 AM, Zack Rusin <zackr at vmware.com> wrote:
>> > On Monday 02 August 2010 12:33:50 Chia-I Wu wrote:
>> >> While studying the draw module, I noticed that multiple primitive
>> >> decomposers exist: draw_pt_vcache_tmp.h, draw_gs_tmp.h,
>> >> draw_so_emit_tmp.h, and draw_pt_decompose.h.  The differences between
>> >> them are small, yet some of them support primitive modes that others
>> >> don't.
>> > Yes, that's because they all operate on a different set of primitives and
>> > presence of any of the others should result in an assert since it
>> > signifies that something went seriously wrong.
>> draw_pt_vcache_tmp.h needs to handle primitive modes with adjacency.  When
>> GS is not active, draw_pt_decompose.h also needs to handle them.
> I'm not sure if should, if adjacency primitives are set there should always be
> a gs and if not we should set a pass-through gs should which just emits
> triangles.
There is no pass-through GS right now, but it is something I'd like to look
into after this change (and some tuning work).  It should be required by the
non-pipeline path.  Besides, as GS may output more vertices than its input, it
may be a problem if the number of output vertices exceeds vbuf_render's limit.
I'd like to see if they can be solved altogether.
>> With
>> OpenGL, GS never sees QUADS or POLYGON;  Stream output never sees those
>> modes with adjacency.
>
> Great.
>
>> There is FUNC_ENTER that is used to insert arbitrary code before the
>> decompose loop.  It is used by some decomposers to add assertions.  One
>> way is to use it to insert assertions like
>>
>>   if (mode == GL_QUADS || mode == GL_POLYGON /* || ... */) {
>>     assert(!"unexpected primitve type");
>>     return;
>>   }
> That sounds good.
>> >> As for PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY, the GS decomposer does not
>> >> seem to follow the vertex ordering of GL_TRIANGLE_STRIP_ADJACENCY.  I
>> >> write that part from scratch.  I am not 100% sure here as I don't have
>> >> a test case to verify.  It would be great if someone can clarify.
>> >
>> > That's very vague, what's not right? The only thing I see in the old code
>> > is that we possibly flip the first and second adjacency vertex.
>>
>> Sorry, I was not clear here.  It should be easier to describe with an
>> example.
>>
>> When there are 8 vertices, the two decomposed triangles should be
>>
>>   TRI_ADJ(0, 1, 2, 6, 4, 3);
>>   TRI_ADJ(4, 0, 2, 5, 6, 7);
>>
>> while the old code would emit
>>
>>   TRI_ADJ(0, 1, 2, 3, 4, 5);
>>   TRI_ADJ(2, 5, 6, 3, 4, 7);
>>
>> (Table 2.4 of glspec33.core.20100311.pdf)
>
> Ah, I see, yea, that's different from  D3D:
> http://msdn.microsoft.com/en-us/library/bb205124(VS.85).aspx
> please keep what's in there right now until we figure out the best way to
> switch that decomposition based on the api. The GL semantics look pretty
> messed up to me, why would 4 be a leading vertex twice? (for i=1 and i=2)
I don't think the current behavior is correct for D3D, if I understand the
diagram correctly.  The difference between D3D and OpenGL seems to be only in
the provoking conventions.  In the diagram, there are 14 vertices which will
generate 5 triangles

        vertices         adjacent verts
i=0      0,2,4             1,6,3
i=1      2,4,6             0,8,5
i=2      4,6,8             2,10,7
i=3      6,8,10            4,12,9
i=4      8,10,12           6,13,11

To have the correct winding direction, we should swap the vertices when i is
odd.

If D3D provoking convention is used, the last two vertices should be swapped so
that the provoking (leading) vertices are 0, 2, 4, and so on respectively.  As
a result of the swap, the first and the last adjacent vertices should also be
swapped.  This gives

        vertices         adjacent verts
i=0      0,2,4             1,6,3
i=1      2,6,4             5,8,0
i=2      4,6,8             2,10,7
i=3      6,10,8            9,12,4
i=4      8,10,12           6,13,11

which is exactly the diagram in the link.

If OpenGL provoking convention is used, the first two vertices should be
swapped so that the provoking vertex are 4, 6, 8, and so on respectively.  As a
result of the swap, the first and the last adjacent vertices should also be
swapped.  This gives

        vertices         adjacent verts
i=0      0,2,4             1,6,3
i=1      4,2,6             0,5,8
i=2      4,6,8             2,10,7
i=3      8,6,10            4,9,12
i=4      8,10,12           6,13,11

which is Table 2.4 in OpenGL 3.3 core profile.

-- 
olv at LunarG.com


More information about the mesa-dev mailing list