return (struct gen_batch_decode_bo) { };
}
+static unsigned
+decode_get_state_size(void *v_batch, uint32_t offset_from_base)
+{
+ struct iris_batch *batch = v_batch;
+
+ /* The decoder gives us offsets from a base address, which is not great.
+ * Binding tables are relative to surface state base address, and other
+ * state is relative to dynamic state base address. These could alias,
+ * but in practice it's unlikely because surface offsets are always in
+ * the [0, 64K) range, and we assign dynamic state addresses starting at
+ * the top of the 4GB range. We should fix this but it's likely good
+ * enough for now.
+ */
+ unsigned size = (uintptr_t)
+ _mesa_hash_table_u64_search(batch->state_sizes, offset_from_base);
+
+ return size;
+}
+
/**
* Decode the current batch.
*/
struct iris_vtable *vtbl,
struct pipe_debug_callback *dbg,
struct pipe_device_reset_callback *reset,
+ struct hash_table_u64 *state_sizes,
struct iris_batch *all_batches,
enum iris_batch_name name,
uint8_t engine,
batch->vtbl = vtbl;
batch->dbg = dbg;
batch->reset = reset;
+ batch->state_sizes = state_sizes;
batch->name = name;
/* engine should be one of I915_EXEC_RENDER, I915_EXEC_BLT, etc. */
GEN_BATCH_DECODE_OFFSETS |
GEN_BATCH_DECODE_FLOATS;
- /* TODO: track state size so we can print the right # of entries */
gen_batch_decode_ctx_init(&batch->decoder, &screen->devinfo,
stderr, decode_flags, NULL,
- decode_get_bo, NULL, batch);
+ decode_get_bo, decode_get_state_size, batch);
batch->decoder.max_vbo_decoded_lines = 32;
}
} cache;
struct gen_batch_decode_ctx decoder;
+ struct hash_table_u64 *state_sizes;
/** Have we emitted any draw calls to this batch? */
bool contains_draw;
struct iris_vtable *vtbl,
struct pipe_debug_callback *dbg,
struct pipe_device_reset_callback *reset,
+ struct hash_table_u64 *state_sizes,
struct iris_batch *all_batches,
enum iris_batch_name name,
uint8_t ring,
iris_syncpt_reference(batch->screen, out_syncpt, syncpt);
}
+/**
+ * Record the size of a piece of state for use in INTEL_DEBUG=bat printing.
+ */
+static inline void
+iris_record_state_size(struct hash_table_u64 *ht,
+ uint32_t offset_from_base,
+ uint32_t size)
+{
+ if (ht) {
+ _mesa_hash_table_u64_insert(ht, offset_from_base,
+ (void *)(uintptr_t) size);
+ }
+}
+
#endif
for (int stage = 0; stage <= MESA_SHADER_FRAGMENT; stage++) {
if (ice->state.dirty & (IRIS_DIRTY_BINDINGS_VS << stage)) {
binder->bt_offset[stage] = sizes[stage] > 0 ? offset : 0;
+ iris_record_state_size(ice->state.sizes,
+ binder->bo->gtt_offset + offset, sizes[stage]);
offset += sizes[stage];
}
}
struct iris_bo *bo = iris_resource_bo(res);
iris_use_pinned_bo(batch, bo, false);
+ iris_record_state_size(batch->state_sizes,
+ bo->gtt_offset + *out_offset, size);
+
/* If the caller has asked for a BO, we leave them the responsibility of
* adding bo->gtt_offset (say, by handing an address to genxml). If not,
* we assume they want the offset from a base address.
if (flags & PIPE_CONTEXT_LOW_PRIORITY)
priority = GEN_CONTEXT_LOW_PRIORITY;
+ if (unlikely(INTEL_DEBUG & DEBUG_BATCH))
+ ice->state.sizes = _mesa_hash_table_u64_create(ice);
+
for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
iris_init_batch(&ice->batches[i], screen, &ice->vtbl, &ice->dbg,
- &ice->reset, ice->batches, (enum iris_batch_name) i,
+ &ice->reset, ice->state.sizes,
+ ice->batches, (enum iris_batch_name) i,
I915_EXEC_RENDER, priority);
}
struct pipe_resource *blend;
struct pipe_resource *index_buffer;
} last_res;
+
+ /** Records the size of variable-length state for INTEL_DEBUG=bat */
+ struct hash_table_u64 *sizes;
} state;
};
*out_offset += iris_bo_offset_from_base_address(bo);
+ iris_record_state_size(batch->state_sizes, *out_offset, size);
+
return ptr;
}
* in the dynamic state memory zone, so we can point to it via the
* 3DSTATE_SAMPLER_STATE_POINTERS_* commands.
*/
+ unsigned size = count * 4 * GENX(SAMPLER_STATE_length);
uint32_t *map =
- upload_state(ice->state.dynamic_uploader, &shs->sampler_table,
- count * 4 * GENX(SAMPLER_STATE_length), 32);
+ upload_state(ice->state.dynamic_uploader, &shs->sampler_table, size, 32);
if (unlikely(!map))
return;
shs->sampler_table.offset +=
iris_bo_offset_from_base_address(iris_resource_bo(res));
+ iris_record_state_size(ice->state.sizes, shs->sampler_table.offset, size);
+
/* Make sure all land in the same BO */
iris_border_color_pool_reserve(ice, IRIS_MAX_TEXTURE_SAMPLERS);