Handling depth sorting key and hardware instancing

Started by
21 comments, last by Adaline 11 years ago

Is it even possible ?

I'm creating draw calls as a pair of <sort key, ptr to draw call data> which I then sort after the key that stores my depth (32bit unsigned integer). Now as I would create a draw call for let's say an instance of 10000 objects how would I be able to sort these 10000 objects after their depth when it's just a single draw call that I'm creating.

Advertisement

It does not work that way. You have no guarantee on the order of execution (much less on the order of completion) inside a single draw-call.

It's really simple. Multiple execution units --> race conditions. You see those GPU blocks on every article each time a new GPU is released.

The only decent way to do order-independant-transparency is using D3D11 linked lists in my opinion.

edit: wrong!

Previously "Krohm"

What are you trying to accomplish with this? I have to agree with Krohm, there is no way to sort the order that your instances are going to be rendered, unless you are directly using an explicit sorting mechanism (i.e. depth sorting with a depth buffer!). Depending on what you are trying to do, there might be some alternative suggestions that we could make...

Well I'm trying to sort my draw calls. But in that case it seems I will have to give up on sorting them. I just find it interesting that in the frostbite 2.0 paper they say that they just assume everything as instanced. So they also just give up on sorting opaques front to back?

Don't they use a variant of deferred rendering? If so, then it is very likely that they do a depth pre-pass which would make it not so important to have depth sorting. I haven't read through the paper yet though - do you have a link to it?

I'm having a similar problem now with opaque / transparent objects. In a deferred renderer I'd render them seperately as a forward pass after the opaque + lighting, correct? But what happens if there's 200 of the same plane, but 1 of them is now being changed (by the user) to be transparent.

So before I had an instancegroup of 200 objects. The only solution would be to remove this object from the previous instance group and add it to a new one I guess ? But then I'd have to always check for every object if it has changed from opaque to transparent during runtime. This sounds very complicated...

It does not work that way. You have no guarantee on the order of execution (much less on the order of completion) inside a single draw-call.

It's really simple. Multiple execution units --> race conditions. You see those GPU blocks on every article each time a new GPU is released.

The only decent way to do order-independant-transparency is using D3D11 linked lists in my opinion.


The order that a primitive is rasterized and written to a render target is the same as the order in which you submit those primitives. This is part of the DX spec, and is guaranteed by the hardware. In fact the hardware has to jump through a lot of hoops to maintain this guarantee while still making use of multiple hardware units. This means that if you were able to perfectly sort all primitives in a mesh by depth, you would get perfect transparency. The same goes for multiple instances in a single draw call. The only case that's totally impossible to handle without OIT is the case of intersecting primitives.

It does not work that way. You have no guarantee on the order of execution (much less on the order of completion) inside a single draw-call.

It's really simple. Multiple execution units --> race conditions. You see those GPU blocks on every article each time a new GPU is released.

The only decent way to do order-independant-transparency is using D3D11 linked lists in my opinion.


The order that a primitive is rasterized and written to a render target is the same as the order in which you submit those primitives. This is part of the DX spec, and is guaranteed by the hardware. In fact the hardware has to jump through a lot of hoops to maintain this guarantee while still making use of multiple hardware units. This means that if you were able to perfectly sort all primitives in a mesh by depth, you would get perfect transparency. The same goes for multiple instances in a single draw call. The only case that's totally impossible to handle without OIT is the case of intersecting primitives.

Are you sure about this behavior? How can this be assured when multiple primitives are being rasterized in parallel? There is also some gray area regarding generated primitives too (via tessellation or the geometry shader) as they can be generated in parallel instances of the shaders...

I have always heard that the order is roughly equivalent to the order they are submitted in, but that they are explicitly not guaranteed to be processed in exact order.

I have always heard that the order is roughly equivalent to the order they are submitted in, but that they are explicitly not guaranteed to be processed in exact order.

It is guranteed at least at successive Pass::Begin Pass::End encapsuled instructions, but I have tested multiple DrawIndexedPrimitive in one pass (to save some overhead), and it was successive I can tell (since I did stencil shadow 2 back front passes). But as you said, I am not sure of this, and it seems I will implement it in 2 passes, to avoid breaking my game on some GPUs or drivers. Do not know, I cannot test profile all GPUs and I just don't trust them, I wanna sleep well. Interesting topic.

It does not work that way. You have no guarantee on the order of execution (much less on the order of completion) inside a single draw-call.

It's really simple. Multiple execution units --> race conditions. You see those GPU blocks on every article each time a new GPU is released.

The only decent way to do order-independant-transparency is using D3D11 linked lists in my opinion.


The order that a primitive is rasterized and written to a render target is the same as the order in which you submit those primitives. This is part of the DX spec, and is guaranteed by the hardware. In fact the hardware has to jump through a lot of hoops to maintain this guarantee while still making use of multiple hardware units. This means that if you were able to perfectly sort all primitives in a mesh by depth, you would get perfect transparency. The same goes for multiple instances in a single draw call. The only case that's totally impossible to handle without OIT is the case of intersecting primitives.

Are you sure about this behavior? How can this be assured when multiple primitives are being rasterized in parallel? There is also some gray area regarding generated primitives too (via tessellation or the geometry shader) as they can be generated in parallel instances of the shaders...

I have always heard that the order is roughly equivalent to the order they are submitted in, but that they are explicitly not guaranteed to be processed in exact order.


Definitely. You're never guaranteed about the order in which vertices/primitives/pixels are processed in the shader units, but the ROPS will guarantee that the final results written to the render target match the triangle submission order (which is often done by buffering and re-ordering pending writes from pixel shaders). This is even true for geometry shaders, which is a big part of what makes them so slow.

This topic is closed to new replies.

Advertisement