[Intel-gfx] [PATCH libdrm] intel: Add EXEC_OBJECT_SUPPORTS_48BADDRESS flag.

Michel Thierry michel.thierry at intel.com
Tue Jun 23 05:21:26 PDT 2015


Gen8+ supports 48-bit virtual addresses, but some objects must always be
allocated inside the 32-bit address range.

In specific, any resource used with flat/heapless (0x00000000-0xfffff000)
General State Heap (GSH) or Intruction State Heap (ISH) must be in a
32-bit range, because the General State Offset and Instruction State Offset
are limited to 32-bits.

Provide a flag to set when the 4GB limit is not necessary in a given bo.
48-bit range will only be used when explicitly requested.

Cc: dri-devel at lists.freedesktop.org
Signed-off-by: Michel Thierry <michel.thierry at intel.com>
---
 include/drm/i915_drm.h    |  3 ++-
 intel/intel_bufmgr.c      | 12 ++++++++++++
 intel/intel_bufmgr.h      |  2 ++
 intel/intel_bufmgr_gem.c  | 48 +++++++++++++++++++++++++++++++++++++++++++----
 intel/intel_bufmgr_priv.h | 11 +++++++++++
 5 files changed, 71 insertions(+), 5 deletions(-)

diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index ded43b1..d6fb99d 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -680,7 +680,8 @@ struct drm_i915_gem_exec_object2 {
 #define EXEC_OBJECT_NEEDS_FENCE (1<<0)
 #define EXEC_OBJECT_NEEDS_GTT	(1<<1)
 #define EXEC_OBJECT_WRITE	(1<<2)
-#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_WRITE<<1)
+#define EXEC_OBJECT_SUPPORTS_48BADDRESS (1<<3)
+#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_SUPPORTS_48BADDRESS<<1)
 	__u64 flags;
 
 	__u64 rsvd1;
diff --git a/intel/intel_bufmgr.c b/intel/intel_bufmgr.c
index 14ea9f9..c4ddecb 100644
--- a/intel/intel_bufmgr.c
+++ b/intel/intel_bufmgr.c
@@ -188,6 +188,18 @@ drm_intel_bufmgr_check_aperture_space(drm_intel_bo ** bo_array, int count)
 	return bo_array[0]->bufmgr->check_aperture_space(bo_array, count);
 }
 
+void drm_intel_bo_set_supports_48baddress(drm_intel_bo *bo)
+{
+	if (bo->bufmgr->bo_set_supports_48baddress)
+		bo->bufmgr->bo_set_supports_48baddress(bo);
+}
+
+void drm_intel_bo_clear_supports_48baddress(drm_intel_bo *bo)
+{
+	if (bo->bufmgr->bo_clear_supports_48baddress)
+		bo->bufmgr->bo_clear_supports_48baddress(bo);
+}
+
 int
 drm_intel_bo_flink(drm_intel_bo *bo, uint32_t * name)
 {
diff --git a/intel/intel_bufmgr.h b/intel/intel_bufmgr.h
index 285919e..b51aff8 100644
--- a/intel/intel_bufmgr.h
+++ b/intel/intel_bufmgr.h
@@ -137,6 +137,8 @@ void drm_intel_bo_wait_rendering(drm_intel_bo *bo);
 
 void drm_intel_bufmgr_set_debug(drm_intel_bufmgr *bufmgr, int enable_debug);
 void drm_intel_bufmgr_destroy(drm_intel_bufmgr *bufmgr);
+void drm_intel_bo_set_supports_48baddress(drm_intel_bo *bo);
+void drm_intel_bo_clear_supports_48baddress(drm_intel_bo *bo);
 int drm_intel_bo_exec(drm_intel_bo *bo, int used,
 		      struct drm_clip_rect *cliprects, int num_cliprects, int DR4);
 int drm_intel_bo_mrb_exec(drm_intel_bo *bo, int used,
diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
index 60c06fc..54e839e 100644
--- a/intel/intel_bufmgr_gem.c
+++ b/intel/intel_bufmgr_gem.c
@@ -143,6 +143,7 @@ typedef struct _drm_intel_bufmgr_gem {
 } drm_intel_bufmgr_gem;
 
 #define DRM_INTEL_RELOC_FENCE (1<<0)
+#define DRM_INTEL_RELOC_SUPPORTS_48BADDRESS (2<<0)
 
 typedef struct _drm_intel_reloc_target_info {
 	drm_intel_bo *bo;
@@ -240,6 +241,14 @@ struct _drm_intel_bo_gem {
 	bool is_userptr;
 
 	/**
+	 * Boolean of whether this buffer can be in the whole 48-bit address.
+	 *
+	 * By default, buffers will be keep in a 32-bit range, unless this
+	 * flag is explicitly set.
+	 */
+	bool supports_48baddress;
+
+	/**
 	 * Size in bytes of this buffer and its relocation descendents.
 	 *
 	 * Used to avoid costly tree walking in
@@ -471,13 +480,18 @@ drm_intel_add_validate_buffer(drm_intel_bo *bo)
 }
 
 static void
-drm_intel_add_validate_buffer2(drm_intel_bo *bo, int need_fence)
+drm_intel_add_validate_buffer2(drm_intel_bo *bo, int need_fence,
+			       int supports_48baddress)
 {
 	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo->bufmgr;
 	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
 	int index;
 
 	if (bo_gem->validate_index != -1) {
+		if (supports_48baddress) {
+			bufmgr_gem->exec2_objects[bo_gem->validate_index].flags |=
+				EXEC_OBJECT_SUPPORTS_48BADDRESS;
+		}
 		if (need_fence)
 			bufmgr_gem->exec2_objects[bo_gem->validate_index].flags |=
 				EXEC_OBJECT_NEEDS_FENCE;
@@ -516,6 +530,10 @@ drm_intel_add_validate_buffer2(drm_intel_bo *bo, int need_fence)
 		bufmgr_gem->exec2_objects[index].flags |=
 			EXEC_OBJECT_NEEDS_FENCE;
 	}
+	if (supports_48baddress) {
+		bufmgr_gem->exec2_objects[index].flags |=
+			EXEC_OBJECT_SUPPORTS_48BADDRESS;
+	}
 	bufmgr_gem->exec_count++;
 }
 
@@ -1931,11 +1949,27 @@ do_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
 	else
 		bo_gem->reloc_target_info[bo_gem->reloc_count].flags = 0;
 
+	if (target_bo_gem->supports_48baddress)
+		bo_gem->reloc_target_info[bo_gem->reloc_count].flags |=
+			DRM_INTEL_RELOC_SUPPORTS_48BADDRESS;
+
 	bo_gem->reloc_count++;
 
 	return 0;
 }
 
+static void drm_intel_gem_bo_set_supports_48baddress(drm_intel_bo *bo)
+{
+	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
+	bo_gem->supports_48baddress = 1;
+}
+
+static void drm_intel_gem_bo_clear_supports_48baddress(drm_intel_bo *bo)
+{
+	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
+	bo_gem->supports_48baddress = 0;
+}
+
 static int
 drm_intel_gem_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
 			    drm_intel_bo *target_bo, uint32_t target_offset,
@@ -2049,7 +2083,7 @@ drm_intel_gem_bo_process_reloc2(drm_intel_bo *bo)
 
 	for (i = 0; i < bo_gem->reloc_count; i++) {
 		drm_intel_bo *target_bo = bo_gem->reloc_target_info[i].bo;
-		int need_fence;
+		int need_fence, supports_48baddr;
 
 		if (target_bo == bo)
 			continue;
@@ -2062,8 +2096,12 @@ drm_intel_gem_bo_process_reloc2(drm_intel_bo *bo)
 		need_fence = (bo_gem->reloc_target_info[i].flags &
 			      DRM_INTEL_RELOC_FENCE);
 
+		supports_48baddr = (bo_gem->reloc_target_info[i].flags &
+				    DRM_INTEL_RELOC_SUPPORTS_48BADDRESS);
+
 		/* Add the target to the validate list */
-		drm_intel_add_validate_buffer2(target_bo, need_fence);
+		drm_intel_add_validate_buffer2(target_bo, need_fence,
+					       supports_48baddr);
 	}
 }
 
@@ -2508,7 +2546,7 @@ do_exec2(drm_intel_bo *bo, int used, drm_intel_context *ctx,
 	/* Add the batch buffer to the validation list.  There are no relocations
 	 * pointing to it.
 	 */
-	drm_intel_add_validate_buffer2(bo, 0);
+	drm_intel_add_validate_buffer2(bo, 0, 0);
 
 	memclear(execbuf);
 	execbuf.buffers_ptr = (uintptr_t)bufmgr_gem->exec2_objects;
@@ -3657,6 +3695,8 @@ drm_intel_bufmgr_gem_init(int fd, int batch_size)
 	bufmgr_gem->bufmgr.bo_wait_rendering = drm_intel_gem_bo_wait_rendering;
 	bufmgr_gem->bufmgr.bo_emit_reloc = drm_intel_gem_bo_emit_reloc;
 	bufmgr_gem->bufmgr.bo_emit_reloc_fence = drm_intel_gem_bo_emit_reloc_fence;
+	bufmgr_gem->bufmgr.bo_set_supports_48baddress = drm_intel_gem_bo_set_supports_48baddress;
+	bufmgr_gem->bufmgr.bo_clear_supports_48baddress = drm_intel_gem_bo_clear_supports_48baddress;
 	bufmgr_gem->bufmgr.bo_pin = drm_intel_gem_bo_pin;
 	bufmgr_gem->bufmgr.bo_unpin = drm_intel_gem_bo_unpin;
 	bufmgr_gem->bufmgr.bo_get_tiling = drm_intel_gem_bo_get_tiling;
diff --git a/intel/intel_bufmgr_priv.h b/intel/intel_bufmgr_priv.h
index 59ebd18..02fe4c8 100644
--- a/intel/intel_bufmgr_priv.h
+++ b/intel/intel_bufmgr_priv.h
@@ -152,6 +152,17 @@ struct _drm_intel_bufmgr {
 	void (*destroy) (drm_intel_bufmgr *bufmgr);
 
 	/**
+	 * Set/Clear 48-bit address support flag in a given bo.
+	 *
+	 * Any resource used with flat/heapless (0x00000000-0xfffff000)
+	 * General State Heap (GSH) or Intructions State Heap (ISH) must
+	 * be in a 32-bit range. 48-bit range will only be used when explicitly
+	 * requested.
+	 */
+	void (*bo_set_supports_48baddress) (drm_intel_bo *bo);
+	void (*bo_clear_supports_48baddress) (drm_intel_bo *bo);
+
+	/**
 	 * Add relocation entry in reloc_buf, which will be updated with the
 	 * target buffer's real offset on on command submission.
 	 *
-- 
2.4.4



More information about the Intel-gfx mailing list