summaryrefslogtreecommitdiff
path: root/src/gallium/state_trackers/vega
diff options
context:
space:
mode:
authorChia-I Wu <olv@lunarg.com>2010-11-27 15:04:30 +0800
committerChia-I Wu <olv@lunarg.com>2010-12-01 11:23:49 +0800
commit3b71cb6ad6dabfefc9363a35872f4e70e1125603 (patch)
tree9080df502622b053af88cc7e964521de4cb7451b /src/gallium/state_trackers/vega
parentb23f732075fc4e1cd9cbf5eaaaaa8ef8dc2b7922 (diff)
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.
Diffstat (limited to 'src/gallium/state_trackers/vega')
-rw-r--r--src/gallium/state_trackers/vega/polygon.c300
-rw-r--r--src/gallium/state_trackers/vega/renderer.c195
-rw-r--r--src/gallium/state_trackers/vega/renderer.h22
3 files changed, 277 insertions, 240 deletions
diff --git a/src/gallium/state_trackers/vega/polygon.c b/src/gallium/state_trackers/vega/polygon.c
index ca8831064c..a491de27fa 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 e14eb4706e..7543fa1d41 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 288c17f9c8..8d13c02f3b 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,