diff options
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_context.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_jit.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_rast.c | 198 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_rast.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_rast_priv.h | 20 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_scene.c | 12 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_scene.h | 7 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup.c | 1 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup_context.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup_line.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup_point.c | 7 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup_tri.c | 17 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_derived.c | 13 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_texture.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_texture.h | 10 |
15 files changed, 195 insertions, 110 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 54f38303ae5..abfe852bae5 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -119,6 +119,9 @@ struct llvmpipe_context { /** Which vertex shader output slot contains viewport index */ int viewport_index_slot; + /** Which geometry shader output slot contains layer */ + int layer_slot; + /**< minimum resolvable depth value, for polygon offset */ double mrd; diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h index 4e9ca764fe7..2ecfde75a09 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.h +++ b/src/gallium/drivers/llvmpipe/lp_jit.h @@ -204,7 +204,7 @@ typedef void const void *dadx, const void *dady, uint8_t **color, - void *depth, + uint8_t *depth, uint32_t mask, struct lp_jit_thread_data *thread_data, unsigned *stride, diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 981dd712126..dcd66ab00c1 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -109,6 +109,7 @@ 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. + * Clear commands always clear all bound layers. */ static void lp_rast_clear_color(struct lp_rasterizer_task *task, @@ -134,6 +135,8 @@ lp_rast_clear_color(struct lp_rasterizer_task *task, for (i = 0; i < scene->fb.nr_cbufs; i++) { enum pipe_format format = scene->fb.cbufs[i]->format; + unsigned layer; + uint8_t *map_layer = scene->cbufs[i].map; if (util_format_is_pure_sint(format)) { util_format_write_4i(format, arg.clear_color.i, 0, &uc, 0, 0, 0, 1, 1); @@ -143,14 +146,17 @@ lp_rast_clear_color(struct lp_rasterizer_task *task, util_format_write_4ui(format, arg.clear_color.ui, 0, &uc, 0, 0, 0, 1, 1); } - util_fill_rect(scene->cbufs[i].map, - scene->fb.cbufs[i]->format, - scene->cbufs[i].stride, - task->x, - task->y, - task->width, - task->height, - &uc); + for (layer = 0; layer <= scene->fb_max_layer; layer++) { + util_fill_rect(map_layer, + scene->fb.cbufs[i]->format, + scene->cbufs[i].stride, + task->x, + task->y, + task->width, + task->height, + &uc); + map_layer += scene->cbufs[i].layer_stride; + } } } else { @@ -167,18 +173,22 @@ lp_rast_clear_color(struct lp_rasterizer_task *task, clear_color[3]); for (i = 0; i < scene->fb.nr_cbufs; i++) { - - util_pack_color(arg.clear_color.f, - scene->fb.cbufs[i]->format, &uc); - - util_fill_rect(scene->cbufs[i].map, - scene->fb.cbufs[i]->format, - scene->cbufs[i].stride, - task->x, - task->y, - task->width, - task->height, - &uc); + unsigned layer; + uint8_t *map_layer = scene->cbufs[i].map; + + for (layer = 0; layer <= scene->fb_max_layer; layer++) { + util_pack_color(arg.clear_color.f, + scene->fb.cbufs[i]->format, &uc); + util_fill_rect(map_layer, + scene->fb.cbufs[i]->format, + scene->cbufs[i].stride, + task->x, + task->y, + task->width, + task->height, + &uc); + map_layer += scene->cbufs[i].layer_stride; + } } } } @@ -192,6 +202,7 @@ 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. + * Clear commands always clear all bound layers. */ static void lp_rast_clear_zstencil(struct lp_rasterizer_task *task, @@ -204,10 +215,10 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task, uint32_t clear_mask = (uint32_t) clear_mask64; const unsigned height = task->height; const unsigned width = task->width; - const unsigned block_size = scene->zsbuf.blocksize; const unsigned dst_stride = scene->zsbuf.stride; uint8_t *dst; unsigned i, j; + unsigned block_size; LP_DBG(DEBUG_RAST, "%s: value=0x%08x, mask=0x%08x\n", __FUNCTION__, clear_value, clear_mask); @@ -217,81 +228,87 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task, */ if (scene->fb.zsbuf) { - - dst = lp_rast_get_unswizzled_depth_tile_pointer(task, LP_TEX_USAGE_READ_WRITE); + unsigned layer; + uint8_t *dst_layer = lp_rast_get_unswizzled_depth_tile_pointer(task, LP_TEX_USAGE_READ_WRITE); + block_size = util_format_get_blocksize(scene->fb.zsbuf->format); clear_value &= clear_mask; - switch (block_size) { - case 1: - assert(clear_mask == 0xff); - memset(dst, (uint8_t) clear_value, height * width); - break; - case 2: - if (clear_mask == 0xffff) { - for (i = 0; i < height; i++) { - uint16_t *row = (uint16_t *)dst; - for (j = 0; j < width; j++) - *row++ = (uint16_t) clear_value; - dst += dst_stride; + for (layer = 0; layer <= scene->fb_max_layer; layer++) { + dst = dst_layer; + + switch (block_size) { + case 1: + assert(clear_mask == 0xff); + memset(dst, (uint8_t) clear_value, height * width); + break; + case 2: + if (clear_mask == 0xffff) { + for (i = 0; i < height; i++) { + uint16_t *row = (uint16_t *)dst; + for (j = 0; j < width; j++) + *row++ = (uint16_t) clear_value; + dst += dst_stride; + } } - } - else { - for (i = 0; i < height; i++) { - uint16_t *row = (uint16_t *)dst; - for (j = 0; j < width; j++) { - uint16_t tmp = ~clear_mask & *row; - *row++ = clear_value | tmp; + else { + for (i = 0; i < height; i++) { + uint16_t *row = (uint16_t *)dst; + for (j = 0; j < width; j++) { + uint16_t tmp = ~clear_mask & *row; + *row++ = clear_value | tmp; + } + dst += dst_stride; } - dst += dst_stride; } - } - break; - case 4: - if (clear_mask == 0xffffffff) { - for (i = 0; i < height; i++) { - uint32_t *row = (uint32_t *)dst; - for (j = 0; j < width; j++) - *row++ = clear_value; - dst += dst_stride; + break; + case 4: + if (clear_mask == 0xffffffff) { + for (i = 0; i < height; i++) { + uint32_t *row = (uint32_t *)dst; + for (j = 0; j < width; j++) + *row++ = clear_value; + dst += dst_stride; + } } - } - else { - for (i = 0; i < height; i++) { - uint32_t *row = (uint32_t *)dst; - for (j = 0; j < width; j++) { - uint32_t tmp = ~clear_mask & *row; - *row++ = clear_value | tmp; + else { + for (i = 0; i < height; i++) { + uint32_t *row = (uint32_t *)dst; + for (j = 0; j < width; j++) { + uint32_t tmp = ~clear_mask & *row; + *row++ = clear_value | tmp; + } + dst += dst_stride; } - dst += dst_stride; } - } - break; - case 8: - clear_value64 &= clear_mask64; - if (clear_mask64 == 0xffffffffffULL) { - for (i = 0; i < height; i++) { - uint64_t *row = (uint64_t *)dst; - for (j = 0; j < width; j++) - *row++ = clear_value64; - dst += dst_stride; + break; + case 8: + clear_value64 &= clear_mask64; + if (clear_mask64 == 0xffffffffffULL) { + for (i = 0; i < height; i++) { + uint64_t *row = (uint64_t *)dst; + for (j = 0; j < width; j++) + *row++ = clear_value64; + dst += dst_stride; + } } - } - else { - for (i = 0; i < height; i++) { - uint64_t *row = (uint64_t *)dst; - for (j = 0; j < width; j++) { - uint64_t tmp = ~clear_mask64 & *row; - *row++ = clear_value64 | tmp; + else { + for (i = 0; i < height; i++) { + uint64_t *row = (uint64_t *)dst; + for (j = 0; j < width; j++) { + uint64_t tmp = ~clear_mask64 & *row; + *row++ = clear_value64 | tmp; + } + dst += dst_stride; } - dst += dst_stride; } - } - break; + break; - default: - assert(0); - break; + default: + assert(0); + break; + } + dst_layer += scene->zsbuf.layer_stride; } } } @@ -340,17 +357,17 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task, /* color buffer */ for (i = 0; i < scene->fb.nr_cbufs; i++){ stride[i] = scene->cbufs[i].stride; - - color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, tile_x + x, tile_y + y); + color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, tile_x + x, + tile_y + y, inputs->layer); } /* depth buffer */ if (scene->zsbuf.map) { - depth = lp_rast_get_unswizzled_depth_block_pointer(task, tile_x + x, tile_y + y); + depth = lp_rast_get_unswizzled_depth_block_pointer(task, tile_x + x, + tile_y + y, inputs->layer); depth_stride = scene->zsbuf.stride; } - /* run shader on 4x4 block */ BEGIN_JIT_CALL(state, task); variant->jit_function[RAST_WHOLE]( &state->jit_context, @@ -408,7 +425,7 @@ lp_rast_shade_quads_mask(struct lp_rasterizer_task *task, const struct lp_scene *scene = task->scene; uint8_t *color[PIPE_MAX_COLOR_BUFS]; unsigned stride[PIPE_MAX_COLOR_BUFS]; - void *depth = NULL; + uint8_t *depth = NULL; unsigned depth_stride = 0; unsigned i; @@ -426,14 +443,13 @@ lp_rast_shade_quads_mask(struct lp_rasterizer_task *task, /* color buffer */ for (i = 0; i < scene->fb.nr_cbufs; i++) { stride[i] = scene->cbufs[i].stride; - - color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, x, y); + color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, x, y, inputs->layer); } /* depth buffer */ if (scene->zsbuf.map) { depth_stride = scene->zsbuf.stride; - depth = lp_rast_get_unswizzled_depth_block_pointer(task, x, y); + depth = lp_rast_get_unswizzled_depth_block_pointer(task, x, y, inputs->layer); } assert(lp_check_alignment(state->jit_context.u8_blend_color, 16)); diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index 9fe89e5b6f1..50917a7c633 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -86,8 +86,8 @@ struct lp_rast_shader_inputs { unsigned opaque:1; /** Is opaque */ unsigned pad0:29; /* wasted space */ unsigned stride; /* how much to advance data between a0, dadx, dady */ + unsigned layer; /* the layer to render to (from gs, already clamped) */ unsigned pad2; /* wasted space */ - unsigned pad3; /* wasted space */ /* followed by a0, dadx, dady and planes[] */ }; diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index 4876d7472fb..6f03023eafe 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -203,7 +203,8 @@ lp_rast_get_unswizzled_depth_tile_pointer(struct lp_rasterizer_task *task, */ static INLINE uint8_t * lp_rast_get_unswizzled_color_block_pointer(struct lp_rasterizer_task *task, - unsigned buf, unsigned x, unsigned y) + unsigned buf, unsigned x, unsigned y, + unsigned layer) { unsigned px, py, pixel_offset, format_bytes; uint8_t *color; @@ -225,6 +226,10 @@ lp_rast_get_unswizzled_color_block_pointer(struct lp_rasterizer_task *task, color = color + pixel_offset; + if (layer) { + color += layer * task->scene->cbufs[buf].layer_stride; + } + assert(lp_check_alignment(color, llvmpipe_get_format_alignment(task->scene->fb.cbufs[buf]->format))); return color; } @@ -236,7 +241,7 @@ lp_rast_get_unswizzled_color_block_pointer(struct lp_rasterizer_task *task, */ static INLINE uint8_t * lp_rast_get_unswizzled_depth_block_pointer(struct lp_rasterizer_task *task, - unsigned x, unsigned y) + unsigned x, unsigned y, unsigned layer) { unsigned px, py, pixel_offset, format_bytes; uint8_t *depth; @@ -257,6 +262,10 @@ lp_rast_get_unswizzled_depth_block_pointer(struct lp_rasterizer_task *task, depth = depth + pixel_offset; + if (layer) { + depth += layer * task->scene->zsbuf.layer_stride; + } + assert(lp_check_alignment(depth, llvmpipe_get_format_alignment(task->scene->fb.zsbuf->format))); return depth; } @@ -278,19 +287,18 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task, struct lp_fragment_shader_variant *variant = state->variant; uint8_t *color[PIPE_MAX_COLOR_BUFS]; unsigned stride[PIPE_MAX_COLOR_BUFS]; - void *depth = NULL; + uint8_t *depth = NULL; unsigned depth_stride = 0; unsigned i; /* color buffer */ for (i = 0; i < scene->fb.nr_cbufs; i++) { stride[i] = scene->cbufs[i].stride; - - color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, x, y); + color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, x, y, inputs->layer); } if (scene->zsbuf.map) { - depth = lp_rast_get_unswizzled_depth_block_pointer(task, x, y); + depth = lp_rast_get_unswizzled_depth_block_pointer(task, x, y, inputs->layer); depth_stride = scene->zsbuf.stride; } diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c index 771ad085a12..2abbd25f929 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene.c +++ b/src/gallium/drivers/llvmpipe/lp_scene.c @@ -151,6 +151,7 @@ lp_scene_begin_rasterization(struct lp_scene *scene) { const struct pipe_framebuffer_state *fb = &scene->fb; int i; + unsigned max_layer = ~0; //LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); @@ -159,6 +160,9 @@ lp_scene_begin_rasterization(struct lp_scene *scene) 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); + max_layer = MIN2(max_layer, cbuf->u.tex.last_layer - cbuf->u.tex.first_layer); scene->cbufs[i].map = llvmpipe_resource_map(cbuf->texture, cbuf->u.tex.level, @@ -169,6 +173,8 @@ lp_scene_begin_rasterization(struct lp_scene *scene) struct llvmpipe_resource *lpr = llvmpipe_resource(cbuf->texture); unsigned pixstride = util_format_get_blocksize(cbuf->format); scene->cbufs[i].stride = cbuf->texture->width0; + max_layer = 0; + scene->cbufs[i].map = lpr->data; scene->cbufs[i].map += cbuf->u.buf.first_element * pixstride; } @@ -177,14 +183,16 @@ lp_scene_begin_rasterization(struct lp_scene *scene) if (fb->zsbuf) { struct pipe_surface *zsbuf = scene->fb.zsbuf; scene->zsbuf.stride = llvmpipe_resource_stride(zsbuf->texture, zsbuf->u.tex.level); - scene->zsbuf.blocksize = - util_format_get_blocksize(zsbuf->texture->format); + scene->zsbuf.layer_stride = llvmpipe_layer_stride(zsbuf->texture, zsbuf->u.tex.level); + max_layer = MIN2(max_layer, zsbuf->u.tex.last_layer - zsbuf->u.tex.first_layer); scene->zsbuf.map = llvmpipe_resource_map(zsbuf->texture, zsbuf->u.tex.level, zsbuf->u.tex.first_layer, LP_TEX_USAGE_READ_WRITE); } + + scene->fb_max_layer = max_layer; } diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h index fa5bbcaf013..2d63c002ce2 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene.h +++ b/src/gallium/drivers/llvmpipe/lp_scene.h @@ -135,9 +135,12 @@ struct lp_scene { struct { uint8_t *map; unsigned stride; - unsigned blocksize; + unsigned layer_stride; } zsbuf, cbufs[PIPE_MAX_COLOR_BUFS]; - + + /* OpenGL permits different amount of layers per rt, but rendering limited to minimum */ + unsigned fb_max_layer; + /** the framebuffer to render the scene into */ struct pipe_framebuffer_state fb; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index bafcf56b803..e2fb257e1c1 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -1056,6 +1056,7 @@ lp_setup_update_state( struct lp_setup_context *setup, */ setup->psize = lp->psize_slot; setup->viewport_index_slot = lp->viewport_index_slot; + setup->layer_slot = lp->layer_slot; assert(lp->dirty == 0); diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 62d5a3c5796..cc2b97390c0 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -104,6 +104,7 @@ struct lp_setup_context float point_size; float psize; unsigned viewport_index_slot; + unsigned layer_slot; struct pipe_framebuffer_state fb; struct u_rect framebuffer; diff --git a/src/gallium/drivers/llvmpipe/lp_setup_line.c b/src/gallium/drivers/llvmpipe/lp_setup_line.c index 57a96d57ce7..a9809a0ed12 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_line.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_line.c @@ -290,6 +290,7 @@ try_setup_line( struct lp_setup_context *setup, int i; int nr_planes = 4; unsigned scissor_index = 0; + unsigned layer = 0; /* linewidth should be interpreted as integer */ int fixed_width = util_iround(width) * FIXED_ONE; @@ -325,6 +326,10 @@ try_setup_line( struct lp_setup_context *setup, nr_planes = 4; } + if (setup->layer_slot > 0) { + layer = *(unsigned*)v1[setup->layer_slot]; + layer = MIN2(layer, scene->fb_max_layer); + } dx = v1[0][0] - v2[0][0]; dy = v1[0][1] - v2[0][1]; @@ -616,6 +621,7 @@ try_setup_line( struct lp_setup_context *setup, line->inputs.frontfacing = TRUE; line->inputs.disable = FALSE; line->inputs.opaque = FALSE; + line->inputs.layer = layer; for (i = 0; i < 4; i++) { diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c b/src/gallium/drivers/llvmpipe/lp_setup_point.c index b8040ae56f6..789caa80761 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_point.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c @@ -325,11 +325,17 @@ try_setup_point( struct lp_setup_context *setup, unsigned nr_planes = 4; struct point_info info; unsigned scissor_index = 0; + unsigned layer = 0; if (setup->viewport_index_slot > 0) { unsigned *udata = (unsigned*)v0[setup->viewport_index_slot]; scissor_index = lp_clamp_scissor_idx(*udata); } + if (setup->layer_slot > 0) { + layer = *(unsigned*)v0[setup->layer_slot]; + layer = MIN2(layer, scene->fb_max_layer); + } + /* Bounding rectangle (in pixels) */ { /* Yes this is necessary to accurately calculate bounding boxes @@ -386,6 +392,7 @@ try_setup_point( struct lp_setup_context *setup, point->inputs.frontfacing = TRUE; point->inputs.disable = FALSE; point->inputs.opaque = FALSE; + point->inputs.layer = layer; { struct lp_rast_plane *plane = GET_PLANES(point); diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index e0aaa196c9a..2ca47bca43e 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -203,7 +203,14 @@ lp_setup_whole_tile(struct lp_setup_context *setup, LP_COUNT(nr_fully_covered_64); /* if variant is opaque and scissor doesn't effect the tile */ - if (inputs->opaque) { + /* + * Need to disable this optimization for layered rendering and cannot use + * setup->layer_slot here to determine it, because it could incorrectly + * reset the tile if a previous shader used layer_slot but not this one + * (or maybe even "undo" clears). So determine this from presence of layers + * instead (in which case layer_slot will have no effect). + */ + if (inputs->opaque && scene->fb_max_layer == 0) { if (!scene->fb.zsbuf) { /* * All previous rendering will be overwritten so reset the bin. @@ -247,6 +254,7 @@ do_triangle_ccw(struct lp_setup_context *setup, unsigned tri_bytes; int nr_planes = 3; unsigned scissor_index = 0; + unsigned layer = 0; /* Area should always be positive here */ assert(position->area > 0); @@ -264,6 +272,10 @@ do_triangle_ccw(struct lp_setup_context *setup, else { nr_planes = 3; } + if (setup->layer_slot > 0) { + layer = *(unsigned*)v1[setup->layer_slot]; + layer = MIN2(layer, scene->fb_max_layer); + } /* Bounding rectangle (in pixels) */ { @@ -334,6 +346,7 @@ do_triangle_ccw(struct lp_setup_context *setup, tri->inputs.frontfacing = frontfacing; tri->inputs.disable = FALSE; tri->inputs.opaque = setup->fs.current.variant->opaque; + tri->inputs.layer = layer; if (0) lp_dump_setup_coef(&setup->setup.variant->key, @@ -519,7 +532,7 @@ do_triangle_ccw(struct lp_setup_context *setup, plane[6].eo = 0; } - return lp_setup_bin_triangle( setup, tri, &bbox, nr_planes, scissor_index ); + return lp_setup_bin_triangle(setup, tri, &bbox, nr_planes, scissor_index); } /* diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index ea24ffcd6b6..dc80358c7be 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -126,7 +126,18 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe) } else { llvmpipe->viewport_index_slot = 0; } - + + /* Figure out if we need layer */ + vs_index = draw_find_shader_output(llvmpipe->draw, + TGSI_SEMANTIC_LAYER, + 0); + if (vs_index >= 0) { + llvmpipe->layer_slot = vinfo->num_attribs; + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index); + } else { + llvmpipe->layer_slot = 0; + } + draw_compute_vertex_size(vinfo); lp_setup_set_vertex_info(llvmpipe->setup, vinfo); diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index f1a1ed0960a..2263e0a5b47 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -496,14 +496,12 @@ llvmpipe_create_surface(struct pipe_context *pipe, ps->format = surf_tmpl->format; if (llvmpipe_resource_is_texture(pt)) { assert(surf_tmpl->u.tex.level <= pt->last_level); + assert(surf_tmpl->u.tex.first_layer <= surf_tmpl->u.tex.last_layer); ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level); ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level); ps->u.tex.level = surf_tmpl->u.tex.level; ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer; ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer; - if (ps->u.tex.first_layer != ps->u.tex.last_layer) { - debug_printf("creating surface with multiple layers, rendering to first layer only\n"); - } } else { /* setting width as number of elements should get us correct renderbuffer width */ @@ -520,7 +518,7 @@ llvmpipe_create_surface(struct pipe_context *pipe, } -static void +static void llvmpipe_surface_destroy(struct pipe_context *pipe, struct pipe_surface *surf) { diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h index e73d44946d2..2960574fb2c 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.h +++ b/src/gallium/drivers/llvmpipe/lp_texture.h @@ -181,6 +181,16 @@ llvmpipe_resource_is_1d(const struct pipe_resource *resource) static INLINE unsigned +llvmpipe_layer_stride(struct pipe_resource *resource, + unsigned level) +{ + struct llvmpipe_resource *lpr = llvmpipe_resource(resource); + assert(level < LP_MAX_TEXTURE_2D_LEVELS); + return lpr->img_stride[level]; +} + + +static INLINE unsigned llvmpipe_resource_stride(struct pipe_resource *resource, unsigned level) { |