summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Whitwell <keithw@vmware.com>2010-09-07 14:02:15 +0100
committerKeith Whitwell <keithw@vmware.com>2010-09-07 14:02:15 +0100
commit9f6e8e1d6b8696a3ee96cba01b2466ba7a1a8ef6 (patch)
tree6d4ae00b3f30ec9fd8aa78a673a7e65ea6a2851c
parent040e59851ae4c26ce0509d42d2ee71e007b3b3d1 (diff)
llvmpipe: use opcodes instead of function pointers in bins
Also, move some state from rasterizer struct to the scene.
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.c203
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.h77
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast_priv.h69
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast_tri_tmp.h5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_scene.c180
-rw-r--r--src/gallium/drivers/llvmpipe/lp_scene.h80
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c244
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_context.h13
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_line.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_point.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_tri.c41
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_vbuf.c6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c18
-rw-r--r--src/gallium/drivers/llvmpipe/lp_surface.c8
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c2
15 files changed, 513 insertions, 441 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index 694b007eb8b..6a610aaf298 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -30,6 +30,7 @@
#include "util/u_math.h"
#include "util/u_rect.h"
#include "util/u_surface.h"
+#include "util/u_pack_color.h"
#include "lp_scene_queue.h"
#include "lp_debug.h"
@@ -57,39 +58,12 @@ static void
lp_rast_begin( struct lp_rasterizer *rast,
struct lp_scene *scene )
{
- const struct pipe_framebuffer_state *fb = &scene->fb;
- int i;
rast->curr_scene = scene;
LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
- rast->state.nr_cbufs = scene->fb.nr_cbufs;
-
- for (i = 0; i < rast->state.nr_cbufs; i++) {
- struct pipe_surface *cbuf = scene->fb.cbufs[i];
- llvmpipe_resource_map(cbuf->texture,
- cbuf->face,
- cbuf->level,
- cbuf->zslice,
- LP_TEX_USAGE_READ_WRITE,
- LP_TEX_LAYOUT_LINEAR);
- }
-
- if (fb->zsbuf) {
- struct pipe_surface *zsbuf = scene->fb.zsbuf;
- rast->zsbuf.stride = llvmpipe_resource_stride(zsbuf->texture, zsbuf->level);
- rast->zsbuf.blocksize =
- util_format_get_blocksize(zsbuf->texture->format);
-
- rast->zsbuf.map = llvmpipe_resource_map(zsbuf->texture,
- zsbuf->face,
- zsbuf->level,
- zsbuf->zslice,
- LP_TEX_USAGE_READ_WRITE,
- LP_TEX_LAYOUT_NONE);
- }
-
+ lp_scene_begin_rasterization( scene );
lp_scene_bin_iter_begin( scene );
}
@@ -97,29 +71,7 @@ lp_rast_begin( struct lp_rasterizer *rast,
static void
lp_rast_end( struct lp_rasterizer *rast )
{
- struct lp_scene *scene = rast->curr_scene;
- unsigned i;
-
- /* Unmap color buffers */
- for (i = 0; i < rast->state.nr_cbufs; i++) {
- struct pipe_surface *cbuf = scene->fb.cbufs[i];
- llvmpipe_resource_unmap(cbuf->texture,
- cbuf->face,
- cbuf->level,
- cbuf->zslice);
- }
-
- /* Unmap z/stencil buffer */
- if (rast->zsbuf.map) {
- struct pipe_surface *zsbuf = scene->fb.zsbuf;
- llvmpipe_resource_unmap(zsbuf->texture,
- zsbuf->face,
- zsbuf->level,
- zsbuf->zslice);
- rast->zsbuf.map = NULL;
- }
-
- lp_scene_reset( rast->curr_scene );
+ lp_scene_end_rasterization( rast->curr_scene );
rast->curr_scene = NULL;
@@ -138,26 +90,23 @@ lp_rast_end( struct lp_rasterizer *rast )
*/
static void
lp_rast_tile_begin(struct lp_rasterizer_task *task,
- unsigned x, unsigned y)
+ const struct cmd_bin *bin)
{
- struct lp_rasterizer *rast = task->rast;
- struct lp_scene *scene = rast->curr_scene;
+ const struct lp_scene *scene = task->scene;
enum lp_texture_usage usage;
- LP_DBG(DEBUG_RAST, "%s %d,%d\n", __FUNCTION__, x, y);
-
- assert(x % TILE_SIZE == 0);
- assert(y % TILE_SIZE == 0);
+ LP_DBG(DEBUG_RAST, "%s %d,%d\n", __FUNCTION__, bin->x, bin->y);
- task->x = x;
- task->y = y;
+ task->bin = bin;
+ task->x = bin->x * TILE_SIZE;
+ task->y = bin->y * TILE_SIZE;
/* reset pointers to color tile(s) */
memset(task->color_tiles, 0, sizeof(task->color_tiles));
/* get pointer to depth/stencil tile */
{
- struct pipe_surface *zsbuf = rast->curr_scene->fb.zsbuf;
+ struct pipe_surface *zsbuf = task->scene->fb.zsbuf;
if (zsbuf) {
struct llvmpipe_resource *lpt = llvmpipe_resource(zsbuf->texture);
@@ -173,11 +122,14 @@ lp_rast_tile_begin(struct lp_rasterizer_task *task,
zsbuf->face + zsbuf->zslice,
zsbuf->level,
usage,
- x, y);
+ task->x,
+ task->y);
/* Get actual pointer to the tile data. Note that depth/stencil
* data is tiled differently than color data.
*/
- task->depth_tile = lp_rast_get_depth_block_pointer(task, x, y);
+ task->depth_tile = lp_rast_get_depth_block_pointer(task,
+ task->x,
+ task->y);
assert(task->depth_tile);
}
@@ -192,11 +144,11 @@ lp_rast_tile_begin(struct lp_rasterizer_task *task,
* Clear the rasterizer's current color tile.
* This is a bin command called during bin processing.
*/
-void
+static void
lp_rast_clear_color(struct lp_rasterizer_task *task,
const union lp_rast_cmd_arg arg)
{
- struct lp_rasterizer *rast = task->rast;
+ const struct lp_scene *scene = task->scene;
const uint8_t *clear_color = arg.clear_color;
unsigned i;
@@ -211,7 +163,7 @@ lp_rast_clear_color(struct lp_rasterizer_task *task,
clear_color[1] == clear_color[2] &&
clear_color[2] == clear_color[3]) {
/* clear to grayscale value {x, x, x, x} */
- for (i = 0; i < rast->state.nr_cbufs; i++) {
+ for (i = 0; i < scene->fb.nr_cbufs; i++) {
uint8_t *ptr =
lp_rast_get_color_tile_pointer(task, i, LP_TEX_USAGE_WRITE_ALL);
memset(ptr, clear_color[0], TILE_SIZE * TILE_SIZE * 4);
@@ -224,7 +176,7 @@ lp_rast_clear_color(struct lp_rasterizer_task *task,
* works.
*/
const unsigned chunk = TILE_SIZE / 4;
- for (i = 0; i < rast->state.nr_cbufs; i++) {
+ for (i = 0; i < scene->fb.nr_cbufs; i++) {
uint8_t *c =
lp_rast_get_color_tile_pointer(task, i, LP_TEX_USAGE_WRITE_ALL);
unsigned j;
@@ -246,21 +198,25 @@ lp_rast_clear_color(struct lp_rasterizer_task *task,
}
+
+
+
+
/**
* Clear the rasterizer's current z/stencil tile.
* This is a bin command called during bin processing.
*/
-void
+static void
lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
const union lp_rast_cmd_arg arg)
{
- struct lp_rasterizer *rast = task->rast;
+ const struct lp_scene *scene = task->scene;
unsigned clear_value = arg.clear_zstencil.value;
unsigned clear_mask = arg.clear_zstencil.mask;
const unsigned height = TILE_SIZE / TILE_VECTOR_HEIGHT;
const unsigned width = TILE_SIZE * TILE_VECTOR_HEIGHT;
- const unsigned block_size = rast->zsbuf.blocksize;
- const unsigned dst_stride = rast->zsbuf.stride * TILE_VECTOR_HEIGHT;
+ const unsigned block_size = scene->zsbuf.blocksize;
+ const unsigned dst_stride = scene->zsbuf.stride * TILE_VECTOR_HEIGHT;
uint8_t *dst;
unsigned i, j;
@@ -326,14 +282,13 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
* threading/parallelism.
* This is a bin command which is stored in all bins.
*/
-void
+static void
lp_rast_store_linear_color( struct lp_rasterizer_task *task )
{
- struct lp_rasterizer *rast = task->rast;
- struct lp_scene *scene = rast->curr_scene;
+ const struct lp_scene *scene = task->scene;
unsigned buf;
- for (buf = 0; buf < rast->state.nr_cbufs; buf++) {
+ for (buf = 0; buf < scene->fb.nr_cbufs; buf++) {
struct pipe_surface *cbuf = scene->fb.cbufs[buf];
const unsigned face_slice = cbuf->face + cbuf->zslice;
const unsigned level = cbuf->level;
@@ -357,11 +312,11 @@ lp_rast_store_linear_color( struct lp_rasterizer_task *task )
* completely contained inside a triangle.
* This is a bin command called during bin processing.
*/
-void
+static void
lp_rast_shade_tile(struct lp_rasterizer_task *task,
const union lp_rast_cmd_arg arg)
{
- struct lp_rasterizer *rast = task->rast;
+ const struct lp_scene *scene = task->scene;
const struct lp_rast_shader_inputs *inputs = arg.shade_tile;
const struct lp_rast_state *state = inputs->state;
struct lp_fragment_shader_variant *variant = state->variant;
@@ -383,7 +338,7 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task,
unsigned i;
/* color buffer */
- for (i = 0; i < rast->state.nr_cbufs; i++)
+ for (i = 0; i < scene->fb.nr_cbufs; i++)
color[i] = lp_rast_get_color_block_pointer(task, i,
tile_x + x, tile_y + y);
@@ -413,17 +368,17 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task,
* completely contained inside a triangle, and the shader is opaque.
* This is a bin command called during bin processing.
*/
-void
+static void
lp_rast_shade_tile_opaque(struct lp_rasterizer_task *task,
const union lp_rast_cmd_arg arg)
{
- struct lp_rasterizer *rast = task->rast;
+ const struct lp_scene *scene = task->scene;
unsigned i;
LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
/* this will prevent converting the layout from tiled to linear */
- for (i = 0; i < rast->state.nr_cbufs; i++) {
+ for (i = 0; i < scene->fb.nr_cbufs; i++) {
(void)lp_rast_get_color_tile_pointer(task, i, LP_TEX_USAGE_WRITE_ALL);
}
@@ -445,7 +400,7 @@ lp_rast_shade_quads_mask(struct lp_rasterizer_task *task,
{
const struct lp_rast_state *state = inputs->state;
struct lp_fragment_shader_variant *variant = state->variant;
- struct lp_rasterizer *rast = task->rast;
+ const struct lp_scene *scene = task->scene;
uint8_t *color[PIPE_MAX_COLOR_BUFS];
void *depth;
unsigned i;
@@ -460,7 +415,7 @@ lp_rast_shade_quads_mask(struct lp_rasterizer_task *task,
assert((y % 4) == 0);
/* color buffer */
- for (i = 0; i < rast->state.nr_cbufs; i++) {
+ for (i = 0; i < scene->fb.nr_cbufs; i++) {
color[i] = lp_rast_get_color_block_pointer(task, i, x, y);
assert(lp_check_alignment(color[i], 16));
}
@@ -493,7 +448,7 @@ lp_rast_shade_quads_mask(struct lp_rasterizer_task *task,
* This is a bin command put in all bins.
* Called per thread.
*/
-void
+static void
lp_rast_begin_query(struct lp_rasterizer_task *task,
const union lp_rast_cmd_arg arg)
{
@@ -510,7 +465,7 @@ lp_rast_begin_query(struct lp_rasterizer_task *task,
* This is a bin command put in all bins.
* Called per thread.
*/
-void
+static void
lp_rast_end_query(struct lp_rasterizer_task *task,
const union lp_rast_cmd_arg arg)
{
@@ -581,10 +536,10 @@ lp_rast_tile_end(struct lp_rasterizer_task *task)
{
#ifdef DEBUG
if (LP_DEBUG & (DEBUG_SHOW_SUBTILES | DEBUG_SHOW_TILES)) {
- struct lp_rasterizer *rast = task->rast;
+ const struct lp_scene *scene = task->scene;
unsigned buf;
- for (buf = 0; buf < rast->state.nr_cbufs; buf++) {
+ for (buf = 0; buf < scene->fb.nr_cbufs; buf++) {
uint8_t *color = lp_rast_get_color_block_pointer(task, buf,
task->x, task->y);
@@ -608,10 +563,44 @@ lp_rast_tile_end(struct lp_rasterizer_task *task)
/* debug */
memset(task->color_tiles, 0, sizeof(task->color_tiles));
task->depth_tile = NULL;
+
+ task->bin = NULL;
}
+static lp_rast_cmd_func dispatch[LP_RAST_OP_MAX] =
+{
+ lp_rast_clear_color,
+ lp_rast_clear_zstencil,
+ lp_rast_triangle_1,
+ lp_rast_triangle_2,
+ lp_rast_triangle_3,
+ lp_rast_triangle_4,
+ lp_rast_triangle_5,
+ lp_rast_triangle_6,
+ lp_rast_triangle_7,
+ lp_rast_triangle_8,
+ lp_rast_triangle_3_16,
+ lp_rast_shade_tile,
+ lp_rast_shade_tile_opaque,
+ lp_rast_begin_query,
+ lp_rast_end_query,
+};
+static void
+do_rasterize_bin(struct lp_rasterizer_task *task,
+ const struct cmd_bin *bin)
+{
+ const struct cmd_block *block;
+ unsigned k;
+
+ for (block = bin->head; block; block = block->next) {
+ for (k = 0; k < block->count; k++) {
+ dispatch[block->cmd[k]]( task, block->arg[k] );
+ }
+ }
+}
+
/**
@@ -622,26 +611,25 @@ lp_rast_tile_end(struct lp_rasterizer_task *task)
*/
static void
rasterize_bin(struct lp_rasterizer_task *task,
- const struct cmd_bin *bin,
- int x, int y)
+ const struct cmd_bin *bin )
{
- const struct cmd_block_list *commands = &bin->commands;
- struct cmd_block *block;
- unsigned k;
-
- lp_rast_tile_begin( task, x * TILE_SIZE, y * TILE_SIZE );
+ lp_rast_tile_begin( task, bin );
- /* simply execute each of the commands in the block list */
- for (block = commands->head; block; block = block->next) {
- for (k = 0; k < block->count; k++) {
- block->cmd[k]( task, block->arg[k] );
- }
- }
+ do_rasterize_bin(task, bin);
lp_rast_tile_end(task);
-}
+ /* Debug/Perf flags:
+ */
+ if (bin->head->count == 1) {
+ if (bin->head->cmd[0] == LP_RAST_OP_SHADE_TILE_OPAQUE)
+ LP_COUNT(nr_pure_shade_opaque_64);
+ else if (bin->head->cmd[0] == LP_RAST_OP_SHADE_TILE)
+ LP_COUNT(nr_pure_shade_64);
+ }
+}
+
/* An empty bin is one that just loads the contents of the tile and
* stores them again unchanged. This typically happens when bins have
@@ -653,11 +641,10 @@ rasterize_bin(struct lp_rasterizer_task *task,
static boolean
is_empty_bin( const struct cmd_bin *bin )
{
- return bin->commands.head == NULL;
+ return bin->head == NULL;
}
-
/**
* Rasterize/execute all bins within a scene.
* Called per thread.
@@ -666,6 +653,7 @@ static void
rasterize_scene(struct lp_rasterizer_task *task,
struct lp_scene *scene)
{
+ task->scene = scene;
/* loop over scene bins, rasterize each */
#if 0
{
@@ -680,12 +668,11 @@ rasterize_scene(struct lp_rasterizer_task *task,
#else
{
struct cmd_bin *bin;
- int x, y;
assert(scene);
- while ((bin = lp_scene_bin_iter_next(scene, &x, &y))) {
+ while ((bin = lp_scene_bin_iter_next(scene))) {
if (!is_empty_bin( bin ))
- rasterize_bin(task, bin, x, y);
+ rasterize_bin(task, bin);
}
}
#endif
@@ -693,6 +680,8 @@ rasterize_scene(struct lp_rasterizer_task *task,
if (scene->fence) {
lp_fence_signal(scene->fence);
}
+
+ task->scene = NULL;
}
@@ -712,8 +701,6 @@ lp_rast_queue_scene( struct lp_rasterizer *rast,
rasterize_scene( &rast->tasks[0], scene );
- lp_scene_reset( scene );
-
lp_rast_end( rast );
rast->curr_scene = NULL;
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h
index 4697054e8d4..5f3059e794a 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast.h
@@ -79,8 +79,8 @@ struct lp_rast_state {
*/
struct lp_rast_shader_inputs {
float facing; /** Positive for front-facing, negative for back-facing */
- boolean opaque:1; /** Is opaque */
boolean disable:1; /** Partially binned, disable this command */
+ boolean opaque:1; /** Is opaque */
float (*a0)[4];
float (*dadx)[4];
@@ -205,18 +205,18 @@ lp_rast_arg_clearzs( unsigned value, unsigned mask )
static INLINE union lp_rast_cmd_arg
-lp_rast_arg_null( void )
+lp_rast_arg_query( struct llvmpipe_query *pq )
{
union lp_rast_cmd_arg arg;
- arg.set_state = NULL;
+ arg.query_obj = pq;
return arg;
}
static INLINE union lp_rast_cmd_arg
-lp_rast_arg_query( struct llvmpipe_query *pq )
+lp_rast_arg_null( void )
{
union lp_rast_cmd_arg arg;
- arg.query_obj = pq;
+ arg.set_state = NULL;
return arg;
}
@@ -226,54 +226,23 @@ lp_rast_arg_query( struct llvmpipe_query *pq )
* These get put into bins by the setup code and are called when
* the bins are executed.
*/
-
-void lp_rast_clear_color( struct lp_rasterizer_task *,
- const union lp_rast_cmd_arg );
-
-void lp_rast_clear_zstencil( struct lp_rasterizer_task *,
- const union lp_rast_cmd_arg );
-
-void lp_rast_triangle_1( struct lp_rasterizer_task *,
- const union lp_rast_cmd_arg );
-void lp_rast_triangle_2( struct lp_rasterizer_task *,
- const union lp_rast_cmd_arg );
-void lp_rast_triangle_3( struct lp_rasterizer_task *,
- const union lp_rast_cmd_arg );
-void lp_rast_triangle_4( struct lp_rasterizer_task *,
- const union lp_rast_cmd_arg );
-void lp_rast_triangle_5( struct lp_rasterizer_task *,
- const union lp_rast_cmd_arg );
-void lp_rast_triangle_6( struct lp_rasterizer_task *,
- const union lp_rast_cmd_arg );
-void lp_rast_triangle_7( struct lp_rasterizer_task *,
- const union lp_rast_cmd_arg );
-void lp_rast_triangle_8( struct lp_rasterizer_task *,
- const union lp_rast_cmd_arg );
-
-void lp_rast_shade_tile( struct lp_rasterizer_task *,
- const union lp_rast_cmd_arg );
-
-void lp_rast_shade_tile_opaque( struct lp_rasterizer_task *,
- const union lp_rast_cmd_arg );
-
-void lp_rast_fence( struct lp_rasterizer_task *,
- const union lp_rast_cmd_arg );
-
-void lp_rast_store_linear_color( struct lp_rasterizer_task *);
-
-
-void lp_rast_begin_query(struct lp_rasterizer_task *,
- const union lp_rast_cmd_arg );
-
-void lp_rast_restart_query(struct lp_rasterizer_task *,
- const union lp_rast_cmd_arg );
-
-void lp_rast_end_query(struct lp_rasterizer_task *,
- const union lp_rast_cmd_arg );
-
-void
-lp_rast_triangle_3_16(struct lp_rasterizer_task *task,
- const union lp_rast_cmd_arg arg);
-
+#define LP_RAST_OP_CLEAR_COLOR 0x0
+#define LP_RAST_OP_CLEAR_ZSTENCIL 0x1
+#define LP_RAST_OP_TRIANGLE_1 0x2
+#define LP_RAST_OP_TRIANGLE_2 0x3
+#define LP_RAST_OP_TRIANGLE_3 0x4
+#define LP_RAST_OP_TRIANGLE_4 0x5
+#define LP_RAST_OP_TRIANGLE_5 0x6
+#define LP_RAST_OP_TRIANGLE_6 0x7
+#define LP_RAST_OP_TRIANGLE_7 0x8
+#define LP_RAST_OP_TRIANGLE_8 0x9
+#define LP_RAST_OP_TRIANGLE_3_16 0xa
+#define LP_RAST_OP_SHADE_TILE 0xb
+#define LP_RAST_OP_SHADE_TILE_OPAQUE 0xc
+#define LP_RAST_OP_BEGIN_QUERY 0xd
+#define LP_RAST_OP_END_QUERY 0xe
+
+#define LP_RAST_OP_MAX 0xf
+#define LP_RAST_OP_MASK 0xff
#endif
diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
index 6bc10159120..b1b4546bb8e 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
@@ -69,13 +69,16 @@ extern const struct lp_rast_state *jit_state;
struct lp_rasterizer;
-
+struct cmd_bin;
/**
* Per-thread rasterization state
*/
struct lp_rasterizer_task
{
+ const struct cmd_bin *bin;
+
+ struct lp_scene *scene;
unsigned x, y; /**< Pos of this tile in framebuffer, in pixels */
uint8_t *color_tiles[PIPE_MAX_COLOR_BUFS];
@@ -105,33 +108,9 @@ struct lp_rasterizer
{
boolean exit_flag;
- /* Framebuffer stuff
- */
- struct {
- uint8_t *map;
- unsigned stride;
- unsigned blocksize;
- } zsbuf;
-
- struct {
- unsigned nr_cbufs;
- unsigned clear_color;
- unsigned clear_depth;
- char clear_stencil;
- } state;
-
/** The incoming queue of scenes ready to rasterize */
struct lp_scene_queue *full_scenes;
- /**
- * The outgoing queue of processed scenes to return to setup module
- *
- * XXX: while scenes are per-context but the rasterizer is
- * (potentially) shared, these empty scenes should be returned to
- * the context which created them rather than retained here.
- */
- /* struct lp_scene_queue *empty_scenes; */
-
/** The scene currently being rasterized by the threads */
struct lp_scene *curr_scene;
@@ -165,13 +144,13 @@ static INLINE void *
lp_rast_get_depth_block_pointer(struct lp_rasterizer_task *task,
unsigned x, unsigned y)
{
- const struct lp_rasterizer *rast = task->rast;
+ const struct lp_scene *scene = task->scene;
void *depth;
assert((x % TILE_VECTOR_WIDTH) == 0);
assert((y % TILE_VECTOR_HEIGHT) == 0);
- if (!rast->zsbuf.map) {
+ if (!scene->zsbuf.map) {
/* Either out of memory or no zsbuf. Can't tell without access
* to the state. Just use dummy tile memory, but don't print
* the oom warning as this most likely because there is no
@@ -180,9 +159,9 @@ lp_rast_get_depth_block_pointer(struct lp_rasterizer_task *task,
return lp_dummy_tile;
}
- depth = (rast->zsbuf.map +
- rast->zsbuf.stride * y +
- rast->zsbuf.blocksize * x * TILE_VECTOR_HEIGHT);
+ depth = (scene->zsbuf.map +
+ scene->zsbuf.stride * y +
+ scene->zsbuf.blocksize * x * TILE_VECTOR_HEIGHT);
assert(lp_check_alignment(depth, 16));
return depth;
@@ -196,14 +175,14 @@ static INLINE uint8_t *
lp_rast_get_color_tile_pointer(struct lp_rasterizer_task *task,
unsigned buf, enum lp_texture_usage usage)
{
- struct lp_rasterizer *rast = task->rast;
+ const struct lp_scene *scene = task->scene;
assert(task->x % TILE_SIZE == 0);
assert(task->y % TILE_SIZE == 0);
- assert(buf < rast->state.nr_cbufs);
+ assert(buf < scene->fb.nr_cbufs);
if (!task->color_tiles[buf]) {
- struct pipe_surface *cbuf = rast->curr_scene->fb.cbufs[buf];
+ struct pipe_surface *cbuf = scene->fb.cbufs[buf];
struct llvmpipe_resource *lpt;
assert(cbuf);
lpt = llvmpipe_resource(cbuf->texture);
@@ -264,7 +243,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
const struct lp_rast_shader_inputs *inputs,
unsigned x, unsigned y )
{
- const struct lp_rasterizer *rast = task->rast;
+ const struct lp_scene *scene = task->scene;
const struct lp_rast_state *state = inputs->state;
struct lp_fragment_shader_variant *variant = state->variant;
uint8_t *color[PIPE_MAX_COLOR_BUFS];
@@ -272,7 +251,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
unsigned i;
/* color buffer */
- for (i = 0; i < rast->state.nr_cbufs; i++)
+ for (i = 0; i < scene->fb.nr_cbufs; i++)
color[i] = lp_rast_get_color_block_pointer(task, i, x, y);
depth = lp_rast_get_depth_block_pointer(task, x, y);
@@ -292,5 +271,25 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
END_JIT_CALL();
}
+void lp_rast_triangle_1( struct lp_rasterizer_task *,
+ const union lp_rast_cmd_arg );
+void lp_rast_triangle_2( struct lp_rasterizer_task *,
+ const union lp_rast_cmd_arg );
+void lp_rast_triangle_3( struct lp_rasterizer_task *,
+ const union lp_rast_cmd_arg );
+void lp_rast_triangle_4( struct lp_rasterizer_task *,
+ const union lp_rast_cmd_arg );
+void lp_rast_triangle_5( struct lp_rasterizer_task *,
+ const union lp_rast_cmd_arg );
+void lp_rast_triangle_6( struct lp_rasterizer_task *,
+ const union lp_rast_cmd_arg );
+void lp_rast_triangle_7( struct lp_rasterizer_task *,
+ const union lp_rast_cmd_arg );
+void lp_rast_triangle_8( struct lp_rasterizer_task *,
+ const union lp_rast_cmd_arg );
+
+void lp_rast_triangle_3_16( struct lp_rasterizer_task *,
+ const union lp_rast_cmd_arg );
+
#endif
diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri_tmp.h b/src/gallium/drivers/llvmpipe/lp_rast_tri_tmp.h
index eca25bbf2a4..52b9012036d 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast_tri_tmp.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast_tri_tmp.h
@@ -162,6 +162,11 @@ TAG(lp_rast_triangle)(struct lp_rasterizer_task *task,
unsigned outmask, inmask, partmask, partial_mask;
unsigned j = 0;
+ if (tri->inputs.disable) {
+ /* This triangle was partially binned and has been disabled */
+ return;
+ }
+
outmask = 0; /* outside one or more trivial reject planes */
partmask = 0; /* outside one or more trivial accept planes */
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c
index 67bc7475f50..2a26896e628 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene.c
+++ b/src/gallium/drivers/llvmpipe/lp_scene.c
@@ -30,10 +30,10 @@
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "util/u_simple_list.h"
+#include "util/u_format.h"
#include "lp_scene.h"
-#include "lp_debug.h"
-#include "lp_scene_queue.h"
#include "lp_fence.h"
+#include "lp_debug.h"
#define RESOURCE_REF_SZ 32
@@ -51,15 +51,14 @@ struct resource_ref {
* \param queue the queue to put newly rendered/emptied scenes into
*/
struct lp_scene *
-lp_scene_create( struct pipe_context *pipe,
- struct lp_scene_queue *queue )
+lp_scene_create( struct pipe_context *pipe )
{
struct lp_scene *scene = CALLOC_STRUCT(lp_scene);
if (!scene)
return NULL;
scene->pipe = pipe;
- scene->empty_queue = queue;
+ scene->data.head = &scene->data.first;
pipe_mutex_init(scene->mutex);
@@ -73,9 +72,8 @@ lp_scene_create( struct pipe_context *pipe,
void
lp_scene_destroy(struct lp_scene *scene)
{
- lp_scene_reset(scene);
-
pipe_mutex_destroy(scene->mutex);
+ assert(scene->data.head == &scene->data.first);
FREE(scene);
}
@@ -92,8 +90,7 @@ lp_scene_is_empty(struct lp_scene *scene )
for (y = 0; y < TILES_Y; y++) {
for (x = 0; x < TILES_X; x++) {
const struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
- const struct cmd_block_list *list = &bin->commands;
- if (list->head) {
+ if (bin->head) {
return FALSE;
}
}
@@ -103,8 +100,8 @@ lp_scene_is_empty(struct lp_scene *scene )
/* Returns true if there has ever been a failed allocation attempt in
- * this scene. Used in triangle/rectangle emit to avoid having to
- * check success at each bin.
+ * this scene. Used in triangle emit to avoid having to check success
+ * at each bin.
*/
boolean
lp_scene_is_oom(struct lp_scene *scene)
@@ -120,31 +117,90 @@ void
lp_scene_bin_reset(struct lp_scene *scene, unsigned x, unsigned y)
{
struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
- struct cmd_block_list *list = &bin->commands;
- list->head = list->tail;
- if (list->tail) {
- list->tail->next = NULL;
- list->tail->count = 0;
+ bin->head = bin->tail;
+ if (bin->tail) {
+ bin->tail->next = NULL;
+ bin->tail->count = 0;
+ }
+}
+
+
+void
+lp_scene_begin_rasterization(struct lp_scene *scene)
+{
+ const struct pipe_framebuffer_state *fb = &scene->fb;
+ 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 (fb->zsbuf) {
+ struct pipe_surface *zsbuf = scene->fb.zsbuf;
+ scene->zsbuf.stride = llvmpipe_resource_stride(zsbuf->texture, zsbuf->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);
}
}
+
+
/**
- * Free all the temporary data in a scene. May be called from the
- * rasterizer thread(s).
+ * Free all the temporary data in a scene.
*/
void
-lp_scene_reset(struct lp_scene *scene )
+lp_scene_end_rasterization(struct lp_scene *scene )
{
int i, j;
+ /* Unmap color buffers */
+ 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);
+ scene->cbufs[i].map = NULL;
+ }
+ }
+
+ /* Unmap z/stencil buffer */
+ if (scene->zsbuf.map) {
+ struct pipe_surface *zsbuf = scene->fb.zsbuf;
+ llvmpipe_resource_unmap(zsbuf->texture,
+ zsbuf->face,
+ zsbuf->level,
+ zsbuf->zslice);
+ scene->zsbuf.map = NULL;
+ }
+
/* Reset all 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);
- memset(bin, 0, sizeof *bin);
+ bin->head = bin->tail = NULL;
}
}
@@ -186,10 +242,12 @@ lp_scene_reset(struct lp_scene *scene )
for (block = list->head; block; block = tmp) {
tmp = block->next;
- FREE(block);
+ if (block != &list->first)
+ FREE(block);
}
- list->head = NULL;
+ list->head = &list->first;
+ list->head->next = NULL;
}
lp_fence_reference(&scene->fence, NULL);
@@ -200,6 +258,8 @@ lp_scene_reset(struct lp_scene *scene )
scene->has_depthstencil_clear = FALSE;
scene->alloc_failed = FALSE;
+
+ util_unreference_framebuffer_state( &scene->fb );
}
@@ -213,13 +273,13 @@ lp_scene_new_cmd_block( struct lp_scene *scene,
{
struct cmd_block *block = lp_scene_alloc(scene, sizeof(struct cmd_block));
if (block) {
- if (bin->commands.tail) {
- bin->commands.tail->next = block;
- bin->commands.tail = block;
+ if (bin->tail) {
+ bin->tail->next = block;
+ bin->tail = block;
}
else {
- bin->commands.head = block;
- bin->commands.tail = block;
+ bin->head = block;
+ bin->tail = block;
}
//memset(block, 0, sizeof *block);
block->next = NULL;
@@ -269,27 +329,14 @@ lp_scene_data_size( const struct lp_scene *scene )
}
-/** Return number of bytes used for a single bin */
-static 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;
-}
-
/**
* Add a reference to a resource by the scene.
*/
boolean
lp_scene_add_resource_reference(struct lp_scene *scene,
- struct pipe_resource *resource)
+ struct pipe_resource *resource,
+ boolean initializing_scene)
{
struct resource_ref *ref, **last = &scene->resources;
int i;
@@ -327,7 +374,17 @@ lp_scene_add_resource_reference(struct lp_scene *scene,
add_new_ref:
pipe_resource_reference(&ref->resource[ref->count++], resource);
scene->resource_reference_size += llvmpipe_resource_size(resource);
- return scene->resource_reference_size < LP_SCENE_MAX_RESOURCE_SIZE;
+
+ /* Heuristic to advise scene flushes. This isn't helpful in the
+ * initial setup of the scene, but after that point flush on the
+ * next resource added which exceeds 64MB in referenced texture
+ * data.
+ */
+ if (!initializing_scene &&
+ scene->resource_reference_size < LP_SCENE_MAX_RESOURCE_SIZE)
+ return FALSE;
+
+ return TRUE;
}
@@ -384,7 +441,7 @@ lp_scene_bin_iter_begin( struct lp_scene *scene )
* 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 )
+lp_scene_bin_iter_next( struct lp_scene *scene )
{
struct cmd_bin *bin = NULL;
@@ -401,8 +458,6 @@ lp_scene_bin_iter_next( struct lp_scene *scene, int *bin_x, int *bin_y )
}
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);*/
@@ -426,34 +481,13 @@ void lp_scene_begin_binning( struct lp_scene *scene,
}
-void lp_scene_rasterize( struct lp_scene *scene,
- struct lp_rasterizer *rast )
+void lp_scene_end_binning( struct lp_scene *scene )
{
- if (0) {
- unsigned x, y;
+ if (LP_DEBUG & DEBUG_SCENE) {
debug_printf("rasterize scene:\n");
- debug_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++) {
- debug_printf(" bin %u, %u size: %u\n", x, y,
- lp_scene_bin_size(scene, x, y));
- }
- }
+ debug_printf(" scene_size: %u\n",
+ scene->scene_size);
+ debug_printf(" data size: %u\n",
+ lp_scene_data_size(scene));
}
-
- /* Enqueue the scene for rasterization, then immediately wait for
- * it to finish.
- */
- lp_rast_queue_scene( rast, scene );
-
- /* Currently just wait for the rasterizer to finish. Some
- * threading interactions need to be worked out, particularly once
- * transfers become per-context:
- */
- lp_rast_finish( rast );
-
- util_unreference_framebuffer_state( &scene->fb );
-
- /* put scene into the empty list */
- lp_scene_enqueue( scene->empty_queue, scene );
}
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h
index d4f7b047c2a..cc19def3b11 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene.h
+++ b/src/gallium/drivers/llvmpipe/lp_scene.h
@@ -63,11 +63,12 @@ struct lp_scene_queue;
/* switch to a non-pointer value for this:
*/
-typedef void (*lp_rast_cmd)( struct lp_rasterizer_task *,
- const union lp_rast_cmd_arg );
+typedef void (*lp_rast_cmd_func)( struct lp_rasterizer_task *,
+ const union lp_rast_cmd_arg );
+
struct cmd_block {
- lp_rast_cmd cmd[CMD_BLOCK_MAX];
+ uint8_t cmd[CMD_BLOCK_MAX];
union lp_rast_cmd_arg arg[CMD_BLOCK_MAX];
unsigned count;
struct cmd_block *next;
@@ -90,7 +91,10 @@ struct data_block {
* For each screen tile we have one of these bins.
*/
struct cmd_bin {
- struct cmd_block_list commands;
+ ushort x;
+ ushort y;
+ struct cmd_block *head;
+ struct cmd_block *tail;
};
@@ -100,8 +104,12 @@ struct cmd_bin {
*
* Examples include triangle data and state data. The commands in
* the per-tile bins will point to chunks of data in this structure.
+ *
+ * Include the first block of data statically to ensure we can always
+ * initiate a scene without relying on malloc succeeding.
*/
struct data_block_list {
+ struct data_block first;
struct data_block *head;
};
@@ -119,6 +127,15 @@ struct lp_scene {
struct pipe_context *pipe;
struct lp_fence *fence;
+ /* Framebuffer mappings - valid only between begin_rasterization()
+ * and end_rasterization().
+ */
+ struct {
+ uint8_t *map;
+ unsigned stride;
+ unsigned blocksize;
+ } zsbuf, cbufs[PIPE_MAX_COLOR_BUFS];
+
/** the framebuffer to render the scene into */
struct pipe_framebuffer_state fb;
@@ -137,7 +154,6 @@ struct lp_scene {
unsigned resource_reference_size;
boolean alloc_failed;
-
boolean has_depthstencil_clear;
/**
@@ -149,26 +165,19 @@ struct lp_scene {
int curr_x, curr_y; /**< for iterating over bins */
pipe_mutex mutex;
- /* Where to place this scene once it has been rasterized:
- */
- struct lp_scene_queue *empty_queue;
-
struct cmd_bin tile[TILES_X][TILES_Y];
struct data_block_list data;
};
-struct lp_scene *lp_scene_create(struct pipe_context *pipe,
- struct lp_scene_queue *empty_queue);
+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_scene_new_data_block( struct lp_scene *scene );
@@ -176,7 +185,8 @@ struct cmd_block *lp_scene_new_cmd_block( struct lp_scene *scene,
struct cmd_bin *bin );
boolean lp_scene_add_resource_reference(struct lp_scene *scene,
- struct pipe_resource *resource);
+ struct pipe_resource *resource,
+ boolean initializing_scene);
boolean lp_scene_is_resource_referenced(const struct lp_scene *scene,
const struct pipe_resource *resource );
@@ -193,8 +203,9 @@ lp_scene_alloc( struct lp_scene *scene, unsigned size)
struct data_block *block = list->head;
assert(size <= DATA_BLOCK_SIZE);
+ assert(block != NULL);
- if (block == NULL || block->used + size > DATA_BLOCK_SIZE) {
+ if (block->used + size > DATA_BLOCK_SIZE) {
block = lp_scene_new_data_block( scene );
if (!block) {
/* out of memory */
@@ -220,8 +231,9 @@ lp_scene_alloc_aligned( struct lp_scene *scene, unsigned size,
struct data_block_list *list = &scene->data;
struct data_block *block = list->head;
- if (block == NULL ||
- block->used + size + alignment - 1 > DATA_BLOCK_SIZE) {
+ assert(block != NULL);
+
+ if (block->used + size + alignment - 1 > DATA_BLOCK_SIZE) {
block = lp_scene_new_data_block( scene );
if (!block)
return NULL;
@@ -264,15 +276,16 @@ lp_scene_bin_reset(struct lp_scene *scene, unsigned x, unsigned y);
*/
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 )
+ unsigned x, unsigned y,
+ unsigned cmd,
+ union lp_rast_cmd_arg arg )
{
struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
- struct cmd_block *tail = bin->commands.tail;
+ struct cmd_block *tail = bin->tail;
assert(x < scene->tiles_x);
assert(y < scene->tiles_y);
+ assert(cmd <= LP_RAST_OP_END_QUERY);
if (tail == NULL || tail->count == CMD_BLOCK_MAX) {
tail = lp_scene_new_cmd_block( scene, bin );
@@ -284,7 +297,7 @@ lp_scene_bin_command( struct lp_scene *scene,
{
unsigned i = tail->count;
- tail->cmd[i] = cmd;
+ tail->cmd[i] = cmd & LP_RAST_OP_MASK;
tail->arg[i] = arg;
tail->count++;
}
@@ -297,7 +310,7 @@ lp_scene_bin_command( struct lp_scene *scene,
*/
static INLINE boolean
lp_scene_bin_everywhere( struct lp_scene *scene,
- lp_rast_cmd cmd,
+ unsigned cmd,
const union lp_rast_cmd_arg arg )
{
unsigned i, j;
@@ -323,17 +336,30 @@ 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 );
+lp_scene_bin_iter_next( struct lp_scene *scene );
-void
-lp_scene_rasterize( struct lp_scene *scene,
- struct lp_rasterizer *rast );
+/* Begin/end binning of a scene
+ */
void
lp_scene_begin_binning( struct lp_scene *scene,
struct pipe_framebuffer_state *fb );
+void
+lp_scene_end_binning( struct lp_scene *scene );
+
+
+/* Begin/end rasterization of a scene
+ */
+void
+lp_scene_begin_rasterization(struct lp_scene *scene);
+
+void
+lp_scene_end_rasterization(struct lp_scene *scene );
+
+
+
#endif /* LP_BIN_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index 4cb6166badd..f653dd5f0bb 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -42,7 +42,6 @@
#include "lp_context.h"
#include "lp_memory.h"
#include "lp_scene.h"
-#include "lp_scene_queue.h"
#include "lp_texture.h"
#include "lp_debug.h"
#include "lp_fence.h"
@@ -57,16 +56,31 @@
#include "draw/draw_vbuf.h"
-static void set_scene_state( struct lp_setup_context *, enum setup_state );
+static void set_scene_state( struct lp_setup_context *, enum setup_state,
+ const char *reason);
+static boolean try_update_scene_state( struct lp_setup_context *setup );
-struct lp_scene *
-lp_setup_get_current_scene(struct lp_setup_context *setup)
+static void
+lp_setup_get_empty_scene(struct lp_setup_context *setup)
{
- if (!setup->scene) {
- set_scene_state( setup, SETUP_EMPTY );
+ assert(setup->scene == NULL);
+
+ setup->scene_idx++;
+ setup->scene_idx %= Elements(setup->scenes);
+
+ setup->scene = setup->scenes[setup->scene_idx];
+
+ if (setup->scene->fence) {
+ if (LP_DEBUG & DEBUG_SETUP)
+ debug_printf("%s: wait for scene %d\n",
+ __FUNCTION__, setup->scene->fence->id);
+
+ lp_fence_wait(setup->scene->fence);
}
- return setup->scene;
+
+ lp_scene_begin_binning(setup->scene, &setup->fb);
+
}
@@ -76,7 +90,7 @@ first_triangle( struct lp_setup_context *setup,
const float (*v1)[4],
const float (*v2)[4])
{
- set_scene_state( setup, SETUP_ACTIVE );
+ assert(setup->state == SETUP_ACTIVE);
lp_setup_choose_triangle( setup );
setup->triangle( setup, v0, v1, v2 );
}
@@ -86,7 +100,7 @@ first_line( struct lp_setup_context *setup,
const float (*v0)[4],
const float (*v1)[4])
{
- set_scene_state( setup, SETUP_ACTIVE );
+ assert(setup->state == SETUP_ACTIVE);
lp_setup_choose_line( setup );
setup->line( setup, v0, v1 );
}
@@ -95,12 +109,12 @@ static void
first_point( struct lp_setup_context *setup,
const float (*v0)[4])
{
- set_scene_state( setup, SETUP_ACTIVE );
+ assert(setup->state == SETUP_ACTIVE);
lp_setup_choose_point( setup );
setup->point( setup, v0 );
}
-static void reset_context( struct lp_setup_context *setup )
+static void lp_setup_reset( struct lp_setup_context *setup )
{
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
@@ -130,19 +144,23 @@ static void reset_context( struct lp_setup_context *setup )
static void
lp_setup_rasterize_scene( struct lp_setup_context *setup )
{
- struct lp_scene *scene = lp_setup_get_current_scene(setup);
+ struct lp_scene *scene = setup->scene;
struct llvmpipe_screen *screen = llvmpipe_screen(scene->pipe->screen);
+ lp_scene_end_binning(scene);
+
lp_fence_reference(&setup->last_fence, scene->fence);
if (setup->last_fence)
setup->last_fence->issued = TRUE;
pipe_mutex_lock(screen->rast_mutex);
- lp_scene_rasterize(scene, screen->rast);
+ lp_rast_queue_scene(screen->rast, scene);
+ lp_rast_finish(screen->rast);
pipe_mutex_unlock(screen->rast_mutex);
- reset_context( setup );
+ lp_scene_end_rasterization(setup->scene);
+ lp_setup_reset( setup );
LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__);
}
@@ -152,8 +170,10 @@ lp_setup_rasterize_scene( struct lp_setup_context *setup )
static void
begin_binning( struct lp_setup_context *setup )
{
- struct lp_scene *scene = lp_setup_get_current_scene(setup);
+ struct lp_scene *scene = setup->scene;
boolean need_zsload = FALSE;
+ boolean ok;
+ unsigned i, j;
assert(scene);
assert(scene->fence == NULL);
@@ -162,6 +182,17 @@ begin_binning( struct lp_setup_context *setup )
*/
scene->fence = lp_fence_create(MAX2(1, setup->num_threads));
+ /* Initialize the bin flags and x/y coords:
+ */
+ for (i = 0; i < scene->tiles_x; i++) {
+ for (j = 0; j < scene->tiles_y; j++) {
+ scene->tile[i][j].x = i;
+ scene->tile[i][j].y = j;
+ }
+ }
+
+ ok = try_update_scene_state(setup);
+ assert(ok);
if (setup->fb.zsbuf &&
((setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
@@ -175,7 +206,7 @@ begin_binning( struct lp_setup_context *setup )
if (setup->fb.nr_cbufs) {
if (setup->clear.flags & PIPE_CLEAR_COLOR) {
ok = lp_scene_bin_everywhere( scene,
- lp_rast_clear_color,
+ LP_RAST_OP_CLEAR_COLOR,
setup->clear.color );
assert(ok);
}
@@ -186,22 +217,26 @@ begin_binning( struct lp_setup_context *setup )
if (!need_zsload)
scene->has_depthstencil_clear = TRUE;
ok = lp_scene_bin_everywhere( scene,
- lp_rast_clear_zstencil,
+ LP_RAST_OP_CLEAR_ZSTENCIL,
lp_rast_arg_clearzs(
- setup->clear.zsmask,
- setup->clear.zsvalue));
+ setup->clear.zsvalue,
+ setup->clear.zsmask));
assert(ok);
}
}
if (setup->active_query) {
ok = lp_scene_bin_everywhere( scene,
- lp_rast_begin_query,
+ LP_RAST_OP_BEGIN_QUERY,
lp_rast_arg_query(setup->active_query) );
assert(ok);
}
+ setup->clear.flags = 0;
+ setup->clear.zsmask = 0;
+ setup->clear.zsvalue = 0;
+
LP_DBG(DEBUG_SETUP, "%s done\n", __FUNCTION__);
}
@@ -217,50 +252,53 @@ execute_clears( struct lp_setup_context *setup )
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
begin_binning( setup );
- lp_setup_rasterize_scene( setup );
}
+const char *states[] = {
+ "FLUSHED",
+ "EMPTY ",
+ "CLEARED",
+ "ACTIVE "
+};
+
static void
set_scene_state( struct lp_setup_context *setup,
- enum setup_state new_state )
+ enum setup_state new_state,
+ const char *reason)
{
unsigned old_state = setup->state;
if (old_state == new_state)
return;
-
- LP_DBG(DEBUG_SETUP, "%s old %d new %d\n", __FUNCTION__, old_state, new_state);
-
- switch (new_state) {
- case SETUP_EMPTY:
- assert(old_state == SETUP_FLUSHED);
- assert(setup->scene == NULL);
+
+ if (LP_DEBUG & DEBUG_SETUP) {
+ debug_printf("%s old %s new %s%s%s\n",
+ __FUNCTION__,
+ states[old_state],
+ states[new_state],
+ (new_state == SETUP_FLUSHED) ? ": " : "",
+ (new_state == SETUP_FLUSHED) ? reason : "");
+ }
- /* wait for a free/empty scene
- */
- setup->scene = lp_scene_dequeue(setup->empty_scenes, TRUE);
- lp_scene_begin_binning(setup->scene,
- &setup->fb );
- break;
+ /* wait for a free/empty scene
+ */
+ if (old_state == SETUP_FLUSHED)
+ lp_setup_get_empty_scene(setup);
+ switch (new_state) {
case SETUP_CLEARED:
- assert(old_state == SETUP_EMPTY);
- assert(setup->scene != NULL);
break;
case SETUP_ACTIVE:
- assert(old_state == SETUP_EMPTY ||
- old_state == SETUP_CLEARED);
- assert(setup->scene != NULL);
begin_binning( setup );
break;
case SETUP_FLUSHED:
if (old_state == SETUP_CLEARED)
execute_clears( setup );
- else
- lp_setup_rasterize_scene( setup );
+
+ lp_setup_rasterize_scene( setup );
assert(setup->scene == NULL);
break;
@@ -281,9 +319,7 @@ lp_setup_flush( struct lp_setup_context *setup,
struct pipe_fence_handle **fence,
const char *reason)
{
- LP_DBG(DEBUG_SETUP, "%s %s\n", __FUNCTION__, reason);
-
- set_scene_state( setup, SETUP_FLUSHED );
+ set_scene_state( setup, SETUP_FLUSHED, reason );
if (fence) {
lp_fence_reference((struct lp_fence **)fence, setup->last_fence);
@@ -299,7 +335,7 @@ lp_setup_bind_framebuffer( struct lp_setup_context *setup,
/* Flush any old scene.
*/
- set_scene_state( setup, SETUP_FLUSHED );
+ set_scene_state( setup, SETUP_FLUSHED, __FUNCTION__ );
/*
* Ensure the old scene is not reused.
@@ -325,30 +361,34 @@ lp_setup_try_clear( struct lp_setup_context *setup,
unsigned stencil,
unsigned flags )
{
- struct lp_scene *scene = lp_setup_get_current_scene(setup);
uint32_t zsmask = 0;
uint32_t zsvalue = 0;
- uint8_t clear_color[4];
+ union lp_rast_cmd_arg color_arg;
unsigned i;
LP_DBG(DEBUG_SETUP, "%s state %d\n", __FUNCTION__, setup->state);
if (flags & PIPE_CLEAR_COLOR) {
for (i = 0; i < 4; i++)
- clear_color[i] = float_to_ubyte(color[i]);
+ color_arg.clear_color[i] = float_to_ubyte(color[i]);
}
if (flags & PIPE_CLEAR_DEPTHSTENCIL) {
+ unsigned zmask = (flags & PIPE_CLEAR_DEPTH) ? ~0 : 0;
+ unsigned smask = (flags & PIPE_CLEAR_STENCIL) ? ~0 : 0;
+
zsvalue = util_pack_z_stencil(setup->fb.zsbuf->format,
depth,
stencil);
zsmask = util_pack_uint_z_stencil(setup->fb.zsbuf->format,
- 0xffffffff,
- 0xff);
+ zmask,
+ smask);
}
if (setup->state == SETUP_ACTIVE) {
+ struct lp_scene *scene = setup->scene;
+
/* 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
@@ -357,15 +397,15 @@ lp_setup_try_clear( struct lp_setup_context *setup,
*/
if (flags & PIPE_CLEAR_COLOR) {
if (!lp_scene_bin_everywhere( scene,
- lp_rast_clear_color,
- setup->clear.color ))
+ LP_RAST_OP_CLEAR_COLOR,
+ color_arg ))
return FALSE;
}
if (flags & PIPE_CLEAR_DEPTHSTENCIL) {
if (!lp_scene_bin_everywhere( scene,
- lp_rast_clear_zstencil,
- lp_rast_arg_clearzs(zsmask, zsvalue) ))
+ LP_RAST_OP_CLEAR_ZSTENCIL,
+ lp_rast_arg_clearzs(zsvalue, zsmask) ))
return FALSE;
}
}
@@ -375,7 +415,7 @@ lp_setup_try_clear( struct lp_setup_context *setup,
* buffers which the app or state-tracker might issue
* separately.
*/
- set_scene_state( setup, SETUP_CLEARED );
+ set_scene_state( setup, SETUP_CLEARED, __FUNCTION__ );
setup->clear.flags |= flags;
@@ -387,11 +427,11 @@ lp_setup_try_clear( struct lp_setup_context *setup,
if (flags & PIPE_CLEAR_COLOR) {
memcpy(setup->clear.color.clear_color,
- clear_color,
- sizeof clear_color);
+ &color_arg,
+ sizeof color_arg);
}
}
-
+
return TRUE;
}
@@ -677,21 +717,20 @@ lp_setup_is_resource_referenced( const struct lp_setup_context *setup,
static boolean
try_update_scene_state( struct lp_setup_context *setup )
{
- struct lp_scene *scene;
-
- LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
-
- scene = lp_setup_get_current_scene(setup);
+ boolean new_scene = (setup->fs.stored == NULL);
+ struct lp_scene *scene = setup->scene;
- assert(setup->fs.current.variant);
+ assert(scene);
if(setup->dirty & LP_SETUP_NEW_BLEND_COLOR) {
uint8_t *stored;
unsigned i, j;
stored = lp_scene_alloc_aligned(scene, 4 * 16, 16);
- if (!stored)
+ if (!stored) {
+ assert(!new_scene);
return FALSE;
+ }
/* smear each blend color component across 16 ubyte elements */
for (i = 0; i < 4; ++i) {
@@ -722,8 +761,10 @@ try_update_scene_state( struct lp_setup_context *setup )
void *stored;
stored = lp_scene_alloc(scene, current_size);
- if (!stored)
+ if (!stored) {
+ assert(!new_scene);
return FALSE;
+ }
memcpy(stored,
current_data,
@@ -756,8 +797,10 @@ try_update_scene_state( struct lp_setup_context *setup )
* and append it to the bin's setup data buffer.
*/
stored = (struct lp_rast_state *) lp_scene_alloc(scene, sizeof *stored);
- if (!stored)
+ if (!stored) {
+ assert(!new_scene);
return FALSE;
+ }
memcpy(stored,
&setup->fs.current,
@@ -770,8 +813,11 @@ try_update_scene_state( struct lp_setup_context *setup )
for (i = 0; i < Elements(setup->fs.current_tex); i++) {
if (setup->fs.current_tex[i]) {
if (!lp_scene_add_resource_reference(scene,
- setup->fs.current_tex[i]))
+ setup->fs.current_tex[i],
+ new_scene)) {
+ assert(!new_scene);
return FALSE;
+ }
}
}
}
@@ -792,7 +838,8 @@ try_update_scene_state( struct lp_setup_context *setup )
}
void
-lp_setup_update_state( struct lp_setup_context *setup )
+lp_setup_update_state( struct lp_setup_context *setup,
+ boolean update_scene )
{
/* Some of the 'draw' pipeline stages may have changed some driver state.
* Make sure we've processed those state changes before anything else.
@@ -814,13 +861,19 @@ lp_setup_update_state( struct lp_setup_context *setup )
assert(lp->dirty == 0);
}
- /* XXX: only call into update_scene_state() if we already have a
+ if (update_scene)
+ set_scene_state( setup, SETUP_ACTIVE, __FUNCTION__ );
+
+ /* Only call into update_scene_state() if we already have a
* scene:
*/
- if (!try_update_scene_state(setup)) {
- set_scene_state( setup, SETUP_FLUSHED );
- if (!try_update_scene_state(setup))
- assert(0);
+ if (update_scene && setup->scene) {
+ assert(setup->state == SETUP_ACTIVE);
+ if (!try_update_scene_state(setup)) {
+ lp_setup_flush_and_restart(setup);
+ if (!try_update_scene_state(setup))
+ assert(0);
+ }
}
}
@@ -833,7 +886,7 @@ lp_setup_destroy( struct lp_setup_context *setup )
{
uint i;
- reset_context( setup );
+ lp_setup_reset( setup );
util_unreference_framebuffer_state(&setup->fb);
@@ -844,15 +897,15 @@ lp_setup_destroy( struct lp_setup_context *setup )
pipe_resource_reference(&setup->constants.current, NULL);
/* free the scenes in the 'empty' queue */
- while (1) {
- struct lp_scene *scene = lp_scene_dequeue(setup->empty_scenes, FALSE);
- if (!scene)
- break;
+ for (i = 0; i < Elements(setup->scenes); i++) {
+ struct lp_scene *scene = setup->scenes[i];
+
+ if (scene->fence)
+ lp_fence_wait(scene->fence);
+
lp_scene_destroy(scene);
}
- lp_scene_queue_destroy(setup->empty_scenes);
-
FREE( setup );
}
@@ -879,9 +932,6 @@ lp_setup_create( struct pipe_context *pipe,
*/
setup->pipe = pipe;
- setup->empty_scenes = lp_scene_queue_create();
- if (!setup->empty_scenes)
- goto fail;
setup->num_threads = screen->num_threads;
setup->vbuf = draw_vbuf_stage(draw, &setup->base);
@@ -893,9 +943,7 @@ lp_setup_create( struct pipe_context *pipe,
/* create some empty scenes */
for (i = 0; i < MAX_SCENES; i++) {
- setup->scenes[i] = lp_scene_create( pipe, setup->empty_scenes );
-
- lp_scene_enqueue(setup->empty_scenes, setup->scenes[i]);
+ setup->scenes[i] = lp_scene_create( pipe );
}
setup->triangle = first_triangle;
@@ -910,9 +958,6 @@ fail:
if (setup->vbuf)
;
- if (setup->empty_scenes)
- lp_scene_queue_destroy(setup->empty_scenes);
-
FREE(setup);
return NULL;
}
@@ -930,12 +975,13 @@ lp_setup_begin_query(struct lp_setup_context *setup,
if (setup->scene) {
if (!lp_scene_bin_everywhere(setup->scene,
- lp_rast_begin_query,
+ LP_RAST_OP_BEGIN_QUERY,
lp_rast_arg_query(pq))) {
+
lp_setup_flush_and_restart(setup);
if (!lp_scene_bin_everywhere(setup->scene,
- lp_rast_begin_query,
+ LP_RAST_OP_BEGIN_QUERY,
lp_rast_arg_query(pq))) {
assert(0);
return;
@@ -969,7 +1015,9 @@ lp_setup_end_query(struct lp_setup_context *setup, struct llvmpipe_query *pq)
*/
lp_fence_reference(&pq->fence, setup->scene->fence);
- if (!lp_scene_bin_everywhere(setup->scene, lp_rast_end_query, dummy)) {
+ if (!lp_scene_bin_everywhere(setup->scene,
+ LP_RAST_OP_END_QUERY,
+ dummy)) {
lp_setup_flush(setup, 0, NULL, __FUNCTION__);
}
}
@@ -985,8 +1033,8 @@ lp_setup_flush_and_restart(struct lp_setup_context *setup)
if (0) debug_printf("%s\n", __FUNCTION__);
assert(setup->state == SETUP_ACTIVE);
- set_scene_state(setup, SETUP_FLUSHED);
- set_scene_state(setup, SETUP_EMPTY);
- set_scene_state(setup, SETUP_ACTIVE);
- lp_setup_update_state(setup);
+ set_scene_state(setup, SETUP_FLUSHED, __FUNCTION__);
+ lp_setup_update_state(setup, TRUE);
}
+
+
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h
index 3126cf112c1..80b356476ab 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h
@@ -49,8 +49,6 @@
#define LP_SETUP_NEW_SCISSOR 0x08
-struct lp_scene_queue;
-
/** Max number of scenes */
#define MAX_SCENES 2
@@ -84,9 +82,9 @@ struct lp_setup_context
*/
struct draw_stage *vbuf;
unsigned num_threads;
+ unsigned scene_idx;
struct lp_scene *scenes[MAX_SCENES]; /**< all the scenes */
struct lp_scene *scene; /**< current scene being built */
- struct lp_scene_queue *empty_scenes; /**< queue of empty scenes */
struct lp_fence *last_fence;
struct llvmpipe_query *active_query;
@@ -115,7 +113,6 @@ struct lp_setup_context
enum setup_state {
SETUP_FLUSHED, /**< scene is null */
- SETUP_EMPTY, /**< scene exists but has only state changes */
SETUP_CLEARED, /**< scene exists but has only clears */
SETUP_ACTIVE /**< scene exists and has at least one draw/query */
} state;
@@ -161,14 +158,15 @@ void lp_setup_choose_triangle( struct lp_setup_context *setup );
void lp_setup_choose_line( struct lp_setup_context *setup );
void lp_setup_choose_point( struct lp_setup_context *setup );
-struct lp_scene *lp_setup_get_current_scene(struct lp_setup_context *setup);
-
void lp_setup_init_vbuf(struct lp_setup_context *setup);
-void lp_setup_update_state( struct lp_setup_context *setup );
+void lp_setup_update_state( struct lp_setup_context *setup,
+ boolean update_scene);
void lp_setup_destroy( struct lp_setup_context *setup );
+void lp_setup_flush_and_restart(struct lp_setup_context *setup);
+
void
lp_setup_print_triangle(struct lp_setup_context *setup,
const float (*v0)[4],
@@ -196,4 +194,3 @@ lp_setup_bin_triangle( struct lp_setup_context *setup,
void lp_setup_flush_and_restart(struct lp_setup_context *setup);
#endif
-
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_line.c b/src/gallium/drivers/llvmpipe/lp_setup_line.c
index c9d3d7a4563..9f090d1992e 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_line.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_line.c
@@ -268,7 +268,7 @@ try_setup_line( struct lp_setup_context *setup,
const float (*v1)[4],
const float (*v2)[4])
{
- struct lp_scene *scene = lp_setup_get_current_scene(setup);
+ struct lp_scene *scene = setup->scene;
struct lp_rast_triangle *line;
struct lp_line_info info;
float width = MAX2(1.0, setup->line_width);
@@ -585,6 +585,8 @@ try_setup_line( struct lp_setup_context *setup,
line->inputs.facing = 1.0F;
line->inputs.state = setup->fs.stored;
+ line->inputs.disable = FALSE;
+ line->inputs.opaque = FALSE;
for (i = 0; i < 4; i++) {
struct lp_rast_plane *plane = &line->plane[i];
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c b/src/gallium/drivers/llvmpipe/lp_setup_point.c
index fd6b53e2bb2..55389871518 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_point.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c
@@ -229,7 +229,7 @@ try_setup_point( struct lp_setup_context *setup,
const int x0 = subpixel_snap(v0[0][0] - setup->pixel_offset) - fixed_width/2;
const int y0 = subpixel_snap(v0[0][1] - setup->pixel_offset) - fixed_width/2;
- struct lp_scene *scene = lp_setup_get_current_scene(setup);
+ struct lp_scene *scene = setup->scene;
struct lp_rast_triangle *point;
unsigned bytes;
struct u_rect bbox;
@@ -289,6 +289,8 @@ try_setup_point( struct lp_setup_context *setup,
point->inputs.facing = 1.0F;
point->inputs.state = setup->fs.stored;
+ point->inputs.disable = FALSE;
+ point->inputs.opaque = FALSE;
{
point->plane[0].dcdx = -1;
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
index d8dd9ab7ca9..e3cc3f494c0 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
@@ -160,16 +160,17 @@ lp_setup_print_triangle(struct lp_setup_context *setup,
}
-lp_rast_cmd lp_rast_tri_tab[9] = {
- NULL, /* should be impossible */
- lp_rast_triangle_1,
- lp_rast_triangle_2,
- lp_rast_triangle_3,
- lp_rast_triangle_4,
- lp_rast_triangle_5,
- lp_rast_triangle_6,
- lp_rast_triangle_7,
- lp_rast_triangle_8
+static unsigned
+lp_rast_tri_tab[9] = {
+ 0, /* should be impossible */
+ LP_RAST_OP_TRIANGLE_1,
+ LP_RAST_OP_TRIANGLE_2,
+ LP_RAST_OP_TRIANGLE_3,
+ LP_RAST_OP_TRIANGLE_4,
+ LP_RAST_OP_TRIANGLE_5,
+ LP_RAST_OP_TRIANGLE_6,
+ LP_RAST_OP_TRIANGLE_7,
+ LP_RAST_OP_TRIANGLE_8
};
@@ -199,12 +200,12 @@ lp_setup_whole_tile(struct lp_setup_context *setup,
LP_COUNT(nr_shade_opaque_64);
return lp_scene_bin_command( scene, tx, ty,
- lp_rast_shade_tile_opaque,
- lp_rast_arg_inputs(inputs) );
+ LP_RAST_OP_SHADE_TILE_OPAQUE,
+ lp_rast_arg_inputs(inputs) );
} else {
LP_COUNT(nr_shade_64);
return lp_scene_bin_command( scene, tx, ty,
- lp_rast_shade_tile,
+ LP_RAST_OP_SHADE_TILE,
lp_rast_arg_inputs(inputs) );
}
}
@@ -222,8 +223,7 @@ do_triangle_ccw(struct lp_setup_context *setup,
const float (*v2)[4],
boolean frontfacing )
{
- struct lp_scene *scene = lp_setup_get_current_scene(setup);
- struct lp_fragment_shader_variant *variant = setup->fs.current.variant;
+ struct lp_scene *scene = setup->scene;
struct lp_rast_triangle *tri;
int x[3];
int y[3];
@@ -236,7 +236,7 @@ do_triangle_ccw(struct lp_setup_context *setup,
unsigned tri_bytes;
int i;
int nr_planes = 3;
-
+
if (0)
lp_setup_print_triangle(setup, v0, v1, v2);
@@ -280,13 +280,13 @@ do_triangle_ccw(struct lp_setup_context *setup,
bbox.y1 < bbox.y0) {
if (0) debug_printf("empty bounding box\n");
LP_COUNT(nr_culled_tris);
- return FALSE;
+ return TRUE;
}
if (!u_rect_test_intersection(&setup->draw_region, &bbox)) {
if (0) debug_printf("offscreen\n");
LP_COUNT(nr_culled_tris);
- return FALSE;
+ return TRUE;
}
u_rect_find_intersection(&setup->draw_region, &bbox);
@@ -355,11 +355,10 @@ do_triangle_ccw(struct lp_setup_context *setup,
lp_setup_tri_coef( setup, &tri->inputs, &info );
tri->inputs.facing = frontfacing ? 1.0F : -1.0F;
- tri->inputs.opaque = variant->opaque;
tri->inputs.disable = FALSE;
+ tri->inputs.opaque = setup->fs.current.variant->opaque;
tri->inputs.state = setup->fs.stored;
-
for (i = 0; i < 3; i++) {
struct lp_rast_plane *plane = &tri->plane[i];
@@ -496,7 +495,7 @@ lp_setup_bin_triangle( struct lp_setup_context *setup,
int mask = (ix0 & 3) | ((iy0 & 3) << 4);
return lp_scene_bin_command( scene, ix0/4, iy0/4,
- lp_rast_triangle_3_16,
+ LP_RAST_OP_TRIANGLE_3_16,
lp_rast_arg_triangle(tri, mask) );
}
}
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
index 51948f5bf29..6308561f242 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
@@ -64,7 +64,7 @@ lp_setup_get_vertex_info(struct vbuf_render *vbr)
/* Vertex size/info depends on the latest state.
* The draw module may have issued additional state-change commands.
*/
- lp_setup_update_state(setup);
+ lp_setup_update_state(setup, FALSE);
return setup->vertex_info;
}
@@ -141,7 +141,7 @@ lp_setup_draw_elements(struct vbuf_render *vbr, const ushort *indices, uint nr)
const boolean flatshade_first = setup->flatshade_first;
unsigned i;
- lp_setup_update_state(setup);
+ lp_setup_update_state(setup, TRUE);
switch (setup->prim) {
case PIPE_PRIM_POINTS:
@@ -338,7 +338,7 @@ lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
const boolean flatshade_first = setup->flatshade_first;
unsigned i;
- lp_setup_update_state(setup);
+ lp_setup_update_state(setup, TRUE);
switch (setup->prim) {
case PIPE_PRIM_POINTS:
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index d43b2f63589..8f3976c0f90 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -824,13 +824,6 @@ generate_variant(struct llvmpipe_context *lp,
memcpy(&variant->key, key, shader->variant_key_size);
- if (gallivm_debug & GALLIVM_DEBUG_IR) {
- lp_debug_fs_variant(variant);
- }
-
- generate_fragment(lp, shader, variant, RAST_WHOLE);
- generate_fragment(lp, shader, variant, RAST_EDGE_TEST);
-
/*
* Determine whether we are touching all channels in the color buffer.
*/
@@ -854,6 +847,14 @@ generate_variant(struct llvmpipe_context *lp,
!shader->info.uses_kill
? TRUE : FALSE;
+
+ if (gallivm_debug & GALLIVM_DEBUG_IR) {
+ lp_debug_fs_variant(variant);
+ }
+
+ generate_fragment(lp, shader, variant, RAST_WHOLE);
+ generate_fragment(lp, shader, variant, RAST_EDGE_TEST);
+
return variant;
}
@@ -900,6 +901,9 @@ llvmpipe_create_fs_state(struct pipe_context *pipe,
debug_printf("\n");
}
+ /* Keep a copy of the tokens in shader->base.tokens */
+ shader->base.tokens = tgsi_dup_tokens(templ->tokens);
+
return shader;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c
index 63ddc669c2c..164242eda67 100644
--- a/src/gallium/drivers/llvmpipe/lp_surface.c
+++ b/src/gallium/drivers/llvmpipe/lp_surface.c
@@ -68,16 +68,16 @@ lp_resource_copy(struct pipe_context *pipe,
0, /* flush_flags */
FALSE, /* read_only */
TRUE, /* cpu_access */
- FALSE,
- "blit dst"); /* do_not_block */
+ FALSE, /* do_not_block */
+ "blit dest");
llvmpipe_flush_resource(pipe,
src, subsrc.face, subsrc.level,
0, /* flush_flags */
TRUE, /* read_only */
TRUE, /* cpu_access */
- FALSE,
- "blit src"); /* do_not_block */
+ FALSE, /* do_not_block */
+ "blit src");
/*
printf("surface copy from %u to %u: %u,%u to %u,%u %u x %u\n",
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 5832ea27445..a4b9f2590af 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -585,7 +585,7 @@ llvmpipe_get_transfer(struct pipe_context *pipe,
read_only,
TRUE, /* cpu_access */
do_not_block,
- "transfer dest")) {
+ __FUNCTION__)) {
/*
* It would have blocked, but state tracker requested no to.
*/