@@ -43,9 +43,6 @@
/* broadwater flush bits */
#define BRW_MI_GLOBAL_SNAPSHOT_RESET (1 << 3)
-#define MI_COND_BATCH_BUFFER_END (0x36<<23 | 1)
-#define MI_DO_COMPARE (1<<21)
-
#define MI_BATCH_BUFFER_END (0xA << 23)
/* Noop */
@@ -75,7 +75,7 @@ emit_recursive_batch(igt_spin_t *spin,
#define SCRATCH 0
#define BATCH IGT_SPIN_BATCH
const int gen = intel_gen(intel_get_drm_devid(fd));
- struct drm_i915_gem_relocation_entry relocs[2], *r;
+ struct drm_i915_gem_relocation_entry relocs[3], *r;
struct drm_i915_gem_execbuffer2 *execbuf;
struct drm_i915_gem_exec_object2 *obj;
unsigned int flags[GEM_MAX_ENGINES];
@@ -205,7 +205,42 @@ emit_recursive_batch(igt_spin_t *spin,
* trouble. See https://bugs.freedesktop.org/show_bug.cgi?id=102262
*/
if (!(opts->flags & IGT_SPIN_FAST))
- cs += 1000;
+ cs += 960;
+
+ /*
+ * When using a cmdparser, the batch is copied into a read only location
+ * and validated. We are then unable to alter the executing batch,
+ * breaking the older *spin->condition = MI_BB_END termination.
+ * Instead we can use a conditional MI_BB_END here that looks at
+ * the user's copy of the batch and terminates when they modified it,
+ * no matter how they modify it (from either the GPU or CPU).
+ */
+ if (gen >= 8) { /* arbitrary cutoff between ring/execlists submission */
+ r = &relocs[obj[BATCH].relocation_count++];
+
+ /*
+ * On Sandybridge+ the comparison is a strict greater-than:
+ * if the value at spin->condition is greater than BB_END,
+ * we loop back to the beginning.
+ * Beginning with Kabylake, we can select the comparison mode
+ * and loop back to the beginning if spin->condition != BB_END
+ * (using 5 << 12).
+ * For simplicity, we try to stick to a one-size fits all.
+ */
+ spin->condition = batch + BATCH_SIZE / sizeof(*batch) - 1;
+ *spin->condition = 0xffffffff;
+
+ r->presumed_offset = 0;
+ r->target_handle = obj[BATCH].handle;
+ r->offset = (cs + 2 - batch) * sizeof(*cs);
+ r->read_domains = I915_GEM_DOMAIN_COMMAND;
+ r->delta = (spin->condition - batch) * sizeof(*cs);
+
+ *cs++ = MI_COND_BATCH_BUFFER_END | MI_DO_COMPARE | 2;
+ *cs++ = MI_BATCH_BUFFER_END;
+ *cs++ = r->delta;
+ *cs++ = 0;
+ }
/* recurse */
r = &relocs[obj[BATCH].relocation_count++];
@@ -2593,6 +2593,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define MI_BATCH_BUFFER ((0x30 << 23) | 1)
#define MI_BATCH_BUFFER_START (0x31 << 23)
#define MI_BATCH_BUFFER_END (0xA << 23)
+#define MI_COND_BATCH_BUFFER_END (0x36 << 23)
+#define MI_DO_COMPARE (1 << 21)
+
#define MI_BATCH_NON_SECURE (1)
#define MI_BATCH_NON_SECURE_I965 (1 << 8)
#define MI_BATCH_NON_SECURE_HSW (1<<13) /* Additional bit for RCS */
@@ -52,8 +52,6 @@ static drm_intel_bo *target_buffer, *blt_bo;
IGT_TEST_DESCRIPTION("Basic check for missed IRQs on blt ring.");
-#define MI_COND_BATCH_BUFFER_END (0x36<<23 | 1)
-#define MI_DO_COMPARE (1<<21)
static void
dummy_reloc_loop(void)
{
@@ -115,7 +115,7 @@ static void run_test(int ring)
* otherwise the obj->last_write_seqno will be updated. */
if (ring == I915_EXEC_RENDER) {
BEGIN_BATCH(4, 1);
- OUT_BATCH(MI_COND_BATCH_BUFFER_END | MI_DO_COMPARE);
+ OUT_BATCH(MI_COND_BATCH_BUFFER_END | MI_DO_COMPARE | 1);
OUT_BATCH(0xffffffff); /* compare dword */
OUT_RELOC(target_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
OUT_BATCH(MI_NOOP);