1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**********************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009-2011 VMware, Inc. All rights reserved.
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * obtaining a copy of this software and associated documentation
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * files (the "Software"), to deal in the Software without
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * restriction, including without limitation the rights to use, copy,
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * modify, merge, publish, distribute, sublicense, and/or sell copies
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software, and to permit persons to whom the Software is
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * furnished to do so, subject to the following conditions:
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * included in all copies or substantial portions of the Software.
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE.
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *********************************************************
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Authors:
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Zack Rusin <zackr-at-vmware-dot-com>
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Thomas Hellstrom <thellstrom-at-vmware-dot-com>
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "xa_composite.h"
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "xa_context.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "xa_priv.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "cso_cache/cso_context.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_sampler.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_inlines.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*XXX also in Xrender.h but the including it here breaks compilition */
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define XFixedToDouble(f)    (((double) (f)) / 65536.)
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct xa_composite_blend {
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned op : 8;
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned alpha_dst : 4;
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned alpha_src : 4;
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned rgb_src : 8;    /**< PIPE_BLENDFACTOR_x */
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned rgb_dst : 8;    /**< PIPE_BLENDFACTOR_x */
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define XA_BLEND_OP_OVER 3
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct xa_composite_blend xa_blends[] = {
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { xa_op_clear,
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      0, 0, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO},
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { xa_op_src,
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ZERO},
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { xa_op_dst,
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      0, 0, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ONE},
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { xa_op_over,
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      0, 1, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { xa_op_over_reverse,
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      1, 0, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ONE},
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { xa_op_in,
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      1, 0, PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_ZERO},
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { xa_op_in_reverse,
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      0, 1, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_SRC_ALPHA},
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { xa_op_out,
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      1, 0, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_ZERO},
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { xa_op_out_reverse,
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      0, 1, PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { xa_op_atop,
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      1, 1, PIPE_BLENDFACTOR_DST_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { xa_op_atop_reverse,
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      1, 1, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_SRC_ALPHA},
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { xa_op_xor,
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      1, 1, PIPE_BLENDFACTOR_INV_DST_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA},
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { xa_op_add,
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      0, 0, PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE},
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The alpha value stored in a luminance texture is read by the
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * hardware as color.
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgxa_convert_blend_for_luminance(unsigned factor)
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch(factor) {
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case PIPE_BLENDFACTOR_DST_ALPHA:
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return PIPE_BLENDFACTOR_DST_COLOR;
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case PIPE_BLENDFACTOR_INV_DST_ALPHA:
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return PIPE_BLENDFACTOR_INV_DST_COLOR;
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    default:
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	break;
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return factor;
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgblend_for_op(struct xa_composite_blend *blend,
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     enum xa_composite_op op,
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     struct xa_picture *src_pic,
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     struct xa_picture *mask_pic,
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     struct xa_picture *dst_pic)
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const int num_blends =
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	sizeof(xa_blends)/sizeof(struct xa_composite_blend);
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int i;
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    boolean supported = FALSE;
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /*
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * Temporarily disable component alpha since it appears buggy.
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     */
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (mask_pic && mask_pic->component_alpha)
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return FALSE;
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /*
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * our default in case something goes wrong
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     */
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *blend = xa_blends[XA_BLEND_OP_OVER];
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (i = 0; i < num_blends; ++i) {
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (xa_blends[i].op == op) {
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    *blend = xa_blends[i];
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    supported = TRUE;
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!dst_pic->srf)
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return supported;
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (dst_pic->srf->tex->format == PIPE_FORMAT_L8_UNORM) {
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	blend->rgb_src = xa_convert_blend_for_luminance(blend->rgb_src);
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	blend->rgb_dst = xa_convert_blend_for_luminance(blend->rgb_dst);
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /*
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * If there's no dst alpha channel, adjust the blend op so that we'll treat
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * it as always 1.
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     */
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (xa_format_a(dst_pic->pict_format) == 0 && blend->alpha_dst) {
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (blend->rgb_src == PIPE_BLENDFACTOR_DST_ALPHA)
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    blend->rgb_src = PIPE_BLENDFACTOR_ONE;
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	else if (blend->rgb_src == PIPE_BLENDFACTOR_INV_DST_ALPHA)
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    blend->rgb_src = PIPE_BLENDFACTOR_ZERO;
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /*
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * If the source alpha is being used, then we should only be in a case where
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * the source blend factor is 0, and the source blend value is the mask
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * channels multiplied by the source picture's alpha.
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     */
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (mask_pic && mask_pic->component_alpha &&
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	xa_format_rgb(mask_pic->pict_format) &&
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	blend->alpha_src) {
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (blend->rgb_dst == PIPE_BLENDFACTOR_SRC_ALPHA) {
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    blend->rgb_dst = PIPE_BLENDFACTOR_SRC_COLOR;
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else if (blend->rgb_dst == PIPE_BLENDFACTOR_INV_SRC_ALPHA) {
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    blend->rgb_dst = PIPE_BLENDFACTOR_INV_SRC_COLOR;
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return supported;
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE int
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgxa_repeat_to_gallium(int mode)
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch(mode) {
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case xa_wrap_clamp_to_border:
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return PIPE_TEX_WRAP_CLAMP_TO_BORDER;
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case xa_wrap_repeat:
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return PIPE_TEX_WRAP_REPEAT;
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case xa_wrap_mirror_repeat:
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return PIPE_TEX_WRAP_MIRROR_REPEAT;
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case xa_wrap_clamp_to_edge:
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return PIPE_TEX_WRAP_CLAMP_TO_EDGE;
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    default:
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	break;
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return PIPE_TEX_WRAP_REPEAT;
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgxa_filter_to_gallium(int xrender_filter, int *out_filter)
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch (xrender_filter) {
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case xa_filter_nearest:
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	*out_filter = PIPE_TEX_FILTER_NEAREST;
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	break;
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case xa_filter_linear:
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	*out_filter = PIPE_TEX_FILTER_LINEAR;
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	break;
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    default:
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	*out_filter = PIPE_TEX_FILTER_NEAREST;
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return FALSE;
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return TRUE;
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgxa_is_filter_accelerated(struct xa_picture *pic)
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int filter;
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (pic && !xa_filter_to_gallium(pic->filter, &filter))
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return 0;
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 1;
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgXA_EXPORT int
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgxa_composite_check_accelerated(const struct xa_composite *comp)
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct xa_composite_blend blend;
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct xa_picture *src_pic = comp->src;
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!xa_is_filter_accelerated(src_pic) ||
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	!xa_is_filter_accelerated(comp->mask)) {
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return -XA_ERR_INVAL;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (src_pic->src_pict) {
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (src_pic->src_pict->type != xa_src_pict_solid_fill)
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    return -XA_ERR_INVAL;
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/*
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * Currently we don't support solid fill with a mask.
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * We can easily do that, but that would require shader,
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * sampler view setup and vertex setup modification.
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 */
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (comp->mask)
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    return -XA_ERR_INVAL;
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (blend_for_op(&blend, comp->op, comp->src, comp->mask, comp->dst)) {
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct xa_picture *mask = comp->mask;
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (mask && mask->component_alpha &&
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    xa_format_rgb(mask->pict_format)) {
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (blend.alpha_src && blend.rgb_src != PIPE_BLENDFACTOR_ZERO) {
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return -XA_ERR_INVAL;
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    }
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return XA_ERR_NONE;
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return -XA_ERR_INVAL;
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbind_composite_blend_state(struct xa_context *ctx,
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   const struct xa_composite *comp)
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct xa_composite_blend blend_opt;
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct pipe_blend_state blend;
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!blend_for_op(&blend_opt, comp->op, comp->src, comp->mask, comp->dst))
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return -XA_ERR_INVAL;
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    memset(&blend, 0, sizeof(struct pipe_blend_state));
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    blend.rt[0].blend_enable = 1;
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    blend.rt[0].colormask = PIPE_MASK_RGBA;
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    blend.rt[0].rgb_src_factor   = blend_opt.rgb_src;
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    blend.rt[0].alpha_src_factor = blend_opt.rgb_src;
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    blend.rt[0].rgb_dst_factor   = blend_opt.rgb_dst;
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    blend.rt[0].alpha_dst_factor = blend_opt.rgb_dst;
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    cso_set_blend(ctx->cso, &blend);
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return XA_ERR_NONE;
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned int
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpicture_format_fixups(struct xa_picture *src_pic,
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		      int mask)
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    boolean set_alpha = FALSE;
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    boolean swizzle = FALSE;
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned ret = 0;
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct xa_surface *src = src_pic->srf;
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    enum xa_formats src_hw_format, src_pic_format;
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    enum xa_surface_type src_hw_type, src_pic_type;
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!src)
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return 0;
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    src_hw_format = xa_surface_format(src);
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    src_pic_format = src_pic->pict_format;
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    set_alpha = (xa_format_type_is_color(src_pic_format) &&
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 xa_format_a(src_pic_format) == 0);
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (set_alpha)
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA;
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (src_hw_format == src_pic_format) {
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (src->tex->format == PIPE_FORMAT_L8_UNORM)
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    return ((mask) ? FS_MASK_LUMINANCE : FS_SRC_LUMINANCE);
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return ret;
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    src_hw_type = xa_format_type(src_hw_format);
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    src_pic_type = xa_format_type(src_pic_format);
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    swizzle = ((src_hw_type == xa_type_argb &&
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		src_pic_type == xa_type_abgr) ||
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       ((src_hw_type == xa_type_abgr &&
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 src_pic_type == xa_type_argb)));
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!swizzle && (src_hw_type != src_pic_type))
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return ret;
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (swizzle)
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ret |= mask ? FS_MASK_SWIZZLE_RGB : FS_SRC_SWIZZLE_RGB;
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return ret;
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbind_shaders(struct xa_context *ctx, const struct xa_composite *comp)
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned vs_traits = 0, fs_traits = 0;
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct xa_shader shader;
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct xa_picture *src_pic = comp->src;
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct xa_picture *mask_pic = comp->mask;
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ctx->has_solid_color = FALSE;
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (src_pic) {
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (src_pic->wrap == xa_wrap_clamp_to_border && src_pic->has_transform)
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    fs_traits |= FS_SRC_REPEAT_NONE;
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (src_pic->src_pict) {
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (src_pic->src_pict->type == xa_src_pict_solid_fill) {
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		fs_traits |= FS_SOLID_FILL | FS_FILL;
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		vs_traits |= VS_SOLID_FILL;
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		xa_pixel_to_float4(src_pic->src_pict->solid_fill.color,
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				   ctx->solid_color);
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ctx->has_solid_color = TRUE;
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    }
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else {
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    fs_traits |= FS_COMPOSITE;
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    vs_traits |= VS_COMPOSITE;
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	fs_traits |= picture_format_fixups(src_pic, 0);
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (mask_pic) {
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	vs_traits |= VS_MASK;
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	fs_traits |= FS_MASK;
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (mask_pic->wrap == xa_wrap_clamp_to_border &&
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    mask_pic->has_transform)
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    fs_traits |= FS_MASK_REPEAT_NONE;
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (mask_pic->component_alpha) {
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    struct xa_composite_blend blend;
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (!blend_for_op(&blend, comp->op, src_pic, mask_pic, NULL))
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return -XA_ERR_INVAL;
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (blend.alpha_src) {
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		fs_traits |= FS_CA_SRCALPHA;
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    } else
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		fs_traits |= FS_CA_FULL;
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	fs_traits |= picture_format_fixups(mask_pic, 1);
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (ctx->srf->format == PIPE_FORMAT_L8_UNORM)
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	fs_traits |= FS_DST_LUMINANCE;
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    shader = xa_shaders_get(ctx->shaders, vs_traits, fs_traits);
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    cso_set_vertex_shader_handle(ctx->cso, shader.vs);
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    cso_set_fragment_shader_handle(ctx->cso, shader.fs);
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return XA_ERR_NONE;
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbind_samplers(struct xa_context *ctx,
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      const struct xa_composite *comp)
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct pipe_sampler_state src_sampler, mask_sampler;
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct pipe_sampler_view view_templ;
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct pipe_sampler_view *src_view;
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct pipe_context *pipe = ctx->pipe;
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct xa_picture *src_pic = comp->src;
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct xa_picture *mask_pic = comp->mask;
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ctx->num_bound_samplers = 0;
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (src_pic) {
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (ctx->has_solid_color) {
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    samplers[0] = NULL;
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    pipe_sampler_view_reference(&ctx->bound_sampler_views[0], NULL);
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else {
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    unsigned src_wrap = xa_repeat_to_gallium(src_pic->wrap);
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    int filter;
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    (void) xa_filter_to_gallium(src_pic->filter, &filter);
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    src_sampler.wrap_s = src_wrap;
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    src_sampler.wrap_t = src_wrap;
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    src_sampler.min_img_filter = filter;
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    src_sampler.mag_img_filter = filter;
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    src_sampler.normalized_coords = 1;
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    samplers[0] = &src_sampler;
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ctx->num_bound_samplers = 1;
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    u_sampler_view_default_template(&view_templ,
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					    src_pic->srf->tex,
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					    src_pic->srf->tex->format);
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    src_view = pipe->create_sampler_view(pipe, src_pic->srf->tex,
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						 &view_templ);
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    pipe_sampler_view_reference(&ctx->bound_sampler_views[0], NULL);
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ctx->bound_sampler_views[0] = src_view;
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (mask_pic) {
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned mask_wrap = xa_repeat_to_gallium(mask_pic->wrap);
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int filter;
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	(void) xa_filter_to_gallium(mask_pic->filter, &filter);
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	mask_sampler.wrap_s = mask_wrap;
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	mask_sampler.wrap_t = mask_wrap;
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	mask_sampler.min_img_filter = filter;
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	mask_sampler.mag_img_filter = filter;
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	mask_sampler.normalized_coords = 1;
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	samplers[1] = &mask_sampler;
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->num_bound_samplers = 2;
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	u_sampler_view_default_template(&view_templ,
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					mask_pic->srf->tex,
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					mask_pic->srf->tex->format);
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	src_view = pipe->create_sampler_view(pipe, mask_pic->srf->tex,
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					     &view_templ);
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	pipe_sampler_view_reference(&ctx->bound_sampler_views[1], NULL);
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->bound_sampler_views[1] = src_view;
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/*
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * If src is a solid color, we have no src view, so set up a
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * dummy one that will not be used anyway.
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 */
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (ctx->bound_sampler_views[0] == NULL)
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    pipe_sampler_view_reference(&ctx->bound_sampler_views[0],
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					src_view);
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    cso_set_samplers(ctx->cso, PIPE_SHADER_FRAGMENT, ctx->num_bound_samplers,
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     (const struct pipe_sampler_state **)samplers);
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, ctx->num_bound_samplers,
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				   ctx->bound_sampler_views);
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgXA_EXPORT int
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgxa_composite_prepare(struct xa_context *ctx,
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     const struct xa_composite *comp)
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct xa_surface *dst_srf = comp->dst->srf;
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int ret;
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ret = xa_ctx_srf_create(ctx, dst_srf);
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (ret != XA_ERR_NONE)
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return ret;
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ctx->dst = dst_srf;
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    renderer_bind_destination(ctx, ctx->srf, ctx->srf->width,
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      ctx->srf->height);
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ret = bind_composite_blend_state(ctx, comp);
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (ret != XA_ERR_NONE)
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return ret;
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ret = bind_shaders(ctx, comp);
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (ret != XA_ERR_NONE)
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return ret;
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    bind_samplers(ctx, comp);
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (ctx->num_bound_samplers == 0 ) { /* solid fill */
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	renderer_begin_solid(ctx);
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	renderer_begin_textures(ctx);
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->comp = comp;
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    xa_ctx_srf_destroy(ctx);
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return XA_ERR_NONE;
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgXA_EXPORT void
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgxa_composite_rect(struct xa_context *ctx,
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  int srcX, int srcY, int maskX, int maskY,
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  int dstX, int dstY, int width, int height)
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (ctx->num_bound_samplers == 0 ) { /* solid fill */
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	renderer_solid(ctx, dstX, dstY, dstX + width, dstY + height,
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		       ctx->solid_color);
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct xa_composite *comp = ctx->comp;
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	int pos[6] = {srcX, srcY, maskX, maskY, dstX, dstY};
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const float *src_matrix = NULL;
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const float *mask_matrix = NULL;
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (comp->src->has_transform)
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    src_matrix = comp->src->transform;
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (comp->mask && comp->mask->has_transform)
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    mask_matrix = comp->mask->transform;
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	renderer_texture(ctx, pos, width, height,
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			 src_matrix, mask_matrix);
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgXA_EXPORT void
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgxa_composite_done(struct xa_context *ctx)
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    renderer_draw_flush(ctx);
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ctx->pipe->flush(ctx->pipe, &ctx->last_fence);
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ctx->comp = NULL;
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ctx->has_solid_color = FALSE;
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    xa_ctx_sampler_views_destroy(ctx);
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct xa_composite_allocation a = {
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    .xa_composite_size = sizeof(struct xa_composite),
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    .xa_picture_size = sizeof(struct xa_picture),
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    .xa_source_pict_size = sizeof(union xa_source_pict),
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgXA_EXPORT const struct xa_composite_allocation *
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgxa_composite_allocation(void)
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return &a;
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
548