Mesa (master): etnaviv: drm: add softpin interface

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Oct 18 17:11:34 UTC 2019


Module: Mesa
Branch: master
Commit: 0bdf5420f1ef7174fc81f57c307cd446bb673fc8
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0bdf5420f1ef7174fc81f57c307cd446bb673fc8

Author: Lucas Stach <l.stach at pengutronix.de>
Date:   Fri Aug  2 14:48:09 2019 +0200

etnaviv: drm: add softpin interface

If softpin is available on the kernel side, we transparently replace the
relocs with self-managed GPU virtual addresses. This allows to skip some
work at the kernel side, as it doesn't need to touch the command stream
anymore before submitting it to the hardware.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Reviewed-by: Jonathan Marek <jonathan at marek.ca>

---

 src/etnaviv/drm/etnaviv_bo.c         | 11 +++++++++++
 src/etnaviv/drm/etnaviv_cmd_stream.c | 28 +++++++++++++++++++++-------
 src/etnaviv/drm/etnaviv_device.c     | 21 +++++++++++++++++++++
 src/etnaviv/drm/etnaviv_drmif.h      |  5 +++++
 src/etnaviv/drm/etnaviv_priv.h       |  5 +++++
 5 files changed, 63 insertions(+), 7 deletions(-)

diff --git a/src/etnaviv/drm/etnaviv_bo.c b/src/etnaviv/drm/etnaviv_bo.c
index ccf5da7c8c7..0ec64b780f5 100644
--- a/src/etnaviv/drm/etnaviv_bo.c
+++ b/src/etnaviv/drm/etnaviv_bo.c
@@ -46,6 +46,9 @@ void _etna_bo_del(struct etna_bo *bo)
 {
 	VG_BO_FREE(bo);
 
+	if (bo->va)
+		util_vma_heap_free(&bo->dev->address_space, bo->va, bo->size);
+
 	if (bo->map)
 		os_munmap(bo->map, bo->size);
 
@@ -106,6 +109,9 @@ static struct etna_bo *bo_from_handle(struct etna_device *dev,
 	/* add ourselves to the handle table: */
 	_mesa_hash_table_insert(dev->handle_table, &bo->handle, bo);
 
+	if (dev->use_softpin)
+		bo->va = util_vma_heap_alloc(&dev->address_space, bo->size, 4096);
+
 	return bo;
 }
 
@@ -319,6 +325,11 @@ uint32_t etna_bo_size(struct etna_bo *bo)
 	return bo->size;
 }
 
+uint32_t etna_bo_gpu_va(struct etna_bo *bo)
+{
+	return bo->va;
+}
+
 void *etna_bo_map(struct etna_bo *bo)
 {
 	if (!bo->map) {
diff --git a/src/etnaviv/drm/etnaviv_cmd_stream.c b/src/etnaviv/drm/etnaviv_cmd_stream.c
index ef5143003ae..0c12bfe4452 100644
--- a/src/etnaviv/drm/etnaviv_cmd_stream.c
+++ b/src/etnaviv/drm/etnaviv_cmd_stream.c
@@ -159,6 +159,7 @@ static uint32_t append_bo(struct etna_cmd_stream *stream, struct etna_bo *bo)
 
 	priv->submit.bos[idx].flags = 0;
 	priv->submit.bos[idx].handle = bo->handle;
+	priv->submit.bos[idx].presumed = bo->va;
 
 	priv->bos[idx] = etna_bo_ref(bo);
 
@@ -232,6 +233,9 @@ void etna_cmd_stream_flush(struct etna_cmd_stream *stream, int in_fence_fd,
 	if (out_fence_fd)
 		req.flags |= ETNA_SUBMIT_FENCE_FD_OUT;
 
+	if (gpu->dev->use_softpin)
+		req.flags |= ETNA_SUBMIT_SOFTPIN;
+
 	ret = drmCommandWriteRead(gpu->dev->fd, DRM_ETNAVIV_GEM_SUBMIT,
 			&req, sizeof(req));
 
@@ -267,19 +271,29 @@ void etna_cmd_stream_reloc(struct etna_cmd_stream *stream,
 {
 	struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream);
 	struct drm_etnaviv_gem_submit_reloc *reloc;
-	uint32_t idx = APPEND(&priv->submit, relocs);
-	uint32_t addr = 0;
+	uint32_t addr = r->bo->va + r->offset;
+	uint32_t bo_idx = bo2idx(stream, r->bo, r->flags);
+	uint32_t idx;
 
-	reloc = &priv->submit.relocs[idx];
+	if (!priv->pipe->gpu->dev->use_softpin) {
+		idx = APPEND(&priv->submit, relocs);
+		reloc = &priv->submit.relocs[idx];
 
-	reloc->reloc_idx = bo2idx(stream, r->bo, r->flags);
-	reloc->reloc_offset = r->offset;
-	reloc->submit_offset = stream->offset * 4; /* in bytes */
-	reloc->flags = 0;
+		reloc->reloc_idx = bo_idx;
+		reloc->reloc_offset = r->offset;
+		reloc->submit_offset = stream->offset * 4; /* in bytes */
+		reloc->flags = 0;
+	}
 
 	etna_cmd_stream_emit(stream, addr);
 }
 
+void etna_cmd_stream_ref_bo(struct etna_cmd_stream *stream, struct etna_bo *bo,
+		uint32_t flags)
+{
+	bo2idx(stream, bo, flags);
+}
+
 void etna_cmd_stream_perf(struct etna_cmd_stream *stream, const struct etna_perf *p)
 {
 	struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream);
diff --git a/src/etnaviv/drm/etnaviv_device.c b/src/etnaviv/drm/etnaviv_device.c
index b8d465ac8a4..32991d0a5b3 100644
--- a/src/etnaviv/drm/etnaviv_device.c
+++ b/src/etnaviv/drm/etnaviv_device.c
@@ -46,6 +46,10 @@ u32_equals(const void *key1, const void *key2)
 struct etna_device *etna_device_new(int fd)
 {
 	struct etna_device *dev = calloc(sizeof(*dev), 1);
+	struct drm_etnaviv_param req = {
+		.param = ETNAVIV_PARAM_SOFTPIN_START_ADDR,
+	};
+	int ret;
 
 	if (!dev)
 		return NULL;
@@ -56,6 +60,14 @@ struct etna_device *etna_device_new(int fd)
 	dev->name_table = _mesa_hash_table_create(NULL, u32_hash, u32_equals);
 	etna_bo_cache_init(&dev->bo_cache);
 
+	ret = drmCommandWriteRead(dev->fd, DRM_ETNAVIV_GET_PARAM, &req, sizeof(req));
+	if (!ret && req.value != ~0ULL) {
+		const uint64_t _4GB = 1ull << 32;
+
+		util_vma_heap_init(&dev->address_space, req.value, _4GB - req.value);
+		dev->use_softpin = 1;
+	}
+
 	return dev;
 }
 
@@ -84,6 +96,10 @@ struct etna_device *etna_device_ref(struct etna_device *dev)
 static void etna_device_del_impl(struct etna_device *dev)
 {
 	etna_bo_cache_cleanup(&dev->bo_cache, 0);
+
+	if (dev->use_softpin)
+		util_vma_heap_finish(&dev->address_space);
+
 	_mesa_hash_table_destroy(dev->handle_table, NULL);
 	_mesa_hash_table_destroy(dev->name_table, NULL);
 
@@ -115,3 +131,8 @@ int etna_device_fd(struct etna_device *dev)
 {
    return dev->fd;
 }
+
+bool etnaviv_device_softpin_capable(struct etna_device *dev)
+{
+	return !!dev->use_softpin;
+}
diff --git a/src/etnaviv/drm/etnaviv_drmif.h b/src/etnaviv/drm/etnaviv_drmif.h
index ff08ab50dbc..c2dd034cc2e 100644
--- a/src/etnaviv/drm/etnaviv_drmif.h
+++ b/src/etnaviv/drm/etnaviv_drmif.h
@@ -28,6 +28,7 @@
 #define ETNAVIV_DRMIF_H_
 
 #include <xf86drm.h>
+#include <stdbool.h>
 #include <stdint.h>
 
 struct etna_bo;
@@ -92,6 +93,7 @@ struct etna_device *etna_device_new_dup(int fd);
 struct etna_device *etna_device_ref(struct etna_device *dev);
 void etna_device_del(struct etna_device *dev);
 int etna_device_fd(struct etna_device *dev);
+bool etnaviv_device_softpin_capable(struct etna_device *dev);
 
 /* gpu functions:
  */
@@ -124,6 +126,7 @@ int etna_bo_get_name(struct etna_bo *bo, uint32_t *name);
 uint32_t etna_bo_handle(struct etna_bo *bo);
 int etna_bo_dmabuf(struct etna_bo *bo);
 uint32_t etna_bo_size(struct etna_bo *bo);
+uint32_t etna_bo_gpu_va(struct etna_bo *bo);
 void * etna_bo_map(struct etna_bo *bo);
 int etna_bo_cpu_prep(struct etna_bo *bo, uint32_t op);
 void etna_bo_cpu_fini(struct etna_bo *bo);
@@ -192,6 +195,8 @@ struct etna_reloc {
 };
 
 void etna_cmd_stream_reloc(struct etna_cmd_stream *stream, const struct etna_reloc *r);
+void etna_cmd_stream_ref_bo(struct etna_cmd_stream *stream,
+		struct etna_bo *bo, uint32_t flags);
 
 /* performance monitoring functions:
  */
diff --git a/src/etnaviv/drm/etnaviv_priv.h b/src/etnaviv/drm/etnaviv_priv.h
index a4b6a9df254..2ab0e473ea9 100644
--- a/src/etnaviv/drm/etnaviv_priv.h
+++ b/src/etnaviv/drm/etnaviv_priv.h
@@ -44,6 +44,7 @@
 #include "util/macros.h"
 #include "util/u_atomic.h"
 #include "util/u_debug.h"
+#include "util/vma.h"
 
 #include "etnaviv_drmif.h"
 #include "drm-uapi/etnaviv_drm.h"
@@ -76,6 +77,9 @@ struct etna_device {
 
 	struct etna_bo_cache bo_cache;
 
+	int use_softpin;
+	struct util_vma_heap address_space;
+
 	int closefd;        /* call close(fd) upon destruction */
 };
 
@@ -97,6 +101,7 @@ struct etna_bo {
 	uint32_t        flags;
 	uint32_t        name;           /* flink global handle (DRI2 name) */
 	uint64_t        offset;         /* offset to mmap() */
+	uint32_t        va;             /* GPU virtual address */
 	int		refcnt;
 
 	/*




More information about the mesa-commit mailing list