[Mesa-dev] [PATCH 03/11] freedreno: use renderonly scanout

Jonathan Marek jonathan at marek.ca
Mon Sep 17 18:22:12 UTC 2018


Signed-off-by: Jonathan Marek <jonathan at marek.ca>
---
 .../drivers/freedreno/freedreno_resource.c    | 57 +++++++++++++++++--
 .../drivers/freedreno/freedreno_resource.h    |  1 +
 .../drivers/freedreno/freedreno_screen.c      | 29 +++-------
 .../drivers/freedreno/freedreno_screen.h      | 10 ++--
 .../freedreno/drm/freedreno_drm_public.h      |  4 ++
 .../freedreno/drm/freedreno_drm_winsys.c      | 23 ++++++--
 6 files changed, 85 insertions(+), 39 deletions(-)

diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
index 344004f696..adfa0f27a7 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -645,6 +645,9 @@ fd_resource_destroy(struct pipe_screen *pscreen,
 	fd_bc_invalidate_resource(rsc, true);
 	if (rsc->bo)
 		fd_bo_del(rsc->bo);
+	if (rsc->scanout)
+		renderonly_scanout_destroy(rsc->scanout, fd_screen(pscreen)->ro);
+
 	util_range_destroy(&rsc->valid_buffer_range);
 	FREE(rsc);
 }
@@ -657,9 +660,26 @@ fd_resource_get_handle(struct pipe_screen *pscreen,
 		unsigned usage)
 {
 	struct fd_resource *rsc = fd_resource(prsc);
-
-	return fd_screen_bo_get_handle(pscreen, rsc->bo,
-			rsc->slices[0].pitch * rsc->cpp, handle);
+	struct renderonly_scanout *scanout = rsc->scanout;
+	struct fd_bo *bo = rsc->bo;
+
+	handle->stride = rsc->slices[0].pitch * rsc->cpp;
+
+	if (handle->type == WINSYS_HANDLE_TYPE_SHARED) {
+		return fd_bo_get_name(bo, &handle->handle) == 0;
+	} else if (handle->type == WINSYS_HANDLE_TYPE_KMS) {
+		if (renderonly_get_handle(scanout, handle)) {
+			return TRUE;
+		} else {
+			handle->handle = fd_bo_handle(bo);
+			return TRUE;
+		}
+	} else if (handle->type == WINSYS_HANDLE_TYPE_FD) {
+		handle->handle = fd_bo_dmabuf(bo);
+		return TRUE;
+	} else {
+		return FALSE;
+	}
 }
 
 static uint32_t
@@ -801,8 +821,8 @@ fd_resource_create(struct pipe_screen *pscreen,
 		const struct pipe_resource *tmpl)
 {
 	struct fd_screen *screen = fd_screen(pscreen);
-	struct fd_resource *rsc = CALLOC_STRUCT(fd_resource);
-	struct pipe_resource *prsc = &rsc->base;
+	struct fd_resource *rsc;
+	struct pipe_resource *prsc;
 	enum pipe_format format = tmpl->format;
 	uint32_t size;
 
@@ -813,6 +833,33 @@ fd_resource_create(struct pipe_screen *pscreen,
 			tmpl->array_size, tmpl->last_level, tmpl->nr_samples,
 			tmpl->usage, tmpl->bind, tmpl->flags);
 
+	if (tmpl->bind & PIPE_BIND_SCANOUT) {
+		struct pipe_resource scanout_templat = *tmpl;
+		struct renderonly_scanout *scanout;
+		struct winsys_handle handle;
+
+		scanout = renderonly_scanout_for_resource(&scanout_templat,
+										screen->ro, &handle);
+		if (!scanout)
+			return NULL;
+
+		assert(handle.type == WINSYS_HANDLE_TYPE_FD);
+		// handle.modifier = modifier;
+		scanout_templat.bind &= ~PIPE_BIND_SCANOUT;
+		rsc = fd_resource(pscreen->resource_from_handle(pscreen, &scanout_templat,
+												&handle,
+												PIPE_HANDLE_USAGE_WRITE));
+		close(handle.handle);
+		if (!rsc)
+			return NULL;
+
+		rsc->scanout = scanout;
+		return &rsc->base;
+	}
+
+	rsc = CALLOC_STRUCT(fd_resource);
+	prsc = &rsc->base;
+
 	if (!rsc)
 		return NULL;
 
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.h b/src/gallium/drivers/freedreno/freedreno_resource.h
index 2834969110..baad2baa68 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.h
+++ b/src/gallium/drivers/freedreno/freedreno_resource.h
@@ -65,6 +65,7 @@ struct set;
 
 struct fd_resource {
 	struct pipe_resource base;
+	struct renderonly_scanout *scanout;
 	struct fd_bo *bo;
 	uint32_t cpp;
 	enum pipe_format internal_format;
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
index 33f14b8f24..ef88e5b121 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.c
+++ b/src/gallium/drivers/freedreno/freedreno_screen.c
@@ -649,27 +649,6 @@ fd_get_compiler_options(struct pipe_screen *pscreen,
 	return NULL;
 }
 
-boolean
-fd_screen_bo_get_handle(struct pipe_screen *pscreen,
-		struct fd_bo *bo,
-		unsigned stride,
-		struct winsys_handle *whandle)
-{
-	whandle->stride = stride;
-
-	if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
-		return fd_bo_get_name(bo, &whandle->handle) == 0;
-	} else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
-		whandle->handle = fd_bo_handle(bo);
-		return TRUE;
-	} else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
-		whandle->handle = fd_bo_dmabuf(bo);
-		return TRUE;
-	} else {
-		return FALSE;
-	}
-}
-
 struct fd_bo *
 fd_screen_bo_from_handle(struct pipe_screen *pscreen,
 		struct winsys_handle *whandle)
@@ -697,7 +676,7 @@ fd_screen_bo_from_handle(struct pipe_screen *pscreen,
 }
 
 struct pipe_screen *
-fd_screen_create(struct fd_device *dev)
+fd_screen_create(struct fd_device *dev, struct renderonly *ro)
 {
 	struct fd_screen *screen = CALLOC_STRUCT(fd_screen);
 	struct pipe_screen *pscreen;
@@ -717,8 +696,14 @@ fd_screen_create(struct fd_device *dev)
 	pscreen = &screen->base;
 
 	screen->dev = dev;
+	screen->ro = renderonly_dup(ro);
 	screen->refcnt = 1;
 
+	if (!screen->ro) {
+		DBG("could not create renderonly object");
+		goto fail;
+	}
+
 	// maybe this should be in context?
 	screen->pipe = fd_pipe_new(screen->dev, FD_PIPE_3D);
 	if (!screen->pipe) {
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.h b/src/gallium/drivers/freedreno/freedreno_screen.h
index 4d9497ccb5..a39fcb50a7 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.h
+++ b/src/gallium/drivers/freedreno/freedreno_screen.h
@@ -36,6 +36,7 @@
 #include "util/u_memory.h"
 #include "util/slab.h"
 #include "os/os_thread.h"
+#include "renderonly/renderonly.h"
 
 #include "freedreno_batch_cache.h"
 #include "freedreno_perfcntr.h"
@@ -82,6 +83,7 @@ struct fd_screen {
 	void *compiler;          /* currently unused for a2xx */
 
 	struct fd_device *dev;
+	struct renderonly *ro;
 
 	/* NOTE: we still need a pipe associated with the screen in a few
 	 * places, like screen->get_timestamp().  For anything context
@@ -104,15 +106,11 @@ fd_screen(struct pipe_screen *pscreen)
 {
 	return (struct fd_screen *)pscreen;
 }
-
-boolean fd_screen_bo_get_handle(struct pipe_screen *pscreen,
-		struct fd_bo *bo,
-		unsigned stride,
-		struct winsys_handle *whandle);
 struct fd_bo * fd_screen_bo_from_handle(struct pipe_screen *pscreen,
 		struct winsys_handle *whandle);
 
-struct pipe_screen * fd_screen_create(struct fd_device *dev);
+struct pipe_screen *
+fd_screen_create(struct fd_device *dev, struct renderonly *ro);
 
 static inline boolean
 is_a20x(struct fd_screen *screen)
diff --git a/src/gallium/winsys/freedreno/drm/freedreno_drm_public.h b/src/gallium/winsys/freedreno/drm/freedreno_drm_public.h
index a7ba20707d..ea643ccfe8 100644
--- a/src/gallium/winsys/freedreno/drm/freedreno_drm_public.h
+++ b/src/gallium/winsys/freedreno/drm/freedreno_drm_public.h
@@ -3,6 +3,10 @@
 #define __FREEDRENO_DRM_PUBLIC_H__
 
 struct pipe_screen;
+struct renderonly;
+
+struct pipe_screen *
+fd_drm_screen_create_renderonly(struct renderonly *ro);
 
 struct pipe_screen *fd_drm_screen_create(int drmFD);
 
diff --git a/src/gallium/winsys/freedreno/drm/freedreno_drm_winsys.c b/src/gallium/winsys/freedreno/drm/freedreno_drm_winsys.c
index c1ea22a064..ea28b5b6b2 100644
--- a/src/gallium/winsys/freedreno/drm/freedreno_drm_winsys.c
+++ b/src/gallium/winsys/freedreno/drm/freedreno_drm_winsys.c
@@ -36,9 +36,8 @@
 #include "util/u_hash_table.h"
 #include "os/os_thread.h"
 
-#include "freedreno_drm_public.h"
-
 #include "freedreno/freedreno_screen.h"
+#include "freedreno_drm_public.h"
 
 static struct util_hash_table *fd_tab = NULL;
 
@@ -87,7 +86,7 @@ static int compare_fd(void *key1, void *key2)
 }
 
 struct pipe_screen *
-fd_drm_screen_create(int fd)
+fd_drm_screen_create_renderonly(struct renderonly *ro)
 {
 	struct pipe_screen *pscreen = NULL;
 
@@ -98,15 +97,15 @@ fd_drm_screen_create(int fd)
 			goto unlock;
 	}
 
-	pscreen = util_hash_table_get(fd_tab, intptr_to_pointer(fd));
+	pscreen = util_hash_table_get(fd_tab, intptr_to_pointer(ro->gpu_fd));
 	if (pscreen) {
 		fd_screen(pscreen)->refcnt++;
 	} else {
-		struct fd_device *dev = fd_device_new_dup(fd);
+		struct fd_device *dev = fd_device_new_dup(ro->gpu_fd);
 		if (!dev)
 			goto unlock;
 
-		pscreen = fd_screen_create(dev);
+		pscreen = fd_screen_create(dev, ro);
 		if (pscreen) {
 			int fd = fd_device_fd(dev);
 
@@ -125,3 +124,15 @@ unlock:
 	mtx_unlock(&fd_screen_mutex);
 	return pscreen;
 }
+
+struct pipe_screen *
+fd_drm_screen_create(int fd)
+{
+	struct renderonly ro = {
+      .create_for_resource = renderonly_create_gpu_import_for_resource,
+      .kms_fd = -1,
+      .gpu_fd = fd
+   };
+
+   return fd_drm_screen_create_renderonly(&ro);
+}
-- 
2.17.1



More information about the mesa-dev mailing list