The engine to which the batch was sent to is now set to the decoder context when
decoding the batch. This is needed so that we can distinguish between
instructions as the render and video pipe share some of the instruction opcodes.
v2: The engine is now in the decoder context and the batch decoder uses a local
function for finding the instruction for an engine.
v3: Spec uses engine_mask now instead of engine, replaced engine class enums
with the definitions from UAPI.
v4: Fix up aubinator_viewer (Lionel)
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
ctx->fp = fp;
ctx->flags = flags;
ctx->max_vbo_decoded_lines = -1; /* No limit! */
+ ctx->engine = I915_ENGINE_CLASS_RENDER;
if (xml_path == NULL)
ctx->spec = gen_spec_load(devinfo);
fprintf(ctx->fp, "\n");
}
+static struct gen_group *
+gen_ctx_find_instruction(struct gen_batch_decode_ctx *ctx, const uint32_t *p)
+{
+ return gen_spec_find_instruction(ctx->spec, ctx->engine, p);
+}
+
static void
handle_state_base_address(struct gen_batch_decode_ctx *ctx, const uint32_t *p)
{
- struct gen_group *inst = gen_spec_find_instruction(ctx->spec, p);
+ struct gen_group *inst = gen_ctx_find_instruction(ctx, p);
struct gen_field_iterator iter;
gen_field_iterator_init(&iter, inst, p, 0, false);
handle_media_interface_descriptor_load(struct gen_batch_decode_ctx *ctx,
const uint32_t *p)
{
- struct gen_group *inst = gen_spec_find_instruction(ctx->spec, p);
+ struct gen_group *inst = gen_ctx_find_instruction(ctx, p);
struct gen_group *desc =
gen_spec_find_struct(ctx->spec, "INTERFACE_DESCRIPTOR_DATA");
handle_3dstate_vertex_buffers(struct gen_batch_decode_ctx *ctx,
const uint32_t *p)
{
- struct gen_group *inst = gen_spec_find_instruction(ctx->spec, p);
+ struct gen_group *inst = gen_ctx_find_instruction(ctx, p);
struct gen_group *vbs = gen_spec_find_struct(ctx->spec, "VERTEX_BUFFER_STATE");
struct gen_batch_decode_bo vb = {};
handle_3dstate_index_buffer(struct gen_batch_decode_ctx *ctx,
const uint32_t *p)
{
- struct gen_group *inst = gen_spec_find_instruction(ctx->spec, p);
+ struct gen_group *inst = gen_ctx_find_instruction(ctx, p);
struct gen_batch_decode_bo ib = {};
uint32_t ib_size = 0;
static void
decode_single_ksp(struct gen_batch_decode_ctx *ctx, const uint32_t *p)
{
- struct gen_group *inst = gen_spec_find_instruction(ctx->spec, p);
+ struct gen_group *inst = gen_ctx_find_instruction(ctx, p);
uint64_t ksp = 0;
bool is_simd8 = false; /* vertex shaders on Gen8+ only */
static void
decode_ps_kernels(struct gen_batch_decode_ctx *ctx, const uint32_t *p)
{
- struct gen_group *inst = gen_spec_find_instruction(ctx->spec, p);
+ struct gen_group *inst = gen_ctx_find_instruction(ctx, p);
uint64_t ksp[3] = {0, 0, 0};
bool enabled[3] = {false, false, false};
static void
decode_3dstate_constant(struct gen_batch_decode_ctx *ctx, const uint32_t *p)
{
- struct gen_group *inst = gen_spec_find_instruction(ctx->spec, p);
+ struct gen_group *inst = gen_ctx_find_instruction(ctx, p);
struct gen_group *body =
gen_spec_find_struct(ctx->spec, "3DSTATE_CONSTANT_BODY");
const char *struct_type, const uint32_t *p,
int count)
{
- struct gen_group *inst = gen_spec_find_instruction(ctx->spec, p);
+ struct gen_group *inst = gen_ctx_find_instruction(ctx, p);
uint32_t state_offset = 0;
struct gen_group *inst;
for (p = batch; p < end; p += length) {
- inst = gen_spec_find_instruction(ctx->spec, p);
+ inst = gen_ctx_find_instruction(ctx, p);
length = gen_group_get_length(inst, p);
assert(inst == NULL || length > 0);
length = MAX2(1, length);
}
struct gen_group *
-gen_spec_find_instruction(struct gen_spec *spec, const uint32_t *p)
+gen_spec_find_instruction(struct gen_spec *spec,
+ enum drm_i915_gem_engine_class engine,
+ const uint32_t *p)
{
hash_table_foreach(spec->commands, entry) {
struct gen_group *command = entry->data;
uint32_t opcode = *p & command->opcode_mask;
- if (opcode == command->opcode)
+ if ((command->engine_mask & I915_ENGINE_CLASS_TO_MASK(engine)) &&
+ opcode == command->opcode)
return command;
}
const char *path);
void gen_spec_destroy(struct gen_spec *spec);
uint32_t gen_spec_get_gen(struct gen_spec *spec);
-struct gen_group *gen_spec_find_instruction(struct gen_spec *spec, const uint32_t *p);
+struct gen_group *gen_spec_find_instruction(struct gen_spec *spec,
+ enum drm_i915_gem_engine_class engine,
+ const uint32_t *p);
struct gen_group *gen_spec_find_register(struct gen_spec *spec, uint32_t offset);
struct gen_group *gen_spec_find_register_by_name(struct gen_spec *spec, const char *name);
struct gen_enum *gen_spec_find_enum(struct gen_spec *spec, const char *name);
uint64_t instruction_base;
int max_vbo_decoded_lines;
+
+ enum drm_i915_gem_engine_class engine;
};
void gen_batch_decode_ctx_init(struct gen_batch_decode_ctx *ctx,
batch_ctx.get_bo = aub_mem_get_ggtt_bo;
}
- (void)engine; /* TODO */
+ batch_ctx.engine = engine;
gen_print_batch(&batch_ctx, commands, ring_buffer_tail - ring_buffer_head,
0);
aub_mem_clear_bo_maps(&mem);
batch_ctx.user_data = &mem;
batch_ctx.get_bo = aub_mem_get_ggtt_bo;
+ batch_ctx.engine = engine;
gen_print_batch(&batch_ctx, data, data_len, 0);
aub_mem_clear_bo_maps(&mem);
}
struct ring_register_mapping {
- unsigned ring_class;
+ enum drm_i915_gem_engine_class ring_class;
unsigned ring_instance;
const char *register_name;
};
-enum {
- RCS,
- BCS,
- VCS,
- VECS,
-};
-
static const struct ring_register_mapping acthd_registers[] = {
- { BCS, 0, "BCS_ACTHD_UDW" },
- { VCS, 0, "VCS_ACTHD_UDW" },
- { VCS, 1, "VCS2_ACTHD_UDW" },
- { RCS, 0, "ACTHD_UDW" },
- { VECS, 0, "VECS_ACTHD_UDW" },
+ { I915_ENGINE_CLASS_COPY, 0, "BCS_ACTHD_UDW" },
+ { I915_ENGINE_CLASS_VIDEO, 0, "VCS_ACTHD_UDW" },
+ { I915_ENGINE_CLASS_VIDEO, 1, "VCS2_ACTHD_UDW" },
+ { I915_ENGINE_CLASS_RENDER, 0, "ACTHD_UDW" },
+ { I915_ENGINE_CLASS_VIDEO_ENHANCE, 0, "VECS_ACTHD_UDW" },
};
static const struct ring_register_mapping ctl_registers[] = {
- { BCS, 0, "BCS_RING_BUFFER_CTL" },
- { VCS, 0, "VCS_RING_BUFFER_CTL" },
- { VCS, 1, "VCS2_RING_BUFFER_CTL" },
- { RCS, 0, "RCS_RING_BUFFER_CTL" },
- { VECS, 0, "VECS_RING_BUFFER_CTL" },
+ { I915_ENGINE_CLASS_COPY, 0, "BCS_RING_BUFFER_CTL" },
+ { I915_ENGINE_CLASS_VIDEO, 0, "VCS_RING_BUFFER_CTL" },
+ { I915_ENGINE_CLASS_VIDEO, 1, "VCS2_RING_BUFFER_CTL" },
+ { I915_ENGINE_CLASS_RENDER, 0, "RCS_RING_BUFFER_CTL" },
+ { I915_ENGINE_CLASS_VIDEO_ENHANCE, 0, "VECS_RING_BUFFER_CTL" },
};
static const struct ring_register_mapping fault_registers[] = {
- { BCS, 0, "BCS_FAULT_REG" },
- { VCS, 0, "VCS_FAULT_REG" },
- { RCS, 0, "RCS_FAULT_REG" },
- { VECS, 0, "VECS_FAULT_REG" },
+ { I915_ENGINE_CLASS_COPY, 0, "BCS_FAULT_REG" },
+ { I915_ENGINE_CLASS_VIDEO, 0, "VCS_FAULT_REG" },
+ { I915_ENGINE_CLASS_RENDER, 0, "RCS_FAULT_REG" },
+ { I915_ENGINE_CLASS_VIDEO_ENHANCE, 0, "VECS_FAULT_REG" },
};
static int ring_name_to_class(const char *ring_name,
- unsigned int *class)
+ enum drm_i915_gem_engine_class *class)
{
static const char *class_names[] = {
- [RCS] = "rcs",
- [BCS] = "bcs",
- [VCS] = "vcs",
- [VECS] = "vecs",
+ [I915_ENGINE_CLASS_RENDER] = "rcs",
+ [I915_ENGINE_CLASS_COPY] = "bcs",
+ [I915_ENGINE_CLASS_VIDEO] = "vcs",
+ [I915_ENGINE_CLASS_VIDEO_ENHANCE] = "vecs",
};
for (size_t i = 0; i < ARRAY_SIZE(class_names); i++) {
if (strncmp(ring_name, class_names[i], strlen(class_names[i])))
unsigned int class;
int instance;
} legacy_names[] = {
- { "render", RCS, 0 },
- { "blt", BCS, 0 },
- { "bsd", VCS, 0 },
- { "bsd2", VCS, 1 },
- { "vebox", VECS, 0 },
+ { "render", I915_ENGINE_CLASS_RENDER, 0 },
+ { "blt", I915_ENGINE_CLASS_COPY, 0 },
+ { "bsd", I915_ENGINE_CLASS_VIDEO, 0 },
+ { "bsd2", I915_ENGINE_CLASS_VIDEO, 1 },
+ { "vebox", I915_ENGINE_CLASS_VIDEO_ENHANCE, 0 },
};
for (size_t i = 0; i < ARRAY_SIZE(legacy_names); i++) {
if (strcmp(ring_name, legacy_names[i].name))
unsigned nb_mapping,
const char *ring_name)
{
- unsigned int class;
+ enum drm_i915_gem_engine_class class;
int instance;
instance = ring_name_to_class(ring_name, &class);
instdone_register_for_ring(const struct gen_device_info *devinfo,
const char *ring_name)
{
- unsigned int class;
+ enum drm_i915_gem_engine_class class;
int instance;
instance = ring_name_to_class(ring_name, &class);
return NULL;
switch (class) {
- case RCS:
+ case I915_ENGINE_CLASS_RENDER:
if (devinfo->gen == 6)
return "INSTDONE_2";
else
return "INSTDONE_1";
- case BCS:
+ case I915_ENGINE_CLASS_COPY:
return "BCS_INSTDONE";
- case VCS:
+ case I915_ENGINE_CLASS_VIDEO:
switch (instance) {
case 0:
return "VCS_INSTDONE";
return NULL;
}
- case VECS:
+ case I915_ENGINE_CLASS_VIDEO_ENHANCE:
return "VECS_INSTDONE";
}
for (int s = 0; s < num_sections; s++) {
+ enum drm_i915_gem_engine_class class;
+ ring_name_to_class(sections[s].ring_name, &class);
+
printf("--- %s (%s) at 0x%08x %08x\n",
sections[s].buffer_name, sections[s].ring_name,
(unsigned) (sections[s].gtt_offset >> 32),
strcmp(sections[s].buffer_name, "batch buffer") == 0 ||
strcmp(sections[s].buffer_name, "ring buffer") == 0 ||
strcmp(sections[s].buffer_name, "HW Context") == 0) {
+ batch_ctx.engine = class;
gen_print_batch(&batch_ctx, sections[s].data,
sections[s].dword_count * 4,
sections[s].gtt_offset);
}
static void
-display_batch_execlist_write(void *user_data, enum drm_i915_gem_engine_class,
+display_batch_execlist_write(void *user_data,
+ enum drm_i915_gem_engine_class engine,
uint64_t context_descriptor)
{
struct batch_window *window = (struct batch_window *) user_data;
window->uses_ppgtt = true;
+ window->decode_ctx.engine = engine;
aub_viewer_render_batch(&window->decode_ctx, commands,
ring_buffer_tail - ring_buffer_head,
ring_buffer_start);
struct gen_spec *spec;
struct gen_disasm *disasm;
+ enum drm_i915_gem_engine_class engine;
struct aub_viewer_cfg *cfg;
struct aub_viewer_decode_cfg *decode_cfg;
ctx->get_bo = get_bo;
ctx->get_state_size = get_state_size;
ctx->user_data = user_data;
+ ctx->engine = I915_ENGINE_CLASS_RENDER;
ctx->cfg = cfg;
ctx->decode_cfg = decode_cfg;
int length;
for (p = batch; p < end; p += length) {
- inst = gen_spec_find_instruction(ctx->spec, p);
+ inst = gen_spec_find_instruction(ctx->spec, ctx->engine, p);
length = gen_group_get_length(inst, p);
assert(inst == NULL || length > 0);
length = MAX2(1, length);