Drawing with a nullptr vertex and index buffer in D3D11

Started by
18 comments, last by Hodgman 6 years, 7 months ago

Apparently, you can render a quad directly in d3d10< without using vertices and indices. The approach is:

"In order to render a full screen quad, you will need to set both index and vertex buffers to null. Set the topology to triangle strip and call Draw with four vertices starting from position zero."


device_context->IASetVertexBuffers(0, 1, nullptr, {???}, {0});

device_context->IASetIndexBuffer(nullptr, ???, 0);

device_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);

device_context->Draw(4, 0);

What index format and stride size do you need to use?

 

Is it a good practice to use this approach for other "frequently" used meshes as well (such as a cube of lines for visualizing bounding boxes)?

🧙

Advertisement

You don't need to unbind the buffers, just the input layout. And also make sure that your shaders don't try to access the buffers. Skip the vertex buffer read by leaving the input parameters of the vertex shader. You can still use system generated attributes like SV_VertexID or SV_InstanceID. You can skip reading the index buffer by just calling a regular Draw() instead of DrawIndexed().

I am using this technique very frequently, for debug geometries, full screen triangles (better than full screen quad!) and deferred light volumes for example.

6 minutes ago, turanszkij said:

better than full screen quad!

What do you mean with "better"? You need the quad for the unpacking in deferred shading?

 

8 minutes ago, turanszkij said:

You don't need to unbind the buffers, just the input layout

And the Topology?

Assuming, I have a VS with signature VS(SV_VertexID), couldn't I just use the InputLayout obtained while creating the VS? Or does it have to be nullptr? 

🧙

You will still need a correct topology, that is something you can't unbind. You are probably good with the input layout reflected from the shader, though I am not used to doing that. I have few layouts which I create by hand and shared across different shaders.

A full screen triangle is also good for unpacking the deferred G-buffer, and even better than a quad because a quad has worse pixel occupancy along the intersection of triangles. This means that the pixel shader could be running on pixels which will be discarded later (these are called helper pixels because pixel shaders actually run in 2x2 pixel blocks so that derivatives can be obtained for instance). Though it probably is not a real problem. :) 

23 minutes ago, matt77hias said:

What do you mean with "better"? You need the quad for the unpacking in deferred shading?

Look at fullscreen triangle here: 

It also has the null vertex buffer trick, but no example.

-potential energy is easily made kinetic-

This is all pretty standard, you just use sv_vertexid and build whatever you want from it :

 

1 hour ago, turanszkij said:

You will still need a correct topology, that is something you can't unbind. You are probably good with the input layout reflected from the shader, though I am not used to doing that. I have few layouts which I create by hand and shared across different shaders.

A full screen triangle is also good for unpacking the deferred G-buffer, and even better than a quad because a quad has worse pixel occupancy along the intersection of triangles. This means that the pixel shader could be running on pixels which will be discarded later (these are called helper pixels because pixel shaders actually run in 2x2 pixel blocks so that derivatives can be obtained for instance). Though it probably is not a real problem.  

The triangle trick does not apply anymore, it was a ps3/x360 era trick. GPUs this days apply the triangle clipping earlier and you end up with two triangle anyway.

49 minutes ago, galop1n said:

The triangle trick does not apply anymore, it was a ps3/x360 era trick. GPUs this days apply the triangle clipping earlier and you end up with two triangle anyway.

Are you sure about that?  Do you have a source?  The document I posted was from 2013 and 14... it must've still been relevent.  Also aren't triangles rasterized in tiles?  Implying that when the triangle trick is used it stays one triangle.

-potential energy is easily made kinetic-

5 hours ago, Infinisearch said:

Are you sure about that?  Do you have a source?  The document I posted was from 2013 and 14... it must've still been relevent.  Also aren't triangles rasterized in tiles?  Implying that when the triangle trick is used it stays one triangle.

I do not have anything public that i can think off, this is knowledge from observing gpu counters with very detailed profiler at work. To tip it, the triangle trick was possible thanks to the guard band settings on x360/ps3, and it does not exist anymore. Of course, what i say i very AMD/GCN related, take it with a pinch of salt before transposing to nVidia or intel !

6 hours ago, galop1n said:

I do not have anything public that i can think off, this is knowledge from observing gpu counters with very detailed profiler at work. To tip it, the triangle trick was possible thanks to the guard band settings on x360/ps3, and it does not exist anymore. Of course, what i say i very AMD/GCN related, take it with a pinch of salt before transposing to nVidia or intel !

That's not my experience of full-screen triangles on GCN.

Using probably the same tools you're talking about, I can see that a single full-screen triangle at 1080p on an Xbox One generates exactly 32,400 waves and the Radeon RGP Profiler measures exactly 14,400 waves for a 720p full-screen triangle on PC.

Two triangles produces 14,433 waves for 720p on PC and 32,446 waves for 1080p on Xbox.

YMMV on other consoles, but it's not an AMD/GCN thing, and it's definitely not true to say it won't work on AMD GPUs on Windows.

Adam Miles - Principal Software Development Engineer - Microsoft Xbox Advanced Technology Group

1 hour ago, ajmiles said:

14,400 waves for a 720p full-screen triangle on PC.

What is one wave?

🧙

This topic is closed to new replies.

Advertisement