From 0ab423388cd5a74472a84adb557527b1589fc652 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 1 May 2018 17:16:06 -0700 Subject: [PATCH] i965: Reuse batch decoder infrastructure rather than open coding it. 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. Reviewed-by: Lionel Landwerlin --- 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 be43eab43cc..23406816a9b 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -48,6 +48,7 @@ #include #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 b511be37419..b3e4bdc981e 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) { @@ -122,6 +156,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 = @@ -285,8 +329,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); + } } /** @@ -485,215 +531,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. */ @@ -981,8 +818,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); @@ -1150,16 +990,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. * -- 2.30.2