st/xorg: start rendering and compositing pictures

This commit is contained in:
Zack Rusin 2009-09-01 14:43:04 -04:00
parent 847bc5c852
commit 91c366359c
3 changed files with 188 additions and 74 deletions

View file

@ -77,79 +77,189 @@ blend_for_op(int op)
}
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)
static INLINE void
setup_vertex0(float vertex[2][4], float x, float y,
float color[4])
{
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*/
vertex[0][0] = x;
vertex[0][1] = y;
vertex[0][2] = 0.f; /*z*/
vertex[0][3] = 1.f; /*w*/
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;
return pipe_user_buffer_create(ctx->ctx->screen,
ctx->vertices,
sizeof(ctx->vertices));
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_data0(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];
/* 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,
vertices,
sizeof(vertices));
}
static INLINE void
setup_vertex1(float vertex[2][4], float x, float y, float s, float t)
{
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);
return pipe_user_buffer_create(ctx->ctx->screen,
vertices,
sizeof(vertices));
}
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_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)
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;
float s0, t0, s1, t1;
struct pipe_buffer *buf = 0;
assert(tex->width[0] != 0);
assert(tex->height[0] != 0);
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);
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);
}

View file

@ -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);

View file

@ -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];
};