diff options
author | Keith Whitwell <[email protected]> | 2010-08-27 17:49:40 +0100 |
---|---|---|
committer | Keith Whitwell <[email protected]> | 2010-09-07 14:01:43 +0100 |
commit | 6419ecd02ce43a2614822e228f306d4db589f317 (patch) | |
tree | 36aeeb7d37fdec2cd5e6a7f72440c3e1fa30c552 /src/gallium/drivers/llvmpipe/lp_scene.h | |
parent | c512ba88a7e33f14b86feb9c0aaf1ebed5f50629 (diff) |
llvmpipe: enforce fixed memory limit on scenes
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_scene.h')
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_scene.h | 140 |
1 files changed, 70 insertions, 70 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h index e933a84b902..d4f7b047c2a 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene.h +++ b/src/gallium/drivers/llvmpipe/lp_scene.h @@ -48,9 +48,17 @@ struct lp_scene_queue; #define TILES_Y (LP_MAX_HEIGHT / TILE_SIZE) -#define CMD_BLOCK_MAX 128 -#define DATA_BLOCK_SIZE (16 * 1024 - sizeof(unsigned) - sizeof(void *)) - +#define CMD_BLOCK_MAX 16 +#define DATA_BLOCK_SIZE (64 * 1024 - 2 * sizeof(void *)) + +/* Scene temporary storage is clamped to this size: + */ +#define LP_SCENE_MAX_SIZE (1024*1024) + +/* The maximum amount of texture storage referenced by a scene is + * clamped ot this size: + */ +#define LP_SCENE_MAX_RESOURCE_SIZE (64*1024*1024) /* switch to a non-pointer value for this: @@ -65,16 +73,18 @@ struct cmd_block { struct cmd_block *next; }; +struct cmd_block_list { + struct cmd_block *head; + struct cmd_block *tail; +}; + struct data_block { ubyte data[DATA_BLOCK_SIZE]; unsigned used; struct data_block *next; }; -struct cmd_block_list { - struct cmd_block *head; - struct cmd_block *tail; -}; + /** * For each screen tile we have one of these bins. @@ -85,22 +95,17 @@ struct cmd_bin { /** - * This stores bulk data which is shared by all bins within a scene. + * This stores bulk data which is used for all memory allocations + * within a scene. + * * Examples include triangle data and state data. The commands in * the per-tile bins will point to chunks of data in this structure. */ struct data_block_list { struct data_block *head; - struct data_block *tail; -}; - - -/** List of resource references */ -struct resource_ref { - struct pipe_resource *resource; - struct resource_ref *prev, *next; /**< linked list w/ u_simple_list.h */ }; +struct resource_ref; /** * All bins and bin data are contained here. @@ -118,13 +123,21 @@ struct lp_scene { struct pipe_framebuffer_state fb; /** list of resources referenced by the scene commands */ - struct resource_ref resources; + struct resource_ref *resources; - /** Approx memory used by the scene (in bytes). This includes the - * shared and per-tile bins plus any referenced resources/textures. + /** Total memory used by the scene (in bytes). This sums all the + * data blocks and counts all bins, state, resource references and + * other random allocations within the scene. */ unsigned scene_size; + /** Sum of sizes of all resources referenced by the scene. Sums + * all the textures read by the scene: + */ + unsigned resource_reference_size; + + boolean alloc_failed; + boolean has_depthstencil_clear; /** @@ -151,22 +164,18 @@ struct lp_scene *lp_scene_create(struct pipe_context *pipe, void lp_scene_destroy(struct lp_scene *scene); - - boolean lp_scene_is_empty(struct lp_scene *scene ); +boolean lp_scene_is_oom(struct lp_scene *scene ); void lp_scene_reset(struct lp_scene *scene ); -struct data_block *lp_bin_new_data_block( struct data_block_list *list ); - -struct cmd_block *lp_bin_new_cmd_block( struct cmd_block_list *list ); +struct data_block *lp_scene_new_data_block( struct lp_scene *scene ); -unsigned lp_scene_data_size( const struct lp_scene *scene ); +struct cmd_block *lp_scene_new_cmd_block( struct lp_scene *scene, + struct cmd_bin *bin ); -unsigned lp_scene_bin_size( const struct lp_scene *scene, unsigned x, unsigned y ); - -void lp_scene_add_resource_reference(struct lp_scene *scene, +boolean lp_scene_add_resource_reference(struct lp_scene *scene, struct pipe_resource *resource); boolean lp_scene_is_resource_referenced(const struct lp_scene *scene, @@ -181,21 +190,21 @@ static INLINE void * lp_scene_alloc( struct lp_scene *scene, unsigned size) { struct data_block_list *list = &scene->data; - struct data_block *tail = list->tail; + struct data_block *block = list->head; - if (tail->used + size > DATA_BLOCK_SIZE) { - tail = lp_bin_new_data_block( list ); - if (!tail) { + assert(size <= DATA_BLOCK_SIZE); + + if (block == NULL || block->used + size > DATA_BLOCK_SIZE) { + block = lp_scene_new_data_block( scene ); + if (!block) { /* out of memory */ return NULL; } } - scene->scene_size += size; - { - ubyte *data = tail->data + tail->used; - tail->used += size; + ubyte *data = block->data + block->used; + block->used += size; return data; } } @@ -209,20 +218,19 @@ lp_scene_alloc_aligned( struct lp_scene *scene, unsigned size, unsigned alignment ) { struct data_block_list *list = &scene->data; - struct data_block *tail = list->tail; + struct data_block *block = list->head; - if (tail->used + size + alignment - 1 > DATA_BLOCK_SIZE) { - tail = lp_bin_new_data_block( list ); - if (!tail) + if (block == NULL || + block->used + size + alignment - 1 > DATA_BLOCK_SIZE) { + block = lp_scene_new_data_block( scene ); + if (!block) return NULL; } - scene->scene_size += size; - { - ubyte *data = tail->data + tail->used; + ubyte *data = block->data + block->used; unsigned offset = (((uintptr_t)data + alignment - 1) & ~(alignment - 1)) - (uintptr_t)data; - tail->used += offset + size; + block->used += offset + size; return data + offset; } } @@ -234,9 +242,8 @@ static INLINE void lp_scene_putback_data( struct lp_scene *scene, unsigned size) { struct data_block_list *list = &scene->data; - scene->scene_size -= size; - assert(list->tail->used >= size); - list->tail->used -= size; + assert(list->head && list->head->used >= size); + list->head->used -= size; } @@ -255,24 +262,22 @@ lp_scene_bin_reset(struct lp_scene *scene, unsigned x, unsigned y); /* Add a command to bin[x][y]. */ -static INLINE void +static INLINE boolean lp_scene_bin_command( struct lp_scene *scene, unsigned x, unsigned y, lp_rast_cmd cmd, union lp_rast_cmd_arg arg ) { struct cmd_bin *bin = lp_scene_get_bin(scene, x, y); - struct cmd_block_list *list = &bin->commands; - struct cmd_block *tail = list->tail; + struct cmd_block *tail = bin->commands.tail; assert(x < scene->tiles_x); assert(y < scene->tiles_y); - if (tail->count == CMD_BLOCK_MAX) { - tail = lp_bin_new_cmd_block( list ); + if (tail == NULL || tail->count == CMD_BLOCK_MAX) { + tail = lp_scene_new_cmd_block( scene, bin ); if (!tail) { - /* out of memory - simply ignore this command (for now) */ - return; + return FALSE; } assert(tail->count == 0); } @@ -283,27 +288,28 @@ lp_scene_bin_command( struct lp_scene *scene, tail->arg[i] = arg; tail->count++; } + + return TRUE; } /* Add a command to all active bins. */ -static INLINE void +static INLINE boolean lp_scene_bin_everywhere( struct lp_scene *scene, lp_rast_cmd cmd, const union lp_rast_cmd_arg arg ) { unsigned i, j; - for (i = 0; i < scene->tiles_x; i++) - for (j = 0; j < scene->tiles_y; j++) - lp_scene_bin_command( scene, i, j, cmd, arg ); -} - + for (i = 0; i < scene->tiles_x; i++) { + for (j = 0; j < scene->tiles_y; j++) { + if (!lp_scene_bin_command( scene, i, j, cmd, arg )) + return FALSE; + } + } -void -lp_scene_bin_state_command( struct lp_scene *scene, - lp_rast_cmd cmd, - const union lp_rast_cmd_arg arg ); + return TRUE; +} static INLINE unsigned @@ -329,11 +335,5 @@ lp_scene_begin_binning( struct lp_scene *scene, struct pipe_framebuffer_state *fb ); -static INLINE unsigned -lp_scene_get_size(const struct lp_scene *scene) -{ - return scene->scene_size; -} - #endif /* LP_BIN_H */ |