summaryrefslogtreecommitdiffstats
path: root/src/etnaviv
diff options
context:
space:
mode:
authorMarek Vasut <[email protected]>2019-09-05 19:57:39 +0200
committerLucas Stach <[email protected]>2019-10-18 17:03:25 +0000
commit0c38c5454b34af6746b63210f9eb43a40316333e (patch)
tree93a19344ae63163b7fbdf25410735286c57c8b96 /src/etnaviv
parent1456aa61cc51f6e7727944d58a662d00158cf111 (diff)
etnaviv: Command buffer realloc
Reallocate the command stream buffer in case it is too small. The older kernel versions are limited to 64 kiB buffer, so limit the size to avoid oversized buffers. Signed-off-by: Marek Vasut <[email protected]>
Diffstat (limited to 'src/etnaviv')
-rw-r--r--src/etnaviv/drm/etnaviv_cmd_stream.c30
-rw-r--r--src/etnaviv/drm/etnaviv_drmif.h4
2 files changed, 33 insertions, 1 deletions
diff --git a/src/etnaviv/drm/etnaviv_cmd_stream.c b/src/etnaviv/drm/etnaviv_cmd_stream.c
index 6a218ad0bf2..ef5143003ae 100644
--- a/src/etnaviv/drm/etnaviv_cmd_stream.c
+++ b/src/etnaviv/drm/etnaviv_cmd_stream.c
@@ -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)
{
diff --git a/src/etnaviv/drm/etnaviv_drmif.h b/src/etnaviv/drm/etnaviv_drmif.h
index 7fb01c8a654..ff08ab50dbc 100644
--- a/src/etnaviv/drm/etnaviv_drmif.h
+++ b/src/etnaviv/drm/etnaviv_drmif.h
@@ -154,10 +154,12 @@ static inline uint32_t etna_cmd_stream_avail(struct etna_cmd_stream *stream)
return stream->size - stream->offset - END_CLEARANCE;
}
+void etna_cmd_stream_realloc(struct etna_cmd_stream *stream, size_t n);
+
static inline void etna_cmd_stream_reserve(struct etna_cmd_stream *stream, size_t n)
{
if (etna_cmd_stream_avail(stream) < n)
- etna_cmd_stream_force_flush(stream);
+ etna_cmd_stream_realloc(stream, n);
}
static inline void etna_cmd_stream_emit(struct etna_cmd_stream *stream, uint32_t data)