Support for semaphores

Mesa doesn't implement semaphores.  We implement them
to allow for cross process use in the future.  They're
also useful for implementing page flipping.

Change-Id: I874441f12736023889da97bf176560b6066335c0
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index d1bec59..2d9d1b5 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -1776,26 +1776,25 @@
 
 // Queue semaphore functions
 
-VkResult anv_CreateSemaphore(
-    VkDevice                                    device,
-    const VkSemaphoreCreateInfo*                pCreateInfo,
-    const VkAllocationCallbacks*                pAllocator,
-    VkSemaphore*                                pSemaphore)
+VkResult anv_CreateSemaphore(VkDevice _device, const VkSemaphoreCreateInfo* pCreateInfo,
+                             const VkAllocationCallbacks* pAllocator, VkSemaphore* pSemaphore)
 {
-   /* The DRM execbuffer ioctl always execute in-oder, even between different
-    * rings. As such, there's nothing to do for the user space semaphore.
-    */
+   ANV_FROM_HANDLE(anv_device, device, _device);
 
-   *pSemaphore = (VkSemaphore)1;
+   anv_semaphore_t semaphore;
+   if (anv_platform_create_semaphore(device, &semaphore) != 0)
+      return VK_ERROR_OUT_OF_HOST_MEMORY;
+
+   *pSemaphore = (VkSemaphore)semaphore;
 
    return VK_SUCCESS;
 }
 
-void anv_DestroySemaphore(
-    VkDevice                                    device,
-    VkSemaphore                                 semaphore,
-    const VkAllocationCallbacks*                pAllocator)
+void anv_DestroySemaphore(VkDevice _device, VkSemaphore semaphore,
+                          const VkAllocationCallbacks* pAllocator)
 {
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   anv_platform_destroy_semaphore(device, (anv_semaphore_t)semaphore);
 }
 
 // Event functions
diff --git a/src/intel/vulkan/anv_platform.cc b/src/intel/vulkan/anv_platform.cc
index 4bd493c..68e9d81 100644
--- a/src/intel/vulkan/anv_platform.cc
+++ b/src/intel/vulkan/anv_platform.cc
@@ -5,15 +5,18 @@
 #include "anv_private.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) {
+int anv_platform_futex_wake(uint32_t* addr, int count)
+{
    if (!magma::PlatformFutex::Wake(addr, count))
       return DRET_MSG(-1, "Wake failed");
    return 0;
 }
 
-int anv_platform_futex_wait(uint32_t *addr, int32_t value) {
+int anv_platform_futex_wait(uint32_t* addr, int32_t value)
+{
   magma::PlatformFutex::WaitResult result;
   if (!magma::PlatformFutex::WaitForever(addr, value, &result))
     return DRET_MSG(-EINVAL, "WaitForever failed");
@@ -22,3 +25,19 @@
   assert(result == magma::PlatformFutex::WaitResult::AWOKE);
   return 0;
 }
+
+int anv_platform_create_semaphore(anv_device* device, anv_semaphore_t* semaphore_out)
+{
+   magma_semaphore_t semaphore;
+   magma_status_t status = magma_system_create_semaphore(device->connection, &semaphore);
+   if (status != MAGMA_STATUS_OK)
+      return DRET_MSG(-EINVAL, "magma_system_create_semaphore failed: %d", status);
+   *semaphore_out = reinterpret_cast<anv_semaphore_t>(semaphore);
+   return 0;
+}
+
+void anv_platform_destroy_semaphore(anv_device* device, anv_semaphore_t semaphore)
+{
+   magma_system_destroy_semaphore(device->connection,
+                                  reinterpret_cast<magma_semaphore_t>(semaphore));
+}
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 60c992d..89f4fa9 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -596,6 +596,8 @@
     struct magma_system_connection*             connection;
 };
 
+typedef uintptr_t anv_semaphore_t;
+
 void anv_device_get_cache_uuid(void *uuid);
 
 void anv_device_init_blorp(struct anv_device *device);
@@ -634,6 +636,9 @@
 int anv_platform_futex_wake(uint32_t *addr, int count);
 int anv_platform_futex_wait(uint32_t *addr, int32_t value);
 
+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);
+
 VkResult anv_bo_init_new(struct anv_bo *bo, struct anv_device *device, uint64_t size);
 
 struct anv_reloc_list {