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 {