diff options
author | Igor Oliveira <igor.oliveira@openbossa.org> | 2010-07-09 09:48:25 -0400 |
---|---|---|
committer | Igor Oliveira <igor.oliveira@openbossa.org> | 2010-07-09 09:48:25 -0400 |
commit | f9799a5ce4512accafb08de07b0f998b83027d2d (patch) | |
tree | 58dadc22c91beb80293b1073db3abfa1a2157512 | |
parent | 3336d8482db508137b33437e7cde026c159176dd (diff) |
DRM/Gallium3D: support to non-zero and even-odd working
-rw-r--r-- | src/drm/cairo-drm-gallium-surface.c | 150 |
1 files changed, 127 insertions, 23 deletions
diff --git a/src/drm/cairo-drm-gallium-surface.c b/src/drm/cairo-drm-gallium-surface.c index 744e5c8c..415067ed 100644 --- a/src/drm/cairo-drm-gallium-surface.c +++ b/src/drm/cairo-drm-gallium-surface.c @@ -1156,38 +1156,142 @@ gallium_surface_fill (void *abstract_surface, device->pipe->clear(device->pipe, PIPE_CLEAR_DEPTHSTENCIL, NULL, 1.0, 0); - // initialize stencil - st.depth.enabled = 1; st.stencil[0].enabled = 1; - st.stencil[0].func = PIPE_FUNC_ALWAYS; - st.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; - st.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; - st.stencil[0].zpass_op = PIPE_STENCIL_OP_INVERT; - st.stencil[0].valuemask = ~0; - st.stencil[0].writemask = 1; - st.stencil[1] = st.stencil[0]; - cso_set_depth_stencil_alpha(device->cso, &st); + st.depth.enabled = 1; + if (fill_rule == CAIRO_FILL_RULE_EVEN_ODD) { + // initialize stencil + st.stencil[0].func = PIPE_FUNC_ALWAYS; + st.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; + st.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; + st.stencil[0].zpass_op = PIPE_STENCIL_OP_INVERT; + st.stencil[0].valuemask = ~0; + st.stencil[0].writemask = 1; + cso_set_depth_stencil_alpha(device->cso, &st); - { - struct list_head *head, *next; + { + struct list_head *head, *next; - for (head = gallium_stroke->list_head.next; head != &gallium_stroke->list_head; head = next) { - gallium_path_t *gallium_path = LIST_ENTRY (gallium_path_t, head, list); + for (head = gallium_stroke->list_head.next; head != &gallium_stroke->list_head; head = next) { + gallium_path_t *gallium_path = LIST_ENTRY (gallium_path_t, head, list); - draw_path(abstract_surface, gallium_path, PIPE_PRIM_TRIANGLE_FAN); - _gallium_finish_path(gallium_path); + draw_path(abstract_surface, gallium_path, PIPE_PRIM_TRIANGLE_FAN); + _gallium_finish_path(gallium_path); - gallium_stroke->minx = MIN2(gallium_stroke->minx, gallium_path->minx); - gallium_stroke->maxx = MAX2(gallium_stroke->maxx, gallium_path->maxx); + gallium_stroke->minx = MIN2(gallium_stroke->minx, gallium_path->minx); + gallium_stroke->maxx = MAX2(gallium_stroke->maxx, gallium_path->maxx); - gallium_stroke->miny = MIN2(gallium_stroke->miny, gallium_path->miny); - gallium_stroke->maxy = MAX2(gallium_stroke->maxy, gallium_path->maxy); + gallium_stroke->miny = MIN2(gallium_stroke->miny, gallium_path->miny); + gallium_stroke->maxy = MAX2(gallium_stroke->maxy, gallium_path->maxy); - gallium_surface_flush(abstract_surface); - next = head->next; + gallium_surface_flush(abstract_surface); + next = head->next; + } + } + } else { + if (device->screen->get_param(device->screen, PIPE_CAP_TWO_SIDED_STENCIL)) { + st.stencil[0].func = PIPE_FUNC_ALWAYS; + st.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; + st.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; + st.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP; + st.stencil[0].valuemask = ~0; + st.stencil[0].writemask = ~0; + + st.stencil[1].enabled = 1; + st.stencil[1].func = PIPE_FUNC_ALWAYS; + st.stencil[1].fail_op = PIPE_STENCIL_OP_KEEP; + st.stencil[1].zfail_op = PIPE_STENCIL_OP_KEEP; + st.stencil[1].zpass_op = PIPE_STENCIL_OP_DECR_WRAP; + st.stencil[1].valuemask = ~0; + st.stencil[1].writemask = ~0; + + cso_set_depth_stencil_alpha(device->cso, &st); + + { + struct list_head *head, *next; + + for (head = gallium_stroke->list_head.next; head != &gallium_stroke->list_head; head = next) { + gallium_path_t *gallium_path = LIST_ENTRY (gallium_path_t, head, list); + + draw_path(abstract_surface, gallium_path, PIPE_PRIM_TRIANGLE_FAN); + + gallium_stroke->minx = MIN2(gallium_stroke->minx, gallium_path->minx); + gallium_stroke->maxx = MAX2(gallium_stroke->maxx, gallium_path->maxx); + + gallium_stroke->miny = MIN2(gallium_stroke->miny, gallium_path->miny); + gallium_stroke->maxy = MAX2(gallium_stroke->maxy, gallium_path->maxy); + + gallium_surface_flush(abstract_surface); + next = head->next; + } + } + + + } else { + struct pipe_rasterizer_state rasterizer; + memcpy(&rasterizer, &surface->rasterizer, sizeof(struct pipe_rasterizer_state)); + cso_save_rasterizer(device->cso); + + rasterizer.cull_face = PIPE_FACE_BACK; + cso_set_rasterizer(device->cso, &rasterizer); + + // initialize stencil + st.depth.enabled = 1; + st.stencil[0].enabled = 1; + st.stencil[0].func = PIPE_FUNC_ALWAYS; + st.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; + st.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; + st.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP; + st.stencil[0].valuemask = ~0; + st.stencil[0].writemask = 1; + st.stencil[1] = st.stencil[0]; + cso_set_depth_stencil_alpha(device->cso, &st); + + { + struct list_head *head, *next; + + for (head = gallium_stroke->list_head.next; head != &gallium_stroke->list_head; head = next) { + gallium_path_t *gallium_path = LIST_ENTRY (gallium_path_t, head, list); + + draw_path(abstract_surface, gallium_path, PIPE_PRIM_TRIANGLE_FAN); + gallium_surface_flush(abstract_surface); + + next = head->next; + } + } + + rasterizer.cull_face = PIPE_FACE_FRONT; + cso_set_rasterizer(device->cso, &rasterizer); + + // initialize stencil + st.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; + st.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; + st.stencil[0].zpass_op = PIPE_STENCIL_OP_DECR_WRAP; + cso_set_depth_stencil_alpha(device->cso, &st); + + { + struct list_head *head, *next; + + for (head = gallium_stroke->list_head.next; head != &gallium_stroke->list_head; head = next) { + gallium_path_t *gallium_path = LIST_ENTRY (gallium_path_t, head, list); + + draw_path(abstract_surface, gallium_path, PIPE_PRIM_TRIANGLE_FAN); + + gallium_stroke->minx = MIN2(gallium_stroke->minx, gallium_path->minx); + gallium_stroke->maxx = MAX2(gallium_stroke->maxx, gallium_path->maxx); + + gallium_stroke->miny = MIN2(gallium_stroke->miny, gallium_path->miny); + gallium_stroke->maxy = MAX2(gallium_stroke->maxy, gallium_path->maxy); + + gallium_surface_flush(abstract_surface); + next = head->next; + } + } + cso_restore_rasterizer(device->cso); } } + st.depth.enabled = 0; + st.stencil[1].enabled = 0; st.stencil[0].func = PIPE_FUNC_NOTEQUAL; st.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; st.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; @@ -1198,7 +1302,7 @@ gallium_surface_fill (void *abstract_surface, cso_set_depth_stencil_alpha(device->cso, &st); cso_restore_blend(device->cso); - _gallium_draw_quad(surface, + _gallium_draw_quad(surface, gallium_stroke->minx, gallium_stroke->miny, gallium_stroke->maxx, gallium_stroke->maxy); |