etnaviv: drm: Don't miscalculate timeout
[mesa.git] / src / etnaviv / drm / etnaviv_cmd_stream.c
index 6a218ad0bf23ee2d2c4bcbfd5ccd750f7a7f96d3..0c12bfe4452c7914128dd01d69a51d335cd0c88b 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <assert.h>
+#include <stdlib.h>
 
 #include "etnaviv_drmif.h"
 #include "etnaviv_priv.h"
@@ -49,6 +50,35 @@ static void *grow(void *ptr, uint32_t nr, uint32_t *max, uint32_t sz)
        (x)->nr_ ## name ++; \
 })
 
+void etna_cmd_stream_realloc(struct etna_cmd_stream *stream, size_t n)
+{
+       size_t size;
+       void *buffer;
+
+       /*
+        * Increase the command buffer size by 1 kiB. Here we pick 1 kiB
+        * increment to prevent it from growing too much too quickly.
+        */
+       size = ALIGN(stream->size + n, 1024);
+
+       /* Command buffer is too big for older kernel versions */
+       if (size >= 32768)
+               goto error;
+
+       buffer = realloc(stream->buffer, size * 4);
+       if (!buffer)
+               goto error;
+
+       stream->buffer = buffer;
+       stream->size = size;
+
+       return;
+
+error:
+       WARN_MSG("command buffer too long, forcing flush.");
+       etna_cmd_stream_force_flush(stream);
+}
+
 static inline struct etna_cmd_stream_priv *
 etna_cmd_stream_priv(struct etna_cmd_stream *stream)
 {
@@ -129,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);
 
@@ -202,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));
 
@@ -237,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);