Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit efdfd91f authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915/cmdparser: Compare against the previous command descriptor



On the blitter (and in test code), we see long sequences of repeated
commands, e.g. XY_PIXEL_BLT, XY_SCANLINE_BLT, or XY_SRC_COPY. For these,
we can skip the hashtable lookup by remembering the previous command
descriptor and doing a straightforward compare of the command header.
The corollary is that we need to do one extra comparison before lookup
up new commands.

v2: Less magic mask (ok, it is still magic, but now you cannot see!)

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20160818161718.27187-36-chris@chris-wilson.co.uk
parent d6a4ead7
Loading
Loading
Loading
Loading
+14 −7
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@
#define STD_3D_OPCODE_SHIFT  (32 - 16)
#define STD_2D_OPCODE_SHIFT  (32 - 10)
#define STD_MFX_OPCODE_SHIFT (32 - 16)
#define MIN_OPCODE_SHIFT 16

#define CMD(op, opm, f, lm, fl, ...)				\
	{							\
@@ -350,6 +351,9 @@ static const struct drm_i915_cmd_descriptor hsw_blt_cmds[] = {
	CMD(  MI_LOAD_SCAN_LINES_EXCL,          SMI,   !F,  0x3F,   R  ),
};

static const struct drm_i915_cmd_descriptor noop_desc =
	CMD(MI_NOOP, SMI, F, 1, S);

#undef CMD
#undef SMI
#undef S3D
@@ -893,11 +897,14 @@ find_cmd_in_table(struct intel_engine_cs *engine,
static const struct drm_i915_cmd_descriptor*
find_cmd(struct intel_engine_cs *engine,
	 u32 cmd_header,
	 const struct drm_i915_cmd_descriptor *desc,
	 struct drm_i915_cmd_descriptor *default_desc)
{
	const struct drm_i915_cmd_descriptor *desc;
	u32 mask;

	if (((cmd_header ^ desc->cmd.value) & desc->cmd.mask) == 0)
		return desc;

	desc = find_cmd_in_table(engine, cmd_header);
	if (desc)
		return desc;
@@ -906,10 +913,10 @@ find_cmd(struct intel_engine_cs *engine,
	if (!mask)
		return NULL;

	BUG_ON(!default_desc);
	default_desc->flags = CMD_DESC_SKIP;
	default_desc->cmd.value = cmd_header;
	default_desc->cmd.mask = ~0u << MIN_OPCODE_SHIFT;
	default_desc->length.mask = mask;

	default_desc->flags = CMD_DESC_SKIP;
	return default_desc;
}

@@ -1188,7 +1195,8 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine,
			    bool is_master)
{
	u32 *cmd, *batch_end;
	struct drm_i915_cmd_descriptor default_desc = { 0 };
	struct drm_i915_cmd_descriptor default_desc = noop_desc;
	const struct drm_i915_cmd_descriptor *desc = &default_desc;
	bool oacontrol_set = false; /* OACONTROL tracking. See check_cmd() */
	bool needs_clflush_after = false;
	int ret = 0;
@@ -1208,13 +1216,12 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine,
	 */
	batch_end = cmd + (batch_len / sizeof(*batch_end));
	while (cmd < batch_end) {
		const struct drm_i915_cmd_descriptor *desc;
		u32 length;

		if (*cmd == MI_BATCH_BUFFER_END)
			break;

		desc = find_cmd(engine, *cmd, &default_desc);
		desc = find_cmd(engine, *cmd, desc, &default_desc);
		if (!desc) {
			DRM_DEBUG_DRIVER("CMD: Unrecognized command: 0x%08X\n",
					 *cmd);