From patchwork Wed Jul 1 15:28:08 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michel Thierry X-Patchwork-Id: 6704421 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id E6BF29F1C1 for ; Wed, 1 Jul 2015 15:48:47 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id AD54520741 for ; Wed, 1 Jul 2015 15:48:46 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 3625720783 for ; Wed, 1 Jul 2015 15:48:45 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F302F6EBA6; Wed, 1 Jul 2015 08:48:36 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTP id 3166D7A017; Wed, 1 Jul 2015 08:28:12 -0700 (PDT) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 01 Jul 2015 08:28:12 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.15,386,1432623600"; d="scan'208";a="738570340" Received: from michelth-linux2.isw.intel.com ([10.102.226.189]) by fmsmga001.fm.intel.com with ESMTP; 01 Jul 2015 08:28:10 -0700 From: Michel Thierry To: intel-gfx@lists.freedesktop.org Subject: [PATCH libdrm v2 1/2] intel: Add EXEC_OBJECT_SUPPORTS_48B_ADDRESS flag. Date: Wed, 1 Jul 2015 16:28:08 +0100 Message-Id: <1435764490-12029-1-git-send-email-michel.thierry@intel.com> X-Mailer: git-send-email 2.4.5 In-Reply-To: <1435062089-19877-1-git-send-email-michel.thierry@intel.com> References: <1435062089-19877-1-git-send-email-michel.thierry@intel.com> X-Mailman-Approved-At: Wed, 01 Jul 2015 08:48:33 -0700 Cc: Dave Gordon , Ben Widawsky , dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.8 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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. Calls to the new drm_intel_bo_emit_reloc_48bit function will have this flag set automatically, while calls to drm_intel_bo_emit_reloc will clear it. v2: Make set/clear functions nops on pre-gen8 platforms, and use them internally in emit_reloc functions (Ben) s/48BADDRESS/48B_ADDRESS/ (Dave) Cc: Ben Widawsky Cc: Dave Gordon Cc: dri-devel@lists.freedesktop.org Signed-off-by: Michel Thierry --- include/drm/i915_drm.h | 3 ++- intel/intel_bufmgr.c | 24 +++++++++++++++++++++ intel/intel_bufmgr.h | 8 ++++++- intel/intel_bufmgr_gem.c | 54 +++++++++++++++++++++++++++++++++++++++++++---- intel/intel_bufmgr_priv.h | 11 ++++++++++ 5 files changed, 94 insertions(+), 6 deletions(-) diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index ded43b1..426b25c 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_48B_ADDRESS (1<<3) +#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_SUPPORTS_48B_ADDRESS<<1) __u64 flags; __u64 rsvd1; diff --git a/intel/intel_bufmgr.c b/intel/intel_bufmgr.c index 14ea9f9..590a855 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_48b_address(drm_intel_bo *bo) +{ + if (bo->bufmgr->bo_set_supports_48b_address) + bo->bufmgr->bo_set_supports_48b_address(bo); +} + +void drm_intel_bo_clear_supports_48b_address(drm_intel_bo *bo) +{ + if (bo->bufmgr->bo_clear_supports_48b_address) + bo->bufmgr->bo_clear_supports_48b_address(bo); +} + int drm_intel_bo_flink(drm_intel_bo *bo, uint32_t * name) { @@ -202,6 +214,18 @@ drm_intel_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset, drm_intel_bo *target_bo, uint32_t target_offset, uint32_t read_domains, uint32_t write_domain) { + drm_intel_bo_clear_supports_48b_address(target_bo); + return bo->bufmgr->bo_emit_reloc(bo, offset, + target_bo, target_offset, + read_domains, write_domain); +} + +int +drm_intel_bo_emit_reloc_48bit(drm_intel_bo *bo, uint32_t offset, + drm_intel_bo *target_bo, uint32_t target_offset, + uint32_t read_domains, uint32_t write_domain) +{ + drm_intel_bo_set_supports_48b_address(target_bo); return bo->bufmgr->bo_emit_reloc(bo, offset, target_bo, target_offset, read_domains, write_domain); diff --git a/intel/intel_bufmgr.h b/intel/intel_bufmgr.h index 285919e..62480cb 100644 --- a/intel/intel_bufmgr.h +++ b/intel/intel_bufmgr.h @@ -87,7 +87,8 @@ struct _drm_intel_bo { /** * Last seen card virtual address (offset from the beginning of the * aperture) for the object. This should be used to fill relocation - * entries when calling drm_intel_bo_emit_reloc() + * entries when calling drm_intel_bo_emit_reloc() or + * drm_intel_bo_emit_reloc_48bit() */ uint64_t offset64; }; @@ -137,6 +138,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_48b_address(drm_intel_bo *bo); +void drm_intel_bo_clear_supports_48b_address(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, @@ -147,6 +150,9 @@ int drm_intel_bufmgr_check_aperture_space(drm_intel_bo ** bo_array, int count); int drm_intel_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset, drm_intel_bo *target_bo, uint32_t target_offset, uint32_t read_domains, uint32_t write_domain); +int drm_intel_bo_emit_reloc_48bit(drm_intel_bo *bo, uint32_t offset, + drm_intel_bo *target_bo, uint32_t target_offset, + uint32_t read_domains, uint32_t write_domain); int drm_intel_bo_emit_reloc_fence(drm_intel_bo *bo, uint32_t offset, drm_intel_bo *target_bo, uint32_t target_offset, diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c index 60c06fc..e3e2b0e 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_48B_ADDRESS (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_48b_address; + + /** * 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_48b_address) { 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_48b_address) { + bufmgr_gem->exec2_objects[bo_gem->validate_index].flags |= + EXEC_OBJECT_SUPPORTS_48B_ADDRESS; + } 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_48b_address) { + bufmgr_gem->exec2_objects[index].flags |= + EXEC_OBJECT_SUPPORTS_48B_ADDRESS; + } bufmgr_gem->exec_count++; } @@ -1931,11 +1949,33 @@ 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_48b_address) + bo_gem->reloc_target_info[bo_gem->reloc_count].flags |= + DRM_INTEL_RELOC_SUPPORTS_48B_ADDRESS; + bo_gem->reloc_count++; return 0; } +static void drm_intel_gem_bo_set_supports_48b_address(drm_intel_bo *bo) +{ + drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr; + drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo; + + if (bufmgr_gem->gen >= 8) + bo_gem->supports_48b_address = 1; +} + +static void drm_intel_gem_bo_clear_supports_48b_address(drm_intel_bo *bo) +{ + drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr; + drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo; + + if (bufmgr_gem->gen >= 8) + bo_gem->supports_48b_address = 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 +2089,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_48b_addr; if (target_bo == bo) continue; @@ -2062,8 +2102,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_48b_addr = (bo_gem->reloc_target_info[i].flags & + DRM_INTEL_RELOC_SUPPORTS_48B_ADDRESS); + /* 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_48b_addr); } } @@ -2508,7 +2552,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 +3701,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_48b_address = drm_intel_gem_bo_set_supports_48b_address; + bufmgr_gem->bufmgr.bo_clear_supports_48b_address = drm_intel_gem_bo_clear_supports_48b_address; 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..774fa02 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_48b_address) (drm_intel_bo *bo); + void (*bo_clear_supports_48b_address) (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. *