diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-08-18 12:17:15 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2016-08-18 17:37:00 -0400 |
commit | efdfd91f9b234638705d79a2b2f0a6ac8a5f99e8 (patch) | |
tree | 8544bd0aab615c71850514d0d61d59a229b8fd4c | |
parent | d6a4ead7a38666b9acdb098012a178c4c4950eca (diff) |
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: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20160818161718.27187-36-chris@chris-wilson.co.uk
-rw-r--r-- | drivers/gpu/drm/i915/i915_cmd_parser.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 54aeab3f9614..558077a25052 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c | |||
@@ -90,6 +90,7 @@ | |||
90 | #define STD_3D_OPCODE_SHIFT (32 - 16) | 90 | #define STD_3D_OPCODE_SHIFT (32 - 16) |
91 | #define STD_2D_OPCODE_SHIFT (32 - 10) | 91 | #define STD_2D_OPCODE_SHIFT (32 - 10) |
92 | #define STD_MFX_OPCODE_SHIFT (32 - 16) | 92 | #define STD_MFX_OPCODE_SHIFT (32 - 16) |
93 | #define MIN_OPCODE_SHIFT 16 | ||
93 | 94 | ||
94 | #define CMD(op, opm, f, lm, fl, ...) \ | 95 | #define CMD(op, opm, f, lm, fl, ...) \ |
95 | { \ | 96 | { \ |
@@ -350,6 +351,9 @@ static const struct drm_i915_cmd_descriptor hsw_blt_cmds[] = { | |||
350 | CMD( MI_LOAD_SCAN_LINES_EXCL, SMI, !F, 0x3F, R ), | 351 | CMD( MI_LOAD_SCAN_LINES_EXCL, SMI, !F, 0x3F, R ), |
351 | }; | 352 | }; |
352 | 353 | ||
354 | static const struct drm_i915_cmd_descriptor noop_desc = | ||
355 | CMD(MI_NOOP, SMI, F, 1, S); | ||
356 | |||
353 | #undef CMD | 357 | #undef CMD |
354 | #undef SMI | 358 | #undef SMI |
355 | #undef S3D | 359 | #undef S3D |
@@ -893,11 +897,14 @@ find_cmd_in_table(struct intel_engine_cs *engine, | |||
893 | static const struct drm_i915_cmd_descriptor* | 897 | static const struct drm_i915_cmd_descriptor* |
894 | find_cmd(struct intel_engine_cs *engine, | 898 | find_cmd(struct intel_engine_cs *engine, |
895 | u32 cmd_header, | 899 | u32 cmd_header, |
900 | const struct drm_i915_cmd_descriptor *desc, | ||
896 | struct drm_i915_cmd_descriptor *default_desc) | 901 | struct drm_i915_cmd_descriptor *default_desc) |
897 | { | 902 | { |
898 | const struct drm_i915_cmd_descriptor *desc; | ||
899 | u32 mask; | 903 | u32 mask; |
900 | 904 | ||
905 | if (((cmd_header ^ desc->cmd.value) & desc->cmd.mask) == 0) | ||
906 | return desc; | ||
907 | |||
901 | desc = find_cmd_in_table(engine, cmd_header); | 908 | desc = find_cmd_in_table(engine, cmd_header); |
902 | if (desc) | 909 | if (desc) |
903 | return desc; | 910 | return desc; |
@@ -906,10 +913,10 @@ find_cmd(struct intel_engine_cs *engine, | |||
906 | if (!mask) | 913 | if (!mask) |
907 | return NULL; | 914 | return NULL; |
908 | 915 | ||
909 | BUG_ON(!default_desc); | 916 | default_desc->cmd.value = cmd_header; |
910 | default_desc->flags = CMD_DESC_SKIP; | 917 | default_desc->cmd.mask = ~0u << MIN_OPCODE_SHIFT; |
911 | default_desc->length.mask = mask; | 918 | default_desc->length.mask = mask; |
912 | 919 | default_desc->flags = CMD_DESC_SKIP; | |
913 | return default_desc; | 920 | return default_desc; |
914 | } | 921 | } |
915 | 922 | ||
@@ -1188,7 +1195,8 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine, | |||
1188 | bool is_master) | 1195 | bool is_master) |
1189 | { | 1196 | { |
1190 | u32 *cmd, *batch_end; | 1197 | u32 *cmd, *batch_end; |
1191 | struct drm_i915_cmd_descriptor default_desc = { 0 }; | 1198 | struct drm_i915_cmd_descriptor default_desc = noop_desc; |
1199 | const struct drm_i915_cmd_descriptor *desc = &default_desc; | ||
1192 | bool oacontrol_set = false; /* OACONTROL tracking. See check_cmd() */ | 1200 | bool oacontrol_set = false; /* OACONTROL tracking. See check_cmd() */ |
1193 | bool needs_clflush_after = false; | 1201 | bool needs_clflush_after = false; |
1194 | int ret = 0; | 1202 | int ret = 0; |
@@ -1208,13 +1216,12 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine, | |||
1208 | */ | 1216 | */ |
1209 | batch_end = cmd + (batch_len / sizeof(*batch_end)); | 1217 | batch_end = cmd + (batch_len / sizeof(*batch_end)); |
1210 | while (cmd < batch_end) { | 1218 | while (cmd < batch_end) { |
1211 | const struct drm_i915_cmd_descriptor *desc; | ||
1212 | u32 length; | 1219 | u32 length; |
1213 | 1220 | ||
1214 | if (*cmd == MI_BATCH_BUFFER_END) | 1221 | if (*cmd == MI_BATCH_BUFFER_END) |
1215 | break; | 1222 | break; |
1216 | 1223 | ||
1217 | desc = find_cmd(engine, *cmd, &default_desc); | 1224 | desc = find_cmd(engine, *cmd, desc, &default_desc); |
1218 | if (!desc) { | 1225 | if (!desc) { |
1219 | DRM_DEBUG_DRIVER("CMD: Unrecognized command: 0x%08X\n", | 1226 | DRM_DEBUG_DRIVER("CMD: Unrecognized command: 0x%08X\n", |
1220 | *cmd); | 1227 | *cmd); |