llvmpipe: reorganize transfer usage
Move transfer creation and mapping to the "scene" object, and out of the rasterizer. The rasterizer operates on already-mapped framebuffers only, and no longer needs a screen or context pointer. The scene object has access to a pipe_context, and this reorg prepares for moving transfer functionality from the screen to the context.
This commit is contained in:
@@ -183,7 +183,7 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
|
||||
if (debug_get_bool_option( "LP_NO_RAST", FALSE ))
|
||||
llvmpipe->no_rast = TRUE;
|
||||
|
||||
llvmpipe->setup = lp_setup_create( screen,
|
||||
llvmpipe->setup = lp_setup_create( &llvmpipe->pipe,
|
||||
llvmpipe->draw );
|
||||
if (!llvmpipe->setup)
|
||||
goto fail;
|
||||
|
||||
@@ -42,114 +42,60 @@
|
||||
#include "lp_scene.h"
|
||||
|
||||
|
||||
/**
|
||||
* Begin the rasterization phase.
|
||||
* Map the framebuffer surfaces. Initialize the 'rast' state.
|
||||
/* Begin rasterizing a scene:
|
||||
*/
|
||||
static boolean
|
||||
lp_rast_begin( struct lp_rasterizer *rast,
|
||||
const struct pipe_framebuffer_state *fb,
|
||||
boolean write_color,
|
||||
boolean write_zstencil )
|
||||
struct lp_scene *scene )
|
||||
{
|
||||
struct pipe_screen *screen = rast->screen;
|
||||
struct pipe_surface *cbuf, *zsbuf;
|
||||
const struct pipe_framebuffer_state *fb = &scene->fb;
|
||||
boolean write_color = fb->nr_cbufs != 0;
|
||||
boolean write_zstencil = fb->zsbuf != NULL;
|
||||
int i;
|
||||
|
||||
rast->curr_scene = scene;
|
||||
|
||||
LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
|
||||
|
||||
util_copy_framebuffer_state(&rast->state.fb, fb);
|
||||
|
||||
rast->state.nr_cbufs = scene->fb.nr_cbufs;
|
||||
rast->state.write_zstencil = write_zstencil;
|
||||
rast->state.write_color = write_color;
|
||||
|
||||
rast->check_for_clipped_tiles = (fb->width % TILE_SIZE != 0 ||
|
||||
fb->height % TILE_SIZE != 0);
|
||||
|
||||
|
||||
for (i = 0; i < rast->state.fb.nr_cbufs; i++) {
|
||||
cbuf = rast->state.fb.cbufs[i];
|
||||
if (cbuf) {
|
||||
rast->cbuf_transfer[i] = screen->get_tex_transfer(rast->screen,
|
||||
cbuf->texture,
|
||||
cbuf->face,
|
||||
cbuf->level,
|
||||
cbuf->zslice,
|
||||
PIPE_TRANSFER_READ_WRITE,
|
||||
0, 0,
|
||||
cbuf->width,
|
||||
cbuf->height);
|
||||
if (!rast->cbuf_transfer[i])
|
||||
goto fail;
|
||||
|
||||
rast->cbuf_map[i] = screen->transfer_map(rast->screen,
|
||||
rast->cbuf_transfer[i]);
|
||||
if (!rast->cbuf_map[i])
|
||||
goto fail;
|
||||
}
|
||||
for (i = 0; i < rast->state.nr_cbufs; i++) {
|
||||
rast->cbuf[i].map = scene->cbuf_map[i];
|
||||
rast->cbuf[i].format = scene->cbuf_transfer[i]->texture->format;
|
||||
rast->cbuf[i].width = scene->cbuf_transfer[i]->width;
|
||||
rast->cbuf[i].height = scene->cbuf_transfer[i]->height;
|
||||
rast->cbuf[i].stride = scene->cbuf_transfer[i]->stride;
|
||||
}
|
||||
|
||||
zsbuf = rast->state.fb.zsbuf;
|
||||
if (zsbuf) {
|
||||
rast->zsbuf_transfer = screen->get_tex_transfer(rast->screen,
|
||||
zsbuf->texture,
|
||||
zsbuf->face,
|
||||
zsbuf->level,
|
||||
zsbuf->zslice,
|
||||
PIPE_TRANSFER_READ_WRITE,
|
||||
0, 0,
|
||||
zsbuf->width,
|
||||
zsbuf->height);
|
||||
if (!rast->zsbuf_transfer)
|
||||
goto fail;
|
||||
|
||||
rast->zsbuf_map = screen->transfer_map(rast->screen,
|
||||
rast->zsbuf_transfer);
|
||||
if (!rast->zsbuf_map)
|
||||
goto fail;
|
||||
if (write_zstencil) {
|
||||
rast->zsbuf.map = scene->zsbuf_map;
|
||||
rast->zsbuf.stride = scene->zsbuf_transfer->stride;
|
||||
rast->zsbuf.blocksize =
|
||||
util_format_get_blocksize(scene->zsbuf_transfer->texture->format);
|
||||
}
|
||||
|
||||
lp_scene_bin_iter_begin( scene );
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
/* Unmap and release transfers?
|
||||
*/
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finish the rasterization phase.
|
||||
* Unmap framebuffer surfaces.
|
||||
*/
|
||||
static void
|
||||
lp_rast_end( struct lp_rasterizer *rast )
|
||||
{
|
||||
struct pipe_screen *screen = rast->screen;
|
||||
unsigned i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rast->state.fb.nr_cbufs; i++) {
|
||||
if (rast->cbuf_map[i])
|
||||
screen->transfer_unmap(screen, rast->cbuf_transfer[i]);
|
||||
lp_scene_reset( rast->curr_scene );
|
||||
|
||||
if (rast->cbuf_transfer[i])
|
||||
screen->tex_transfer_destroy(rast->cbuf_transfer[i]);
|
||||
for (i = 0; i < rast->state.nr_cbufs; i++)
|
||||
rast->cbuf[i].map = NULL;
|
||||
|
||||
rast->cbuf_transfer[i] = NULL;
|
||||
rast->cbuf_map[i] = NULL;
|
||||
}
|
||||
|
||||
if (rast->zsbuf_map)
|
||||
screen->transfer_unmap(screen, rast->zsbuf_transfer);
|
||||
|
||||
if (rast->zsbuf_transfer)
|
||||
screen->tex_transfer_destroy(rast->zsbuf_transfer);
|
||||
|
||||
rast->zsbuf_transfer = NULL;
|
||||
rast->zsbuf_map = NULL;
|
||||
rast->zsbuf.map = NULL;
|
||||
rast->curr_scene = NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Begining rasterization of a tile.
|
||||
* \param x window X position of the tile, in pixels
|
||||
@@ -189,7 +135,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.fb.nr_cbufs; i++) {
|
||||
for (i = 0; i < rast->state.nr_cbufs; i++) {
|
||||
memset(color_tile[i], clear_color[0], TILE_SIZE * TILE_SIZE * 4);
|
||||
}
|
||||
}
|
||||
@@ -200,7 +146,7 @@ lp_rast_clear_color(struct lp_rasterizer_task *task,
|
||||
* works.
|
||||
*/
|
||||
const unsigned chunk = TILE_SIZE / 4;
|
||||
for (i = 0; i < rast->state.fb.nr_cbufs; i++) {
|
||||
for (i = 0; i < rast->state.nr_cbufs; i++) {
|
||||
uint8_t *c = color_tile[i];
|
||||
unsigned j;
|
||||
for (j = 0; j < 4 * TILE_SIZE; j++) {
|
||||
@@ -232,17 +178,17 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
|
||||
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;
|
||||
const unsigned width = TILE_SIZE*TILE_VECTOR_HEIGHT;
|
||||
unsigned block_size = util_format_get_blocksize(rast->zsbuf_transfer->texture->format);
|
||||
const unsigned height = TILE_SIZE / TILE_VECTOR_HEIGHT;
|
||||
const unsigned width = TILE_SIZE * TILE_VECTOR_HEIGHT;
|
||||
unsigned block_size = rast->zsbuf.blocksize;
|
||||
uint8_t *dst;
|
||||
unsigned dst_stride = rast->zsbuf_transfer->stride*TILE_VECTOR_HEIGHT;
|
||||
unsigned dst_stride = rast->zsbuf.stride * TILE_VECTOR_HEIGHT;
|
||||
unsigned i, j;
|
||||
|
||||
LP_DBG(DEBUG_RAST, "%s 0x%x\n", __FUNCTION__, arg.clear_zstencil);
|
||||
|
||||
assert(rast->zsbuf_map);
|
||||
if (!rast->zsbuf_map)
|
||||
assert(rast->zsbuf.map);
|
||||
if (!rast->zsbuf.map)
|
||||
return;
|
||||
|
||||
LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
|
||||
@@ -278,8 +224,8 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,25 +244,16 @@ lp_rast_load_color(struct lp_rasterizer_task *task,
|
||||
|
||||
LP_DBG(DEBUG_RAST, "%s at %u, %u\n", __FUNCTION__, x, y);
|
||||
|
||||
for (i = 0; i < rast->state.fb.nr_cbufs; i++) {
|
||||
struct pipe_transfer *transfer = rast->cbuf_transfer[i];
|
||||
int w = TILE_SIZE;
|
||||
int h = TILE_SIZE;
|
||||
|
||||
if (x >= transfer->width || y >= transfer->height)
|
||||
for (i = 0; i < rast->state.nr_cbufs; i++) {
|
||||
if (x >= rast->cbuf[i].width || y >= rast->cbuf[i].height)
|
||||
continue;
|
||||
|
||||
assert(w >= 0);
|
||||
assert(h >= 0);
|
||||
assert(w <= TILE_SIZE);
|
||||
assert(h <= TILE_SIZE);
|
||||
|
||||
lp_tile_read_4ub(transfer->texture->format,
|
||||
lp_tile_read_4ub(rast->cbuf[i].format,
|
||||
task->tile.color[i],
|
||||
rast->cbuf_map[i],
|
||||
transfer->stride,
|
||||
rast->cbuf[i].map,
|
||||
rast->cbuf[i].stride,
|
||||
x, y,
|
||||
w, h);
|
||||
TILE_SIZE, TILE_SIZE);
|
||||
|
||||
LP_COUNT(nr_color_tile_load);
|
||||
}
|
||||
@@ -366,7 +303,7 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task,
|
||||
block_offset = ((y / 4) * (16 * 16) + (x / 4) * 16);
|
||||
|
||||
/* color buffer */
|
||||
for (i = 0; i < rast->state.fb.nr_cbufs; i++)
|
||||
for (i = 0; i < rast->state.nr_cbufs; i++)
|
||||
color[i] = tile->color[i] + 4 * block_offset;
|
||||
|
||||
/* depth buffer */
|
||||
@@ -423,7 +360,7 @@ void lp_rast_shade_quads( struct lp_rasterizer_task *task,
|
||||
block_offset = ((iy / 4) * (16 * 16) + (ix / 4) * 16);
|
||||
|
||||
/* color buffer */
|
||||
for (i = 0; i < rast->state.fb.nr_cbufs; i++)
|
||||
for (i = 0; i < rast->state.nr_cbufs; i++)
|
||||
color[i] = tile->color[i] + 4 * block_offset;
|
||||
|
||||
/* depth buffer */
|
||||
@@ -516,51 +453,33 @@ lp_rast_store_color(struct lp_rasterizer_task *task)
|
||||
const unsigned x = task->x, y = task->y;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < rast->state.fb.nr_cbufs; i++) {
|
||||
struct pipe_transfer *transfer = rast->cbuf_transfer[i];
|
||||
int w = TILE_SIZE;
|
||||
int h = TILE_SIZE;
|
||||
|
||||
if (x >= transfer->width)
|
||||
for (i = 0; i < rast->state.nr_cbufs; i++) {
|
||||
if (x >= rast->cbuf[i].width)
|
||||
continue;
|
||||
|
||||
if (y >= transfer->height)
|
||||
if (y >= rast->cbuf[i].height)
|
||||
continue;
|
||||
|
||||
LP_DBG(DEBUG_RAST, "%s [%u] %d,%d %dx%d\n", __FUNCTION__,
|
||||
task->thread_index, x, y, w, h);
|
||||
LP_DBG(DEBUG_RAST, "%s [%u] %d,%d\n", __FUNCTION__,
|
||||
task->thread_index, x, y);
|
||||
|
||||
if (LP_DEBUG & DEBUG_SHOW_SUBTILES)
|
||||
outline_subtiles(task->tile.color[i]);
|
||||
else if (LP_DEBUG & DEBUG_SHOW_TILES)
|
||||
outline_tile(task->tile.color[i]);
|
||||
|
||||
lp_tile_write_4ub(transfer->texture->format,
|
||||
lp_tile_write_4ub(rast->cbuf[i].format,
|
||||
task->tile.color[i],
|
||||
rast->cbuf_map[i],
|
||||
transfer->stride,
|
||||
rast->cbuf[i].map,
|
||||
rast->cbuf[i].stride,
|
||||
x, y,
|
||||
w, h);
|
||||
TILE_SIZE, TILE_SIZE);
|
||||
|
||||
LP_COUNT(nr_color_tile_store);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write the rasterizer's tiles to the framebuffer.
|
||||
*/
|
||||
static void
|
||||
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(task);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Signal on a fence. This is called during bin execution/rasterization.
|
||||
@@ -586,23 +505,6 @@ lp_rast_fence(struct lp_rasterizer_task *task,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* When all the threads are done rasterizing a scene, one thread will
|
||||
* call this function to reset the scene and put it onto the empty queue.
|
||||
*/
|
||||
static void
|
||||
release_scene( struct lp_rasterizer *rast,
|
||||
struct lp_scene *scene )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -620,7 +522,7 @@ rasterize_bin(struct lp_rasterizer_task *task,
|
||||
struct cmd_block *block;
|
||||
unsigned k;
|
||||
|
||||
lp_rast_start_tile( task, x, y );
|
||||
lp_rast_start_tile( task, x * TILE_SIZE, y * TILE_SIZE );
|
||||
|
||||
/* simply execute each of the commands in the block list */
|
||||
for (block = commands->head; block; block = block->next) {
|
||||
@@ -629,7 +531,14 @@ rasterize_bin(struct lp_rasterizer_task *task,
|
||||
}
|
||||
}
|
||||
|
||||
lp_rast_end_tile( task );
|
||||
/* Write the rasterizer's tiles to the framebuffer.
|
||||
*/
|
||||
if (task->rast->state.write_color)
|
||||
lp_rast_store_color(task);
|
||||
|
||||
/* Free data for this bin.
|
||||
*/
|
||||
lp_scene_bin_reset( task->rast->curr_scene, x, y);
|
||||
}
|
||||
|
||||
|
||||
@@ -714,8 +623,7 @@ is_empty_bin( const struct cmd_bin *bin )
|
||||
*/
|
||||
static void
|
||||
rasterize_scene(struct lp_rasterizer_task *task,
|
||||
struct lp_scene *scene,
|
||||
bool write_depth)
|
||||
struct lp_scene *scene)
|
||||
{
|
||||
/* loop over scene bins, rasterize each */
|
||||
#if 0
|
||||
@@ -724,7 +632,7 @@ rasterize_scene(struct lp_rasterizer_task *task,
|
||||
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);
|
||||
rasterize_bin(task, bin, i * TILE_SIZE, j * TILE_SIZE);
|
||||
rasterize_bin(task, bin, i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -736,7 +644,7 @@ rasterize_scene(struct lp_rasterizer_task *task,
|
||||
assert(scene);
|
||||
while ((bin = lp_scene_bin_iter_next(scene, &x, &y))) {
|
||||
if (!is_empty_bin( bin ))
|
||||
rasterize_bin(task, bin, x * TILE_SIZE, y * TILE_SIZE);
|
||||
rasterize_bin(task, bin, x, y);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -747,44 +655,20 @@ rasterize_scene(struct lp_rasterizer_task *task,
|
||||
* Called by setup module when it has something for us to render.
|
||||
*/
|
||||
void
|
||||
lp_rasterize_scene( struct lp_rasterizer *rast,
|
||||
struct lp_scene *scene,
|
||||
const struct pipe_framebuffer_state *fb,
|
||||
bool write_depth )
|
||||
lp_rast_queue_scene( struct lp_rasterizer *rast,
|
||||
struct lp_scene *scene)
|
||||
{
|
||||
boolean debug = false;
|
||||
|
||||
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
|
||||
|
||||
if (debug) {
|
||||
unsigned x, y;
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* save framebuffer state in the bin */
|
||||
util_copy_framebuffer_state(&scene->fb, fb);
|
||||
scene->write_depth = write_depth;
|
||||
|
||||
if (rast->num_threads == 0) {
|
||||
/* no threading */
|
||||
|
||||
lp_rast_begin( rast, fb,
|
||||
fb->nr_cbufs != 0, /* always write color if cbufs present */
|
||||
fb->zsbuf != NULL && write_depth );
|
||||
lp_rast_begin( rast, scene );
|
||||
|
||||
lp_scene_bin_iter_begin( scene );
|
||||
rasterize_scene( &rast->tasks[0], scene, write_depth );
|
||||
rasterize_scene( &rast->tasks[0], scene );
|
||||
|
||||
release_scene( rast, scene );
|
||||
|
||||
lp_rast_end( rast );
|
||||
lp_scene_reset( scene );
|
||||
rast->curr_scene = NULL;
|
||||
}
|
||||
else {
|
||||
/* threaded rendering! */
|
||||
@@ -796,14 +680,26 @@ lp_rasterize_scene( struct lp_rasterizer *rast,
|
||||
for (i = 0; i < rast->num_threads; i++) {
|
||||
pipe_semaphore_signal(&rast->tasks[i].work_ready);
|
||||
}
|
||||
}
|
||||
|
||||
LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lp_rast_finish( struct lp_rasterizer *rast )
|
||||
{
|
||||
if (rast->num_threads == 0) {
|
||||
/* nothing to do */
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
|
||||
/* wait for work to complete */
|
||||
for (i = 0; i < rast->num_threads; i++) {
|
||||
pipe_semaphore_wait(&rast->tasks[i].work_done);
|
||||
}
|
||||
}
|
||||
|
||||
LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
@@ -834,19 +730,8 @@ static PIPE_THREAD_ROUTINE( thread_func, init_data )
|
||||
* - get next scene to rasterize
|
||||
* - map the framebuffer surfaces
|
||||
*/
|
||||
const struct pipe_framebuffer_state *fb;
|
||||
boolean write_depth;
|
||||
|
||||
rast->curr_scene = lp_scene_dequeue( rast->full_scenes, TRUE );
|
||||
|
||||
lp_scene_bin_iter_begin( rast->curr_scene );
|
||||
|
||||
fb = &rast->curr_scene->fb;
|
||||
write_depth = rast->curr_scene->write_depth;
|
||||
|
||||
lp_rast_begin( rast, fb,
|
||||
fb->nr_cbufs != 0,
|
||||
fb->zsbuf != NULL && write_depth );
|
||||
lp_rast_begin( rast,
|
||||
lp_scene_dequeue( rast->full_scenes, TRUE ) );
|
||||
}
|
||||
|
||||
/* Wait for all threads to get here so that threads[1+] don't
|
||||
@@ -857,25 +742,23 @@ static PIPE_THREAD_ROUTINE( thread_func, init_data )
|
||||
/* do work */
|
||||
if (debug)
|
||||
debug_printf("thread %d doing work\n", task->thread_index);
|
||||
|
||||
rasterize_scene(task,
|
||||
rast->curr_scene,
|
||||
rast->curr_scene->write_depth);
|
||||
rast->curr_scene);
|
||||
|
||||
/* wait for all threads to finish with this scene */
|
||||
pipe_barrier_wait( &rast->barrier );
|
||||
|
||||
/* XXX: shouldn't be necessary:
|
||||
*/
|
||||
if (task->thread_index == 0) {
|
||||
/* thread[0]:
|
||||
* - release the scene object
|
||||
* - unmap the framebuffer surfaces
|
||||
*/
|
||||
release_scene( rast, rast->curr_scene );
|
||||
lp_rast_end( rast );
|
||||
}
|
||||
|
||||
/* signal done with work */
|
||||
if (debug)
|
||||
debug_printf("thread %d done working\n", task->thread_index);
|
||||
|
||||
pipe_semaphore_signal(&task->work_done);
|
||||
}
|
||||
|
||||
@@ -918,7 +801,7 @@ create_rast_threads(struct lp_rasterizer *rast)
|
||||
* processing them.
|
||||
*/
|
||||
struct lp_rasterizer *
|
||||
lp_rast_create( struct pipe_screen *screen, struct lp_scene_queue *empty )
|
||||
lp_rast_create( void )
|
||||
{
|
||||
struct lp_rasterizer *rast;
|
||||
unsigned i, cbuf;
|
||||
@@ -927,9 +810,6 @@ lp_rast_create( struct pipe_screen *screen, struct lp_scene_queue *empty )
|
||||
if(!rast)
|
||||
return NULL;
|
||||
|
||||
rast->screen = screen;
|
||||
|
||||
rast->empty_scenes = empty;
|
||||
rast->full_scenes = lp_scene_queue_create();
|
||||
|
||||
for (i = 0; i < Elements(rast->tasks); i++) {
|
||||
@@ -957,8 +837,6 @@ void lp_rast_destroy( struct lp_rasterizer *rast )
|
||||
{
|
||||
unsigned i, cbuf;
|
||||
|
||||
util_unreference_framebuffer_state(&rast->state.fb);
|
||||
|
||||
for (i = 0; i < Elements(rast->tasks); i++) {
|
||||
for (cbuf = 0; cbuf < PIPE_MAX_COLOR_BUFS; cbuf++ )
|
||||
align_free(rast->tasks[i].tile.color[cbuf]);
|
||||
|
||||
@@ -43,10 +43,8 @@
|
||||
|
||||
struct lp_rasterizer;
|
||||
struct lp_scene;
|
||||
struct lp_scene_queue;
|
||||
struct lp_fence;
|
||||
struct cmd_bin;
|
||||
struct pipe_screen;
|
||||
|
||||
/** For sub-pixel positioning */
|
||||
#define FIXED_ORDER 4
|
||||
@@ -129,18 +127,21 @@ struct lp_rast_triangle {
|
||||
|
||||
|
||||
|
||||
struct lp_rasterizer *lp_rast_create( struct pipe_screen *screen,
|
||||
struct lp_scene_queue *empty );
|
||||
struct lp_rasterizer *
|
||||
lp_rast_create( void );
|
||||
|
||||
void lp_rast_destroy( struct lp_rasterizer * );
|
||||
void
|
||||
lp_rast_destroy( struct lp_rasterizer * );
|
||||
|
||||
unsigned lp_rast_get_num_threads( struct lp_rasterizer * );
|
||||
unsigned
|
||||
lp_rast_get_num_threads( struct lp_rasterizer * );
|
||||
|
||||
void lp_rasterize_scene( struct lp_rasterizer *rast,
|
||||
struct lp_scene *scene,
|
||||
const struct pipe_framebuffer_state *fb,
|
||||
bool write_depth );
|
||||
void
|
||||
lp_rast_queue_scene( struct lp_rasterizer *rast,
|
||||
struct lp_scene *scene );
|
||||
|
||||
void
|
||||
lp_rast_finish( struct lp_rasterizer *rast );
|
||||
|
||||
|
||||
union lp_rast_cmd_arg {
|
||||
|
||||
@@ -38,8 +38,6 @@
|
||||
#define MAX_THREADS 8 /* XXX probably temporary here */
|
||||
|
||||
|
||||
struct pipe_transfer;
|
||||
struct pipe_screen;
|
||||
struct lp_rasterizer;
|
||||
|
||||
|
||||
@@ -82,20 +80,26 @@ struct lp_rasterizer_task
|
||||
*/
|
||||
struct lp_rasterizer
|
||||
{
|
||||
boolean clipped_tile;
|
||||
boolean check_for_clipped_tiles;
|
||||
boolean exit_flag;
|
||||
|
||||
/* Framebuffer stuff
|
||||
*/
|
||||
struct pipe_screen *screen;
|
||||
struct pipe_transfer *cbuf_transfer[PIPE_MAX_COLOR_BUFS];
|
||||
struct pipe_transfer *zsbuf_transfer;
|
||||
void *cbuf_map[PIPE_MAX_COLOR_BUFS];
|
||||
uint8_t *zsbuf_map;
|
||||
struct {
|
||||
void *map;
|
||||
unsigned stride;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
enum pipe_format format;
|
||||
} cbuf[PIPE_MAX_COLOR_BUFS];
|
||||
|
||||
struct {
|
||||
struct pipe_framebuffer_state fb;
|
||||
uint8_t *map;
|
||||
unsigned stride;
|
||||
unsigned blocksize;
|
||||
} zsbuf;
|
||||
|
||||
struct {
|
||||
unsigned nr_cbufs;
|
||||
boolean write_color;
|
||||
boolean write_zstencil;
|
||||
unsigned clear_color;
|
||||
@@ -105,7 +109,14 @@ struct lp_rasterizer
|
||||
|
||||
/** The incoming queue of scenes ready to rasterize */
|
||||
struct lp_scene_queue *full_scenes;
|
||||
/** The outgoing queue of processed scenes to return to setup modulee */
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
@@ -137,17 +148,18 @@ lp_rast_depth_pointer( struct lp_rasterizer *rast,
|
||||
unsigned x, unsigned y )
|
||||
{
|
||||
void * depth;
|
||||
|
||||
assert((x % TILE_VECTOR_WIDTH) == 0);
|
||||
assert((y % TILE_VECTOR_HEIGHT) == 0);
|
||||
if(!rast->zsbuf_map)
|
||||
|
||||
if (!rast->zsbuf.map)
|
||||
return NULL;
|
||||
assert(rast->zsbuf_transfer);
|
||||
depth = rast->zsbuf_map +
|
||||
y*rast->zsbuf_transfer->stride +
|
||||
TILE_VECTOR_HEIGHT*x*util_format_get_blocksize(rast->zsbuf_transfer->texture->format);
|
||||
#ifdef DEBUG
|
||||
|
||||
depth = (rast->zsbuf.map +
|
||||
rast->zsbuf.stride * y +
|
||||
rast->zsbuf.blocksize * x * TILE_VECTOR_HEIGHT);
|
||||
|
||||
assert(lp_check_alignment(depth, 16));
|
||||
#endif
|
||||
return depth;
|
||||
}
|
||||
|
||||
@@ -175,7 +187,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
|
||||
block_offset = (iy / 4) * (16 * 16) + (ix / 4) * 16;
|
||||
|
||||
/* color buffer */
|
||||
for (i = 0; i < rast->state.fb.nr_cbufs; i++)
|
||||
for (i = 0; i < rast->state.nr_cbufs; i++)
|
||||
color[i] = tile->color[i] + 4 * block_offset;
|
||||
|
||||
depth = lp_rast_depth_pointer(rast, x, y);
|
||||
|
||||
@@ -29,37 +29,30 @@
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_simple_list.h"
|
||||
#include "util/u_surface.h"
|
||||
#include "lp_scene.h"
|
||||
#include "lp_scene_queue.h"
|
||||
#include "lp_debug.h"
|
||||
|
||||
|
||||
struct lp_scene *
|
||||
lp_scene_create(void)
|
||||
{
|
||||
struct lp_scene *scene = CALLOC_STRUCT(lp_scene);
|
||||
if (scene)
|
||||
lp_scene_init(scene);
|
||||
return scene;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lp_scene_destroy(struct lp_scene *scene)
|
||||
{
|
||||
lp_scene_reset(scene);
|
||||
lp_scene_free_bin_data(scene);
|
||||
FREE(scene);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lp_scene_init(struct lp_scene *scene)
|
||||
lp_scene_create( struct pipe_context *pipe,
|
||||
struct lp_scene_queue *queue )
|
||||
{
|
||||
unsigned i, j;
|
||||
for (i = 0; i < TILES_X; i++)
|
||||
struct lp_scene *scene = CALLOC_STRUCT(lp_scene);
|
||||
if (!scene)
|
||||
return NULL;
|
||||
|
||||
scene->pipe = pipe;
|
||||
scene->empty_queue = queue;
|
||||
|
||||
for (i = 0; i < TILES_X; i++) {
|
||||
for (j = 0; j < TILES_Y; j++) {
|
||||
struct cmd_bin *bin = lp_scene_get_bin(scene, i, j);
|
||||
bin->commands.head = bin->commands.tail = CALLOC_STRUCT(cmd_block);
|
||||
}
|
||||
}
|
||||
|
||||
scene->data.head =
|
||||
scene->data.tail = CALLOC_STRUCT(data_block);
|
||||
@@ -67,6 +60,36 @@ lp_scene_init(struct lp_scene *scene)
|
||||
make_empty_list(&scene->textures);
|
||||
|
||||
pipe_mutex_init(scene->mutex);
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Free all data associated with the given scene, and free(scene).
|
||||
*/
|
||||
void
|
||||
lp_scene_destroy(struct lp_scene *scene)
|
||||
{
|
||||
unsigned i, j;
|
||||
|
||||
lp_scene_reset(scene);
|
||||
|
||||
for (i = 0; i < TILES_X; i++)
|
||||
for (j = 0; j < TILES_Y; j++) {
|
||||
struct cmd_bin *bin = lp_scene_get_bin(scene, i, j);
|
||||
assert(bin->commands.head == bin->commands.tail);
|
||||
FREE(bin->commands.head);
|
||||
bin->commands.head = NULL;
|
||||
bin->commands.tail = NULL;
|
||||
}
|
||||
|
||||
FREE(scene->data.head);
|
||||
scene->data.head = NULL;
|
||||
|
||||
pipe_mutex_destroy(scene->mutex);
|
||||
|
||||
FREE(scene);
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +115,9 @@ lp_scene_is_empty(struct lp_scene *scene )
|
||||
}
|
||||
|
||||
|
||||
/* Free data for one particular bin. May be called from the
|
||||
* rasterizer thread(s).
|
||||
*/
|
||||
void
|
||||
lp_scene_bin_reset(struct lp_scene *scene, unsigned x, unsigned y)
|
||||
{
|
||||
@@ -115,7 +141,8 @@ lp_scene_bin_reset(struct lp_scene *scene, unsigned x, unsigned y)
|
||||
|
||||
|
||||
/**
|
||||
* Set scene to empty state.
|
||||
* Free all the temporary data in a scene. May be called from the
|
||||
* rasterizer thread(s).
|
||||
*/
|
||||
void
|
||||
lp_scene_reset(struct lp_scene *scene )
|
||||
@@ -162,40 +189,8 @@ lp_scene_reset(struct lp_scene *scene )
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Free all data associated with the given bin, but don't free(scene).
|
||||
*/
|
||||
void
|
||||
lp_scene_free_bin_data(struct lp_scene *scene)
|
||||
{
|
||||
unsigned i, j;
|
||||
|
||||
for (i = 0; i < TILES_X; i++)
|
||||
for (j = 0; j < TILES_Y; j++) {
|
||||
struct cmd_bin *bin = lp_scene_get_bin(scene, i, j);
|
||||
/* lp_reset_scene() should have been already called */
|
||||
assert(bin->commands.head == bin->commands.tail);
|
||||
FREE(bin->commands.head);
|
||||
bin->commands.head = NULL;
|
||||
bin->commands.tail = NULL;
|
||||
}
|
||||
|
||||
FREE(scene->data.head);
|
||||
scene->data.head = NULL;
|
||||
|
||||
pipe_mutex_destroy(scene->mutex);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lp_scene_set_framebuffer_size( struct lp_scene *scene,
|
||||
unsigned width, unsigned height )
|
||||
{
|
||||
assert(lp_scene_is_empty(scene));
|
||||
|
||||
scene->tiles_x = align(width, TILE_SIZE) / TILE_SIZE;
|
||||
scene->tiles_y = align(height, TILE_SIZE) / TILE_SIZE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
@@ -393,3 +388,158 @@ end:
|
||||
pipe_mutex_unlock(scene->mutex);
|
||||
return bin;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prepare this scene for the rasterizer.
|
||||
* Map the framebuffer surfaces. Initialize the 'rast' state.
|
||||
*/
|
||||
static boolean
|
||||
lp_scene_map_buffers( struct lp_scene *scene )
|
||||
{
|
||||
struct pipe_screen *screen = scene->pipe->screen;
|
||||
struct pipe_surface *cbuf, *zsbuf;
|
||||
int i;
|
||||
|
||||
LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
|
||||
|
||||
|
||||
/* Map all color buffers
|
||||
*/
|
||||
for (i = 0; i < scene->fb.nr_cbufs; i++) {
|
||||
cbuf = scene->fb.cbufs[i];
|
||||
if (cbuf) {
|
||||
scene->cbuf_transfer[i] = screen->get_tex_transfer(screen,
|
||||
cbuf->texture,
|
||||
cbuf->face,
|
||||
cbuf->level,
|
||||
cbuf->zslice,
|
||||
PIPE_TRANSFER_READ_WRITE,
|
||||
0, 0,
|
||||
cbuf->width,
|
||||
cbuf->height);
|
||||
if (!scene->cbuf_transfer[i])
|
||||
goto fail;
|
||||
|
||||
scene->cbuf_map[i] = screen->transfer_map(screen,
|
||||
scene->cbuf_transfer[i]);
|
||||
if (!scene->cbuf_map[i])
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* Map the zsbuffer
|
||||
*/
|
||||
zsbuf = scene->fb.zsbuf;
|
||||
if (zsbuf) {
|
||||
scene->zsbuf_transfer = screen->get_tex_transfer(screen,
|
||||
zsbuf->texture,
|
||||
zsbuf->face,
|
||||
zsbuf->level,
|
||||
zsbuf->zslice,
|
||||
PIPE_TRANSFER_READ_WRITE,
|
||||
0, 0,
|
||||
zsbuf->width,
|
||||
zsbuf->height);
|
||||
if (!scene->zsbuf_transfer)
|
||||
goto fail;
|
||||
|
||||
scene->zsbuf_map = screen->transfer_map(screen,
|
||||
scene->zsbuf_transfer);
|
||||
if (!scene->zsbuf_map)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
/* Unmap and release transfers?
|
||||
*/
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Called after rasterizer as finished rasterizing a scene.
|
||||
*
|
||||
* We want to call this from the pipe_context's current thread to
|
||||
* avoid having to have mutexes on the transfer functions.
|
||||
*/
|
||||
static void
|
||||
lp_scene_unmap_buffers( struct lp_scene *scene )
|
||||
{
|
||||
struct pipe_screen *screen = scene->pipe->screen;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < scene->fb.nr_cbufs; i++) {
|
||||
if (scene->cbuf_map[i])
|
||||
screen->transfer_unmap(screen, scene->cbuf_transfer[i]);
|
||||
|
||||
if (scene->cbuf_transfer[i])
|
||||
screen->tex_transfer_destroy(scene->cbuf_transfer[i]);
|
||||
|
||||
scene->cbuf_transfer[i] = NULL;
|
||||
scene->cbuf_map[i] = NULL;
|
||||
}
|
||||
|
||||
if (scene->zsbuf_map)
|
||||
screen->transfer_unmap(screen, scene->zsbuf_transfer);
|
||||
|
||||
if (scene->zsbuf_transfer)
|
||||
screen->tex_transfer_destroy(scene->zsbuf_transfer);
|
||||
|
||||
scene->zsbuf_transfer = NULL;
|
||||
scene->zsbuf_map = NULL;
|
||||
|
||||
util_unreference_framebuffer_state( &scene->fb );
|
||||
}
|
||||
|
||||
|
||||
void lp_scene_begin_binning( struct lp_scene *scene,
|
||||
struct pipe_framebuffer_state *fb )
|
||||
{
|
||||
assert(lp_scene_is_empty(scene));
|
||||
|
||||
util_copy_framebuffer_state(&scene->fb, fb);
|
||||
|
||||
scene->tiles_x = align(fb->width, TILE_SIZE) / TILE_SIZE;
|
||||
scene->tiles_y = align(fb->height, TILE_SIZE) / TILE_SIZE;
|
||||
}
|
||||
|
||||
|
||||
void lp_scene_rasterize( struct lp_scene *scene,
|
||||
struct lp_rasterizer *rast,
|
||||
boolean write_depth )
|
||||
{
|
||||
if (0) {
|
||||
unsigned x, y;
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
scene->write_depth = (scene->fb.zsbuf != NULL &&
|
||||
write_depth);
|
||||
|
||||
lp_scene_map_buffers( 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 );
|
||||
lp_scene_unmap_buffers( scene );
|
||||
lp_scene_enqueue( scene->empty_queue, scene );
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "lp_tile_soa.h"
|
||||
#include "lp_rast.h"
|
||||
|
||||
struct lp_scene_queue;
|
||||
|
||||
/* We're limited to 2K by 2K for 32bit fixed point rasterization.
|
||||
* Will need a 64-bit version for larger framebuffers.
|
||||
@@ -112,8 +113,14 @@ struct texture_ref {
|
||||
* scenes:
|
||||
*/
|
||||
struct lp_scene {
|
||||
struct cmd_bin tile[TILES_X][TILES_Y];
|
||||
struct data_block_list data;
|
||||
struct pipe_context *pipe;
|
||||
struct pipe_transfer *cbuf_transfer[PIPE_MAX_COLOR_BUFS];
|
||||
struct pipe_transfer *zsbuf_transfer;
|
||||
|
||||
/* Scene's buffers are mapped at the time the scene is enqueued:
|
||||
*/
|
||||
void *cbuf_map[PIPE_MAX_COLOR_BUFS];
|
||||
uint8_t *zsbuf_map;
|
||||
|
||||
/** the framebuffer to render the scene into */
|
||||
struct pipe_framebuffer_state fb;
|
||||
@@ -131,25 +138,28 @@ 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(void);
|
||||
struct lp_scene *lp_scene_create(struct pipe_context *pipe,
|
||||
struct lp_scene_queue *empty_queue);
|
||||
|
||||
void lp_scene_destroy(struct lp_scene *scene);
|
||||
|
||||
|
||||
void lp_scene_init(struct lp_scene *scene);
|
||||
|
||||
boolean lp_scene_is_empty(struct lp_scene *scene );
|
||||
|
||||
void lp_scene_reset(struct lp_scene *scene );
|
||||
|
||||
void lp_scene_free_bin_data(struct lp_scene *scene);
|
||||
|
||||
void lp_scene_set_framebuffer_size( struct lp_scene *scene,
|
||||
unsigned width, unsigned height );
|
||||
|
||||
void lp_bin_new_data_block( struct data_block_list *list );
|
||||
|
||||
@@ -296,5 +306,13 @@ 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 );
|
||||
|
||||
void
|
||||
lp_scene_rasterize( struct lp_scene *scene,
|
||||
struct lp_rasterizer *rast,
|
||||
boolean write_depth );
|
||||
|
||||
void
|
||||
lp_scene_begin_binning( struct lp_scene *scene,
|
||||
struct pipe_framebuffer_state *fb );
|
||||
|
||||
#endif /* LP_BIN_H */
|
||||
|
||||
@@ -66,11 +66,8 @@ lp_setup_get_current_scene(struct setup_context *setup)
|
||||
|
||||
assert(lp_scene_is_empty(setup->scene));
|
||||
|
||||
if(0)lp_scene_reset( setup->scene ); /* XXX temporary? */
|
||||
|
||||
lp_scene_set_framebuffer_size(setup->scene,
|
||||
setup->fb.width,
|
||||
setup->fb.height);
|
||||
lp_scene_begin_binning(setup->scene,
|
||||
&setup->fb );
|
||||
}
|
||||
return setup->scene;
|
||||
}
|
||||
@@ -135,13 +132,12 @@ static void reset_context( struct setup_context *setup )
|
||||
/** Rasterize all scene's bins */
|
||||
static void
|
||||
lp_setup_rasterize_scene( struct setup_context *setup,
|
||||
boolean write_depth )
|
||||
boolean write_depth )
|
||||
{
|
||||
struct lp_scene *scene = lp_setup_get_current_scene(setup);
|
||||
|
||||
lp_rasterize_scene(setup->rast,
|
||||
scene,
|
||||
&setup->fb,
|
||||
lp_scene_rasterize(scene,
|
||||
setup->rast,
|
||||
write_depth);
|
||||
|
||||
reset_context( setup );
|
||||
@@ -246,19 +242,16 @@ void
|
||||
lp_setup_bind_framebuffer( struct setup_context *setup,
|
||||
const struct pipe_framebuffer_state *fb )
|
||||
{
|
||||
struct lp_scene *scene = lp_setup_get_current_scene(setup);
|
||||
|
||||
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
|
||||
|
||||
/* Flush any old scene.
|
||||
*/
|
||||
set_scene_state( setup, SETUP_FLUSHED );
|
||||
|
||||
/* re-get scene pointer, may have a new scene after flushing */
|
||||
(void) scene;
|
||||
scene = lp_setup_get_current_scene(setup);
|
||||
|
||||
/* Set new state. This will be picked up later when we next need a
|
||||
* scene.
|
||||
*/
|
||||
util_copy_framebuffer_state(&setup->fb, fb);
|
||||
|
||||
lp_scene_set_framebuffer_size(scene, setup->fb.width, setup->fb.height);
|
||||
}
|
||||
|
||||
|
||||
@@ -683,7 +676,7 @@ lp_setup_destroy( struct setup_context *setup )
|
||||
* it.
|
||||
*/
|
||||
struct setup_context *
|
||||
lp_setup_create( struct pipe_screen *screen,
|
||||
lp_setup_create( struct pipe_context *pipe,
|
||||
struct draw_context *draw )
|
||||
{
|
||||
unsigned i;
|
||||
@@ -698,7 +691,9 @@ lp_setup_create( struct pipe_screen *screen,
|
||||
if (!setup->empty_scenes)
|
||||
goto fail;
|
||||
|
||||
setup->rast = lp_rast_create( screen, setup->empty_scenes );
|
||||
/* XXX: move this to the screen and share between contexts:
|
||||
*/
|
||||
setup->rast = lp_rast_create();
|
||||
if (!setup->rast)
|
||||
goto fail;
|
||||
|
||||
@@ -711,7 +706,8 @@ lp_setup_create( struct pipe_screen *screen,
|
||||
|
||||
/* create some empty scenes */
|
||||
for (i = 0; i < MAX_SCENES; i++) {
|
||||
setup->scenes[i] = lp_scene_create();
|
||||
setup->scenes[i] = lp_scene_create( pipe, setup->empty_scenes );
|
||||
|
||||
lp_scene_enqueue(setup->empty_scenes, setup->scenes[i]);
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ struct lp_fragment_shader;
|
||||
struct lp_jit_context;
|
||||
|
||||
struct setup_context *
|
||||
lp_setup_create( struct pipe_screen *screen,
|
||||
lp_setup_create( struct pipe_context *pipe,
|
||||
struct draw_context *draw );
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user