0
\$\begingroup\$

I was wondering what the InputAssembler does if the size of the bound buffers does not match the vertex count of the Draw() call.

I've seen the example at http://msdn.microsoft.com/en-us/library/windows/desktop/bb232912%28v=vs.85%29.aspx where the InputAssembler is used without any buffers, however, the vertex shader input is simply defined as

struct VSIn
{
    uint vertexId : SV_VertexID;
};

and I understand that SV_VertexID is filled in by the InputAssembler.

But what if I define the input as follows?

struct VSIn
{
    uint vertexId : SV_VertexID;
    float4 color : COLOR;
};

I tested this and it appears that input.color always returns the default value float4(0, 0, 0, 0). Is this expected behavior or might other drivers produce different results?

A more elaborate example: If I bind a buffer with ten positions to slot 0 and a buffer with five colors to slot 1 and render ten vertices, will the first five vertices have the color as defined in the color buffer and the other five have color zero? I tested this as well and this seems to be the case. Again, Is this expected behavior or might other drivers produce different results?

And even if i can to this, should I?

Background: I have "regular" vertex data which I bind to slot 0. In some (rare) cases I have additional data which I bind to slot 1. At the moment if I don't have additional data I will still generate a secondary buffer of equal size as the "regular" buffer filling it all with zeros. I was wondering if this is necessary or if I can simply set the secondary buffer to null and let the InputAssembler do the work.

Bonus question: Can I change the default value the InputAssembler uses if there is no buffer value?

\$\endgroup\$
1
\$\begingroup\$

If your actual vertex buffer differs in layout compared to what is set to the input assembler that is most likely undefined behaviour. In my opinion you only should do this extreme way you described if you can actually test this on multiple different hardware. For the first vertexID example which you show, you can use that input without any vertex buffer because vertexID comes from the draw call itself from the parameter vertexCount or indexCount. This way you generate SV_POSITION outputs from these values. This is usually used when rendering a full screen quad.

UPDATE: I just tried messing a bit with different vertex buffers and I was getting different results with an Nvidia and an Intel GPU, though not the exact case you suggested.

\$\endgroup\$
  • \$\begingroup\$ Thank you. I'd be interested what results you got when you tried this with different GPUs. \$\endgroup\$ – Roman Reiner Mar 19 '14 at 16:01
0
\$\begingroup\$

I just tried this with the debug layer enabled and I got the info:

D3D11 INFO: ID3D11DeviceContext::DrawIndexed: Element [1] in the current Input Layout's declaration references input slot 1, but there is no Buffer bound to this slot. This is OK, as reads from an empty slot are defined to return 0. It is also possible the developer knows the data will not be used anyway. This is only a problem if the developer actually intended to bind an input Buffer here. [ EXECUTION INFO #348: DEVICE_DRAW_VERTEX_BUFFER_NOT_SET]

which answers the first part of the question, and

D3D11 WARNING: ID3D11DeviceContext::Draw: Vertex Buffer at the input vertex slot 0 is not big enough for what the Draw*() call expects to traverse. This is OK, as reading off the end of the Buffer is defined to return 0. However the developer probably did not intend to make use of this behavior. [ EXECUTION WARNING #356: DEVICE_DRAW_VERTEX_BUFFER_TOO_SMALL]

which answers the second part of the question.

\$\endgroup\$

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.