Pushed, thanks! Roland
Am 11.12.2015 um 12:43 schrieb Edward O'Callaghan: > Mostly related to making sure the rasterizer can correctly > pick out the correct scissor box for the current viewport. > > Signed-off-by: Edward O'Callaghan <[email protected]> > --- > src/gallium/drivers/softpipe/sp_context.h | 9 ++- > src/gallium/drivers/softpipe/sp_quad.h | 1 + > src/gallium/drivers/softpipe/sp_quad_depth_test.c | 5 +- > src/gallium/drivers/softpipe/sp_setup.c | 49 +++++++++++---- > src/gallium/drivers/softpipe/sp_setup.h | 5 ++ > src/gallium/drivers/softpipe/sp_state_clip.c | 15 +++-- > src/gallium/drivers/softpipe/sp_state_derived.c | 76 > +++++++++++++++-------- > src/gallium/drivers/softpipe/sp_surface.c | 4 +- > 8 files changed, 112 insertions(+), 52 deletions(-) > > diff --git a/src/gallium/drivers/softpipe/sp_context.h > b/src/gallium/drivers/softpipe/sp_context.h > index 073b71a..8e5e242 100644 > --- a/src/gallium/drivers/softpipe/sp_context.h > +++ b/src/gallium/drivers/softpipe/sp_context.h > @@ -79,10 +79,10 @@ struct softpipe_context { > struct pipe_resource > *constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_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]; > 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]; > 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]; > @@ -123,6 +123,9 @@ struct softpipe_context { > /** Which vertex shader output slot contains point size */ > int psize_slot; > > + /** Which vertex shader output slot contains viewport index */ > + int viewport_index_slot; > + > /** Which vertex shader output slot contains layer */ > int layer_slot; > > @@ -140,7 +143,7 @@ struct softpipe_context { > unsigned reduced_prim; > > /** Derived from scissor and surface bounds: */ > - struct pipe_scissor_state cliprect; > + struct pipe_scissor_state cliprect[PIPE_MAX_VIEWPORTS]; > > unsigned line_stipple_counter; > > diff --git a/src/gallium/drivers/softpipe/sp_quad.h > b/src/gallium/drivers/softpipe/sp_quad.h > index b29dad2..2c2b018 100644 > --- a/src/gallium/drivers/softpipe/sp_quad.h > +++ b/src/gallium/drivers/softpipe/sp_quad.h > @@ -63,6 +63,7 @@ struct quad_header_input > { > int x0, y0; /**< quad window pos, always even */ > unsigned layer; > + unsigned viewport_index; > float coverage[TGSI_QUAD_SIZE]; /**< fragment coverage for antialiasing */ > unsigned facing:1; /**< Front (0) or back (1) facing? */ > unsigned prim:2; /**< QUAD_PRIM_POINT, LINE, TRI */ > diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c > b/src/gallium/drivers/softpipe/sp_quad_depth_test.c > index bac40c0..4cce9e9 100644 > --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c > +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c > @@ -785,6 +785,7 @@ depth_test_quads_fallback(struct quad_stage *qs, > boolean interp_depth = !fsInfo->writes_z; > boolean shader_stencil_ref = fsInfo->writes_stencil; > struct depth_data data; > + unsigned vp_idx = quads[0]->input.viewport_index; > > data.use_shader_stencil_refs = FALSE; > > @@ -804,8 +805,8 @@ depth_test_quads_fallback(struct quad_stage *qs, > quads[0]->input.y0, > quads[0]->input.layer); > data.clamp = !qs->softpipe->rasterizer->depth_clip; > > - near_val = qs->softpipe->viewport.translate[2] - > qs->softpipe->viewport.scale[2]; > - far_val = near_val + (qs->softpipe->viewport.scale[2] * 2.0); > + near_val = qs->softpipe->viewports[vp_idx].translate[2] - > qs->softpipe->viewports[vp_idx].scale[2]; > + far_val = near_val + (qs->softpipe->viewports[vp_idx].scale[2] * 2.0); > data.minval = MIN2(near_val, far_val); > data.maxval = MAX2(near_val, far_val); > > diff --git a/src/gallium/drivers/softpipe/sp_setup.c > b/src/gallium/drivers/softpipe/sp_setup.c > index 973803e..ac2d978 100644 > --- a/src/gallium/drivers/softpipe/sp_setup.c > +++ b/src/gallium/drivers/softpipe/sp_setup.c > @@ -128,7 +128,8 @@ struct setup_context { > static inline void > quad_clip(struct setup_context *setup, struct quad_header *quad) > { > - const struct pipe_scissor_state *cliprect = &setup->softpipe->cliprect; > + unsigned viewport_index = quad[0].input.viewport_index; > + const struct pipe_scissor_state *cliprect = > &setup->softpipe->cliprect[viewport_index]; > const int minx = (int) cliprect->minx; > const int maxx = (int) cliprect->maxx; > const int miny = (int) cliprect->miny; > @@ -159,7 +160,7 @@ quad_clip(struct setup_context *setup, struct quad_header > *quad) > static inline void > clip_emit_quad(struct setup_context *setup, struct quad_header *quad) > { > - quad_clip( setup, quad ); > + quad_clip(setup, quad); > > if (quad->inout.mask) { > struct softpipe_context *sp = setup->softpipe; > @@ -707,9 +708,10 @@ static void > subtriangle(struct setup_context *setup, > struct edge *eleft, > struct edge *eright, > - int lines) > + int lines, > + unsigned viewport_index) > { > - const struct pipe_scissor_state *cliprect = &setup->softpipe->cliprect; > + const struct pipe_scissor_state *cliprect = > &setup->softpipe->cliprect[viewport_index]; > const int minx = (int) cliprect->minx; > const int maxx = (int) cliprect->maxx; > const int miny = (int) cliprect->miny; > @@ -807,6 +809,7 @@ sp_setup_tri(struct setup_context *setup, > { > float det; > uint layer = 0; > + unsigned viewport_index = 0; > #if DEBUG_VERTS > debug_printf("Setup triangle:\n"); > print_vertex(setup, v0); > @@ -845,19 +848,25 @@ sp_setup_tri(struct setup_context *setup, > } > setup->quad[0].input.layer = layer; > > + if (setup->softpipe->viewport_index_slot > 0) { > + unsigned *udata = (unsigned*)v0[setup->softpipe->viewport_index_slot]; > + viewport_index = sp_clamp_viewport_idx(*udata); > + } > + setup->quad[0].input.viewport_index = viewport_index; > + > /* init_constant_attribs( setup ); */ > > if (setup->oneoverarea < 0.0) { > /* emaj on left: > */ > - subtriangle( setup, &setup->emaj, &setup->ebot, setup->ebot.lines ); > - subtriangle( setup, &setup->emaj, &setup->etop, setup->etop.lines ); > + subtriangle(setup, &setup->emaj, &setup->ebot, setup->ebot.lines, > viewport_index); > + subtriangle(setup, &setup->emaj, &setup->etop, setup->etop.lines, > viewport_index); > } > else { > /* emaj on right: > */ > - subtriangle( setup, &setup->ebot, &setup->emaj, setup->ebot.lines ); > - subtriangle( setup, &setup->etop, &setup->emaj, setup->etop.lines ); > + subtriangle(setup, &setup->ebot, &setup->emaj, setup->ebot.lines, > viewport_index); > + subtriangle(setup, &setup->etop, &setup->emaj, setup->etop.lines, > viewport_index); > } > > flush_spans( setup ); > @@ -1054,7 +1063,7 @@ plot(struct setup_context *setup, int x, int y) > /* flush prev quad, start new quad */ > > if (setup->quad[0].input.x0 != -1) > - clip_emit_quad( setup, &setup->quad[0] ); > + clip_emit_quad(setup, &setup->quad[0]); > > setup->quad[0].input.x0 = quadX; > setup->quad[0].input.y0 = quadY; > @@ -1083,6 +1092,7 @@ sp_setup_line(struct setup_context *setup, > int dy = y1 - y0; > int xstep, ystep; > uint layer = 0; > + unsigned viewport_index = 0; > > #if DEBUG_VERTS > debug_printf("Setup line:\n"); > @@ -1132,6 +1142,12 @@ sp_setup_line(struct setup_context *setup, > } > setup->quad[0].input.layer = layer; > > + if (setup->softpipe->viewport_index_slot > 0) { > + unsigned *udata = > (unsigned*)setup->vprovoke[setup->softpipe->viewport_index_slot]; > + viewport_index = sp_clamp_viewport_idx(*udata); > + } > + setup->quad[0].input.viewport_index = viewport_index; > + > /* XXX temporary: set coverage to 1.0 so the line appears > * if AA mode happens to be enabled. > */ > @@ -1183,7 +1199,7 @@ sp_setup_line(struct setup_context *setup, > > /* draw final quad */ > if (setup->quad[0].inout.mask) { > - clip_emit_quad( setup, &setup->quad[0] ); > + clip_emit_quad(setup, &setup->quad[0]); > } > } > > @@ -1223,6 +1239,7 @@ sp_setup_point(struct setup_context *setup, > const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); > uint fragSlot; > uint layer = 0; > + unsigned viewport_index = 0; > #if DEBUG_VERTS > debug_printf("Setup point:\n"); > print_vertex(setup, v0); > @@ -1239,6 +1256,12 @@ sp_setup_point(struct setup_context *setup, > } > setup->quad[0].input.layer = layer; > > + if (setup->softpipe->viewport_index_slot > 0) { > + unsigned *udata = (unsigned*)v0[setup->softpipe->viewport_index_slot]; > + viewport_index = sp_clamp_viewport_idx(*udata); > + } > + setup->quad[0].input.viewport_index = viewport_index; > + > /* For points, all interpolants are constant-valued. > * However, for point sprites, we'll need to setup texcoords > appropriately. > * XXX: which coefficients are the texcoords??? > @@ -1300,7 +1323,7 @@ sp_setup_point(struct setup_context *setup, > setup->quad[0].input.x0 = (int) x - ix; > setup->quad[0].input.y0 = (int) y - iy; > setup->quad[0].inout.mask = (1 << ix) << (2 * iy); > - clip_emit_quad( setup, &setup->quad[0] ); > + clip_emit_quad(setup, &setup->quad[0]); > } > else { > if (round) { > @@ -1361,7 +1384,7 @@ sp_setup_point(struct setup_context *setup, > if (setup->quad[0].inout.mask) { > setup->quad[0].input.x0 = ix; > setup->quad[0].input.y0 = iy; > - clip_emit_quad( setup, &setup->quad[0] ); > + clip_emit_quad(setup, &setup->quad[0]); > } > } > } > @@ -1408,7 +1431,7 @@ sp_setup_point(struct setup_context *setup, > setup->quad[0].inout.mask = mask; > setup->quad[0].input.x0 = ix; > setup->quad[0].input.y0 = iy; > - clip_emit_quad( setup, &setup->quad[0] ); > + clip_emit_quad(setup, &setup->quad[0]); > } > } > } > diff --git a/src/gallium/drivers/softpipe/sp_setup.h > b/src/gallium/drivers/softpipe/sp_setup.h > index 885be73..191494a 100644 > --- a/src/gallium/drivers/softpipe/sp_setup.h > +++ b/src/gallium/drivers/softpipe/sp_setup.h > @@ -45,6 +45,11 @@ void > sp_setup_point( struct setup_context *setup, > const float (*v0)[4] ); > > +static inline unsigned > +sp_clamp_viewport_idx(int idx) > +{ > + return (PIPE_MAX_VIEWPORTS > idx && idx >= 0) ? idx : 0; > +} > > struct setup_context *sp_setup_create_context( struct softpipe_context > *softpipe ); > void sp_setup_prepare( struct setup_context *setup ); > diff --git a/src/gallium/drivers/softpipe/sp_state_clip.c > b/src/gallium/drivers/softpipe/sp_state_clip.c > index 59c22c6..4de6296 100644 > --- a/src/gallium/drivers/softpipe/sp_state_clip.c > +++ b/src/gallium/drivers/softpipe/sp_state_clip.c > @@ -47,15 +47,16 @@ static void > softpipe_set_viewport_states(struct pipe_context *pipe, > unsigned start_slot, > unsigned num_viewports, > - const struct pipe_viewport_state *viewport) > + const struct pipe_viewport_state *viewports) > { > struct softpipe_context *softpipe = softpipe_context(pipe); > > /* pass the viewport info to the draw module */ > draw_set_viewport_states(softpipe->draw, start_slot, num_viewports, > - viewport); > + viewports); > > - softpipe->viewport = *viewport; /* struct copy */ > + memcpy(softpipe->viewports + start_slot, viewports, > + sizeof(struct pipe_viewport_state) * num_viewports); > softpipe->dirty |= SP_NEW_VIEWPORT; > } > > @@ -64,13 +65,17 @@ static void > softpipe_set_scissor_states(struct pipe_context *pipe, > unsigned start_slot, > unsigned num_scissors, > - const struct pipe_scissor_state *scissor) > + const struct pipe_scissor_state *scissors) > { > struct softpipe_context *softpipe = softpipe_context(pipe); > > draw_flush(softpipe->draw); > > - softpipe->scissor = *scissor; /* struct copy */ > + debug_assert(start_slot < PIPE_MAX_VIEWPORTS); > + debug_assert((start_slot + num_scissors) <= PIPE_MAX_VIEWPORTS); > + > + memcpy(softpipe->scissors + start_slot, scissors, > + sizeof(struct pipe_scissor_state) * num_scissors); > softpipe->dirty |= SP_NEW_SCISSOR; > } > > diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c > b/src/gallium/drivers/softpipe/sp_state_derived.c > index 2a6a6f4..7e998af 100644 > --- a/src/gallium/drivers/softpipe/sp_state_derived.c > +++ b/src/gallium/drivers/softpipe/sp_state_derived.c > @@ -64,6 +64,7 @@ struct vertex_info * > softpipe_get_vertex_info(struct softpipe_context *softpipe) > { > struct vertex_info *vinfo = &softpipe->vertex_info; > + int vs_index; > > if (vinfo->num_attribs == 0) { > /* compute vertex layout now */ > @@ -135,17 +136,35 @@ softpipe_get_vertex_info(struct softpipe_context > *softpipe) > draw_emit_vertex_attr(vinfo, EMIT_4F, interp, src); > } > > - softpipe->psize_slot = draw_find_shader_output(softpipe->draw, > - TGSI_SEMANTIC_PSIZE, 0); > - if (softpipe->psize_slot >= 0) { > - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, > - softpipe->psize_slot); > + /* Figure out if we need pointsize as well. */ > + vs_index = draw_find_shader_output(softpipe->draw, > + TGSI_SEMANTIC_PSIZE, 0); > + > + if (vs_index >= 0) { > + softpipe->psize_slot = vinfo->num_attribs; > + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index); > + } > + > + /* Figure out if we need viewport index */ > + vs_index = draw_find_shader_output(softpipe->draw, > + TGSI_SEMANTIC_VIEWPORT_INDEX, > + 0); > + if (vs_index >= 0) { > + softpipe->viewport_index_slot = vinfo->num_attribs; > + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index); > + } else { > + softpipe->viewport_index_slot = 0; > } > > - softpipe->layer_slot = draw_find_shader_output(softpipe->draw, > - TGSI_SEMANTIC_LAYER, 0); > - if (softpipe->layer_slot >= 0) { > - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, > softpipe->layer_slot); > + /* Figure out if we need layer */ > + vs_index = draw_find_shader_output(softpipe->draw, > + TGSI_SEMANTIC_LAYER, > + 0); > + if (vs_index >= 0) { > + softpipe->layer_slot = vinfo->num_attribs; > + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index); > + } else { > + softpipe->layer_slot = 0; > } > > draw_compute_vertex_size(vinfo); > @@ -183,30 +202,33 @@ softpipe_get_vbuf_vertex_info(struct softpipe_context > *softpipe) > static void > compute_cliprect(struct softpipe_context *sp) > { > + unsigned i; > /* SP_NEW_FRAMEBUFFER > */ > uint surfWidth = sp->framebuffer.width; > uint surfHeight = sp->framebuffer.height; > > - /* SP_NEW_RASTERIZER > - */ > - if (sp->rasterizer->scissor) { > - > - /* SP_NEW_SCISSOR > - * > - * clip to scissor rect: > + for (i = 0; i < PIPE_MAX_VIEWPORTS; i++) { > + /* SP_NEW_RASTERIZER > */ > - sp->cliprect.minx = MAX2(sp->scissor.minx, 0); > - sp->cliprect.miny = MAX2(sp->scissor.miny, 0); > - sp->cliprect.maxx = MIN2(sp->scissor.maxx, surfWidth); > - sp->cliprect.maxy = MIN2(sp->scissor.maxy, surfHeight); > - } > - else { > - /* clip to surface bounds */ > - sp->cliprect.minx = 0; > - sp->cliprect.miny = 0; > - sp->cliprect.maxx = surfWidth; > - sp->cliprect.maxy = surfHeight; > + if (sp->rasterizer->scissor) { > + > + /* SP_NEW_SCISSOR > + * > + * clip to scissor rect: > + */ > + sp->cliprect[i].minx = MAX2(sp->scissors[i].minx, 0); > + sp->cliprect[i].miny = MAX2(sp->scissors[i].miny, 0); > + sp->cliprect[i].maxx = MIN2(sp->scissors[i].maxx, surfWidth); > + sp->cliprect[i].maxy = MIN2(sp->scissors[i].maxy, surfHeight); > + } > + else { > + /* clip to surface bounds */ > + sp->cliprect[i].minx = 0; > + sp->cliprect[i].miny = 0; > + sp->cliprect[i].maxx = surfWidth; > + sp->cliprect[i].maxy = surfHeight; > + } > } > } > > diff --git a/src/gallium/drivers/softpipe/sp_surface.c > b/src/gallium/drivers/softpipe/sp_surface.c > index 768e898..e2ecbdf 100644 > --- a/src/gallium/drivers/softpipe/sp_surface.c > +++ b/src/gallium/drivers/softpipe/sp_surface.c > @@ -67,8 +67,8 @@ static void sp_blit(struct pipe_context *pipe, > util_blitter_save_so_targets(sp->blitter, sp->num_so_targets, > (struct pipe_stream_output_target**)sp->so_targets); > util_blitter_save_rasterizer(sp->blitter, sp->rasterizer); > - util_blitter_save_viewport(sp->blitter, &sp->viewport); > - util_blitter_save_scissor(sp->blitter, &sp->scissor); > + util_blitter_save_viewport(sp->blitter, &sp->viewports[0]); > + util_blitter_save_scissor(sp->blitter, &sp->scissors[0]); > util_blitter_save_fragment_shader(sp->blitter, sp->fs); > util_blitter_save_blend(sp->blitter, sp->blend); > util_blitter_save_depth_stencil_alpha(sp->blitter, sp->depth_stencil); > _______________________________________________ mesa-dev mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-dev
