summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Oliveira <igor.oliveira@openbossa.org>2010-06-30 07:40:36 -0400
committerIgor Oliveira <igor.oliveira@openbossa.org>2010-06-30 07:40:36 -0400
commit886b98b55aecc6e87f9218df42a3225969c1688f (patch)
treef09c8b8ec8dd635e748216a54ecf663135abf98c
parent6056a3a2ee5741a48d88713a4b9ca8e272658745 (diff)
DRM/Gallium3D: several fix to gallium 3D path and shader infrastructure
-rw-r--r--src/drm/cairo-drm-gallium-surface.c258
1 files changed, 170 insertions, 88 deletions
diff --git a/src/drm/cairo-drm-gallium-surface.c b/src/drm/cairo-drm-gallium-surface.c
index a284e5f8..cb6069a3 100644
--- a/src/drm/cairo-drm-gallium-surface.c
+++ b/src/drm/cairo-drm-gallium-surface.c
@@ -66,12 +66,15 @@
#define MAX_CONTANTS 20
+int draw_operation = 0;
+
typedef enum _shader_type shadertype_t;
typedef struct _gallium_paint gallium_paint_t;
typedef struct _gallium_surface gallium_surface_t;
typedef struct _gallium_shader gallium_shader_t;
typedef struct _gallium_device gallium_device_t;
+typedef struct _gallium_path gallium_path_t;
struct _gallium_device {
cairo_drm_device_t drm;
@@ -417,21 +420,22 @@ shader_destroy(gallium_shader_t *shader)
static void
setup_shader(gallium_shader_t *shader, shadertype_t type)
{
+ void *vs, *fs;
{
const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
TGSI_SEMANTIC_GENERIC };
const uint semantic_indexes[] = {0, 0};
- shader->vs = util_make_vertex_passthrough_shader(shader->device->pipe,
- 2,
- semantic_names,
- semantic_indexes);
+ vs = util_make_vertex_passthrough_shader(shader->device->pipe,
+ 1,
+ semantic_names,
+ semantic_indexes);
}
- cso_set_vertex_shader_handle(shader->device->cso, shader->vs);
+ cso_set_vertex_shader_handle(shader->device->cso, vs);
- shader->fs = shader_from_cache(shader->device, type, shader->fs);
- cso_set_fragment_shader_handle(shader->device->cso, shader->fs);
+ fs = shader_from_cache(shader->device, type, shader->fs);
+ cso_set_fragment_shader_handle(shader->device->cso, fs);
}
static INLINE void
@@ -553,6 +557,19 @@ gallium_surface_release_source_image (void *abstract_surface,
}
}
+static void
+_gallium_set_states(void *abstract_surface)
+{
+ gallium_surface_t *surface = abstract_surface;
+ gallium_device_t *device = gallium_device (surface);
+
+ cso_set_framebuffer (device->cso, &device->framebuffer);
+ cso_set_blend (device->cso, &surface->blend);
+ cso_set_depth_stencil_alpha (device->cso, &surface->depthstencil);
+ cso_set_rasterizer (device->cso, &surface->rasterizer);
+ cso_set_viewport (device->cso, &device->viewport);
+}
+
static cairo_status_t
gallium_surface_flush (void *abstract_surface)
{
@@ -560,29 +577,10 @@ gallium_surface_flush (void *abstract_surface)
gallium_device_t *device = gallium_device (surface);
cairo_status_t status;
- printf("fudeo");
-
- {
- cso_set_framebuffer (device->cso, &device->framebuffer);
- cso_set_blend (device->cso, &surface->blend);
- cso_set_depth_stencil_alpha (device->cso, &surface->depthstencil);
- cso_set_rasterizer (device->cso, &surface->rasterizer);
- cso_set_viewport (device->cso, &device->viewport);
-
- cso_set_vertex_elements (device->cso, 2, surface->velem);
-
- util_draw_vertex_buffer (device->pipe,
- surface->vbuf, 0,
- PIPE_PRIM_QUADS,
- 4,
- 2);
- }
-
if (surface->fallback == NULL) {
device->pipe->flush (device->pipe,
PIPE_FLUSH_RENDER_CACHE,
NULL);
- printf("flush\n");
return CAIRO_STATUS_SUCCESS;
}
@@ -599,22 +597,41 @@ gallium_surface_flush (void *abstract_surface)
cairo_device_release (&device->drm.base);
}
- printf("flushing");
-
status = cairo_surface_status (surface->fallback);
cairo_surface_destroy (surface->fallback);
surface->fallback = NULL;
- debug_dump_surface_bmp(device->pipe, "result.bmp", device->framebuffer.cbufs[0]);
-
return status;
}
-#define MIN_POINTS 10
+static void
+_gallium_surface_paint_get_solid(gallium_surface_t *surface, const cairo_pattern_t *pattern)
+{
+ cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *)pattern;
+
+ surface->paint.solid_color[0] = solid->color.red;
+ surface->paint.solid_color[1] = solid->color.green;
+ surface->paint.solid_color[2] = solid->color.blue;
+ surface->paint.solid_color[3] = solid->color.alpha;
+}
+
+
+static cairo_status_t
+_gallium_surface_paint_solid (gallium_surface_t *surface,
+ const cairo_pattern_t *pattern,
+ gallium_shader_t *shader)
+{
+ _gallium_surface_paint_get_solid(surface, pattern);
+ setup_constant_buffer(shader, &surface->paint.solid_color[0], 4*sizeof(float));
+ setup_shader(shader, SOLID_FILL);
+ return CAIRO_STATUS_SUCCESS;
+}
+
+#define MIN_POINTS 50
-typedef struct _gallium_path {
+struct _gallium_path {
cairo_matrix_t *ctm_inverse;
- double *points;
+ float *points;
int count;
float minx;
@@ -625,22 +642,19 @@ typedef struct _gallium_path {
float width;
struct pipe_resource *buf;
-} gallium_path_t;
+};
-static cairo_status_t
-_gallium_init_path (gallium_path_t *path)
+static gallium_path_t *
+_gallium_init_path ()
{
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
-
+ gallium_path_t *path = NULL;
path = (gallium_path_t *) malloc(sizeof(gallium_path_t));
if (path == NULL) {
- status = CAIRO_STATUS_NO_MEMORY;
goto CLEAN;
}
- path->points = (double *) malloc(sizeof(double) * MIN_POINTS * 2);
+ path->points = (float *) malloc(sizeof(float) * MIN_POINTS * 2);
if (path->points == NULL) {
- status = CAIRO_STATUS_NO_MEMORY;
goto CLEAN;
}
path->count = 0;
@@ -648,7 +662,7 @@ _gallium_init_path (gallium_path_t *path)
path->minx = path->miny = path->maxx = path->maxy = 0;
CLEAN:
- return status;
+ return path;
}
static cairo_status_t
@@ -666,13 +680,13 @@ _gallium_append_point (gallium_path_t *path, const cairo_point_t *point)
cairo_status_t status = CAIRO_STATUS_SUCCESS;
if (path->count >= MIN_POINTS) {
- double *new_points = (double *) malloc (sizeof(double) * (path->count + 2));
+ float *new_points = (float *) malloc (sizeof(float) * (path->count + 2));
if (new_points == NULL) {
status = CAIRO_STATUS_NO_MEMORY;
goto CLEAN;
}
- memcpy(new_points, path->points, path->count * 2 * sizeof(double));
+ memcpy(new_points, path->points, path->count * sizeof(float));
free(path->points);
path->points = new_points;
}
@@ -680,41 +694,41 @@ _gallium_append_point (gallium_path_t *path, const cairo_point_t *point)
path->points[path->count] = _cairo_fixed_to_double (point->x);
path->points[path->count + 1] = _cairo_fixed_to_double (point->y);
- path->count += 2;
-
path->minx = MIN2(path->points[path->count], path->minx);
path->maxx = MAX2(path->points[path->count], path->maxx);
path->miny = MIN2(path->points[path->count + 1], path->miny);
path->maxy = MAX2(path->points[path->count + 1], path->maxy);
+ path->count += 2;
+
CLEAN:
return status;
}
static void
-draw_path (gallium_device_t *device,
+draw_path (gallium_surface_t *surface,
gallium_path_t *path)
{
const int components = 2;
+ gallium_device_t *device= gallium_device(surface);
struct pipe_context *ctx = device->pipe;
- gallium_surface_t *surface = gallium_device(device);
struct pipe_vertex_buffer vbuffer;
struct pipe_vertex_element velement;
struct pipe_rasterizer_state rasterizer;
- int vert_size = components * path->count * sizeof(float);
+ int vert_size = path->count * sizeof(float);
+ int num_vert = path->count * 0.5;
- path->buf= pipe_user_buffer_create(ctx->screen,
- path->points,
- vert_size,
- PIPE_BIND_VERTEX_BUFFER);
+ path->buf = pipe_buffer_create(device->pipe->screen, PIPE_BIND_CONSTANT_BUFFER, vert_size);
+ pipe_buffer_write(device->pipe, path->buf, 0, vert_size, path->points);
+ device->pipe->set_constant_buffer(device->pipe, PIPE_SHADER_VERTEX, 0, path->buf);
memset(&vbuffer, 0, sizeof(vbuffer));
vbuffer.buffer = path->buf;
// We just have x and y components
vbuffer.stride = components * sizeof(float);
vbuffer.buffer_offset = 0;
- vbuffer.max_index = path->count - 1;
+ vbuffer.max_index = num_vert - 1;
ctx->set_vertex_buffers(ctx, 1, &vbuffer);
memset(&velement, 0, sizeof(velement));
@@ -724,14 +738,16 @@ draw_path (gallium_device_t *device,
velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
cso_set_vertex_elements(device->cso, 1, &velement);
+ _gallium_set_states(surface);
+
memset(&rasterizer, &surface->rasterizer, sizeof(struct pipe_rasterizer_state));
rasterizer.line_width = path->width;
cso_save_rasterizer(device->cso);
cso_set_rasterizer(device->cso, &rasterizer);
- ctx->draw_arrays(ctx, PIPE_PRIM_TRIANGLE_FAN,
- 0, path->count);
+ ctx->draw_arrays(ctx, PIPE_PRIM_LINE_STRIP,
+ 0, num_vert);
cso_restore_rasterizer(device->cso);
}
@@ -747,31 +763,30 @@ _gallium_draw_quad(gallium_surface_t *surface,
float vertices[4][2][4] = {
{
{ x0, y0, 0.0f, 1.0f },
- { 0.0f, 0.0f, 0.0f, 1.0f }
+ { 0.0f, 0.0f, 0.0f, 1.0f}
},
{
- { x0, y1, 0.0f, 1.0f },
+ { x0, y0 + y1, 0.0f, 1.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f }
},
{
- { x1, y1, 0.0f, 1.0f },
+ { x0 + x1, y0 + y1, 0.0f, 1.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f }
},
{
- { x0, 0.0f, 0.0f, 1.0f },
+ { x0 + x1, y0, 0.0f, 1.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f }
}
- };
+ };
buf = pipe_user_buffer_create (device->pipe->screen,
vertices,
sizeof(vertices),
PIPE_BIND_VERTEX_BUFFER);
-
if (buf != NULL) {
cso_set_vertex_elements (device->cso, 2, surface->velem);
util_draw_vertex_buffer (device->pipe, buf, 0,
- PIPE_PRIM_TRIANGLE_FAN,
+ PIPE_PRIM_QUADS,
4,
2);
@@ -783,21 +798,24 @@ static cairo_status_t
_gallium_move_to_line_to (void *closure, const cairo_point_t *point)
{
gallium_path_t *path = closure;
+ printf("line to\n");
- if (path->ctm_inverse)
- cairo_matrix_transform_point (path->ctm_inverse, point->x, point->y);
+ //if (path->ctm_inverse)
+ // cairo_matrix_transform_point (path->ctm_inverse, point->x, point->y);
_gallium_append_point(path, point);
return CAIRO_STATUS_SUCCESS;
}
+//XXX:make it works
static cairo_status_t
_gallium_close_path (void *closure)
{
cairo_status_t status = CAIRO_STATUS_NO_MEMORY;
gallium_path_t *path = closure;
+ printf("close path\n");
if (path->count != 0) {
cairo_point_t close_point_path;
close_point_path.x = path->points[0];
@@ -852,7 +870,7 @@ _gallium_path_from_cairo (gallium_path_t *gallium_path, const cairo_path_fixed_t
_gallium_move_to_line_to,
_gallium_move_to_line_to,
_gallium_curve_to,
- 0,
+ _gallium_close_path,
gallium_path);
assert (status == CAIRO_STATUS_SUCCESS);
@@ -869,7 +887,7 @@ _gallium_surface_clip (gallium_surface_t *abstract_surface,
struct pipe_depth_stencil_alpha_state st;
struct pipe_scissor_state scissor;
- _gallium_init_path(gallium_path);
+ gallium_path = _gallium_init_path();
_gallium_path_from_cairo(gallium_path, &clip->path->path);
st.depth.writemask = 1;
@@ -893,17 +911,6 @@ _gallium_surface_clip (gallium_surface_t *abstract_surface,
return CAIRO_STATUS_SUCCESS;
}
-static void
-_gallium_surface_paint_solid(gallium_surface_t *surface, const cairo_pattern_t *pattern)
-{
- cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *)pattern;
-
- surface->paint.solid_color[0] = solid->color.red;
- surface->paint.solid_color[1] = solid->color.green;
- surface->paint.solid_color[2] = solid->color.blue;
- surface->paint.solid_color[3] = solid->color.alpha;
-}
-
static cairo_int_status_t
gallium_surface_paint (void *abstract_surface,
cairo_operator_t op,
@@ -911,6 +918,7 @@ gallium_surface_paint (void *abstract_surface,
cairo_clip_t *clip)
{
gallium_surface_t *surface = abstract_surface;
+ gallium_device_t *device = gallium_device(surface);
gallium_shader_t *shader = gallium_device(surface)->shader;
cairo_status_t status;
@@ -924,14 +932,21 @@ gallium_surface_paint (void *abstract_surface,
return status;
if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
- _gallium_surface_paint_solid(surface, source);
- setup_constant_buffer(shader, &surface->paint.solid_color[0], 4*sizeof(float));
- setup_shader(shader, SOLID_FILL);
- status = CAIRO_STATUS_SUCCESS;
+ status = _gallium_surface_paint_solid(surface, source, shader);
} else {
status = _cairo_surface_paint (surface->fallback, op, source, clip);
}
+ _gallium_set_states(surface);
+
+ cso_set_vertex_elements (device->cso, 2, surface->velem);
+
+ util_draw_vertex_buffer (device->pipe,
+ surface->vbuf, 0,
+ PIPE_PRIM_QUADS,
+ 4,
+ 2);
+
gallium_surface_flush(abstract_surface);
return status;
@@ -974,13 +989,14 @@ gallium_surface_stroke (void *abstract_surface,
gallium_surface_t *surface = abstract_surface;
gallium_path_t *gallium_path;
gallium_device_t *device = gallium_device(surface);
+ gallium_shader_t *shader = device->shader;
cairo_status_t status;
status = _gallium_surface_clip (surface, clip);
if (unlikely (status))
return status;
- _gallium_init_path(gallium_path);
+ gallium_path = _gallium_init_path();
gallium_path->ctm_inverse = ctm_inverse;
@@ -988,9 +1004,15 @@ gallium_surface_stroke (void *abstract_surface,
gallium_path->width = style->line_width;
- draw_path(device, gallium_path);
+ if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
+ _gallium_surface_paint_solid(abstract_surface, source, shader);
+ }
+
+ draw_path(abstract_surface, gallium_path);
_gallium_finish_path(gallium_path);
+ gallium_surface_flush(abstract_surface);
+
return status;
}
@@ -1008,38 +1030,98 @@ gallium_surface_fill (void *abstract_surface,
gallium_surface_t *surface = abstract_surface;
gallium_path_t *gallium_path;
gallium_device_t *device = gallium_device(surface);
+ gallium_shader_t *shader = device->shader;
struct pipe_depth_stencil_alpha_state st;
+ struct pipe_stencil_ref sr;
cairo_status_t status;
status = _gallium_surface_clip (surface, clip);
if (unlikely (status))
return status;
- _gallium_init_path(gallium_path);
+ if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
+ _gallium_surface_paint_solid(abstract_surface, source, shader);
+ }
+
+ _gallium_set_states(abstract_surface);
+
+ gallium_path = _gallium_init_path();
_gallium_path_from_cairo(gallium_path, path);
+ struct pipe_surface *zsurface;
+ struct pipe_resource *resource;
+ {
+ struct pipe_resource template;
+ memset(&template, 0, sizeof(template));
+ template.target = PIPE_TEXTURE_2D;
+ template.format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ template.width0 = surface->drm.width;
+ template.height0 = surface->drm.height;
+ template.depth0 = 1;
+ template.last_level = 0;
+ template.bind = PIPE_BIND_RENDER_TARGET;
+ resource = device->screen->resource_create (device->screen,
+ &template);
+
+ zsurface = device->screen->get_tex_surface(device->pipe->screen,
+ resource,
+ 0, 0, 0,
+ PIPE_BIND_DEPTH_STENCIL);
+
+ }
+
+ device->framebuffer.zsbuf = zsurface;
+ _gallium_set_states(abstract_surface);
+
+ {
+ cso_save_blend(device->cso);
+ struct pipe_blend_state blend;
+ memset(&blend, 0, sizeof(struct pipe_blend_state));
+ blend.rt[0].colormask = PIPE_MASK_R; /*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;
+
+ cso_set_blend(device->cso, &blend);
+ }
+ memset(&sr, 0, sizeof(struct pipe_stencil_ref));
+ cso_set_stencil_ref(device->cso, &sr);
+
+ device->pipe->clear(device->pipe, PIPE_CLEAR_STENCIL, NULL, 0.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_REPLACE;
st.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
st.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
st.stencil[0].valuemask = 1;
+ st.stencil[0].writemask = 1;
cso_set_depth_stencil_alpha(device->cso, &st);
- draw_path(device, gallium_path);
+ draw_path(abstract_surface, gallium_path);
+ st.depth.enabled = 0;
st.stencil[0].func = PIPE_FUNC_EQUAL;
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_KEEP;
st.stencil[0].valuemask = 1;
cso_set_depth_stencil_alpha(device->cso, &st);
+ cso_restore_blend(device->cso);
_gallium_draw_quad(surface,
gallium_path->minx, gallium_path->miny,
gallium_path->maxx, gallium_path->maxy);
_gallium_finish_path(gallium_path);
+
+ gallium_surface_flush(abstract_surface);
cso_restore_depth_stencil_alpha(device->cso);
+ printf("filling");
+
+ return status;
}
static cairo_int_status_t
@@ -1209,7 +1291,7 @@ gallium_surface_create_internal (gallium_device_t *device,
{
{ 1.0f, 0.0f, 0.0f, 1.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f }
- }
+ }
};
surface->vbuf = pipe_buffer_create(device->pipe->screen, PIPE_BIND_CONSTANT_BUFFER, sizeof(vertices));
@@ -1449,7 +1531,7 @@ _cairo_drm_gallium_device_create (int fd, dev_t dev, int vendor_id, int chip_id)
//device->drm.surface.flink = gallium_surface_flink;
device->drm.surface.flink = NULL;
- device->drm.device.flush = NULL;
+ device->drm.device.flush = gallium_surface_flush;
device->drm.device.throttle = NULL;
device->drm.device.destroy = gallium_device_destroy;