X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fllvmpipe%2Flp_state_rasterizer.c;h=574f9e940efe7eaa4564a385597c5680ada5992c;hb=772b25e1f366edc857e77b8c1ccdc5297d82cc41;hp=afd3e0b21c912c043a7672b41de020f3077e4c2d;hpb=bcc13b74443137043e8a34f8cb64a5add0d8af93;p=mesa.git diff --git a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c index afd3e0b21c9..574f9e940ef 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c +++ b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c @@ -32,16 +32,64 @@ #include "lp_setup.h" #include "draw/draw_context.h" +struct lp_rast_state { + struct pipe_rasterizer_state lp_state; + struct pipe_rasterizer_state draw_state; +}; + +/* State which might be handled in either the draw module or locally. + * This function is used to turn that state off in one of the two + * places. + */ +static void +clear_flags(struct pipe_rasterizer_state *rast) +{ + rast->light_twoside = 0; + rast->offset_tri = 0; +} + static void * llvmpipe_create_rasterizer_state(struct pipe_context *pipe, const struct pipe_rasterizer_state *rast) { - /* We do nothing special with rasterizer state. - * The CSO handle is just a pointer to a pipe_rasterizer_state object. + boolean need_pipeline; + + /* Partition rasterizer state into what we want the draw module to + * handle, and what we'll look after ourselves. + */ + struct lp_rast_state *state = MALLOC_STRUCT(lp_rast_state); + if (state == NULL) + return NULL; + + memcpy(&state->draw_state, rast, sizeof *rast); + memcpy(&state->lp_state, rast, sizeof *rast); + + /* We rely on draw module to do unfilled polyons, AA lines and + * points and stipple. + * + * Over time, reduce this list of conditions, and expand the list + * of flags which get cleared in clear_flags(). */ - return mem_dup(rast, sizeof(*rast)); + need_pipeline = (rast->fill_front != PIPE_POLYGON_MODE_FILL || + rast->fill_back != PIPE_POLYGON_MODE_FILL || + rast->point_smooth || + rast->line_smooth || + rast->line_stipple_enable || + rast->poly_stipple_enable); + + /* If not using the pipeline, clear out the flags which we can + * handle ourselves. If we *are* using the pipeline, do everything + * on the pipeline and clear those flags on our internal copy of + * the state. + */ + if (need_pipeline) + clear_flags(&state->lp_state); + else + clear_flags(&state->draw_state); + + return state; } @@ -50,29 +98,33 @@ static void llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, void *handle) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); - const struct pipe_rasterizer_state *rasterizer = - (const struct pipe_rasterizer_state *) handle; - - if (llvmpipe->rasterizer == rasterizer) - return; + const struct lp_rast_state *state = + (const struct lp_rast_state *) handle; - /* pass-through to draw module */ - draw_set_rasterizer_state(llvmpipe->draw, rasterizer, handle); + if (state) { + llvmpipe->rasterizer = &state->lp_state; + draw_set_rasterizer_state(llvmpipe->draw, &state->draw_state, handle); - llvmpipe->rasterizer = rasterizer; - - /* Note: we can immediately set the triangle state here and - * not worry about binning because we handle culling during - * triangle setup, not when rasterizing the bins. - */ - if (llvmpipe->rasterizer) { + /* XXX: just pass lp_state directly to setup. + */ lp_setup_set_triangle_state( llvmpipe->setup, - llvmpipe->rasterizer->cull_face, - llvmpipe->rasterizer->front_ccw, - llvmpipe->rasterizer->scissor, - llvmpipe->rasterizer->gl_rasterization_rules); + state->lp_state.cull_face, + state->lp_state.front_ccw, + state->lp_state.scissor, + state->lp_state.gl_rasterization_rules); lp_setup_set_flatshade_first( llvmpipe->setup, - llvmpipe->rasterizer->flatshade_first); + state->lp_state.flatshade_first); + lp_setup_set_line_state( llvmpipe->setup, + state->lp_state.line_width); + lp_setup_set_point_state( llvmpipe->setup, + state->lp_state.point_size, + state->lp_state.point_size_per_vertex, + state->lp_state.sprite_coord_enable, + state->lp_state.sprite_coord_mode); + } + else { + llvmpipe->rasterizer = NULL; + draw_set_rasterizer_state(llvmpipe->draw, NULL, handle); } llvmpipe->dirty |= LP_NEW_RASTERIZER;