Vulkan: how does host coherence work? I have a memory that is persistently mapped. It is both HOST_VISIBLE and HOST_COHERENT but not DEVICE_LOCAL. (My physical device offers no memory that is exclusively HOST_VISIBLE without also being HOST_COHERENT.)

This memory contains vertex buffers. I send commands every frame to draw those buffers. Some of those, I change the content every frame, and others more rarely. 

I believe buffers somehow need to be transfered by the driver into the GPU before it can draw them, yes? Here, I never need to invalidate/flush anything because the memory is HOST_COHERENT. How does the driver know what to update/transfer and when? Does it have to a way to detect parts where I change stuff, or does it compulsively retransfer data every frame?
How does the driver know what to update/transfer and when?


It doesn't. There is no transfer or update in that fashion.

All memory allocated through a Vulkan device represents memory that some device operations can read directly. If a Vulkan device advertises that it can use visible/coherent memory as source vertex data for rendering operations, that does not mean that some kind of upload is going on to make this happen. The device is reading that data from the memory you write to. The vkFlushMappedRange function merely expunges writes from CPU cache lines, so that they actually reach the memory.

Memory that is host-coherent and host-visible would represent memory that either:


Is not cached by the CPU, and therefore the GPU sees the memory as it is. This also means that CPU writes and reads tend to be slow.
The GPU can directly access the CPU's caches, to one degree or another.


Usually, #2 happens when the GPU is on-die with the CPU. Which would also mean that this would be device-local memory. Since you've said that it isn't device-local, odds are good that it is simply not cached. It may use write-combining (which improves the efficiency of sequential writes), but CPU writes otherwise are delivered as they are. Given that the memory does not seem to include "cached" in its description, I'd say #1 is the most likely.

Note that just because you don't need to explicitly flush memory does not change the fact that you still need a dependency between the CPU operation writing that data and the GPU command(s) that read it. This would generally be some from of event with a memory dependency.