1 /**************************************************************************
3 * Copyright 2009 VMware, Inc. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 **************************************************************************/
30 #include "tgsi/tgsi_ureg.h"
32 typedef void (* ureg_func
)( struct ureg_program
*ureg
,
35 struct ureg_src
*sampler
,
36 struct ureg_dst
*temp
,
37 struct ureg_src
*constant
);
40 solid_fill( struct ureg_program
*ureg
,
43 struct ureg_src
*sampler
,
44 struct ureg_dst
*temp
,
45 struct ureg_src
*constant
)
47 ureg_MOV(ureg
, *out
, constant
[2]);
51 linear_grad( struct ureg_program
*ureg
,
54 struct ureg_src
*sampler
,
55 struct ureg_dst
*temp
,
56 struct ureg_src
*constant
)
60 ureg_writemask(temp
[0], TGSI_WRITEMASK_XY
),
63 ureg_writemask(temp
[0], TGSI_WRITEMASK_Z
),
64 ureg_scalar(constant
[3], TGSI_SWIZZLE_Y
));
65 ureg_DP3(ureg
, temp
[1], constant
[4], ureg_src(temp
[0]));
66 ureg_DP3(ureg
, temp
[2], constant
[5], ureg_src(temp
[0]));
67 ureg_DP3(ureg
, temp
[3], constant
[6], ureg_src(temp
[0]));
68 ureg_RCP(ureg
, temp
[3], ureg_src(temp
[3]));
69 ureg_MUL(ureg
, temp
[1], ureg_src(temp
[1]), ureg_src(temp
[3]));
70 ureg_MUL(ureg
, temp
[2], ureg_src(temp
[2]), ureg_src(temp
[3]));
71 ureg_MOV(ureg
, ureg_writemask(temp
[4], TGSI_WRITEMASK_X
), ureg_src(temp
[1]));
72 ureg_MOV(ureg
, ureg_writemask(temp
[4], TGSI_WRITEMASK_Y
), ureg_src(temp
[2]));
73 ureg_MUL(ureg
, temp
[0],
74 ureg_scalar(constant
[2], TGSI_SWIZZLE_Y
),
75 ureg_scalar(ureg_src(temp
[4]), TGSI_SWIZZLE_Y
));
76 ureg_MAD(ureg
, temp
[1],
77 ureg_scalar(constant
[2], TGSI_SWIZZLE_X
),
78 ureg_scalar(ureg_src(temp
[4]), TGSI_SWIZZLE_X
),
80 ureg_MUL(ureg
, temp
[2], ureg_src(temp
[1]),
81 ureg_scalar(constant
[2], TGSI_SWIZZLE_Z
));
82 ureg_TEX(ureg
, *out
, TGSI_TEXTURE_1D
, ureg_src(temp
[2]), sampler
[0]);
86 radial_grad( struct ureg_program
*ureg
,
89 struct ureg_src
*sampler
,
90 struct ureg_dst
*temp
,
91 struct ureg_src
*constant
)
94 ureg_MOV(ureg
, ureg_writemask(temp
[0], TGSI_WRITEMASK_XY
), in
[0]);
96 ureg_writemask(temp
[0], TGSI_WRITEMASK_Z
),
97 ureg_scalar(constant
[3], TGSI_SWIZZLE_Y
));
98 ureg_DP3(ureg
, temp
[1], constant
[4], ureg_src(temp
[0]));
99 ureg_DP3(ureg
, temp
[2], constant
[5], ureg_src(temp
[0]));
100 ureg_DP3(ureg
, temp
[3], constant
[6], ureg_src(temp
[0]));
101 ureg_RCP(ureg
, temp
[3], ureg_src(temp
[3]));
102 ureg_MUL(ureg
, temp
[1], ureg_src(temp
[1]), ureg_src(temp
[3]));
103 ureg_MUL(ureg
, temp
[2], ureg_src(temp
[2]), ureg_src(temp
[3]));
104 ureg_MOV(ureg
, ureg_writemask(temp
[5], TGSI_WRITEMASK_X
), ureg_src(temp
[1]));
105 ureg_MOV(ureg
, ureg_writemask(temp
[5], TGSI_WRITEMASK_Y
), ureg_src(temp
[2]));
106 ureg_MUL(ureg
, temp
[0], ureg_scalar(constant
[2], TGSI_SWIZZLE_Y
),
107 ureg_scalar(ureg_src(temp
[5]), TGSI_SWIZZLE_Y
));
108 ureg_MAD(ureg
, temp
[1],
109 ureg_scalar(constant
[2], TGSI_SWIZZLE_X
),
110 ureg_scalar(ureg_src(temp
[5]), TGSI_SWIZZLE_X
), ureg_src(temp
[0]));
111 ureg_ADD(ureg
, temp
[1], ureg_src(temp
[1]), ureg_src(temp
[1]));
112 ureg_MUL(ureg
, temp
[3],
113 ureg_scalar(ureg_src(temp
[5]), TGSI_SWIZZLE_Y
),
114 ureg_scalar(ureg_src(temp
[5]), TGSI_SWIZZLE_Y
));
115 ureg_MAD(ureg
, temp
[4],
116 ureg_scalar(ureg_src(temp
[5]), TGSI_SWIZZLE_X
),
117 ureg_scalar(ureg_src(temp
[5]), TGSI_SWIZZLE_X
),
119 ureg_MOV(ureg
, temp
[4], ureg_negate(ureg_src(temp
[4])));
120 ureg_MUL(ureg
, temp
[2],
121 ureg_scalar(constant
[2], TGSI_SWIZZLE_Z
),
123 ureg_MUL(ureg
, temp
[0],
124 ureg_scalar(constant
[3], TGSI_SWIZZLE_W
),
126 ureg_MUL(ureg
, temp
[3], ureg_src(temp
[1]), ureg_src(temp
[1]));
128 ureg_SUB(ureg
, temp
[2], ureg_src(temp
[3]), ureg_src(temp
[0]));
129 ureg_RSQ(ureg
, temp
[2], ureg_abs(ureg_src(temp
[2])));
130 ureg_RCP(ureg
, temp
[2], ureg_src(temp
[2]));
131 ureg_SUB(ureg
, temp
[1], ureg_src(temp
[2]), ureg_src(temp
[1]));
132 ureg_ADD(ureg
, temp
[0],
133 ureg_scalar(constant
[2], TGSI_SWIZZLE_Z
),
134 ureg_scalar(constant
[2], TGSI_SWIZZLE_Z
));
135 ureg_RCP(ureg
, temp
[0], ureg_src(temp
[0]));
136 ureg_MUL(ureg
, temp
[2], ureg_src(temp
[1]), ureg_src(temp
[0]));
137 ureg_TEX(ureg
, *out
, TGSI_TEXTURE_1D
, ureg_src(temp
[2]), sampler
[0]);
143 pattern( struct ureg_program
*ureg
,
144 struct ureg_dst
*out
,
146 struct ureg_src
*sampler
,
147 struct ureg_dst
*temp
,
148 struct ureg_src
*constant
)
151 ureg_writemask(temp
[0], TGSI_WRITEMASK_XY
),
154 ureg_writemask(temp
[0], TGSI_WRITEMASK_Z
),
155 ureg_scalar(constant
[3], TGSI_SWIZZLE_Y
));
156 ureg_DP3(ureg
, temp
[1], constant
[4], ureg_src(temp
[0]));
157 ureg_DP3(ureg
, temp
[2], constant
[5], ureg_src(temp
[0]));
158 ureg_DP3(ureg
, temp
[3], constant
[6], ureg_src(temp
[0]));
159 ureg_RCP(ureg
, temp
[3], ureg_src(temp
[3]));
160 ureg_MUL(ureg
, temp
[1], ureg_src(temp
[1]), ureg_src(temp
[3]));
161 ureg_MUL(ureg
, temp
[2], ureg_src(temp
[2]), ureg_src(temp
[3]));
162 ureg_MOV(ureg
, ureg_writemask(temp
[4], TGSI_WRITEMASK_X
), ureg_src(temp
[1]));
163 ureg_MOV(ureg
, ureg_writemask(temp
[4], TGSI_WRITEMASK_Y
), ureg_src(temp
[2]));
164 ureg_RCP(ureg
, temp
[0],
165 ureg_swizzle(constant
[3],
170 ureg_MOV(ureg
, temp
[1], ureg_src(temp
[4]));
172 ureg_writemask(temp
[1], TGSI_WRITEMASK_X
),
176 ureg_writemask(temp
[1], TGSI_WRITEMASK_Y
),
179 ureg_TEX(ureg
, *out
, TGSI_TEXTURE_2D
, ureg_src(temp
[1]), sampler
[0]);
183 color_transform( struct ureg_program
*ureg
,
184 struct ureg_dst
*out
,
186 struct ureg_src
*sampler
,
187 struct ureg_dst
*temp
,
188 struct ureg_src
*constant
)
190 ureg_MUL(ureg
, temp
[1], ureg_src(temp
[0]), constant
[0]);
191 ureg_ADD(ureg
, temp
[1], ureg_src(temp
[1]), constant
[1]);
192 ureg_CLAMP(ureg
, temp
[1],
194 ureg_scalar(constant
[3], TGSI_SWIZZLE_X
),
195 ureg_scalar(constant
[3], TGSI_SWIZZLE_Y
));
196 ureg_MOV(ureg
, *out
, ureg_src(temp
[1]));
200 mask( struct ureg_program
*ureg
,
201 struct ureg_dst
*out
,
203 struct ureg_src
*sampler
,
204 struct ureg_dst
*temp
,
205 struct ureg_src
*constant
)
207 ureg_TEX(ureg
, temp
[1], TGSI_TEXTURE_2D
, in
[0], sampler
[1]);
208 ureg_MUL(ureg
, ureg_writemask(temp
[0], TGSI_WRITEMASK_W
),
209 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_W
),
210 ureg_scalar(ureg_src(temp
[1]), TGSI_SWIZZLE_W
));
211 ureg_MOV(ureg
, *out
, ureg_src(temp
[0]));
215 image_normal( struct ureg_program
*ureg
,
216 struct ureg_dst
*out
,
218 struct ureg_src
*sampler
,
219 struct ureg_dst
*temp
,
220 struct ureg_src
*constant
)
222 ureg_TEX(ureg
, *out
, TGSI_TEXTURE_2D
, in
[1], sampler
[3]);
227 image_multiply( struct ureg_program
*ureg
,
228 struct ureg_dst
*out
,
230 struct ureg_src
*sampler
,
231 struct ureg_dst
*temp
,
232 struct ureg_src
*constant
)
234 ureg_TEX(ureg
, temp
[1], TGSI_TEXTURE_2D
, in
[1], sampler
[3]);
235 ureg_MUL(ureg
, *out
, ureg_src(temp
[0]), ureg_src(temp
[1]));
240 image_stencil( struct ureg_program
*ureg
,
241 struct ureg_dst
*out
,
243 struct ureg_src
*sampler
,
244 struct ureg_dst
*temp
,
245 struct ureg_src
*constant
)
247 ureg_TEX(ureg
, temp
[1], TGSI_TEXTURE_2D
, in
[1], sampler
[3]);
248 ureg_MUL(ureg
, *out
, ureg_src(temp
[0]), ureg_src(temp
[1]));
251 #define EXTENDED_BLENDER_OVER_FUNC \
252 ureg_SUB(ureg, temp[3], \
253 ureg_scalar(constant[3], TGSI_SWIZZLE_Y), \
254 ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W)); \
255 ureg_SUB(ureg, temp[4], \
256 ureg_scalar(constant[3], TGSI_SWIZZLE_Y), \
257 ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W)); \
258 ureg_MUL(ureg, temp[3], ureg_src(temp[0]), ureg_src(temp[3])); \
259 ureg_MUL(ureg, temp[4], ureg_src(temp[1]), ureg_src(temp[4])); \
260 ureg_ADD(ureg, temp[3], ureg_src(temp[3]), ureg_src(temp[4]));
264 blend_multiply( struct ureg_program
*ureg
,
265 struct ureg_dst
*out
,
267 struct ureg_src
*sampler
,
268 struct ureg_dst
*temp
,
269 struct ureg_src
*constant
)
271 ureg_TEX(ureg
, temp
[1], TGSI_TEXTURE_2D
, in
[0], sampler
[2]);
272 EXTENDED_BLENDER_OVER_FUNC
273 ureg_MUL(ureg
, temp
[4], ureg_src(temp
[0]), ureg_src(temp
[1]));
274 ureg_ADD(ureg
, temp
[1], ureg_src(temp
[4]), ureg_src(temp
[3]));
276 ureg_MUL(ureg
, temp
[2], ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_W
),
277 ureg_scalar(ureg_src(temp
[1]), TGSI_SWIZZLE_W
));
278 ureg_ADD(ureg
, temp
[3], ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_W
),
279 ureg_scalar(ureg_src(temp
[1]), TGSI_SWIZZLE_W
));
280 ureg_SUB(ureg
, ureg_writemask(temp
[1], TGSI_WRITEMASK_W
),
281 ureg_src(temp
[3]), ureg_src(temp
[2]));
283 ureg_MOV(ureg
, *out
, ureg_src(temp
[1]));
287 blend_screen( struct ureg_program
*ureg
,
288 struct ureg_dst
*out
,
290 struct ureg_src
*sampler
,
291 struct ureg_dst
*temp
,
292 struct ureg_src
*constant
)
294 ureg_TEX(ureg
, temp
[1], TGSI_TEXTURE_2D
, in
[0], sampler
[2]);
295 ureg_ADD(ureg
, temp
[3], ureg_src(temp
[0]), ureg_src(temp
[1]));
296 ureg_MUL(ureg
, temp
[2], ureg_src(temp
[0]), ureg_src(temp
[1]));
297 ureg_SUB(ureg
, *out
, ureg_src(temp
[3]), ureg_src(temp
[2]));
301 blend_darken( struct ureg_program
*ureg
,
302 struct ureg_dst
*out
,
304 struct ureg_src
*sampler
,
305 struct ureg_dst
*temp
,
306 struct ureg_src
*constant
)
308 ureg_TEX(ureg
, temp
[1], TGSI_TEXTURE_2D
, in
[0], sampler
[2]);
309 EXTENDED_BLENDER_OVER_FUNC
310 ureg_MUL(ureg
, temp
[4], ureg_src(temp
[0]),
311 ureg_scalar(ureg_src(temp
[1]), TGSI_SWIZZLE_W
));
312 ureg_MUL(ureg
, temp
[5], ureg_src(temp
[1]),
313 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_W
));
314 ureg_MIN(ureg
, temp
[4], ureg_src(temp
[4]), ureg_src(temp
[5]));
315 ureg_ADD(ureg
, temp
[1], ureg_src(temp
[3]), ureg_src(temp
[4]));
317 ureg_MUL(ureg
, temp
[2], ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_W
),
318 ureg_scalar(ureg_src(temp
[1]), TGSI_SWIZZLE_W
));
319 ureg_ADD(ureg
, temp
[3], ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_W
),
320 ureg_scalar(ureg_src(temp
[1]), TGSI_SWIZZLE_W
));
321 ureg_SUB(ureg
, ureg_writemask(temp
[1], TGSI_WRITEMASK_W
),
322 ureg_src(temp
[3]), ureg_src(temp
[2]));
324 ureg_MOV(ureg
, *out
, ureg_src(temp
[1]));
328 blend_lighten( struct ureg_program
*ureg
,
329 struct ureg_dst
*out
,
331 struct ureg_src
*sampler
,
332 struct ureg_dst
*temp
,
333 struct ureg_src
*constant
)
335 ureg_TEX(ureg
, temp
[1], TGSI_TEXTURE_2D
, in
[0], sampler
[2]);
336 EXTENDED_BLENDER_OVER_FUNC
337 ureg_MUL(ureg
, temp
[4], ureg_src(temp
[0]),
338 ureg_scalar(ureg_src(temp
[1]), TGSI_SWIZZLE_W
));
339 ureg_MUL(ureg
, temp
[5], ureg_src(temp
[1]),
340 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_W
));
341 ureg_MAX(ureg
, temp
[4], ureg_src(temp
[4]), ureg_src(temp
[5]));
342 ureg_ADD(ureg
, temp
[1], ureg_src(temp
[3]), ureg_src(temp
[4]));
344 ureg_MUL(ureg
, temp
[2], ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_W
),
345 ureg_scalar(ureg_src(temp
[1]), TGSI_SWIZZLE_W
));
346 ureg_ADD(ureg
, temp
[3], ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_W
),
347 ureg_scalar(ureg_src(temp
[1]), TGSI_SWIZZLE_W
));
348 ureg_SUB(ureg
, ureg_writemask(temp
[1], TGSI_WRITEMASK_W
),
349 ureg_src(temp
[3]), ureg_src(temp
[2]));
351 ureg_MOV(ureg
, *out
, ureg_src(temp
[1]));
355 premultiply( struct ureg_program
*ureg
,
356 struct ureg_dst
*out
,
358 struct ureg_src
*sampler
,
359 struct ureg_dst
*temp
,
360 struct ureg_src
*constant
)
363 ureg_writemask(temp
[0], TGSI_WRITEMASK_XYZ
),
365 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_W
));
369 unpremultiply( struct ureg_program
*ureg
,
370 struct ureg_dst
*out
,
372 struct ureg_src
*sampler
,
373 struct ureg_dst
*temp
,
374 struct ureg_src
*constant
)
376 ureg_TEX(ureg
, temp
[0], TGSI_TEXTURE_2D
, in
[0], sampler
[1]);
381 color_bw( struct ureg_program
*ureg
,
382 struct ureg_dst
*out
,
384 struct ureg_src
*sampler
,
385 struct ureg_dst
*temp
,
386 struct ureg_src
*constant
)
388 ureg_ADD(ureg
, temp
[1],
389 ureg_scalar(constant
[3], TGSI_SWIZZLE_Y
),
390 ureg_scalar(constant
[3], TGSI_SWIZZLE_Y
));
391 ureg_RCP(ureg
, temp
[2], ureg_src(temp
[1]));
392 ureg_ADD(ureg
, temp
[1],
393 ureg_scalar(constant
[3], TGSI_SWIZZLE_Y
),
395 ureg_ADD(ureg
, ureg_writemask(temp
[2], TGSI_WRITEMASK_X
),
396 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_X
),
397 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_Y
));
398 ureg_ADD(ureg
, ureg_writemask(temp
[2], TGSI_WRITEMASK_X
),
399 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_Z
),
400 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_X
));
402 ureg_writemask(temp
[0], TGSI_WRITEMASK_XYZ
),
403 ureg_scalar(ureg_src(temp
[2]), TGSI_SWIZZLE_X
),
406 ureg_writemask(temp
[0], TGSI_WRITEMASK_W
),
407 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_W
),
408 ureg_scalar(ureg_src(temp
[2]), TGSI_SWIZZLE_Y
));
409 ureg_MOV(ureg
, *out
, ureg_src(temp
[0]));
413 struct shader_asm_info
{
417 VGboolean needs_position
;
431 static const struct shader_asm_info shaders_paint_asm
[] = {
432 {VEGA_SOLID_FILL_SHADER
, solid_fill
,
433 VG_FALSE
, 2, 1, 0, 0, 0, 0},
434 {VEGA_LINEAR_GRADIENT_SHADER
, linear_grad
,
435 VG_TRUE
, 2, 5, 0, 1, 0, 5},
436 {VEGA_RADIAL_GRADIENT_SHADER
, radial_grad
,
437 VG_TRUE
, 2, 5, 0, 1, 0, 6},
438 {VEGA_PATTERN_SHADER
, pattern
,
439 VG_TRUE
, 3, 4, 0, 1, 0, 5}
442 /* image draw modes */
443 static const struct shader_asm_info shaders_image_asm
[] = {
444 {VEGA_IMAGE_NORMAL_SHADER
, image_normal
,
445 VG_TRUE
, 0, 0, 3, 1, 0, 0},
446 {VEGA_IMAGE_MULTIPLY_SHADER
, image_multiply
,
447 VG_TRUE
, 0, 0, 3, 1, 0, 2},
448 {VEGA_IMAGE_STENCIL_SHADER
, image_stencil
,
449 VG_TRUE
, 0, 0, 3, 1, 0, 2}
452 static const struct shader_asm_info shaders_color_transform_asm
[] = {
453 {VEGA_COLOR_TRANSFORM_SHADER
, color_transform
,
454 VG_FALSE
, 0, 4, 0, 0, 0, 2}
457 static const struct shader_asm_info shaders_mask_asm
[] = {
458 {VEGA_MASK_SHADER
, mask
,
459 VG_TRUE
, 0, 0, 1, 1, 0, 2}
462 /* extra blend modes */
463 static const struct shader_asm_info shaders_blend_asm
[] = {
464 {VEGA_BLEND_MULTIPLY_SHADER
, blend_multiply
,
465 VG_TRUE
, 3, 1, 2, 1, 0, 5},
466 {VEGA_BLEND_SCREEN_SHADER
, blend_screen
,
467 VG_TRUE
, 0, 0, 2, 1, 0, 4},
468 {VEGA_BLEND_DARKEN_SHADER
, blend_darken
,
469 VG_TRUE
, 3, 1, 2, 1, 0, 6},
470 {VEGA_BLEND_LIGHTEN_SHADER
, blend_lighten
,
471 VG_TRUE
, 3, 1, 2, 1, 0, 6},
475 static const struct shader_asm_info shaders_premultiply_asm
[] = {
476 {VEGA_PREMULTIPLY_SHADER
, premultiply
,
477 VG_FALSE
, 0, 0, 0, 0, 0, 1},
478 {VEGA_UNPREMULTIPLY_SHADER
, unpremultiply
,
479 VG_FALSE
, 0, 0, 0, 0, 0, 1},
482 /* color transform to black and white */
483 static const struct shader_asm_info shaders_bw_asm
[] = {
484 {VEGA_BW_SHADER
, color_bw
,
485 VG_FALSE
, 3, 1, 0, 0, 0, 3},