@@ -64,6 +64,22 @@ static bool has_semaphores(int fd, int dir)
return val;
}
+static int cmd_parser_version(int fd)
+{
+ int val = 0;
+ struct drm_i915_getparam gp = {
+ gp.param = I915_PARAM_CMD_PARSER_VERSION,
+ gp.value = &val,
+ };
+
+ if (ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp) < 0) {
+ val = -errno;
+ igt_assert(val < 0);
+ }
+
+ return val;
+}
+
/**
* gem_submission_method:
* @fd: open i915 drm file descriptor
@@ -253,3 +269,49 @@ void gem_require_blitter(int i915)
{
igt_require(gem_has_blitter(i915));
}
+
+static bool gem_engine_has_immutable_submission(int i915, int class)
+{
+ const int gen = intel_gen(intel_get_drm_devid(i915));
+ int parser_version;
+
+ parser_version = cmd_parser_version(i915);
+
+ if (parser_version < 0)
+ return false;
+
+ if (gen == 9 && class == I915_ENGINE_CLASS_COPY && parser_version > 9)
+ return true;
+
+ return false;
+}
+
+
+/**
+ * gem_class_has_mutable_submission:
+ * @i915: open i915 drm file descriptor
+ * @class: engine class
+ *
+ * Returns boolean value if the engine class allows batch modifications
+ * post execbuf.
+ */
+
+bool
+gem_class_has_mutable_submission(int fd, int class)
+{
+ return !gem_engine_has_immutable_submission(fd, class);
+}
+
+/**
+ * gem_engine_has_mutable_submission:
+ * @i915: open i915 drm file descriptor
+ * @engine: the engine (I915_EXEC_RING id) of target
+ *
+ * Returns boolean value if the engine allows batch modifications
+ * post execbuf.
+ */
+bool gem_engine_has_mutable_submission(int i915, unsigned int engine)
+{
+ return gem_class_has_mutable_submission(i915,
+ gem_execbuf_flags_to_engine_class(engine));
+}
@@ -34,6 +34,8 @@ void gem_submission_print_method(int fd);
bool gem_has_semaphores(int fd);
bool gem_has_execlists(int fd);
bool gem_has_guc_submission(int fd);
+bool gem_engine_has_mutable_submission(int fd, unsigned int engine);
+bool gem_class_has_mutable_submission(int fd, int class);
int gem_cmdparser_version(int i915, uint32_t engine);
static inline bool gem_has_cmdparser(int i915, uint32_t engine)
@@ -243,6 +243,10 @@ static void one(int fd, const struct intel_execution_engine2 *e, unsigned test_f
i++;
igt_assert(i < size/sizeof(*batch));
+
+ if ((test_flags & HANG) == 0)
+ igt_require(gem_class_has_mutable_submission(fd, e->class));
+
igt_require(__gem_execbuf(fd, &execbuf) == 0);
__gem_busy(fd, obj[SCRATCH].handle, &read[SCRATCH], &write[SCRATCH]);
@@ -256,7 +260,8 @@ static void one(int fd, const struct intel_execution_engine2 *e, unsigned test_f
e2->instance == e->instance)
continue;
- if (!gem_class_can_store_dword(fd, e2->class))
+ if (!gem_class_can_store_dword(fd, e2->class) ||
+ !gem_class_has_mutable_submission(fd, e2->class))
continue;
igt_debug("Testing %s in parallel\n", e2->name);
@@ -138,6 +138,9 @@ static void one(int fd, unsigned ring, uint32_t flags)
execbuf.buffers_ptr = to_user_pointer(obj);
execbuf.buffer_count = 2;
execbuf.flags = ring | flags;
+
+ igt_require(gem_engine_has_mutable_submission(fd, ring));
+
igt_require(__gem_execbuf(fd, &execbuf) == 0);
gem_close(fd, obj[BATCH].handle);
@@ -78,8 +78,13 @@ static void wide(int fd, int ring_size, int timeout, unsigned int flags)
double time;
nengine = 0;
- for_each_physical_engine(e, fd)
+ for_each_physical_engine(e, fd) {
+ if (!gem_engine_has_mutable_submission(fd, eb_ring(e)))
+ continue;
+
engines[nengine++] = eb_ring(e);
+ }
+
igt_require(nengine);
exec = calloc(nengine, sizeof(*exec));
@@ -129,6 +129,9 @@ static void test_fence_busy(int fd, unsigned ring, unsigned flags)
uint32_t *batch;
int fence, i, timeout;
+ if ((flags & HANG) == 0)
+ igt_require(gem_engine_has_mutable_submission(fd, ring));
+
gem_quiescent_gpu(fd);
memset(&execbuf, 0, sizeof(execbuf));
@@ -265,6 +268,8 @@ static void test_fence_busy_all(int fd, unsigned flags)
for_each_engine(e, fd) {
int fence, new;
+ if ((flags & HANG) == 0)
+ igt_require(gem_engine_has_mutable_submission(fd, eb_ring(e)));
execbuf.flags = eb_ring(e) | LOCAL_EXEC_FENCE_OUT;
execbuf.rsvd2 = -1;
gem_execbuf_wr(fd, &execbuf);
@@ -321,6 +326,9 @@ static void test_fence_await(int fd, unsigned ring, unsigned flags)
uint32_t *out;
int i;
+ if ((flags & HANG) == 0)
+ igt_require(gem_engine_has_mutable_submission(fd, ring));
+
igt_require(gem_can_store_dword(fd, 0));
out = gem_mmap__wc(fd, scratch, 0, 4096, PROT_WRITE);
@@ -128,6 +128,8 @@ static void latency_on_ring(int fd,
double gpu_latency;
int i, j;
+ igt_require(gem_engine_has_mutable_submission(fd, ring));
+
reg = (volatile uint32_t *)((volatile char *)igt_global_mmio + RCS_TIMESTAMP);
memset(&execbuf, 0, sizeof(execbuf));
@@ -271,6 +273,8 @@ static void latency_from_ring(int fd,
uint32_t ctx[2] = {};
int i, j;
+ igt_require(gem_engine_has_mutable_submission(fd, ring));
+
if (flags & PREEMPT) {
ctx[0] = gem_context_create(fd);
gem_context_set_priority(fd, ctx[0], -1023);
@@ -316,6 +320,9 @@ static void latency_from_ring(int fd,
igt_spin_t *spin = NULL;
IGT_CORK_HANDLE(c);
+ if (!gem_engine_has_mutable_submission(fd, eb_ring(e)))
+ continue;
+
gem_set_domain(fd, obj[2].handle,
I915_GEM_DOMAIN_GTT,
I915_GEM_DOMAIN_GTT);
@@ -123,6 +123,7 @@ static void poll_ring(int fd, unsigned engine, const char *name, int timeout)
gem_require_ring(fd, engine);
igt_require(gem_can_store_dword(fd, engine));
+ igt_require(gem_engine_has_mutable_submission(fd, engine));
memset(&obj, 0, sizeof(obj));
obj.handle = gem_create(fd, 4096);
@@ -234,7 +235,8 @@ static void poll_sequential(int fd, const char *name, int timeout)
nengine = 0;
for_each_physical_engine(e, fd) {
- if (!gem_can_store_dword(fd, eb_ring(e)))
+ if (!gem_can_store_dword(fd, eb_ring(e)) ||
+ !gem_engine_has_mutable_submission(fd, eb_ring(e)))
continue;
engines[nengine++] = eb_ring(e);
@@ -652,7 +652,8 @@ static void semaphore_noskip(int i915)
igt_spin_t *chain, *spin;
if (eb_ring(inner) == eb_ring(outer) ||
- !gem_can_store_dword(i915, eb_ring(inner)))
+ !gem_can_store_dword(i915, eb_ring(inner)) ||
+ !gem_engine_has_mutable_submission(i915, eb_ring(inner)))
continue;
chain = __igt_spin_new(i915, .engine = eb_ring(outer));
@@ -1157,6 +1158,9 @@ static void deep(int fd, unsigned ring)
int dep_nreq;
int n;
+ igt_require(gem_can_store_dword(fd, ring));
+ igt_require(gem_engine_has_mutable_submission(fd, ring));
+
ctx = malloc(sizeof(*ctx) * MAX_CONTEXTS);
for (n = 0; n < MAX_CONTEXTS; n++) {
ctx[n] = gem_context_create(fd);
@@ -204,13 +204,15 @@ static void whisper(int fd, unsigned engine, unsigned flags)
nengine = 0;
if (engine == ALL_ENGINES) {
for_each_physical_engine(e, fd) {
- if (gem_can_store_dword(fd, eb_ring(e)))
+ if (gem_can_store_dword(fd, eb_ring(e)) &&
+ gem_engine_has_mutable_submission(fd, eb_ring(e)))
engines[nengine++] = eb_ring(e);
}
} else {
igt_assert(!(flags & ALL));
igt_require(gem_has_ring(fd, engine));
igt_require(gem_can_store_dword(fd, engine));
+ igt_require(gem_engine_has_mutable_submission(fd, engine));
engines[nengine++] = engine;
}
igt_require(nengine);
@@ -53,6 +53,9 @@ static void busy(int fd, unsigned ring, unsigned flags)
uint32_t *batch, *bbe;
int i, count, timeout;
+ if ((flags & HANG) == 0)
+ igt_require(gem_engine_has_mutable_submission(fd, ring));
+
gem_quiescent_gpu(fd);
memset(&execbuf, 0, sizeof(execbuf));
@@ -342,6 +342,8 @@ static void work(int i915, int dmabuf, unsigned ring, uint32_t flags)
uint32_t *batch, *bbe;
int i, count;
+ igt_require(gem_engine_has_mutable_submission(i915, ring));
+
memset(&execbuf, 0, sizeof(execbuf));
execbuf.buffers_ptr = (uintptr_t)obj;
execbuf.buffer_count = 2;
@@ -850,6 +852,7 @@ igt_main
e->name) {
gem_require_ring(i915, eb_ring(e));
igt_require(gem_can_store_dword(i915, eb_ring(e)));
+ igt_require(gem_engine_has_mutable_submission(i915, eb_ring(e)));
gem_quiescent_gpu(i915);
test_sync(i915, vgem, e->exec_id, e->flags);
@@ -862,6 +865,7 @@ igt_main
e->name) {
gem_require_ring(i915, eb_ring(e));
igt_require(gem_can_store_dword(i915, eb_ring(e)));
+ igt_require(gem_engine_has_mutable_submission(i915, eb_ring(e)));
gem_quiescent_gpu(i915);
test_busy(i915, vgem, e->exec_id, e->flags);
@@ -874,6 +878,7 @@ igt_main
e->name) {
gem_require_ring(i915, eb_ring(e));
igt_require(gem_can_store_dword(i915, eb_ring(e)));
+ igt_require(gem_engine_has_mutable_submission(i915, eb_ring(e)));
gem_quiescent_gpu(i915);
test_wait(i915, vgem, e->exec_id, e->flags);
@@ -897,6 +902,7 @@ igt_main
e->name) {
gem_require_ring(i915, eb_ring(e));
igt_require(gem_can_store_dword(i915, eb_ring(e)));
+ igt_require(gem_engine_has_mutable_submission(i915, eb_ring(e)));
gem_quiescent_gpu(i915);
test_fence_wait(i915, vgem, e->exec_id, e->flags);