summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Oliveira <igor.oliveira@openbossa.org>2010-07-09 09:48:25 -0400
committerIgor Oliveira <igor.oliveira@openbossa.org>2010-07-09 09:48:25 -0400
commitf9799a5ce4512accafb08de07b0f998b83027d2d (patch)
tree58dadc22c91beb80293b1073db3abfa1a2157512
parent3336d8482db508137b33437e7cde026c159176dd (diff)
DRM/Gallium3D: support to non-zero and even-odd working
-rw-r--r--src/drm/cairo-drm-gallium-surface.c150
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);