diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c index a0693c0e5b6..efe304c01c7 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene.c +++ b/src/gallium/drivers/llvmpipe/lp_scene.c @@ -28,6 +28,7 @@ #include "util/u_framebuffer.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/reallocarray.h" #include "util/u_inlines.h" #include "util/format/u_format.h" #include "lp_scene.h" @@ -101,6 +102,7 @@ lp_scene_destroy(struct lp_scene *scene) { lp_scene_end_rasterization(scene); mtx_destroy(&scene->mutex); + free(scene->tiles); assert(scene->data.head == &scene->data.first); slab_free_st(&scene->setup->scene_slab, scene); } @@ -245,7 +247,7 @@ lp_scene_end_rasterization(struct lp_scene *scene ) /* Reset all command lists: */ - memset(scene->tile, 0, sizeof scene->tile); + memset(scene->tiles, 0, sizeof(struct cmd_bin) * scene->num_alloced_tiles); /* Decrement texture ref counts */ @@ -612,6 +614,15 @@ void lp_scene_begin_binning(struct lp_scene *scene, assert(scene->tiles_x <= TILES_X); assert(scene->tiles_y <= TILES_Y); + unsigned num_required_tiles = scene->tiles_x * scene->tiles_y; + if (scene->num_alloced_tiles < num_required_tiles) { + scene->tiles = reallocarray(scene->tiles, num_required_tiles, sizeof(struct cmd_bin)); + if (!scene->tiles) + return; + memset(scene->tiles, 0, sizeof(struct cmd_bin) * num_required_tiles); + scene->num_alloced_tiles = num_required_tiles; + } + /* * Determine how many layers the fb has (used for clamping layer value). * OpenGL (but not d3d10) permits different amount of layers per rt, however diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h index 0a527ede8ad..cbcc4339a9a 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene.h +++ b/src/gallium/drivers/llvmpipe/lp_scene.h @@ -197,7 +197,8 @@ struct lp_scene { int curr_x, curr_y; /**< for iterating over bins */ mtx_t mutex; - struct cmd_bin tile[TILES_X][TILES_Y]; + unsigned num_alloced_tiles; + struct cmd_bin *tiles; struct data_block_list data; }; @@ -300,7 +301,8 @@ lp_scene_alloc_aligned(struct lp_scene *scene, unsigned size, static inline struct cmd_bin * lp_scene_get_bin(struct lp_scene *scene, unsigned x, unsigned y) { - return &scene->tile[x][y]; + unsigned idx = scene->tiles_x * y + x; + return &scene->tiles[idx]; }