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