diff options
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_context.h | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_state.h | 1 | ||||
-rw-r--r-- | 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 <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 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. * |