#include <fcntl.h>
#include <unistd.h>
+#include "util/os_file.h"
+
#include "anv_private.h"
#include "vk_util.h"
struct anv_semaphore_impl *impl = &semaphore->permanent;
assert(impl->type == ANV_SEMAPHORE_TYPE_SYNC_FILE);
- impl->fd = dup(submit->out_fence);
+ impl->fd = os_dupfd_cloexec(submit->out_fence);
}
} else {
/* Unblock any waiter by signaling the points, the application will get
}
static struct anv_queue_submit *
-anv_queue_submit_alloc(struct anv_device *device)
+anv_queue_submit_alloc(struct anv_device *device, int perf_query_pass)
{
const VkAllocationCallbacks *alloc = &device->vk.alloc;
VkSystemAllocationScope alloc_scope = VK_SYSTEM_ALLOCATION_SCOPE_DEVICE;
submit->alloc_scope = alloc_scope;
submit->in_fence = -1;
submit->out_fence = -1;
+ submit->perf_query_pass = perf_query_pass;
return submit;
}
return VK_SUCCESS;
struct anv_device *device = queue->device;
- struct anv_queue_submit *submit = anv_queue_submit_alloc(device);
+ struct anv_queue_submit *submit = anv_queue_submit_alloc(device, -1);
if (!submit)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
const uint64_t *out_values,
uint32_t num_out_semaphores,
struct anv_bo *wsi_signal_bo,
- VkFence _fence)
+ VkFence _fence,
+ int perf_query_pass)
{
ANV_FROM_HANDLE(anv_fence, fence, _fence);
struct anv_device *device = queue->device;
UNUSED struct anv_physical_device *pdevice = device->physical;
- struct anv_queue_submit *submit = anv_queue_submit_alloc(device);
+ struct anv_queue_submit *submit = anv_queue_submit_alloc(device, perf_query_pass);
if (!submit)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
* common case.
*/
result = anv_queue_submit(queue, NULL, NULL, NULL, 0, NULL, NULL, 0,
- NULL, fence);
+ NULL, fence, -1);
goto out;
}
const VkTimelineSemaphoreSubmitInfoKHR *timeline_info =
vk_find_struct_const(pSubmits[i].pNext,
TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR);
+ const VkPerformanceQuerySubmitInfoKHR *perf_info =
+ vk_find_struct_const(pSubmits[i].pNext,
+ PERFORMANCE_QUERY_SUBMIT_INFO_KHR);
const uint64_t *wait_values =
timeline_info && timeline_info->waitSemaphoreValueCount ?
timeline_info->pWaitSemaphoreValues : NULL;
signal_values,
pSubmits[i].signalSemaphoreCount,
wsi_signal_bo,
- submit_fence);
+ submit_fence,
+ -1);
if (result != VK_SUCCESS)
goto out;
result = anv_queue_submit(queue, cmd_buffer,
in_semaphores, in_values, num_in_semaphores,
out_semaphores, out_values, num_out_semaphores,
- wsi_signal_bo, execbuf_fence);
+ wsi_signal_bo, execbuf_fence,
+ perf_info ? perf_info->counterPassIndex : 0);
if (result != VK_SUCCESS)
goto out;
}
break;
- case VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT:
+ case VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT: {
/* Sync files are a bit tricky. Because we want to continue using the
* syncobj implementation of WaitForFences, we don't use the sync file
* directly but instead import it into a syncobj.
*/
new_impl.type = ANV_FENCE_TYPE_SYNCOBJ;
- new_impl.syncobj = anv_gem_syncobj_create(device, 0);
+ /* "If handleType is VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT, the
+ * special value -1 for fd is treated like a valid sync file descriptor
+ * referring to an object that has already signaled. The import
+ * operation will succeed and the VkFence will have a temporarily
+ * imported payload as if a valid file descriptor had been provided."
+ */
+ uint32_t create_flags = 0;
+ if (fd == -1)
+ create_flags |= DRM_SYNCOBJ_CREATE_SIGNALED;
+
+ new_impl.syncobj = anv_gem_syncobj_create(device, create_flags);
if (!new_impl.syncobj)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
- if (anv_gem_syncobj_import_sync_file(device, new_impl.syncobj, fd)) {
+ if (fd != -1 &&
+ anv_gem_syncobj_import_sync_file(device, new_impl.syncobj, fd)) {
anv_gem_syncobj_destroy(device, new_impl.syncobj);
return vk_errorf(device, NULL, VK_ERROR_INVALID_EXTERNAL_HANDLE,
"syncobj sync file import failed: %m");
}
break;
+ }
default:
return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE);
switch (impl->type) {
case ANV_SEMAPHORE_TYPE_TIMELINE: {
pthread_mutex_lock(&device->mutex);
+ anv_timeline_gc_locked(device, &impl->timeline);
*pValue = impl->timeline.highest_past;
pthread_mutex_unlock(&device->mutex);
return VK_SUCCESS;
uint64_t abs_timeout_ns)
{
if (!wait_all && n_timelines > 1) {
+ pthread_mutex_lock(&device->mutex);
+
while (1) {
VkResult result;
- pthread_mutex_lock(&device->mutex);
for (uint32_t i = 0; i < n_timelines; i++) {
result =
anv_timeline_wait_locked(device, timelines[i], serials[i], 0);
if (handle_count > 0) {
result = anv_timelines_wait(device, timelines, values, handle_count,
!(pWaitInfo->flags & VK_SEMAPHORE_WAIT_ANY_BIT_KHR),
- timeout);
+ anv_get_absolute_timeout(timeout));
}
vk_free(&device->vk.alloc, timelines);