Jump to content
  • Advertisement
Sign in to follow this  
Volgogradetzzz

How to get patch id in domain shader.

This topic is 814 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Greetings,

 

In my domain shader I want to sample a structured buffer with current patch id. I specified SV_PrimitiveID as input parameter but the value is 0 for all patches. And to be honest I don't see how the pipeline can provide a patch id if I draw each patch with separate draw call (DrawIndexedInstanced()). But the documentation says I can use it for patch id.

Share this post


Link to post
Share on other sites
Advertisement

SV_PrimitiveID always starts at 0 for every draw call, and then increases for every primitive processed as part of that draw call. So if you only every draw 1 primitive per draw, then it's always going to be 0. If you need some sort of global ID, then you'll need to provide an offset in a constant buffer.

Share this post


Link to post
Share on other sites
Also, drawing each path in its own DrawCall sounds incredibly inefficient. You need to provide at least 256 vertices per draw call to fully utilize the vertex shader.

Share this post


Link to post
Share on other sites

Also, drawing each path in its own DrawCall sounds incredibly inefficient. You need to provide at least 256 vertices per draw call to fully utilize the vertex shader.

I thought it was 64 vertices to fully utilize the vertex shader and 256 to not become command processor limited.

 

edit - for amd.

Edited by Infinisearch

Share this post


Link to post
Share on other sites

Thank you @MJP. That make sense. And actually documentation says that though I had to read it several times to understand.

 

@Matias is it still true if I have a pass-through vertex shader?

 

And maybe you can help me with my scenario. I have a big buffer with all control points. A have several index buffers for patches. Some patches should be drawn multiple times with different transformation. So if I want to draw everything in one call I have to duplicate indices. Right now I'm drawing each patch in it's own draw call and for patches that need to be drawn multiple times I'm using instancing. Here's a problem - for each new instance SV_PrimitiveID resets to 0. SV_InstanceID is not available in hull/domain shader and I have to pass it from vertex shader unnecessary duplicating data. Looks like instancing not works very well with tessellation.

Share this post


Link to post
Share on other sites

 

Also, drawing each path in its own DrawCall sounds incredibly inefficient. You need to provide at least 256 vertices per draw call to fully utilize the vertex shader.

I thought it was 64 vertices to fully utilize the vertex shader and 256 to not become command processor limited.
 
edit - for amd.

 

AMD's wavefront size is of 64, that's true, but there are some inefficiencies and overhead details, such as needing 3 vertices to make a triangle (e.g. 64 triangles x 3 = 192 vertices assuming no tri shares any vertex). Real world testing shows on average you get near optimum throughput at >= 256 vertices per draw.
Edit. See http://www.g-truc.net/post-0666.html
 

@Matias is it still true if I have a pass-through vertex shader?

Yep.

Edited by Matias Goldberg

Share this post


Link to post
Share on other sites

Thank you @MJP. That make sense. And actually documentation says that though I had to read it several times to understand.

 

@Matias is it still true if I have a pass-through vertex shader?

 

And maybe you can help me with my scenario. I have a big buffer with all control points. A have several index buffers for patches. Some patches should be drawn multiple times with different transformation. So if I want to draw everything in one call I have to duplicate indices. Right now I'm drawing each patch in it's own draw call and for patches that need to be drawn multiple times I'm using instancing. Here's a problem - for each new instance SV_PrimitiveID resets to 0. SV_InstanceID is not available in hull/domain shader and I have to pass it from vertex shader unnecessary duplicating data. Looks like instancing not works very well with tessellation.

 

Have you considered putting your control point data into a resource that can be read by a shader (i.e. constant buffer or a structured buffer)?  That would allow you to have a very small vertex format (like a single integer offset) and you can just update your vertex buffer to indicate which set of control points you want each instance to use, and then utilize one of the basic draw calls instead of real instancing.  That should keep your primitive ID sequential, while still offering the reuse of most of your data without bloating.

 

Also, maybe I missed it, but what are you using the primitive ID for?  Is a unique value within the domain/hull shader needed?

Share this post


Link to post
Share on other sites
Hi Jason, it's a good solution, thank you. But if I understood you correctly, your approach is basically the same as drawing with indices. If I would have a set of points as one constant/structured buffer, I have to pass the id of a point as a vertex data, right? So, drawing the same patch multiple times will require to duplicate vertices.

And I need a unique sequential patch id for coloring entire patch. So in domain shader a could sample structured buffer of colors.

Share this post


Link to post
Share on other sites

That's right, but each vertex would only contain a single index into your structured buffer.  So even if you had to repeat a vertex, it would be relatively low cost.  If you have a way to generate the desired indices when given a sequential value, you could always use an empty vertex type and just generate the vertices on the fly in the vertex shader.  That would be super low cost, and you can easily expand the vertex data as needed throughout the pipeline (i.e. in the VS, DS, and HS).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!