Dynamic QRhiBuffer updates map to a glBufferSubData with gl, while with Vulkan they are each a memcopy to a (persistently mapped) host visible, maybe host coherent, but maybe uncached, memory area.
Consider if we should switch to what the d3d11 backend does for QRhiBuffer::Dynamic: keep a copy of the full buffer data on CPU side, then map with MAP_DISCARD and always copy the full contents regardless of the changed region). This in fact is closer to what the scenegraph does on the direct OpenGL code path, although there it is at the mercy of what glBufferData does internally, but the important part is that it also avoids the partial glBufferSubData (or map/memcpy/unmap). The same would be true for the gl backend of QRhi then (it would do a full glBufferData instead of subData)
But then, it should be considered if the gl backend should employ double buffering (i.e. keep two native buffers per QRhiBuffer etc.) since we do not have a true MAP_DISCARD style solution in ES 2.0. May not be worth it though.
Note that any change to the Vulkan approach must be retested on a mobile/embedded device due to the different characteristics - for instance the fact that we benefit greatly from persistent mapping was only found out when running on the Shield TV (Tegra X1, Android). Regressions must be avoided.
Dropped the priority since this is not the cause of the huge difference between d3d11 and vulkan/gl. An experiment for the gl backend is at https://codereview.qt-project.org/c/qt/qtbase/+/275687 with no real improvements.