return NULL;
scene->pipe = pipe;
- scene->data.head = &scene->data.first;
+
+ scene->data.head =
+ CALLOC_STRUCT(data_block);
pipe_mutex_init(scene->mutex);
+#ifdef DEBUG
+ /* Do some scene limit sanity checks here */
+ {
+ size_t maxBins = TILES_X * TILES_Y;
+ size_t maxCommandBytes = sizeof(struct cmd_block) * maxBins;
+ size_t maxCommandPlusData = maxCommandBytes + DATA_BLOCK_SIZE;
+ /* We'll need at least one command block per bin. Make sure that's
+ * less than the max allowed scene size.
+ */
+ assert(maxCommandBytes < LP_SCENE_MAX_SIZE);
+ /* We'll also need space for at least one other data block */
+ assert(maxCommandPlusData <= LP_SCENE_MAX_SIZE);
+ }
+#endif
+
return scene;
}
void
lp_scene_destroy(struct lp_scene *scene)
{
+ lp_fence_reference(&scene->fence, NULL);
pipe_mutex_destroy(scene->mutex);
- assert(scene->data.head == &scene->data.first);
+ assert(scene->data.head->next == NULL);
+ FREE(scene->data.head);
FREE(scene);
}
{
struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
+ bin->last_state = NULL;
bin->head = bin->tail;
if (bin->tail) {
bin->tail->next = NULL;
int i;
//LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
-
+
for (i = 0; i < scene->fb.nr_cbufs; i++) {
struct pipe_surface *cbuf = scene->fb.cbufs[i];
- scene->cbufs[i].stride = llvmpipe_resource_stride(cbuf->texture,
- cbuf->level);
-
- scene->cbufs[i].map = llvmpipe_resource_map(cbuf->texture,
- cbuf->face,
- cbuf->level,
- cbuf->zslice,
- LP_TEX_USAGE_READ_WRITE,
- LP_TEX_LAYOUT_LINEAR);
+ if (llvmpipe_resource_is_texture(cbuf->texture)) {
+ scene->cbufs[i].stride = llvmpipe_resource_stride(cbuf->texture,
+ cbuf->u.tex.level);
+
+ scene->cbufs[i].map = llvmpipe_resource_map(cbuf->texture,
+ cbuf->u.tex.level,
+ cbuf->u.tex.first_layer,
+ LP_TEX_USAGE_READ_WRITE);
+ }
+ else {
+ struct llvmpipe_resource *lpr = llvmpipe_resource(cbuf->texture);
+ unsigned pixstride = util_format_get_blocksize(cbuf->format);
+ scene->cbufs[i].stride = cbuf->texture->width0;
+ scene->cbufs[i].map = lpr->data;
+ scene->cbufs[i].map += cbuf->u.buf.first_element * pixstride;
+ }
}
if (fb->zsbuf) {
struct pipe_surface *zsbuf = scene->fb.zsbuf;
- scene->zsbuf.stride = llvmpipe_resource_stride(zsbuf->texture, zsbuf->level);
+ scene->zsbuf.stride = llvmpipe_resource_stride(zsbuf->texture, zsbuf->u.tex.level);
scene->zsbuf.blocksize =
util_format_get_blocksize(zsbuf->texture->format);
scene->zsbuf.map = llvmpipe_resource_map(zsbuf->texture,
- zsbuf->face,
- zsbuf->level,
- zsbuf->zslice,
- LP_TEX_USAGE_READ_WRITE,
- LP_TEX_LAYOUT_NONE);
+ zsbuf->u.tex.level,
+ zsbuf->u.tex.first_layer,
+ LP_TEX_USAGE_READ_WRITE);
}
}
for (i = 0; i < scene->fb.nr_cbufs; i++) {
if (scene->cbufs[i].map) {
struct pipe_surface *cbuf = scene->fb.cbufs[i];
- llvmpipe_resource_unmap(cbuf->texture,
- cbuf->face,
- cbuf->level,
- cbuf->zslice);
+ if (llvmpipe_resource_is_texture(cbuf->texture)) {
+ llvmpipe_resource_unmap(cbuf->texture,
+ cbuf->u.tex.level,
+ cbuf->u.tex.first_layer);
+ }
scene->cbufs[i].map = NULL;
}
}
if (scene->zsbuf.map) {
struct pipe_surface *zsbuf = scene->fb.zsbuf;
llvmpipe_resource_unmap(zsbuf->texture,
- zsbuf->face,
- zsbuf->level,
- zsbuf->zslice);
+ zsbuf->u.tex.level,
+ zsbuf->u.tex.first_layer);
scene->zsbuf.map = NULL;
}
for (i = 0; i < scene->tiles_x; i++) {
for (j = 0; j < scene->tiles_y; j++) {
struct cmd_bin *bin = lp_scene_get_bin(scene, i, j);
- bin->head = bin->tail = NULL;
+ bin->head = NULL;
+ bin->tail = NULL;
+ bin->last_state = NULL;
}
}
if (LP_DEBUG & DEBUG_SETUP)
debug_printf("resource %d: %p %dx%d sz %d\n",
j,
- ref->resource[i],
+ (void *) ref->resource[i],
ref->resource[i]->width0,
ref->resource[i]->height0,
llvmpipe_resource_size(ref->resource[i]));
struct data_block_list *list = &scene->data;
struct data_block *block, *tmp;
- for (block = list->head; block; block = tmp) {
+ for (block = list->head->next; block; block = tmp) {
tmp = block->next;
- if (block != &list->first)
- FREE(block);
+ FREE(block);
}
- list->head = &list->first;
list->head->next = NULL;
+ list->head->used = 0;
}
lp_fence_reference(&scene->fence, NULL);
/* Look at existing resource blocks:
*/
for (ref = scene->resources; ref; ref = ref->next) {
+ last = &ref->next;
/* Search for this resource:
*/
if (ref->resource[i] == resource)
return TRUE;
- /* If the block is half-empty, this is the last block. Append
- * the reference here.
- */
- if (ref->count < RESOURCE_REF_SZ)
- goto add_new_ref;
-
- last = &ref->next;
+ if (ref->count < RESOURCE_REF_SZ) {
+ /* If the block is half-empty, then append the reference here.
+ */
+ break;
+ }
}
- /* Otherwise, need to create a new block:
+ /* Create a new block if no half-empty block was found.
*/
- *last = lp_scene_alloc(scene, sizeof(struct resource_ref));
- if (*last) {
+ if (!ref) {
+ assert(*last == NULL);
+ *last = lp_scene_alloc(scene, sizeof *ref);
+ if (*last == NULL)
+ return FALSE;
+
ref = *last;
memset(ref, 0, sizeof *ref);
- goto add_new_ref;
}
- return FALSE;
-
-add_new_ref:
+ /* Append the reference to the reference block.
+ */
pipe_resource_reference(&ref->resource[ref->count++], resource);
scene->resource_reference_size += llvmpipe_resource_size(resource);
* data.
*/
if (!initializing_scene &&
- scene->resource_reference_size < LP_SCENE_MAX_RESOURCE_SIZE)
+ scene->resource_reference_size >= LP_SCENE_MAX_RESOURCE_SIZE)
return FALSE;
return TRUE;
* of work (a bin) to work on.
*/
struct cmd_bin *
-lp_scene_bin_iter_next( struct lp_scene *scene )
+lp_scene_bin_iter_next( struct lp_scene *scene , int *x, int *y)
{
struct cmd_bin *bin = NULL;
}
bin = lp_scene_get_bin(scene, scene->curr_x, scene->curr_y);
+ *x = scene->curr_x;
+ *y = scene->curr_y;
end:
/*printf("return bin %p at %d, %d\n", (void *) bin, *bin_x, *bin_y);*/
void lp_scene_begin_binning( struct lp_scene *scene,
- struct pipe_framebuffer_state *fb )
+ struct pipe_framebuffer_state *fb, boolean discard )
{
assert(lp_scene_is_empty(scene));
+ scene->discard = discard;
util_copy_framebuffer_state(&scene->fb, fb);
scene->tiles_x = align(fb->width, TILE_SIZE) / TILE_SIZE;
scene->scene_size);
debug_printf(" data size: %u\n",
lp_scene_data_size(scene));
+
+ if (0)
+ lp_debug_bins( scene );
}
}