[Mesa-dev] [PATCH 5/9] anv: Add vma_heap allocators in anv_device
Scott D Phillips
scott.d.phillips at intel.com
Wed May 2 16:01:05 UTC 2018
These will be used to assign virtual addresses to soft pinned
buffers in a later patch.
---
src/intel/vulkan/anv_device.c | 75 ++++++++++++++++++++++++++++++++++++++++++
src/intel/vulkan/anv_private.h | 11 +++++++
2 files changed, 86 insertions(+)
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index c0cec175826..d3d9c779d62 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -369,6 +369,8 @@ anv_physical_device_init(struct anv_physical_device *device,
device->has_exec_async = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_ASYNC);
device->has_exec_capture = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_CAPTURE);
device->has_exec_fence = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_FENCE);
+ device->has_exec_softpin = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_SOFTPIN)
+ && device->supports_48bit_addresses;
device->has_syncobj = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_FENCE_ARRAY);
device->has_syncobj_wait = device->has_syncobj &&
anv_gem_supports_syncobj_wait(fd);
@@ -1527,6 +1529,26 @@ VkResult anv_CreateDevice(
goto fail_fd;
}
+ if (physical_device->has_exec_softpin) {
+ if (pthread_mutex_init(&device->vma_mutex, NULL) != 0) {
+ result = vk_error(VK_ERROR_INITIALIZATION_FAILED);
+ goto fail_fd;
+ }
+
+ /* keep the page with address zero out of the allocator */
+ util_vma_heap_init(&device->vma_lo, 4096, (1ull << 32) - 2 * 4096);
+ device->vma_lo_available =
+ physical_device->memory.heaps[physical_device->memory.heap_count - 1].size;
+
+ /* Leave the last 4GiB out of the high vma range, so that no state base
+ * address + size can overflow 48 bits.
+ */
+ util_vma_heap_init(&device->vma_hi, (1ull << 32) + 4096,
+ (1ull << 48) - 2 * (1ull << 32) - 2 * 4096);
+ device->vma_hi_available = physical_device->memory.heap_count == 1 ? 0 :
+ physical_device->memory.heaps[0].size;
+ }
+
/* As per spec, the driver implementation may deny requests to acquire
* a priority above the default priority (MEDIUM) if the caller does not
* have sufficient privileges. In this scenario VK_ERROR_NOT_PERMITTED_EXT
@@ -1887,6 +1909,59 @@ VkResult anv_DeviceWaitIdle(
return anv_device_submit_simple_batch(device, &batch);
}
+bool
+anv_vma_alloc(struct anv_device *device, struct anv_bo *bo)
+{
+ if (!(bo->flags & EXEC_OBJECT_PINNED))
+ return true;
+
+ pthread_mutex_lock(&device->vma_mutex);
+
+ bo->offset = 0;
+
+ if (bo->flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS &&
+ device->vma_hi_available >= bo->size) {
+ uint64_t addr = util_vma_heap_alloc(&device->vma_hi, bo->size, 4096);
+ if (addr) {
+ bo->offset = canonical_address(addr);
+ device->vma_hi_available -= bo->size;
+ }
+ }
+
+ if (bo->offset == 0 && device->vma_lo_available >= bo->size) {
+ uint64_t addr = util_vma_heap_alloc(&device->vma_lo, bo->size, 4096);
+ if (addr) {
+ bo->offset = canonical_address(addr);
+ device->vma_lo_available -= bo->size;
+ }
+ }
+
+ pthread_mutex_unlock(&device->vma_mutex);
+
+ return bo->offset != 0;
+}
+
+void
+anv_vma_free(struct anv_device *device, struct anv_bo *bo)
+{
+ if (!(bo->flags & EXEC_OBJECT_PINNED))
+ return;
+
+ pthread_mutex_lock(&device->vma_mutex);
+
+ if (bo->offset >= 1ull << 32) {
+ util_vma_heap_free(&device->vma_hi, bo->offset, bo->size);
+ device->vma_hi_available += bo->size;
+ } else {
+ util_vma_heap_free(&device->vma_lo, bo->offset, bo->size);
+ device->vma_lo_available += bo->size;
+ }
+
+ pthread_mutex_unlock(&device->vma_mutex);
+
+ bo->offset = 0;
+}
+
VkResult
anv_bo_init_new(struct anv_bo *bo, struct anv_device *device, uint64_t size)
{
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 761601d1e37..708c3a540d3 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -49,6 +49,7 @@
#include "util/list.h"
#include "util/u_atomic.h"
#include "util/u_vector.h"
+#include "util/vma.h"
#include "vk_alloc.h"
#include "vk_debug_report.h"
@@ -802,6 +803,7 @@ struct anv_physical_device {
bool has_exec_async;
bool has_exec_capture;
bool has_exec_fence;
+ bool has_exec_softpin;
bool has_syncobj;
bool has_syncobj_wait;
bool has_context_priority;
@@ -898,6 +900,12 @@ struct anv_device {
struct anv_device_extension_table enabled_extensions;
struct anv_dispatch_table dispatch;
+ pthread_mutex_t vma_mutex;
+ struct util_vma_heap vma_lo;
+ struct util_vma_heap vma_hi;
+ uint64_t vma_lo_available;
+ uint64_t vma_hi_available;
+
struct anv_bo_pool batch_bo_pool;
struct anv_bo_cache bo_cache;
@@ -991,6 +999,9 @@ int anv_gem_syncobj_wait(struct anv_device *device,
uint32_t *handles, uint32_t num_handles,
int64_t abs_timeout_ns, bool wait_all);
+bool anv_vma_alloc(struct anv_device *device, struct anv_bo *bo);
+void anv_vma_free(struct anv_device *device, struct anv_bo *bo);
+
VkResult anv_bo_init_new(struct anv_bo *bo, struct anv_device *device, uint64_t size);
struct anv_reloc_list {
--
2.14.3
More information about the mesa-dev
mailing list