X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fllvmpipe%2Flp_scene.c;h=59eed4145504942a08f6250f37cb72dd2af5ebb3;hb=0dac24790e7386a51f1d513762ef08ca20ed994d;hp=a4fdf7cff3626f8d3bf9587f988cef2b9523b285;hpb=4926c5748028d33da4808f8a5473aa7b2f2bdc62;p=mesa.git diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c index a4fdf7cff36..59eed414550 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene.c +++ b/src/gallium/drivers/llvmpipe/lp_scene.c @@ -29,8 +29,8 @@ #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_inlines.h" -#include "util/u_simple_list.h" -#include "util/u_format.h" +#include "util/simple_list.h" +#include "util/format/u_format.h" #include "lp_scene.h" #include "lp_fence.h" #include "lp_debug.h" @@ -62,7 +62,22 @@ lp_scene_create( struct pipe_context *pipe ) scene->data.head = CALLOC_STRUCT(data_block); - pipe_mutex_init(scene->mutex); + (void) mtx_init(&scene->mutex, mtx_plain); + +#ifdef DEBUG + /* Do some scene limit sanity checks here */ + { + size_t maxBins = TILES_X * TILES_Y; + size_t maxCommandBytes = sizeof(struct cmd_block) * maxBins; + size_t maxCommandPlusData = maxCommandBytes + DATA_BLOCK_SIZE; + /* We'll need at least one command block per bin. Make sure that's + * less than the max allowed scene size. + */ + assert(maxCommandBytes < LP_SCENE_MAX_SIZE); + /* We'll also need space for at least one other data block */ + assert(maxCommandPlusData <= LP_SCENE_MAX_SIZE); + } +#endif return scene; } @@ -74,7 +89,8 @@ lp_scene_create( struct pipe_context *pipe ) void lp_scene_destroy(struct lp_scene *scene) { - pipe_mutex_destroy(scene->mutex); + lp_fence_reference(&scene->fence, NULL); + mtx_destroy(&scene->mutex); assert(scene->data.head->next == NULL); FREE(scene->data.head); FREE(scene); @@ -90,8 +106,8 @@ lp_scene_is_empty(struct lp_scene *scene ) { unsigned x, y; - for (y = 0; y < TILES_Y; y++) { - for (x = 0; x < TILES_X; x++) { + for (y = 0; y < scene->tiles_y; y++) { + for (x = 0; x < scene->tiles_x; x++) { const struct cmd_bin *bin = lp_scene_get_bin(scene, x, y); if (bin->head) { return FALSE; @@ -121,6 +137,7 @@ lp_scene_bin_reset(struct lp_scene *scene, unsigned x, unsigned y) { struct cmd_bin *bin = lp_scene_get_bin(scene, x, y); + bin->last_state = NULL; bin->head = bin->tail; if (bin->tail) { bin->tail->next = NULL; @@ -136,32 +153,57 @@ lp_scene_begin_rasterization(struct lp_scene *scene) 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 (!cbuf) { + scene->cbufs[i].stride = 0; + scene->cbufs[i].layer_stride = 0; + scene->cbufs[i].sample_stride = 0; + scene->cbufs[i].nr_samples = 0; + scene->cbufs[i].map = NULL; + continue; + } + + if (llvmpipe_resource_is_texture(cbuf->texture)) { + scene->cbufs[i].stride = llvmpipe_resource_stride(cbuf->texture, + cbuf->u.tex.level); + scene->cbufs[i].layer_stride = llvmpipe_layer_stride(cbuf->texture, + cbuf->u.tex.level); + scene->cbufs[i].sample_stride = llvmpipe_sample_stride(cbuf->texture); + + scene->cbufs[i].map = llvmpipe_resource_map(cbuf->texture, + cbuf->u.tex.level, + cbuf->u.tex.first_layer, + LP_TEX_USAGE_READ_WRITE); + scene->cbufs[i].format_bytes = util_format_get_blocksize(cbuf->format); + scene->cbufs[i].nr_samples = util_res_sample_count(cbuf->texture); + } + else { + struct llvmpipe_resource *lpr = llvmpipe_resource(cbuf->texture); + unsigned pixstride = util_format_get_blocksize(cbuf->format); + scene->cbufs[i].stride = cbuf->texture->width0; + scene->cbufs[i].layer_stride = 0; + scene->cbufs[i].sample_stride = 0; + scene->cbufs[i].nr_samples = 1; + scene->cbufs[i].map = lpr->data; + scene->cbufs[i].map += cbuf->u.buf.first_element * pixstride; + scene->cbufs[i].format_bytes = util_format_get_blocksize(cbuf->format); + } } 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.stride = llvmpipe_resource_stride(zsbuf->texture, zsbuf->u.tex.level); + scene->zsbuf.layer_stride = llvmpipe_layer_stride(zsbuf->texture, zsbuf->u.tex.level); + scene->zsbuf.sample_stride = llvmpipe_sample_stride(zsbuf->texture); + scene->zsbuf.nr_samples = util_res_sample_count(zsbuf->texture); scene->zsbuf.map = llvmpipe_resource_map(zsbuf->texture, - zsbuf->face, - zsbuf->level, - zsbuf->zslice, - LP_TEX_USAGE_READ_WRITE, - LP_TEX_LAYOUT_NONE); + zsbuf->u.tex.level, + zsbuf->u.tex.first_layer, + LP_TEX_USAGE_READ_WRITE); + scene->zsbuf.format_bytes = util_format_get_blocksize(zsbuf->format); } } @@ -180,10 +222,11 @@ lp_scene_end_rasterization(struct lp_scene *scene ) for (i = 0; i < scene->fb.nr_cbufs; i++) { if (scene->cbufs[i].map) { struct pipe_surface *cbuf = scene->fb.cbufs[i]; - llvmpipe_resource_unmap(cbuf->texture, - cbuf->face, - cbuf->level, - cbuf->zslice); + if (llvmpipe_resource_is_texture(cbuf->texture)) { + llvmpipe_resource_unmap(cbuf->texture, + cbuf->u.tex.level, + cbuf->u.tex.first_layer); + } scene->cbufs[i].map = NULL; } } @@ -192,9 +235,8 @@ lp_scene_end_rasterization(struct lp_scene *scene ) if (scene->zsbuf.map) { struct pipe_surface *zsbuf = scene->fb.zsbuf; llvmpipe_resource_unmap(zsbuf->texture, - zsbuf->face, - zsbuf->level, - zsbuf->zslice); + zsbuf->u.tex.level, + zsbuf->u.tex.first_layer); scene->zsbuf.map = NULL; } @@ -260,7 +302,6 @@ lp_scene_end_rasterization(struct lp_scene *scene ) scene->scene_size = 0; scene->resource_reference_size = 0; - scene->has_depthstencil_clear = FALSE; scene->alloc_failed = FALSE; util_unreference_framebuffer_state( &scene->fb ); @@ -303,7 +344,7 @@ lp_scene_new_data_block( struct lp_scene *scene ) } else { struct data_block *block = MALLOC_STRUCT(data_block); - if (block == NULL) + if (!block) return NULL; scene->scene_size += sizeof *block; @@ -446,11 +487,11 @@ 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 ) +lp_scene_bin_iter_next( struct lp_scene *scene , int *x, int *y) { struct cmd_bin *bin = NULL; - pipe_mutex_lock(scene->mutex); + mtx_lock(&scene->mutex); if (scene->curr_x < 0) { /* first bin */ @@ -463,26 +504,61 @@ lp_scene_bin_iter_next( struct lp_scene *scene ) } bin = lp_scene_get_bin(scene, scene->curr_x, scene->curr_y); + *x = scene->curr_x; + *y = scene->curr_y; end: /*printf("return bin %p at %d, %d\n", (void *) bin, *bin_x, *bin_y);*/ - pipe_mutex_unlock(scene->mutex); + mtx_unlock(&scene->mutex); return bin; } -void lp_scene_begin_binning( struct lp_scene *scene, - struct pipe_framebuffer_state *fb ) +void lp_scene_begin_binning(struct lp_scene *scene, + struct pipe_framebuffer_state *fb) { + int i; + unsigned max_layer = ~0; + 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; - assert(scene->tiles_x <= TILES_X); assert(scene->tiles_y <= TILES_Y); + + /* + * Determine how many layers the fb has (used for clamping layer value). + * OpenGL (but not d3d10) permits different amount of layers per rt, however + * results are undefined if layer exceeds the amount of layers of ANY + * attachment hence don't need separate per cbuf and zsbuf max. + */ + for (i = 0; i < scene->fb.nr_cbufs; i++) { + struct pipe_surface *cbuf = scene->fb.cbufs[i]; + if (cbuf) { + if (llvmpipe_resource_is_texture(cbuf->texture)) { + max_layer = MIN2(max_layer, + cbuf->u.tex.last_layer - cbuf->u.tex.first_layer); + } + else { + max_layer = 0; + } + } + } + if (fb->zsbuf) { + struct pipe_surface *zsbuf = scene->fb.zsbuf; + max_layer = MIN2(max_layer, zsbuf->u.tex.last_layer - zsbuf->u.tex.first_layer); + } + scene->fb_max_layer = max_layer; + scene->fb_max_samples = util_framebuffer_get_num_samples(fb); + if (scene->fb_max_samples == 4) { + for (unsigned i = 0; i < 4; i++) { + scene->fixed_sample_pos[i][0] = util_iround(lp_sample_pos_4x[i][0] * FIXED_ONE); + scene->fixed_sample_pos[i][1] = util_iround(lp_sample_pos_4x[i][1] * FIXED_ONE); + } + } }