summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/llvmpipe/lp_scene.h
diff options
context:
space:
mode:
authorKeith Whitwell <[email protected]>2010-08-27 17:49:40 +0100
committerKeith Whitwell <[email protected]>2010-09-07 14:01:43 +0100
commit6419ecd02ce43a2614822e228f306d4db589f317 (patch)
tree36aeeb7d37fdec2cd5e6a7f72440c3e1fa30c552 /src/gallium/drivers/llvmpipe/lp_scene.h
parentc512ba88a7e33f14b86feb9c0aaf1ebed5f50629 (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.h140
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 */