Performante question for hide object

Hello,
In my implementation I decide to record command buffer only when the number of geometries changes or are switched.
let say I have 3 cubes then as long as I only have the SAME 3 cubes I will just present the VkCommandBuffer[image_index].

However if one cube is let say temporary destroyed and has to reappear after a little while I have 2 Ideas now to do it but I don’t know about performance:

1/ all cubes are in geometries_map. if I have to hide a cube i just remove it from the map and record the command-buffers and submit it again.

2/ I change nothing else than the uniform value of that cube to scale it to vec3(0.0f) so it is invisible.

the second is easier to implement and on CPU side it looks faster than updating geometries_map. But I have no idea of what is happening on GPU side… I hope that a scaled vec3(0.0f) object is just ignored.

At the present moment I use 2 but I don’t like the fact that I don’t know about performances. I may need to hide thousand of more complex objects.

Once again thank you for your time.

How do you do that? If you’re changing memory, that would require a full CPU/GPU synchronization, since you can’t modify GPU-accessible memory that the GPU is potentially reading from. And if you’re double-buffering memory (so that you’re modifying one while the other is being read from), you’d also need to be double-buffering command buffers.

Maybe I was not clear. I scale the object to be of size 0. and update uniform and that’s it. I still use the same command buffer with the drawcall for all cubes.

There are no “uniforms” in Vulkan. There are UBOs, and there are push constants. UBOs are memory resources, and while you can change the underlying memory, you cannot modify that memory while a command buffer using that range of memory is being executed by the GPU. And push constant values are baked into the command buffer, so you cannot modify them without modifying the CB.

So again, how are you changing this uniform?

It is probably a misunderstanding in my explanation. let’s talk in a language with no ambiguities.

void draw(context)
{
    uint34_t indx;
    VkDevice device = context->gpu;
    
vkWaitForFences....
vkAcquireNextImageKHR....


void * data;
vkMapMemory(device, context->UBO.resource[indx]->bufferMemory, 0 sizeof(ubo), 0, &data);
{
   memcpy(data, &ubo, sizeof(ubo));
}
vkUnmapMemory(...)

VkSubmitInfo info = {};
info.sType = ...
...
info.commandBufferCount = 1;
info.pCommandBuffer = &context->commandBuffers[indx];
...
vkQueueSubmit(....);
..... 
vkQueuePresentKHR(...)
}

So I did’t recreate commandBuffer it was done in InitVulkan function. ubo contains the matrix model where I scaled to 0.0f

I may have some typos as I didn’t copy/paste my code. but the idea is here.

@ Alfonse_Reinheart
It there something wrong with what I am doing here? the only thing I can say is at least it’s show/hide my object when I scale 1.0f/0.0f.
But based on your previous answers looks like I should modify also the command buffer !?

This is not a function you use if CPU performance matters to you. Not unless you have run out of anything else your thread could possibly be doing. And even then, you should not be waiting on a fence for a batch you just submitted; you want CPU/GPU execution overlap.

You should unmap a piece of memory exactly once: when you are about to delete it. Vulkan is not OpenGL; you can (and should) keep memory mapped indefinitely (and modern OpenGL lets you do that).

So as I said: you need to double-buffer your memory, so that you don’t do a full CPU/GPU sync every frame. But that means double-buffering your command buffers too.

Thanks for your answer, I will modify it.
Thank you

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.