}
}
+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)
{
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 =
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);
+ }
}
/**
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.
*/
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);
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.
*