summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/llvmpipe
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
-rw-r--r--src/gallium/drivers/llvmpipe/Makefile1
-rw-r--r--src/gallium/drivers/llvmpipe/README4
-rw-r--r--src/gallium/drivers/llvmpipe/SConscript8
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.c144
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.h24
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast_priv.h12
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast_tri.c66
-rw-r--r--src/gallium/drivers/llvmpipe/lp_scene.c3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_scene.h3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c15
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tile_image.c126
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tile_image.h57
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tile_soa.py176
15 files changed, 412 insertions, 235 deletions
diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile
index 3173251437..41ac1cee72 100644
--- a/src/gallium/drivers/llvmpipe/Makefile
+++ b/src/gallium/drivers/llvmpipe/Makefile
@@ -37,6 +37,7 @@ C_SOURCES = \
lp_surface.c \
lp_tex_sample_llvm.c \
lp_texture.c \
+ lp_tile_image.c \
lp_tile_soa.c
CPP_SOURCES = \
diff --git a/src/gallium/drivers/llvmpipe/README b/src/gallium/drivers/llvmpipe/README
index 72d9f39658..ae2c1ba943 100644
--- a/src/gallium/drivers/llvmpipe/README
+++ b/src/gallium/drivers/llvmpipe/README
@@ -86,7 +86,7 @@ Building
To build everything on Linux invoke scons as:
- scons debug=yes statetrackers=mesa drivers=trace,llvmpipe winsys=xlib dri=false
+ scons debug=yes statetrackers=mesa drivers=llvmpipe winsys=xlib dri=false
Alternatively, you can build it with GNU make, if you prefer, by invoking it as
@@ -96,7 +96,7 @@ but the rest of these instructions assume that scons is used.
For windows is everything the except except the winsys:
- scons debug=yes statetrackers=mesa drivers=trace,llvmpipe winsys=gdi dri=false
+ scons debug=yes statetrackers=mesa drivers=llvmpipe winsys=gdi dri=false
Using
=====
diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript
index a39283e5e8..13c1a13e87 100644
--- a/src/gallium/drivers/llvmpipe/SConscript
+++ b/src/gallium/drivers/llvmpipe/SConscript
@@ -18,6 +18,13 @@ env.CodeGenerate(
command = 'python $SCRIPT $SOURCE > $TARGET'
)
+# XXX: Our dependency scanner only finds depended modules in relative dirs.
+env.Depends('lp_tile_soa.c', [
+ '#src/gallium/auxiliary/util/u_format_parse.py',
+ '#src/gallium/auxiliary/util/u_format_pack.py',
+ '#src/gallium/auxiliary/util/u_format_access.py',
+])
+
llvmpipe = env.ConvenienceLibrary(
target = 'llvmpipe',
source = [
@@ -52,6 +59,7 @@ llvmpipe = env.ConvenienceLibrary(
'lp_surface.c',
'lp_tex_sample_llvm.c',
'lp_texture.c',
+ 'lp_tile_image.c',
'lp_tile_soa.c',
])
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index 6dbcb3c9b3..82c006d78b 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -156,14 +156,13 @@ lp_rast_end( struct lp_rasterizer *rast )
* \param y window Y position of the tile, in pixels
*/
static void
-lp_rast_start_tile( struct lp_rasterizer *rast,
- unsigned thread_index,
- unsigned x, unsigned y )
+lp_rast_start_tile(struct lp_rasterizer_task *task,
+ unsigned x, unsigned y)
{
LP_DBG(DEBUG_RAST, "%s %d,%d\n", __FUNCTION__, x, y);
- rast->tasks[thread_index].x = x;
- rast->tasks[thread_index].y = y;
+ task->x = x;
+ task->y = y;
}
@@ -171,12 +170,13 @@ lp_rast_start_tile( struct lp_rasterizer *rast,
* Clear the rasterizer's current color tile.
* This is a bin command called during bin processing.
*/
-void lp_rast_clear_color( struct lp_rasterizer *rast,
- unsigned thread_index,
- const union lp_rast_cmd_arg arg )
+void
+lp_rast_clear_color(struct lp_rasterizer_task *task,
+ const union lp_rast_cmd_arg arg)
{
+ struct lp_rasterizer *rast = task->rast;
const uint8_t *clear_color = arg.clear_color;
- uint8_t **color_tile = rast->tasks[thread_index].tile.color;
+ uint8_t **color_tile = task->tile.color;
unsigned i;
LP_DBG(DEBUG_RAST, "%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__,
@@ -225,11 +225,11 @@ void lp_rast_clear_color( struct lp_rasterizer *rast,
* Clear the rasterizer's current z/stencil tile.
* This is a bin command called during bin processing.
*/
-void lp_rast_clear_zstencil( struct lp_rasterizer *rast,
- unsigned thread_index,
- const union lp_rast_cmd_arg arg)
+void
+lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
+ const union lp_rast_cmd_arg arg)
{
- struct lp_rasterizer_task *task = &rast->tasks[thread_index];
+ struct lp_rasterizer *rast = task->rast;
const unsigned tile_x = task->x;
const unsigned tile_y = task->y;
const unsigned height = TILE_SIZE/TILE_VECTOR_HEIGHT;
@@ -288,13 +288,12 @@ void lp_rast_clear_zstencil( struct lp_rasterizer *rast,
* Load tile color from the framebuffer surface.
* This is a bin command called during bin processing.
*/
-void lp_rast_load_color( struct lp_rasterizer *rast,
- unsigned thread_index,
- const union lp_rast_cmd_arg arg)
+void
+lp_rast_load_color(struct lp_rasterizer_task *task,
+ const union lp_rast_cmd_arg arg)
{
- struct lp_rasterizer_task *task = &rast->tasks[thread_index];
- const unsigned x = task->x;
- const unsigned y = task->y;
+ struct lp_rasterizer *rast = task->rast;
+ const unsigned x = task->x, y = task->y;
unsigned i;
LP_DBG(DEBUG_RAST, "%s at %u, %u\n", __FUNCTION__, x, y);
@@ -304,10 +303,7 @@ void lp_rast_load_color( struct lp_rasterizer *rast,
int w = TILE_SIZE;
int h = TILE_SIZE;
- if (x >= transfer->width)
- continue;
-
- if (y >= transfer->height)
+ if (x >= transfer->width || y >= transfer->height)
continue;
assert(w >= 0);
@@ -327,16 +323,16 @@ void lp_rast_load_color( struct lp_rasterizer *rast,
}
-void lp_rast_set_state( struct lp_rasterizer *rast,
- unsigned thread_index,
- const union lp_rast_cmd_arg arg )
+void
+lp_rast_set_state(struct lp_rasterizer_task *task,
+ const union lp_rast_cmd_arg arg)
{
const struct lp_rast_state *state = arg.set_state;
LP_DBG(DEBUG_RAST, "%s %p\n", __FUNCTION__, (void *) state);
/* just set the current state pointer for this rasterizer */
- rast->tasks[thread_index].current_state = state;
+ task->current_state = state;
}
@@ -346,16 +342,15 @@ void lp_rast_set_state( struct lp_rasterizer *rast,
* completely contained inside a triangle.
* This is a bin command called during bin processing.
*/
-void lp_rast_shade_tile( struct lp_rasterizer *rast,
- unsigned thread_index,
- const union lp_rast_cmd_arg arg )
+void
+lp_rast_shade_tile(struct lp_rasterizer_task *task,
+ const union lp_rast_cmd_arg arg)
{
- struct lp_rasterizer_task *task = &rast->tasks[thread_index];
+ struct lp_rasterizer *rast = task->rast;
const struct lp_rast_state *state = task->current_state;
struct lp_rast_tile *tile = &task->tile;
const struct lp_rast_shader_inputs *inputs = arg.shade_tile;
- const unsigned tile_x = task->x;
- const unsigned tile_y = task->y;
+ const unsigned tile_x = task->x, tile_y = task->y;
unsigned x, y;
LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
@@ -396,14 +391,13 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast,
* Compute shading for a 4x4 block of pixels.
* This is a bin command called during bin processing.
*/
-void lp_rast_shade_quads( struct lp_rasterizer *rast,
- unsigned thread_index,
+void lp_rast_shade_quads( struct lp_rasterizer_task *task,
const struct lp_rast_shader_inputs *inputs,
unsigned x, unsigned y,
int32_t c1, int32_t c2, int32_t c3)
{
- struct lp_rasterizer_task *task = &rast->tasks[thread_index];
const struct lp_rast_state *state = task->current_state;
+ struct lp_rasterizer *rast = task->rast;
struct lp_rast_tile *tile = &task->tile;
uint8_t *color[PIPE_MAX_COLOR_BUFS];
void *depth;
@@ -515,12 +509,11 @@ outline_subtiles(uint8_t *tile)
/**
* Write the rasterizer's color tile to the framebuffer.
*/
-static void lp_rast_store_color( struct lp_rasterizer *rast,
- unsigned thread_index)
+static void
+lp_rast_store_color(struct lp_rasterizer_task *task)
{
- struct lp_rasterizer_task *task = &rast->tasks[thread_index];
- const unsigned x = task->x;
- const unsigned y = task->y;
+ struct lp_rasterizer *rast = task->rast;
+ const unsigned x = task->x, y = task->y;
unsigned i;
for (i = 0; i < rast->state.fb.nr_cbufs; i++) {
@@ -535,7 +528,7 @@ static void lp_rast_store_color( struct lp_rasterizer *rast,
continue;
LP_DBG(DEBUG_RAST, "%s [%u] %d,%d %dx%d\n", __FUNCTION__,
- thread_index, x, y, w, h);
+ task->thread_index, x, y, w, h);
if (LP_DEBUG & DEBUG_SHOW_SUBTILES)
outline_subtiles(task->tile.color[i]);
@@ -558,13 +551,14 @@ static void lp_rast_store_color( struct lp_rasterizer *rast,
* Write the rasterizer's tiles to the framebuffer.
*/
static void
-lp_rast_end_tile( struct lp_rasterizer *rast,
- unsigned thread_index )
+lp_rast_end_tile(struct lp_rasterizer_task *task)
{
+ struct lp_rasterizer *rast = task->rast;
+
LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
if (rast->state.write_color)
- lp_rast_store_color(rast, thread_index);
+ lp_rast_store_color(task);
}
@@ -572,9 +566,9 @@ lp_rast_end_tile( struct lp_rasterizer *rast,
* Signal on a fence. This is called during bin execution/rasterization.
* Called per thread.
*/
-void lp_rast_fence( struct lp_rasterizer *rast,
- unsigned thread_index,
- const union lp_rast_cmd_arg arg )
+void
+lp_rast_fence(struct lp_rasterizer_task *task,
+ const union lp_rast_cmd_arg arg)
{
struct lp_fence *fence = arg.fence;
@@ -603,6 +597,9 @@ release_scene( struct lp_rasterizer *rast,
util_unreference_framebuffer_state( &scene->fb );
lp_scene_reset( scene );
+
+ assert(lp_scene_is_empty(scene));
+
lp_scene_enqueue( rast->empty_scenes, scene );
rast->curr_scene = NULL;
}
@@ -615,25 +612,24 @@ release_scene( struct lp_rasterizer *rast,
* Called per thread.
*/
static void
-rasterize_bin( struct lp_rasterizer *rast,
- unsigned thread_index,
- const struct cmd_bin *bin,
- int x, int y)
+rasterize_bin(struct lp_rasterizer_task *task,
+ const struct cmd_bin *bin,
+ int x, int y)
{
const struct cmd_block_list *commands = &bin->commands;
struct cmd_block *block;
unsigned k;
- lp_rast_start_tile( rast, thread_index, x, y );
+ lp_rast_start_tile( task, x, y );
/* 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]( rast, thread_index, block->arg[k] );
+ block->cmd[k]( task, block->arg[k] );
}
}
- lp_rast_end_tile( rast, thread_index );
+ lp_rast_end_tile( task );
}
@@ -717,10 +713,9 @@ is_empty_bin( const struct cmd_bin *bin )
* Called per thread.
*/
static void
-rasterize_scene( struct lp_rasterizer *rast,
- unsigned thread_index,
+rasterize_scene(struct lp_rasterizer_task *task,
struct lp_scene *scene,
- bool write_depth )
+ bool write_depth)
{
/* loop over scene bins, rasterize each */
#if 0
@@ -728,9 +723,8 @@ rasterize_scene( struct lp_rasterizer *rast,
unsigned 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 );
+ struct cmd_bin *bin = lp_scene_get_bin(scene, i, j);
+ rasterize_bin(task, bin, i * TILE_SIZE, j * TILE_SIZE);
}
}
}
@@ -742,7 +736,7 @@ rasterize_scene( struct lp_rasterizer *rast,
assert(scene);
while ((bin = lp_scene_bin_iter_next(scene, &x, &y))) {
if (!is_empty_bin( bin ))
- rasterize_bin( rast, thread_index, bin, x * TILE_SIZE, y * TILE_SIZE);
+ rasterize_bin(task, bin, x * TILE_SIZE, y * TILE_SIZE);
}
}
#endif
@@ -786,7 +780,7 @@ lp_rasterize_scene( struct lp_rasterizer *rast,
fb->zsbuf != NULL && write_depth );
lp_scene_bin_iter_begin( scene );
- rasterize_scene( rast, 0, scene, write_depth );
+ rasterize_scene( &rast->tasks[0], scene, write_depth );
release_scene( rast, scene );
@@ -832,6 +826,9 @@ static PIPE_THREAD_ROUTINE( thread_func, init_data )
debug_printf("thread %d waiting for work\n", task->thread_index);
pipe_semaphore_wait(&task->work_ready);
+ if (rast->exit_flag)
+ break;
+
if (task->thread_index == 0) {
/* thread[0]:
* - get next scene to rasterize
@@ -860,10 +857,9 @@ static PIPE_THREAD_ROUTINE( thread_func, init_data )
/* do work */
if (debug)
debug_printf("thread %d doing work\n", task->thread_index);
- rasterize_scene(rast,
- task->thread_index,
- rast->curr_scene,
- rast->curr_scene->write_depth);
+ rasterize_scene(task,
+ rast->curr_scene,
+ rast->curr_scene->write_depth);
/* wait for all threads to finish with this scene */
pipe_barrier_wait( &rast->barrier );
@@ -968,6 +964,20 @@ void lp_rast_destroy( struct lp_rasterizer *rast )
align_free(rast->tasks[i].tile.color[cbuf]);
}
+ /* Set exit_flag and signal each thread's work_ready semaphore.
+ * Each thread will be woken up, notice that the exit_flag is set and
+ * break out of its main loop. The thread will then exit.
+ */
+ rast->exit_flag = TRUE;
+ for (i = 0; i < rast->num_threads; i++) {
+ pipe_semaphore_signal(&rast->tasks[i].work_ready);
+ }
+
+ for (i = 0; i < rast->num_threads; i++) {
+ pipe_semaphore_destroy(&rast->tasks[i].work_ready);
+ pipe_semaphore_destroy(&rast->tasks[i].work_done);
+ }
+
/* for synchronizing rasterization threads */
pipe_barrier_destroy( &rast->barrier );
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h
index 875f18e0c0..1ed2700191 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast.h
@@ -53,6 +53,9 @@ struct pipe_screen;
#define FIXED_ONE (1<<FIXED_ORDER)
+struct lp_rasterizer_task;
+
+
/**
* Rasterization state.
* Objects of this type are put into the shared data bin and pointed
@@ -201,32 +204,25 @@ lp_rast_arg_null( void )
* the bins are executed.
*/
-void lp_rast_clear_color( struct lp_rasterizer *,
- unsigned thread_index,
+void lp_rast_clear_color( struct lp_rasterizer_task *,
const union lp_rast_cmd_arg );
-void lp_rast_clear_zstencil( struct lp_rasterizer *,
- unsigned thread_index,
+void lp_rast_clear_zstencil( struct lp_rasterizer_task *,
const union lp_rast_cmd_arg );
-void lp_rast_load_color( struct lp_rasterizer *,
- unsigned thread_index,
+void lp_rast_load_color( struct lp_rasterizer_task *,
const union lp_rast_cmd_arg );
-void lp_rast_set_state( struct lp_rasterizer *,
- unsigned thread_index,
+void lp_rast_set_state( struct lp_rasterizer_task *,
const union lp_rast_cmd_arg );
-void lp_rast_triangle( struct lp_rasterizer *,
- unsigned thread_index,
+void lp_rast_triangle( struct lp_rasterizer_task *,
const union lp_rast_cmd_arg );
-void lp_rast_shade_tile( struct lp_rasterizer *,
- unsigned thread_index,
+void lp_rast_shade_tile( struct lp_rasterizer_task *,
const union lp_rast_cmd_arg );
-void lp_rast_fence( struct lp_rasterizer *,
- unsigned thread_index,
+void lp_rast_fence( struct lp_rasterizer_task *,
const union lp_rast_cmd_arg );
#endif
diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
index 5c5497e092..abc5a9ad89 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
@@ -84,6 +84,7 @@ struct lp_rasterizer
{
boolean clipped_tile;
boolean check_for_clipped_tiles;
+ boolean exit_flag;
/* Framebuffer stuff
*/
@@ -121,8 +122,7 @@ struct lp_rasterizer
};
-void lp_rast_shade_quads( struct lp_rasterizer *rast,
- unsigned thread_index,
+void lp_rast_shade_quads( struct lp_rasterizer_task *task,
const struct lp_rast_shader_inputs *inputs,
unsigned x, unsigned y,
int32_t c1, int32_t c2, int32_t c3);
@@ -159,13 +159,13 @@ lp_rast_depth_pointer( struct lp_rasterizer *rast,
* \param x, y location of 4x4 block in window coords
*/
static INLINE void
-lp_rast_shade_quads_all( struct lp_rasterizer *rast,
- unsigned thread_index,
+lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
const struct lp_rast_shader_inputs *inputs,
unsigned x, unsigned y )
{
- const struct lp_rast_state *state = rast->tasks[thread_index].current_state;
- struct lp_rast_tile *tile = &rast->tasks[thread_index].tile;
+ struct lp_rasterizer *rast = task->rast;
+ const struct lp_rast_state *state = task->current_state;
+ struct lp_rast_tile *tile = &task->tile;
const unsigned ix = x % TILE_SIZE, iy = y % TILE_SIZE;
uint8_t *color[PIPE_MAX_COLOR_BUFS];
void *depth;
diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c
index 0334705ef7..a5f0d14c95 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c
@@ -89,14 +89,11 @@ static const int pos_table16[16][2] = {
* Shade all pixels in a 4x4 block.
*/
static void
-block_full_4( struct lp_rasterizer_task *rast_task,
- const struct lp_rast_triangle *tri,
- int x, int y )
+block_full_4(struct lp_rasterizer_task *task,
+ const struct lp_rast_triangle *tri,
+ int x, int y)
{
- lp_rast_shade_quads_all(rast_task->rast,
- rast_task->thread_index,
- &tri->inputs,
- x, y);
+ lp_rast_shade_quads_all(task, &tri->inputs, x, y);
}
@@ -104,16 +101,16 @@ block_full_4( struct lp_rasterizer_task *rast_task,
* Shade all pixels in a 16x16 block.
*/
static void
-block_full_16( struct lp_rasterizer_task *rast_task,
- const struct lp_rast_triangle *tri,
- int x, int y )
+block_full_16(struct lp_rasterizer_task *task,
+ const struct lp_rast_triangle *tri,
+ int x, int y)
{
unsigned ix, iy;
assert(x % 16 == 0);
assert(y % 16 == 0);
for (iy = 0; iy < 16; iy += 4)
for (ix = 0; ix < 16; ix += 4)
- block_full_4(rast_task, tri, x + ix, y + iy);
+ block_full_4(task, tri, x + ix, y + iy);
}
@@ -123,18 +120,15 @@ block_full_16( struct lp_rasterizer_task *rast_task,
* will be done as part of the fragment shader.
*/
static void
-do_block_4( struct lp_rasterizer_task *rast_task,
- const struct lp_rast_triangle *tri,
- int x, int y,
- int c1,
- int c2,
- int c3 )
+do_block_4(struct lp_rasterizer_task *task,
+ const struct lp_rast_triangle *tri,
+ int x, int y,
+ int c1, int c2, int c3)
{
- lp_rast_shade_quads(rast_task->rast,
- rast_task->thread_index,
- &tri->inputs,
- x, y,
- -c1, -c2, -c3);
+ assert(x >= 0);
+ assert(y >= 0);
+
+ lp_rast_shade_quads(task, &tri->inputs, x, y, -c1, -c2, -c3);
}
@@ -143,18 +137,18 @@ do_block_4( struct lp_rasterizer_task *rast_task,
* of the triangle's bounds.
*/
static void
-do_block_16( struct lp_rasterizer_task *rast_task,
- const struct lp_rast_triangle *tri,
- int x, int y,
- int c0,
- int c1,
- int c2 )
+do_block_16(struct lp_rasterizer_task *task,
+ const struct lp_rast_triangle *tri,
+ int x, int y,
+ int c0, int c1, int c2)
{
unsigned mask = 0;
int eo[3];
int c[3];
int i, j;
+ assert(x >= 0);
+ assert(y >= 0);
assert(x % 16 == 0);
assert(y % 16 == 0);
@@ -193,7 +187,7 @@ do_block_16( struct lp_rasterizer_task *rast_task,
* the triangle. It's a little faster to do it in the jit code.
*/
LP_COUNT(nr_non_empty_4);
- do_block_4(rast_task, tri, px, py, cx1, cx2, cx3);
+ do_block_4(task, tri, px, py, cx1, cx2, cx3);
}
}
@@ -203,15 +197,11 @@ do_block_16( struct lp_rasterizer_task *rast_task,
* for this triangle.
*/
void
-lp_rast_triangle( struct lp_rasterizer *rast,
- unsigned thread_index,
- const union lp_rast_cmd_arg arg )
+lp_rast_triangle(struct lp_rasterizer_task *task,
+ const union lp_rast_cmd_arg arg)
{
- struct lp_rasterizer_task *rast_task = &rast->tasks[thread_index];
const struct lp_rast_triangle *tri = arg.triangle;
-
- int x = rast_task->x;
- int y = rast_task->y;
+ const int x = task->x, y = task->y;
int ei[3], eo[3], c[3];
unsigned outmask, inmask, partial_mask;
unsigned i, j;
@@ -272,7 +262,7 @@ lp_rast_triangle( struct lp_rasterizer *rast,
partial_mask &= ~(1 << i);
LP_COUNT(nr_partially_covered_16);
- do_block_16(rast_task, tri, px, py, cx1, cx2, cx3);
+ do_block_16(task, tri, px, py, cx1, cx2, cx3);
}
/* Iterate over fulls:
@@ -285,6 +275,6 @@ lp_rast_triangle( struct lp_rasterizer *rast,
inmask &= ~(1 << i);
LP_COUNT(nr_fully_covered_16);
- block_full_16(rast_task, tri, px, py);
+ block_full_16(task, tri, px, py);
}
}
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c
index b7116297ec..cba0e21298 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene.c
+++ b/src/gallium/drivers/llvmpipe/lp_scene.c
@@ -100,6 +100,9 @@ lp_scene_bin_reset(struct lp_scene *scene, unsigned x, unsigned y)
struct cmd_block *block;
struct cmd_block *tmp;
+ assert(x < TILES_X);
+ assert(y < TILES_Y);
+
for (block = list->head; block != list->tail; block = tmp) {
tmp = block->next;
FREE(block);
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h
index fb478cc2eb..8d725cd437 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene.h
+++ b/src/gallium/drivers/llvmpipe/lp_scene.h
@@ -56,8 +56,7 @@
/* switch to a non-pointer value for this:
*/
-typedef void (*lp_rast_cmd)( struct lp_rasterizer *,
- unsigned thread_index,
+typedef void (*lp_rast_cmd)( struct lp_rasterizer_task *,
const union lp_rast_cmd_arg );
struct cmd_block {
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 1cd3ea9a84..f84ede675b 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -83,7 +83,7 @@ llvmpipe_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
return PIPE_MAX_SAMPLERS;
case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
- return PIPE_MAX_VERTEX_SAMPLERS;
+ return 0;
case PIPE_CAP_MAX_COMBINED_SAMPLERS:
return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS;
case PIPE_CAP_NPOT_TEXTURES:
@@ -194,9 +194,7 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
format_desc->block.height != 1)
return FALSE;
- if(format_desc->layout != UTIL_FORMAT_LAYOUT_SCALAR &&
- format_desc->layout != UTIL_FORMAT_LAYOUT_ARITH &&
- format_desc->layout != UTIL_FORMAT_LAYOUT_ARRAY)
+ if(format_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
return FALSE;
if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB &&
@@ -224,15 +222,16 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
format_desc->block.height != 1)
return FALSE;
- if(format_desc->layout != UTIL_FORMAT_LAYOUT_SCALAR &&
- format_desc->layout != UTIL_FORMAT_LAYOUT_ARITH &&
- format_desc->layout != UTIL_FORMAT_LAYOUT_ARRAY)
+ if(format_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
return FALSE;
if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB &&
- format_desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB &&
format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
return FALSE;
+
+ /* not supported yet */
+ if (format == PIPE_FORMAT_Z16_UNORM)
+ return FALSE;
}
return TRUE;
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index cb873667a2..3aec9de373 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -64,6 +64,8 @@ lp_setup_get_current_scene(struct setup_context *setup)
*/
setup->scene = lp_scene_dequeue(setup->empty_scenes, TRUE);
+ assert(lp_scene_is_empty(setup->scene));
+
if(0)lp_scene_reset( setup->scene ); /* XXX temporary? */
lp_scene_set_framebuffer_size(setup->scene,
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 022bf92cb4..7f45635542 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -124,12 +124,6 @@ llvmpipe_texture_create(struct pipe_screen *_screen,
pipe_reference_init(&lpt->base.reference, 1);
lpt->base.screen = &screen->base;
- /* XXX: The xlib state tracker is brain-dead and will request
- * PIPE_FORMAT_Z16_UNORM no matter how much we tell it we don't support it.
- */
- if (lpt->base.format == PIPE_FORMAT_Z16_UNORM)
- lpt->base.format = PIPE_FORMAT_Z32_UNORM;
-
if (lpt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_PRIMARY)) {
if (!llvmpipe_displaytarget_layout(screen, lpt))
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_image.c b/src/gallium/drivers/llvmpipe/lp_tile_image.c
new file mode 100644
index 0000000000..c1980b316d
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_tile_image.c
@@ -0,0 +1,126 @@
+/**************************************************************************
+ *
+ * Copyright 2010 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 THE AUTHORS 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 "lp_tile_soa.h"
+#include "lp_tile_image.h"
+
+
+#define BYTES_PER_TILE (TILE_SIZE * TILE_SIZE * 4)
+
+
+/**
+ * Convert a tiled image into a linear image.
+ * \param src_stride source row stride in bytes (bytes per row of tiles)
+ * \param dst_stride dest row stride in bytes
+ */
+void
+lp_tiled_to_linear(const uint8_t *src,
+ uint8_t *dst,
+ unsigned width, unsigned height,
+ enum pipe_format format,
+ unsigned src_stride,
+ unsigned dst_stride)
+{
+ const unsigned tiles_per_row = src_stride / BYTES_PER_TILE;
+ unsigned i, j;
+
+ for (j = 0; j < height; j += TILE_SIZE) {
+ for (i = 0; i < width; i += TILE_SIZE) {
+ unsigned tile_offset =
+ ((j / TILE_SIZE) * tiles_per_row + i / TILE_SIZE);
+ unsigned byte_offset = tile_offset * BYTES_PER_TILE;
+ const uint8_t *src_tile = src + byte_offset;
+
+ lp_tile_write_4ub(format,
+ src_tile,
+ dst,
+ dst_stride,
+ i, j, TILE_SIZE, TILE_SIZE);
+ }
+ }
+}
+
+
+/**
+ * Convert a linear image into a tiled image.
+ * \param src_stride source row stride in bytes
+ * \param dst_stride dest row stride in bytes (bytes per row of tiles)
+ */
+void
+lp_linear_to_tiled(const uint8_t *src,
+ uint8_t *dst,
+ unsigned width, unsigned height,
+ enum pipe_format format,
+ unsigned src_stride,
+ unsigned dst_stride)
+{
+ const unsigned tiles_per_row = dst_stride / BYTES_PER_TILE;
+ unsigned i, j;
+
+ for (j = 0; j < height; j += TILE_SIZE) {
+ for (i = 0; i < width; i += TILE_SIZE) {
+ unsigned tile_offset =
+ ((j / TILE_SIZE) * tiles_per_row + i / TILE_SIZE);
+ unsigned byte_offset = tile_offset * BYTES_PER_TILE;
+ uint8_t *dst_tile = dst + byte_offset;
+
+ lp_tile_read_4ub(format,
+ dst_tile,
+ src,
+ src_stride,
+ i, j, TILE_SIZE, TILE_SIZE);
+ }
+ }
+}
+
+
+/**
+ * For testing only.
+ */
+void
+test_tiled_linear_conversion(uint8_t *data,
+ enum pipe_format format,
+ unsigned width, unsigned height,
+ unsigned stride)
+{
+ /* size in tiles */
+ unsigned wt = (width + TILE_SIZE - 1) / TILE_SIZE;
+ unsigned ht = (height + TILE_SIZE - 1) / TILE_SIZE;
+
+ uint8_t *tiled = malloc(wt * ht * TILE_SIZE * TILE_SIZE * 4);
+
+ unsigned tiled_stride = wt * TILE_SIZE * TILE_SIZE * 4;
+
+ lp_linear_to_tiled(data, tiled, width, height, format,
+ stride, tiled_stride);
+
+ lp_tiled_to_linear(tiled, data, width, height, format,
+ tiled_stride, stride);
+
+ free(tiled);
+}
+
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_image.h b/src/gallium/drivers/llvmpipe/lp_tile_image.h
new file mode 100644
index 0000000000..60d472e8c5
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_tile_image.h
@@ -0,0 +1,57 @@
+/**************************************************************************
+ *
+ * Copyright 2010 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 THE AUTHORS 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_TILE_IMAGE_H
+#define LP_TILE_IMAGE_H
+
+
+void
+lp_tiled_to_linear(const uint8_t *src,
+ uint8_t *dst,
+ unsigned width, unsigned height,
+ enum pipe_format format,
+ unsigned src_stride,
+ unsigned dst_stride);
+
+
+void
+lp_linear_to_tiled(const uint8_t *src,
+ uint8_t *dst,
+ unsigned width, unsigned height,
+ enum pipe_format format,
+ unsigned src_stride,
+ unsigned dst_stride);
+
+
+void
+test_tiled_linear_conversion(uint8_t *data,
+ enum pipe_format format,
+ unsigned width, unsigned height,
+ unsigned stride);
+
+
+#endif /* LP_TILE_IMAGE_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_soa.py b/src/gallium/drivers/llvmpipe/lp_tile_soa.py
index 5d53689a3d..00b8d4fc38 100644
--- a/src/gallium/drivers/llvmpipe/lp_tile_soa.py
+++ b/src/gallium/drivers/llvmpipe/lp_tile_soa.py
@@ -45,10 +45,10 @@ sys.path.insert(0, os.path.join(os.path.dirname(sys.argv[0]), '../../auxiliary/u
from u_format_access import *
-def generate_format_read(format, dst_type, dst_native_type, dst_suffix):
+def generate_format_read(format, dst_channel, dst_native_type, dst_suffix):
'''Generate the function to read pixels from a particular format'''
- name = short_name(format)
+ name = format.short_name()
src_native_type = native_type(format)
@@ -64,11 +64,11 @@ def generate_format_read(format, dst_type, dst_native_type, dst_suffix):
names = ['']*4
if format.colorspace == 'rgb':
for i in range(4):
- swizzle = format.out_swizzle[i]
+ swizzle = format.swizzles[i]
if swizzle < 4:
names[swizzle] += 'rgba'[i]
elif format.colorspace == 'zs':
- swizzle = format.out_swizzle[0]
+ swizzle = format.swizzles[0]
if swizzle < 4:
names[swizzle] = 'z'
else:
@@ -76,48 +76,49 @@ def generate_format_read(format, dst_type, dst_native_type, dst_suffix):
else:
assert False
- if format.layout == ARITH:
- print ' %s pixel = *src_pixel++;' % src_native_type
- shift = 0;
- for i in range(4):
- src_type = format.in_types[i]
- width = src_type.size
- if names[i]:
- value = 'pixel'
- mask = (1 << width) - 1
- if shift:
- value = '(%s >> %u)' % (value, shift)
- if shift + width < format.block_size():
- value = '(%s & 0x%x)' % (value, mask)
- value = conversion_expr(src_type, dst_type, dst_native_type, value)
- print ' %s %s = %s;' % (dst_native_type, names[i], value)
- shift += width
- elif format.layout == ARRAY:
- for i in range(4):
- src_type = format.in_types[i]
- if names[i]:
- value = '(*src_pixel++)'
- value = conversion_expr(src_type, dst_type, dst_native_type, value)
- print ' %s %s = %s;' % (dst_native_type, names[i], value)
+ if format.layout == PLAIN:
+ if not format.is_array():
+ print ' %s pixel = *src_pixel++;' % src_native_type
+ shift = 0;
+ for i in range(4):
+ src_channel = format.channels[i]
+ width = src_channel.size
+ if names[i]:
+ value = 'pixel'
+ mask = (1 << width) - 1
+ if shift:
+ value = '(%s >> %u)' % (value, shift)
+ if shift + width < format.block_size():
+ value = '(%s & 0x%x)' % (value, mask)
+ value = conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=False)
+ print ' %s %s = %s;' % (dst_native_type, names[i], value)
+ shift += width
+ else:
+ for i in range(4):
+ src_channel = format.channels[i]
+ if names[i]:
+ value = '(*src_pixel++)'
+ value = conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=False)
+ print ' %s %s = %s;' % (dst_native_type, names[i], value)
else:
assert False
for i in range(4):
if format.colorspace == 'rgb':
- swizzle = format.out_swizzle[i]
+ swizzle = format.swizzles[i]
if swizzle < 4:
value = names[swizzle]
elif swizzle == SWIZZLE_0:
value = '0'
elif swizzle == SWIZZLE_1:
- value = '1'
+ value = get_one(dst_channel)
else:
assert False
elif format.colorspace == 'zs':
if i < 3:
value = 'z'
else:
- value = '1'
+ value = get_one(dst_channel)
else:
assert False
print ' TILE_PIXEL(dst, x, y, %u) = %s; /* %s */' % (i, value, 'rgba'[i])
@@ -129,31 +130,16 @@ def generate_format_read(format, dst_type, dst_native_type, dst_suffix):
print
-def compute_inverse_swizzle(format):
- '''Return an array[4] of inverse swizzle terms'''
- inv_swizzle = [None]*4
- if format.colorspace == 'rgb':
- for i in range(4):
- swizzle = format.out_swizzle[i]
- if swizzle < 4:
- inv_swizzle[swizzle] = i
- elif format.colorspace == 'zs':
- swizzle = format.out_swizzle[0]
- if swizzle < 4:
- inv_swizzle[swizzle] = 0
- return inv_swizzle
-
-
-def pack_rgba(format, src_type, r, g, b, a):
+def pack_rgba(format, src_channel, r, g, b, a):
"""Return an expression for packing r, g, b, a into a pixel of the
given format. Ex: '(b << 24) | (g << 16) | (r << 8) | (a << 0)'
"""
assert format.colorspace == 'rgb'
- inv_swizzle = compute_inverse_swizzle(format)
+ inv_swizzle = format.inv_swizzles()
shift = 0
expr = None
for i in range(4):
- # choose r, g, b, or a depending on the inverse swizzle term
+ # choose r, g, b, or a depending on the inverse swizzle term
if inv_swizzle[i] == 0:
value = r
elif inv_swizzle[i] == 1:
@@ -166,25 +152,25 @@ def pack_rgba(format, src_type, r, g, b, a):
value = None
if value:
- dst_type = format.in_types[i]
+ dst_channel = format.channels[i]
dst_native_type = native_type(format)
- value = conversion_expr(src_type, dst_type, dst_native_type, value)
+ value = conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=False)
term = "((%s) << %d)" % (value, shift)
if expr:
expr = expr + " | " + term
else:
expr = term
- width = format.in_types[i].size
+ width = format.channels[i].size
shift = shift + width
return expr
-def emit_unrolled_write_code(format, src_type):
+def emit_unrolled_write_code(format, src_channel):
'''Emit code for writing a block based on unrolled loops.
This is considerably faster than the TILE_PIXEL-based code below.
'''
- dst_native_type = native_type(format)
+ dst_native_type = 'uint%u_t' % format.block_size()
print ' const unsigned dstpix_stride = dst_stride / %d;' % format.stride()
print ' %s *dstpix = (%s *) dst;' % (dst_native_type, dst_native_type)
print ' unsigned int qx, qy, i;'
@@ -199,8 +185,8 @@ def emit_unrolled_write_code(format, src_type):
print ' const uint8_t *a = src + 3 * TILE_C_STRIDE;'
print ' (void) r; (void) g; (void) b; (void) a; /* silence warnings */'
print ' for (i = 0; i < TILE_C_STRIDE; i += 2) {'
- print ' const uint32_t pixel0 = %s;' % pack_rgba(format, src_type, "r[i+0]", "g[i+0]", "b[i+0]", "a[i+0]")
- print ' const uint32_t pixel1 = %s;' % pack_rgba(format, src_type, "r[i+1]", "g[i+1]", "b[i+1]", "a[i+1]")
+ print ' const uint32_t pixel0 = %s;' % pack_rgba(format, src_channel, "r[i+0]", "g[i+0]", "b[i+0]", "a[i+0]")
+ print ' const uint32_t pixel1 = %s;' % pack_rgba(format, src_channel, "r[i+1]", "g[i+1]", "b[i+1]", "a[i+1]")
print ' const unsigned offset = (py + tile_y_offset[i]) * dstpix_stride + (px + tile_x_offset[i]);'
print ' dstpix[offset + 0] = pixel0;'
print ' dstpix[offset + 1] = pixel1;'
@@ -210,11 +196,11 @@ def emit_unrolled_write_code(format, src_type):
print ' }'
-def emit_tile_pixel_write_code(format, src_type):
+def emit_tile_pixel_write_code(format, src_channel):
'''Emit code for writing a block based on the TILE_PIXEL macro.'''
dst_native_type = native_type(format)
- inv_swizzle = compute_inverse_swizzle(format)
+ inv_swizzle = format.inv_swizzles()
print ' unsigned x, y;'
print ' uint8_t *dst_row = dst + y0*dst_stride;'
@@ -222,27 +208,28 @@ def emit_tile_pixel_write_code(format, src_type):
print ' %s *dst_pixel = (%s *)(dst_row + x0*%u);' % (dst_native_type, dst_native_type, format.stride())
print ' for (x = 0; x < w; ++x) {'
- if format.layout == ARITH:
- print ' %s pixel = 0;' % dst_native_type
- shift = 0;
- for i in range(4):
- dst_type = format.in_types[i]
- width = dst_type.size
- if inv_swizzle[i] is not None:
- value = 'TILE_PIXEL(src, x, y, %u)' % inv_swizzle[i]
- value = conversion_expr(src_type, dst_type, dst_native_type, value)
- if shift:
- value = '(%s << %u)' % (value, shift)
- print ' pixel |= %s;' % value
- shift += width
- print ' *dst_pixel++ = pixel;'
- elif format.layout == ARRAY:
- for i in range(4):
- dst_type = format.in_types[i]
- if inv_swizzle[i] is not None:
- value = 'TILE_PIXEL(src, x, y, %u)' % inv_swizzle[i]
- value = conversion_expr(src_type, dst_type, dst_native_type, value)
- print ' *dst_pixel++ = %s;' % value
+ if format.layout == PLAIN:
+ if not format.is_array():
+ print ' %s pixel = 0;' % dst_native_type
+ shift = 0;
+ for i in range(4):
+ dst_channel = format.channels[i]
+ width = dst_channel.size
+ if inv_swizzle[i] is not None:
+ value = 'TILE_PIXEL(src, x, y, %u)' % inv_swizzle[i]
+ value = conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=False)
+ if shift:
+ value = '(%s << %u)' % (value, shift)
+ print ' pixel |= %s;' % value
+ shift += width
+ print ' *dst_pixel++ = pixel;'
+ else:
+ for i in range(4):
+ dst_channel = format.channels[i]
+ if inv_swizzle[i] is not None:
+ value = 'TILE_PIXEL(src, x, y, %u)' % inv_swizzle[i]
+ value = conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=False)
+ print ' *dst_pixel++ = %s;' % value
else:
assert False
@@ -251,28 +238,33 @@ def emit_tile_pixel_write_code(format, src_type):
print ' }'
-def generate_format_write(format, src_type, src_native_type, src_suffix):
+def generate_format_write(format, src_channel, src_native_type, src_suffix):
'''Generate the function to write pixels to a particular format'''
- name = short_name(format)
+ name = format.short_name()
print 'static void'
print 'lp_tile_%s_write_%s(const %s *src, uint8_t *dst, unsigned dst_stride, unsigned x0, unsigned y0, unsigned w, unsigned h)' % (name, src_suffix, src_native_type)
print '{'
- if format.layout == ARITH and format.colorspace == 'rgb':
- emit_unrolled_write_code(format, src_type)
+ if format.layout == PLAIN \
+ and format.colorspace == 'rgb' \
+ and format.block_size() <= 32 \
+ and format.is_pot() \
+ and not format.is_mixed() \
+ and format.channels[0].type == UNSIGNED:
+ emit_unrolled_write_code(format, src_channel)
else:
- emit_tile_pixel_write_code(format, src_type)
+ emit_tile_pixel_write_code(format, src_channel)
print '}'
print
-def generate_read(formats, dst_type, dst_native_type, dst_suffix):
+def generate_read(formats, dst_channel, dst_native_type, dst_suffix):
'''Generate the dispatch function to read pixels from any format'''
for format in formats:
if is_format_supported(format):
- generate_format_read(format, dst_type, dst_native_type, dst_suffix)
+ generate_format_read(format, dst_channel, dst_native_type, dst_suffix)
print 'void'
print 'lp_tile_read_%s(enum pipe_format format, %s *dst, const void *src, unsigned src_stride, unsigned x, unsigned y, unsigned w, unsigned h)' % (dst_suffix, dst_native_type)
@@ -282,7 +274,7 @@ def generate_read(formats, dst_type, dst_native_type, dst_suffix):
for format in formats:
if is_format_supported(format):
print ' case %s:' % format.name
- print ' func = &lp_tile_%s_read_%s;' % (short_name(format), dst_suffix)
+ print ' func = &lp_tile_%s_read_%s;' % (format.short_name(), dst_suffix)
print ' break;'
print ' default:'
print ' debug_printf("unsupported format\\n");'
@@ -293,12 +285,12 @@ def generate_read(formats, dst_type, dst_native_type, dst_suffix):
print
-def generate_write(formats, src_type, src_native_type, src_suffix):
+def generate_write(formats, src_channel, src_native_type, src_suffix):
'''Generate the dispatch function to write pixels to any format'''
for format in formats:
if is_format_supported(format):
- generate_format_write(format, src_type, src_native_type, src_suffix)
+ generate_format_write(format, src_channel, src_native_type, src_suffix)
print 'void'
print 'lp_tile_write_%s(enum pipe_format format, const %s *src, void *dst, unsigned dst_stride, unsigned x, unsigned y, unsigned w, unsigned h)' % (src_suffix, src_native_type)
@@ -309,7 +301,7 @@ def generate_write(formats, src_type, src_native_type, src_suffix):
for format in formats:
if is_format_supported(format):
print ' case %s:' % format.name
- print ' func = &lp_tile_%s_write_%s;' % (short_name(format), src_suffix)
+ print ' func = &lp_tile_%s_write_%s;' % (format.short_name(), src_suffix)
print ' break;'
print ' default:'
print ' debug_printf("unsupported format\\n");'
@@ -359,12 +351,12 @@ def main():
generate_clamp()
- type = Type(UNSIGNED, True, 8)
+ channel = Channel(UNSIGNED, True, 8)
native_type = 'uint8_t'
suffix = '4ub'
- generate_read(formats, type, native_type, suffix)
- generate_write(formats, type, native_type, suffix)
+ generate_read(formats, channel, native_type, suffix)
+ generate_write(formats, channel, native_type, suffix)
if __name__ == '__main__':