[igt-dev] [PATCH v7 01/14] fb: Add buffer map/unmap functions

Maxime Ripard maxime.ripard at bootlin.com
Tue Sep 11 08:47:28 UTC 2018


The current code to manipulate the buffer has the assumption that we can
create an underlying cairo instance.

However, when it comes to supporting various formats, cairo is very limited
so we would need to decouple the buffer access from cairo surfaces.

Let's create a function that allows to map the underlying GEM buffer from
an igt_fb structure, which will then allow use to manipulate as we wish.

Reviewed-by: Eric Anholt <eric at anholt.net>
Signed-off-by: Maxime Ripard <maxime.ripard at bootlin.com>
---
 lib/igt_fb.c | 65 +++++++++++++++++++++++++++++++++++++++++++----------
 lib/igt_fb.h |  2 ++-
 2 files changed, 55 insertions(+), 12 deletions(-)

diff --git a/lib/igt_fb.c b/lib/igt_fb.c
index 1085d25d33ce..542c62610412 100644
--- a/lib/igt_fb.c
+++ b/lib/igt_fb.c
@@ -1330,23 +1330,29 @@ int igt_dirty_fb(int fd, struct igt_fb *fb)
 	return drmModeDirtyFB(fb->fd, fb->fb_id, NULL, 0);
 }
 
+static void unmap_bo(struct igt_fb *fb, void *ptr)
+{
+	gem_munmap(ptr, fb->size);
+
+	if (fb->is_dumb)
+		igt_dirty_fb(fb->fd, fb);
+}
+
 static void destroy_cairo_surface__gtt(void *arg)
 {
 	struct igt_fb *fb = arg;
 
-	gem_munmap(cairo_image_surface_get_data(fb->cairo_surface), fb->size);
+	unmap_bo(fb, cairo_image_surface_get_data(fb->cairo_surface));
 	fb->cairo_surface = NULL;
-
-	if (fb->is_dumb)
-		igt_dirty_fb(fb->fd, fb);
 }
 
-static void create_cairo_surface__gtt(int fd, struct igt_fb *fb)
+static void *map_bo(int fd, struct igt_fb *fb)
 {
 	void *ptr;
 
-	gem_set_domain(fd, fb->gem_handle,
-		       I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
+	if (is_i915_device(fd))
+		gem_set_domain(fd, fb->gem_handle,
+			       I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
 
 	if (fb->is_dumb)
 		ptr = kmstest_dumb_map_buffer(fd, fb->gem_handle, fb->size,
@@ -1355,6 +1361,13 @@ static void create_cairo_surface__gtt(int fd, struct igt_fb *fb)
 		ptr = gem_mmap__gtt(fd, fb->gem_handle, fb->size,
 				    PROT_READ | PROT_WRITE);
 
+	return ptr;
+}
+
+static void create_cairo_surface__gtt(int fd, struct igt_fb *fb)
+{
+	void *ptr = map_bo(fd, fb);
+
 	fb->cairo_surface =
 		cairo_image_surface_create_for_data(ptr,
 						    drm_format_to_cairo(fb->drm_format),
@@ -1772,7 +1785,7 @@ static void destroy_cairo_surface__convert(void *arg)
 	if (blit->linear.handle)
 		free_linear_mapping(blit->fd, blit->fb, &blit->linear);
 	else
-		gem_munmap(blit->linear.map, fb->size);
+		unmap_bo(fb, blit->linear.map);
 
 	free(blit);
 
@@ -1796,11 +1809,9 @@ static void create_cairo_surface__convert(int fd, struct igt_fb *fb)
 		setup_linear_mapping(fd, fb, &blit->linear);
 	} else {
 		blit->linear.handle = 0;
-		gem_set_domain(fd, fb->gem_handle,
-			       I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
-		blit->linear.map = gem_mmap__gtt(fd, fb->gem_handle, fb->size,
-					      PROT_READ | PROT_WRITE);
+		blit->linear.map = map_bo(fd, fb);
 		igt_assert(blit->linear.map);
+
 		blit->linear.stride = fb->stride;
 		blit->linear.size = fb->size;
 		memcpy(blit->linear.offsets, fb->offsets, sizeof(fb->offsets));
@@ -1834,6 +1845,36 @@ static void create_cairo_surface__convert(int fd, struct igt_fb *fb)
 }
 
 /**
+ * igt_fb_map_buffer:
+ * @fd: open drm file descriptor
+ * @fb: pointer to an #igt_fb structure
+ *
+ * This function will creating a new mapping of the buffer and return a pointer
+ * to the content of the supplied framebuffer's plane. This mapping needs to be
+ * deleted using igt_fb_unmap_buffer().
+ *
+ * Returns:
+ * A pointer to a buffer with the contents of the framebuffer
+ */
+void *igt_fb_map_buffer(int fd, struct igt_fb *fb)
+{
+	return map_bo(fd, fb);
+}
+
+/**
+ * igt_fb_unmap_buffer:
+ * @fb: pointer to the backing igt_fb structure
+ * @buffer: pointer to the buffer previously mappped
+ *
+ * This function will unmap a buffer mapped previously with
+ * igt_fb_map_buffer().
+ */
+void igt_fb_unmap_buffer(struct igt_fb *fb, void *buffer)
+{
+	return unmap_bo(fb, buffer);
+}
+
+/**
  * igt_get_cairo_surface:
  * @fd: open drm file descriptor
  * @fb: pointer to an #igt_fb structure
diff --git a/lib/igt_fb.h b/lib/igt_fb.h
index d28bc0c4110a..ca028f550ab8 100644
--- a/lib/igt_fb.h
+++ b/lib/igt_fb.h
@@ -132,6 +132,8 @@ unsigned int igt_create_stereo_fb(int drm_fd, drmModeModeInfo *mode,
 				  uint32_t format, uint64_t tiling);
 void igt_remove_fb(int fd, struct igt_fb *fb);
 int igt_dirty_fb(int fd, struct igt_fb *fb);
+void *igt_fb_map_buffer(int fd, struct igt_fb *fb);
+void igt_fb_unmap_buffer(struct igt_fb *fb, void *buffer);
 
 int igt_create_bo_with_dimensions(int fd, int width, int height, uint32_t format,
 				  uint64_t modifier, unsigned stride,
-- 
git-series 0.9.1


More information about the igt-dev mailing list