On Sun, Jul 10, 2011 at 4:31 PM, Vadim Girlin <[email protected]> wrote:
> This patch uses ZPASS_DONE counters to get the mask on context creation,
> then uses it for query buffer initialization.
>
> Signed-off-by: Vadim Girlin <[email protected]>
> ---
>
> Probably it's not the best way, but i hope it should be more reliable than
> the current implementation. I've tested it with the juniper card which uses
> backends 0 & 2 only (don't know if it is normal, maybe the card is broken,
> or it's hw configuration bug, but it works fine). This patch fixes lockups 
> with
> conditional rendering. Current implementation doesn't set highest bits for
> backends 1 & 3 and then conditional rendering causes gpu lockups.

We could use this as a backup for older kernels, but the proper way is
to add a RADEON_INFO query to get the backend map from the kernel.
The drm sets up the backend map when it initializes the GPU.  That
attached patch should be a good start.

Alex

>
>  src/gallium/drivers/r600/r600.h                    |    2 +
>  src/gallium/winsys/r600/drm/evergreen_hw_context.c |    2 +
>  src/gallium/winsys/r600/drm/r600_hw_context.c      |   68 
> +++++++++++++++++++-
>  3 files changed, 69 insertions(+), 3 deletions(-)
>
> diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h
> index 2af4d31..b9689df 100644
> --- a/src/gallium/drivers/r600/r600.h
> +++ b/src/gallium/drivers/r600/r600.h
> @@ -254,6 +254,7 @@ struct r600_context {
>        u32                     *pm4;
>        struct list_head        query_list;
>        unsigned                num_query_running;
> +       unsigned                zpass_backends_mask;
>        struct list_head        fenced_bo;
>        unsigned                max_db; /* for OQ */
>        unsigned                num_dest_buffers;
> @@ -275,6 +276,7 @@ struct r600_draw {
>        struct r600_bo          *indices;
>  };
>
> +void r600_get_zpass_backends_mask(struct r600_context *ctx);
>  int r600_context_init(struct r600_context *ctx, struct radeon *radeon);
>  void r600_context_fini(struct r600_context *ctx);
>  void r600_context_pipe_state_set(struct r600_context *ctx, struct 
> r600_pipe_state *state);
> diff --git a/src/gallium/winsys/r600/drm/evergreen_hw_context.c 
> b/src/gallium/winsys/r600/drm/evergreen_hw_context.c
> index 4d9dd50..87445ab 100644
> --- a/src/gallium/winsys/r600/drm/evergreen_hw_context.c
> +++ b/src/gallium/winsys/r600/drm/evergreen_hw_context.c
> @@ -1018,6 +1018,8 @@ int evergreen_context_init(struct r600_context *ctx, 
> struct radeon *radeon)
>
>        LIST_INITHEAD(&ctx->fenced_bo);
>
> +       r600_get_zpass_backends_mask(ctx);
> +
>        return 0;
>  out_err:
>        r600_context_fini(ctx);
> diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c 
> b/src/gallium/winsys/r600/drm/r600_hw_context.c
> index a2f13ff..2fafe35 100644
> --- a/src/gallium/winsys/r600/drm/r600_hw_context.c
> +++ b/src/gallium/winsys/r600/drm/r600_hw_context.c
> @@ -40,6 +40,64 @@
>
>  #define GROUP_FORCE_NEW_BLOCK  0
>
> +/* Get backends mask for ZPASS_DONE event */
> +void r600_get_zpass_backends_mask(struct r600_context *ctx)
> +{
> +       struct r600_bo * buffer;
> +       u32 * results;
> +       unsigned i, mask = 0;
> +
> +       /* create buffer for event data */
> +       buffer = r600_bo(ctx->radeon, ctx->max_db*16, 1, 0,
> +                               PIPE_USAGE_STAGING);
> +       if (!buffer)
> +               goto err;
> +
> +       /* initialize buffer with zeroes */
> +       results = r600_bo_map(ctx->radeon, buffer, PB_USAGE_CPU_WRITE, NULL);
> +       if (results) {
> +               memset(results, 0, ctx->max_db * 4 * 4);
> +               r600_bo_unmap(ctx->radeon, buffer);
> +
> +               /* emit EVENT_WRITE for ZPASS_DONE */
> +               ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 2, 0);
> +               ctx->pm4[ctx->pm4_cdwords++] = 
> EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1);
> +               ctx->pm4[ctx->pm4_cdwords++] = r600_bo_offset(buffer);
> +               ctx->pm4[ctx->pm4_cdwords++] = 0;
> +
> +               ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0, 0);
> +               ctx->pm4[ctx->pm4_cdwords++] = 0;
> +               r600_context_bo_reloc(ctx, &ctx->pm4[ctx->pm4_cdwords - 1], 
> buffer);
> +
> +               /* execute */
> +               r600_context_flush(ctx);
> +
> +               /* analyze results */
> +               results = r600_bo_map(ctx->radeon, buffer, PB_USAGE_CPU_READ, 
> NULL);
> +               if (results) {
> +                       for(i = 0; i < ctx->max_db; i++) {
> +                               /* if highest bit is set then backend is used 
> */
> +                               if (results[i*4 + 1] & 0x80000000) {
> +                                       mask |= (1<<i);
> +                               }
> +                       }
> +                       r600_bo_unmap(ctx->radeon, buffer);
> +               }
> +       }
> +
> +       r600_bo_reference(ctx->radeon, &buffer, NULL);
> +
> +       if (mask != 0) {
> +               ctx->zpass_backends_mask = mask;
> +               return;
> +       }
> +
> +err:
> +       /* fallback to old method - set num_backends lower bits to 1 */
> +       ctx->zpass_backends_mask = 
> (~((u32)0))>>(32-r600_get_num_backends(ctx->radeon));
> +       return;
> +}
> +
>  static inline void r600_context_ps_partial_flush(struct r600_context *ctx)
>  {
>        if (!(ctx->flags & R600_CONTEXT_DRAW_PENDING))
> @@ -899,6 +957,8 @@ int r600_context_init(struct r600_context *ctx, struct 
> radeon *radeon)
>
>        ctx->max_db = 4;
>
> +       r600_get_zpass_backends_mask(ctx);
> +
>        return 0;
>  out_err:
>        r600_context_fini(ctx);
> @@ -1759,9 +1819,11 @@ void r600_query_begin(struct r600_context *ctx, struct 
> r600_query *query)
>                if (results) {
>                        memset(results + query->num_results, 0, ctx->max_db * 
> 4 * 4);
>
> -                       for (i = num_backends; i < ctx->max_db; i++) {
> -                               results[(i * 4)+1] = 0x80000000;
> -                               results[(i * 4)+3] = 0x80000000;
> +                       for (i = 0; i < ctx->max_db; i++) {
> +                               if (!(ctx->zpass_backends_mask & (1<<i))) {
> +                                       results[(i * 4)+1] = 0x80000000;
> +                                       results[(i * 4)+3] = 0x80000000;
> +                               }
>                        }
>                        r600_bo_unmap(ctx->radeon, query->buffer);
>                }
> --
> 1.7.6
>
> _______________________________________________
> mesa-dev mailing list
> [email protected]
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
From f2a431c8882c10c1094f165d56552ac02c963bb7 Mon Sep 17 00:00:00 2001
From: Alex Deucher <[email protected]>
Date: Sun, 10 Jul 2011 19:31:05 -0400
Subject: [PATCH] drm/radeon/kms: add info query for backend map

The 3D driver need to get the pipe to backend
map to certain things.  Add a query to get the
info.

Signed-off-by: Alex Deucher <[email protected]>
---
 drivers/gpu/drm/radeon/evergreen.c  |    1 +
 drivers/gpu/drm/radeon/ni.c         |    1 +
 drivers/gpu/drm/radeon/r600.c       |    1 +
 drivers/gpu/drm/radeon/radeon.h     |    3 +++
 drivers/gpu/drm/radeon/radeon_drv.c |    3 ++-
 drivers/gpu/drm/radeon/radeon_kms.c |   13 +++++++++++++
 drivers/gpu/drm/radeon/rv770.c      |    1 +
 include/drm/radeon_drm.h            |    1 +
 8 files changed, 23 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 8d7bd90..0e3bacc 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -2047,6 +2047,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
 	rdev->config.evergreen.tile_config |=
 		((gb_addr_config & 0x30000000) >> 28) << 12;
 
+	rdev->config.evergreen.backend_map = gb_backend_map;
 	WREG32(GB_BACKEND_MAP, gb_backend_map);
 	WREG32(GB_ADDR_CONFIG, gb_addr_config);
 	WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 16caafe..93af56d 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -833,6 +833,7 @@ static void cayman_gpu_init(struct radeon_device *rdev)
 	rdev->config.cayman.tile_config |=
 		((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12;
 
+	rdev->config.cayman.backend_map = gb_backend_map;
 	WREG32(GB_BACKEND_MAP, gb_backend_map);
 	WREG32(GB_ADDR_CONFIG, gb_addr_config);
 	WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index f79d2cc..48abb6d 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -1662,6 +1662,7 @@ void r600_gpu_init(struct radeon_device *rdev)
 									       R6XX_MAX_BACKENDS_MASK) >> 16)),
 							(cc_rb_backend_disable >> 16));
 	rdev->config.r600.tile_config = tiling_config;
+	rdev->config.r600.backend_map = backend_map;
 	tiling_config |= BACKEND_MAP(backend_map);
 	WREG32(GB_TILING_CONFIG, tiling_config);
 	WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff);
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index ef0e0e0..ec534f5 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1003,6 +1003,7 @@ struct r600_asic {
 	unsigned		tiling_npipes;
 	unsigned		tiling_group_size;
 	unsigned		tile_config;
+	unsigned		backend_map;
 	struct r100_gpu_lockup	lockup;
 };
 
@@ -1028,6 +1029,7 @@ struct rv770_asic {
 	unsigned		tiling_npipes;
 	unsigned		tiling_group_size;
 	unsigned		tile_config;
+	unsigned		backend_map;
 	struct r100_gpu_lockup	lockup;
 };
 
@@ -1054,6 +1056,7 @@ struct evergreen_asic {
 	unsigned tiling_npipes;
 	unsigned tiling_group_size;
 	unsigned tile_config;
+	unsigned backend_map;
 	struct r100_gpu_lockup	lockup;
 };
 
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 73dfbe8..3e81e21 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -51,9 +51,10 @@
  *   2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf, r300->r500 CMASK, clock crystal query
  *   2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query
  *   2.10.0 - fusion 2D tiling
+ *   2.11.0 - add backend_map query
  */
 #define KMS_DRIVER_MAJOR	2
-#define KMS_DRIVER_MINOR	10
+#define KMS_DRIVER_MINOR	11
 #define KMS_DRIVER_PATCHLEVEL	0
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
 int radeon_driver_unload_kms(struct drm_device *dev);
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index bd58af6..8302c11 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -237,6 +237,19 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 	case RADEON_INFO_FUSION_GART_WORKING:
 		value = 1;
 		break;
+	case RADEON_INFO_BACKEND_MAP:
+		if (rdev->family >= CHIP_CAYMAN)
+			value = rdev->config.cayman.backend_map;
+		else if (rdev->family >= CHIP_CEDAR)
+			value = rdev->config.evergreen.backend_map;
+		else if (rdev->family >= CHIP_RV770)
+			value = rdev->config.rv770.backend_map;
+		else if (rdev->family >= CHIP_R600)
+			value = rdev->config.r600.backend_map;
+		else {
+			return -EINVAL;
+		}
+		break;
 	default:
 		DRM_DEBUG_KMS("Invalid request %d\n", info->request);
 		return -EINVAL;
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 8bb347d..7b5e9cb 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -778,6 +778,7 @@ static void rv770_gpu_init(struct radeon_device *rdev)
 								(cc_rb_backend_disable >> 16));
 
 	rdev->config.rv770.tile_config = gb_tiling_config;
+	rdev->config.rv770.backend_map = backend_map;
 	gb_tiling_config |= BACKEND_MAP(backend_map);
 
 	WREG32(GB_TILING_CONFIG, gb_tiling_config);
diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h
index 787f7b6..b65be60 100644
--- a/include/drm/radeon_drm.h
+++ b/include/drm/radeon_drm.h
@@ -911,6 +911,7 @@ struct drm_radeon_cs {
 #define RADEON_INFO_NUM_BACKENDS	0x0a /* DB/backends for r600+ - need for OQ */
 #define RADEON_INFO_NUM_TILE_PIPES	0x0b /* tile pipes for r600+ */
 #define RADEON_INFO_FUSION_GART_WORKING	0x0c /* fusion writes to GTT were broken before this */
+#define RADEON_INFO_BACKEND_MAP		0x0d /* pipe to backend map, needed by mesa */
 
 struct drm_radeon_info {
 	uint32_t		request;
-- 
1.7.1.1

_______________________________________________
mesa-dev mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to