[igt-dev] [PATCH i-g-t 5/6] igt/shell: Add primitive i915 wrapping

Chris Wilson chris at chris-wilson.co.uk
Mon Aug 20 13:01:48 UTC 2018


Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 shell/drm/i915/i915-builtin.c    |  34 ++++++++
 shell/drm/i915/i915-constants.c  | 139 +++++++++++++++++++++++++++++++
 shell/drm/i915/i915-constants.h  |   6 ++
 shell/drm/i915/i915-object.c     |  47 +++++++++++
 shell/drm/i915/i915-object.h     |   6 ++
 shell/examples/i915/gem_basic.js | 108 ++++++++++++++++++++++++
 shell/meson.build                |   3 +
 7 files changed, 343 insertions(+)
 create mode 100644 shell/drm/i915/i915-builtin.c
 create mode 100644 shell/drm/i915/i915-constants.c
 create mode 100644 shell/drm/i915/i915-constants.h
 create mode 100644 shell/drm/i915/i915-object.c
 create mode 100644 shell/drm/i915/i915-object.h
 create mode 100644 shell/examples/i915/gem_basic.js

diff --git a/shell/drm/i915/i915-builtin.c b/shell/drm/i915/i915-builtin.c
new file mode 100644
index 000000000..9338f92f2
--- /dev/null
+++ b/shell/drm/i915/i915-builtin.c
@@ -0,0 +1,34 @@
+#include "duktape.h"
+#include "drm-builtin.h"
+#include "igt-builtins.h"
+
+#include "i915-constants.h"
+#include "i915-object.h"
+
+static duk_ret_t i915_builtin_ctor(duk_context *ctx)
+{
+	duk_push_object(ctx);
+
+	duk_get_global_string(ctx, "drm");
+	duk_dup_top(ctx);
+	duk_put_prop_string(ctx, -3, "drm");
+	duk_set_prototype(ctx, -2);
+
+	duk_push_string(ctx, "i915");
+	duk_put_prop_string(ctx, -2, "name");
+
+	i915_constants(ctx);
+	i915_object_setup(ctx);
+
+	return 1;
+}
+
+__attribute__((constructor))
+static void __i915_register_builtin__(void)
+{
+	static struct drm_driver driver = {
+		.name = "i915",
+		.ctor = i915_builtin_ctor
+	};
+	drm_module_register_driver(&driver);
+}
diff --git a/shell/drm/i915/i915-constants.c b/shell/drm/i915/i915-constants.c
new file mode 100644
index 000000000..ef7b7457a
--- /dev/null
+++ b/shell/drm/i915/i915-constants.c
@@ -0,0 +1,139 @@
+#include "drm-uapi/i915_drm.h"
+#include "duktape.h"
+
+#include "i915-constants.h"
+
+#define C(x) { #x, x }
+
+static const duk_number_list_entry i915_ioctl[] = {
+	C(DRM_IOCTL_I915_INIT),
+	C(DRM_IOCTL_I915_FLUSH),
+	C(DRM_IOCTL_I915_FLIP),
+	C(DRM_IOCTL_I915_BATCHBUFFER),
+	C(DRM_IOCTL_I915_IRQ_EMIT),
+	C(DRM_IOCTL_I915_IRQ_WAIT),
+	C(DRM_IOCTL_I915_GETPARAM),
+	C(DRM_IOCTL_I915_SETPARAM),
+	C(DRM_IOCTL_I915_ALLOC),
+	C(DRM_IOCTL_I915_FREE),
+	C(DRM_IOCTL_I915_INIT_HEAP),
+	C(DRM_IOCTL_I915_CMDBUFFER),
+	C(DRM_IOCTL_I915_DESTROY_HEAP),
+	C(DRM_IOCTL_I915_SET_VBLANK_PIPE),
+	C(DRM_IOCTL_I915_GET_VBLANK_PIPE),
+	C(DRM_IOCTL_I915_VBLANK_SWAP),
+	C(DRM_IOCTL_I915_HWS_ADDR),
+	C(DRM_IOCTL_I915_GEM_INIT),
+	C(DRM_IOCTL_I915_GEM_EXECBUFFER),
+	C(DRM_IOCTL_I915_GEM_EXECBUFFER2),
+	C(DRM_IOCTL_I915_GEM_EXECBUFFER2_WR),
+	C(DRM_IOCTL_I915_GEM_PIN),
+	C(DRM_IOCTL_I915_GEM_UNPIN),
+	C(DRM_IOCTL_I915_GEM_BUSY),
+	C(DRM_IOCTL_I915_GEM_SET_CACHING),
+	C(DRM_IOCTL_I915_GEM_GET_CACHING),
+	C(DRM_IOCTL_I915_GEM_THROTTLE),
+	C(DRM_IOCTL_I915_GEM_ENTERVT),
+	C(DRM_IOCTL_I915_GEM_LEAVEVT),
+	C(DRM_IOCTL_I915_GEM_CREATE),
+	C(DRM_IOCTL_I915_GEM_PREAD),
+	C(DRM_IOCTL_I915_GEM_PWRITE),
+	C(DRM_IOCTL_I915_GEM_MMAP),
+	C(DRM_IOCTL_I915_GEM_MMAP_GTT),
+	C(DRM_IOCTL_I915_GEM_SET_DOMAIN),
+	C(DRM_IOCTL_I915_GEM_SW_FINISH),
+	C(DRM_IOCTL_I915_GEM_SET_TILING),
+	C(DRM_IOCTL_I915_GEM_GET_TILING),
+	C(DRM_IOCTL_I915_GEM_GET_APERTURE),
+	C(DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID),
+	C(DRM_IOCTL_I915_GEM_MADVISE),
+	C(DRM_IOCTL_I915_OVERLAY_PUT_IMAGE),
+	C(DRM_IOCTL_I915_OVERLAY_ATTRS),
+	C(DRM_IOCTL_I915_SET_SPRITE_COLORKEY),
+	C(DRM_IOCTL_I915_GET_SPRITE_COLORKEY),
+	C(DRM_IOCTL_I915_GEM_WAIT),
+	C(DRM_IOCTL_I915_GEM_CONTEXT_CREATE),
+	C(DRM_IOCTL_I915_GEM_CONTEXT_DESTROY),
+	C(DRM_IOCTL_I915_REG_READ),
+	C(DRM_IOCTL_I915_GET_RESET_STATS),
+	C(DRM_IOCTL_I915_GEM_USERPTR),
+	C(DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM),
+	C(DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM),
+	C(DRM_IOCTL_I915_PERF_OPEN),
+	C(DRM_IOCTL_I915_PERF_ADD_CONFIG),
+	C(DRM_IOCTL_I915_PERF_REMOVE_CONFIG),
+	C(DRM_IOCTL_I915_QUERY),
+
+	{ },
+};
+
+static const duk_number_list_entry i915_query[] = {
+	C(I915_PARAM_IRQ_ACTIVE),
+	C(I915_PARAM_ALLOW_BATCHBUFFER),
+	C(I915_PARAM_LAST_DISPATCH),
+	C(I915_PARAM_CHIPSET_ID),
+	C(I915_PARAM_HAS_GEM),
+	C(I915_PARAM_NUM_FENCES_AVAIL),
+	C(I915_PARAM_HAS_OVERLAY),
+	C(I915_PARAM_HAS_PAGEFLIPPING),
+	C(I915_PARAM_HAS_EXECBUF2),
+	C(I915_PARAM_HAS_BSD),
+	C(I915_PARAM_HAS_BLT),
+	C(I915_PARAM_HAS_RELAXED_FENCING),
+	C(I915_PARAM_HAS_COHERENT_RINGS),
+	C(I915_PARAM_HAS_EXEC_CONSTANTS),
+	C(I915_PARAM_HAS_RELAXED_DELTA),
+	C(I915_PARAM_HAS_GEN7_SOL_RESET),
+	C(I915_PARAM_HAS_LLC),
+	C(I915_PARAM_HAS_ALIASING_PPGTT),
+	C(I915_PARAM_HAS_WAIT_TIMEOUT),
+	C(I915_PARAM_HAS_SEMAPHORES),
+	C(I915_PARAM_HAS_PRIME_VMAP_FLUSH),
+	C(I915_PARAM_HAS_VEBOX),
+	C(I915_PARAM_HAS_SECURE_BATCHES),
+	C(I915_PARAM_HAS_PINNED_BATCHES),
+	C(I915_PARAM_HAS_EXEC_NO_RELOC),
+	C(I915_PARAM_HAS_EXEC_HANDLE_LUT),
+	C(I915_PARAM_HAS_WT),
+	C(I915_PARAM_CMD_PARSER_VERSION),
+	C(I915_PARAM_HAS_COHERENT_PHYS_GTT),
+	C(I915_PARAM_MMAP_VERSION),
+	C(I915_PARAM_HAS_BSD2),
+	C(I915_PARAM_REVISION),
+	C(I915_PARAM_SUBSLICE_TOTAL),
+	C(I915_PARAM_EU_TOTAL),
+	C(I915_PARAM_HAS_GPU_RESET),
+	C(I915_PARAM_HAS_RESOURCE_STREAMER),
+	C(I915_PARAM_HAS_EXEC_SOFTPIN),
+	C(I915_PARAM_HAS_POOLED_EU),
+	C(I915_PARAM_MIN_EU_IN_POOL),
+	C(I915_PARAM_MMAP_GTT_VERSION),
+	C(I915_PARAM_HAS_SCHEDULER),
+	C(I915_PARAM_HUC_STATUS),
+	C(I915_PARAM_HAS_EXEC_ASYNC),
+	C(I915_PARAM_HAS_EXEC_FENCE),
+	C(I915_PARAM_HAS_EXEC_CAPTURE),
+	C(I915_PARAM_SLICE_MASK),
+	C(I915_PARAM_SUBSLICE_MASK),
+	C(I915_PARAM_HAS_EXEC_BATCH_FIRST),
+	C(I915_PARAM_HAS_EXEC_FENCE_ARRAY),
+	C(I915_PARAM_HAS_CONTEXT_ISOLATION),
+	C(I915_PARAM_CS_TIMESTAMP_FREQUENCY),
+	//C(I915_PARAM_MMAP_GTT_COHERENT),
+
+	{},
+};
+
+void i915_constants(duk_context *ctx)
+{
+	duk_push_object(ctx);
+	duk_put_number_list(ctx, -1, i915_ioctl);
+	duk_put_prop_string(ctx, -2, "ioctl");
+
+	duk_push_object(ctx);
+	duk_put_number_list(ctx, -1, i915_query);
+	duk_put_prop_string(ctx, -2, "query");
+}
+
+#undef C
+
diff --git a/shell/drm/i915/i915-constants.h b/shell/drm/i915/i915-constants.h
new file mode 100644
index 000000000..832372253
--- /dev/null
+++ b/shell/drm/i915/i915-constants.h
@@ -0,0 +1,6 @@
+#ifndef I915_CONSTANTS_H
+#define I915_CONSTANTS_H
+
+void i915_constants(duk_context *ctx);
+
+#endif /* I915_CONSTANTS_H */
diff --git a/shell/drm/i915/i915-object.c b/shell/drm/i915/i915-object.c
new file mode 100644
index 000000000..71e722f75
--- /dev/null
+++ b/shell/drm/i915/i915-object.c
@@ -0,0 +1,47 @@
+#include <sys/ioctl.h>
+
+#include "duktape.h"
+
+#include "drm-gem.h"
+#include "i915-object.h"
+
+#include "drm-uapi/i915_drm.h"
+
+static duk_ret_t i915_object_ctor(duk_context *ctx)
+{
+	struct drm_i915_gem_create arg = {
+		.size = duk_get_uint(ctx, -1)
+	};
+	int fd;
+
+	duk_push_this(ctx);
+	duk_get_prop_string(ctx, -1, "fd");
+	fd = duk_get_int(ctx, -1);
+
+	if (ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &arg) < 0)
+		return -1;
+
+	duk_push_object(ctx);
+
+	duk_push_uint(ctx, arg.handle);
+	duk_put_prop_string(ctx, -2, "handle");
+
+	duk_push_uint(ctx, arg.size);
+	duk_put_prop_string(ctx, -2, "size");
+
+	duk_push_this(ctx);
+	duk_put_prop_string(ctx, -2, "driver");
+
+	duk_push_c_function(ctx, drm_gem_object_dtor, 1);
+	duk_set_finalizer(ctx, -2);
+
+	return 1;
+}
+
+duk_ret_t i915_object_setup(duk_context *ctx)
+{
+	duk_push_c_function(ctx, i915_object_ctor, 1);
+	duk_put_prop_string(ctx, -2, "Object");
+
+	return 1;
+}
diff --git a/shell/drm/i915/i915-object.h b/shell/drm/i915/i915-object.h
new file mode 100644
index 000000000..4b9a221d1
--- /dev/null
+++ b/shell/drm/i915/i915-object.h
@@ -0,0 +1,6 @@
+#ifndef I915_OBJECT_H
+#define I915_OBJECT_H
+
+duk_ret_t i915_object_setup(duk_context *ctx);
+
+#endif /* I915_OBJECT_H */
diff --git a/shell/examples/i915/gem_basic.js b/shell/examples/i915/gem_basic.js
new file mode 100644
index 000000000..e2c270ed6
--- /dev/null
+++ b/shell/examples/i915/gem_basic.js
@@ -0,0 +1,108 @@
+const i915 = igt.require(drm.drivers.i915.card());
+
+const i_create = i915.driver.ioctl.DRM_IOCTL_I915_GEM_CREATE;
+const i_open = i915.driver.drm.ioctl.DRM_IOCTL_GEM_OPEN;
+const i_flink = i915.driver.drm.ioctl.DRM_IOCTL_GEM_FLINK;
+const i_close = i915.driver.drm.ioctl.DRM_IOCTL_GEM_CLOSE;
+
+var arg = new Uint32Array(4);
+var handle;
+
+const create = function(size) {
+	arg[0] = size; /* only up to 4GiB! */
+	arg[1] = 0;
+	i915.ioctl(i_create, arg);
+	return arg[2];
+}
+
+const flink = function(handle) {
+	arg[0] = handle;
+	i915.ioctl(i_flink, arg);
+	return arg[1];
+}
+
+const open = function(name) {
+	arg[0] = name;
+	i915.ioctl(i_open, arg);
+	return arg[1];
+}
+
+const clone = function(handle) {
+	return open(flink(handle));
+}
+
+const close = function(handle) {
+	arg[0] = handle;
+	i915.ioctl(i_close, arg);
+}
+
+const bad_close = function(handle) {
+	arg[0] = handle;
+	i915.expect_ioctl(i_close, arg, -os.EINVAL);
+}
+
+const bad_values = [
+	0x00000000,
+	0x00000001,
+	0x00000010,
+	0x00000100,
+	0x00001000,
+	0x00010000,
+	0x00100000,
+	0x01000000,
+	0x10000000,
+	0x00010001,
+	0x00100010,
+	0x01000100,
+	0x10001000,
+	0x01010101,
+	0x10101010,
+	0x11111111,
+	0x00c00fee,
+	0xdeadbeef,
+	0xcccccccc,
+	0xaaaaaaaa,
+	0xa5a5a5a5,
+	0xc3c3c3c3,
+	0x0000ffff,
+	0x0007ffff,
+	0x0008ffff,
+	0x000fffff,
+	0x007fffff,
+	0x008fffff,
+	0x00ffffff,
+	0x07ffffff,
+	0x08ffffff,
+	0x0fffffff,
+	0x7fffffff,
+	0x8fffffff,
+	0xffffffff,
+];
+
+/* Check that all bad values (and their inverse) generate -EINVAL */
+bad_values.forEach(function(val) { bad_close(val); bad_close(~val); });
+
+/* Check basics do work after all */
+close(create(4096));
+
+/* And that we disallow double closes */
+close(handle = create(4096));
+bad_close(handle);
+
+/* But cloning does produce two distinct handles */
+close(clone(handle = create(4096)));
+close(handle);
+
+/* More clones; an army of them. */
+handle = create(4096);
+const count = 4096;
+const handles = new Array(count);
+for(var i = 0; i < count; i++)
+	handles[i] = clone(handle);
+close(handle);
+Math.permute(handles).forEach(close);
+Math.permute(handles).forEach(bad_close);
+bad_close(handle);
+
+/* And now that we're empty again, everything should be bad. */
+bad_values.forEach(function(val) { bad_close(val); bad_close(~val); });
diff --git a/shell/meson.build b/shell/meson.build
index ea871925e..c29950dba 100644
--- a/shell/meson.build
+++ b/shell/meson.build
@@ -5,6 +5,9 @@ executable('igt', [
 	     'drm/drm-gem.c',
 	     'drm/drm-kmod.c',
 	     'drm/drm-module.c',
+	     'drm/i915/i915-builtin.c',
+	     'drm/i915/i915-constants.c',
+	     'drm/i915/i915-object.c',
 	     'igt-builtins.c',
 	     'igt-builtins.c',
 	     'igt-math.c',
-- 
2.18.0



More information about the igt-dev mailing list