unsigned flags)
{
struct drm_i915_gem_exec_fence *fence =
- util_dynarray_grow(&batch->exec_fences, sizeof(*fence));
+ util_dynarray_grow(&batch->exec_fences, struct drm_i915_gem_exec_fence, 1);
*fence = (struct drm_i915_gem_exec_fence) {
.handle = syncpt->handle,
};
struct iris_syncpt **store =
- util_dynarray_grow(&batch->syncpts, sizeof(*store));
+ util_dynarray_grow(&batch->syncpts, struct iris_syncpt *, 1);
*store = NULL;
iris_syncpt_reference(batch->screen, store, syncpt);
/* plbu commands */
#define PLBU_CMD_BEGIN(max) { \
int i = 0, max_n = max; \
- uint32_t *plbu_cmd = util_dynarray_grow_cap(&ctx->plbu_cmd_array, max_n * 4);
+ uint32_t *plbu_cmd = util_dynarray_ensure_cap(&ctx->plbu_cmd_array, ctx->plbu_cmd_array.size + max_n * 4);
#define PLBU_CMD_END() \
assert(i <= max_n); \
/* vs commands */
#define VS_CMD_BEGIN(max) { \
int i = 0, max_n = max; \
- uint32_t *vs_cmd = util_dynarray_grow_cap(&ctx->vs_cmd_array, max_n * 4);
+ uint32_t *vs_cmd = util_dynarray_ensure_cap(&ctx->vs_cmd_array, ctx->vs_cmd_array.size + max_n * 4);
#define VS_CMD_END() \
assert(i <= max_n); \
lima_finish_plbu_cmd(struct lima_context *ctx)
{
int i = 0;
- uint32_t *plbu_cmd = util_dynarray_grow_cap(&ctx->plbu_cmd_array, 2 * 4);
+ uint32_t *plbu_cmd = util_dynarray_ensure_cap(&ctx->plbu_cmd_array, ctx->plbu_cmd_array.size + 2 * 4);
plbu_cmd[i++] = 0x00000000;
plbu_cmd[i++] = 0x50000000; /* END */
}
struct drm_lima_gem_submit_bo *submit_bo =
- util_dynarray_grow(&submit->gem_bos, sizeof(*submit_bo));
+ util_dynarray_grow(&submit->gem_bos, struct drm_lima_gem_submit_bo, 1);
submit_bo->handle = bo->handle;
submit_bo->flags = flags;
- struct lima_bo **jbo = util_dynarray_grow(&submit->bos, sizeof(*jbo));
+ struct lima_bo **jbo = util_dynarray_grow(&submit->bos, struct lima_bo, 1);
*jbo = bo;
/* prevent bo from being freed when submit start */
float v[4] = {a, b, c, d};
int idx = fpc->imm_data.size >> 4;
- memcpy(util_dynarray_grow(&fpc->imm_data, sizeof(float) * 4), v, 4 * sizeof(float));
+ memcpy(util_dynarray_grow(&fpc->imm_data, float, 4), v, 4 * sizeof(float));
return nvfx_reg(NVFXSR_IMM, idx);
}
if (nv50->global_residents.size <= (end * sizeof(struct pipe_resource *))) {
const unsigned old_size = nv50->global_residents.size;
- const unsigned req_size = end * sizeof(struct pipe_resource *);
- util_dynarray_resize(&nv50->global_residents, req_size);
+ util_dynarray_resize(&nv50->global_residents, struct pipe_resource *, end);
memset((uint8_t *)nv50->global_residents.data + old_size, 0,
- req_size - old_size);
+ nv50->global_residents.size - old_size);
}
if (resources) {
if (nvc0->global_residents.size <= (end * sizeof(struct pipe_resource *))) {
const unsigned old_size = nvc0->global_residents.size;
- const unsigned req_size = end * sizeof(struct pipe_resource *);
- util_dynarray_resize(&nvc0->global_residents, req_size);
+ util_dynarray_resize(&nvc0->global_residents, struct pipe_resource *, end);
memset((uint8_t *)nvc0->global_residents.data + old_size, 0,
- req_size - old_size);
+ nvc0->global_residents.size - old_size);
}
if (resources) {
source = &scalarized;
}
- memcpy(util_dynarray_grow(emission, size), source, size);
+ memcpy(util_dynarray_grow_bytes(emission, 1, size), source, size);
}
/* Emit padding (all zero) */
- memset(util_dynarray_grow(emission, bundle->padding), 0, bundle->padding);
+ memset(util_dynarray_grow_bytes(emission, 1, bundle->padding), 0, bundle->padding);
/* Tack on constants */
}
struct ubo_range_entry *entry =
- util_dynarray_grow(&ranges, sizeof(struct ubo_range_entry));
+ util_dynarray_grow(&ranges, struct ubo_range_entry, 1);
entry->range.block = b;
entry->range.start = first_bit;
* Set the first bit used, and return the start address.
*/
uint64_t node_size = 64ull * bucket->size;
- node = util_dynarray_grow(vma_list, sizeof(struct vma_bucket_node));
+ node = util_dynarray_grow(vma_list, struct vma_bucket_node, 1);
if (unlikely(!node))
return 0ull;
if (!node) {
/* No node - the whole group of 64 blocks must have been in-use. */
- node = util_dynarray_grow(vma_list, sizeof(struct vma_bucket_node));
+ node = util_dynarray_grow(vma_list, struct vma_bucket_node, 1);
if (unlikely(!node))
return; /* bogus, leaks some GPU VMA, but nothing we can do... */
#include <stdlib.h>
#include <string.h>
+#include <limits.h>
#include "ralloc.h"
#ifdef __cplusplus
return (void *)((char *)buf->data + buf->size);
}
-static inline void *
-util_dynarray_grow_cap(struct util_dynarray *buf, int diff)
-{
- return util_dynarray_ensure_cap(buf, buf->size + diff);
-}
-
/* use util_dynarray_trim to reduce the allocated storage */
-static inline void *
-util_dynarray_resize(struct util_dynarray *buf, unsigned newsize)
+MUST_CHECK static inline void *
+util_dynarray_resize_bytes(struct util_dynarray *buf, unsigned nelts, size_t eltsize)
{
+ if (unlikely(nelts > UINT_MAX / eltsize))
+ return 0;
+
+ unsigned newsize = nelts * eltsize;
void *p = util_dynarray_ensure_cap(buf, newsize);
+ if (!p)
+ return 0;
+
buf->size = newsize;
return p;
struct util_dynarray *from_buf)
{
util_dynarray_init(buf, mem_ctx);
- util_dynarray_resize(buf, from_buf->size);
- memcpy(buf->data, from_buf->data, from_buf->size);
+ if (util_dynarray_resize_bytes(buf, from_buf->size, 1))
+ memcpy(buf->data, from_buf->data, from_buf->size);
}
-static inline void *
-util_dynarray_grow(struct util_dynarray *buf, int diff)
+MUST_CHECK static inline void *
+util_dynarray_grow_bytes(struct util_dynarray *buf, unsigned ngrow, size_t eltsize)
{
- return util_dynarray_resize(buf, buf->size + diff);
+ unsigned growbytes = ngrow * eltsize;
+
+ if (unlikely(ngrow > (UINT_MAX / eltsize) ||
+ growbytes > UINT_MAX - buf->size))
+ return 0;
+
+ unsigned newsize = buf->size + growbytes;
+ void *p = util_dynarray_ensure_cap(buf, newsize);
+ if (!p)
+ return 0;
+
+ buf->size = newsize;
+
+ return p;
}
static inline void
}
}
-#define util_dynarray_append(buf, type, v) do {type __v = (v); memcpy(util_dynarray_grow((buf), sizeof(type)), &__v, sizeof(type));} while(0)
+#define util_dynarray_append(buf, type, v) do {type __v = (v); memcpy(util_dynarray_grow_bytes((buf), 1, sizeof(type)), &__v, sizeof(type));} while(0)
+/* Returns a pointer to the space of the first new element (in case of growth) or NULL on failure. */
+#define util_dynarray_resize(buf, type, nelts) util_dynarray_resize_bytes(buf, (nelts), sizeof(type))
+#define util_dynarray_grow(buf, type, ngrow) util_dynarray_grow_bytes(buf, (ngrow), sizeof(type))
#define util_dynarray_top_ptr(buf, type) (type*)((char*)(buf)->data + (buf)->size - sizeof(type))
#define util_dynarray_top(buf, type) *util_dynarray_top_ptr(buf, type)
#define util_dynarray_pop_ptr(buf, type) (type*)((char*)(buf)->data + ((buf)->size -= sizeof(type)))