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 */
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "xa_priv.h"
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_format.h"
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_context.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_state.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_shader_tokens.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_ureg.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "cso_cache/cso_context.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "cso_cache/cso_hash.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Vertex shader:
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN[0]    = vertex pos
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN[1]    = src tex coord | solid fill color
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN[2]    = mask tex coord
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN[3]    = dst tex coord
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONST[0] = (2/dst_width, 2/dst_height, 1, 1)
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONST[1] = (-1, -1, 0, 0)
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OUT[0]   = vertex pos
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OUT[1]   = src tex coord | solid fill color
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OUT[2]   = mask tex coord
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OUT[3]   = dst tex coord
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Fragment shader:
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SAMP[0]  = src
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SAMP[1]  = mask
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SAMP[2]  = dst
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN[0]    = pos src | solid fill color
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN[1]    = pos mask
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN[2]    = pos dst
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONST[0] = (0, 0, 0, 1)
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OUT[0] = color
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprint_fs_traits(int fs_traits)
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const char *strings[] = {
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	"FS_COMPOSITE",		/* = 1 << 0, */
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	"FS_MASK",		/* = 1 << 1, */
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	"FS_SOLID_FILL",	/* = 1 << 2, */
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	"FS_LINGRAD_FILL",	/* = 1 << 3, */
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	"FS_RADGRAD_FILL",	/* = 1 << 4, */
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	"FS_CA_FULL",		/* = 1 << 5, *//* src.rgba * mask.rgba */
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	"FS_CA_SRCALPHA",	/* = 1 << 6, *//* src.aaaa * mask.rgba */
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	"FS_YUV",		/* = 1 << 7, */
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	"FS_SRC_REPEAT_NONE",	/* = 1 << 8, */
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	"FS_MASK_REPEAT_NONE",	/* = 1 << 9, */
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	"FS_SRC_SWIZZLE_RGB",	/* = 1 << 10, */
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	"FS_MASK_SWIZZLE_RGB",	/* = 1 << 11, */
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	"FS_SRC_SET_ALPHA",	/* = 1 << 12, */
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	"FS_MASK_SET_ALPHA",	/* = 1 << 13, */
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	"FS_SRC_LUMINANCE",	/* = 1 << 14, */
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	"FS_MASK_LUMINANCE",	/* = 1 << 15, */
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	"FS_DST_LUMINANCE",     /* = 1 << 15, */
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    };
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int i, k;
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    debug_printf("%s: ", __func__);
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (i = 0, k = 1; k < (1 << 16); i++, k <<= 1) {
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (fs_traits & k)
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    debug_printf("%s, ", strings[i]);
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    debug_printf("\n");
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct xa_shaders {
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct xa_context *r;
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct cso_hash *vs_hash;
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct cso_hash *fs_hash;
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsrc_in_mask(struct ureg_program *ureg,
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    struct ureg_dst dst,
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    struct ureg_src src,
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    struct ureg_src mask,
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    unsigned component_alpha, unsigned mask_luminance)
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (component_alpha == FS_CA_FULL) {
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ureg_MUL(ureg, dst, src, mask);
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else if (component_alpha == FS_CA_SRCALPHA) {
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ureg_MUL(ureg, dst, ureg_scalar(src, TGSI_SWIZZLE_W), mask);
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (mask_luminance)
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ureg_MUL(ureg, dst, src, ureg_scalar(mask, TGSI_SWIZZLE_X));
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	else
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ureg_MUL(ureg, dst, src, ureg_scalar(mask, TGSI_SWIZZLE_W));
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct ureg_src
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvs_normalize_coords(struct ureg_program *ureg,
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    struct ureg_src coords,
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    struct ureg_src const0, struct ureg_src const1)
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_dst tmp = ureg_DECL_temporary(ureg);
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_src ret;
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MAD(ureg, tmp, coords, const0, const1);
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ret = ureg_src(tmp);
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_release_temporary(ureg, tmp);
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return ret;
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglinear_gradient(struct ureg_program *ureg,
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct ureg_dst out,
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct ureg_src pos,
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct ureg_src sampler,
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct ureg_src coords,
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct ureg_src const0124,
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct ureg_src matrow0,
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct ureg_src matrow1, struct ureg_src matrow2)
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_dst temp0 = ureg_DECL_temporary(ureg);
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_dst temp1 = ureg_DECL_temporary(ureg);
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_dst temp2 = ureg_DECL_temporary(ureg);
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_dst temp3 = ureg_DECL_temporary(ureg);
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_dst temp4 = ureg_DECL_temporary(ureg);
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_dst temp5 = ureg_DECL_temporary(ureg);
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MOV(ureg, ureg_writemask(temp0, TGSI_WRITEMASK_XY), pos);
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MOV(ureg,
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_writemask(temp0, TGSI_WRITEMASK_Z),
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_scalar(const0124, TGSI_SWIZZLE_Y));
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0));
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0));
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0));
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_RCP(ureg, temp3, ureg_src(temp3));
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3));
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3));
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_X), ureg_src(temp1));
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_Y), ureg_src(temp2));
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MUL(ureg, temp0,
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_scalar(coords, TGSI_SWIZZLE_Y),
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_Y));
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MAD(ureg, temp1,
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_scalar(coords, TGSI_SWIZZLE_X),
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_X), ureg_src(temp0));
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MUL(ureg, temp2, ureg_src(temp1), ureg_scalar(coords, TGSI_SWIZZLE_Z));
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_TEX(ureg, out, TGSI_TEXTURE_1D, ureg_src(temp2), sampler);
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_release_temporary(ureg, temp0);
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_release_temporary(ureg, temp1);
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_release_temporary(ureg, temp2);
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_release_temporary(ureg, temp3);
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_release_temporary(ureg, temp4);
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_release_temporary(ureg, temp5);
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgradial_gradient(struct ureg_program *ureg,
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct ureg_dst out,
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct ureg_src pos,
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct ureg_src sampler,
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct ureg_src coords,
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct ureg_src const0124,
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct ureg_src matrow0,
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct ureg_src matrow1, struct ureg_src matrow2)
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_dst temp0 = ureg_DECL_temporary(ureg);
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_dst temp1 = ureg_DECL_temporary(ureg);
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_dst temp2 = ureg_DECL_temporary(ureg);
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_dst temp3 = ureg_DECL_temporary(ureg);
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_dst temp4 = ureg_DECL_temporary(ureg);
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_dst temp5 = ureg_DECL_temporary(ureg);
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MOV(ureg, ureg_writemask(temp0, TGSI_WRITEMASK_XY), pos);
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MOV(ureg,
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_writemask(temp0, TGSI_WRITEMASK_Z),
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_scalar(const0124, TGSI_SWIZZLE_Y));
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0));
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0));
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0));
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_RCP(ureg, temp3, ureg_src(temp3));
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3));
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3));
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_X), ureg_src(temp1));
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_Y), ureg_src(temp2));
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MUL(ureg, temp0, ureg_scalar(coords, TGSI_SWIZZLE_Y),
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y));
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MAD(ureg, temp1,
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_scalar(coords, TGSI_SWIZZLE_X),
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X), ureg_src(temp0));
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_ADD(ureg, temp1, ureg_src(temp1), ureg_src(temp1));
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MUL(ureg, temp3,
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y),
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y));
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MAD(ureg, temp4,
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X),
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X), ureg_src(temp3));
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MOV(ureg, temp4, ureg_negate(ureg_src(temp4)));
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MUL(ureg, temp2, ureg_scalar(coords, TGSI_SWIZZLE_Z), ureg_src(temp4));
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MUL(ureg, temp0,
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_scalar(const0124, TGSI_SWIZZLE_W), ureg_src(temp2));
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MUL(ureg, temp3, ureg_src(temp1), ureg_src(temp1));
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_SUB(ureg, temp2, ureg_src(temp3), ureg_src(temp0));
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_RSQ(ureg, temp2, ureg_abs(ureg_src(temp2)));
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_RCP(ureg, temp2, ureg_src(temp2));
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_SUB(ureg, temp1, ureg_src(temp2), ureg_src(temp1));
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_ADD(ureg, temp0,
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_scalar(coords, TGSI_SWIZZLE_Z),
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_scalar(coords, TGSI_SWIZZLE_Z));
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_RCP(ureg, temp0, ureg_src(temp0));
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MUL(ureg, temp2, ureg_src(temp1), ureg_src(temp0));
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_TEX(ureg, out, TGSI_TEXTURE_1D, ureg_src(temp2), sampler);
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_release_temporary(ureg, temp0);
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_release_temporary(ureg, temp1);
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_release_temporary(ureg, temp2);
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_release_temporary(ureg, temp3);
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_release_temporary(ureg, temp4);
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_release_temporary(ureg, temp5);
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void *
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcreate_vs(struct pipe_context *pipe, unsigned vs_traits)
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_program *ureg;
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_src src;
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_dst dst;
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_src const0, const1;
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    boolean is_fill = (vs_traits & VS_FILL) != 0;
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    boolean is_composite = (vs_traits & VS_COMPOSITE) != 0;
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    boolean has_mask = (vs_traits & VS_MASK) != 0;
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    boolean is_yuv = (vs_traits & VS_YUV) != 0;
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned input_slot = 0;
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (ureg == NULL)
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return 0;
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const0 = ureg_DECL_constant(ureg, 0);
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const1 = ureg_DECL_constant(ureg, 1);
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* it has to be either a fill or a composite op */
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    debug_assert((is_fill ^ is_composite) ^ is_yuv);
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    src = ureg_DECL_vs_input(ureg, input_slot++);
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    src = vs_normalize_coords(ureg, src, const0, const1);
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MOV(ureg, dst, src);
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (is_yuv) {
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	src = ureg_DECL_vs_input(ureg, input_slot++);
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0);
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ureg_MOV(ureg, dst, src);
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (is_composite) {
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	src = ureg_DECL_vs_input(ureg, input_slot++);
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0);
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ureg_MOV(ureg, dst, src);
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (is_fill) {
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	src = ureg_DECL_vs_input(ureg, input_slot++);
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ureg_MOV(ureg, dst, src);
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (has_mask) {
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	src = ureg_DECL_vs_input(ureg, input_slot++);
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1);
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ureg_MOV(ureg, dst, src);
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_END(ureg);
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return ureg_create_shader_and_destroy(ureg, pipe);
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void *
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcreate_yuv_shader(struct pipe_context *pipe, struct ureg_program *ureg)
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_src y_sampler, u_sampler, v_sampler;
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_src pos;
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_src matrow0, matrow1, matrow2, matrow3;
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_dst y, u, v, rgb;
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_dst out = ureg_DECL_output(ureg,
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   TGSI_SEMANTIC_COLOR,
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   0);
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    pos = ureg_DECL_fs_input(ureg,
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     TGSI_SEMANTIC_GENERIC, 0,
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     TGSI_INTERPOLATE_PERSPECTIVE);
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    rgb = ureg_DECL_temporary(ureg);
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    y = ureg_DECL_temporary(ureg);
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    u = ureg_DECL_temporary(ureg);
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    v = ureg_DECL_temporary(ureg);
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    y_sampler = ureg_DECL_sampler(ureg, 0);
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    u_sampler = ureg_DECL_sampler(ureg, 1);
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    v_sampler = ureg_DECL_sampler(ureg, 2);
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    matrow0 = ureg_DECL_constant(ureg, 0);
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    matrow1 = ureg_DECL_constant(ureg, 1);
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    matrow2 = ureg_DECL_constant(ureg, 2);
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    matrow3 = ureg_DECL_constant(ureg, 3);
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_TEX(ureg, y, TGSI_TEXTURE_2D, pos, y_sampler);
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_TEX(ureg, u, TGSI_TEXTURE_2D, pos, u_sampler);
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_TEX(ureg, v, TGSI_TEXTURE_2D, pos, v_sampler);
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MOV(ureg, rgb, matrow3);
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MAD(ureg, rgb,
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_scalar(ureg_src(y), TGSI_SWIZZLE_X), matrow0, ureg_src(rgb));
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MAD(ureg, rgb,
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_scalar(ureg_src(u), TGSI_SWIZZLE_X), matrow1, ureg_src(rgb));
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MAD(ureg, rgb,
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ureg_scalar(ureg_src(v), TGSI_SWIZZLE_X), matrow2, ureg_src(rgb));
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_MOV(ureg, out, ureg_src(rgb));
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_release_temporary(ureg, rgb);
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_release_temporary(ureg, y);
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_release_temporary(ureg, u);
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_release_temporary(ureg, v);
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_END(ureg);
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return ureg_create_shader_and_destroy(ureg, pipe);
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgxrender_tex(struct ureg_program *ureg,
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    struct ureg_dst dst,
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    struct ureg_src coords,
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    struct ureg_src sampler,
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    struct ureg_src imm0,
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    boolean repeat_none, boolean swizzle, boolean set_alpha)
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (repeat_none) {
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct ureg_dst tmp0 = ureg_DECL_temporary(ureg);
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct ureg_dst tmp1 = ureg_DECL_temporary(ureg);
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ureg_SGT(ureg, tmp1, ureg_swizzle(coords,
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					  TGSI_SWIZZLE_X,
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					  TGSI_SWIZZLE_Y,
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					  TGSI_SWIZZLE_X,
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					  TGSI_SWIZZLE_Y), ureg_scalar(imm0,
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org								       TGSI_SWIZZLE_X));
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ureg_SLT(ureg, tmp0,
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 ureg_swizzle(coords, TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y,
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			      TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y), ureg_scalar(imm0,
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org									   TGSI_SWIZZLE_W));
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ureg_MIN(ureg, tmp0, ureg_src(tmp0), ureg_src(tmp1));
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ureg_MIN(ureg, tmp0, ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_X),
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_Y));
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ureg_TEX(ureg, tmp1, TGSI_TEXTURE_2D, coords, sampler);
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (swizzle)
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ureg_MOV(ureg, tmp1, ureg_swizzle(ureg_src(tmp1),
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					      TGSI_SWIZZLE_Z,
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					      TGSI_SWIZZLE_Y, TGSI_SWIZZLE_X,
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					      TGSI_SWIZZLE_W));
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (set_alpha)
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ureg_MOV(ureg,
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     ureg_writemask(tmp1, TGSI_WRITEMASK_W),
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     ureg_scalar(imm0, TGSI_SWIZZLE_W));
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ureg_MUL(ureg, dst, ureg_src(tmp1), ureg_src(tmp0));
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ureg_release_temporary(ureg, tmp0);
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ureg_release_temporary(ureg, tmp1);
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (swizzle) {
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    struct ureg_dst tmp = ureg_DECL_temporary(ureg);
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ureg_TEX(ureg, tmp, TGSI_TEXTURE_2D, coords, sampler);
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ureg_MOV(ureg, dst, ureg_swizzle(ureg_src(tmp),
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					     TGSI_SWIZZLE_Z,
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					     TGSI_SWIZZLE_Y, TGSI_SWIZZLE_X,
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					     TGSI_SWIZZLE_W));
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ureg_release_temporary(ureg, tmp);
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else {
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ureg_TEX(ureg, dst, TGSI_TEXTURE_2D, coords, sampler);
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (set_alpha)
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ureg_MOV(ureg,
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     ureg_writemask(dst, TGSI_WRITEMASK_W),
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		     ureg_scalar(imm0, TGSI_SWIZZLE_W));
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void *
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcreate_fs(struct pipe_context *pipe, unsigned fs_traits)
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_program *ureg;
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_src /*dst_sampler, */ src_sampler, mask_sampler;
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_src /*dst_pos, */ src_input, mask_pos;
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_dst src, mask;
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_dst out;
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct ureg_src imm0 = { 0 };
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned has_mask = (fs_traits & FS_MASK) != 0;
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned is_fill = (fs_traits & FS_FILL) != 0;
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned is_composite = (fs_traits & FS_COMPOSITE) != 0;
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned is_solid = (fs_traits & FS_SOLID_FILL) != 0;
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned is_lingrad = (fs_traits & FS_LINGRAD_FILL) != 0;
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned is_radgrad = (fs_traits & FS_RADGRAD_FILL) != 0;
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned comp_alpha_mask = fs_traits & FS_COMPONENT_ALPHA;
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned is_yuv = (fs_traits & FS_YUV) != 0;
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned src_repeat_none = (fs_traits & FS_SRC_REPEAT_NONE) != 0;
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned mask_repeat_none = (fs_traits & FS_MASK_REPEAT_NONE) != 0;
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned src_swizzle = (fs_traits & FS_SRC_SWIZZLE_RGB) != 0;
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned mask_swizzle = (fs_traits & FS_MASK_SWIZZLE_RGB) != 0;
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned src_set_alpha = (fs_traits & FS_SRC_SET_ALPHA) != 0;
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned mask_set_alpha = (fs_traits & FS_MASK_SET_ALPHA) != 0;
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned src_luminance = (fs_traits & FS_SRC_LUMINANCE) != 0;
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned mask_luminance = (fs_traits & FS_MASK_LUMINANCE) != 0;
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned dst_luminance = (fs_traits & FS_DST_LUMINANCE) != 0;
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    print_fs_traits(fs_traits);
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    (void)print_fs_traits;
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (ureg == NULL)
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return 0;
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* it has to be either a fill, a composite op or a yuv conversion */
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    debug_assert((is_fill ^ is_composite) ^ is_yuv);
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    (void)is_yuv;
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (src_repeat_none || mask_repeat_none ||
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	src_set_alpha || mask_set_alpha || src_luminance) {
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	imm0 = ureg_imm4f(ureg, 0, 0, 0, 1);
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (is_composite) {
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	src_sampler = ureg_DECL_sampler(ureg, 0);
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	src_input = ureg_DECL_fs_input(ureg,
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       TGSI_SEMANTIC_GENERIC, 0,
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       TGSI_INTERPOLATE_PERSPECTIVE);
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else if (is_fill) {
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (is_solid)
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    src_input = ureg_DECL_fs_input(ureg,
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   TGSI_SEMANTIC_COLOR, 0,
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   TGSI_INTERPOLATE_PERSPECTIVE);
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	else
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    src_input = ureg_DECL_fs_input(ureg,
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   TGSI_SEMANTIC_POSITION, 0,
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   TGSI_INTERPOLATE_PERSPECTIVE);
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	debug_assert(is_yuv);
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return create_yuv_shader(pipe, ureg);
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (has_mask) {
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	mask_sampler = ureg_DECL_sampler(ureg, 1);
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	mask_pos = ureg_DECL_fs_input(ureg,
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				      TGSI_SEMANTIC_GENERIC, 1,
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				      TGSI_INTERPOLATE_PERSPECTIVE);
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0				/* unused right now */
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    dst_sampler = ureg_DECL_sampler(ureg, 2);
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    dst_pos = ureg_DECL_fs_input(ureg,
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 TGSI_SEMANTIC_POSITION, 2,
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 TGSI_INTERPOLATE_PERSPECTIVE);
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (is_composite) {
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (has_mask || src_luminance || dst_luminance)
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    src = ureg_DECL_temporary(ureg);
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	else
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    src = out;
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	xrender_tex(ureg, src, src_input, src_sampler, imm0,
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    src_repeat_none, src_swizzle, src_set_alpha);
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else if (is_fill) {
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (is_solid) {
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (has_mask || src_luminance || dst_luminance)
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		src = ureg_dst(src_input);
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    else
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ureg_MOV(ureg, out, src_input);
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else if (is_lingrad || is_radgrad) {
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    struct ureg_src coords, const0124, matrow0, matrow1, matrow2;
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (has_mask || src_luminance || dst_luminance)
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		src = ureg_DECL_temporary(ureg);
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    else
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		src = out;
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    coords = ureg_DECL_constant(ureg, 0);
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    const0124 = ureg_DECL_constant(ureg, 1);
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    matrow0 = ureg_DECL_constant(ureg, 2);
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    matrow1 = ureg_DECL_constant(ureg, 3);
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    matrow2 = ureg_DECL_constant(ureg, 4);
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (is_lingrad) {
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		linear_gradient(ureg, src,
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				src_input, src_sampler,
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				coords, const0124, matrow0, matrow1, matrow2);
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    } else if (is_radgrad) {
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		radial_gradient(ureg, src,
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				src_input, src_sampler,
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				coords, const0124, matrow0, matrow1, matrow2);
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    }
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    debug_assert(!"Unknown fill type!");
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (src_luminance) {
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ureg_MOV(ureg, src, ureg_scalar(ureg_src(src), TGSI_SWIZZLE_X));
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ureg_MOV(ureg, ureg_writemask(src, TGSI_WRITEMASK_XYZ),
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 ureg_scalar(imm0, TGSI_SWIZZLE_X));
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!has_mask && !dst_luminance)
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ureg_MOV(ureg, out, ureg_src(src));
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (has_mask) {
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	mask = ureg_DECL_temporary(ureg);
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0,
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    mask_repeat_none, mask_swizzle, mask_set_alpha);
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* src IN mask */
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	src_in_mask(ureg, (dst_luminance) ? src : out, ureg_src(src),
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    ureg_src(mask),
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		    comp_alpha_mask, mask_luminance);
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ureg_release_temporary(ureg, mask);
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (dst_luminance) {
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/*
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * Make sure the alpha channel goes into the output L8 surface.
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 */
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ureg_MOV(ureg, out, ureg_scalar(ureg_src(src), TGSI_SWIZZLE_W));
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ureg_END(ureg);
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return ureg_create_shader_and_destroy(ureg, pipe);
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct xa_shaders *
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgxa_shaders_create(struct xa_context *r)
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct xa_shaders *sc = CALLOC_STRUCT(xa_shaders);
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    sc->r = r;
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    sc->vs_hash = cso_hash_create();
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    sc->fs_hash = cso_hash_create();
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return sc;
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcache_destroy(struct cso_context *cso,
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      struct cso_hash *hash, unsigned processor)
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct cso_hash_iter iter = cso_hash_first_node(hash);
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    while (!cso_hash_iter_is_null(iter)) {
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	void *shader = (void *)cso_hash_iter_data(iter);
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (processor == PIPE_SHADER_FRAGMENT) {
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    cso_delete_fragment_shader(cso, shader);
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else if (processor == PIPE_SHADER_VERTEX) {
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    cso_delete_vertex_shader(cso, shader);
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	iter = cso_hash_erase(hash, iter);
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    cso_hash_delete(hash);
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgxa_shaders_destroy(struct xa_shaders *sc)
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    cache_destroy(sc->r->cso, sc->vs_hash, PIPE_SHADER_VERTEX);
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    cache_destroy(sc->r->cso, sc->fs_hash, PIPE_SHADER_FRAGMENT);
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    FREE(sc);
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void *
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgshader_from_cache(struct pipe_context *pipe,
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  unsigned type, struct cso_hash *hash, unsigned key)
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    void *shader = 0;
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct cso_hash_iter iter = cso_hash_find(hash, key);
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (cso_hash_iter_is_null(iter)) {
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (type == PIPE_SHADER_VERTEX)
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    shader = create_vs(pipe, key);
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	else
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    shader = create_fs(pipe, key);
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cso_hash_insert(hash, key, shader);
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	shader = (void *)cso_hash_iter_data(iter);
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return shader;
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct xa_shader
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgxa_shaders_get(struct xa_shaders *sc, unsigned vs_traits, unsigned fs_traits)
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct xa_shader shader = { NULL, NULL };
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    void *vs, *fs;
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    vs = shader_from_cache(sc->r->pipe, PIPE_SHADER_VERTEX,
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   sc->vs_hash, vs_traits);
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    fs = shader_from_cache(sc->r->pipe, PIPE_SHADER_FRAGMENT,
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			   sc->fs_hash, fs_traits);
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    debug_assert(vs && fs);
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!vs || !fs)
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return shader;
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    shader.vs = vs;
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    shader.fs = fs;
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return shader;
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
660