Thanks, that is a quite reasonable answer, I lost track of the fact that mobile IHVs are on-board and might lag hardware capabilities for the core spec.
[QUOTE=Alfonse Reinheart;39942]OK, but that’s not what transform feedback does, so I don’t see how that matters. As I’m sure you’re aware, transform feedback is about marking outputs from a GS to be recorded into a buffer(s). This can be very easily done from a geometry shader.
It has nothing to do with removing any “Elements” from a buffer.[/QUOTE]
It does obviously not remove but copy arbitrary data in order into another buffer consecutively.
[QUOTE=Alfonse Reinheart;39942]The source of my knowledge is thinking about the tools Vulkan provides.
OK, every time you call EmitVertex
in a GS that’s using transform feedback, the implementation takes the data in your output variables and writes them to the various buffers bound for feedback. That’s something that you can do yourself by writing to an SSBO. The only issue is figuring out where in the SSBO’s array to write to. This will be based on your particular invocation, relative to other GS invocations in the rendering command.
That’s where PrimitiveID
comes in. If your GS writes 3 vertices in each GS invocation, then you know that the invocation for PrimitiveID 0 will write to locations 0, 1, and 2 in the SSBO array. PrimitiveID 3’s invocation will write to locations 9, 10, and 11. And so forth.
If you’re instancing your GS, then you need to multiply PrimitiveID with InvocationID.
Now, if you’re conditionally writing with your GS, then we need to talk a bit more about what data you’re conditionally writing. If the data you’re writing is unordered (that is, it doesn’t really matter what order you write i in, so long as it’s tightly packed. This is common for frustum culling), then you can use an atomic counter to compute the index. Each invocation increments the atomic counter if it is going to write data.
Of course, if you don’t need order, then you ought to be using a compute shader. Don’t pretend frustum culling is a rendering operation.[/QUOTE]
Nice, that will work, thanks! However, I do assume that desktop GPUs have more optimal hardware support for the general concept of append/consumeBuffers, other then emulating it with Atomics in the driver, no?
[QUOTE=Alfonse Reinheart;39942]It’s the usual reason why ARB extensions aren’t instantly part of core OpenGL. It’s why ARB_sparse_texture and ARB_bindless_texture never made it to core: because not all 4.x hardware can support it.
Shader draw parameters requires that an implementation be able to provide 3 pieces of data to the VS:
-
The base instance value. Since Vulkan uses InstanceIndex
instead of InstanceID
, this is unnecessary. The InstanceIndex
has the base instance added to it already, so the shader doesn’t need a separate value for the base instance.
-
The base vertex index. Again, since VertexIndex
already includes the base vertex index, there’s no need for a separate value.
-
A counter that increments for each drawing command. That one requires hardware support, since it must also work via vkCmdMultiDrawIndirect.
So Vulkan already has 2/3rds of the data. And the last 1/3rd requires direct hardware support. Admittedly, they could have added that as an optional feature, but at some point, you’ve got to ship the thing out the door. DrawID
alone isn’t all that important.
Especially since Vulkan only permits multidraw operations with indirect rendering commands. So if you need the equivalent of DrawID
, you can always use the base instance if the hardware allows it.[/QUOTE]
I was not aware that it is not trivial to add a DrawID as build in shader if multiDrawIndirect is available. For me its a really nice to have feature, but I think it will be one of the early extensions to come, at least for desktop GPUs.