{
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);
/* 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;
}
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) {
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);
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));
{
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);
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;
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;
}
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);
{
return dev->fd;
}
+
+bool etnaviv_device_softpin_capable(struct etna_device *dev)
+{
+ return !!dev->use_softpin;
+}
#define ETNAVIV_DRMIF_H_
#include <xf86drm.h>
+#include <stdbool.h>
#include <stdint.h>
struct etna_bo;
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:
*/
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);
};
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:
*/
#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"
struct etna_bo_cache bo_cache;
+ int use_softpin;
+ struct util_vma_heap address_space;
+
int closefd; /* call close(fd) upon destruction */
};
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;
/*