Search code examples
windowswinapidirectxdirectx-11

DirectX 11 - Drawing multiple viewports RSSetViewports with an array of CD3D11_VIEWPORT


I've set up my vertex shader and my pixel shader. I then created a vector to represent my viewports (4 in total in this case):

std::vector<CD3D11_VIEWPORT> view_ports;

I've populated the vector and all 4 elements have the same default values:

view_port.Width = 400;
view_port.Height = 300;
view_port.MinDepth = 0;
view_port.MaxDepth = 1;

The only values that differ are the TopLeftX and TopLeftY since I want each view port in a different position.

Now if I call RSSetViewports and DrawIndexed like below, it only draws one of the view ports why is that? RSSetViewports is supposed to accept multiple viewports based on its description.

pContext->RSSetViewports( view_ports.size(), view_ports.data() )
pContext->DrawIndexed( static_cast< UINT > ( std::size( indices ) ), 0u, 0u )

If I do it like this however it does work and draws all 4 viewports:

pContext->RSSetViewports( 1u, &view_ports[0] );
pContext->DrawIndexed( static_cast<UINT> ( std::size( indices ) ), 0u, 0u );
pContext->RSSetViewports( 1u, &view_ports[1] );
pContext->DrawIndexed( static_cast<UINT> ( std::size( indices ) ), 0u, 0u );
pContext->RSSetViewports( 1u, &view_ports[2] );
pContext->DrawIndexed( static_cast<UINT> ( std::size( indices ) ), 0u, 0u );
pContext->RSSetViewports( 1u, &view_ports[3] );
pContext->DrawIndexed( static_cast<UINT> ( std::size( indices ) ), 0u, 0u );

if you look at the arguments of RSSetViewports

void RSSetViewports(
  [in]           UINT                 NumViewports,
  [in, optional] const D3D11_VIEWPORT *pViewports
);

It does take an array of viewports, can't I just call it once with my vector like so?:

pContext->RSSetViewports( view_ports.size(), view_ports.data() )

Why is this happening?


Solution

  • According to the Simon Mourier's suggestion:

    You need to use SV_ViewportArrayIndex semantic in a geometry shader.

    According to the Doc:ID3D11DeviceContext::RSSetViewports

    Which viewport to use is determined by the SV_ViewportArrayIndex semantic output by a geometry shader; if a geometry shader does not specify the semantic, Direct3D will use the first viewport in the array.