drm/radeon/kms: improve performance of blit-copy

Ilija Hadzic ihadzic at research.bell-labs.com
Thu Oct 13 11:21:09 PDT 2011


Dave,

Alex pointed to me that the patches I sent last night under this thread 
may conflict with 003cefe0c238e683a29d2207dba945b508cd45b7 that currently 
resides on drm-fixes branch (my patches are based on drm-next or 
drm-core-next).

I'd like to make sure that the eventual merge goes smoothly:

If you merge drm-fixes before my patches, then I'll rebase my patches and 
resend them after that happens and make sure everything is resolved 
correctly.

If you merge my patches first and then follow with drm-fixes merge, two 
things should happen with 003cefe0c238e683a29d2207dba945b508cd45b7. Hunks 
related to evergreen.c file will fall out but that's expected and OK 
because my patches consolidate the blit code for r600 and evergreen into a 
common one. Then in r600.c, the hunks related to r600_blit_prepare_copy
and r600_kms_blit_copy function calls will show conflicts, which should be 
resolved such that the size argument is num_gpu_pages, not
num_gpu_pages * RADEON_GPU_PAGE_SIZE (this is because the new blit code
takes size argument in pages, not bytes). Everything else will merge 
smoothly.

For reference, pasted below is a patch that resulted after I cherry-picked 
003cefe0c238e683a29d2207dba945b508cd45b7 into drm-next augmented with my 
blit-improvement patches and resolved the conflicts correctly.

I guess the first option is less work for you (and I will be glad to 
rebase my patches if need be), but I hope that the info here is good 
enough to make the second path as easy as it can be

thanks,

Ilija


From b12516c003cb35059f16ace774ef5a21170d6d78 Mon Sep 17 00:00:00 2001
From: Alex Deucher <alexander.deucher at amd.com>
Date: Fri, 16 Sep 2011 12:04:08 -0400
Subject: [PATCH 11/14] drm/radeon/kms: Make GPU/CPU page size handling
  consistent in blit code (v3)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The BO blit code inconsistenly handled the page size.  This wasn't
an issue on system with 4k pages since the GPU's page size is 4k as
well.  Switch the driver blit callbacks to take num pages in GPU
page units.

Fixes lemote mipsel systems using AMD rs780/rs880 chipsets.

v2: incorporate suggestions from Michel.

Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
Cc: stable at kernel.org
Signed-off-by: Dave Airlie <airlied at redhat.com>

v3: reconcile with changes due to blit-copy improvements on drm-next
     branch

     substitutes the v2 patch that currently resides on drm-fixes
     branch

Conflicts:

 	drivers/gpu/drm/radeon/evergreen.c
 	drivers/gpu/drm/radeon/r600.c
 	drivers/gpu/drm/radeon/radeon_asic.h

Signed-off-by: Ilija Hadzic <ihadzic at research.bell-labs.com>
---
  drivers/gpu/drm/radeon/r100.c        |   12 ++++++------
  drivers/gpu/drm/radeon/r200.c        |    4 ++--
  drivers/gpu/drm/radeon/r600.c        |   10 ++++++----
  drivers/gpu/drm/radeon/radeon.h      |    7 ++++---
  drivers/gpu/drm/radeon/radeon_asic.h |    6 +++---
  drivers/gpu/drm/radeon/radeon_ttm.c  |    7 ++++++-
  6 files changed, 27 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 5985cb0..df60803 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -724,11 +724,11 @@ void r100_fence_ring_emit(struct radeon_device *rdev,
  int r100_copy_blit(struct radeon_device *rdev,
  		   uint64_t src_offset,
  		   uint64_t dst_offset,
-		   unsigned num_pages,
+		   unsigned num_gpu_pages,
  		   struct radeon_fence *fence)
  {
  	uint32_t cur_pages;
-	uint32_t stride_bytes = PAGE_SIZE;
+	uint32_t stride_bytes = RADEON_GPU_PAGE_SIZE;
  	uint32_t pitch;
  	uint32_t stride_pixels;
  	unsigned ndw;
@@ -740,7 +740,7 @@ int r100_copy_blit(struct radeon_device *rdev,
  	/* radeon pitch is /64 */
  	pitch = stride_bytes / 64;
  	stride_pixels = stride_bytes / 4;
-	num_loops = DIV_ROUND_UP(num_pages, 8191);
+	num_loops = DIV_ROUND_UP(num_gpu_pages, 8191);

  	/* Ask for enough room for blit + flush + fence */
  	ndw = 64 + (10 * num_loops);
@@ -749,12 +749,12 @@ int r100_copy_blit(struct radeon_device *rdev,
  		DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw);
  		return -EINVAL;
  	}
-	while (num_pages > 0) {
-		cur_pages = num_pages;
+	while (num_gpu_pages > 0) {
+		cur_pages = num_gpu_pages;
  		if (cur_pages > 8191) {
  			cur_pages = 8191;
  		}
-		num_pages -= cur_pages;
+		num_gpu_pages -= cur_pages;

  		/* pages are in Y direction - height
  		   page width in X direction - width */
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c
index f240583..a1f3ba0 100644
--- a/drivers/gpu/drm/radeon/r200.c
+++ b/drivers/gpu/drm/radeon/r200.c
@@ -84,7 +84,7 @@ static int r200_get_vtx_size_0(uint32_t vtx_fmt_0)
  int r200_copy_dma(struct radeon_device *rdev,
  		  uint64_t src_offset,
  		  uint64_t dst_offset,
-		  unsigned num_pages,
+		  unsigned num_gpu_pages,
  		  struct radeon_fence *fence)
  {
  	uint32_t size;
@@ -93,7 +93,7 @@ int r200_copy_dma(struct radeon_device *rdev,
  	int r = 0;

  	/* radeon pitch is /64 */
-	size = num_pages << PAGE_SHIFT;
+	size = num_gpu_pages << RADEON_GPU_PAGE_SHIFT;
  	num_loops = DIV_ROUND_UP(size, 0x1FFFFF);
  	r = radeon_ring_lock(rdev, num_loops * 4 + 64);
  	if (r) {
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 9fc6844..db652ed 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2356,21 +2356,23 @@ void r600_fence_ring_emit(struct radeon_device *rdev,
  }

  int r600_copy_blit(struct radeon_device *rdev,
-		   uint64_t src_offset, uint64_t dst_offset,
-		   unsigned num_pages, struct radeon_fence *fence)
+		   uint64_t src_offset,
+		   uint64_t dst_offset,
+		   unsigned num_gpu_pages,
+		   struct radeon_fence *fence)
  {
  	int r;

  	mutex_lock(&rdev->r600_blit.mutex);
  	rdev->r600_blit.vb_ib = NULL;
-	r = r600_blit_prepare_copy(rdev, num_pages);
+	r = r600_blit_prepare_copy(rdev, num_gpu_pages);
  	if (r) {
  		if (rdev->r600_blit.vb_ib)
  			radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
  		mutex_unlock(&rdev->r600_blit.mutex);
  		return r;
  	}
-	r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages);
+	r600_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages);
  	r600_blit_done_copy(rdev, fence);
  	mutex_unlock(&rdev->r600_blit.mutex);
  	return 0;
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 4841b09..7b2e1d5 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -322,6 +322,7 @@ union radeon_gart_table {

  #define RADEON_GPU_PAGE_SIZE 4096
  #define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1)
+#define RADEON_GPU_PAGE_SHIFT 12

  struct radeon_gart {
  	dma_addr_t			table_addr;
@@ -935,17 +936,17 @@ struct radeon_asic {
  	int (*copy_blit)(struct radeon_device *rdev,
  			 uint64_t src_offset,
  			 uint64_t dst_offset,
-			 unsigned num_pages,
+			 unsigned num_gpu_pages,
  			 struct radeon_fence *fence);
  	int (*copy_dma)(struct radeon_device *rdev,
  			uint64_t src_offset,
  			uint64_t dst_offset,
-			unsigned num_pages,
+			unsigned num_gpu_pages,
  			struct radeon_fence *fence);
  	int (*copy)(struct radeon_device *rdev,
  		    uint64_t src_offset,
  		    uint64_t dst_offset,
-		    unsigned num_pages,
+		    unsigned num_gpu_pages,
  		    struct radeon_fence *fence);
  	uint32_t (*get_engine_clock)(struct radeon_device *rdev);
  	void (*set_engine_clock)(struct radeon_device *rdev, uint32_t eng_clock);
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index e040de3..85f14f0 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -75,7 +75,7 @@ uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg);
  int r100_copy_blit(struct radeon_device *rdev,
  		   uint64_t src_offset,
  		   uint64_t dst_offset,
-		   unsigned num_pages,
+		   unsigned num_gpu_pages,
  		   struct radeon_fence *fence);
  int r100_set_surface_reg(struct radeon_device *rdev, int reg,
  			 uint32_t tiling_flags, uint32_t pitch,
@@ -143,7 +143,7 @@ extern void r100_post_page_flip(struct radeon_device *rdev, int crtc);
  extern int r200_copy_dma(struct radeon_device *rdev,
  			 uint64_t src_offset,
  			 uint64_t dst_offset,
-			 unsigned num_pages,
+			 unsigned num_gpu_pages,
  			 struct radeon_fence *fence);
  void r200_set_safe_registers(struct radeon_device *rdev);

@@ -311,7 +311,7 @@ void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
  int r600_ring_test(struct radeon_device *rdev);
  int r600_copy_blit(struct radeon_device *rdev,
  		   uint64_t src_offset, uint64_t dst_offset,
-		   unsigned num_pages, struct radeon_fence *fence);
+		   unsigned num_gpu_pages, struct radeon_fence *fence);
  void r600_hpd_init(struct radeon_device *rdev);
  void r600_hpd_fini(struct radeon_device *rdev);
  bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 9b86fb0..0b5468b 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -277,7 +277,12 @@ static int radeon_move_blit(struct ttm_buffer_object *bo,
  		DRM_ERROR("Trying to move memory with CP turned off.\n");
  		return -EINVAL;
  	}
-	r = radeon_copy(rdev, old_start, new_start, new_mem->num_pages, fence);
+
+	BUILD_BUG_ON((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) != 0);
+
+	r = radeon_copy(rdev, old_start, new_start,
+			new_mem->num_pages * (PAGE_SIZE / RADEON_GPU_PAGE_SIZE), /* GPU pages */
+			fence);
  	/* FIXME: handle copy error */
  	r = ttm_bo_move_accel_cleanup(bo, (void *)fence, NULL,
  				      evict, no_wait_reserve, no_wait_gpu, new_mem);
-- 
1.7.7





More information about the dri-devel mailing list