From: Zack Rusin Date: Tue, 1 Sep 2009 18:43:04 +0000 (-0400) Subject: st/xorg: start rendering and compositing pictures X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=91c366359ce0bf5f450fd1d774b771c95ed2f651;p=mesa.git st/xorg: start rendering and compositing pictures --- diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c index 86402a0d130..8a12c03267a 100644 --- a/src/gallium/state_trackers/xorg/xorg_composite.c +++ b/src/gallium/state_trackers/xorg/xorg_composite.c @@ -77,79 +77,189 @@ blend_for_op(int op) } +static INLINE void +setup_vertex0(float vertex[2][4], float x, float y, + float color[4]) +{ + vertex[0][0] = x; + vertex[0][1] = y; + vertex[0][2] = 0.f; /*z*/ + vertex[0][3] = 1.f; /*w*/ + + vertex[1][0] = color[0]; /*r*/ + vertex[1][1] = color[1]; /*g*/ + vertex[1][2] = color[2]; /*b*/ + vertex[1][3] = color[3]; /*a*/ +} + static struct pipe_buffer * -setup_vertex_data_tex(struct exa_context *ctx, - float x0, float y0, float x1, float y1, - float x2, float y2, float x3, float y3, - float s0, float t0, float s1, float t1, - float z) +setup_vertex_data0(struct exa_context *ctx, + int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height) { - ctx->vertices[0][0][0] = x0; - ctx->vertices[0][0][1] = y0; - ctx->vertices[0][0][2] = z; - ctx->vertices[0][1][0] = s0; /*s*/ - ctx->vertices[0][1][1] = t0; /*t*/ - - ctx->vertices[1][0][0] = x1; - ctx->vertices[1][0][1] = y1; - ctx->vertices[1][0][2] = z; - ctx->vertices[1][1][0] = s1; /*s*/ - ctx->vertices[1][1][1] = t0; /*t*/ - - ctx->vertices[2][0][0] = x2; - ctx->vertices[2][0][1] = y2; - ctx->vertices[2][0][2] = z; - ctx->vertices[2][1][0] = s1; - ctx->vertices[2][1][1] = t1; - - ctx->vertices[3][0][0] = x3; - ctx->vertices[3][0][1] = y3; - ctx->vertices[3][0][2] = z; - ctx->vertices[3][1][0] = s0; - ctx->vertices[3][1][1] = t1; + float vertices[4][2][4]; + + /* 1st vertex */ + setup_vertex0(vertices[0], dstX, dstY, + ctx->solid_color); + /* 2nd vertex */ + setup_vertex0(vertices[1], dstX + width, dstY, + ctx->solid_color); + /* 3rd vertex */ + setup_vertex0(vertices[2], dstX + width, dstY + height, + ctx->solid_color); + /* 4th vertex */ + setup_vertex0(vertices[3], dstX, dstY + height, + ctx->solid_color); return pipe_user_buffer_create(ctx->ctx->screen, - ctx->vertices, - sizeof(ctx->vertices)); + vertices, + sizeof(vertices)); } -static void -draw_texture(struct exa_context *exa, - struct pipe_texture *tex, - float x1offset, float y1offset, - float x2offset, float y2offset, - float x1, float y1, - float x2, float y2, - float x3, float y3, - float x4, float y4) +static INLINE void +setup_vertex1(float vertex[2][4], float x, float y, float s, float t) { - struct pipe_context *pipe = exa->ctx; - struct pipe_buffer *buf; + vertex[0][0] = x; + vertex[0][1] = y; + vertex[0][2] = 0.f; /*z*/ + vertex[0][3] = 1.f; /*w*/ + + vertex[1][0] = s; /*s*/ + vertex[1][1] = t; /*t*/ + vertex[1][2] = 0.f; /*r*/ + vertex[1][3] = 1.f; /*q*/ +} + +static struct pipe_buffer * +setup_vertex_data1(struct exa_context *ctx, + int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height) +{ + float vertices[4][2][4]; float s0, t0, s1, t1; + struct pipe_texture *src = ctx->bound_textures[0]; + + s0 = srcX / src->width[0]; + s1 = srcX + width / src->width[0]; + t0 = srcY / src->height[0]; + t1 = srcY + height / src->height[0]; + + /* 1st vertex */ + setup_vertex1(vertices[0], dstX, dstY, + s0, t0); + /* 2nd vertex */ + setup_vertex1(vertices[1], dstX + width, dstY, + s1, t0); + /* 3rd vertex */ + setup_vertex1(vertices[2], dstX + width, dstY + height, + s1, t1); + /* 4th vertex */ + setup_vertex1(vertices[3], dstX, dstY + height, + s0, t1); - assert(tex->width[0] != 0); - assert(tex->height[0] != 0); + return pipe_user_buffer_create(ctx->ctx->screen, + vertices, + sizeof(vertices)); +} - s0 = x1offset / tex->width[0]; - s1 = x2offset / tex->width[0]; - t0 = y1offset / tex->height[0]; - t1 = y2offset / tex->height[0]; - /* draw quad */ - buf = setup_vertex_data_tex(exa, x1, y1, x2, y2, x3, y3, x4, y4, - s0, t0, s1, t1, 0.0f); +static INLINE void +setup_vertex2(float vertex[3][4], float x, float y, + float s0, float t0, float s1, float t1) +{ + vertex[0][0] = x; + vertex[0][1] = y; + vertex[0][2] = 0.f; /*z*/ + vertex[0][3] = 1.f; /*w*/ + + vertex[1][0] = s0; /*s*/ + vertex[1][1] = t0; /*t*/ + vertex[1][2] = 0.f; /*r*/ + vertex[1][3] = 1.f; /*q*/ + + vertex[2][0] = s1; /*s*/ + vertex[2][1] = t1; /*t*/ + vertex[2][2] = 0.f; /*r*/ + vertex[2][3] = 1.f; /*q*/ +} + +static struct pipe_buffer * +setup_vertex_data2(struct exa_context *ctx, + int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height) +{ + float vertices[4][3][4]; + float st0[4], st1[4]; + struct pipe_texture *src = ctx->bound_textures[0]; + struct pipe_texture *mask = ctx->bound_textures[0]; + + st0[0] = srcX / src->width[0]; + st0[1] = srcY / src->height[0]; + st0[2] = srcX + width / src->width[0]; + st0[3] = srcY + height / src->height[0]; + + st1[0] = maskX / mask->width[0]; + st1[1] = maskY / mask->height[0]; + st1[2] = maskX + width / mask->width[0]; + st1[3] = maskY + height / mask->height[0]; + + /* 1st vertex */ + setup_vertex2(vertices[0], dstX, dstY, + st0[0], st0[1], st1[0], st1[1]); + /* 2nd vertex */ + setup_vertex2(vertices[1], dstX + width, dstY, + st0[2], st0[1], st1[2], st1[1]); + /* 3rd vertex */ + setup_vertex2(vertices[2], dstX + width, dstY + height, + st0[2], st0[3], st1[2], st1[3]); + /* 4th vertex */ + setup_vertex2(vertices[3], dstX, dstY + height, + st0[0], st0[3], st1[0], st1[3]); + + return pipe_user_buffer_create(ctx->ctx->screen, + vertices, + sizeof(vertices)); +} + + +static void +draw_pictures(struct exa_context *exa, + int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height) +{ + struct pipe_context *pipe = exa->ctx; + struct pipe_buffer *buf = 0; + + if (exa->num_bound_samplers == 0 ) { /* solid fill */ + buf = setup_vertex_data0(exa, + srcX, srcY, maskX, maskY, + dstX, dstY, width, height); + } else if (exa->num_bound_samplers == 1 ) /* src */ + buf = setup_vertex_data1(exa, + srcX, srcY, maskX, maskY, + dstX, dstY, width, height); + else if (exa->num_bound_samplers == 2) /* src + mask */ + buf = setup_vertex_data2(exa, + srcX, srcY, maskX, maskY, + dstX, dstY, width, height); + else if (exa->num_bound_samplers == 3) { /* src + mask + dst */ + debug_assert(!"src/mask/dst not handled right now"); +#if 0 + buf = setup_vertex_data2(exa, + srcX, srcY, maskX, maskY, + dstX, dstY, width, height); +#endif + } if (buf) { util_draw_vertex_buffer(pipe, buf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, /* verts */ - 2); /* attribs/vert */ + 1 + exa->num_bound_samplers); /* attribs/vert */ - pipe_buffer_reference(&buf, - NULL); + pipe_buffer_reference(&buf, NULL); } - - cso_restore_vertex_shader(exa->cso); } boolean xorg_composite_accelerated(int op, @@ -309,9 +419,10 @@ bind_samplers(struct exa_context *exa, int op, struct exa_pixmap_priv *pDst) { struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS]; - struct pipe_texture *textures[PIPE_MAX_SAMPLERS]; struct pipe_sampler_state src_sampler, mask_sampler; + exa->num_bound_samplers = 0; + memset(&src_sampler, 0, sizeof(struct pipe_sampler_state)); memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state)); @@ -322,7 +433,8 @@ bind_samplers(struct exa_context *exa, int op, src_sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST; src_sampler.normalized_coords = 1; samplers[0] = &src_sampler; - textures[0] = pSrc->tex; + exa->bound_textures[0] = pSrc->tex; + ++exa->num_bound_samplers; } if (pMaskPicture && pMask) { @@ -332,12 +444,14 @@ bind_samplers(struct exa_context *exa, int op, mask_sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST; mask_sampler.normalized_coords = 1; samplers[1] = &mask_sampler; - textures[1] = pMask->tex; + exa->bound_textures[1] = pMask->tex; + ++exa->num_bound_samplers; } - cso_set_samplers(exa->cso, 3, + cso_set_samplers(exa->cso, exa->num_bound_samplers, (const struct pipe_sampler_state **)samplers); - cso_set_sampler_textures(exa->cso, 3, textures); + cso_set_sampler_textures(exa->cso, exa->num_bound_samplers, + exa->bound_textures); } static void @@ -409,8 +523,8 @@ boolean xorg_composite_bind_state(struct exa_context *exa, bind_blend_state(exa, op, pSrcPicture, pMaskPicture); bind_rasterizer_state(exa); bind_shaders(exa, op, pSrcPicture, pMaskPicture); - bind_samplers(exa, op, pSrcPicture, pMaskPicture, pDstPicture, - pSrc, pMask, pDst); + bind_samplers(exa, op, pSrcPicture, pMaskPicture, + pDstPicture, pSrc, pMask, pDst); setup_constant_buffers(exa, pDstPicture); @@ -422,5 +536,7 @@ void xorg_composite(struct exa_context *exa, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int width, int height) { + draw_pictures(exa, srcX, srcY, maskX, maskY, + dstX, dstY, width, height); } diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index 3697d26363e..1ed807de93d 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -563,7 +563,6 @@ xorg_exa_init(ScrnInfoPtr pScrn) modesettingPtr ms = modesettingPTR(pScrn); struct exa_context *exa; ExaDriverPtr pExa; - int i; exa = xcalloc(1, sizeof(struct exa_context)); if (!exa) @@ -615,13 +614,6 @@ xorg_exa_init(ScrnInfoPtr pScrn) /* Share context with DRI */ ms->ctx = exa->ctx; - /* common vertex data setup */ - for (i = 0; i < 4; ++i) { - exa->vertices[i][0][3] = 1.0f; /* w */ - exa->vertices[i][1][2] = 0.0f; /* r */ - exa->vertices[i][1][3] = 1.0f; /* q */ - } - exa->cso = cso_create_context(exa->ctx); exa->shaders = xorg_shaders_create(exa); diff --git a/src/gallium/state_trackers/xorg/xorg_exa.h b/src/gallium/state_trackers/xorg/xorg_exa.h index 90ad8400ffd..d4ffe5ce2e8 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.h +++ b/src/gallium/state_trackers/xorg/xorg_exa.h @@ -8,6 +8,9 @@ struct cso_context; struct xorg_shaders; +/* src + mask + dst */ +#define MAX_EXA_SAMPLERS 3 + struct exa_context { ExaDriverPtr pExa; @@ -19,7 +22,10 @@ struct exa_context struct pipe_constant_buffer vs_const_buffer; struct pipe_constant_buffer fs_const_buffer; - float vertices[4][2][4]; + struct pipe_texture *bound_textures[MAX_EXA_SAMPLERS]; + int num_bound_samplers; + + float solid_color[4]; };