[Intel-gfx] [RFC 1/3] drm/i915: Prepare gem object to handle resize

arun.siluvery at linux.intel.com arun.siluvery at linux.intel.com
Thu Mar 27 16:28:27 CET 2014


From: "Siluvery, Arun" <arun.siluvery at intel.com>

This patch adds data structure to handle gem object resize.
One such usecase where it is required is mipmaps; you cannot know
whether higher level mipmaps are required at the time of creating them,
so it is best to defer memory allocation for higher levels if possible.
GEM object should be resizeable to achieve this.

Add new parameter to i915_gem_create to specify initial size of backing store.

When the object is created we allocate backing store only for base size,
in the case of mipmaps it would be level0.
scratch page is used for lazy allocation (Daniel)
A stop marker denotes the end of real pages.
if higher levels are required additional space is requested using new ioctl.

Although the usecase considered is mipmaps, it can be used for other purposes.

Change-Id: I1acf539bb7d8d861deb7fbb1d2f32265f22ad28f
Signed-off-by: Siluvery, Arun <arun.siluvery at intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h |  7 +++++++
 drivers/gpu/drm/i915/i915_gem.c | 28 +++++++++++++++++++++++++++-
 include/uapi/drm/i915_drm.h     |  7 +++++++
 3 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4069800..cf65aad 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1875,6 +1875,13 @@ struct drm_i915_gem_object {
 		} userptr;
 	};
 
+	/* to handle resizing of gem object */
+	struct i915_gem_resize {
+		uint32_t stop;
+		uint32_t base_size;
+		struct page *scratch_page;
+	} gem_resize;
+
 	/** Object userdata */
 	uint32_t userdata;
 };
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 6153e01..71d7526 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -311,10 +311,36 @@ int
 i915_gem_create_ioctl(struct drm_device *dev, void *data,
 		      struct drm_file *file)
 {
+	int ret;
+	int total_page_count;
+	struct drm_i915_gem_object *obj;
 	struct drm_i915_gem_create *args = data;
 
-	return i915_gem_create(file, dev,
+	ret = i915_gem_create(file, dev,
 			       args->size, &args->handle);
+
+	if (ret)
+		return ret;
+
+	/*
+	 * TODO: args->pad is filled with garbage
+	 * Need a better method to identify that its a resizeable object,
+	 * use a magic number temporarily
+	 */
+	if (args->pad != 0x12345678)
+		return ret;
+
+	obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
+	if (&obj->base == NULL) {
+		printk(KERN_ERR "%s(), object not found\n", __func__);
+		return -ENOENT;
+	}
+	total_page_count = obj->base.size / PAGE_SIZE;
+	obj->gem_resize.base_size = 0;
+	obj->gem_resize.stop = total_page_count;
+	obj->gem_resize.scratch_page = NULL;
+
+	return 0;
 }
 
 static inline int
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index aa8469e..e455c9d 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -521,6 +521,13 @@ struct drm_i915_gem_create {
 	 */
 	__u32 handle;
 	__u32 pad;
+	/**
+	 * When an object needs to be resized this denotes the size for
+	 * which backing storage is created initially
+	 * eg in case of mipmaps, size of level0
+	 * object is resized later to allocate for higher levels
+	 */
+	__u64 base_size;
 };
 
 struct drm_i915_gem_pread {
-- 
1.9.1




More information about the Intel-gfx mailing list