Implement VkFence with a semaphore.
Change-Id: Ic97e6f3d3395ab77bee61cc6b8a95694bb891c2f
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index af78d65..bd5c0de 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -1181,7 +1181,8 @@
if (fence) {
struct anv_bo *fence_bo = &fence->bo;
- result = anv_device_execbuf(device, &fence->execbuf, &fence_bo, 0, NULL, 0, NULL);
+ result =
+ anv_device_execbuf(device, &fence->execbuf, &fence_bo, 0, NULL, 1, &fence->semaphore);
if (result != VK_SUCCESS)
goto out;
@@ -1531,10 +1532,14 @@
struct anv_bo fence_bo;
struct anv_fence *fence;
struct anv_batch batch;
+ anv_semaphore_t semaphore;
VkResult result;
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FENCE_CREATE_INFO);
+ if (anv_platform_create_semaphore(device, &semaphore) < 0)
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+
result = anv_bo_pool_alloc(&device->batch_bo_pool, &fence_bo, 4096);
if (result != VK_SUCCESS)
return result;
@@ -1586,6 +1591,8 @@
fence->state = ANV_FENCE_STATE_RESET;
}
+ fence->semaphore = semaphore;
+
*pFence = anv_fence_to_handle(fence);
return VK_SUCCESS;
@@ -1604,6 +1611,8 @@
assert(fence->bo.map == fence);
anv_bo_pool_free(&device->batch_bo_pool, &fence->bo);
+
+ anv_platform_destroy_semaphore(device, fence->semaphore);
}
VkResult anv_ResetFences(
@@ -1611,9 +1620,12 @@
uint32_t fenceCount,
const VkFence* pFences)
{
+ ANV_FROM_HANDLE(anv_device, device, _device);
+
for (uint32_t i = 0; i < fenceCount; i++) {
ANV_FROM_HANDLE(anv_fence, fence, pFences[i]);
fence->state = ANV_FENCE_STATE_RESET;
+ anv_platform_reset_semaphore(fence->semaphore);
}
return VK_SUCCESS;
@@ -1625,7 +1637,7 @@
{
ANV_FROM_HANDLE(anv_device, device, _device);
ANV_FROM_HANDLE(anv_fence, fence, _fence);
- int64_t t = 0;
+ uint64_t t = 0;
int ret;
switch (fence->state) {
@@ -1639,7 +1651,7 @@
case ANV_FENCE_STATE_SUBMITTED:
/* It's been submitted to the GPU but we don't know if it's done yet. */
- ret = anv_gem_wait(device, fence->bo.gem_handle, &t);
+ ret = anv_platform_wait_semaphore(fence->semaphore, t);
if (ret == 0) {
fence->state = ANV_FENCE_STATE_SIGNALED;
return VK_SUCCESS;
@@ -1701,10 +1713,11 @@
/* These are the fences we really care about. Go ahead and wait
* on it until we hit a timeout.
*/
- ret = anv_gem_wait(device, fence->bo.gem_handle, &timeout);
- if (ret == -1 && errno == ETIME) {
+ ret = anv_platform_wait_semaphore(
+ fence->semaphore, _timeout == UINT64_MAX ? UINT64_MAX : _timeout / 1000000);
+ if (ret == -ETIME) {
return VK_TIMEOUT;
- } else if (ret == -1) {
+ } else if (ret < 0) {
/* We don't know the real error. */
return vk_errorf(VK_ERROR_DEVICE_LOST, "gem wait failed: %m");
} else {
diff --git a/src/intel/vulkan/anv_platform.cc b/src/intel/vulkan/anv_platform.cc
index 68e9d81..b0a763d 100644
--- a/src/intel/vulkan/anv_platform.cc
+++ b/src/intel/vulkan/anv_platform.cc
@@ -3,9 +3,10 @@
// found in the LICENSE file.
#include "anv_private.h"
+#include "magma_system.h"
+#include "magma_util/dlog.h"
#include "magma_util/macros.h"
#include "platform_futex.h"
-#include "magma_system.h"
#include <errno.h>
int anv_platform_futex_wake(uint32_t* addr, int count)
@@ -28,6 +29,7 @@
int anv_platform_create_semaphore(anv_device* device, anv_semaphore_t* semaphore_out)
{
+ DLOG("anv_platform_create_semaphore");
magma_semaphore_t semaphore;
magma_status_t status = magma_system_create_semaphore(device->connection, &semaphore);
if (status != MAGMA_STATUS_OK)
@@ -38,6 +40,27 @@
void anv_platform_destroy_semaphore(anv_device* device, anv_semaphore_t semaphore)
{
+ DLOG("anv_platform_destroy_semaphore");
magma_system_destroy_semaphore(device->connection,
reinterpret_cast<magma_semaphore_t>(semaphore));
}
+
+void anv_platform_reset_semaphore(anv_semaphore_t semaphore)
+{
+ DLOG("anv_platform_reset_semaphore");
+ magma_system_reset_semaphore(reinterpret_cast<magma_semaphore_t>(semaphore));
+}
+
+int anv_platform_wait_semaphore(anv_semaphore_t semaphore, uint64_t timeout)
+{
+ DLOG("anv_platform_wait_semaphore");
+ magma_status_t status =
+ magma_system_wait_semaphore(reinterpret_cast<magma_semaphore_t>(semaphore), timeout);
+ switch (status) {
+ case MAGMA_STATUS_OK:
+ return 0;
+ case MAGMA_STATUS_TIMED_OUT:
+ return -ETIME;
+ }
+ return DRET_MSG(-EINVAL, "unhandled magma status: %d", status);
+}
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 9d2fdf5..2712e8e 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -640,6 +640,8 @@
int anv_platform_create_semaphore(struct anv_device* device, anv_semaphore_t* semaphore_out);
void anv_platform_destroy_semaphore(struct anv_device* device, anv_semaphore_t semaphore);
+void anv_platform_reset_semaphore(anv_semaphore_t semaphore);
+int anv_platform_wait_semaphore(anv_semaphore_t semaphore, uint64_t timeout);
VkResult anv_bo_init_new(struct anv_bo *bo, struct anv_device *device, uint64_t size);
@@ -1301,6 +1303,7 @@
struct drm_i915_gem_execbuffer2 execbuf;
struct drm_i915_gem_exec_object2 exec2_objects[1];
enum anv_fence_state state;
+ anv_semaphore_t semaphore;
};
struct anv_event {