summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/etnaviv/drm/etnaviv_bo.c11
-rw-r--r--src/etnaviv/drm/etnaviv_cmd_stream.c28
-rw-r--r--src/etnaviv/drm/etnaviv_device.c21
-rw-r--r--src/etnaviv/drm/etnaviv_drmif.h5
-rw-r--r--src/etnaviv/drm/etnaviv_priv.h5
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;
/*