summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers
diff options
context:
space:
mode:
authorChristian König <[email protected]>2011-07-11 10:48:59 +0200
committerChristian König <[email protected]>2011-07-11 10:48:59 +0200
commitf919547f3785b1d8839b9fc5c00ac397e30896a1 (patch)
tree910cd4fd7ffcd2781a303bb79395a0ee3c044c7d /src/gallium/state_trackers
parentcd4f18089e44872ce9e3c04ac5e808a7204ffc49 (diff)
parent12265d26ddc72f62de927ac24e12ab41fcd8d1c5 (diff)
Merge remote-tracking branch 'origin/master' into pipe-video
Conflicts: src/gallium/drivers/r600/r600_pipe.c src/gallium/drivers/r600/r600_state_inlines.h
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r--src/gallium/state_trackers/dri/common/dri_context.c2
-rw-r--r--src/gallium/state_trackers/egl/x11/x11_screen.c18
-rw-r--r--src/gallium/state_trackers/xa/xa_composite.c111
-rw-r--r--src/gallium/state_trackers/xa/xa_context.c9
-rw-r--r--src/gallium/state_trackers/xa/xa_priv.h12
-rw-r--r--src/gallium/state_trackers/xa/xa_renderer.c8
-rw-r--r--src/gallium/state_trackers/xa/xa_tgsi.c22
7 files changed, 131 insertions, 51 deletions
diff --git a/src/gallium/state_trackers/dri/common/dri_context.c b/src/gallium/state_trackers/dri/common/dri_context.c
index 08bbdf96e34..e6612b1911d 100644
--- a/src/gallium/state_trackers/dri/common/dri_context.c
+++ b/src/gallium/state_trackers/dri/common/dri_context.c
@@ -143,8 +143,6 @@ dri_unbind_context(__DRIcontext * cPriv)
/* dri_util.c ensures cPriv is not null */
struct dri_screen *screen = dri_screen(cPriv->driScreenPriv);
struct dri_context *ctx = dri_context(cPriv);
- struct dri_drawable *draw = dri_drawable(ctx->dPriv);
- struct dri_drawable *read = dri_drawable(ctx->rPriv);
struct st_api *stapi = screen->st_api;
if (--ctx->bind_count == 0) {
diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.c b/src/gallium/state_trackers/egl/x11/x11_screen.c
index f1cc4400ba5..6155b4d03c0 100644
--- a/src/gallium/state_trackers/egl/x11/x11_screen.c
+++ b/src/gallium/state_trackers/egl/x11/x11_screen.c
@@ -452,6 +452,12 @@ dri2InvalidateBuffers(Display *dpy, XID drawable)
extern unsigned
dri2GetSwapEventType(Display *dpy, XID drawable);
+extern void *
+dri2GetGlxDrawableFromXDrawableId(Display *dpy, XID id);
+
+extern void *
+GetGLXDrawable(Display *dpy, XID drawable);
+
/**
* This is also called from src/glx/dri2.c.
*/
@@ -460,4 +466,16 @@ unsigned dri2GetSwapEventType(Display *dpy, XID drawable)
return 0;
}
+void *
+dri2GetGlxDrawableFromXDrawableId(Display *dpy, XID id)
+{
+ return NULL;
+}
+
+void *
+GetGLXDrawable(Display *dpy, XID drawable)
+{
+ return NULL;
+}
+
#endif /* GLX_DIRECT_RENDERING */
diff --git a/src/gallium/state_trackers/xa/xa_composite.c b/src/gallium/state_trackers/xa/xa_composite.c
index 5389af6f363..347fe0cd379 100644
--- a/src/gallium/state_trackers/xa/xa_composite.c
+++ b/src/gallium/state_trackers/xa/xa_composite.c
@@ -79,6 +79,25 @@ static const struct xa_composite_blend xa_blends[] = {
};
+/*
+ * The alpha value stored in a luminance texture is read by the
+ * hardware as color.
+ */
+static unsigned
+xa_convert_blend_for_luminance(unsigned factor)
+{
+ switch(factor) {
+ case PIPE_BLENDFACTOR_DST_ALPHA:
+ return PIPE_BLENDFACTOR_DST_COLOR;
+ case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+ return PIPE_BLENDFACTOR_INV_DST_COLOR;
+ default:
+ break;
+ }
+ return factor;
+}
+
+
static boolean
blend_for_op(struct xa_composite_blend *blend,
enum xa_composite_op op,
@@ -92,9 +111,15 @@ blend_for_op(struct xa_composite_blend *blend,
boolean supported = FALSE;
/*
- * our default in case something goes wrong
+ * Temporarily disable component alpha since it appears buggy.
*/
+ if (src_pic->component_alpha ||
+ (mask_pic && mask_pic->component_alpha))
+ return FALSE;
+ /*
+ * our default in case something goes wrong
+ */
*blend = xa_blends[XA_BLEND_OP_OVER];
for (i = 0; i < num_blends; ++i) {
@@ -104,15 +129,20 @@ blend_for_op(struct xa_composite_blend *blend,
}
}
+ if (!dst_pic->srf)
+ return supported;
+
+ if (dst_pic->srf->tex->format == PIPE_FORMAT_L8_UNORM) {
+ blend->rgb_src = xa_convert_blend_for_luminance(blend->rgb_src);
+ blend->rgb_dst = xa_convert_blend_for_luminance(blend->rgb_dst);
+ }
/*
* If there's no dst alpha channel, adjust the blend op so that we'll treat
* it as always 1.
*/
- if (dst_pic &&
- xa_format_a(dst_pic->pict_format) == 0 &&
- blend->alpha_dst) {
+ if (xa_format_a(dst_pic->pict_format) == 0 && blend->alpha_dst) {
if (blend->rgb_src == PIPE_BLENDFACTOR_DST_ALPHA)
blend->rgb_src = PIPE_BLENDFACTOR_ONE;
else if (blend->rgb_src == PIPE_BLENDFACTOR_INV_DST_ALPHA)
@@ -191,13 +221,13 @@ xa_composite_check_accelerated(const struct xa_composite *comp)
if (!xa_is_filter_accelerated(src_pic) ||
!xa_is_filter_accelerated(comp->mask)) {
- return XA_ERR_INVAL;
+ return -XA_ERR_INVAL;
}
if (src_pic->src_pict) {
if (src_pic->src_pict->type != xa_src_pict_solid_fill)
- return XA_ERR_INVAL;
+ return -XA_ERR_INVAL;
}
if (blend_for_op(&blend, comp->op, comp->src, comp->mask, comp->dst)) {
@@ -205,23 +235,24 @@ xa_composite_check_accelerated(const struct xa_composite *comp)
if (mask && mask->component_alpha &&
xa_format_rgb(mask->pict_format)) {
if (blend.alpha_src && blend.rgb_src != PIPE_BLENDFACTOR_ZERO) {
- return XA_ERR_INVAL;
+ return -XA_ERR_INVAL;
}
}
return XA_ERR_NONE;
}
- return XA_ERR_INVAL;
+ return -XA_ERR_INVAL;
}
-static void
+static int
bind_composite_blend_state(struct xa_context *ctx,
const struct xa_composite *comp)
{
struct xa_composite_blend blend_opt;
struct pipe_blend_state blend;
- blend_for_op(&blend_opt, comp->op, comp->src, comp->mask, comp->dst);
+ if (!blend_for_op(&blend_opt, comp->op, comp->src, comp->mask, comp->dst))
+ return -XA_ERR_INVAL;
memset(&blend, 0, sizeof(struct pipe_blend_state));
blend.rt[0].blend_enable = 1;
@@ -233,11 +264,11 @@ bind_composite_blend_state(struct xa_context *ctx,
blend.rt[0].alpha_dst_factor = blend_opt.rgb_dst;
cso_set_blend(ctx->cso, &blend);
+ return XA_ERR_NONE;
}
static unsigned int
picture_format_fixups(struct xa_picture *src_pic,
- struct xa_picture *dst_pic,
int mask)
{
boolean set_alpha = FALSE;
@@ -253,22 +284,17 @@ picture_format_fixups(struct xa_picture *src_pic,
src_hw_format = xa_surface_format(src);
src_pic_format = src_pic->pict_format;
- if (!src || src_hw_format == src_pic_format) {
- if (src_pic_format == xa_format_a8) {
- if (mask)
- return FS_MASK_LUMINANCE;
- else if (dst_pic->pict_format != xa_format_a8) {
-
- /*
- * if both dst and src are luminance then
- * we don't want to swizzle the alpha (X) of the
- * source into W component of the dst because
- * it will break our destination
- */
- return FS_SRC_LUMINANCE;
- }
- }
- return 0;
+ set_alpha = (xa_format_type_is_color(src_pic_format) &&
+ xa_format_a(src_pic_format) == 0);
+
+ if (set_alpha)
+ ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA;
+
+ if (src_hw_format == src_pic_format) {
+ if (src->tex->format == PIPE_FORMAT_L8_UNORM)
+ return ((mask) ? FS_MASK_LUMINANCE : FS_SRC_LUMINANCE);
+
+ return ret;
}
src_hw_type = xa_format_type(src_hw_format);
@@ -280,27 +306,21 @@ picture_format_fixups(struct xa_picture *src_pic,
src_pic_type == xa_type_argb)));
if (!swizzle && (src_hw_type != src_pic_type))
- return 0;
+ return ret;
- set_alpha = (xa_format_type_is_color(src_pic_format) &&
- xa_format_a(src_pic_type) == 0);
-
- if (set_alpha)
- ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA;
if (swizzle)
ret |= mask ? FS_MASK_SWIZZLE_RGB : FS_SRC_SWIZZLE_RGB;
return ret;
}
-static void
+static int
bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
{
unsigned vs_traits = 0, fs_traits = 0;
struct xa_shader shader;
struct xa_picture *src_pic = comp->src;
struct xa_picture *mask_pic = comp->mask;
- struct xa_picture *dst_pic = comp->dst;
ctx->has_solid_color = FALSE;
@@ -321,7 +341,7 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
vs_traits |= VS_COMPOSITE;
}
- fs_traits |= picture_format_fixups(src_pic, dst_pic, 0);
+ fs_traits |= picture_format_fixups(src_pic, 0);
}
if (mask_pic) {
@@ -333,19 +353,25 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
if (mask_pic->component_alpha) {
struct xa_composite_blend blend;
- blend_for_op(&blend, comp->op, src_pic, mask_pic, NULL);
+ if (!blend_for_op(&blend, comp->op, src_pic, mask_pic, NULL))
+ return -XA_ERR_INVAL;
+
if (blend.alpha_src) {
fs_traits |= FS_CA_SRCALPHA;
} else
fs_traits |= FS_CA_FULL;
}
- fs_traits |= picture_format_fixups(mask_pic, dst_pic, 1);
+ fs_traits |= picture_format_fixups(mask_pic, 1);
}
+ if (ctx->dst->srf->format == PIPE_FORMAT_L8_UNORM)
+ fs_traits |= FS_DST_LUMINANCE;
+
shader = xa_shaders_get(ctx->shaders, vs_traits, fs_traits);
cso_set_vertex_shader_handle(ctx->cso, shader.vs);
cso_set_fragment_shader_handle(ctx->cso, shader.fs);
+ return XA_ERR_NONE;
}
static void
@@ -433,12 +459,17 @@ xa_composite_prepare(struct xa_context *ctx,
if (ret != XA_ERR_NONE)
return ret;
+ ctx->dst = dst_srf;
renderer_bind_destination(ctx, dst_srf->srf,
dst_srf->srf->width,
dst_srf->srf->height);
- bind_composite_blend_state(ctx, comp);
- bind_shaders(ctx, comp);
+ ret = bind_composite_blend_state(ctx, comp);
+ if (ret != XA_ERR_NONE)
+ return ret;
+ ret = bind_shaders(ctx, comp);
+ if (ret != XA_ERR_NONE)
+ return ret;
bind_samplers(ctx, comp);
if (ctx->num_bound_samplers == 0 ) { /* solid fill */
diff --git a/src/gallium/state_trackers/xa/xa_context.c b/src/gallium/state_trackers/xa/xa_context.c
index 3cc25ed2071..118a390a14a 100644
--- a/src/gallium/state_trackers/xa/xa_context.c
+++ b/src/gallium/state_trackers/xa/xa_context.c
@@ -278,13 +278,16 @@ xa_solid_prepare(struct xa_context *ctx, struct xa_surface *dst,
int width, height;
int ret;
- xa_pixel_to_float4(fg, ctx->solid_color);
- ctx->has_solid_color = 1;
-
ret = xa_surface_psurf_create(ctx, dst);
if (ret != XA_ERR_NONE)
return ret;
+ if (dst->srf->format == PIPE_FORMAT_L8_UNORM)
+ xa_pixel_to_float4_a8(fg, ctx->solid_color);
+ else
+ xa_pixel_to_float4(fg, ctx->solid_color);
+ ctx->has_solid_color = 1;
+
ctx->dst = dst;
width = dst->srf->width;
height = dst->srf->height;
diff --git a/src/gallium/state_trackers/xa/xa_priv.h b/src/gallium/state_trackers/xa/xa_priv.h
index 94627e1e9d0..e8f67a12276 100644
--- a/src/gallium/state_trackers/xa/xa_priv.h
+++ b/src/gallium/state_trackers/xa/xa_priv.h
@@ -135,6 +135,7 @@ enum xa_fs_traits {
FS_MASK_SET_ALPHA = 1 << 13,
FS_SRC_LUMINANCE = 1 << 14,
FS_MASK_LUMINANCE = 1 << 15,
+ FS_DST_LUMINANCE = 1 << 16,
FS_FILL = (FS_SOLID_FILL | FS_LINGRAD_FILL | FS_RADGRAD_FILL),
FS_COMPONENT_ALPHA = (FS_CA_FULL | FS_CA_SRCALPHA)
@@ -172,6 +173,17 @@ xa_pixel_to_float4(uint32_t pixel, float *color)
color[3] = ((float)a) / 255.;
}
+static INLINE void
+xa_pixel_to_float4_a8(uint32_t pixel, float *color)
+{
+ uint32_t a;
+
+ a = (pixel >> 24) & 0xff;
+ color[0] = ((float)a) / 255.;
+ color[1] = ((float)a) / 255.;
+ color[2] = ((float)a) / 255.;
+ color[3] = ((float)a) / 255.;
+}
/*
* xa_tgsi.c
diff --git a/src/gallium/state_trackers/xa/xa_renderer.c b/src/gallium/state_trackers/xa/xa_renderer.c
index 559b2699da6..ef762f0ab49 100644
--- a/src/gallium/state_trackers/xa/xa_renderer.c
+++ b/src/gallium/state_trackers/xa/xa_renderer.c
@@ -418,6 +418,7 @@ renderer_copy_prepare(struct xa_context *r,
struct pipe_context *pipe = r->pipe;
struct pipe_screen *screen = pipe->screen;
struct xa_shader shader;
+ uint32_t fs_traits = FS_COMPOSITE;
assert(screen->is_format_supported(screen, dst_surface->format,
PIPE_TEXTURE_2D, 0,
@@ -469,7 +470,12 @@ renderer_copy_prepare(struct xa_context *r,
}
/* shaders */
- shader = xa_shaders_get(r->shaders, VS_COMPOSITE, FS_COMPOSITE);
+ if (src_texture->format == PIPE_FORMAT_L8_UNORM)
+ fs_traits |= FS_SRC_LUMINANCE;
+ if (dst_surface->format == PIPE_FORMAT_L8_UNORM)
+ fs_traits |= FS_DST_LUMINANCE;
+
+ shader = xa_shaders_get(r->shaders, VS_COMPOSITE, fs_traits);
cso_set_vertex_shader_handle(r->cso, shader.vs);
cso_set_fragment_shader_handle(r->cso, shader.fs);
diff --git a/src/gallium/state_trackers/xa/xa_tgsi.c b/src/gallium/state_trackers/xa/xa_tgsi.c
index fb6ffefd636..ed1690ed369 100644
--- a/src/gallium/state_trackers/xa/xa_tgsi.c
+++ b/src/gallium/state_trackers/xa/xa_tgsi.c
@@ -85,6 +85,7 @@ print_fs_traits(int fs_traits)
"FS_MASK_SET_ALPHA", /* = 1 << 13, */
"FS_SRC_LUMINANCE", /* = 1 << 14, */
"FS_MASK_LUMINANCE", /* = 1 << 15, */
+ "FS_DST_LUMINANCE", /* = 1 << 15, */
};
int i, k;
@@ -454,6 +455,7 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
unsigned mask_set_alpha = (fs_traits & FS_MASK_SET_ALPHA) != 0;
unsigned src_luminance = (fs_traits & FS_SRC_LUMINANCE) != 0;
unsigned mask_luminance = (fs_traits & FS_MASK_LUMINANCE) != 0;
+ unsigned dst_luminance = (fs_traits & FS_DST_LUMINANCE) != 0;
#if 0
print_fs_traits(fs_traits);
@@ -508,7 +510,7 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
#endif
if (is_composite) {
- if (has_mask || src_luminance)
+ if (has_mask || src_luminance || dst_luminance)
src = ureg_DECL_temporary(ureg);
else
src = out;
@@ -516,14 +518,14 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
src_repeat_none, src_swizzle, src_set_alpha);
} else if (is_fill) {
if (is_solid) {
- if (has_mask || src_luminance)
+ if (has_mask || src_luminance || dst_luminance)
src = ureg_dst(src_input);
else
ureg_MOV(ureg, out, src_input);
} else if (is_lingrad || is_radgrad) {
struct ureg_src coords, const0124, matrow0, matrow1, matrow2;
- if (has_mask || src_luminance)
+ if (has_mask || src_luminance || dst_luminance)
src = ureg_DECL_temporary(ureg);
else
src = out;
@@ -550,7 +552,7 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
ureg_MOV(ureg, src, ureg_scalar(ureg_src(src), TGSI_SWIZZLE_X));
ureg_MOV(ureg, ureg_writemask(src, TGSI_WRITEMASK_XYZ),
ureg_scalar(imm0, TGSI_SWIZZLE_X));
- if (!has_mask)
+ if (!has_mask && !dst_luminance)
ureg_MOV(ureg, out, ureg_src(src));
}
@@ -559,11 +561,21 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0,
mask_repeat_none, mask_swizzle, mask_set_alpha);
/* src IN mask */
- src_in_mask(ureg, out, ureg_src(src), ureg_src(mask),
+
+ src_in_mask(ureg, (dst_luminance) ? src : out, ureg_src(src),
+ ureg_src(mask),
comp_alpha_mask, mask_luminance);
+
ureg_release_temporary(ureg, mask);
}
+ if (dst_luminance) {
+ /*
+ * Make sure the alpha channel goes into the output L8 surface.
+ */
+ ureg_MOV(ureg, out, ureg_scalar(ureg_src(src), TGSI_SWIZZLE_W));
+ }
+
ureg_END(ureg);
return ureg_create_shader_and_destroy(ureg, pipe);