From 663750d5564a225b4720f7ee8bea93ffb309fc88 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 13 Dec 2009 18:17:25 +0000 Subject: llvmpipe: rename bins to scene It was pretty confusing having an entity named "bin" and another named "bins", not least because sometimes there was a need to talk about >1 of the "bins" objects, which couldn't be pluralized any further... Scene is a term used in a bunch of places to talk about what a binner operates on, so it's a decent choice here. --- src/gallium/drivers/llvmpipe/SConscript | 10 +- src/gallium/drivers/llvmpipe/lp_bin.c | 310 ------------------------ src/gallium/drivers/llvmpipe/lp_bin.h | 275 --------------------- src/gallium/drivers/llvmpipe/lp_bin_queue.c | 164 ------------- src/gallium/drivers/llvmpipe/lp_bin_queue.h | 55 ----- src/gallium/drivers/llvmpipe/lp_rast.c | 96 ++++---- src/gallium/drivers/llvmpipe/lp_rast.h | 14 +- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 12 +- src/gallium/drivers/llvmpipe/lp_scene.c | 310 ++++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_scene.h | 276 +++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_scene_queue.c | 164 +++++++++++++ src/gallium/drivers/llvmpipe/lp_scene_queue.h | 55 +++++ src/gallium/drivers/llvmpipe/lp_setup.c | 112 ++++----- src/gallium/drivers/llvmpipe/lp_setup_context.h | 12 +- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 36 +-- 15 files changed, 952 insertions(+), 949 deletions(-) delete mode 100644 src/gallium/drivers/llvmpipe/lp_bin.c delete mode 100644 src/gallium/drivers/llvmpipe/lp_bin.h delete mode 100644 src/gallium/drivers/llvmpipe/lp_bin_queue.c delete mode 100644 src/gallium/drivers/llvmpipe/lp_bin_queue.h create mode 100644 src/gallium/drivers/llvmpipe/lp_scene.c create mode 100644 src/gallium/drivers/llvmpipe/lp_scene.h create mode 100644 src/gallium/drivers/llvmpipe/lp_scene_queue.c create mode 100644 src/gallium/drivers/llvmpipe/lp_scene_queue.h diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index bc725b65f6..f0b71ef3ee 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -19,8 +19,6 @@ env.CodeGenerate( llvmpipe = env.ConvenienceLibrary( target = 'llvmpipe', source = [ - 'lp_bin.c', - 'lp_bin_queue.c', 'lp_bld_alpha.c', 'lp_bld_arit.c', 'lp_bld_blend_aos.c', @@ -35,9 +33,9 @@ llvmpipe = env.ConvenienceLibrary( 'lp_bld_format_soa.c', 'lp_bld_interp.c', 'lp_bld_intr.c', + 'lp_bld_logic.c', 'lp_bld_sample_soa.c', 'lp_bld_struct.c', - 'lp_bld_logic.c', 'lp_bld_swizzle.c', 'lp_bld_tgsi_soa.c', 'lp_bld_type.c', @@ -50,11 +48,13 @@ llvmpipe = env.ConvenienceLibrary( 'lp_jit.c', 'lp_prim_vbuf.c', 'lp_query.c', + 'lp_scene.c', + 'lp_scene_queue.c', + 'lp_screen.c', 'lp_setup.c', - 'lp_setup_tri.c', 'lp_setup_line.c', 'lp_setup_point.c', - 'lp_screen.c', + 'lp_setup_tri.c', 'lp_state_blend.c', 'lp_state_clip.c', 'lp_state_derived.c', diff --git a/src/gallium/drivers/llvmpipe/lp_bin.c b/src/gallium/drivers/llvmpipe/lp_bin.c deleted file mode 100644 index 703cdd2de5..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_bin.c +++ /dev/null @@ -1,310 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "util/u_math.h" -#include "util/u_memory.h" -#include "lp_bin.h" - - -struct lp_bins * -lp_bins_create(void) -{ - struct lp_bins *bins = CALLOC_STRUCT(lp_bins); - if (bins) - lp_init_bins(bins); - return bins; -} - - -void -lp_bins_destroy(struct lp_bins *bins) -{ - lp_reset_bins(bins); - lp_free_bin_data(bins); - FREE(bins); -} - - -void -lp_init_bins(struct lp_bins *bins) -{ - unsigned i, j; - for (i = 0; i < TILES_X; i++) - for (j = 0; j < TILES_Y; j++) { - struct cmd_bin *bin = lp_get_bin(bins, i, j); - bin->commands.head = bin->commands.tail = CALLOC_STRUCT(cmd_block); - } - - bins->data.head = - bins->data.tail = CALLOC_STRUCT(data_block); - - pipe_mutex_init(bins->mutex); -} - - -/** - * Set bins to empty state. - */ -void -lp_reset_bins(struct lp_bins *bins ) -{ - unsigned i, j; - - /* Free all but last binner command lists: - */ - for (i = 0; i < bins->tiles_x; i++) { - for (j = 0; j < bins->tiles_y; j++) { - struct cmd_bin *bin = lp_get_bin(bins, i, j); - struct cmd_block_list *list = &bin->commands; - struct cmd_block *block; - struct cmd_block *tmp; - - for (block = list->head; block != list->tail; block = tmp) { - tmp = block->next; - FREE(block); - } - - assert(list->tail->next == NULL); - list->head = list->tail; - list->head->count = 0; - } - } - - /* Free all but last binned data block: - */ - { - struct data_block_list *list = &bins->data; - struct data_block *block, *tmp; - - for (block = list->head; block != list->tail; block = tmp) { - tmp = block->next; - FREE(block); - } - - assert(list->tail->next == NULL); - list->head = list->tail; - list->head->used = 0; - } -} - - -/** - * Free all data associated with the given bin, but don't free(bins). - */ -void -lp_free_bin_data(struct lp_bins *bins) -{ - unsigned i, j; - - for (i = 0; i < TILES_X; i++) - for (j = 0; j < TILES_Y; j++) { - struct cmd_bin *bin = lp_get_bin(bins, i, j); - /* lp_reset_bins() should have been already called */ - assert(bin->commands.head == bin->commands.tail); - FREE(bin->commands.head); - bin->commands.head = NULL; - bin->commands.tail = NULL; - } - - FREE(bins->data.head); - bins->data.head = NULL; - - pipe_mutex_destroy(bins->mutex); -} - - -void -lp_bin_set_framebuffer_size( struct lp_bins *bins, - unsigned width, unsigned height ) -{ - bins->tiles_x = align(width, TILE_SIZE) / TILE_SIZE; - bins->tiles_y = align(height, TILE_SIZE) / TILE_SIZE; -} - - -void -lp_bin_new_cmd_block( struct cmd_block_list *list ) -{ - struct cmd_block *block = MALLOC_STRUCT(cmd_block); - list->tail->next = block; - list->tail = block; - block->next = NULL; - block->count = 0; -} - - -void -lp_bin_new_data_block( struct data_block_list *list ) -{ - struct data_block *block = MALLOC_STRUCT(data_block); - list->tail->next = block; - list->tail = block; - block->next = NULL; - block->used = 0; -} - - -/** Return number of bytes used for bin data */ -unsigned -lp_bin_data_size( const struct lp_bins *bins ) -{ - unsigned size = 0; - const struct data_block *block; - for (block = bins->data.head; block; block = block->next) { - size += block->used; - } - return size; -} - - -/** Return number of bytes used for a tile bin */ -unsigned -lp_bin_cmd_size( const struct lp_bins *bins, unsigned x, unsigned y ) -{ - struct cmd_bin *bin = lp_get_bin((struct lp_bins *) bins, x, y); - const struct cmd_block *cmd; - unsigned size = 0; - for (cmd = bin->commands.head; cmd; cmd = cmd->next) { - size += (cmd->count * - (sizeof(lp_rast_cmd) + sizeof(union lp_rast_cmd_arg))); - } - return size; -} - - -/** - * Return last command in the bin - */ -static lp_rast_cmd -lp_get_last_command( const struct cmd_bin *bin ) -{ - const struct cmd_block *tail = bin->commands.tail; - const unsigned i = tail->count; - if (i > 0) - return tail->cmd[i - 1]; - else - return NULL; -} - - -/** - * Replace the arg of the last command in the bin. - */ -static void -lp_replace_last_command_arg( struct cmd_bin *bin, - const union lp_rast_cmd_arg arg ) -{ - struct cmd_block *tail = bin->commands.tail; - const unsigned i = tail->count; - assert(i > 0); - tail->arg[i - 1] = arg; -} - - - -/** - * Put a state-change command into all bins. - * If we find that the last command in a bin was also a state-change - * command, we can simply replace that one with the new one. - */ -void -lp_bin_state_command( struct lp_bins *bins, - lp_rast_cmd cmd, - const union lp_rast_cmd_arg arg ) -{ - unsigned i, j; - for (i = 0; i < bins->tiles_x; i++) { - for (j = 0; j < bins->tiles_y; j++) { - struct cmd_bin *bin = lp_get_bin(bins, i, j); - lp_rast_cmd last_cmd = lp_get_last_command(bin); - if (last_cmd == cmd) { - lp_replace_last_command_arg(bin, arg); - } - else { - lp_bin_command( bins, i, j, cmd, arg ); - } - } - } -} - - -/** advance curr_x,y to the next bin */ -static boolean -next_bin(struct lp_bins *bins) -{ - bins->curr_x++; - if (bins->curr_x >= bins->tiles_x) { - bins->curr_x = 0; - bins->curr_y++; - } - if (bins->curr_y >= bins->tiles_y) { - /* no more bins */ - return FALSE; - } - return TRUE; -} - - -void -lp_bin_iter_begin( struct lp_bins *bins ) -{ - bins->curr_x = bins->curr_y = -1; -} - - -/** - * Return point to next bin to be rendered. - * The lp_bins::curr_x and ::curr_y fields will be advanced. - * Multiple rendering threads will call this function to get a chunk - * of work (a bin) to work on. - */ -struct cmd_bin * -lp_bin_iter_next( struct lp_bins *bins, int *bin_x, int *bin_y ) -{ - struct cmd_bin *bin = NULL; - - pipe_mutex_lock(bins->mutex); - - if (bins->curr_x < 0) { - /* first bin */ - bins->curr_x = 0; - bins->curr_y = 0; - } - else if (!next_bin(bins)) { - /* no more bins left */ - goto end; - } - - bin = lp_get_bin(bins, bins->curr_x, bins->curr_y); - *bin_x = bins->curr_x; - *bin_y = bins->curr_y; - -end: - /*printf("return bin %p at %d, %d\n", (void *) bin, *bin_x, *bin_y);*/ - pipe_mutex_unlock(bins->mutex); - return bin; -} diff --git a/src/gallium/drivers/llvmpipe/lp_bin.h b/src/gallium/drivers/llvmpipe/lp_bin.h deleted file mode 100644 index e763b16ffe..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_bin.h +++ /dev/null @@ -1,275 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * Binner data structures and bin-related functions. - * Note: the "setup" code is concerned with building bins while - * The "rast" code is concerned with consuming/executing bins. - */ - -#ifndef LP_BIN_H -#define LP_BIN_H - -#include "pipe/p_thread.h" -#include "lp_tile_soa.h" -#include "lp_rast.h" - - -/* We're limited to 2K by 2K for 32bit fixed point rasterization. - * Will need a 64-bit version for larger framebuffers. - */ -#define MAXHEIGHT 2048 -#define MAXWIDTH 2048 -#define TILES_X (MAXWIDTH / TILE_SIZE) -#define TILES_Y (MAXHEIGHT / TILE_SIZE) - - -#define CMD_BLOCK_MAX 128 -#define DATA_BLOCK_SIZE (16 * 1024 - sizeof(unsigned) - sizeof(void *)) - - - -/* switch to a non-pointer value for this: - */ -typedef void (*lp_rast_cmd)( struct lp_rasterizer *, - unsigned thread_index, - const union lp_rast_cmd_arg ); - -struct cmd_block { - lp_rast_cmd cmd[CMD_BLOCK_MAX]; - union lp_rast_cmd_arg arg[CMD_BLOCK_MAX]; - unsigned count; - struct cmd_block *next; -}; - -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. - */ -struct cmd_bin { - struct cmd_block_list commands; -}; - - -/** - * This stores bulk data which is shared by all bins. - * 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; -}; - - -/** - * All bins and bin data are contained here. - * Per-bin data goes into the 'tile' bins. - * Shared bin data goes into the 'data' buffer. - * When there are multiple threads, will want to double-buffer the - * bin arrays: - */ -struct lp_bins { - struct cmd_bin tile[TILES_X][TILES_Y]; - struct data_block_list data; - - /** the framebuffer to render the bins into */ - struct pipe_framebuffer_state fb; - - boolean write_depth; - - /** - * Number of active tiles in each dimension. - * This basically the framebuffer size divided by tile size - */ - unsigned tiles_x, tiles_y; - - int curr_x, curr_y; /**< for iterating over bins */ - pipe_mutex mutex; -}; - - - -struct lp_bins *lp_bins_create(void); - -void lp_bins_destroy(struct lp_bins *bins); - - -void lp_init_bins(struct lp_bins *bins); - -void lp_reset_bins(struct lp_bins *bins ); - -void lp_free_bin_data(struct lp_bins *bins); - -void lp_bin_set_framebuffer_size( struct lp_bins *bins, - unsigned width, unsigned height ); - -void lp_bin_new_data_block( struct data_block_list *list ); - -void lp_bin_new_cmd_block( struct cmd_block_list *list ); - -unsigned lp_bin_data_size( const struct lp_bins *bins ); - -unsigned lp_bin_cmd_size( const struct lp_bins *bins, unsigned x, unsigned y ); - - -/** - * Allocate space for a command/data in the bin's data buffer. - * Grow the block list if needed. - */ -static INLINE void * -lp_bin_alloc( struct lp_bins *bins, unsigned size) -{ - struct data_block_list *list = &bins->data; - - if (list->tail->used + size > DATA_BLOCK_SIZE) { - lp_bin_new_data_block( list ); - } - - { - struct data_block *tail = list->tail; - ubyte *data = tail->data + tail->used; - tail->used += size; - return data; - } -} - - -/** - * As above, but with specific alignment. - */ -static INLINE void * -lp_bin_alloc_aligned( struct lp_bins *bins, unsigned size, - unsigned alignment ) -{ - struct data_block_list *list = &bins->data; - - if (list->tail->used + size + alignment - 1 > DATA_BLOCK_SIZE) { - lp_bin_new_data_block( list ); - } - - { - struct data_block *tail = list->tail; - ubyte *data = tail->data + tail->used; - unsigned offset = (((uintptr_t)data + alignment - 1) & ~(alignment - 1)) - (uintptr_t)data; - tail->used += offset + size; - return data + offset; - } -} - - -/* Put back data if we decide not to use it, eg. culled triangles. - */ -static INLINE void -lp_bin_putback_data( struct lp_bins *bins, unsigned size) -{ - struct data_block_list *list = &bins->data; - assert(list->tail->used >= size); - list->tail->used -= size; -} - - -/** Return pointer to a particular tile's bin. */ -static INLINE struct cmd_bin * -lp_get_bin(struct lp_bins *bins, unsigned x, unsigned y) -{ - return &bins->tile[x][y]; -} - - - -/* Add a command to bin[x][y]. - */ -static INLINE void -lp_bin_command( struct lp_bins *bins, - unsigned x, unsigned y, - lp_rast_cmd cmd, - union lp_rast_cmd_arg arg ) -{ - struct cmd_bin *bin = lp_get_bin(bins, x, y); - struct cmd_block_list *list = &bin->commands; - - if (list->tail->count == CMD_BLOCK_MAX) { - lp_bin_new_cmd_block( list ); - } - - { - struct cmd_block *tail = list->tail; - unsigned i = tail->count; - tail->cmd[i] = cmd; - tail->arg[i] = arg; - tail->count++; - } -} - - -/* Add a command to all active bins. - */ -static INLINE void -lp_bin_everywhere( struct lp_bins *bins, - lp_rast_cmd cmd, - const union lp_rast_cmd_arg arg ) -{ - unsigned i, j; - for (i = 0; i < bins->tiles_x; i++) - for (j = 0; j < bins->tiles_y; j++) - lp_bin_command( bins, i, j, cmd, arg ); -} - - -void -lp_bin_state_command( struct lp_bins *bins, - lp_rast_cmd cmd, - const union lp_rast_cmd_arg arg ); - - -static INLINE unsigned -lp_bin_get_num_bins( const struct lp_bins *bins ) -{ - return bins->tiles_x * bins->tiles_y; -} - - -void -lp_bin_iter_begin( struct lp_bins *bins ); - -struct cmd_bin * -lp_bin_iter_next( struct lp_bins *bins, int *bin_x, int *bin_y ); - - -#endif /* LP_BIN_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_bin_queue.c b/src/gallium/drivers/llvmpipe/lp_bin_queue.c deleted file mode 100644 index b39b46b72b..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_bin_queue.c +++ /dev/null @@ -1,164 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * Bin queue. We'll use two queues. One contains "full" bins which - * are produced by the "setup" code. The other contains "empty" bins - * which are produced by the "rast" code when it finishes rendering a bin. - */ - - -#include "pipe/p_thread.h" -#include "util/u_memory.h" -#include "lp_bin_queue.h" - - - -#define MAX_BINS 4 - - -/** - * A queue of bins - */ -struct lp_bins_queue -{ - /** XXX might use a linked list here somedone, but the list will - * probably always be pretty short. - */ - struct lp_bins *bins[MAX_BINS]; - unsigned count; - - pipe_condvar count_change; - pipe_mutex mutex; -}; - - - -/** Allocate a new bins queue */ -struct lp_bins_queue * -lp_bins_queue_create(void) -{ - struct lp_bins_queue *queue = CALLOC_STRUCT(lp_bins_queue); - if (queue) { - pipe_condvar_init(queue->count_change); - pipe_mutex_init(queue->mutex); - } - return queue; -} - - -/** Delete a new bins queue */ -void -lp_bins_queue_destroy(struct lp_bins_queue *queue) -{ - pipe_condvar_destroy(queue->count_change); - pipe_mutex_destroy(queue->mutex); -} - - -/** Remove first lp_bins from head of queue */ -struct lp_bins * -lp_bins_dequeue(struct lp_bins_queue *queue) -{ - struct lp_bins *bins; - unsigned i; - - pipe_mutex_lock(queue->mutex); - while (queue->count == 0) { - pipe_condvar_wait(queue->count_change, queue->mutex); - } - - assert(queue->count >= 1); - - /* get head */ - bins = queue->bins[0]; - - /* shift entries */ - for (i = 0; i < queue->count - 1; i++) { - queue->bins[i] = queue->bins[i + 1]; - } - - queue->count--; - - /* signal size change */ - pipe_condvar_signal(queue->count_change); - - pipe_mutex_unlock(queue->mutex); - - return bins; -} - - -/** Add an lp_bins to tail of queue */ -void -lp_bins_enqueue(struct lp_bins_queue *queue, struct lp_bins *bins) -{ - pipe_mutex_lock(queue->mutex); - - assert(queue->count < MAX_BINS); - - /* debug: check that bins is not already in the queue */ - if (0) { - unsigned i; - for (i = 0; i < queue->count; i++) { - assert(queue->bins[i] != bins); - } - } - - /* add to end */ - queue->bins[queue->count++] = bins; - - /* signal size change */ - pipe_condvar_signal(queue->count_change); - - pipe_mutex_unlock(queue->mutex); -} - - -/** Return number of entries in the queue */ -unsigned -lp_bins_queue_count(struct lp_bins_queue *queue) -{ - unsigned count; - pipe_mutex_lock(queue->mutex); - count = queue->count; - pipe_mutex_unlock(queue->mutex); - return count; -} - - -/** Wait until the queue has exactly 'count' entries */ -void -lp_bins_queue_wait_count(struct lp_bins_queue *queue, unsigned count) -{ - pipe_mutex_lock(queue->mutex); - while (queue->count != count) { - pipe_condvar_wait(queue->count_change, queue->mutex); - } - pipe_mutex_unlock(queue->mutex); -} diff --git a/src/gallium/drivers/llvmpipe/lp_bin_queue.h b/src/gallium/drivers/llvmpipe/lp_bin_queue.h deleted file mode 100644 index 1a0f8832db..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_bin_queue.h +++ /dev/null @@ -1,55 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifndef LP_BIN_QUEUE -#define LP_BIN_QUEUE - -struct lp_bin_queue; -struct lp_bins; - - -struct lp_bins_queue * -lp_bins_queue_create(void); - -void -lp_bins_queue_destroy(struct lp_bins_queue *queue); - -struct lp_bins * -lp_bins_dequeue(struct lp_bins_queue *queue); - -void -lp_bins_enqueue(struct lp_bins_queue *queue, struct lp_bins *bins); - -unsigned -lp_bins_queue_count(struct lp_bins_queue *queue); - -void -lp_bins_queue_wait_count(struct lp_bins_queue *queue, unsigned size); - - -#endif /* LP_BIN_QUEUE */ diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 3e7b3d7ab4..fd9cd67d85 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -30,7 +30,7 @@ #include "util/u_cpu_detect.h" #include "util/u_surface.h" -#include "lp_bin_queue.h" +#include "lp_scene_queue.h" #include "lp_debug.h" #include "lp_fence.h" #include "lp_state.h" @@ -38,7 +38,7 @@ #include "lp_rast_priv.h" #include "lp_tile_soa.h" #include "lp_bld_debug.h" -#include "lp_bin.h" +#include "lp_scene.h" /** @@ -531,18 +531,18 @@ void lp_rast_fence( struct lp_rasterizer *rast, /** - * When all the threads are done rasterizing a bin, one thread will - * call this function to reset the bin and put it onto the empty queue. + * When all the threads are done rasterizing a scene, one thread will + * call this function to reset the scene and put it onto the empty queue. */ static void -release_bins( struct lp_rasterizer *rast, - struct lp_bins *bins ) +release_scene( struct lp_rasterizer *rast, + struct lp_scene *scene ) { - util_unreference_framebuffer_state( &bins->fb ); + util_unreference_framebuffer_state( &scene->fb ); - lp_reset_bins( bins ); - lp_bins_enqueue( rast->empty_bins, bins ); - rast->curr_bins = NULL; + lp_scene_reset( scene ); + lp_scene_enqueue( rast->empty_scenes, scene ); + rast->curr_scene = NULL; } @@ -576,22 +576,22 @@ rasterize_bin( struct lp_rasterizer *rast, /** - * Rasterize/execute all bins. + * Rasterize/execute all bins within a scene. * Called per thread. */ static void -rasterize_bins( struct lp_rasterizer *rast, +rasterize_scene( struct lp_rasterizer *rast, unsigned thread_index, - struct lp_bins *bins, + struct lp_scene *scene, bool write_depth ) { - /* loop over tile bins, rasterize each */ + /* loop over scene bins, rasterize each */ #if 0 { unsigned i, j; - for (i = 0; i < bins->tiles_x; i++) { - for (j = 0; j < bins->tiles_y; j++) { - struct cmd_bin *bin = lp_get_bin(bins, i, j); + for (i = 0; i < scene->tiles_x; i++) { + for (j = 0; j < scene->tiles_y; j++) { + struct cmd_bin *bin = lp_get_bin(scene, i, j); rasterize_bin( rast, thread_index, bin, i * TILE_SIZE, j * TILE_SIZE ); } @@ -602,8 +602,8 @@ rasterize_bins( struct lp_rasterizer *rast, struct cmd_bin *bin; int x, y; - assert(bins); - while ((bin = lp_bin_iter_next(bins, &x, &y))) { + assert(scene); + while ((bin = lp_scene_bin_iter_next(scene, &x, &y))) { rasterize_bin( rast, thread_index, bin, x * TILE_SIZE, y * TILE_SIZE); } } @@ -615,8 +615,8 @@ rasterize_bins( struct lp_rasterizer *rast, * Called by setup module when it has something for us to render. */ void -lp_rasterize_bins( struct lp_rasterizer *rast, - struct lp_bins *bins, +lp_rasterize_scene( struct lp_rasterizer *rast, + struct lp_scene *scene, const struct pipe_framebuffer_state *fb, bool write_depth ) { @@ -626,19 +626,19 @@ lp_rasterize_bins( struct lp_rasterizer *rast, if (debug) { unsigned x, y; - printf("rasterize bins:\n"); - printf(" data size: %u\n", lp_bin_data_size(bins)); - for (y = 0; y < bins->tiles_y; y++) { - for (x = 0; x < bins->tiles_x; x++) { + printf("rasterize scene:\n"); + printf(" data size: %u\n", lp_scene_data_size(scene)); + for (y = 0; y < scene->tiles_y; y++) { + for (x = 0; x < scene->tiles_x; x++) { printf(" bin %u, %u size: %u\n", x, y, - lp_bin_cmd_size(bins, x, y)); + lp_scene_bin_size(scene, x, y)); } } } /* save framebuffer state in the bin */ - util_copy_framebuffer_state(&bins->fb, fb); - bins->write_depth = write_depth; + util_copy_framebuffer_state(&scene->fb, fb); + scene->write_depth = write_depth; if (rast->num_threads == 0) { /* no threading */ @@ -647,10 +647,10 @@ lp_rasterize_bins( struct lp_rasterizer *rast, fb->cbufs[0]!= NULL, fb->zsbuf != NULL && write_depth ); - lp_bin_iter_begin( bins ); - rasterize_bins( rast, 0, bins, write_depth ); + lp_scene_bin_iter_begin( scene ); + rasterize_scene( rast, 0, scene, write_depth ); - release_bins( rast, bins ); + release_scene( rast, scene ); lp_rast_end( rast ); } @@ -658,7 +658,7 @@ lp_rasterize_bins( struct lp_rasterizer *rast, /* threaded rendering! */ unsigned i; - lp_bins_enqueue( rast->full_bins, bins ); + lp_scene_enqueue( rast->full_scenes, scene ); /* signal the threads that there's work to do */ for (i = 0; i < rast->num_threads; i++) { @@ -697,18 +697,18 @@ thread_func( void *init_data ) if (task->thread_index == 0) { /* thread[0]: - * - get next set of bins to rasterize + * - get next scene to rasterize * - map the framebuffer surfaces */ const struct pipe_framebuffer_state *fb; boolean write_depth; - rast->curr_bins = lp_bins_dequeue( rast->full_bins ); + rast->curr_scene = lp_scene_dequeue( rast->full_scenes ); - lp_bin_iter_begin( rast->curr_bins ); + lp_scene_bin_iter_begin( rast->curr_scene ); - fb = &rast->curr_bins->fb; - write_depth = rast->curr_bins->write_depth; + fb = &rast->curr_scene->fb; + write_depth = rast->curr_scene->write_depth; lp_rast_begin( rast, fb, fb->cbufs[0] != NULL, @@ -716,25 +716,27 @@ thread_func( void *init_data ) } /* Wait for all threads to get here so that threads[1+] don't - * get a null rast->curr_bins pointer. + * get a null rast->curr_scene pointer. */ pipe_barrier_wait( &rast->barrier ); /* do work */ if (debug) debug_printf("thread %d doing work\n", task->thread_index); - rasterize_bins(rast, task->thread_index, - rast->curr_bins, rast->curr_bins->write_depth); + rasterize_scene(rast, + task->thread_index, + rast->curr_scene, + rast->curr_scene->write_depth); - /* wait for all threads to finish with this set of bins */ + /* wait for all threads to finish with this scene */ pipe_barrier_wait( &rast->barrier ); if (task->thread_index == 0) { /* thread[0]: - * - release the bins object + * - release the scene object * - unmap the framebuffer surfaces */ - release_bins( rast, rast->curr_bins ); + release_scene( rast, rast->curr_scene ); lp_rast_end( rast ); } @@ -773,11 +775,11 @@ create_rast_threads(struct lp_rasterizer *rast) /** * Create new lp_rasterizer. - * \param empty the queue to put empty bins on after we've finished + * \param empty the queue to put empty scenes on after we've finished * processing them. */ struct lp_rasterizer * -lp_rast_create( struct pipe_screen *screen, struct lp_bins_queue *empty ) +lp_rast_create( struct pipe_screen *screen, struct lp_scene_queue *empty ) { struct lp_rasterizer *rast; unsigned i; @@ -788,8 +790,8 @@ lp_rast_create( struct pipe_screen *screen, struct lp_bins_queue *empty ) rast->screen = screen; - rast->empty_bins = empty; - rast->full_bins = lp_bins_queue_create(); + rast->empty_scenes = empty; + rast->full_scenes = lp_scene_queue_create(); for (i = 0; i < Elements(rast->tasks); i++) { rast->tasks[i].tile.color = align_malloc( TILE_SIZE*TILE_SIZE*4, 16 ); diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index bd8f1ae1c9..2dd0193d8d 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -42,8 +42,8 @@ struct lp_rasterizer; -struct lp_bins; -struct lp_bins_queue; +struct lp_scene; +struct lp_scene_queue; struct lp_fence; struct cmd_bin; struct pipe_screen; @@ -130,16 +130,16 @@ struct lp_rast_triangle { struct lp_rasterizer *lp_rast_create( struct pipe_screen *screen, - struct lp_bins_queue *empty ); + struct lp_scene_queue *empty ); void lp_rast_destroy( struct lp_rasterizer * ); unsigned lp_rast_get_num_threads( struct lp_rasterizer * ); -void lp_rasterize_bins( struct lp_rasterizer *rast, - struct lp_bins *bins, - const struct pipe_framebuffer_state *fb, - bool write_depth ); +void lp_rasterize_scene( struct lp_rasterizer *rast, + struct lp_scene *scene, + const struct pipe_framebuffer_state *fb, + bool write_depth ); diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index ba14fc3675..79a90f6610 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -110,13 +110,13 @@ struct lp_rasterizer char clear_stencil; } state; - /** The incoming queue of filled bins to rasterize */ - struct lp_bins_queue *full_bins; - /** The outgoing queue of emptied bins to return to setup modulee */ - struct lp_bins_queue *empty_bins; + /** The incoming queue of scenes ready to rasterize */ + struct lp_scene_queue *full_scenes; + /** The outgoing queue of processed scenes to return to setup modulee */ + struct lp_scene_queue *empty_scenes; - /** The bins currently being rasterized by the threads */ - struct lp_bins *curr_bins; + /** The scene currently being rasterized by the threads */ + struct lp_scene *curr_scene; /** A task object for each rasterization thread */ struct lp_rasterizer_task tasks[MAX_THREADS]; diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c new file mode 100644 index 0000000000..774a1fecd7 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_scene.c @@ -0,0 +1,310 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "util/u_math.h" +#include "util/u_memory.h" +#include "lp_scene.h" + + +struct lp_scene * +lp_scene_create(void) +{ + struct lp_scene *scene = CALLOC_STRUCT(lp_scene); + if (scene) + lp_scene_init(scene); + return scene; +} + + +void +lp_scene_destroy(struct lp_scene *scene) +{ + lp_scene_reset(scene); + lp_scene_free_bin_data(scene); + FREE(scene); +} + + +void +lp_scene_init(struct lp_scene *scene) +{ + unsigned i, j; + for (i = 0; i < TILES_X; i++) + for (j = 0; j < TILES_Y; j++) { + struct cmd_bin *bin = lp_scene_get_bin(scene, i, j); + bin->commands.head = bin->commands.tail = CALLOC_STRUCT(cmd_block); + } + + scene->data.head = + scene->data.tail = CALLOC_STRUCT(data_block); + + pipe_mutex_init(scene->mutex); +} + + +/** + * Set scene to empty state. + */ +void +lp_scene_reset(struct lp_scene *scene ) +{ + unsigned i, j; + + /* Free all but last binner command lists: + */ + 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); + struct cmd_block_list *list = &bin->commands; + struct cmd_block *block; + struct cmd_block *tmp; + + for (block = list->head; block != list->tail; block = tmp) { + tmp = block->next; + FREE(block); + } + + assert(list->tail->next == NULL); + list->head = list->tail; + list->head->count = 0; + } + } + + /* Free all but last binned data block: + */ + { + struct data_block_list *list = &scene->data; + struct data_block *block, *tmp; + + for (block = list->head; block != list->tail; block = tmp) { + tmp = block->next; + FREE(block); + } + + assert(list->tail->next == NULL); + list->head = list->tail; + list->head->used = 0; + } +} + + +/** + * Free all data associated with the given bin, but don't free(scene). + */ +void +lp_scene_free_bin_data(struct lp_scene *scene) +{ + unsigned i, j; + + for (i = 0; i < TILES_X; i++) + for (j = 0; j < TILES_Y; j++) { + struct cmd_bin *bin = lp_scene_get_bin(scene, i, j); + /* lp_reset_scene() should have been already called */ + assert(bin->commands.head == bin->commands.tail); + FREE(bin->commands.head); + bin->commands.head = NULL; + bin->commands.tail = NULL; + } + + FREE(scene->data.head); + scene->data.head = NULL; + + pipe_mutex_destroy(scene->mutex); +} + + +void +lp_scene_set_framebuffer_size( struct lp_scene *scene, + unsigned width, unsigned height ) +{ + scene->tiles_x = align(width, TILE_SIZE) / TILE_SIZE; + scene->tiles_y = align(height, TILE_SIZE) / TILE_SIZE; +} + + +void +lp_bin_new_cmd_block( struct cmd_block_list *list ) +{ + struct cmd_block *block = MALLOC_STRUCT(cmd_block); + list->tail->next = block; + list->tail = block; + block->next = NULL; + block->count = 0; +} + + +void +lp_bin_new_data_block( struct data_block_list *list ) +{ + struct data_block *block = MALLOC_STRUCT(data_block); + list->tail->next = block; + list->tail = block; + block->next = NULL; + block->used = 0; +} + + +/** Return number of bytes used for all bin data within a scene */ +unsigned +lp_scene_data_size( const struct lp_scene *scene ) +{ + unsigned size = 0; + const struct data_block *block; + for (block = scene->data.head; block; block = block->next) { + size += block->used; + } + return size; +} + + +/** Return number of bytes used for a single bin */ +unsigned +lp_scene_bin_size( const struct lp_scene *scene, unsigned x, unsigned y ) +{ + struct cmd_bin *bin = lp_scene_get_bin((struct lp_scene *) scene, x, y); + const struct cmd_block *cmd; + unsigned size = 0; + for (cmd = bin->commands.head; cmd; cmd = cmd->next) { + size += (cmd->count * + (sizeof(lp_rast_cmd) + sizeof(union lp_rast_cmd_arg))); + } + return size; +} + + +/** + * Return last command in the bin + */ +static lp_rast_cmd +lp_get_last_command( const struct cmd_bin *bin ) +{ + const struct cmd_block *tail = bin->commands.tail; + const unsigned i = tail->count; + if (i > 0) + return tail->cmd[i - 1]; + else + return NULL; +} + + +/** + * Replace the arg of the last command in the bin. + */ +static void +lp_replace_last_command_arg( struct cmd_bin *bin, + const union lp_rast_cmd_arg arg ) +{ + struct cmd_block *tail = bin->commands.tail; + const unsigned i = tail->count; + assert(i > 0); + tail->arg[i - 1] = arg; +} + + + +/** + * Put a state-change command into all bins. + * If we find that the last command in a bin was also a state-change + * command, we can simply replace that one with the new one. + */ +void +lp_scene_bin_state_command( 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++) { + struct cmd_bin *bin = lp_scene_get_bin(scene, i, j); + lp_rast_cmd last_cmd = lp_get_last_command(bin); + if (last_cmd == cmd) { + lp_replace_last_command_arg(bin, arg); + } + else { + lp_scene_bin_command( scene, i, j, cmd, arg ); + } + } + } +} + + +/** advance curr_x,y to the next bin */ +static boolean +next_bin(struct lp_scene *scene) +{ + scene->curr_x++; + if (scene->curr_x >= scene->tiles_x) { + scene->curr_x = 0; + scene->curr_y++; + } + if (scene->curr_y >= scene->tiles_y) { + /* no more bins */ + return FALSE; + } + return TRUE; +} + + +void +lp_scene_bin_iter_begin( struct lp_scene *scene ) +{ + scene->curr_x = scene->curr_y = -1; +} + + +/** + * Return point to next bin to be rendered. + * The lp_scene::curr_x and ::curr_y fields will be advanced. + * Multiple rendering threads will call this function to get a chunk + * of work (a bin) to work on. + */ +struct cmd_bin * +lp_scene_bin_iter_next( struct lp_scene *scene, int *bin_x, int *bin_y ) +{ + struct cmd_bin *bin = NULL; + + pipe_mutex_lock(scene->mutex); + + if (scene->curr_x < 0) { + /* first bin */ + scene->curr_x = 0; + scene->curr_y = 0; + } + else if (!next_bin(scene)) { + /* no more bins left */ + goto end; + } + + bin = lp_scene_get_bin(scene, scene->curr_x, scene->curr_y); + *bin_x = scene->curr_x; + *bin_y = scene->curr_y; + +end: + /*printf("return bin %p at %d, %d\n", (void *) bin, *bin_x, *bin_y);*/ + pipe_mutex_unlock(scene->mutex); + return bin; +} diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h new file mode 100644 index 0000000000..796fc516cc --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_scene.h @@ -0,0 +1,276 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * Binner data structures and bin-related functions. + * Note: the "setup" code is concerned with building scenes while + * The "rast" code is concerned with consuming/executing scenes. + */ + +#ifndef LP_SCENE_H +#define LP_SCENE_H + +#include "pipe/p_thread.h" +#include "lp_tile_soa.h" +#include "lp_rast.h" + + +/* We're limited to 2K by 2K for 32bit fixed point rasterization. + * Will need a 64-bit version for larger framebuffers. + */ +#define MAXHEIGHT 2048 +#define MAXWIDTH 2048 +#define TILES_X (MAXWIDTH / TILE_SIZE) +#define TILES_Y (MAXHEIGHT / TILE_SIZE) + + +#define CMD_BLOCK_MAX 128 +#define DATA_BLOCK_SIZE (16 * 1024 - sizeof(unsigned) - sizeof(void *)) + + + +/* switch to a non-pointer value for this: + */ +typedef void (*lp_rast_cmd)( struct lp_rasterizer *, + unsigned thread_index, + const union lp_rast_cmd_arg ); + +struct cmd_block { + lp_rast_cmd cmd[CMD_BLOCK_MAX]; + union lp_rast_cmd_arg arg[CMD_BLOCK_MAX]; + unsigned count; + struct cmd_block *next; +}; + +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. + */ +struct cmd_bin { + struct cmd_block_list commands; +}; + + +/** + * This stores bulk data which is shared by all bins 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; +}; + + +/** + * All bins and bin data are contained here. + * Per-bin data goes into the 'tile' bins. + * Shared data goes into the 'data' buffer. + * + * When there are multiple threads, will want to double-buffer between + * scenes: + */ +struct lp_scene { + struct cmd_bin tile[TILES_X][TILES_Y]; + struct data_block_list data; + + /** the framebuffer to render the scene into */ + struct pipe_framebuffer_state fb; + + boolean write_depth; + + /** + * Number of active tiles in each dimension. + * This basically the framebuffer size divided by tile size + */ + unsigned tiles_x, tiles_y; + + int curr_x, curr_y; /**< for iterating over bins */ + pipe_mutex mutex; +}; + + + +struct lp_scene *lp_scene_create(void); + +void lp_scene_destroy(struct lp_scene *scene); + + +void lp_scene_init(struct lp_scene *scene); + +void lp_scene_reset(struct lp_scene *scene ); + +void lp_scene_free_bin_data(struct lp_scene *scene); + +void lp_scene_set_framebuffer_size( struct lp_scene *scene, + unsigned width, unsigned height ); + +void lp_bin_new_data_block( struct data_block_list *list ); + +void lp_bin_new_cmd_block( struct cmd_block_list *list ); + +unsigned lp_scene_data_size( const struct lp_scene *scene ); + +unsigned lp_scene_bin_size( const struct lp_scene *scene, unsigned x, unsigned y ); + + +/** + * Allocate space for a command/data in the bin's data buffer. + * Grow the block list if needed. + */ +static INLINE void * +lp_scene_alloc( struct lp_scene *scene, unsigned size) +{ + struct data_block_list *list = &scene->data; + + if (list->tail->used + size > DATA_BLOCK_SIZE) { + lp_bin_new_data_block( list ); + } + + { + struct data_block *tail = list->tail; + ubyte *data = tail->data + tail->used; + tail->used += size; + return data; + } +} + + +/** + * As above, but with specific alignment. + */ +static INLINE void * +lp_scene_alloc_aligned( struct lp_scene *scene, unsigned size, + unsigned alignment ) +{ + struct data_block_list *list = &scene->data; + + if (list->tail->used + size + alignment - 1 > DATA_BLOCK_SIZE) { + lp_bin_new_data_block( list ); + } + + { + struct data_block *tail = list->tail; + ubyte *data = tail->data + tail->used; + unsigned offset = (((uintptr_t)data + alignment - 1) & ~(alignment - 1)) - (uintptr_t)data; + tail->used += offset + size; + return data + offset; + } +} + + +/* Put back data if we decide not to use it, eg. culled triangles. + */ +static INLINE void +lp_scene_putback_data( struct lp_scene *scene, unsigned size) +{ + struct data_block_list *list = &scene->data; + assert(list->tail->used >= size); + list->tail->used -= size; +} + + +/** Return pointer to a particular tile's bin. */ +static INLINE struct cmd_bin * +lp_scene_get_bin(struct lp_scene *scene, unsigned x, unsigned y) +{ + return &scene->tile[x][y]; +} + + + +/* Add a command to bin[x][y]. + */ +static INLINE void +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; + + if (list->tail->count == CMD_BLOCK_MAX) { + lp_bin_new_cmd_block( list ); + } + + { + struct cmd_block *tail = list->tail; + unsigned i = tail->count; + tail->cmd[i] = cmd; + tail->arg[i] = arg; + tail->count++; + } +} + + +/* Add a command to all active bins. + */ +static INLINE void +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 ); +} + + +void +lp_scene_bin_state_command( struct lp_scene *scene, + lp_rast_cmd cmd, + const union lp_rast_cmd_arg arg ); + + +static INLINE unsigned +lp_scene_get_num_bins( const struct lp_scene *scene ) +{ + return scene->tiles_x * scene->tiles_y; +} + + +void +lp_scene_bin_iter_begin( struct lp_scene *scene ); + +struct cmd_bin * +lp_scene_bin_iter_next( struct lp_scene *scene, int *bin_x, int *bin_y ); + + +#endif /* LP_BIN_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_scene_queue.c b/src/gallium/drivers/llvmpipe/lp_scene_queue.c new file mode 100644 index 0000000000..8d65a6a6fa --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_scene_queue.c @@ -0,0 +1,164 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * Scene queue. We'll use two queues. One contains "full" scenes which + * are produced by the "setup" code. The other contains "empty" scenes + * which are produced by the "rast" code when it finishes rendering a scene. + */ + + +#include "pipe/p_thread.h" +#include "util/u_memory.h" +#include "lp_scene_queue.h" + + + +#define MAX_SCENE_QUEUE 4 + + +/** + * A queue of scenes + */ +struct lp_scene_queue +{ + /** XXX might use a linked list here somedone, but the list will + * probably always be pretty short. + */ + struct lp_scene *scenes[MAX_SCENE_QUEUE]; + unsigned count; + + pipe_condvar count_change; + pipe_mutex mutex; +}; + + + +/** Allocate a new scene queue */ +struct lp_scene_queue * +lp_scene_queue_create(void) +{ + struct lp_scene_queue *queue = CALLOC_STRUCT(lp_scene_queue); + if (queue) { + pipe_condvar_init(queue->count_change); + pipe_mutex_init(queue->mutex); + } + return queue; +} + + +/** Delete a scene queue */ +void +lp_scene_queue_destroy(struct lp_scene_queue *queue) +{ + pipe_condvar_destroy(queue->count_change); + pipe_mutex_destroy(queue->mutex); +} + + +/** Remove first lp_scene from head of queue */ +struct lp_scene * +lp_scene_dequeue(struct lp_scene_queue *queue) +{ + struct lp_scene *scene; + unsigned i; + + pipe_mutex_lock(queue->mutex); + while (queue->count == 0) { + pipe_condvar_wait(queue->count_change, queue->mutex); + } + + assert(queue->count >= 1); + + /* get head */ + scene = queue->scenes[0]; + + /* shift entries */ + for (i = 0; i < queue->count - 1; i++) { + queue->scenes[i] = queue->scenes[i + 1]; + } + + queue->count--; + + /* signal size change */ + pipe_condvar_signal(queue->count_change); + + pipe_mutex_unlock(queue->mutex); + + return scene; +} + + +/** Add an lp_scene to tail of queue */ +void +lp_scene_enqueue(struct lp_scene_queue *queue, struct lp_scene *scene) +{ + pipe_mutex_lock(queue->mutex); + + assert(queue->count < MAX_SCENE_QUEUE); + + /* debug: check that scene is not already in the queue */ + if (0) { + unsigned i; + for (i = 0; i < queue->count; i++) { + assert(queue->scenes[i] != scene); + } + } + + /* add to end */ + queue->scenes[queue->count++] = scene; + + /* signal size change */ + pipe_condvar_signal(queue->count_change); + + pipe_mutex_unlock(queue->mutex); +} + + +/** Return number of entries in the queue */ +unsigned +lp_scene_queue_count(struct lp_scene_queue *queue) +{ + unsigned count; + pipe_mutex_lock(queue->mutex); + count = queue->count; + pipe_mutex_unlock(queue->mutex); + return count; +} + + +/** Wait until the queue has exactly 'count' entries */ +void +lp_scene_queue_wait_count(struct lp_scene_queue *queue, unsigned count) +{ + pipe_mutex_lock(queue->mutex); + while (queue->count != count) { + pipe_condvar_wait(queue->count_change, queue->mutex); + } + pipe_mutex_unlock(queue->mutex); +} diff --git a/src/gallium/drivers/llvmpipe/lp_scene_queue.h b/src/gallium/drivers/llvmpipe/lp_scene_queue.h new file mode 100644 index 0000000000..1bd475fa50 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_scene_queue.h @@ -0,0 +1,55 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef LP_SCENE_QUEUE +#define LP_SCENE_QUEUE + +struct lp_scene_queue; +struct lp_scene; + + +struct lp_scene_queue * +lp_scene_queue_create(void); + +void +lp_scene_queue_destroy(struct lp_scene_queue *queue); + +struct lp_scene * +lp_scene_dequeue(struct lp_scene_queue *queue); + +void +lp_scene_enqueue(struct lp_scene_queue *queue, struct lp_scene *bins); + +unsigned +lp_scene_queue_count(struct lp_scene_queue *queue); + +void +lp_scene_queue_wait_count(struct lp_scene_queue *queue, unsigned size); + + +#endif /* LP_BIN_QUEUE */ diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 0972c16784..76e0955237 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -36,8 +36,8 @@ #include "pipe/p_inlines.h" #include "util/u_memory.h" #include "util/u_pack_color.h" -#include "lp_bin.h" -#include "lp_bin_queue.h" +#include "lp_scene.h" +#include "lp_scene_queue.h" #include "lp_debug.h" #include "lp_fence.h" #include "lp_state.h" @@ -47,26 +47,26 @@ /** XXX temporary value, temporary here */ -#define MAX_BINS 2 +#define MAX_SCENES 2 static void set_state( struct setup_context *, unsigned ); -struct lp_bins * -lp_setup_get_current_bins(struct setup_context *setup) +struct lp_scene * +lp_setup_get_current_scene(struct setup_context *setup) { - if (!setup->bins) { + if (!setup->scene) { /* wait for a free/empty bin */ - setup->bins = lp_bins_dequeue(setup->empty_bins); - if(0)lp_reset_bins( setup->bins ); /* XXX temporary? */ + setup->scene = lp_scene_dequeue(setup->empty_scenes); + if(0)lp_scene_reset( setup->scene ); /* XXX temporary? */ if (setup->fb) { - lp_bin_set_framebuffer_size(setup->bins, + lp_scene_set_framebuffer_size(setup->scene, setup->fb->width, setup->fb->height); } } - return setup->bins; + return setup->scene; } @@ -111,7 +111,7 @@ static void reset_context( struct setup_context *setup ) setup->dirty = ~0; /* no current bin */ - setup->bins = NULL; + setup->scene = NULL; /* Reset some state: */ @@ -126,15 +126,15 @@ static void reset_context( struct setup_context *setup ) } -/** Rasterize all tile's bins */ +/** Rasterize all scene's bins */ static void -lp_setup_rasterize_bins( struct setup_context *setup, +lp_setup_rasterize_scene( struct setup_context *setup, boolean write_depth ) { - struct lp_bins *bins = lp_setup_get_current_bins(setup); + struct lp_scene *scene = lp_setup_get_current_scene(setup); - lp_rasterize_bins(setup->rast, - bins, + lp_rasterize_scene(setup->rast, + scene, setup->fb, write_depth); @@ -148,28 +148,28 @@ lp_setup_rasterize_bins( struct setup_context *setup, static void begin_binning( struct setup_context *setup ) { - struct lp_bins *bins = lp_setup_get_current_bins(setup); + struct lp_scene *scene = lp_setup_get_current_scene(setup); LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); if (setup->fb->cbufs[0]) { if (setup->clear.flags & PIPE_CLEAR_COLOR) - lp_bin_everywhere( bins, + lp_scene_bin_everywhere( scene, lp_rast_clear_color, setup->clear.color ); else - lp_bin_everywhere( bins, + lp_scene_bin_everywhere( scene, lp_rast_load_color, lp_rast_arg_null() ); } if (setup->fb->zsbuf) { if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) - lp_bin_everywhere( bins, + lp_scene_bin_everywhere( scene, lp_rast_clear_zstencil, setup->clear.zstencil ); else - lp_bin_everywhere( bins, + lp_scene_bin_everywhere( scene, lp_rast_load_zstencil, lp_rast_arg_null() ); } @@ -189,7 +189,7 @@ execute_clears( struct setup_context *setup ) LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); begin_binning( setup ); - lp_setup_rasterize_bins( setup, TRUE ); + lp_setup_rasterize_scene( setup, TRUE ); } @@ -220,7 +220,7 @@ set_state( struct setup_context *setup, if (old_state == SETUP_CLEARED) execute_clears( setup ); else - lp_setup_rasterize_bins( setup, TRUE ); + lp_setup_rasterize_scene( setup, TRUE ); break; } @@ -242,7 +242,7 @@ void lp_setup_bind_framebuffer( struct setup_context *setup, const struct pipe_framebuffer_state *fb ) { - struct lp_bins *bins = lp_setup_get_current_bins(setup); + struct lp_scene *scene = lp_setup_get_current_scene(setup); LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); @@ -250,7 +250,7 @@ lp_setup_bind_framebuffer( struct setup_context *setup, setup->fb = fb; - lp_bin_set_framebuffer_size(bins, setup->fb->width, setup->fb->height); + lp_scene_set_framebuffer_size(scene, setup->fb->width, setup->fb->height); } @@ -261,7 +261,7 @@ lp_setup_clear( struct setup_context *setup, unsigned stencil, unsigned flags ) { - struct lp_bins *bins = lp_setup_get_current_bins(setup); + struct lp_scene *scene = lp_setup_get_current_scene(setup); unsigned i; LP_DBG(DEBUG_SETUP, "%s state %d\n", __FUNCTION__, setup->state); @@ -280,19 +280,19 @@ lp_setup_clear( struct setup_context *setup, } if (setup->state == SETUP_ACTIVE) { - /* Add the clear to existing bins. In the unusual case where + /* Add the clear to existing scene. In the unusual case where * both color and depth-stencil are being cleared when there's * already been some rendering, we could discard the currently * binned scene and start again, but I don't see that as being * a common usage. */ if (flags & PIPE_CLEAR_COLOR) - lp_bin_everywhere( bins, + lp_scene_bin_everywhere( scene, lp_rast_clear_color, setup->clear.color ); if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) - lp_bin_everywhere( bins, + lp_scene_bin_everywhere( scene, lp_rast_clear_zstencil, setup->clear.zstencil ); } @@ -315,8 +315,8 @@ lp_setup_clear( struct setup_context *setup, struct pipe_fence_handle * lp_setup_fence( struct setup_context *setup ) { - struct lp_bins *bins = lp_setup_get_current_bins(setup); - const unsigned rank = lp_bin_get_num_bins( bins ); + struct lp_scene *scene = lp_setup_get_current_scene(setup); + const unsigned rank = lp_scene_get_num_bins( scene ); /* xxx */ struct lp_fence *fence = lp_fence_create(rank); LP_DBG(DEBUG_SETUP, "%s rank %u\n", __FUNCTION__, rank); @@ -324,9 +324,9 @@ lp_setup_fence( struct setup_context *setup ) set_state( setup, SETUP_ACTIVE ); /* insert the fence into all command bins */ - lp_bin_everywhere( bins, - lp_rast_fence, - lp_rast_arg_fence(fence) ); + lp_scene_bin_everywhere( scene, + lp_rast_fence, + lp_rast_arg_fence(fence) ); return (struct pipe_fence_handle *) fence; } @@ -455,7 +455,7 @@ lp_setup_is_texture_referenced( struct setup_context *setup, static INLINE void lp_setup_update_shader_state( struct setup_context *setup ) { - struct lp_bins *bins = lp_setup_get_current_bins(setup); + struct lp_scene *scene = lp_setup_get_current_scene(setup); LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); @@ -465,7 +465,7 @@ lp_setup_update_shader_state( struct setup_context *setup ) uint8_t *stored; unsigned i, j; - stored = lp_bin_alloc_aligned(bins, 4 * 16, 16); + stored = lp_scene_alloc_aligned(scene, 4 * 16, 16); /* smear each blend color component across 16 ubyte elements */ for (i = 0; i < 4; ++i) { @@ -497,7 +497,7 @@ lp_setup_update_shader_state( struct setup_context *setup ) current_size) != 0) { void *stored; - stored = lp_bin_alloc(bins, current_size); + stored = lp_scene_alloc(scene, current_size); if(stored) { memcpy(stored, current_data, @@ -522,12 +522,12 @@ lp_setup_update_shader_state( struct setup_context *setup ) memcmp(setup->fs.stored, &setup->fs.current, sizeof setup->fs.current) != 0) { - /* The fs state that's been stored in the bins is different from + /* The fs state that's been stored in the scene is different from * the new, current state. So allocate a new lp_rast_state object * and append it to the bin's setup data buffer. */ struct lp_rast_state *stored = - (struct lp_rast_state *) lp_bin_alloc(bins, sizeof *stored); + (struct lp_rast_state *) lp_scene_alloc(scene, sizeof *stored); if(stored) { memcpy(stored, &setup->fs.current, @@ -535,9 +535,9 @@ lp_setup_update_shader_state( struct setup_context *setup ) setup->fs.stored = stored; /* put the state-set command into all bins */ - lp_bin_state_command( bins, - lp_rast_set_state, - lp_rast_arg_state(setup->fs.stored) ); + lp_scene_bin_state_command( scene, + lp_rast_set_state, + lp_rast_arg_state(setup->fs.stored) ); } } } @@ -587,12 +587,12 @@ lp_setup_destroy( struct setup_context *setup ) pipe_buffer_reference(&setup->constants.current, NULL); - /* free the bins in the 'empty' queue */ - while (lp_bins_queue_count(setup->empty_bins) > 0) { - struct lp_bins *bins = lp_bins_dequeue(setup->empty_bins); - if (!bins) + /* free the scenes in the 'empty' queue */ + while (lp_scene_queue_count(setup->empty_scenes) > 0) { + struct lp_scene *scene = lp_scene_dequeue(setup->empty_scenes); + if (!scene) break; - lp_bins_destroy(bins); + lp_scene_destroy(scene); } lp_rast_destroy( setup->rast ); @@ -614,18 +614,18 @@ lp_setup_create( struct pipe_screen *screen ) if (!setup) return NULL; - setup->empty_bins = lp_bins_queue_create(); - if (!setup->empty_bins) + setup->empty_scenes = lp_scene_queue_create(); + if (!setup->empty_scenes) goto fail; - setup->rast = lp_rast_create( screen, setup->empty_bins ); + setup->rast = lp_rast_create( screen, setup->empty_scenes ); if (!setup->rast) goto fail; - /* create some empty bins */ - for (i = 0; i < MAX_BINS; i++) { - struct lp_bins *bins = lp_bins_create(); - lp_bins_enqueue(setup->empty_bins, bins); + /* create some empty scenes */ + for (i = 0; i < MAX_SCENES; i++) { + struct lp_scene *scene = lp_scene_create(); + lp_scene_enqueue(setup->empty_scenes, scene); } setup->triangle = first_triangle; @@ -637,8 +637,8 @@ lp_setup_create( struct pipe_screen *screen ) return setup; fail: - if (setup->empty_bins) - lp_bins_queue_destroy(setup->empty_bins); + if (setup->empty_scenes) + lp_scene_queue_destroy(setup->empty_scenes); FREE(setup); return NULL; diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 584e37665b..180d9eca84 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -38,7 +38,7 @@ #include "lp_setup.h" #include "lp_rast.h" #include "lp_tile_soa.h" /* for TILE_SIZE */ -#include "lp_bin.h" +#include "lp_scene.h" #define LP_SETUP_NEW_FS 0x01 @@ -46,7 +46,7 @@ #define LP_SETUP_NEW_BLEND_COLOR 0x04 -struct lp_bins_queue; +struct lp_scene_queue; /** @@ -59,8 +59,8 @@ struct setup_context { struct lp_rasterizer *rast; - struct lp_bins *bins; /**< current bins */ - struct lp_bins_queue *empty_bins; /**< queue of empty bins */ + struct lp_scene *scene; /**< current scene */ + struct lp_scene_queue *empty_scenes; /**< queue of empty scenes */ boolean ccw_is_frontface; unsigned cullmode; @@ -83,7 +83,7 @@ struct setup_context { struct lp_shader_input input[PIPE_MAX_ATTRIBS]; unsigned nr_inputs; - const struct lp_rast_state *stored; /**< what's in the bins */ + const struct lp_rast_state *stored; /**< what's in the scene */ struct lp_rast_state current; /**< currently set state */ } fs; @@ -118,6 +118,6 @@ void lp_setup_choose_triangle( struct setup_context *setup ); void lp_setup_choose_line( struct setup_context *setup ); void lp_setup_choose_point( struct setup_context *setup ); -struct lp_bins *lp_setup_get_current_bins(struct setup_context *setup); +struct lp_scene *lp_setup_get_current_scene(struct setup_context *setup); #endif diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 80617120b1..aeaf260af2 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -178,7 +178,7 @@ static void setup_tri_coefficients( struct setup_context *setup, const float (*v3)[4], boolean frontface) { - struct lp_bins *bins = lp_setup_get_current_bins(setup); + struct lp_scene *scene = lp_setup_get_current_scene(setup); unsigned slot; /* Allocate space for the a0, dadx and dady arrays @@ -186,9 +186,9 @@ static void setup_tri_coefficients( struct setup_context *setup, { unsigned bytes; bytes = (setup->fs.nr_inputs + 1) * 4 * sizeof(float); - tri->inputs.a0 = lp_bin_alloc_aligned( bins, bytes, 16 ); - tri->inputs.dadx = lp_bin_alloc_aligned( bins, bytes, 16 ); - tri->inputs.dady = lp_bin_alloc_aligned( bins, bytes, 16 ); + tri->inputs.a0 = lp_scene_alloc_aligned( scene, bytes, 16 ); + tri->inputs.dadx = lp_scene_alloc_aligned( scene, bytes, 16 ); + tri->inputs.dady = lp_scene_alloc_aligned( scene, bytes, 16 ); } /* The internal position input is in slot zero: @@ -246,8 +246,8 @@ static inline int subpixel_snap( float a ) /** * Do basic setup for triangle rasterization and determine which - * framebuffer tiles are touched. Put the triangle in the bins for the - * tiles which we overlap. + * framebuffer tiles are touched. Put the triangle in the scene's + * bins for the tiles which we overlap. */ static void do_triangle_ccw(struct setup_context *setup, @@ -264,8 +264,8 @@ do_triangle_ccw(struct setup_context *setup, const int y2 = subpixel_snap(v2[0][1]); const int y3 = subpixel_snap(v3[0][1]); - struct lp_bins *bins = lp_setup_get_current_bins(setup); - struct lp_rast_triangle *tri = lp_bin_alloc( bins, sizeof *tri ); + struct lp_scene *scene = lp_setup_get_current_scene(setup); + struct lp_rast_triangle *tri = lp_scene_alloc( scene, sizeof *tri ); float area, oneoverarea; int minx, maxx, miny, maxy; @@ -285,7 +285,7 @@ do_triangle_ccw(struct setup_context *setup, * XXX: subject to overflow?? */ if (area <= 0) { - lp_bin_putback_data( bins, sizeof *tri ); + lp_scene_putback_data( scene, sizeof *tri ); return; } @@ -297,7 +297,7 @@ do_triangle_ccw(struct setup_context *setup, if (tri->miny == tri->maxy || tri->minx == tri->maxx) { - lp_bin_putback_data( bins, sizeof *tri ); + lp_scene_putback_data( scene, sizeof *tri ); return; } @@ -407,8 +407,8 @@ do_triangle_ccw(struct setup_context *setup, { /* Triangle is contained in a single tile: */ - lp_bin_command( bins, minx, miny, lp_rast_triangle, - lp_rast_arg_triangle(tri) ); + lp_scene_bin_command( scene, minx, miny, lp_rast_triangle, + lp_rast_arg_triangle(tri) ); } else { @@ -466,17 +466,17 @@ do_triangle_ccw(struct setup_context *setup, { in = 1; /* triangle covers the whole tile- shade whole tile */ - lp_bin_command( bins, x, y, - lp_rast_shade_tile, - lp_rast_arg_inputs(&tri->inputs) ); + lp_scene_bin_command( scene, x, y, + lp_rast_shade_tile, + lp_rast_arg_inputs(&tri->inputs) ); } else { in = 1; /* shade partial tile */ - lp_bin_command( bins, x, y, - lp_rast_triangle, - lp_rast_arg_triangle(tri) ); + lp_scene_bin_command( scene, x, y, + lp_rast_triangle, + lp_rast_arg_triangle(tri) ); } /* Iterate cx values across the region: -- cgit v1.2.3