3

I learned how to tie vertexbuffers to specific slots using IASetVertexVuffers. But then, when I learned DrawInstanced, I learned to select vertexs to draw using only the index of the starting vertex. I am wondering how this DrawInstanced selects vertex by calculating that index to the vertexbuffer of which slot. Or is it just an index that continues from slot 0 to the next slots? This question may be difficult to interpret because I am using the wrong English.

우현우
  • 45
  • 4
  • When using multi-stream rendering w/ ``D3D11_INPUT_PER_VERTEX_DATA``, then the one Index Buffer produces an index used for *all* slots in parallel. – Chuck Walbourn Nov 18 '20 at 20:46
  • Does that mean drawinstanced is applied to each vertex buffer of every slot? (If there are vertex buffers in two slots, are they applied to each buffer?) – 우현우 Nov 19 '20 at 09:53

2 Answers2

3

If you have multiple Vertex Buffers bound to multiple slots when you call Draw*, then they are used in parallel based on the current Input Layout.

If you are using DrawIndexed*, then the one bound Index Buffer is used to generate an index used for all Vertex Buffers bound with D3D11_INPUT_PER_VERTEX_DATA. I.e., they are treated like parallel arrays:

// This is psuedo-code!

Vertex0 vb0[nVerts];
Vertex1 vb1[nVerts];
Vertex2 vb2[nVerts];

uint32_t ib[nTris * 3];

Bind vb0 to slot 0, vb1 to slot 1, vb2 to slot 2 of Vertex Buffers
Bind ib to Index Buffer

// For DirectX 12, the input layout is part of the Pipeline State Object (PSO)
Bind an input layout that uses vertex data from from 3 slots

DrawIndexed
    foreach j in 0 to (IndexCount-1);
        index = ib[StartIndexLocation + j] + BaseVertexLocation
        assemble vertex from vb0[index], vb1[index], vb2[index]
        draw when you have enough vertices for the primitive

One of the challenges of using DirectX documentation is that typically each version starts from the assumption that you already know the previous version. Multi-stream rendering was introduced way back in DirectX 9, so that's the last time it was conceptually explained: Programming One or More Streams (Direct3D 9)

In DirectX 11, there are four Draw* methods:

void Draw( 
    UINT VertexCount,
    UINT StartVertexLocation);

void DrawInstanced( 
    UINT VertexCountPerInstance,
    UINT InstanceCount,
    UINT StartVertexLocation,
    UINT StartInstanceLocation);
    
// Uses an Index Buffer
void DrawIndexed( 
    UINT IndexCount,
    UINT StartIndexLocation,
    INT BaseVertexLocation);
   
void DrawIndexedInstanced( 
    UINT IndexCountPerInstance,
    UINT InstanceCount,
    UINT StartIndexLocation,
    INT BaseVertexLocation,
    UINT StartInstanceLocation);

DirectX 12 supports all the same functions, but does it all in two methods. If InstanceCount is 1, then it's not instanced:

void DrawInstanced(
  UINT VertexCountPerInstance,
  UINT InstanceCount,
  UINT StartVertexLocation,
  UINT StartInstanceLocation
);

// Uses an Index Buffer
void DrawIndexedInstanced(
  UINT IndexCountPerInstance,
  UINT InstanceCount,
  UINT StartIndexLocation,
  INT  BaseVertexLocation,
  UINT StartInstanceLocation
);

For information on using instancing, see the C++ sample SimpleInstancing: DX11 / DX12.

Acorn
  • 24,970
  • 5
  • 40
  • 69
Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81
  • Thank you very much I wrote what I understood in the answer. I would really appreciate it if you check it out. – 우현우 Nov 20 '20 at 10:14
0

I was mistaken that the element of the vertex buffer itself represents the actual vertex. The vertex elements themselves in the vertex buffer do not mean the actual vertices, but are only entities that contain some characteristics of the vertices that will be finally created. The elements of the vertex buffer are only information that is referenced to make the actual vertex corresponding to the index of the element by referring to the members of the elements as described in the inputlayout. For example, suppose there are vertex structures with 4 members in the vertex buffer in slot 0, and vertex structures with 2 members in slot 1, the 6 characteristics are synthesized by inputlayout to form a vertex and IA It is passed as an input parameter to the vertex shader (of course, only some of the six may be used). In addition, this is my opinion, but in the IA stage, only the relationship between the vertices is arranged and passed to the later stage, and the members of the vertex buffers are transferred from the vertex shader as described in the inputlayout and seem to be used in earnest.

우현우
  • 45
  • 4