[Mesa-dev] [PATCH] r600g: get and use backends mask for occlusion queries

Alex Deucher alexdeucher at gmail.com
Sun Jul 10 16:33:35 PDT 2011


On Sun, Jul 10, 2011 at 4:31 PM, Vadim Girlin <vadimgirlin at gmail.com> 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 <vadimgirlin at gmail.com>
> ---
>
> 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
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-drm-radeon-kms-add-info-query-for-backend-map.patch
Type: text/x-diff
Size: 5921 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20110710/cf9649b3/attachment.patch>


More information about the mesa-dev mailing list