From: Chia-I Wu Date: Sat, 27 Nov 2010 07:04:30 +0000 (+0800) Subject: st/vega: Add POLYGON_STENCIL and POLYGON_FILL renderer state. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3b71cb6ad6dabfefc9363a35872f4e70e1125603;p=mesa.git st/vega: Add POLYGON_STENCIL and POLYGON_FILL renderer state. The states are designated for polygon filling. Polygon filling is a two-pass process utilizing the stencil buffer. polygon_fill and polygon_array_fill functions are updated to make use of the state. --- diff --git a/src/gallium/state_trackers/vega/polygon.c b/src/gallium/state_trackers/vega/polygon.c index ca8831064c9..a491de27fa6 100644 --- a/src/gallium/state_trackers/vega/polygon.c +++ b/src/gallium/state_trackers/vega/polygon.c @@ -244,24 +244,11 @@ VGboolean polygon_is_closed(struct polygon *p) return floatsEqual(start[0], end[0]) && floatsEqual(start[1], end[1]); } -static void set_blend_for_fill(struct pipe_blend_state *blend) -{ - memset(blend, 0, sizeof(struct pipe_blend_state)); - blend->rt[0].colormask = 0; /*disable colorwrites*/ - - blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; - blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; -} - -static void draw_polygon(struct vg_context *ctx, - struct polygon *poly) +static void polygon_prepare_buffer(struct vg_context *ctx, + struct polygon *poly) { int vert_size; struct pipe_context *pipe; - struct pipe_vertex_buffer vbuffer; - struct pipe_vertex_element velement; vert_size = poly->num_verts * COMPONENTS * sizeof(float); @@ -281,35 +268,15 @@ static void draw_polygon(struct vg_context *ctx, PIPE_BIND_VERTEX_BUFFER); poly->dirty = VG_FALSE; } - - - /* tell pipe about the vertex buffer */ - memset(&vbuffer, 0, sizeof(vbuffer)); - vbuffer.buffer = poly->vbuf; - vbuffer.stride = COMPONENTS * sizeof(float); /* vertex size */ - vbuffer.buffer_offset = 0; - vbuffer.max_index = poly->num_verts - 1; - pipe->set_vertex_buffers(pipe, 1, &vbuffer); - - /* tell pipe about the vertex attributes */ - memset(&velement, 0, sizeof(velement)); - velement.src_offset = 0; - velement.instance_divisor = 0; - velement.vertex_buffer_index = 0; - velement.src_format = PIPE_FORMAT_R32G32_FLOAT; - cso_set_vertex_elements(ctx->cso_context, 1, &velement); - - /* draw */ - util_draw_arrays(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, (uint) poly->num_verts); } void polygon_fill(struct polygon *poly, struct vg_context *ctx) { - struct pipe_depth_stencil_alpha_state dsa; - struct pipe_stencil_ref sr; - struct pipe_blend_state blend; + struct pipe_vertex_element velement; + struct pipe_vertex_buffer vbuffer; VGfloat bounds[4]; VGfloat min_x, min_y, max_x, max_y; + assert(poly); polygon_bounding_rect(poly, bounds); min_x = bounds[0]; @@ -322,113 +289,42 @@ void polygon_fill(struct polygon *poly, struct vg_context *ctx) min_x, min_y, max_x, max_y); #endif - set_blend_for_fill(&blend); - - memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state)); - memset(&sr, 0, sizeof(struct pipe_stencil_ref)); - /* only need a fixed 0. Rely on default or move it out at least? */ - cso_set_stencil_ref(ctx->cso_context, &sr); - - cso_save_blend(ctx->cso_context); - cso_save_depth_stencil_alpha(ctx->cso_context); - - dsa.stencil[0].enabled = 1; - if (ctx->state.vg.fill_rule == VG_EVEN_ODD) { - dsa.stencil[0].writemask = 1; - dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INVERT; - dsa.stencil[0].func = PIPE_FUNC_ALWAYS; - dsa.stencil[0].valuemask = ~0; - - cso_set_blend(ctx->cso_context, &blend); - cso_set_depth_stencil_alpha(ctx->cso_context, &dsa); - draw_polygon(ctx, poly); - } else if (ctx->state.vg.fill_rule == VG_NON_ZERO) { - struct pipe_screen *screen = ctx->pipe->screen; - - if (screen->get_param(screen, PIPE_CAP_TWO_SIDED_STENCIL)) { - /* front */ - dsa.stencil[0].writemask = ~0; - dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP; - dsa.stencil[0].func = PIPE_FUNC_ALWAYS; - dsa.stencil[0].valuemask = ~0; - - /* back */ - dsa.stencil[1].enabled = 1; - dsa.stencil[1].writemask = ~0; - dsa.stencil[1].fail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[1].zfail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[1].zpass_op = PIPE_STENCIL_OP_DECR_WRAP; - dsa.stencil[1].func = PIPE_FUNC_ALWAYS; - dsa.stencil[1].valuemask = ~0; - - cso_set_blend(ctx->cso_context, &blend); - cso_set_depth_stencil_alpha(ctx->cso_context, &dsa); - draw_polygon(ctx, poly); - } else { - struct pipe_rasterizer_state raster; - - memcpy(&raster, &ctx->state.g3d.rasterizer, sizeof(struct pipe_rasterizer_state)); - - cso_save_rasterizer(ctx->cso_context); - dsa.stencil[0].func = PIPE_FUNC_ALWAYS; - dsa.stencil[0].valuemask = ~0; - - raster.cull_face = PIPE_FACE_BACK; - dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP; - - cso_set_blend(ctx->cso_context, &blend); - cso_set_depth_stencil_alpha(ctx->cso_context, &dsa); - cso_set_rasterizer(ctx->cso_context, &raster); - draw_polygon(ctx, poly); - - raster.cull_face = PIPE_FACE_FRONT; - dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_DECR_WRAP; - cso_set_depth_stencil_alpha(ctx->cso_context, &dsa); - cso_set_rasterizer(ctx->cso_context, &raster); - draw_polygon(ctx, poly); - - cso_restore_rasterizer(ctx->cso_context); - } - } + polygon_prepare_buffer(ctx, poly); + + /* tell renderer about the vertex attributes */ + memset(&velement, 0, sizeof(velement)); + velement.src_offset = 0; + velement.instance_divisor = 0; + velement.vertex_buffer_index = 0; + velement.src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* tell renderer about the vertex buffer */ + memset(&vbuffer, 0, sizeof(vbuffer)); + vbuffer.buffer = poly->vbuf; + vbuffer.stride = COMPONENTS * sizeof(float); /* vertex size */ + vbuffer.buffer_offset = 0; + vbuffer.max_index = poly->num_verts - 1; + + renderer_polygon_stencil_begin(ctx->renderer, + &velement, ctx->state.vg.fill_rule, VG_FALSE); + renderer_polygon_stencil(ctx->renderer, &vbuffer, + PIPE_PRIM_TRIANGLE_FAN, 0, (VGuint) poly->num_verts); + renderer_polygon_stencil_end(ctx->renderer); - /* restore color writes */ - cso_restore_blend(ctx->cso_context); - /* setup stencil ops */ - dsa.stencil[0].func = PIPE_FUNC_NOTEQUAL; - dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; - dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; - dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; - dsa.stencil[0].valuemask = dsa.stencil[0].writemask; - dsa.stencil[1].enabled = 0; - memcpy(&dsa.depth, &ctx->state.g3d.dsa.depth, - sizeof(struct pipe_depth_state)); - cso_set_depth_stencil_alpha(ctx->cso_context, &dsa); - - /* render the quad to propagate the rendering from stencil */ - renderer_draw_quad(ctx->renderer, min_x, min_y, - max_x, max_y, 0.0f/*depth should be disabled*/); - - cso_restore_depth_stencil_alpha(ctx->cso_context); + renderer_polygon_fill_begin(ctx->renderer, VG_FALSE); + renderer_polygon_fill(ctx->renderer, min_x, min_y, max_x, max_y); + renderer_polygon_fill_end(ctx->renderer); } void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx) { struct array *polys = polyarray->array; - struct pipe_depth_stencil_alpha_state dsa; - struct pipe_stencil_ref sr; - struct pipe_blend_state blend; VGfloat min_x = polyarray->min_x; VGfloat min_y = polyarray->min_y; VGfloat max_x = polyarray->max_x; VGfloat max_y = polyarray->max_y; + struct pipe_vertex_element velement; + struct pipe_vertex_buffer vbuffer; VGint i; @@ -438,111 +334,35 @@ void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx) min_x, min_y, max_x, max_y); #endif - set_blend_for_fill(&blend); - - memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state)); - memset(&sr, 0, sizeof(struct pipe_stencil_ref)); - /* only need a fixed 0. Rely on default or move it out at least? */ - cso_set_stencil_ref(ctx->cso_context, &sr); - - cso_save_blend(ctx->cso_context); - cso_save_depth_stencil_alpha(ctx->cso_context); - - dsa.stencil[0].enabled = 1; - if (ctx->state.vg.fill_rule == VG_EVEN_ODD) { - dsa.stencil[0].writemask = 1; - dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INVERT; - dsa.stencil[0].func = PIPE_FUNC_ALWAYS; - dsa.stencil[0].valuemask = ~0; - - cso_set_blend(ctx->cso_context, &blend); - cso_set_depth_stencil_alpha(ctx->cso_context, &dsa); - for (i = 0; i < polys->num_elements; ++i) { - struct polygon *poly = (((struct polygon**)polys->data)[i]); - draw_polygon(ctx, poly); - } - } else if (ctx->state.vg.fill_rule == VG_NON_ZERO) { - struct pipe_screen *screen = ctx->pipe->screen; - - if (screen->get_param(screen, PIPE_CAP_TWO_SIDED_STENCIL)) { - /* front */ - dsa.stencil[0].writemask = ~0; - dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP; - dsa.stencil[0].func = PIPE_FUNC_ALWAYS; - dsa.stencil[0].valuemask = ~0; - - /* back */ - dsa.stencil[1].enabled = 1; - dsa.stencil[1].writemask = ~0; - dsa.stencil[1].fail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[1].zfail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[1].zpass_op = PIPE_STENCIL_OP_DECR_WRAP; - dsa.stencil[1].func = PIPE_FUNC_ALWAYS; - dsa.stencil[1].valuemask = ~0; - - cso_set_blend(ctx->cso_context, &blend); - cso_set_depth_stencil_alpha(ctx->cso_context, &dsa); - for (i = 0; i < polys->num_elements; ++i) { - struct polygon *poly = (((struct polygon**)polys->data)[i]); - draw_polygon(ctx, poly); - } - } else { - struct pipe_rasterizer_state raster; - - memcpy(&raster, &ctx->state.g3d.rasterizer, sizeof(struct pipe_rasterizer_state)); - - cso_save_rasterizer(ctx->cso_context); - dsa.stencil[0].func = PIPE_FUNC_ALWAYS; - dsa.stencil[0].valuemask = ~0; - - raster.cull_face = PIPE_FACE_BACK; - dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP; - - cso_set_blend(ctx->cso_context, &blend); - cso_set_depth_stencil_alpha(ctx->cso_context, &dsa); - cso_set_rasterizer(ctx->cso_context, &raster); - for (i = 0; i < polys->num_elements; ++i) { - struct polygon *poly = (((struct polygon**)polys->data)[i]); - draw_polygon(ctx, poly); - } - - raster.cull_face = PIPE_FACE_FRONT; - dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_DECR_WRAP; - cso_set_depth_stencil_alpha(ctx->cso_context, &dsa); - cso_set_rasterizer(ctx->cso_context, &raster); - for (i = 0; i < polys->num_elements; ++i) { - struct polygon *poly = (((struct polygon**)polys->data)[i]); - draw_polygon(ctx, poly); - } - - cso_restore_rasterizer(ctx->cso_context); - } + /* tell renderer about the vertex attributes */ + memset(&velement, 0, sizeof(velement)); + velement.src_offset = 0; + velement.instance_divisor = 0; + velement.vertex_buffer_index = 0; + velement.src_format = PIPE_FORMAT_R32G32_FLOAT; + + /* tell renderer about the vertex buffer */ + memset(&vbuffer, 0, sizeof(vbuffer)); + vbuffer.stride = COMPONENTS * sizeof(float); /* vertex size */ + vbuffer.buffer_offset = 0; + + /* prepare the stencil buffer */ + renderer_polygon_stencil_begin(ctx->renderer, + &velement, ctx->state.vg.fill_rule, VG_FALSE); + for (i = 0; i < polys->num_elements; ++i) { + struct polygon *poly = (((struct polygon**)polys->data)[i]); + + polygon_prepare_buffer(ctx, poly); + vbuffer.buffer = poly->vbuf; + vbuffer.max_index = poly->num_verts - 1; + + renderer_polygon_stencil(ctx->renderer, &vbuffer, + PIPE_PRIM_TRIANGLE_FAN, 0, (VGuint) poly->num_verts); } + renderer_polygon_stencil_end(ctx->renderer); - /* restore color writes */ - cso_restore_blend(ctx->cso_context); - /* setup stencil ops */ - dsa.stencil[0].func = PIPE_FUNC_NOTEQUAL; - dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; - dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; - dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; - dsa.stencil[0].valuemask = dsa.stencil[0].writemask; - dsa.stencil[1].enabled = 0; - memcpy(&dsa.depth, &ctx->state.g3d.dsa.depth, - sizeof(struct pipe_depth_state)); - cso_set_depth_stencil_alpha(ctx->cso_context, &dsa); - - /* render the quad to propagate the rendering from stencil */ - renderer_draw_quad(ctx->renderer, min_x, min_y, - max_x, max_y, 0.0f/*depth should be disabled*/); - - cso_restore_depth_stencil_alpha(ctx->cso_context); + /* fill it */ + renderer_polygon_fill_begin(ctx->renderer, VG_FALSE); + renderer_polygon_fill(ctx->renderer, min_x, min_y, max_x, max_y); + renderer_polygon_fill_end(ctx->renderer); } diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c index e14eb4706e4..7543fa1d41a 100644 --- a/src/gallium/state_trackers/vega/renderer.c +++ b/src/gallium/state_trackers/vega/renderer.c @@ -51,6 +51,8 @@ typedef enum { RENDERER_STATE_SCISSOR, RENDERER_STATE_CLEAR, RENDERER_STATE_FILTER, + RENDERER_STATE_POLYGON_STENCIL, + RENDERER_STATE_POLYGON_FILL, NUM_RENDERER_STATES } RendererState; @@ -103,6 +105,12 @@ struct renderer { VGboolean use_sampler; VGint tex_width, tex_height; } filter; + + struct { + struct pipe_depth_stencil_alpha_state dsa; + VGboolean manual_two_sides; + VGboolean restore_dsa; + } polygon_stencil; } u; }; @@ -837,6 +845,193 @@ void renderer_filter_end(struct renderer *renderer) renderer->state = RENDERER_STATE_INIT; } +/** + * Prepare the renderer for polygon silhouette rendering. + */ +VGboolean renderer_polygon_stencil_begin(struct renderer *renderer, + struct pipe_vertex_element *velem, + VGFillRule rule, + VGboolean restore_dsa) +{ + struct pipe_depth_stencil_alpha_state *dsa; + VGboolean manual_two_sides; + + assert(renderer->state == RENDERER_STATE_INIT); + + cso_save_blend(renderer->cso); + cso_save_depth_stencil_alpha(renderer->cso); + + cso_set_vertex_elements(renderer->cso, 1, velem); + + /* disable color writes */ + renderer_set_blend(renderer, 0); + + manual_two_sides = VG_FALSE; + dsa = &renderer->u.polygon_stencil.dsa; + memset(dsa, 0, sizeof(*dsa)); + if (rule == VG_EVEN_ODD) { + dsa->stencil[0].enabled = 1; + dsa->stencil[0].writemask = 1; + dsa->stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; + dsa->stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; + dsa->stencil[0].zpass_op = PIPE_STENCIL_OP_INVERT; + dsa->stencil[0].func = PIPE_FUNC_ALWAYS; + dsa->stencil[0].valuemask = ~0; + } + else { + assert(rule == VG_NON_ZERO); + + /* front face */ + dsa->stencil[0].enabled = 1; + dsa->stencil[0].writemask = ~0; + dsa->stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; + dsa->stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; + dsa->stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP; + dsa->stencil[0].func = PIPE_FUNC_ALWAYS; + dsa->stencil[0].valuemask = ~0; + + if (renderer->pipe->screen->get_param(renderer->pipe->screen, + PIPE_CAP_TWO_SIDED_STENCIL)) { + /* back face */ + dsa->stencil[1] = dsa->stencil[0]; + dsa->stencil[1].zpass_op = PIPE_STENCIL_OP_DECR_WRAP; + } + else { + manual_two_sides = VG_TRUE; + } + } + cso_set_depth_stencil_alpha(renderer->cso, dsa); + + if (manual_two_sides) + cso_save_rasterizer(renderer->cso); + + renderer->u.polygon_stencil.manual_two_sides = manual_two_sides; + renderer->u.polygon_stencil.restore_dsa = restore_dsa; + renderer->state = RENDERER_STATE_POLYGON_STENCIL; + + return VG_TRUE; +} + +/** + * Render a polygon silhouette to stencil buffer. + */ +void renderer_polygon_stencil(struct renderer *renderer, + struct pipe_vertex_buffer *vbuf, + VGuint mode, VGuint start, VGuint count) +{ + assert(renderer->state == RENDERER_STATE_POLYGON_STENCIL); + + renderer->pipe->set_vertex_buffers(renderer->pipe, 1, vbuf); + + if (!renderer->u.polygon_stencil.manual_two_sides) { + util_draw_arrays(renderer->pipe, mode, start, count); + } + else { + struct pipe_rasterizer_state raster; + struct pipe_depth_stencil_alpha_state dsa; + + /* TODO do not access owner state */ + raster = renderer->owner->state.g3d.rasterizer; + dsa = renderer->u.polygon_stencil.dsa; + + /* front */ + raster.cull_face = PIPE_FACE_BACK; + dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP; + + cso_set_rasterizer(renderer->cso, &raster); + cso_set_depth_stencil_alpha(renderer->cso, &dsa); + util_draw_arrays(renderer->pipe, mode, start, count); + + /* back */ + raster.cull_face = PIPE_FACE_FRONT; + dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_DECR_WRAP; + + cso_set_rasterizer(renderer->cso, &raster); + cso_set_depth_stencil_alpha(renderer->cso, &dsa); + util_draw_arrays(renderer->pipe, mode, start, count); + } +} + +/** + * End polygon silhouette rendering. + */ +void renderer_polygon_stencil_end(struct renderer *renderer) +{ + assert(renderer->state == RENDERER_STATE_POLYGON_STENCIL); + + if (renderer->u.polygon_stencil.manual_two_sides) + cso_restore_rasterizer(renderer->cso); + + /* restore color writes */ + cso_restore_blend(renderer->cso); + + if (renderer->u.polygon_stencil.restore_dsa) + cso_restore_depth_stencil_alpha(renderer->cso); + + renderer->state = RENDERER_STATE_INIT; +} + +/** + * Prepare the renderer for polygon filling. + */ +VGboolean renderer_polygon_fill_begin(struct renderer *renderer, + VGboolean save_dsa) +{ + struct pipe_depth_stencil_alpha_state dsa; + struct pipe_stencil_ref sr; + + assert(renderer->state == RENDERER_STATE_INIT); + + if (save_dsa) + cso_save_depth_stencil_alpha(renderer->cso); + + /* only need a fixed 0. Rely on default or move it out at least? */ + memset(&sr, 0, sizeof(sr)); + cso_set_stencil_ref(renderer->cso, &sr); + + /* setup stencil ops */ + memset(&dsa, 0, sizeof(dsa)); + dsa.stencil[0].enabled = 1; + dsa.stencil[0].func = PIPE_FUNC_NOTEQUAL; + dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; + dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; + dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; + dsa.stencil[0].valuemask = ~0; + dsa.stencil[0].writemask = ~0; + /* TODO do not access owner state */ + dsa.depth = renderer->owner->state.g3d.dsa.depth; + cso_set_depth_stencil_alpha(renderer->cso, &dsa); + + renderer->state = RENDERER_STATE_POLYGON_FILL; + + return VG_TRUE; +} + +/** + * Fill a polygon. + */ +void renderer_polygon_fill(struct renderer *renderer, + VGfloat min_x, VGfloat min_y, + VGfloat max_x, VGfloat max_y) +{ + assert(renderer->state == RENDERER_STATE_POLYGON_FILL); + + renderer_quad_pos(renderer, min_x, min_y, max_x, max_y, VG_TRUE); + renderer_quad_draw(renderer); +} + +/** + * End polygon filling. + */ +void renderer_polygon_fill_end(struct renderer *renderer) +{ + assert(renderer->state == RENDERER_STATE_POLYGON_FILL); + + cso_restore_depth_stencil_alpha(renderer->cso); + + renderer->state = RENDERER_STATE_INIT; +} + static void setup_shaders(struct renderer *ctx) { struct pipe_context *pipe = ctx->pipe; diff --git a/src/gallium/state_trackers/vega/renderer.h b/src/gallium/state_trackers/vega/renderer.h index 288c17f9c89..8d13c02f3be 100644 --- a/src/gallium/state_trackers/vega/renderer.h +++ b/src/gallium/state_trackers/vega/renderer.h @@ -37,6 +37,8 @@ struct pipe_resource; struct pipe_sampler_state; struct pipe_sampler_view; struct pipe_surface; +struct pipe_vertex_element; +struct pipe_vertex_buffer; struct renderer *renderer_create(struct vg_context *owner); void renderer_destroy(struct renderer *); @@ -94,6 +96,26 @@ void renderer_filter(struct renderer *renderer, void renderer_filter_end(struct renderer *renderer); +VGboolean renderer_polygon_stencil_begin(struct renderer *renderer, + struct pipe_vertex_element *velem, + VGFillRule rule, + VGboolean restore_dsa); + +void renderer_polygon_stencil(struct renderer *renderer, + struct pipe_vertex_buffer *vbuf, + VGuint mode, VGuint start, VGuint count); + +void renderer_polygon_stencil_end(struct renderer *renderer); + +VGboolean renderer_polygon_fill_begin(struct renderer *renderer, + VGboolean save_dsa); + +void renderer_polygon_fill(struct renderer *renderer, + VGfloat min_x, VGfloat min_y, + VGfloat max_x, VGfloat max_y); + +void renderer_polygon_fill_end(struct renderer *renderer); + void renderer_draw_quad(struct renderer *, VGfloat x1, VGfloat y1, VGfloat x2, VGfloat y2,