Vulkan (vs.)? MultiDrawIndirect

[QUOTE=Alfonse Reinheart;40517]Actually, it does not. That’s a specific feature which you have to request. If multiDrawIndirect is not requested in your features, then maxIndirectDrawCount will be 1.

That’s wrong in several ways. gl_InstanceID is not gl_InstanceIndex. That’s why they changed the name. gl_InstanceID did not include the baseInstance from the draw command, while gl_InstanceIndex always does.

Also, gl_drawID has nothing at all to do with instancing. It is a count of the number of drawing commands in a multidraw command. You cannot compute it from instances alone, because each draw command can have a different instance count.[/QUOTE]

Thanks for correcting. Answered a bit too quick I guess :wink:

So I’d go with what Christophe wrote in his article and store the draw IDs manually.

[QUOTE=Sascha Willems;40518]Thanks for correcting. Answered a bit too quick I guess :wink:

So I’d go with what Christophe wrote in his article and store the draw IDs manually.[/QUOTE]

Actually, that doesn’t work. Well, it doesn’t work generally. I edited my answer to explain why.

Allow me to clarify all this.

If none of the drawing commands in your multidraw use instancing for anything, then you may have access to an additional per-draw parameter: firstInstance. I say “may” because this also requires an optional Vulkan feature: drawIndirectFirstInstance.

If that feature is active, then firstInstance can be something other than 0. If you’re not using instancing for something, then you can set that to whatever index you like, passing 1 as the instanceCount. If you do that, then gl_InstanceIndex will be the firstInstance value.

Note that this is different from OpenGL’s gl_InstanceID which does not get the base instance added to this.

Also, it’s important to note that in this circumstance, gl_InstanceIndex is dynamically uniform. That’s crucial, since it means that you can use it to access arrays of textures.

Do note that multiDrawIndirect and drawIndirectFirstInstance are not universally supported. Indeed, there’s a surprising amount of AMD hardware that doesn’t support multiDrawIndirect at all. This is surprising because the first OpenGL version of this was AMD_multi_draw_indirect. I assume that’s a driver issue that they intend to work out.

Even so, there’s a lot of Intel hardware that can’t handle either multi-draw-indirect or indirect-first-instance (though again, this may just be early driver issues). So you can’t just assume it’s available.

[QUOTE=Alfonse Reinheart;40522]Do note that multiDrawIndirect and drawIndirectFirstInstance are not universally supported. Indeed, there’s a surprising amount of AMD hardware that doesn’t support multiDrawIndirect at all. This is surprising because the first OpenGL version of this was AMD_multi_draw_indirect. I assume that’s a driver issue that they intend to work out.

Even so, there’s a lot of Intel hardware that can’t handle either multi-draw-indirect or indirect-first-instance (though again, this may just be early driver issues). So you can’t just assume it’s available.[/QUOTE]

Not to forget mobile. Though most of the Android Vulkan implementations are still kinda beta that may pose a limitation too.

I am learning quickly here.
Thank you!!

I shall wait for the drawID.

For the record:

How much more overhead is added through such a loop, compared to a true multiIndirect call.
Or is vulkan so awesome that, this is effectively a multiDraw call?

Update: From the posts above, I glean that this might be the case. Especially when aiming for harware compatibility.
Then again, I am targeting VR, so I take what I can get.


for (int i = 0; i < meshes.size(); i++)
{
	vkCmdPushConstants(
						cmdBuffer,
						pipelineLayouts.scene,
						VK_SHADER_STAGE_FRAGMENT_BIT,
						0,
						sizeof(int),
						&i);

vkCmdDrawIndexedIndirect(cmdBuffer,
						indirectDrawCommandsBuffer,
						sizeof(VkDrawIndexedIndirectCommand)*i,
						1,
						sizeof(VkDrawIndexedIndirectCommand)
						);

}