diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/etnaviv/drm/etnaviv_bo.c | 11 | ||||
-rw-r--r-- | src/etnaviv/drm/etnaviv_cmd_stream.c | 28 | ||||
-rw-r--r-- | src/etnaviv/drm/etnaviv_device.c | 21 | ||||
-rw-r--r-- | src/etnaviv/drm/etnaviv_drmif.h | 5 | ||||
-rw-r--r-- | 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; /* |