[Mesa-dev] [PATCH 3/3] i965: Reuse batch decoder infrastructure rather than open coding it.

Lionel Landwerlin lionel.g.landwerlin at intel.com
Wed May 2 10:55:46 UTC 2018


Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>

On 02/05/18 06:50, Kenneth Graunke wrote:
> With the new callback, Jason's newer batch decoder infrastructure
> should be able to do just as well as the old open coded INTEL_DEBUG=bat
> handling, with much less code.  If there are any limitations, we'd like
> to improve the common code rather than doing one-off hacks here.
> ---
>   src/mesa/drivers/dri/i965/brw_context.h       |   3 +
>   src/mesa/drivers/dri/i965/brw_state.h         |   1 -
>   src/mesa/drivers/dri/i965/intel_batchbuffer.c | 274 ++++--------------
>   3 files changed, 55 insertions(+), 223 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
> index 1e6a45eee1f..4a01ca5d8ab 100644
> --- a/src/mesa/drivers/dri/i965/brw_context.h
> +++ b/src/mesa/drivers/dri/i965/brw_context.h
> @@ -48,6 +48,7 @@
>   #include <brw_bufmgr.h>
>   
>   #include "common/gen_debug.h"
> +#include "common/gen_decoder.h"
>   #include "intel_screen.h"
>   #include "intel_tex_obj.h"
>   
> @@ -524,6 +525,8 @@ struct intel_batchbuffer {
>   
>      /** Map from batch offset to brw_state_batch data (with DEBUG_BATCH) */
>      struct hash_table *state_batch_sizes;
> +
> +   struct gen_batch_decode_ctx decoder;
>   };
>   
>   #define BRW_MAX_XFB_STREAMS 4
> diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
> index 9acb6257401..0417cc2aae0 100644
> --- a/src/mesa/drivers/dri/i965/brw_state.h
> +++ b/src/mesa/drivers/dri/i965/brw_state.h
> @@ -188,7 +188,6 @@ void brw_print_program_cache(struct brw_context *brw);
>   void brw_require_statebuffer_space(struct brw_context *brw, int size);
>   void *brw_state_batch(struct brw_context *brw,
>                         int size, int alignment, uint32_t *out_offset);
> -uint32_t brw_state_batch_size(struct brw_context *brw, uint32_t offset);
>   
>   /* brw_wm_surface_state.c */
>   uint32_t brw_get_surface_tiling_bits(uint32_t tiling);
> diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
> index d745c2a3113..f966b05c01a 100644
> --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c
> +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
> @@ -77,6 +77,40 @@ dump_validation_list(struct intel_batchbuffer *batch)
>      }
>   }
>   
> +static struct gen_batch_decode_bo
> +decode_get_bo(void *v_brw, uint64_t address)
> +{
> +   struct brw_context *brw = v_brw;
> +   struct intel_batchbuffer *batch = &brw->batch;
> +
> +   for (int i = 0; i < batch->exec_count; i++) {
> +      struct brw_bo *bo = batch->exec_bos[i];
> +      /* The decoder zeroes out the top 16 bits, so we need to as well */
> +      uint64_t bo_address = bo->gtt_offset & (~0ull >> 16);
> +
> +      if (address >= bo_address && address < bo_address + bo->size) {
> +         return (struct gen_batch_decode_bo) {
> +            .addr = address,
> +            .size = bo->size,
> +            .map = brw_bo_map(brw, bo, MAP_READ) + (address - bo_address),
> +         };
> +      }
> +   }
> +
> +   return (struct gen_batch_decode_bo) { };
> +}
> +
> +static unsigned
> +decode_get_state_size(void *v_brw, uint32_t offset_from_dsba)
> +{
> +   struct brw_context *brw = v_brw;
> +   struct intel_batchbuffer *batch = &brw->batch;
> +   struct hash_entry *entry =
> +      _mesa_hash_table_search(batch->state_batch_sizes,
> +                              (void *) (uintptr_t) offset_from_dsba);
> +   return entry ? (uintptr_t) entry->data : 0;
> +}
> +
>   static bool
>   uint_key_compare(const void *a, const void *b)
>   {
> @@ -126,6 +160,16 @@ intel_batchbuffer_init(struct brw_context *brw)
>      if (INTEL_DEBUG & DEBUG_BATCH) {
>         batch->state_batch_sizes =
>            _mesa_hash_table_create(NULL, uint_key_hash, uint_key_compare);
> +
> +      const unsigned decode_flags =
> +         GEN_BATCH_DECODE_FULL |
> +         ((INTEL_DEBUG & DEBUG_COLOR) ? GEN_BATCH_DECODE_IN_COLOR : 0) |
> +         GEN_BATCH_DECODE_OFFSETS |
> +         GEN_BATCH_DECODE_FLOATS;
> +
> +      gen_batch_decode_ctx_init(&batch->decoder, devinfo, stderr,
> +                                decode_flags, NULL, decode_get_bo,
> +                                decode_get_state_size, brw);
>      }
>   
>      batch->use_batch_first =
> @@ -287,8 +331,10 @@ intel_batchbuffer_free(struct intel_batchbuffer *batch)
>      brw_bo_unreference(batch->last_bo);
>      brw_bo_unreference(batch->batch.bo);
>      brw_bo_unreference(batch->state.bo);
> -   if (batch->state_batch_sizes)
> +   if (batch->state_batch_sizes) {
>         _mesa_hash_table_destroy(batch->state_batch_sizes, NULL);
> +      gen_batch_decode_ctx_finish(&batch->decoder);
> +   }
>   }
>   
>   /**
> @@ -487,215 +533,6 @@ intel_batchbuffer_require_space(struct brw_context *brw, GLuint sz,
>      brw->batch.ring = ring;
>   }
>   
> -#ifdef DEBUG
> -#define CSI "\e["
> -#define BLUE_HEADER  CSI "0;44m"
> -#define NORMAL       CSI "0m"
> -
> -
> -static void
> -decode_struct(struct brw_context *brw, struct gen_spec *spec,
> -              const char *struct_name, uint32_t *data,
> -              uint32_t gtt_offset, uint32_t offset, bool color)
> -{
> -   struct gen_group *group = gen_spec_find_struct(spec, struct_name);
> -   if (!group)
> -      return;
> -
> -   fprintf(stderr, "%s\n", struct_name);
> -   gen_print_group(stderr, group, gtt_offset + offset,
> -                   &data[offset / 4], 0, color);
> -}
> -
> -static void
> -decode_structs(struct brw_context *brw, struct gen_spec *spec,
> -               const char *struct_name,
> -               uint32_t *data, uint32_t gtt_offset, uint32_t offset,
> -               int struct_size, bool color)
> -{
> -   struct gen_group *group = gen_spec_find_struct(spec, struct_name);
> -   if (!group)
> -      return;
> -
> -   int entries = brw_state_batch_size(brw, offset) / struct_size;
> -   for (int i = 0; i < entries; i++) {
> -      fprintf(stderr, "%s %d\n", struct_name, i);
> -      gen_print_group(stderr, group, gtt_offset + offset,
> -                      &data[(offset + i * struct_size) / 4], 0, color);
> -   }
> -}
> -
> -static void
> -do_batch_dump(struct brw_context *brw)
> -{
> -   const struct gen_device_info *devinfo = &brw->screen->devinfo;
> -   struct intel_batchbuffer *batch = &brw->batch;
> -   struct gen_spec *spec = gen_spec_load(&brw->screen->devinfo);
> -
> -   if (batch->ring != RENDER_RING)
> -      return;
> -
> -   uint32_t *batch_data = brw_bo_map(brw, batch->batch.bo, MAP_READ);
> -   uint32_t *state = brw_bo_map(brw, batch->state.bo, MAP_READ);
> -   if (batch_data == NULL || state == NULL) {
> -      fprintf(stderr, "WARNING: failed to map batchbuffer/statebuffer\n");
> -      return;
> -   }
> -
> -   uint32_t *end = batch_data + USED_BATCH(*batch);
> -   uint32_t batch_gtt_offset = batch->batch.bo->gtt_offset;
> -   uint32_t state_gtt_offset = batch->state.bo->gtt_offset;
> -   int length;
> -
> -   bool color = INTEL_DEBUG & DEBUG_COLOR;
> -   const char *header_color = color ? BLUE_HEADER : "";
> -   const char *reset_color  = color ? NORMAL : "";
> -
> -   for (uint32_t *p = batch_data; p < end; p += length) {
> -      struct gen_group *inst = gen_spec_find_instruction(spec, p);
> -      length = gen_group_get_length(inst, p);
> -      assert(inst == NULL || length > 0);
> -      length = MAX2(1, length);
> -      if (inst == NULL) {
> -         fprintf(stderr, "unknown instruction %08x\n", p[0]);
> -         continue;
> -      }
> -
> -      uint64_t offset = batch_gtt_offset + 4 * (p - batch_data);
> -
> -      fprintf(stderr, "%s0x%08"PRIx64":  0x%08x:  %-80s%s\n", header_color,
> -              offset, p[0], gen_group_get_name(inst), reset_color);
> -
> -      gen_print_group(stderr, inst, offset, p, 0, color);
> -
> -      switch (gen_group_get_opcode(inst) >> 16) {
> -      case _3DSTATE_PIPELINED_POINTERS:
> -         /* Note: these Gen4-5 pointers are full relocations rather than
> -          * offsets from the start of the statebuffer.  So we need to subtract
> -          * gtt_offset (the start of the statebuffer) to obtain an offset we
> -          * can add to the map and get at the data.
> -          */
> -         decode_struct(brw, spec, "VS_STATE", state, state_gtt_offset,
> -                       (p[1] & ~0x1fu) - state_gtt_offset, color);
> -         if (p[2] & 1) {
> -            decode_struct(brw, spec, "GS_STATE", state, state_gtt_offset,
> -                          (p[2] & ~0x1fu) - state_gtt_offset, color);
> -         }
> -         if (p[3] & 1) {
> -            decode_struct(brw, spec, "CLIP_STATE", state, state_gtt_offset,
> -                          (p[3] & ~0x1fu) - state_gtt_offset, color);
> -         }
> -         decode_struct(brw, spec, "SF_STATE", state, state_gtt_offset,
> -                       (p[4] & ~0x1fu) - state_gtt_offset, color);
> -         decode_struct(brw, spec, "WM_STATE", state, state_gtt_offset,
> -                       (p[5] & ~0x1fu) - state_gtt_offset, color);
> -         decode_struct(brw, spec, "COLOR_CALC_STATE", state, state_gtt_offset,
> -                       (p[6] & ~0x3fu) - state_gtt_offset, color);
> -         break;
> -      case _3DSTATE_BINDING_TABLE_POINTERS_VS:
> -      case _3DSTATE_BINDING_TABLE_POINTERS_HS:
> -      case _3DSTATE_BINDING_TABLE_POINTERS_DS:
> -      case _3DSTATE_BINDING_TABLE_POINTERS_GS:
> -      case _3DSTATE_BINDING_TABLE_POINTERS_PS: {
> -         struct gen_group *group =
> -            gen_spec_find_struct(spec, "RENDER_SURFACE_STATE");
> -         if (!group)
> -            break;
> -
> -         uint32_t bt_offset = p[1] & ~0x1fu;
> -         int bt_entries = brw_state_batch_size(brw, bt_offset) / 4;
> -         uint32_t *bt_pointers = &state[bt_offset / 4];
> -         for (int i = 0; i < bt_entries; i++) {
> -            fprintf(stderr, "SURFACE_STATE - BTI = %d\n", i);
> -            gen_print_group(stderr, group, state_gtt_offset + bt_pointers[i],
> -                            &state[bt_pointers[i] / 4], 0, color);
> -         }
> -         break;
> -      }
> -      case _3DSTATE_SAMPLER_STATE_POINTERS_VS:
> -      case _3DSTATE_SAMPLER_STATE_POINTERS_HS:
> -      case _3DSTATE_SAMPLER_STATE_POINTERS_DS:
> -      case _3DSTATE_SAMPLER_STATE_POINTERS_GS:
> -      case _3DSTATE_SAMPLER_STATE_POINTERS_PS:
> -         decode_structs(brw, spec, "SAMPLER_STATE", state,
> -                        state_gtt_offset, p[1] & ~0x1fu, 4 * 4, color);
> -         break;
> -      case _3DSTATE_VIEWPORT_STATE_POINTERS:
> -         decode_structs(brw, spec, "CLIP_VIEWPORT", state,
> -                        state_gtt_offset, p[1] & ~0x3fu, 4 * 4, color);
> -         decode_structs(brw, spec, "SF_VIEWPORT", state,
> -                        state_gtt_offset, p[1] & ~0x3fu, 8 * 4, color);
> -         decode_structs(brw, spec, "CC_VIEWPORT", state,
> -                        state_gtt_offset, p[3] & ~0x3fu, 2 * 4, color);
> -         break;
> -      case _3DSTATE_VIEWPORT_STATE_POINTERS_CC:
> -         decode_structs(brw, spec, "CC_VIEWPORT", state,
> -                        state_gtt_offset, p[1] & ~0x3fu, 2 * 4, color);
> -         break;
> -      case _3DSTATE_VIEWPORT_STATE_POINTERS_SF_CL:
> -         decode_structs(brw, spec, "SF_CLIP_VIEWPORT", state,
> -                        state_gtt_offset, p[1] & ~0x3fu, 16 * 4, color);
> -         break;
> -      case _3DSTATE_SCISSOR_STATE_POINTERS:
> -         decode_structs(brw, spec, "SCISSOR_RECT", state,
> -                        state_gtt_offset, p[1] & ~0x1fu, 2 * 4, color);
> -         break;
> -      case _3DSTATE_BLEND_STATE_POINTERS:
> -         /* TODO: handle Gen8+ extra dword at the beginning */
> -         decode_structs(brw, spec, "BLEND_STATE", state,
> -                        state_gtt_offset, p[1] & ~0x3fu, 8 * 4, color);
> -         break;
> -      case _3DSTATE_CC_STATE_POINTERS:
> -         if (devinfo->gen >= 7) {
> -            decode_struct(brw, spec, "COLOR_CALC_STATE", state,
> -                          state_gtt_offset, p[1] & ~0x3fu, color);
> -         } else if (devinfo->gen == 6) {
> -            decode_structs(brw, spec, "BLEND_STATE", state,
> -                           state_gtt_offset, p[1] & ~0x3fu, 2 * 4, color);
> -            decode_struct(brw, spec, "DEPTH_STENCIL_STATE", state,
> -                          state_gtt_offset, p[2] & ~0x3fu, color);
> -            decode_struct(brw, spec, "COLOR_CALC_STATE", state,
> -                          state_gtt_offset, p[3] & ~0x3fu, color);
> -         }
> -         break;
> -      case _3DSTATE_DEPTH_STENCIL_STATE_POINTERS:
> -         decode_struct(brw, spec, "DEPTH_STENCIL_STATE", state,
> -                       state_gtt_offset, p[1] & ~0x3fu, color);
> -         break;
> -      case MEDIA_INTERFACE_DESCRIPTOR_LOAD: {
> -         struct gen_group *group =
> -            gen_spec_find_struct(spec, "RENDER_SURFACE_STATE");
> -         if (!group)
> -            break;
> -
> -         uint32_t idd_offset = p[3] & ~0x1fu;
> -         decode_struct(brw, spec, "INTERFACE_DESCRIPTOR_DATA", state,
> -                       state_gtt_offset, idd_offset, color);
> -
> -         uint32_t ss_offset = state[idd_offset / 4 + 3] & ~0x1fu;
> -         decode_structs(brw, spec, "SAMPLER_STATE", state,
> -                        state_gtt_offset, ss_offset, 4 * 4, color);
> -
> -         uint32_t bt_offset = state[idd_offset / 4 + 4] & ~0x1fu;
> -         int bt_entries = brw_state_batch_size(brw, bt_offset) / 4;
> -         uint32_t *bt_pointers = &state[bt_offset / 4];
> -         for (int i = 0; i < bt_entries; i++) {
> -            fprintf(stderr, "SURFACE_STATE - BTI = %d\n", i);
> -            gen_print_group(stderr, group, state_gtt_offset + bt_pointers[i],
> -                            &state[bt_pointers[i] / 4], 0, color);
> -         }
> -         break;
> -      }
> -      }
> -   }
> -
> -   brw_bo_unmap(batch->batch.bo);
> -   brw_bo_unmap(batch->state.bo);
> -}
> -#else
> -static void do_batch_dump(struct brw_context *brw) { }
> -#endif
> -
>   /**
>    * Called when starting a new batch buffer.
>    */
> @@ -983,8 +820,11 @@ submit_batch(struct brw_context *brw, int in_fence_fd, int *out_fence_fd)
>         throttle(brw);
>      }
>   
> -   if (unlikely(INTEL_DEBUG & DEBUG_BATCH))
> -      do_batch_dump(brw);
> +   if (unlikely(INTEL_DEBUG & DEBUG_BATCH)) {
> +      gen_print_batch(&batch->decoder, batch->batch.map,
> +                      4 * USED_BATCH(*batch),
> +                      batch->batch.bo->gtt_offset);
> +   }
>   
>      if (brw->ctx.Const.ResetStrategy == GL_LOSE_CONTEXT_ON_RESET_ARB)
>         brw_check_for_reset(brw);
> @@ -1152,16 +992,6 @@ brw_state_reloc(struct intel_batchbuffer *batch, uint32_t state_offset,
>                        target, target_offset, reloc_flags);
>   }
>   
> -
> -uint32_t
> -brw_state_batch_size(struct brw_context *brw, uint32_t offset)
> -{
> -   struct hash_entry *entry =
> -      _mesa_hash_table_search(brw->batch.state_batch_sizes,
> -                              (void *) (uintptr_t) offset);
> -   return entry ? (uintptr_t) entry->data : 0;
> -}
> -
>   /**
>    * Reserve some space in the statebuffer, or flush.
>    *




More information about the mesa-dev mailing list