Repository: godotengine/godot (language: cpp)

Issue:
Stuttering issue when using Godot 4.4 beta 1
### Tested versions

4.4.beta1 and 4.3-stable

### System information

Godot v4.3.stable.mono - Windows 10.0.26100 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3060 Ti (NVIDIA; 32.0.15.6109) - 13th Gen Intel(R) Core(TM) i5-13600K (20 Threads)

### Issue description

In version 4.4.beta1, when running the F5 project, the lag is 3 to 5 times worse than in version 4.3.

### Steps to reproduce

In version 4.3, drawing is performed, while in version 4.4.beta, drawing is performed by holding down the left mouse button.

### Minimal reproduction project (MRP)

[draw_new.zip](https://github.com/user-attachments/files/18503670/draw_new.zip)


Discussion / hints:
Seems a regression between 4.3 stable and 4.4 dev 1, i'll bisect.
Bisected to #90993, @darksylinc

![Image](https://github.com/user-attachments/assets/8b0373a6-427a-47ab-85a0-f34c8c15986b)

<br>

As can be deduced by the culprit pr. the performance drop only happens with vulkan, with the compatibility renderer no lag happens. Also, i recommend compile without the `dev_build=yes` and with `production=yes` so you'll not lose some time with a wrong bisect 😄 
Bisect is wrong.

Ancestor to my PR, i.e. commit 5ca419e32c can also repro the bug.

PS: I'm testing on Linux with AMD GPU Radeon 6800 XT. Bug repros there too.

**Edit:** Wait. Something's up. I see the same issue on 4.3 on Linux, but slightly different.
**Edit:** Nevermind. I was wrong. Bisect was correct.
OK found the cause. I'll figure out the fix later:

The problem is in `RenderingDeviceDriverVulkan::buffer_create` which needed to change how buffers are created so we could send in the allocation callbacks.

Originally we just called (relevant code):

```cpp
alloc_create_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_HOST; // Relevant!
VkResult err = vmaCreateBuffer(allocator, &create_info, &alloc_create_info, &vk_buffer, &allocation, &alloc_info);
```

But now we do:

```cpp
VkResult err = vkCreateBuffer(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER), &vk_buffer);
ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't create buffer of size: " + itos(p_size) + ", error " + itos(err) + ".");
err = vmaAllocateMemoryForBuffer(allocator, vk_buffer, &alloc_create_info, &allocation, &alloc_info);
ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't allocate memory for buffer of size: " + itos(p_size) + ", error " + itos(err) + ".");
err = vmaBindBufferMemory2(allocator, allocation, 0, vk_buffer, NULL);
ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't bind memory to buffer of size: " + itos(p_size) + ", error " + itos(err) + ".");
```

It would seem this results in the wrong memory pool being chosen.

Fix patch:
diff --git a/drivers/vulkan/rendering_device_driver_vulkan.cpp b/drivers/vulkan/rendering_device_driver_vulkan.cpp
index 45c574914d65..f46015f1fc33 100644
--- a/drivers/vulkan/rendering_device_driver_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_driver_vulkan.cpp
@@ -1530,10 +1530,12 @@ RDD::BufferID RenderingDeviceDriverVulkan::buffer_create(uint64_t p_size, BitFie
 			if (is_src && !is_dst) {
 				// Looks like a staging buffer: CPU maps, writes sequentially, then GPU copies to VRAM.
 				alloc_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
+				alloc_create_info.preferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
 			}
 			if (is_dst && !is_src) {
 				// Looks like a readback buffer: GPU copies from VRAM, then CPU maps and reads.
 				alloc_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT;
+				alloc_create_info.preferredFlags |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
 			}
 			alloc_create_info.requiredFlags = (VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
 		} break;


Test patch: