[Mesa-dev] [PATCH 1/4] st/xa: Render update. Better support for solid pictures

Thomas Hellstrom thellstrom at vmware.com
Tue Nov 13 07:35:24 UTC 2018


Remove unused and obsolete code for gradients and component-alpha
Support solid source- and mask pictures using a variable number
of samplers in the composite pipeline rather than the fixed number
we used before.

Tested using rendercheck for XA.

Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
Reviewed-by: Brian Paul <brianp at vmware.com>
---
 src/gallium/state_trackers/xa/xa_composite.c | 211 +++++------
 src/gallium/state_trackers/xa/xa_context.c   |  10 +-
 src/gallium/state_trackers/xa/xa_priv.h      |  44 +--
 src/gallium/state_trackers/xa/xa_renderer.c  |  46 ++-
 src/gallium/state_trackers/xa/xa_tgsi.c      | 354 +++++--------------
 5 files changed, 225 insertions(+), 440 deletions(-)

diff --git a/src/gallium/state_trackers/xa/xa_composite.c b/src/gallium/state_trackers/xa/xa_composite.c
index bcb27ea1825..8de51b34d96 100644
--- a/src/gallium/state_trackers/xa/xa_composite.c
+++ b/src/gallium/state_trackers/xa/xa_composite.c
@@ -112,7 +112,7 @@ blend_for_op(struct xa_composite_blend *blend,
     boolean supported = FALSE;
 
     /*
-     * Temporarily disable component alpha since it appears buggy.
+     * No component alpha yet.
      */
     if (mask_pic && mask_pic->component_alpha)
 	return FALSE;
@@ -126,6 +126,7 @@ blend_for_op(struct xa_composite_blend *blend,
 	if (xa_blends[i].op == op) {
 	    *blend = xa_blends[i];
 	    supported = TRUE;
+            break;
 	}
     }
 
@@ -150,21 +151,6 @@ blend_for_op(struct xa_composite_blend *blend,
 	    blend->rgb_src = PIPE_BLENDFACTOR_ZERO;
     }
 
-    /*
-     * If the source alpha is being used, then we should only be in a case where
-     * the source blend factor is 0, and the source blend value is the mask
-     * channels multiplied by the source picture's alpha.
-     */
-    if (mask_pic && mask_pic->component_alpha &&
-	xa_format_rgb(mask_pic->pict_format) &&
-	blend->alpha_src) {
-	if (blend->rgb_dst == PIPE_BLENDFACTOR_SRC_ALPHA) {
-	    blend->rgb_dst = PIPE_BLENDFACTOR_SRC_COLOR;
-	} else if (blend->rgb_dst == PIPE_BLENDFACTOR_INV_SRC_ALPHA) {
-	    blend->rgb_dst = PIPE_BLENDFACTOR_INV_SRC_COLOR;
-	}
-    }
-
     return supported;
 }
 
@@ -219,38 +205,26 @@ xa_composite_check_accelerated(const struct xa_composite *comp)
 {
     struct xa_composite_blend blend;
     struct xa_picture *src_pic = comp->src;
+    struct xa_picture *mask_pic = comp->mask;
+
+    /*
+     * No component alpha yet.
+     */
+    if (mask_pic && mask_pic->component_alpha)
+	return -XA_ERR_INVAL;
 
     if (!xa_is_filter_accelerated(src_pic) ||
 	!xa_is_filter_accelerated(comp->mask)) {
 	return -XA_ERR_INVAL;
     }
 
+    if (src_pic->src_pict &&src_pic->src_pict->type != xa_src_pict_solid_fill)
+        return -XA_ERR_INVAL;
 
-    if (src_pic->src_pict) {
-	if (src_pic->src_pict->type != xa_src_pict_solid_fill)
-	    return -XA_ERR_INVAL;
-
-	/*
-	 * Currently we don't support solid fill with a mask.
-	 * We can easily do that, but that would require shader,
-	 * sampler view setup and vertex setup modification.
-	 */
-	if (comp->mask)
-	    return -XA_ERR_INVAL;
-    }
-
-    if (blend_for_op(&blend, comp->op, comp->src, comp->mask, comp->dst)) {
-	struct xa_picture *mask = comp->mask;
-	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;
-	    }
-	}
+    if (!blend_for_op(&blend, comp->op, comp->src, comp->mask, comp->dst))
+	return -XA_ERR_INVAL;
 
-	return XA_ERR_NONE;
-    }
-    return -XA_ERR_INVAL;
+    return XA_ERR_NONE;
 }
 
 static int
@@ -293,7 +267,7 @@ picture_format_fixups(struct xa_picture *src_pic,
     src_hw_format = xa_surface_format(src);
     src_pic_format = src_pic->pict_format;
 
-    set_alpha = (xa_format_type_is_color(src_pic_format) &&
+    set_alpha = (xa_format_type_is_color(src_hw_format) &&
 		 xa_format_a(src_pic_format) == 0);
 
     if (set_alpha)
@@ -324,6 +298,15 @@ picture_format_fixups(struct xa_picture *src_pic,
     return ret;
 }
 
+static void
+xa_src_in_mask(float src[4], const float mask[4])
+{
+	src[0] *= mask[3];
+	src[1] *= mask[3];
+	src[2] *= mask[3];
+	src[3] *= mask[3];
+}
+
 static int
 bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
 {
@@ -332,47 +315,56 @@ bind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
     struct xa_picture *src_pic = comp->src;
     struct xa_picture *mask_pic = comp->mask;
 
-    ctx->has_solid_color = FALSE;
+    ctx->has_solid_src = FALSE;
+    ctx->has_solid_mask = FALSE;
 
     if (src_pic) {
 	if (src_pic->wrap == xa_wrap_clamp_to_border && src_pic->has_transform)
 	    fs_traits |= FS_SRC_REPEAT_NONE;
 
+        fs_traits |= FS_COMPOSITE;
+        vs_traits |= VS_COMPOSITE;
+
 	if (src_pic->src_pict) {
 	    if (src_pic->src_pict->type == xa_src_pict_solid_fill) {
-		fs_traits |= FS_SOLID_FILL | FS_FILL;
-		vs_traits |= VS_SOLID_FILL;
+               fs_traits |= FS_SRC_SRC;
+		vs_traits |= VS_SRC_SRC;
 		xa_pixel_to_float4(src_pic->src_pict->solid_fill.color,
 				   ctx->solid_color);
-		ctx->has_solid_color = TRUE;
+		ctx->has_solid_src = TRUE;
 	    }
-	} else {
-	    fs_traits |= FS_COMPOSITE;
-	    vs_traits |= VS_COMPOSITE;
-	}
-
-	fs_traits |= picture_format_fixups(src_pic, 0);
+	} else
+           fs_traits |= picture_format_fixups(src_pic, 0);
     }
 
     if (mask_pic) {
 	vs_traits |= VS_MASK;
 	fs_traits |= FS_MASK;
-	if (mask_pic->wrap == xa_wrap_clamp_to_border &&
-	    mask_pic->has_transform)
-	    fs_traits |= FS_MASK_REPEAT_NONE;
-
-	if (mask_pic->component_alpha) {
-	    struct xa_composite_blend blend;
-	    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, 1);
+        if (mask_pic->src_pict) {
+            if (mask_pic->src_pict->type == xa_src_pict_solid_fill) {
+                if (ctx->has_solid_src) {
+                    float solid_mask[4];
+
+                    xa_pixel_to_float4(mask_pic->src_pict->solid_fill.color,
+                                       solid_mask);
+                    xa_src_in_mask(ctx->solid_color, solid_mask);
+                    vs_traits &= ~(VS_MASK);
+                    fs_traits &= ~(FS_MASK);
+                } else {
+                    xa_pixel_to_float4(mask_pic->src_pict->solid_fill.color,
+                                       ctx->solid_color);
+                    vs_traits |= VS_MASK_SRC;
+                    fs_traits |= FS_MASK_SRC;
+                }
+                ctx->has_solid_mask = TRUE;
+            }
+        } else {
+            if (mask_pic->wrap == xa_wrap_clamp_to_border &&
+                mask_pic->has_transform)
+                fs_traits |= FS_MASK_REPEAT_NONE;
+
+            fs_traits |= picture_format_fixups(mask_pic, 1);
+        }
     }
 
     if (ctx->srf->format == PIPE_FORMAT_L8_UNORM ||
@@ -396,42 +388,35 @@ bind_samplers(struct xa_context *ctx,
     struct pipe_context *pipe = ctx->pipe;
     struct xa_picture *src_pic = comp->src;
     struct xa_picture *mask_pic = comp->mask;
+    int num_samplers = 0;
 
-    ctx->num_bound_samplers = 0;
-
+    xa_ctx_sampler_views_destroy(ctx);
     memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
     memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
 
-    if (src_pic) {
-	if (ctx->has_solid_color) {
-	    samplers[0] = NULL;
-	    pipe_sampler_view_reference(&ctx->bound_sampler_views[0], NULL);
-	} else {
-	    unsigned src_wrap = xa_repeat_to_gallium(src_pic->wrap);
-	    int filter;
-
-	    (void) xa_filter_to_gallium(src_pic->filter, &filter);
-
-	    src_sampler.wrap_s = src_wrap;
-	    src_sampler.wrap_t = src_wrap;
-	    src_sampler.min_img_filter = filter;
-	    src_sampler.mag_img_filter = filter;
-	    src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
-	    src_sampler.normalized_coords = 1;
-	    samplers[0] = &src_sampler;
-	    ctx->num_bound_samplers = 1;
-	    u_sampler_view_default_template(&view_templ,
-					    src_pic->srf->tex,
-					    src_pic->srf->tex->format);
-	    src_view = pipe->create_sampler_view(pipe, src_pic->srf->tex,
-						 &view_templ);
-	    pipe_sampler_view_reference(&ctx->bound_sampler_views[0], NULL);
-	    ctx->bound_sampler_views[0] = src_view;
-	}
+    if (src_pic && !ctx->has_solid_src) {
+	unsigned src_wrap = xa_repeat_to_gallium(src_pic->wrap);
+	int filter;
+
+	(void) xa_filter_to_gallium(src_pic->filter, &filter);
+
+	src_sampler.wrap_s = src_wrap;
+	src_sampler.wrap_t = src_wrap;
+	src_sampler.min_img_filter = filter;
+	src_sampler.mag_img_filter = filter;
+	src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
+	src_sampler.normalized_coords = 1;
+	samplers[0] = &src_sampler;
+	u_sampler_view_default_template(&view_templ,
+					src_pic->srf->tex,+					src_pic->srf->tex->format);
+	src_view = pipe->create_sampler_view(pipe, src_pic->srf->tex,
+					     &view_templ);
+	ctx->bound_sampler_views[0] = src_view;
+	num_samplers++;
     }
 
-    if (mask_pic) {
-	unsigned mask_wrap = xa_repeat_to_gallium(mask_pic->wrap);
+    if (mask_pic && !ctx->has_solid_mask) {
+        unsigned mask_wrap = xa_repeat_to_gallium(mask_pic->wrap);
 	int filter;
 
 	(void) xa_filter_to_gallium(mask_pic->filter, &filter);
@@ -442,31 +427,21 @@ bind_samplers(struct xa_context *ctx,
 	mask_sampler.mag_img_filter = filter;
 	src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
 	mask_sampler.normalized_coords = 1;
-	samplers[1] = &mask_sampler;
-	ctx->num_bound_samplers = 2;
+        samplers[num_samplers] = &mask_sampler;
 	u_sampler_view_default_template(&view_templ,
 					mask_pic->srf->tex,
 					mask_pic->srf->tex->format);
 	src_view = pipe->create_sampler_view(pipe, mask_pic->srf->tex,
 					     &view_templ);
-	pipe_sampler_view_reference(&ctx->bound_sampler_views[1], NULL);
-	ctx->bound_sampler_views[1] = src_view;
-
-
-	/*
-	 * If src is a solid color, we have no src view, so set up a
-	 * dummy one that will not be used anyway.
-	 */
-	if (ctx->bound_sampler_views[0] == NULL)
-	    pipe_sampler_view_reference(&ctx->bound_sampler_views[0],
-					src_view);
-
+        ctx->bound_sampler_views[num_samplers] = src_view;
+        num_samplers++;
     }
 
-    cso_set_samplers(ctx->cso, PIPE_SHADER_FRAGMENT, ctx->num_bound_samplers,
+    cso_set_samplers(ctx->cso, PIPE_SHADER_FRAGMENT, num_samplers,
 		     (const struct pipe_sampler_state **)samplers);
-    cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, ctx->num_bound_samplers,
+    cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, num_samplers,
 				   ctx->bound_sampler_views);
+    ctx->num_bound_samplers = num_samplers;
 }
 
 XA_EXPORT int
@@ -476,9 +451,6 @@ xa_composite_prepare(struct xa_context *ctx,
     struct xa_surface *dst_srf = comp->dst->srf;
     int ret;
 
-    if (comp->mask && !comp->mask->srf)
-	return -XA_ERR_INVAL;
-
     ret = xa_ctx_srf_create(ctx, dst_srf);
     if (ret != XA_ERR_NONE)
 	return ret;
@@ -511,8 +483,8 @@ xa_composite_rect(struct xa_context *ctx,
 		  int dstX, int dstY, int width, int height)
 {
     if (ctx->num_bound_samplers == 0 ) { /* solid fill */
-	renderer_solid(ctx, dstX, dstY, dstX + width, dstY + height,
-		       ctx->solid_color);
+	xa_scissor_update(ctx, dstX, dstY, dstX + width, dstY + height);
+	renderer_solid(ctx, dstX, dstY, dstX + width, dstY + height);
     } else {
 	const struct xa_composite *comp = ctx->comp;
 	int pos[6] = {srcX, srcY, maskX, maskY, dstX, dstY};
@@ -537,7 +509,8 @@ xa_composite_done(struct xa_context *ctx)
     renderer_draw_flush(ctx);
 
     ctx->comp = NULL;
-    ctx->has_solid_color = FALSE;
+    ctx->has_solid_src = FALSE;
+    ctx->has_solid_mask = FALSE;
     xa_ctx_sampler_views_destroy(ctx);
 }
 
diff --git a/src/gallium/state_trackers/xa/xa_context.c b/src/gallium/state_trackers/xa/xa_context.c
index ba220877c84..94f7185272a 100644
--- a/src/gallium/state_trackers/xa/xa_context.c
+++ b/src/gallium/state_trackers/xa/xa_context.c
@@ -308,7 +308,7 @@ xa_solid_prepare(struct xa_context *ctx, struct xa_surface *dst,
 	xa_pixel_to_float4_a8(fg, ctx->solid_color);
     else
 	xa_pixel_to_float4(fg, ctx->solid_color);
-    ctx->has_solid_color = 1;
+    ctx->has_solid_src = 1;
 
     ctx->dst = dst;
 
@@ -320,8 +320,8 @@ xa_solid_prepare(struct xa_context *ctx, struct xa_surface *dst,
 		 exa->solid_color[2], exa->solid_color[3]);
 #endif
 
-    vs_traits = VS_SOLID_FILL;
-    fs_traits = FS_SOLID_FILL;
+    vs_traits = VS_SRC_SRC | VS_COMPOSITE;
+    fs_traits = FS_SRC_SRC | VS_COMPOSITE;
 
     renderer_bind_destination(ctx, ctx->srf);
     bind_solid_blend_state(ctx);
@@ -342,7 +342,7 @@ XA_EXPORT void
 xa_solid(struct xa_context *ctx, int x, int y, int width, int height)
 {
     xa_scissor_update(ctx, x, y, x + width, y + height);
-    renderer_solid(ctx, x, y, x + width, y + height, ctx->solid_color);
+    renderer_solid(ctx, x, y, x + width, y + height);
 }
 
 XA_EXPORT void
@@ -350,7 +350,7 @@ xa_solid_done(struct xa_context *ctx)
 {
     renderer_draw_flush(ctx);
     ctx->comp = NULL;
-    ctx->has_solid_color = FALSE;
+    ctx->has_solid_src = FALSE;
     ctx->num_bound_samplers = 0;
 }
 
diff --git a/src/gallium/state_trackers/xa/xa_priv.h b/src/gallium/state_trackers/xa/xa_priv.h
index c513b8d9629..09a858ff972 100644
--- a/src/gallium/state_trackers/xa/xa_priv.h
+++ b/src/gallium/state_trackers/xa/xa_priv.h
@@ -113,7 +113,8 @@ struct xa_context {
 
     int simple_copy;
 
-    int has_solid_color;
+    int has_solid_src;
+    int has_solid_mask;
     float solid_color[4];
 
     unsigned int num_bound_samplers;
@@ -145,35 +146,26 @@ xa_scissor_update(struct xa_context *ctx, unsigned minx, unsigned miny,
 enum xa_vs_traits {
     VS_COMPOSITE = 1 << 0,
     VS_MASK = 1 << 1,
-    VS_SOLID_FILL = 1 << 2,
-    VS_LINGRAD_FILL = 1 << 3,
-    VS_RADGRAD_FILL = 1 << 4,
-    VS_YUV = 1 << 5,
-
-    VS_FILL = (VS_SOLID_FILL | VS_LINGRAD_FILL | VS_RADGRAD_FILL)
+    VS_SRC_SRC = 1 << 2,
+    VS_MASK_SRC = 1 << 3,
+    VS_YUV = 1 << 4,
 };
 
 enum xa_fs_traits {
     FS_COMPOSITE = 1 << 0,
     FS_MASK = 1 << 1,
-    FS_SOLID_FILL = 1 << 2,
-    FS_LINGRAD_FILL = 1 << 3,
-    FS_RADGRAD_FILL = 1 << 4,
-    FS_CA_FULL = 1 << 5,	/* src.rgba * mask.rgba */
-    FS_CA_SRCALPHA = 1 << 6,	/* src.aaaa * mask.rgba */
-    FS_YUV = 1 << 7,
-    FS_SRC_REPEAT_NONE = 1 << 8,
-    FS_MASK_REPEAT_NONE = 1 << 9,
-    FS_SRC_SWIZZLE_RGB = 1 << 10,
-    FS_MASK_SWIZZLE_RGB = 1 << 11,
-    FS_SRC_SET_ALPHA = 1 << 12,
-    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)
+    FS_SRC_SRC = 1 << 2,
+    FS_MASK_SRC = 1 << 3,
+    FS_YUV = 1 << 4,
+    FS_SRC_REPEAT_NONE = 1 << 5,
+    FS_MASK_REPEAT_NONE = 1 << 6,
+    FS_SRC_SWIZZLE_RGB = 1 << 7,
+    FS_MASK_SWIZZLE_RGB = 1 << 8,
+    FS_SRC_SET_ALPHA = 1 << 9,
+    FS_MASK_SET_ALPHA = 1 << 10,
+    FS_SRC_LUMINANCE = 1 << 11,
+    FS_MASK_LUMINANCE = 1 << 12,
+    FS_DST_LUMINANCE = 1 << 13,
 };
 
 struct xa_shader {
@@ -282,7 +274,7 @@ void renderer_draw_flush(struct xa_context *r);
 
 void renderer_begin_solid(struct xa_context *r);
 void renderer_solid(struct xa_context *r,
-		    int x0, int y0, int x1, int y1, float *color);
+		    int x0, int y0, int x1, int y1);
 void
 renderer_begin_textures(struct xa_context *r);
 
diff --git a/src/gallium/state_trackers/xa/xa_renderer.c b/src/gallium/state_trackers/xa/xa_renderer.c
index d87a14e8088..0cb75a8c968 100644
--- a/src/gallium/state_trackers/xa/xa_renderer.c
+++ b/src/gallium/state_trackers/xa/xa_renderer.c
@@ -137,7 +137,7 @@ renderer_init_state(struct xa_context *r)
 }
 
 static inline void
-add_vertex_color(struct xa_context *r, float x, float y, float color[4])
+add_vertex_none(struct xa_context *r, float x, float y)
 {
     float *vertex = r->buffer + r->buffer_size;
 
@@ -146,12 +146,7 @@ add_vertex_color(struct xa_context *r, float x, float y, float color[4])
     vertex[2] = 0.f;		/*z */
     vertex[3] = 1.f;		/*w */
 
-    vertex[4] = color[0];	/*r */
-    vertex[5] = color[1];	/*g */
-    vertex[6] = color[2];	/*b */
-    vertex[7] = color[3];	/*a */
-
-    r->buffer_size += 8;
+    r->buffer_size += 4;
 }
 
 static inline void
@@ -554,27 +549,29 @@ void
 renderer_begin_solid(struct xa_context *r)
 {
     r->buffer_size = 0;
-    r->attrs_per_vertex = 2;
+    r->attrs_per_vertex = 1;
+    renderer_set_constants(r, PIPE_SHADER_FRAGMENT, r->solid_color,
+                           4 * sizeof(float));
 }
 
 void
 renderer_solid(struct xa_context *r,
-	       int x0, int y0, int x1, int y1, float *color)
+	       int x0, int y0, int x1, int y1)
 {
     /*
      * debug_printf("solid rect[(%d, %d), (%d, %d)], rgba[%f, %f, %f, %f]\n",
      * x0, y0, x1, y1, color[0], color[1], color[2], color[3]); */
 
-    renderer_draw_conditional(r, 4 * 8);
+    renderer_draw_conditional(r, 4 * 4);
 
     /* 1st vertex */
-    add_vertex_color(r, x0, y0, color);
+    add_vertex_none(r, x0, y0);
     /* 2nd vertex */
-    add_vertex_color(r, x1, y0, color);
+    add_vertex_none(r, x1, y0);
     /* 3rd vertex */
-    add_vertex_color(r, x1, y1, color);
+    add_vertex_none(r, x1, y1);
     /* 4th vertex */
-    add_vertex_color(r, x0, y1, color);
+    add_vertex_none(r, x0, y1);
 }
 
 void
@@ -588,6 +585,9 @@ renderer_begin_textures(struct xa_context *r)
 {
     r->attrs_per_vertex = 1 + r->num_bound_samplers;
     r->buffer_size = 0;
+    if (r->has_solid_src || r->has_solid_mask)
+       renderer_set_constants(r, PIPE_SHADER_FRAGMENT, r->solid_color,
+                              4 * sizeof(float));
 }
 
 void
@@ -617,11 +617,19 @@ renderer_texture(struct xa_context *r,
     switch(r->attrs_per_vertex) {
     case 2:
 	renderer_draw_conditional(r, 4 * 8);
-	add_vertex_data1(r,
-			 pos[0], pos[1], /* src */
-			 pos[4], pos[5], /* dst */
-			 width, height,
-			 sampler_view[0]->texture, src_matrix);
+        if (!r->has_solid_src) {
+           add_vertex_data1(r,
+                            pos[0], pos[1], /* src */
+                            pos[4], pos[5], /* dst */
+                            width, height,
+                            sampler_view[0]->texture, src_matrix);
+        } else {
+           add_vertex_data1(r,
+                            pos[2], pos[3], /* mask */
+                            pos[4], pos[5], /* dst */
+                            width, height,
+                            sampler_view[0]->texture, mask_matrix);
+        }
 	break;
     case 3:
 	renderer_draw_conditional(r, 4 * 12);
diff --git a/src/gallium/state_trackers/xa/xa_tgsi.c b/src/gallium/state_trackers/xa/xa_tgsi.c
index 344a576d975..5f2608aee55 100644
--- a/src/gallium/state_trackers/xa/xa_tgsi.c
+++ b/src/gallium/state_trackers/xa/xa_tgsi.c
@@ -48,19 +48,18 @@
  * CONST[1] = (-1, -1, 0, 0)
  *
  * OUT[0]   = vertex pos
- * OUT[1]   = src tex coord | solid fill color
+ * OUT[1]   = src tex coord
  * OUT[2]   = mask tex coord
  * OUT[3]   = dst tex coord
  */
 
-/* Fragment shader:
- * SAMP[0]  = src
- * SAMP[1]  = mask
- * SAMP[2]  = dst
- * IN[0]    = pos src | solid fill color
- * IN[1]    = pos mask
- * IN[2]    = pos dst
- * CONST[0] = (0, 0, 0, 1)
+/* Fragment shader. Samplers are allocated when needed.
+ * SAMP[0]  = sampler for first texture (src or mask if src is solid)
+ * SAMP[1]  = sampler for second texture (mask or none)
+ * IN[0]    = first texture coordinates if present
+ * IN[1]    = second texture coordinates if present
+ * CONST[0] = Solid color (src if src solid or mask if mask solid
+ *            or src in mask if both solid).
  *
  * OUT[0] = color
  */
@@ -71,21 +70,18 @@ print_fs_traits(int fs_traits)
     const char *strings[] = {
 	"FS_COMPOSITE",		/* = 1 << 0, */
 	"FS_MASK",		/* = 1 << 1, */
-	"FS_SOLID_FILL",	/* = 1 << 2, */
-	"FS_LINGRAD_FILL",	/* = 1 << 3, */
-	"FS_RADGRAD_FILL",	/* = 1 << 4, */
-	"FS_CA_FULL",		/* = 1 << 5, *//* src.rgba * mask.rgba */
-	"FS_CA_SRCALPHA",	/* = 1 << 6, *//* src.aaaa * mask.rgba */
-	"FS_YUV",		/* = 1 << 7, */
-	"FS_SRC_REPEAT_NONE",	/* = 1 << 8, */
-	"FS_MASK_REPEAT_NONE",	/* = 1 << 9, */
-	"FS_SRC_SWIZZLE_RGB",	/* = 1 << 10, */
-	"FS_MASK_SWIZZLE_RGB",	/* = 1 << 11, */
-	"FS_SRC_SET_ALPHA",	/* = 1 << 12, */
-	"FS_MASK_SET_ALPHA",	/* = 1 << 13, */
-	"FS_SRC_LUMINANCE",	/* = 1 << 14, */
-	"FS_MASK_LUMINANCE",	/* = 1 << 15, */
-	"FS_DST_LUMINANCE",     /* = 1 << 15, */
+	"FS_SRC_SRC",	        /* = 1 << 2, */
+	"FS_MASK_SRC",	        /* = 1 << 3, */
+	"FS_YUV",	        /* = 1 << 4, */
+	"FS_SRC_REPEAT_NONE",	/* = 1 << 5, */
+	"FS_MASK_REPEAT_NONE",	/* = 1 << 6, */
+	"FS_SRC_SWIZZLE_RGB",	/* = 1 << 7, */
+	"FS_MASK_SWIZZLE_RGB",	/* = 1 << 8, */
+	"FS_SRC_SET_ALPHA",	/* = 1 << 9, */
+	"FS_MASK_SET_ALPHA",	/* = 1 << 10, */
+	"FS_SRC_LUMINANCE",	/* = 1 << 11, */
+	"FS_MASK_LUMINANCE",	/* = 1 << 12, */
+	"FS_DST_LUMINANCE",     /* = 1 << 13, */
     };
     int i, k;
 
@@ -111,18 +107,12 @@ src_in_mask(struct ureg_program *ureg,
 	    struct ureg_dst dst,
 	    struct ureg_src src,
 	    struct ureg_src mask,
-	    unsigned component_alpha, unsigned mask_luminance)
+	    unsigned mask_luminance)
 {
-    if (component_alpha == FS_CA_FULL) {
-	ureg_MUL(ureg, dst, src, mask);
-    } else if (component_alpha == FS_CA_SRCALPHA) {
-	ureg_MUL(ureg, dst, ureg_scalar(src, TGSI_SWIZZLE_W), mask);
-    } else {
-	if (mask_luminance)
-	    ureg_MUL(ureg, dst, src, ureg_scalar(mask, TGSI_SWIZZLE_X));
-	else
-	    ureg_MUL(ureg, dst, src, ureg_scalar(mask, TGSI_SWIZZLE_W));
-    }
+    if (mask_luminance)
+        ureg_MUL(ureg, dst, src, ureg_scalar(mask, TGSI_SWIZZLE_X));
+    else
+        ureg_MUL(ureg, dst, src, ureg_scalar(mask, TGSI_SWIZZLE_W));
 }
 
 static struct ureg_src
@@ -139,125 +129,6 @@ vs_normalize_coords(struct ureg_program *ureg,
     return ret;
 }
 
-static void
-linear_gradient(struct ureg_program *ureg,
-		struct ureg_dst out,
-		struct ureg_src pos,
-		struct ureg_src sampler,
-		struct ureg_src coords,
-		struct ureg_src const0124,
-		struct ureg_src matrow0,
-		struct ureg_src matrow1, struct ureg_src matrow2)
-{
-    struct ureg_dst temp0 = ureg_DECL_temporary(ureg);
-    struct ureg_dst temp1 = ureg_DECL_temporary(ureg);
-    struct ureg_dst temp2 = ureg_DECL_temporary(ureg);
-    struct ureg_dst temp3 = ureg_DECL_temporary(ureg);
-    struct ureg_dst temp4 = ureg_DECL_temporary(ureg);
-    struct ureg_dst temp5 = ureg_DECL_temporary(ureg);
-
-    ureg_MOV(ureg, ureg_writemask(temp0, TGSI_WRITEMASK_XY), pos);
-    ureg_MOV(ureg,
-	     ureg_writemask(temp0, TGSI_WRITEMASK_Z),
-	     ureg_scalar(const0124, TGSI_SWIZZLE_Y));
-
-    ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0));
-    ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0));
-    ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0));
-    ureg_RCP(ureg, temp3, ureg_src(temp3));
-    ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3));
-    ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3));
-
-    ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_X), ureg_src(temp1));
-    ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_Y), ureg_src(temp2));
-
-    ureg_MUL(ureg, temp0,
-	     ureg_scalar(coords, TGSI_SWIZZLE_Y),
-	     ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_Y));
-    ureg_MAD(ureg, temp1,
-	     ureg_scalar(coords, TGSI_SWIZZLE_X),
-	     ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_X), ureg_src(temp0));
-
-    ureg_MUL(ureg, temp2, ureg_src(temp1), ureg_scalar(coords, TGSI_SWIZZLE_Z));
-
-    ureg_TEX(ureg, out, TGSI_TEXTURE_1D, ureg_src(temp2), sampler);
-
-    ureg_release_temporary(ureg, temp0);
-    ureg_release_temporary(ureg, temp1);
-    ureg_release_temporary(ureg, temp2);
-    ureg_release_temporary(ureg, temp3);
-    ureg_release_temporary(ureg, temp4);
-    ureg_release_temporary(ureg, temp5);
-}
-
-static void
-radial_gradient(struct ureg_program *ureg,
-		struct ureg_dst out,
-		struct ureg_src pos,
-		struct ureg_src sampler,
-		struct ureg_src coords,
-		struct ureg_src const0124,
-		struct ureg_src matrow0,
-		struct ureg_src matrow1, struct ureg_src matrow2)
-{
-    struct ureg_dst temp0 = ureg_DECL_temporary(ureg);
-    struct ureg_dst temp1 = ureg_DECL_temporary(ureg);
-    struct ureg_dst temp2 = ureg_DECL_temporary(ureg);
-    struct ureg_dst temp3 = ureg_DECL_temporary(ureg);
-    struct ureg_dst temp4 = ureg_DECL_temporary(ureg);
-    struct ureg_dst temp5 = ureg_DECL_temporary(ureg);
-
-    ureg_MOV(ureg, ureg_writemask(temp0, TGSI_WRITEMASK_XY), pos);
-    ureg_MOV(ureg,
-	     ureg_writemask(temp0, TGSI_WRITEMASK_Z),
-	     ureg_scalar(const0124, TGSI_SWIZZLE_Y));
-
-    ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0));
-    ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0));
-    ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0));
-    ureg_RCP(ureg, temp3, ureg_src(temp3));
-    ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3));
-    ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3));
-
-    ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_X), ureg_src(temp1));
-    ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_Y), ureg_src(temp2));
-
-    ureg_MUL(ureg, temp0, ureg_scalar(coords, TGSI_SWIZZLE_Y),
-	     ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y));
-    ureg_MAD(ureg, temp1,
-	     ureg_scalar(coords, TGSI_SWIZZLE_X),
-	     ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X), ureg_src(temp0));
-    ureg_ADD(ureg, temp1, ureg_src(temp1), ureg_src(temp1));
-    ureg_MUL(ureg, temp3,
-	     ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y),
-	     ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y));
-    ureg_MAD(ureg, temp4,
-	     ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X),
-	     ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X), ureg_src(temp3));
-    ureg_MOV(ureg, temp4, ureg_negate(ureg_src(temp4)));
-    ureg_MUL(ureg, temp2, ureg_scalar(coords, TGSI_SWIZZLE_Z), ureg_src(temp4));
-    ureg_MUL(ureg, temp0,
-	     ureg_scalar(const0124, TGSI_SWIZZLE_W), ureg_src(temp2));
-    ureg_MUL(ureg, temp3, ureg_src(temp1), ureg_src(temp1));
-    ureg_ADD(ureg, temp2, ureg_src(temp3), ureg_negate(ureg_src(temp0)));
-    ureg_RSQ(ureg, temp2, ureg_abs(ureg_src(temp2)));
-    ureg_RCP(ureg, temp2, ureg_src(temp2));
-    ureg_ADD(ureg, temp1, ureg_src(temp2), ureg_negate(ureg_src(temp1)));
-    ureg_ADD(ureg, temp0,
-	     ureg_scalar(coords, TGSI_SWIZZLE_Z),
-	     ureg_scalar(coords, TGSI_SWIZZLE_Z));
-    ureg_RCP(ureg, temp0, ureg_src(temp0));
-    ureg_MUL(ureg, temp2, ureg_src(temp1), ureg_src(temp0));
-    ureg_TEX(ureg, out, TGSI_TEXTURE_1D, ureg_src(temp2), sampler);
-
-    ureg_release_temporary(ureg, temp0);
-    ureg_release_temporary(ureg, temp1);
-    ureg_release_temporary(ureg, temp2);
-    ureg_release_temporary(ureg, temp3);
-    ureg_release_temporary(ureg, temp4);
-    ureg_release_temporary(ureg, temp5);
-}
-
 static void *
 create_vs(struct pipe_context *pipe, unsigned vs_traits)
 {
@@ -265,10 +136,11 @@ create_vs(struct pipe_context *pipe, unsigned vs_traits)
     struct ureg_src src;
     struct ureg_dst dst;
     struct ureg_src const0, const1;
-    boolean is_fill = (vs_traits & VS_FILL) != 0;
     boolean is_composite = (vs_traits & VS_COMPOSITE) != 0;
     boolean has_mask = (vs_traits & VS_MASK) != 0;
     boolean is_yuv = (vs_traits & VS_YUV) != 0;
+    boolean is_src_src = (vs_traits & VS_SRC_SRC) != 0;
+    boolean is_mask_src = (vs_traits & VS_MASK_SRC) != 0;
     unsigned input_slot = 0;
 
     ureg = ureg_create(PIPE_SHADER_VERTEX);
@@ -279,8 +151,6 @@ create_vs(struct pipe_context *pipe, unsigned vs_traits)
     const1 = ureg_DECL_constant(ureg, 1);
 
     /* it has to be either a fill or a composite op */
-    debug_assert((is_fill ^ is_composite) ^ is_yuv);
-
     src = ureg_DECL_vs_input(ureg, input_slot++);
     dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
     src = vs_normalize_coords(ureg, src, const0, const1);
@@ -293,21 +163,17 @@ create_vs(struct pipe_context *pipe, unsigned vs_traits)
     }
 
     if (is_composite) {
-	src = ureg_DECL_vs_input(ureg, input_slot++);
-	dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0);
-	ureg_MOV(ureg, dst, src);
-    }
-
-    if (is_fill) {
-	src = ureg_DECL_vs_input(ureg, input_slot++);
-	dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
-	ureg_MOV(ureg, dst, src);
-    }
-
-    if (has_mask) {
-	src = ureg_DECL_vs_input(ureg, input_slot++);
-	dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1);
-	ureg_MOV(ureg, dst, src);
+        if (!is_src_src || (has_mask && !is_mask_src)) {
+            src = ureg_DECL_vs_input(ureg, input_slot++);
+            dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0);
+            ureg_MOV(ureg, dst, src);
+        }
+
+        if (!is_src_src && (has_mask && !is_mask_src)) {
+            src = ureg_DECL_vs_input(ureg, input_slot++);
+            dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1);
+            ureg_MOV(ureg, dst, src);
+        }
     }
 
     ureg_END(ureg);
@@ -383,7 +249,7 @@ xrender_tex(struct ureg_program *ureg,
 	    struct ureg_dst dst,
 	    struct ureg_src coords,
 	    struct ureg_src sampler,
-	    struct ureg_src imm0,
+	    const struct ureg_src *imm0,
 	    boolean repeat_none, boolean swizzle, boolean set_alpha)
 {
     if (repeat_none) {
@@ -394,11 +260,11 @@ xrender_tex(struct ureg_program *ureg,
 					  TGSI_SWIZZLE_X,
 					  TGSI_SWIZZLE_Y,
 					  TGSI_SWIZZLE_X,
-					  TGSI_SWIZZLE_Y), ureg_scalar(imm0,
+					  TGSI_SWIZZLE_Y), ureg_scalar(*imm0,
 								       TGSI_SWIZZLE_X));
 	ureg_SLT(ureg, tmp0,
 		 ureg_swizzle(coords, TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y,
-			      TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y), ureg_scalar(imm0,
+			      TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y), ureg_scalar(*imm0,
 									   TGSI_SWIZZLE_W));
 	ureg_MIN(ureg, tmp0, ureg_src(tmp0), ureg_src(tmp1));
 	ureg_MIN(ureg, tmp0, ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_X),
@@ -412,7 +278,7 @@ xrender_tex(struct ureg_program *ureg,
 	if (set_alpha)
 	    ureg_MOV(ureg,
 		     ureg_writemask(tmp1, TGSI_WRITEMASK_W),
-		     ureg_scalar(imm0, TGSI_SWIZZLE_W));
+		     ureg_scalar(*imm0, TGSI_SWIZZLE_W));
 	ureg_MUL(ureg, dst, ureg_src(tmp1), ureg_src(tmp0));
 	ureg_release_temporary(ureg, tmp0);
 	ureg_release_temporary(ureg, tmp1);
@@ -432,7 +298,32 @@ xrender_tex(struct ureg_program *ureg,
 	if (set_alpha)
 	    ureg_MOV(ureg,
 		     ureg_writemask(dst, TGSI_WRITEMASK_W),
-		     ureg_scalar(imm0, TGSI_SWIZZLE_W));
+		     ureg_scalar(*imm0, TGSI_SWIZZLE_W));
+    }
+}
+
+static void
+read_input(struct ureg_program *ureg,
+           struct ureg_dst dst,
+           const struct ureg_src *imm0,
+           boolean repeat_none, boolean swizzle, boolean set_alpha,
+           boolean is_src, unsigned *cur_constant, unsigned *cur_sampler)
+{
+    struct ureg_src input, sampler;
+
+    if (is_src) {
+        input = ureg_DECL_constant(ureg, (*cur_constant)++);
+        ureg_MOV(ureg, dst, input);
+    } else {
+        sampler = ureg_DECL_sampler(ureg, *cur_sampler);
+        ureg_DECL_sampler_view(ureg, *cur_sampler, TGSI_TEXTURE_2D,
+                               TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT,
+                               TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT);
+        input = ureg_DECL_fs_input(ureg,
+                                   TGSI_SEMANTIC_GENERIC, (*cur_sampler)++,
+                                   TGSI_INTERPOLATE_PERSPECTIVE);
+        xrender_tex(ureg, dst, input, sampler, imm0,
+                    repeat_none, swizzle, set_alpha);
     }
 }
 
@@ -440,18 +331,10 @@ static void *
 create_fs(struct pipe_context *pipe, unsigned fs_traits)
 {
     struct ureg_program *ureg;
-    struct ureg_src /*dst_sampler, */ src_sampler, mask_sampler;
-    struct ureg_src /*dst_pos, */ src_input, mask_pos;
     struct ureg_dst src, mask;
     struct ureg_dst out;
     struct ureg_src imm0 = { 0 };
     unsigned has_mask = (fs_traits & FS_MASK) != 0;
-    unsigned is_fill = (fs_traits & FS_FILL) != 0;
-    unsigned is_composite = (fs_traits & FS_COMPOSITE) != 0;
-    unsigned is_solid = (fs_traits & FS_SOLID_FILL) != 0;
-    unsigned is_lingrad = (fs_traits & FS_LINGRAD_FILL) != 0;
-    unsigned is_radgrad = (fs_traits & FS_RADGRAD_FILL) != 0;
-    unsigned comp_alpha_mask = fs_traits & FS_COMPONENT_ALPHA;
     unsigned is_yuv = (fs_traits & FS_YUV) != 0;
     unsigned src_repeat_none = (fs_traits & FS_SRC_REPEAT_NONE) != 0;
     unsigned mask_repeat_none = (fs_traits & FS_MASK_REPEAT_NONE) != 0;
@@ -462,6 +345,10 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
     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;
+    unsigned is_src_src = (fs_traits & FS_SRC_SRC) != 0;
+    unsigned is_mask_src = (fs_traits & FS_MASK_SRC) != 0;
+    unsigned cur_sampler = 0;
+    unsigned cur_constant = 0;
 
 #if 0
     print_fs_traits(fs_traits);
@@ -473,9 +360,8 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
     if (ureg == NULL)
 	return 0;
 
-    /* it has to be either a fill, a composite op or a yuv conversion */
-    debug_assert((is_fill ^ is_composite) ^ is_yuv);
-    (void)is_yuv;
+    if (is_yuv)
+       return create_yuv_shader(pipe, ureg);
 
     out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
 
@@ -483,86 +369,13 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
 	src_set_alpha || mask_set_alpha || src_luminance) {
 	imm0 = ureg_imm4f(ureg, 0, 0, 0, 1);
     }
-    if (is_composite) {
-	src_sampler = ureg_DECL_sampler(ureg, 0);
-        ureg_DECL_sampler_view(ureg, 0, TGSI_TEXTURE_2D,
-                               TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT,
-                               TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT);
-	src_input = ureg_DECL_fs_input(ureg,
-				       TGSI_SEMANTIC_GENERIC, 0,
-				       TGSI_INTERPOLATE_PERSPECTIVE);
-    } else if (is_fill) {
-	if (is_solid)
-	    src_input = ureg_DECL_fs_input(ureg,
-					   TGSI_SEMANTIC_COLOR, 0,
-					   TGSI_INTERPOLATE_PERSPECTIVE);
-	else
-	    src_input = ureg_DECL_fs_input(ureg,
-					   TGSI_SEMANTIC_POSITION, 0,
-					   TGSI_INTERPOLATE_PERSPECTIVE);
-    } else {
-	debug_assert(is_yuv);
-	return create_yuv_shader(pipe, ureg);
-    }
 
-    if (has_mask) {
-	mask_sampler = ureg_DECL_sampler(ureg, 1);
-        ureg_DECL_sampler_view(ureg, 1, TGSI_TEXTURE_2D,
-                               TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT,
-                               TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT);
-	mask_pos = ureg_DECL_fs_input(ureg,
-				      TGSI_SEMANTIC_GENERIC, 1,
-				      TGSI_INTERPOLATE_PERSPECTIVE);
-    }
-#if 0				/* unused right now */
-    dst_sampler = ureg_DECL_sampler(ureg, 2);
-    ureg_DECL_sampler_view(ureg, 2, TGSI_TEXTURE_2D,
-                           TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT,
-                           TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT);
-    dst_pos = ureg_DECL_fs_input(ureg,
-				 TGSI_SEMANTIC_POSITION, 2,
-				 TGSI_INTERPOLATE_PERSPECTIVE);
-#endif
+    src = (has_mask || src_luminance || dst_luminance) ?
+        ureg_DECL_temporary(ureg) : out;
+
+    read_input(ureg, src, &imm0, src_repeat_none, src_swizzle,
+               src_set_alpha, is_src_src, &cur_constant, &cur_sampler);
 
-    if (is_composite) {
-	if (has_mask || src_luminance || dst_luminance)
-	    src = ureg_DECL_temporary(ureg);
-	else
-	    src = out;
-	xrender_tex(ureg, src, src_input, src_sampler, imm0,
-		    src_repeat_none, src_swizzle, src_set_alpha);
-    } else if (is_fill) {
-	if (is_solid) {
-	    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 || dst_luminance)
-		src = ureg_DECL_temporary(ureg);
-	    else
-		src = out;
-
-	    coords = ureg_DECL_constant(ureg, 0);
-	    const0124 = ureg_DECL_constant(ureg, 1);
-	    matrow0 = ureg_DECL_constant(ureg, 2);
-	    matrow1 = ureg_DECL_constant(ureg, 3);
-	    matrow2 = ureg_DECL_constant(ureg, 4);
-
-	    if (is_lingrad) {
-		linear_gradient(ureg, src,
-				src_input, src_sampler,
-				coords, const0124, matrow0, matrow1, matrow2);
-	    } else if (is_radgrad) {
-		radial_gradient(ureg, src,
-				src_input, src_sampler,
-				coords, const0124, matrow0, matrow1, matrow2);
-	    }
-	} else
-	    debug_assert(!"Unknown fill type!");
-    }
     if (src_luminance) {
 	ureg_MOV(ureg, src, ureg_scalar(ureg_src(src), TGSI_SWIZZLE_X));
 	ureg_MOV(ureg, ureg_writemask(src, TGSI_WRITEMASK_XYZ),
@@ -573,13 +386,12 @@ create_fs(struct pipe_context *pipe, unsigned fs_traits)
 
     if (has_mask) {
 	mask = ureg_DECL_temporary(ureg);
-	xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0,
-		    mask_repeat_none, mask_swizzle, mask_set_alpha);
-	/* src IN mask */
+        read_input(ureg, mask, &imm0, mask_repeat_none,
+                   mask_swizzle, mask_set_alpha, is_mask_src, &cur_constant,
+                   &cur_sampler);
 
 	src_in_mask(ureg, (dst_luminance) ? src : out, ureg_src(src),
-		    ureg_src(mask),
-		    comp_alpha_mask, mask_luminance);
+		    ureg_src(mask), mask_luminance);
 
 	ureg_release_temporary(ureg, mask);
     }
-- 
2.19.0.rc1



More information about the mesa-dev mailing list