turnip: Properly return VK_DEVICE_LOST on queuesubmit failures.
The device lost support closely matches the anv code for the same.
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/2769>
diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c
index dd046f3..5790574 100644
--- a/src/freedreno/vulkan/tu_device.c
+++ b/src/freedreno/vulkan/tu_device.c
@@ -1216,6 +1216,7 @@
device->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
device->instance = physical_device->instance;
device->physical_device = physical_device;
+ device->_lost = false;
if (pAllocator)
device->alloc = *pAllocator;
@@ -1366,6 +1367,29 @@
}
VkResult
+_tu_device_set_lost(struct tu_device *device,
+ const char *file, int line,
+ const char *msg, ...)
+{
+ /* Set the flag indicating that waits should return in finite time even
+ * after device loss.
+ */
+ p_atomic_inc(&device->_lost);
+
+ /* TODO: Report the log message through VkDebugReportCallbackEXT instead */
+ fprintf(stderr, "%s:%d: ", file, line);
+ va_list ap;
+ va_start(ap, msg);
+ vfprintf(stderr, msg, ap);
+ va_end(ap);
+
+ if (env_var_as_boolean("TU_ABORT_ON_DEVICE_LOSS", false))
+ abort();
+
+ return VK_ERROR_DEVICE_LOST;
+}
+
+VkResult
tu_get_scratch_bo(struct tu_device *dev, uint64_t size, struct tu_bo **bo)
{
unsigned size_log2 = MAX2(util_logbase2_ceil64(size), MIN_SCRATCH_BO_SIZE_LOG2);
@@ -1547,18 +1571,17 @@
pSubmits[i].waitSemaphoreCount,
false, &in_syncobjs, &nr_in_syncobjs);
if (result != VK_SUCCESS) {
- /* TODO: emit VK_ERROR_DEVICE_LOST */
- fprintf(stderr, "failed to allocate space for semaphore submission\n");
- abort();
+ return tu_device_set_lost(queue->device,
+ "failed to allocate space for semaphore submission\n");
}
result = tu_get_semaphore_syncobjs(pSubmits[i].pSignalSemaphores,
pSubmits[i].signalSemaphoreCount,
false, &out_syncobjs, &nr_out_syncobjs);
if (result != VK_SUCCESS) {
- /* TODO: emit VK_ERROR_DEVICE_LOST */
- fprintf(stderr, "failed to allocate space for semaphore submission\n");
- abort();
+ free(in_syncobjs);
+ return tu_device_set_lost(queue->device,
+ "failed to allocate space for semaphore submission\n");
}
uint32_t entry_count = 0;
@@ -1617,8 +1640,10 @@
DRM_MSM_GEM_SUBMIT,
&req, sizeof(req));
if (ret) {
- fprintf(stderr, "submit failed: %s\n", strerror(errno));
- abort();
+ free(in_syncobjs);
+ free(out_syncobjs);
+ return tu_device_set_lost(queue->device, "submit failed: %s\n",
+ strerror(errno));
}
tu_bo_list_destroy(&bo_list);
@@ -1648,6 +1673,9 @@
{
TU_FROM_HANDLE(tu_queue, queue, _queue);
+ if (tu_device_is_lost(queue->device))
+ return VK_ERROR_DEVICE_LOST;
+
tu_fence_wait_idle(&queue->submit_fence);
return VK_SUCCESS;
@@ -1658,6 +1686,9 @@
{
TU_FROM_HANDLE(tu_device, device, _device);
+ if (tu_device_is_lost(device))
+ return VK_ERROR_DEVICE_LOST;
+
for (unsigned i = 0; i < TU_MAX_QUEUE_FAMILIES; i++) {
for (unsigned q = 0; q < device->queue_count[i]; q++) {
tu_QueueWaitIdle(tu_queue_to_handle(&device->queues[i][q]));
diff --git a/src/freedreno/vulkan/tu_fence.c b/src/freedreno/vulkan/tu_fence.c
index 62094c9..f3de4ee 100644
--- a/src/freedreno/vulkan/tu_fence.c
+++ b/src/freedreno/vulkan/tu_fence.c
@@ -336,6 +336,9 @@
{
TU_FROM_HANDLE(tu_device, device, _device);
+ if (tu_device_is_lost(device))
+ return VK_ERROR_DEVICE_LOST;
+
/* add a simpler path for when fenceCount == 1? */
struct pollfd stack_fds[8];
diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h
index a70bb3b..0d59c3c 100644
--- a/src/freedreno/vulkan/tu_private.h
+++ b/src/freedreno/vulkan/tu_private.h
@@ -47,6 +47,7 @@
#include "main/macros.h"
#include "util/list.h"
#include "util/macros.h"
+#include "util/u_atomic.h"
#include "vk_alloc.h"
#include "vk_debug_report.h"
#include "wsi_common.h"
@@ -350,6 +351,7 @@
int queue_count[TU_MAX_QUEUE_FAMILIES];
struct tu_physical_device *physical_device;
+ int _lost;
struct ir3_compiler *compiler;
@@ -377,6 +379,18 @@
struct tu_device_extension_table enabled_extensions;
};
+VkResult _tu_device_set_lost(struct tu_device *device,
+ const char *file, int line,
+ const char *msg, ...) PRINTFLIKE(4, 5);
+#define tu_device_set_lost(dev, ...) \
+ _tu_device_set_lost(dev, __FILE__, __LINE__, __VA_ARGS__)
+
+static inline bool
+tu_device_is_lost(struct tu_device *device)
+{
+ return unlikely(p_atomic_read(&device->_lost));
+}
+
VkResult
tu_bo_init_new(struct tu_device *dev, struct tu_bo *bo, uint64_t size);
VkResult
diff --git a/src/freedreno/vulkan/tu_query.c b/src/freedreno/vulkan/tu_query.c
index 6a106a4..143f144 100644
--- a/src/freedreno/vulkan/tu_query.c
+++ b/src/freedreno/vulkan/tu_query.c
@@ -311,6 +311,9 @@
TU_FROM_HANDLE(tu_query_pool, pool, queryPool);
assert(firstQuery + queryCount <= pool->size);
+ if (tu_device_is_lost(device))
+ return VK_ERROR_DEVICE_LOST;
+
switch (pool->type) {
case VK_QUERY_TYPE_OCCLUSION:
case VK_QUERY_TYPE_TIMESTAMP: