Am 23.05.2013 22:33, schrieb Zack Rusin: > Largely related to making sure the rasterizer can correctly > pick out the correct scissor box for the current viewport. > > Signed-off-by: Zack Rusin <za...@vmware.com> > --- > src/gallium/drivers/llvmpipe/lp_context.h | 9 ++++-- > src/gallium/drivers/llvmpipe/lp_screen.c | 2 +- > src/gallium/drivers/llvmpipe/lp_setup.c | 34 > +++++++++++++++-------- > src/gallium/drivers/llvmpipe/lp_setup.h | 5 ++-- > src/gallium/drivers/llvmpipe/lp_setup_context.h | 9 ++++-- > src/gallium/drivers/llvmpipe/lp_setup_line.c | 12 ++++++-- > src/gallium/drivers/llvmpipe/lp_setup_point.c | 12 +++++--- > src/gallium/drivers/llvmpipe/lp_setup_tri.c | 17 ++++++++---- > src/gallium/drivers/llvmpipe/lp_state_clip.c | 8 ++++-- > src/gallium/drivers/llvmpipe/lp_state_derived.c | 15 +++++++++- > src/gallium/drivers/llvmpipe/lp_surface.c | 4 +-- > 11 files changed, 91 insertions(+), 36 deletions(-) > > diff --git a/src/gallium/drivers/llvmpipe/lp_context.h > b/src/gallium/drivers/llvmpipe/lp_context.h > index d605dba..444c768 100644 > --- a/src/gallium/drivers/llvmpipe/lp_context.h > +++ b/src/gallium/drivers/llvmpipe/lp_context.h > @@ -75,10 +75,12 @@ struct llvmpipe_context { > struct pipe_constant_buffer > constants[PIPE_SHADER_TYPES][LP_MAX_TGSI_CONST_BUFFERS]; > struct pipe_framebuffer_state framebuffer; > struct pipe_poly_stipple poly_stipple; > - struct pipe_scissor_state scissor; > + struct pipe_scissor_state scissors[PIPE_MAX_VIEWPORTS]; > + unsigned num_scissors; > struct pipe_sampler_view > *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS]; > > - struct pipe_viewport_state viewport; > + struct pipe_viewport_state viewports[PIPE_MAX_VIEWPORTS]; > + unsigned num_viewports; > struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; > struct pipe_index_buffer index_buffer; > struct pipe_resource *mapped_vs_tex[PIPE_MAX_SHADER_SAMPLER_VIEWS]; > @@ -116,6 +118,9 @@ struct llvmpipe_context { > /** Which vertex shader output slot contains point size */ > int psize_slot; > > + /** Which vertex shader output slot contains viewport index */ > + int viewport_index_slot; > + > /**< minimum resolvable depth value, for polygon offset */ > double mrd; > > diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c > b/src/gallium/drivers/llvmpipe/lp_screen.c > index 712b7c6..9c4de72 100644 > --- a/src/gallium/drivers/llvmpipe/lp_screen.c > +++ b/src/gallium/drivers/llvmpipe/lp_screen.c > @@ -231,7 +231,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum > pipe_cap param) > case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: > return 0; > case PIPE_CAP_MULTIPLE_VIEWPORTS: > - return 0; > + return 1; > } > /* should only get here on unhandled cases */ > debug_printf("Unexpected PIPE_CAP %d query\n", param); > diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c > b/src/gallium/drivers/llvmpipe/lp_setup.c > index 9fef34e..caa168d 100644 > --- a/src/gallium/drivers/llvmpipe/lp_setup.c > +++ b/src/gallium/drivers/llvmpipe/lp_setup.c > @@ -616,17 +616,23 @@ lp_setup_set_blend_color( struct lp_setup_context > *setup, > > > void > -lp_setup_set_scissor( struct lp_setup_context *setup, > - const struct pipe_scissor_state *scissor ) > +lp_setup_set_scissors( struct lp_setup_context *setup, > + unsigned num_scissors, > + const struct pipe_scissor_state *scissors ) > { > + unsigned i; > LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); > > - assert(scissor); > + assert(scissors); > + > + setup->num_scissors = num_scissors; > > - setup->scissor.x0 = scissor->minx; > - setup->scissor.x1 = scissor->maxx-1; > - setup->scissor.y0 = scissor->miny; > - setup->scissor.y1 = scissor->maxy-1; > + for (i = 0; i < num_scissors; ++i) { > + setup->scissors[i].x0 = scissors[i].minx; > + setup->scissors[i].x1 = scissors[i].maxx-1; > + setup->scissors[i].y0 = scissors[i].miny; > + setup->scissors[i].y1 = scissors[i].maxy-1; > + } > setup->dirty |= LP_SETUP_NEW_SCISSOR; > } > > @@ -1012,10 +1018,15 @@ try_update_scene_state( struct lp_setup_context > *setup ) > } > > if (setup->dirty & LP_SETUP_NEW_SCISSOR) { > - setup->draw_region = setup->framebuffer; > - if (setup->scissor_test) { > - u_rect_possible_intersection(&setup->scissor, > - &setup->draw_region); > + unsigned i; > + /* we always need at least one draw region */ > + setup->draw_regions[0] = setup->framebuffer; > + for (i = 0; i < setup->num_scissors; ++i) { > + setup->draw_regions[i] = setup->framebuffer; > + if (setup->scissor_test) { > + u_rect_possible_intersection(&setup->scissors[i], > + &setup->draw_regions[i]); > + } > } > /* If the framebuffer is large we have to think about fixed-point > * integer overflow. For 2K by 2K images, coordinates need 15 bits > @@ -1061,6 +1072,7 @@ lp_setup_update_state( struct lp_setup_context *setup, > * to know about vertex shader point size attribute. > */ > setup->psize = lp->psize_slot; > + setup->viewport_index_slot = lp->viewport_index_slot; > > assert(lp->dirty == 0); > > diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h > b/src/gallium/drivers/llvmpipe/lp_setup.h > index 802ab01..68c710b 100644 > --- a/src/gallium/drivers/llvmpipe/lp_setup.h > +++ b/src/gallium/drivers/llvmpipe/lp_setup.h > @@ -117,8 +117,9 @@ lp_setup_set_blend_color( struct lp_setup_context *setup, > const struct pipe_blend_color *blend_color ); > > void > -lp_setup_set_scissor( struct lp_setup_context *setup, > - const struct pipe_scissor_state *scissor ); > +lp_setup_set_scissors( struct lp_setup_context *setup, > + unsigned num_scissors, > + const struct pipe_scissor_state *scissors ); > > void > lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup, > diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h > b/src/gallium/drivers/llvmpipe/lp_setup_context.h > index 6b35a02..da85f78 100644 > --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h > +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h > @@ -103,11 +103,13 @@ struct lp_setup_context > float line_width; > float point_size; > float psize; > + unsigned viewport_index_slot; > > struct pipe_framebuffer_state fb; > struct u_rect framebuffer; > - struct u_rect scissor; > - struct u_rect draw_region; /* intersection of fb & scissor */ > + struct u_rect scissors[PIPE_MAX_VIEWPORTS]; > + unsigned num_scissors; > + struct u_rect draw_regions[PIPE_MAX_VIEWPORTS]; /* intersection of fb & > scissor */ > > struct { > unsigned flags; > @@ -195,6 +197,7 @@ boolean > lp_setup_bin_triangle( struct lp_setup_context *setup, > struct lp_rast_triangle *tri, > const struct u_rect *bbox, > - int nr_planes ); > + int nr_planes, > + unsigned scissor_index ); > > #endif > diff --git a/src/gallium/drivers/llvmpipe/lp_setup_line.c > b/src/gallium/drivers/llvmpipe/lp_setup_line.c > index 54f19cb..c2a069f 100644 > --- a/src/gallium/drivers/llvmpipe/lp_setup_line.c > +++ b/src/gallium/drivers/llvmpipe/lp_setup_line.c > @@ -289,6 +289,7 @@ try_setup_line( struct lp_setup_context *setup, > int y[4]; > int i; > int nr_planes = 4; > + unsigned scissor_index = 0; > > /* linewidth should be interpreted as integer */ > int fixed_width = util_iround(width) * FIXED_ONE; > @@ -315,6 +316,10 @@ try_setup_line( struct lp_setup_context *setup, > > if (setup->scissor_test) { > nr_planes = 8; > + if (setup->viewport_index_slot > 0) { > + unsigned *udata = (unsigned*)v1[setup->viewport_index_slot]; > + scissor_index = *udata; > + } > } > else { > nr_planes = 4; > @@ -563,7 +568,7 @@ try_setup_line( struct lp_setup_context *setup, > return TRUE; > } > > - if (!u_rect_test_intersection(&setup->draw_region, &bbox)) { > + if (!u_rect_test_intersection(&setup->draw_regions[scissor_index], > &bbox)) { > if (0) debug_printf("offscreen\n"); > LP_COUNT(nr_culled_tris); > return TRUE; > @@ -672,7 +677,8 @@ try_setup_line( struct lp_setup_context *setup, > * these planes elsewhere. > */ > if (nr_planes == 8) { > - const struct u_rect *scissor = &setup->scissor; > + const struct u_rect *scissor = > + &setup->scissors[scissor_index]; > > plane[4].dcdx = -1; > plane[4].dcdy = 0; > @@ -695,7 +701,7 @@ try_setup_line( struct lp_setup_context *setup, > plane[7].eo = 0; > } > > - return lp_setup_bin_triangle(setup, line, &bbox, nr_planes); > + return lp_setup_bin_triangle(setup, line, &bbox, nr_planes, > scissor_index); > } > > > diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c > b/src/gallium/drivers/llvmpipe/lp_setup_point.c > index 146f1bd..30ce7490 100644 > --- a/src/gallium/drivers/llvmpipe/lp_setup_point.c > +++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c > @@ -324,8 +324,12 @@ try_setup_point( struct lp_setup_context *setup, > struct u_rect bbox; > unsigned nr_planes = 4; > struct point_info info; > + unsigned scissor_index = 0; > > - > + if (setup->viewport_index_slot > 0) { > + unsigned *udata = (unsigned*)v0[setup->viewport_index_slot]; > + scissor_index = *udata; > + } > /* Bounding rectangle (in pixels) */ > { > /* Yes this is necessary to accurately calculate bounding boxes > @@ -346,13 +350,13 @@ try_setup_point( struct lp_setup_context *setup, > bbox.y1--; > } > > - if (!u_rect_test_intersection(&setup->draw_region, &bbox)) { > + if (!u_rect_test_intersection(&setup->draw_regions[scissor_index], > &bbox)) { > if (0) debug_printf("offscreen\n"); > LP_COUNT(nr_culled_tris); > return TRUE; > } > > - u_rect_find_intersection(&setup->draw_region, &bbox); > + u_rect_find_intersection(&setup->draw_regions[scissor_index], &bbox); > > point = lp_setup_alloc_triangle(scene, > key->num_inputs, > @@ -407,7 +411,7 @@ try_setup_point( struct lp_setup_context *setup, > plane[3].eo = 0; > } > > - return lp_setup_bin_triangle(setup, point, &bbox, nr_planes); > + return lp_setup_bin_triangle(setup, point, &bbox, nr_planes, > scissor_index); > } > > > diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c > b/src/gallium/drivers/llvmpipe/lp_setup_tri.c > index b2c8cb5..c1ba52e 100644 > --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c > +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c > @@ -246,6 +246,7 @@ do_triangle_ccw(struct lp_setup_context *setup, > struct u_rect bbox; > unsigned tri_bytes; > int nr_planes = 3; > + unsigned scissor_index = 0; > > /* Area should always be positive here */ > assert(position->area > 0); > @@ -255,6 +256,10 @@ do_triangle_ccw(struct lp_setup_context *setup, > > if (setup->scissor_test) { > nr_planes = 7; > + if (setup->viewport_index_slot > 0) { > + unsigned *udata = (unsigned*)v0[setup->viewport_index_slot]; > + scissor_index = *udata; > + } > } > else { > nr_planes = 3; > @@ -285,7 +290,7 @@ do_triangle_ccw(struct lp_setup_context *setup, > return TRUE; > } > > - if (!u_rect_test_intersection(&setup->draw_region, &bbox)) { > + if (!u_rect_test_intersection(&setup->draw_regions[scissor_index], > &bbox)) { > if (0) debug_printf("offscreen\n"); > LP_COUNT(nr_culled_tris); > return TRUE; > @@ -491,7 +496,7 @@ do_triangle_ccw(struct lp_setup_context *setup, > * these planes elsewhere. > */ > if (nr_planes == 7) { > - const struct u_rect *scissor = &setup->scissor; > + const struct u_rect *scissor = &setup->scissors[scissor_index]; > > plane[3].dcdx = -1; > plane[3].dcdy = 0; > @@ -514,7 +519,7 @@ do_triangle_ccw(struct lp_setup_context *setup, > plane[6].eo = 0; > } > > - return lp_setup_bin_triangle( setup, tri, &bbox, nr_planes ); > + return lp_setup_bin_triangle( setup, tri, &bbox, nr_planes, scissor_index > ); > } > > /* > @@ -548,7 +553,8 @@ boolean > lp_setup_bin_triangle( struct lp_setup_context *setup, > struct lp_rast_triangle *tri, > const struct u_rect *bbox, > - int nr_planes ) > + int nr_planes, > + unsigned scissor_index ) > { > struct lp_scene *scene = setup->scene; > struct u_rect trimmed_box = *bbox; > @@ -570,7 +576,8 @@ lp_setup_bin_triangle( struct lp_setup_context *setup, > * the rasterizer to also respect scissor, etc, just for the rare > * cases where a small triangle extends beyond the scissor. > */ > - u_rect_find_intersection(&setup->draw_region, &trimmed_box); > + u_rect_find_intersection(&setup->draw_regions[scissor_index], > + &trimmed_box); > > /* Determine which tile(s) intersect the triangle's bounding box > */ > diff --git a/src/gallium/drivers/llvmpipe/lp_state_clip.c > b/src/gallium/drivers/llvmpipe/lp_state_clip.c > index ed47e5e..e33d82a 100644 > --- a/src/gallium/drivers/llvmpipe/lp_state_clip.c > +++ b/src/gallium/drivers/llvmpipe/lp_state_clip.c > @@ -53,7 +53,9 @@ llvmpipe_set_viewport_states(struct pipe_context *pipe, > /* pass the viewport info to the draw module */ > draw_set_viewport_states(llvmpipe->draw, num_viewports, viewports); > > - llvmpipe->viewport = *viewports; /* struct copy */ > + memcpy(llvmpipe->viewports, viewports, > + sizeof(struct pipe_viewport_state) * num_viewports); > + llvmpipe->num_viewports = num_viewports; > llvmpipe->dirty |= LP_NEW_VIEWPORT; > } > > @@ -67,7 +69,9 @@ llvmpipe_set_scissor_states(struct pipe_context *pipe, > > draw_flush(llvmpipe->draw); > > - llvmpipe->scissor = *scissors; /* struct copy */ > + llvmpipe->num_scissors = num_scissors; > + memcpy(llvmpipe->scissors, scissors, > + sizeof(struct pipe_scissor_state) * num_scissors); > llvmpipe->dirty |= LP_NEW_SCISSOR; > } > > diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c > b/src/gallium/drivers/llvmpipe/lp_state_derived.c > index aef222d..9002139 100644 > --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c > +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c > @@ -116,6 +116,18 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe) > draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index); > } > > + /* Figure out if we need viewport index */ > + vs_index = draw_find_shader_output(llvmpipe->draw, > + TGSI_SEMANTIC_VIEWPORT_INDEX, > + 0); > + if (vs_index > 0) { Couldn't vs_index legitimately be output zero? Though I guess that would be more a problem with draw_find_shader_output (as it returns 0 for not found indices) than viewport index here specifically.
> + llvmpipe->viewport_index_slot = vinfo->num_attribs; > + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index); > + } else { > + llvmpipe->viewport_index_slot = 0; > + } > + > + > draw_compute_vertex_size(vinfo); > lp_setup_set_vertex_info(llvmpipe->setup, vinfo); > } > @@ -164,7 +176,8 @@ void llvmpipe_update_derived( struct llvmpipe_context > *llvmpipe ) > &llvmpipe->blend_color); > > if (llvmpipe->dirty & LP_NEW_SCISSOR) > - lp_setup_set_scissor(llvmpipe->setup, &llvmpipe->scissor); > + lp_setup_set_scissors(llvmpipe->setup, llvmpipe->num_scissors, > + llvmpipe->scissors); > > if (llvmpipe->dirty & LP_NEW_DEPTH_STENCIL_ALPHA) { > lp_setup_set_alpha_ref_value(llvmpipe->setup, > diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c > b/src/gallium/drivers/llvmpipe/lp_surface.c > index 036b129..5a174f6 100644 > --- a/src/gallium/drivers/llvmpipe/lp_surface.c > +++ b/src/gallium/drivers/llvmpipe/lp_surface.c > @@ -214,8 +214,8 @@ static void lp_blit(struct pipe_context *pipe, > util_blitter_save_so_targets(lp->blitter, lp->num_so_targets, > (struct > pipe_stream_output_target**)lp->so_targets); > util_blitter_save_rasterizer(lp->blitter, (void*)lp->rasterizer); > - util_blitter_save_viewports(lp->blitter, 1, &lp->viewport); > - util_blitter_save_scissors(lp->blitter, 1, &lp->scissor); > + util_blitter_save_viewports(lp->blitter, lp->num_viewports, > lp->viewports); > + util_blitter_save_scissors(lp->blitter, lp->num_scissors, lp->scissors); > util_blitter_save_fragment_shader(lp->blitter, lp->fs); > util_blitter_save_blend(lp->blitter, (void*)lp->blend); > util_blitter_save_depth_stencil_alpha(lp->blitter, > (void*)lp->depth_stencil); > Otherwise looks good. Roland _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev