4
$\begingroup$

I have problems implementing a Vulkan renderer alongside my OpenGL one.

In OpenGL one can change sampler parameters easily at runtime (like anisotropy settings through glTexParameter) or blend/depth states.

I wonder if this is also possible in Vulkan.

I usually create lets say a sampler object with all information needed and throw the creation info away after construction.

I did not find any information on this on the net.

So, is there any way to change those settings at runtime or do I have to create a complete new sampler object down the road?

The same question applies to depth/blend states in pipeline objects.

I think the second case would not actually be particularly fast performance wise.

$\endgroup$

1 Answer 1

3
$\begingroup$

You're sort of asking two different questions here but that's okay.

Changing Sampler states is pretty straightforward. When you create a descriptor set, you write your VkSampler object that you've created into a descriptor set. If you want to update a sampler in a descriptor set, create a VkSampler with the sampler settings you want and then call vkUpdateDescriptorSets with the new VkSampler writes that you want to perform. When you bind that descriptor set again it should contain your new sampler. This is a bit roundabout but you have to architect for it. You probably don't want to update samplers every frame so only do this when you need to. This is not an extremely expensive operation if you do it right. Vulkan expects descriptor set data to change; so long as that data lines up with the descriptor set layout it's going to go pretty fast.

Changing Pipelines is EXTREMELY expensive. Vulkan doesn't like to perform context switches like this so you can't just update an existing pipeline that's in use. You do have to completely rebuild your rendering path to use the new PSO. If you want to change between a few different Pipelines it's best to build them all upfront, build all the different command buffers that use the different pipelines and then execute the command buffer that has the pipeline you want to run. If you want to change your pipeline, execute the other command buffer that uses the pipeline you want.

Vulkan wants you to create, cache and reuse data as much as possible. That's how you get a lot of savings. You don't need to update descriptor sets, command buffers etc. unless they actually change.

$\endgroup$
3
  • $\begingroup$ Thank you very much! You saved me some headache's. You are right. I completely overseen the vkUpdateDescriptorSets method. And in my setup, the pipelines won't change at all. So I can build them all upfront. $\endgroup$
    – char8_t
    Jan 9, 2017 at 21:06
  • $\begingroup$ When you say changing pipelines is extremely expensive, you mean compiling it, right? Simply binding a pipeline in the command buffer will not be expensive at all, right? It should be just a pointer to the program it should run, I think.... $\endgroup$
    – Zebrafish
    Mar 29, 2022 at 8:15
  • $\begingroup$ Changing the pipeline state object on a command buffer does happen instantly but what's expensive about it is what happens in the driver/ on the gpu. Changing the pipeline state requires the driver/gpu to flush its state which is what's expensive. Ideally on a command buffer you want to record all usage of a pipeline state directly after that pipeline state is bound. If you record command buffers where you keep binding a new pipeline state you're going to see serious performance problems. $\endgroup$
    – Honeybunch
    Mar 30, 2022 at 15:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.