From: Marek Vasut Date: Thu, 5 Sep 2019 17:57:39 +0000 (+0200) Subject: etnaviv: Command buffer realloc X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0c38c5454b34af6746b63210f9eb43a40316333e;p=mesa.git 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 --- 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 +#include #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)