4
\$\begingroup\$

I was studying some technical documentation on the Intel HD Graphics 3000 GPU, which I'm using as a lower-end reference for my 2D game engine. I noticed the hardware supports a nice "Quad List" topology, where every 4 vertices in a vert buffer are interpreted as an independent quad. My engine draws nothing but sprite quads, so that would be a nice optimization in my case, to eliminate the need for copying / caching / processing an accompanying index buffer with 12 bytes per quad of trivial triangle edge definitions (I'm using indexed TriangleList primitives at the moment).

From what I can tell though, DirectX 9 doesn't expose quad list, and after some cursory peeking around in DX10/11 (which I don't plan to support at this point) it seems they don't expose this feature either.

Does anyone know if there's a way to use Quad Lists in DirectX? I'd be curious about OpenGL also, if anyone has experience on that side.

\$\endgroup\$
  • \$\begingroup\$ Where is this documentation you're looking at? It's likely got the answer in it. \$\endgroup\$ – Josh Mar 26 '15 at 16:12
  • 1
    \$\begingroup\$ Pages 11 & 16 of this manual describe it: 01.org/linuxgraphics/sites/default/files/documentation/… - it's a low level manual intended for driver writers though, so doesn't talk about DirectX/OpenGL etc. \$\endgroup\$ – QuadrupleA Mar 26 '15 at 16:16
7
\$\begingroup\$

There's no documented way to do this in Direct3D; it simply does not have support at the API level for quads as a primitive type.

D3D doesn't have an extension mechanism like OpenGL does, but in some cases driver vendors support enabling certain kinds of "extended" features by passing certain combinations of invalid or otherwise-nonsense parameters to certain APIs. If this is the case for this GPU, you'll likely find the information you need in the GPU documentation, not the D3D documentation.

It's also possible that the card simply supports this primitive type internally as a optimization or a bootstrapping phase of certain kinds of higher-order primitive or tessellation support.

It's also possible that this is simply a legacy mode left over from, and still existing to support, older OpenGL versions (which had a quad primitive type), or for use with other more specialized APIs than D3D and OpenGL.

\$\endgroup\$
5
\$\begingroup\$

While D3D doesn't support quad primitives, there's nothing in principle wrong with continuing to draw them as a triangle list.

First thing to realise is that the index buffer used to simulate quads with a triangle list can always remain static, so you can create it once only (during startup), then just reuse it every time you wish to draw. The code to generate it is utterly trivial:

unsigned int *ndx = // pointer to memory returned by ID3DIndexBuffer9::Lock; change to unsigned short for 16-bit indices

// MAX_QUAD_VERTS should be a multiple of 4 and be 4 times the maximum number of quads you draw
for (int v = 0; v < MAX_QUAD_VERTS; v += 4, ndx += 6)
{
    ndx[0] = v;
    ndx[1] = v + 1;
    ndx[2] = v + 2;

    ndx[3] = v;
    ndx[4] = v + 2;
    ndx[5] = v + 3;
}

Using this index buffer you can then pass the exact same vertices to your vertex buffer as if you were drawing quads natively and get the same result.

This will also have the advantage of working the very same (and using the very same code) on hardware that doesn't support quads natively. Even on hardware that does support quads natively it may provide better performance as hardware and drivers are more likely to be optimized around drawing indexed triangle lists.

OpenGL does support quad lists and quad strips but they're deprecated in modern core contexts.

\$\endgroup\$
  • \$\begingroup\$ Thanks - that's been on my list, to pre-calculate the index buffer, since it is identical for all draw calls. \$\endgroup\$ – QuadrupleA Mar 26 '15 at 21:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.