turnip: implement timestamp fences/semaphores for kgsl backend
This gets fences and semaphores working for kgsl (minus import/export). Signed-off-by: Jonathan Marek <jonathan@marek.ca> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7000>
This commit is contained in:
committed by
Marge Bot
parent
462d62351d
commit
8163c818e3
@@ -26,7 +26,6 @@
|
|||||||
#include <hardware/gralloc.h>
|
#include <hardware/gralloc.h>
|
||||||
#include <hardware/hardware.h>
|
#include <hardware/hardware.h>
|
||||||
#include <hardware/hwvulkan.h>
|
#include <hardware/hwvulkan.h>
|
||||||
#include <libsync.h>
|
|
||||||
|
|
||||||
#include <vulkan/vk_android_native_buffer.h>
|
#include <vulkan/vk_android_native_buffer.h>
|
||||||
#include <vulkan/vk_icd.h>
|
#include <vulkan/vk_icd.h>
|
||||||
@@ -322,55 +321,3 @@ tu_AcquireImageANDROID(VkDevice device,
|
|||||||
return semaphore_result;
|
return semaphore_result;
|
||||||
return fence_result;
|
return fence_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult
|
|
||||||
tu_QueueSignalReleaseImageANDROID(VkQueue _queue,
|
|
||||||
uint32_t waitSemaphoreCount,
|
|
||||||
const VkSemaphore *pWaitSemaphores,
|
|
||||||
VkImage image,
|
|
||||||
int *pNativeFenceFd)
|
|
||||||
{
|
|
||||||
TU_FROM_HANDLE(tu_queue, queue, _queue);
|
|
||||||
VkResult result = VK_SUCCESS;
|
|
||||||
|
|
||||||
if (waitSemaphoreCount == 0) {
|
|
||||||
if (pNativeFenceFd)
|
|
||||||
*pNativeFenceFd = -1;
|
|
||||||
return VK_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fd = -1;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < waitSemaphoreCount; ++i) {
|
|
||||||
int tmp_fd;
|
|
||||||
result = tu_GetSemaphoreFdKHR(
|
|
||||||
tu_device_to_handle(queue->device),
|
|
||||||
&(VkSemaphoreGetFdInfoKHR) {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
|
|
||||||
.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
|
|
||||||
.semaphore = pWaitSemaphores[i],
|
|
||||||
},
|
|
||||||
&tmp_fd);
|
|
||||||
if (result != VK_SUCCESS) {
|
|
||||||
if (fd >= 0)
|
|
||||||
close(fd);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fd < 0)
|
|
||||||
fd = tmp_fd;
|
|
||||||
else if (tmp_fd >= 0) {
|
|
||||||
sync_accumulate("tu", &fd, tmp_fd);
|
|
||||||
close(tmp_fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pNativeFenceFd) {
|
|
||||||
*pNativeFenceFd = fd;
|
|
||||||
} else if (fd >= 0) {
|
|
||||||
close(fd);
|
|
||||||
/* We still need to do the exports, to reset the semaphores, but
|
|
||||||
* otherwise we don't wait on them. */
|
|
||||||
}
|
|
||||||
return VK_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -35,6 +35,11 @@
|
|||||||
|
|
||||||
#include "tu_private.h"
|
#include "tu_private.h"
|
||||||
|
|
||||||
|
struct tu_syncobj {
|
||||||
|
struct vk_object_base base;
|
||||||
|
uint32_t permanent, temporary;
|
||||||
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
tu_drm_get_param(const struct tu_physical_device *dev,
|
tu_drm_get_param(const struct tu_physical_device *dev,
|
||||||
uint32_t param,
|
uint32_t param,
|
||||||
@@ -894,3 +899,72 @@ tu_signal_fences(struct tu_device *device, struct tu_syncobj *fence1, struct tu_
|
|||||||
.count_handles = count
|
.count_handles = count
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
tu_syncobj_to_fd(struct tu_device *device, struct tu_syncobj *sync)
|
||||||
|
{
|
||||||
|
struct drm_syncobj_handle handle = { .handle = sync->permanent };
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = ioctl(device->fd, DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD, &handle);
|
||||||
|
if (ret)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return ret ? -1 : handle.fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
#include <libsync.h>
|
||||||
|
|
||||||
|
VkResult
|
||||||
|
tu_QueueSignalReleaseImageANDROID(VkQueue _queue,
|
||||||
|
uint32_t waitSemaphoreCount,
|
||||||
|
const VkSemaphore *pWaitSemaphores,
|
||||||
|
VkImage image,
|
||||||
|
int *pNativeFenceFd)
|
||||||
|
{
|
||||||
|
TU_FROM_HANDLE(tu_queue, queue, _queue);
|
||||||
|
VkResult result = VK_SUCCESS;
|
||||||
|
|
||||||
|
if (waitSemaphoreCount == 0) {
|
||||||
|
if (pNativeFenceFd)
|
||||||
|
*pNativeFenceFd = -1;
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fd = -1;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < waitSemaphoreCount; ++i) {
|
||||||
|
int tmp_fd;
|
||||||
|
result = tu_GetSemaphoreFdKHR(
|
||||||
|
tu_device_to_handle(queue->device),
|
||||||
|
&(VkSemaphoreGetFdInfoKHR) {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
|
||||||
|
.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
|
||||||
|
.semaphore = pWaitSemaphores[i],
|
||||||
|
},
|
||||||
|
&tmp_fd);
|
||||||
|
if (result != VK_SUCCESS) {
|
||||||
|
if (fd >= 0)
|
||||||
|
close(fd);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
fd = tmp_fd;
|
||||||
|
else if (tmp_fd >= 0) {
|
||||||
|
sync_accumulate("tu", &fd, tmp_fd);
|
||||||
|
close(tmp_fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pNativeFenceFd) {
|
||||||
|
*pNativeFenceFd = fd;
|
||||||
|
} else if (fd >= 0) {
|
||||||
|
close(fd);
|
||||||
|
/* We still need to do the exports, to reset the semaphores, but
|
||||||
|
* otherwise we don't wait on them. */
|
||||||
|
}
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
+224
-28
@@ -31,6 +31,12 @@
|
|||||||
|
|
||||||
#include "msm_kgsl.h"
|
#include "msm_kgsl.h"
|
||||||
|
|
||||||
|
struct tu_syncobj {
|
||||||
|
struct vk_object_base base;
|
||||||
|
uint32_t timestamp;
|
||||||
|
bool timestamp_valid;
|
||||||
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
safe_ioctl(int fd, unsigned long request, void *arg)
|
safe_ioctl(int fd, unsigned long request, void *arg)
|
||||||
{
|
{
|
||||||
@@ -214,6 +220,75 @@ fail:
|
|||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
return VK_ERROR_INITIALIZATION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
timestamp_to_fd(struct tu_queue *queue, uint32_t timestamp)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
struct kgsl_timestamp_event event = {
|
||||||
|
.type = KGSL_TIMESTAMP_EVENT_FENCE,
|
||||||
|
.context_id = queue->msm_queue_id,
|
||||||
|
.timestamp = timestamp,
|
||||||
|
.priv = &fd,
|
||||||
|
.len = sizeof(fd),
|
||||||
|
};
|
||||||
|
|
||||||
|
int ret = safe_ioctl(queue->device->fd, IOCTL_KGSL_TIMESTAMP_EVENT, &event);
|
||||||
|
if (ret)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return true if timestamp a is greater (more recent) then b
|
||||||
|
* this relies on timestamps never having a difference > (1<<31)
|
||||||
|
*/
|
||||||
|
static inline bool
|
||||||
|
timestamp_cmp(uint32_t a, uint32_t b)
|
||||||
|
{
|
||||||
|
return (int32_t) (a - b) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
max_ts(uint32_t a, uint32_t b)
|
||||||
|
{
|
||||||
|
return timestamp_cmp(a, b) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
min_ts(uint32_t a, uint32_t b)
|
||||||
|
{
|
||||||
|
return timestamp_cmp(a, b) ? b : a;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct tu_syncobj
|
||||||
|
sync_merge(const VkSemaphore *syncobjs, uint32_t count, bool wait_all, bool reset)
|
||||||
|
{
|
||||||
|
struct tu_syncobj ret;
|
||||||
|
|
||||||
|
ret.timestamp_valid = false;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < count; ++i) {
|
||||||
|
TU_FROM_HANDLE(tu_syncobj, sync, syncobjs[i]);
|
||||||
|
|
||||||
|
/* TODO: this means the fence is unsignaled and will never become signaled */
|
||||||
|
if (!sync->timestamp_valid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!ret.timestamp_valid)
|
||||||
|
ret.timestamp = sync->timestamp;
|
||||||
|
else if (wait_all)
|
||||||
|
ret.timestamp = max_ts(ret.timestamp, sync->timestamp);
|
||||||
|
else
|
||||||
|
ret.timestamp = min_ts(ret.timestamp, sync->timestamp);
|
||||||
|
|
||||||
|
ret.timestamp_valid = true;
|
||||||
|
if (reset)
|
||||||
|
sync->timestamp_value = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
VkResult
|
VkResult
|
||||||
tu_QueueSubmit(VkQueue _queue,
|
tu_QueueSubmit(VkQueue _queue,
|
||||||
uint32_t submitCount,
|
uint32_t submitCount,
|
||||||
@@ -221,6 +296,7 @@ tu_QueueSubmit(VkQueue _queue,
|
|||||||
VkFence _fence)
|
VkFence _fence)
|
||||||
{
|
{
|
||||||
TU_FROM_HANDLE(tu_queue, queue, _queue);
|
TU_FROM_HANDLE(tu_queue, queue, _queue);
|
||||||
|
TU_FROM_HANDLE(tu_syncobj, fence, _fence);
|
||||||
VkResult result = VK_SUCCESS;
|
VkResult result = VK_SUCCESS;
|
||||||
|
|
||||||
uint32_t max_entry_count = 0;
|
uint32_t max_entry_count = 0;
|
||||||
@@ -261,12 +337,29 @@ tu_QueueSubmit(VkQueue _queue,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct tu_syncobj s = sync_merge(submit->pWaitSemaphores,
|
||||||
|
submit->waitSemaphoreCount,
|
||||||
|
true, true);
|
||||||
|
|
||||||
|
struct kgsl_cmd_syncpoint_timestamp ts = {
|
||||||
|
.context_id = queue->msm_queue_id,
|
||||||
|
.timestamp = s.timestamp,
|
||||||
|
};
|
||||||
|
struct kgsl_command_syncpoint sync = {
|
||||||
|
.type = KGSL_CMD_SYNCPOINT_TYPE_TIMESTAMP,
|
||||||
|
.size = sizeof(ts),
|
||||||
|
.priv = (uintptr_t) &ts,
|
||||||
|
};
|
||||||
|
|
||||||
struct kgsl_gpu_command req = {
|
struct kgsl_gpu_command req = {
|
||||||
.flags = KGSL_CMDBATCH_SUBMIT_IB_LIST,
|
.flags = KGSL_CMDBATCH_SUBMIT_IB_LIST,
|
||||||
.context_id = queue->msm_queue_id,
|
.context_id = queue->msm_queue_id,
|
||||||
.cmdlist = (uint64_t) (uintptr_t) cmds,
|
.cmdlist = (uint64_t) (uintptr_t) cmds,
|
||||||
.numcmds = entry_idx,
|
.numcmds = entry_idx,
|
||||||
.cmdsize = sizeof(struct kgsl_command_object),
|
.cmdsize = sizeof(struct kgsl_command_object),
|
||||||
|
.synclist = (uintptr_t) &sync,
|
||||||
|
.syncsize = sizeof(struct kgsl_command_syncpoint),
|
||||||
|
.numsyncs = s.timestamp_valid ? 1 : 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
int ret = safe_ioctl(queue->device->physical_device->local_fd,
|
int ret = safe_ioctl(queue->device->physical_device->local_fd,
|
||||||
@@ -277,20 +370,16 @@ tu_QueueSubmit(VkQueue _queue,
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < submit->signalSemaphoreCount; i++) {
|
||||||
|
TU_FROM_HANDLE(tu_syncobj, sem, submit->pSignalSemaphores[i]);
|
||||||
|
sem->timestamp = req.timestamp;
|
||||||
|
sem->timestamp_valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
/* no need to merge fences as queue execution is serialized */
|
/* no need to merge fences as queue execution is serialized */
|
||||||
if (i == submitCount - 1) {
|
if (i == submitCount - 1) {
|
||||||
int fd;
|
int fd = timestamp_to_fd(queue, req.timestamp);
|
||||||
struct kgsl_timestamp_event event = {
|
if (fd < 0) {
|
||||||
.type = KGSL_TIMESTAMP_EVENT_FENCE,
|
|
||||||
.context_id = queue->msm_queue_id,
|
|
||||||
.timestamp = req.timestamp,
|
|
||||||
.priv = &fd,
|
|
||||||
.len = sizeof(fd),
|
|
||||||
};
|
|
||||||
|
|
||||||
int ret = safe_ioctl(queue->device->physical_device->local_fd,
|
|
||||||
IOCTL_KGSL_TIMESTAMP_EVENT, &event);
|
|
||||||
if (ret != 0) {
|
|
||||||
result = tu_device_set_lost(queue->device,
|
result = tu_device_set_lost(queue->device,
|
||||||
"Failed to create sync file for timestamp: %s\n",
|
"Failed to create sync file for timestamp: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@@ -300,6 +389,11 @@ tu_QueueSubmit(VkQueue _queue,
|
|||||||
if (queue->fence >= 0)
|
if (queue->fence >= 0)
|
||||||
close(queue->fence);
|
close(queue->fence);
|
||||||
queue->fence = fd;
|
queue->fence = fd;
|
||||||
|
|
||||||
|
if (fence) {
|
||||||
|
fence->timestamp = req.timestamp;
|
||||||
|
fence->timestamp_valid = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fail:
|
fail:
|
||||||
@@ -308,6 +402,30 @@ fail:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VkResult
|
||||||
|
sync_create(VkDevice _device,
|
||||||
|
bool signaled,
|
||||||
|
bool fence,
|
||||||
|
const VkAllocationCallbacks *pAllocator,
|
||||||
|
void **p_sync)
|
||||||
|
{
|
||||||
|
TU_FROM_HANDLE(tu_device, device, _device);
|
||||||
|
|
||||||
|
struct tu_syncobj *sync =
|
||||||
|
vk_object_alloc(&device->vk, pAllocator, sizeof(*sync),
|
||||||
|
fence ? VK_OBJECT_TYPE_FENCE : VK_OBJECT_TYPE_SEMAPHORE);
|
||||||
|
if (!sync)
|
||||||
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||||
|
|
||||||
|
if (signaled)
|
||||||
|
tu_finishme("CREATE FENCE SIGNALED");
|
||||||
|
|
||||||
|
sync->timestamp_valid = false;
|
||||||
|
*p_sync = sync;
|
||||||
|
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
VkResult
|
VkResult
|
||||||
tu_ImportSemaphoreFdKHR(VkDevice _device,
|
tu_ImportSemaphoreFdKHR(VkDevice _device,
|
||||||
const VkImportSemaphoreFdInfoKHR *pImportSemaphoreFdInfo)
|
const VkImportSemaphoreFdInfoKHR *pImportSemaphoreFdInfo)
|
||||||
@@ -326,21 +444,26 @@ tu_GetSemaphoreFdKHR(VkDevice _device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
VkResult
|
VkResult
|
||||||
tu_CreateSemaphore(VkDevice _device,
|
tu_CreateSemaphore(VkDevice device,
|
||||||
const VkSemaphoreCreateInfo *pCreateInfo,
|
const VkSemaphoreCreateInfo *pCreateInfo,
|
||||||
const VkAllocationCallbacks *pAllocator,
|
const VkAllocationCallbacks *pAllocator,
|
||||||
VkSemaphore *pSemaphore)
|
VkSemaphore *pSemaphore)
|
||||||
{
|
{
|
||||||
tu_finishme("CreateSemaphore");
|
return sync_create(device, false, false, pAllocator, (void**) pSemaphore);
|
||||||
return VK_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tu_DestroySemaphore(VkDevice _device,
|
tu_DestroySemaphore(VkDevice _device,
|
||||||
VkSemaphore _semaphore,
|
VkSemaphore semaphore,
|
||||||
const VkAllocationCallbacks *pAllocator)
|
const VkAllocationCallbacks *pAllocator)
|
||||||
{
|
{
|
||||||
tu_finishme("DestroySemaphore");
|
TU_FROM_HANDLE(tu_device, device, _device);
|
||||||
|
TU_FROM_HANDLE(tu_syncobj, sync, semaphore);
|
||||||
|
|
||||||
|
if (!sync)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vk_object_free(&device->vk, pAllocator, sync);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult
|
VkResult
|
||||||
@@ -363,43 +486,84 @@ tu_GetFenceFdKHR(VkDevice _device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
VkResult
|
VkResult
|
||||||
tu_CreateFence(VkDevice _device,
|
tu_CreateFence(VkDevice device,
|
||||||
const VkFenceCreateInfo *pCreateInfo,
|
const VkFenceCreateInfo *info,
|
||||||
const VkAllocationCallbacks *pAllocator,
|
const VkAllocationCallbacks *pAllocator,
|
||||||
VkFence *pFence)
|
VkFence *pFence)
|
||||||
{
|
{
|
||||||
tu_finishme("CreateFence");
|
return sync_create(device, info->flags & VK_FENCE_CREATE_SIGNALED_BIT, true,
|
||||||
return VK_SUCCESS;
|
pAllocator, (void**) pFence);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tu_DestroyFence(VkDevice _device, VkFence _fence, const VkAllocationCallbacks *pAllocator)
|
tu_DestroyFence(VkDevice _device, VkFence fence, const VkAllocationCallbacks *pAllocator)
|
||||||
{
|
{
|
||||||
tu_finishme("DestroyFence");
|
TU_FROM_HANDLE(tu_device, device, _device);
|
||||||
|
TU_FROM_HANDLE(tu_syncobj, sync, fence);
|
||||||
|
|
||||||
|
if (!sync)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vk_object_free(&device->vk, pAllocator, sync);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult
|
VkResult
|
||||||
tu_WaitForFences(VkDevice _device,
|
tu_WaitForFences(VkDevice _device,
|
||||||
uint32_t fenceCount,
|
uint32_t count,
|
||||||
const VkFence *pFences,
|
const VkFence *pFences,
|
||||||
VkBool32 waitAll,
|
VkBool32 waitAll,
|
||||||
uint64_t timeout)
|
uint64_t timeout)
|
||||||
{
|
{
|
||||||
tu_finishme("WaitForFences");
|
TU_FROM_HANDLE(tu_device, device, _device);
|
||||||
|
struct tu_syncobj s = sync_merge((const VkSemaphore*) pFences, count, waitAll, false);
|
||||||
|
|
||||||
|
if (!s.timestamp_valid)
|
||||||
|
return VK_SUCCESS;
|
||||||
|
|
||||||
|
int ret = ioctl(device->fd, IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID,
|
||||||
|
&(struct kgsl_device_waittimestamp_ctxtid) {
|
||||||
|
.context_id = device->queues[0]->msm_queue_id,
|
||||||
|
.timestamp = s.timestamp,
|
||||||
|
.timeout = timeout / 1000000,
|
||||||
|
});
|
||||||
|
if (ret) {
|
||||||
|
assert(errno == ETIME);
|
||||||
|
return VK_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult
|
VkResult
|
||||||
tu_ResetFences(VkDevice _device, uint32_t fenceCount, const VkFence *pFences)
|
tu_ResetFences(VkDevice _device, uint32_t count, const VkFence *pFences)
|
||||||
{
|
{
|
||||||
tu_finishme("ResetFences");
|
for (uint32_t i = 0; i < count; i++) {
|
||||||
|
TU_FROM_HANDLE(tu_syncobj, sync, pFences[i]);
|
||||||
|
sync->timestamp_valid = false;
|
||||||
|
}
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult
|
VkResult
|
||||||
tu_GetFenceStatus(VkDevice _device, VkFence _fence)
|
tu_GetFenceStatus(VkDevice _device, VkFence _fence)
|
||||||
{
|
{
|
||||||
tu_finishme("GetFenceStatus");
|
TU_FROM_HANDLE(tu_device, device, _device);
|
||||||
|
TU_FROM_HANDLE(tu_syncobj, sync, _fence);
|
||||||
|
|
||||||
|
if (!sync->timestamp_valid)
|
||||||
|
return VK_NOT_READY;
|
||||||
|
|
||||||
|
int ret = ioctl(device->fd, IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID,
|
||||||
|
&(struct kgsl_device_waittimestamp_ctxtid) {
|
||||||
|
.context_id = device->queues[0]->msm_queue_id,
|
||||||
|
.timestamp = sync->timestamp,
|
||||||
|
.timeout = 0,
|
||||||
|
});
|
||||||
|
if (ret) {
|
||||||
|
assert(errno == ETIME);
|
||||||
|
return VK_NOT_READY;
|
||||||
|
}
|
||||||
|
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,3 +573,35 @@ tu_signal_fences(struct tu_device *device, struct tu_syncobj *fence1, struct tu_
|
|||||||
tu_finishme("tu_signal_fences");
|
tu_finishme("tu_signal_fences");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
tu_syncobj_to_fd(struct tu_device *device, struct tu_syncobj *sync)
|
||||||
|
{
|
||||||
|
tu_finishme("tu_syncobj_to_fd");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
VkResult
|
||||||
|
tu_QueueSignalReleaseImageANDROID(VkQueue _queue,
|
||||||
|
uint32_t waitSemaphoreCount,
|
||||||
|
const VkSemaphore *pWaitSemaphores,
|
||||||
|
VkImage image,
|
||||||
|
int *pNativeFenceFd)
|
||||||
|
{
|
||||||
|
TU_FROM_HANDLE(tu_queue, queue, _queue);
|
||||||
|
if (!pNativeFenceFd)
|
||||||
|
return VK_SUCCESS;
|
||||||
|
|
||||||
|
struct tu_syncobj s = sync_merge(pWaitSemaphores, waitSemaphoreCount, true, true);
|
||||||
|
|
||||||
|
if (!s.timestamp_valid) {
|
||||||
|
*pNativeFenceFd = -1;
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pNativeFenceFd = timestamp_to_fd(queue, s.timestamp);
|
||||||
|
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -289,10 +289,7 @@ struct tu_pipeline_key
|
|||||||
|
|
||||||
#define TU_MAX_QUEUE_FAMILIES 1
|
#define TU_MAX_QUEUE_FAMILIES 1
|
||||||
|
|
||||||
struct tu_syncobj {
|
struct tu_syncobj;
|
||||||
struct vk_object_base base;
|
|
||||||
uint32_t permanent, temporary;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tu_queue
|
struct tu_queue
|
||||||
{
|
{
|
||||||
@@ -1546,6 +1543,9 @@ tu_drm_submitqueue_close(const struct tu_device *dev, uint32_t queue_id);
|
|||||||
int
|
int
|
||||||
tu_signal_fences(struct tu_device *device, struct tu_syncobj *fence1, struct tu_syncobj *fence2);
|
tu_signal_fences(struct tu_device *device, struct tu_syncobj *fence1, struct tu_syncobj *fence2);
|
||||||
|
|
||||||
|
int
|
||||||
|
tu_syncobj_to_fd(struct tu_device *device, struct tu_syncobj *sync);
|
||||||
|
|
||||||
#define TU_DEFINE_HANDLE_CASTS(__tu_type, __VkType) \
|
#define TU_DEFINE_HANDLE_CASTS(__tu_type, __VkType) \
|
||||||
\
|
\
|
||||||
static inline struct __tu_type *__tu_type##_from_handle(__VkType _handle) \
|
static inline struct __tu_type *__tu_type##_from_handle(__VkType _handle) \
|
||||||
|
|||||||
@@ -259,19 +259,6 @@ tu_DisplayPowerControlEXT(VkDevice _device,
|
|||||||
display_power_info);
|
display_power_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
import_syncobj(int fd, uint32_t syncobj)
|
|
||||||
{
|
|
||||||
struct drm_syncobj_handle handle = { .handle = syncobj };
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = ioctl(fd, DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD, &handle);
|
|
||||||
if (ret)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return ret ? -1 : handle.fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkResult
|
VkResult
|
||||||
tu_RegisterDeviceEventEXT(VkDevice _device,
|
tu_RegisterDeviceEventEXT(VkDevice _device,
|
||||||
const VkDeviceEventInfoEXT *device_event_info,
|
const VkDeviceEventInfoEXT *device_event_info,
|
||||||
@@ -287,7 +274,7 @@ tu_RegisterDeviceEventEXT(VkDevice _device,
|
|||||||
|
|
||||||
TU_FROM_HANDLE(tu_syncobj, fence, *_fence);
|
TU_FROM_HANDLE(tu_syncobj, fence, *_fence);
|
||||||
|
|
||||||
int sync_fd = import_syncobj(device->fd, fence->permanent);
|
int sync_fd = tu_syncobj_to_fd(device, fence);
|
||||||
if (sync_fd >= 0) {
|
if (sync_fd >= 0) {
|
||||||
ret = wsi_register_device_event(_device,
|
ret = wsi_register_device_event(_device,
|
||||||
&device->physical_device->wsi_device,
|
&device->physical_device->wsi_device,
|
||||||
@@ -323,7 +310,7 @@ tu_RegisterDisplayEventEXT(VkDevice _device,
|
|||||||
|
|
||||||
TU_FROM_HANDLE(tu_syncobj, fence, *_fence);
|
TU_FROM_HANDLE(tu_syncobj, fence, *_fence);
|
||||||
|
|
||||||
int sync_fd = import_syncobj(device->fd, fence->permanent);
|
int sync_fd = tu_syncobj_to_fd(device, fence);
|
||||||
if (sync_fd >= 0) {
|
if (sync_fd >= 0) {
|
||||||
ret = wsi_register_display_event(_device,
|
ret = wsi_register_display_event(_device,
|
||||||
&device->physical_device->wsi_device,
|
&device->physical_device->wsi_device,
|
||||||
|
|||||||
Reference in New Issue
Block a user