From faef61aab66f0c9c3faff52a428f3e9906b19b3d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 9 Mar 2023 10:19:24 +0900 Subject: [PATCH] [vulkan] Ensure host-visible buffers are big enough to flush Flushing memory requires nonCoherentAtomSize alignment, but this can cause the flush range to go out of bounds of an improperly sized buffer. However, only host-visible (and probably really only cached, but all three covered) needs flushing, so no rounding up is done for device-local memory. --- libs/video/renderer/vulkan/resource.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/libs/video/renderer/vulkan/resource.c b/libs/video/renderer/vulkan/resource.c index b2b56deae..9641e160d 100644 --- a/libs/video/renderer/vulkan/resource.c +++ b/libs/video/renderer/vulkan/resource.c @@ -28,6 +28,7 @@ # include "config.h" #endif +#include "QF/mathlib.h" #include "QF/va.h" #include "QF/Vulkan/buffer.h" @@ -91,10 +92,19 @@ QFV_CreateResource (qfv_device_t *device, qfv_resource_t *resource) { qfv_devfuncs_t *dfunc = device->funcs; qfv_physdev_t *physdev = device->physDev; + size_t atom = physdev->properties->limits.nonCoherentAtomSize; VkPhysicalDeviceMemoryProperties *memprops = &physdev->memory_properties; VkMemoryRequirements req; VkDeviceSize size = 0; + if (!(resource->memory_properties + & (VK_MEMORY_PROPERTY_HOST_CACHED_BIT + | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT + | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))) { + // if the memory isn't host visible then there's no need to worry about + // alignment with nonCoherentAtomSize + atom = 0; + } for (unsigned i = 0; i < resource->num_objects; i++) { __auto_type obj = &resource->objects[i]; switch (obj->type) { @@ -151,6 +161,7 @@ QFV_CreateResource (qfv_device_t *device, qfv_resource_t *resource) Sys_Error ("%s:%s invalid resource type %d", resource->name, obj->name, obj->type); } + req.alignment = max (req.alignment, atom); size = QFV_NextOffset (size, &req); size += QFV_NextOffset (req.size, &req); } @@ -199,6 +210,7 @@ QFV_CreateResource (qfv_device_t *device, qfv_resource_t *resource) break; } + req.alignment = max (req.alignment, atom); offset = QFV_NextOffset (offset, &req); switch (obj->type) { case qfv_res_buffer: @@ -221,6 +233,7 @@ QFV_CreateResource (qfv_device_t *device, qfv_resource_t *resource) case qfv_res_image_view: break; } + req.alignment = max (req.alignment, atom); offset = QFV_NextOffset (offset, &req); offset += QFV_NextOffset (req.size, &req); }