<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, May 2, 2018 at 9:01 AM, Scott D Phillips <span dir="ltr"><<a href="mailto:scott.d.phillips@intel.com" target="_blank">scott.d.phillips@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">These will be used to assign virtual addresses to soft pinned<br>
buffers in a later patch.<br>
---<br>
 src/intel/vulkan/anv_device.c  | 75 ++++++++++++++++++++++++++++++<wbr>++++++++++++<br>
 src/intel/vulkan/anv_private.h | 11 +++++++<br>
 2 files changed, 86 insertions(+)<br>
<br>
diff --git a/src/intel/vulkan/anv_device.<wbr>c b/src/intel/vulkan/anv_device.<wbr>c<br>
index c0cec175826..d3d9c779d62 100644<br>
--- a/src/intel/vulkan/anv_device.<wbr>c<br>
+++ b/src/intel/vulkan/anv_device.<wbr>c<br>
@@ -369,6 +369,8 @@ anv_physical_device_init(<wbr>struct anv_physical_device *device,<br>
    device->has_exec_async = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_ASYNC);<br>
    device->has_exec_capture = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_CAPTURE);<br>
    device->has_exec_fence = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_FENCE);<br>
+   device->has_exec_softpin = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_SOFTPIN)<br>
+      && device->supports_48bit_<wbr>addresses;<br></blockquote><div><br></div><div>I'd rather we call this something like use_softpin since it isn't just a "does the kernel have this feature" flag.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
    device->has_syncobj = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_FENCE_<wbr>ARRAY);<br>
    device->has_syncobj_wait = device->has_syncobj &&<br>
                               anv_gem_supports_syncobj_wait(<wbr>fd);<br>
@@ -1527,6 +1529,26 @@ VkResult anv_CreateDevice(<br>
       goto fail_fd;<br>
    }<br>
<br>
+   if (physical_device->has_exec_<wbr>softpin) {<br>
+      if (pthread_mutex_init(&device-><wbr>vma_mutex, NULL) != 0) {<br>
+         result = vk_error(VK_ERROR_<wbr>INITIALIZATION_FAILED);<br>
+         goto fail_fd;<br>
+      }<br>
+<br>
+      /* keep the page with address zero out of the allocator */<br>
+      util_vma_heap_init(&device-><wbr>vma_lo, 4096, (1ull << 32) - 2 * 4096);<br></blockquote><div><br></div><div>Why are you subtracting 2 * 4096?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      device->vma_lo_available =<br>
+         physical_device->memory.heaps[<wbr>physical_device->memory.heap_<wbr>count - 1].size;<br>
+<br>
+      /* Leave the last 4GiB out of the high vma range, so that no state base<br>
+       * address + size can overflow 48 bits.<br></blockquote><div><br></div><div>Might be good to have a more detailed comment here or at least reference the comment in anv_allocator.c that deals with the workaround.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+       */<br>
+      util_vma_heap_init(&device-><wbr>vma_hi, (1ull << 32) + 4096,<br>
+                         (1ull << 48) - 2 * (1ull << 32) - 2 * 4096);<br></blockquote><div><br></div><div>Why are you not starting at (1ull << 32)?<br><br></div><div>If neither of those have a good reason, then we should probably only drop the bottom and top pages in the entire 48-bit range.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      device->vma_hi_available = physical_device->memory.heap_<wbr>count == 1 ? 0 :<br>
+         physical_device->memory.heaps[<wbr>0].size;<br>
+   }<br>
+<br>
    /* As per spec, the driver implementation may deny requests to acquire<br>
     * a priority above the default priority (MEDIUM) if the caller does not<br>
     * have sufficient privileges. In this scenario VK_ERROR_NOT_PERMITTED_EXT<br>
@@ -1887,6 +1909,59 @@ VkResult anv_DeviceWaitIdle(<br>
    return anv_device_submit_simple_<wbr>batch(device, &batch);<br>
 }<br>
<br>
+bool<br>
+anv_vma_alloc(struct anv_device *device, struct anv_bo *bo)<br>
+{<br>
+   if (!(bo->flags & EXEC_OBJECT_PINNED))<br>
+      return true;<br></blockquote><div><br></div><div>When are things not pinned?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+   pthread_mutex_lock(&device-><wbr>vma_mutex);<br>
+<br>
+   bo->offset = 0;<br>
+<br>
+   if (bo->flags & EXEC_OBJECT_SUPPORTS_48B_<wbr>ADDRESS && <br></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+       device->vma_hi_available >= bo->size) {<br>
+      uint64_t addr = util_vma_heap_alloc(&device-><wbr>vma_hi, bo->size, 4096);<br>
+      if (addr) {<br>
+         bo->offset = canonical_address(addr);<br>
+         device->vma_hi_available -= bo->size;<br>
+      }<br>
+   }<br>
+<br>
+   if (bo->offset == 0 && device->vma_lo_available >= bo->size) {<br>
+      uint64_t addr = util_vma_heap_alloc(&device-><wbr>vma_lo, bo->size, 4096);<br>
+      if (addr) {<br>
+         bo->offset = canonical_address(addr);<br>
+         device->vma_lo_available -= bo->size;<br>
+      }<br>
+   }<br></blockquote><div><br></div><div>I'm not sure how I feel about using EXEC_OBJECT_SUPPORTS_48B_ADDRESS for this.  I think it certainly works but it's not what I had pictured.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+   pthread_mutex_unlock(&device-><wbr>vma_mutex);<br>
+<br>
+   return bo->offset != 0;<br>
+}<br>
+<br>
+void<br>
+anv_vma_free(struct anv_device *device, struct anv_bo *bo)<br>
+{<br>
+   if (!(bo->flags & EXEC_OBJECT_PINNED))<br>
+      return;<br>
+<br>
+   pthread_mutex_lock(&device-><wbr>vma_mutex);<br>
+<br>
+   if (bo->offset >= 1ull << 32) {<br>
+      util_vma_heap_free(&device-><wbr>vma_hi, bo->offset, bo->size);<br>
+      device->vma_hi_available += bo->size;<br>
+   } else {<br>
+      util_vma_heap_free(&device-><wbr>vma_lo, bo->offset, bo->size);<br>
+      device->vma_lo_available += bo->size;<br>
+   }<br>
+<br>
+   pthread_mutex_unlock(&device-><wbr>vma_mutex);<br>
+<br>
+   bo->offset = 0;<br>
+}<br>
+<br>
 VkResult<br>
 anv_bo_init_new(struct anv_bo *bo, struct anv_device *device, uint64_t size)<br>
 {<br>
diff --git a/src/intel/vulkan/anv_<wbr>private.h b/src/intel/vulkan/anv_<wbr>private.h<br>
index 761601d1e37..708c3a540d3 100644<br>
--- a/src/intel/vulkan/anv_<wbr>private.h<br>
+++ b/src/intel/vulkan/anv_<wbr>private.h<br>
@@ -49,6 +49,7 @@<br>
 #include "util/list.h"<br>
 #include "util/u_atomic.h"<br>
 #include "util/u_vector.h"<br>
+#include "util/vma.h"<br>
 #include "vk_alloc.h"<br>
 #include "vk_debug_report.h"<br>
<br>
@@ -802,6 +803,7 @@ struct anv_physical_device {<br>
     bool                                        has_exec_async;<br>
     bool                                        has_exec_capture;<br>
     bool                                        has_exec_fence;<br>
+    bool                                        has_exec_softpin;<br>
     bool                                        has_syncobj;<br>
     bool                                        has_syncobj_wait;<br>
     bool                                        has_context_priority;<br>
@@ -898,6 +900,12 @@ struct anv_device {<br>
     struct anv_device_extension_table           enabled_extensions;<br>
     struct anv_dispatch_table                   dispatch;<br>
<br>
+    pthread_mutex_t                             vma_mutex;<br>
+    struct util_vma_heap                        vma_lo;<br>
+    struct util_vma_heap                        vma_hi;<br>
+    uint64_t                                    vma_lo_available;<br>
+    uint64_t                                    vma_hi_available;<br>
+<br>
     struct anv_bo_pool                          batch_bo_pool;<br>
<br>
     struct anv_bo_cache                         bo_cache;<br>
@@ -991,6 +999,9 @@ int anv_gem_syncobj_wait(struct anv_device *device,<br>
                          uint32_t *handles, uint32_t num_handles,<br>
                          int64_t abs_timeout_ns, bool wait_all);<br>
<br>
+bool anv_vma_alloc(struct anv_device *device, struct anv_bo *bo);<br>
+void anv_vma_free(struct anv_device *device, struct anv_bo *bo);<br>
+<br>
 VkResult anv_bo_init_new(struct anv_bo *bo, struct anv_device *device, uint64_t size);<br>
<br>
 struct anv_reloc_list {<br>
<span class="HOEnZb"><font color="#888888">-- <br>
2.14.3<br>
<br>
</font></span></blockquote></div><br></div></div>