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 * Perform frag-coord-to-paint-coord transform. The transformation is in
54 #define PAINT_TRANSFORM \
55 ureg_MOV(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_XY), in[0]); \
57 ureg_writemask(temp[0], TGSI_WRITEMASK_Z), \
58 ureg_scalar(constant[3], TGSI_SWIZZLE_Y)); \
59 ureg_DP3(ureg, temp[1], constant[4], ureg_src(temp[0])); \
60 ureg_DP3(ureg, temp[2], constant[5], ureg_src(temp[0])); \
61 ureg_DP3(ureg, temp[3], constant[6], ureg_src(temp[0])); \
62 ureg_RCP(ureg, temp[3], ureg_src(temp[3])); \
63 ureg_MUL(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[3])); \
64 ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[3])); \
66 ureg_writemask(temp[4], TGSI_WRITEMASK_X), \
69 ureg_writemask(temp[4], TGSI_WRITEMASK_Y), \
73 linear_grad( struct ureg_program
*ureg
,
76 struct ureg_src
*sampler
,
77 struct ureg_dst
*temp
,
78 struct ureg_src
*constant
)
82 /* grad = DP2((x, y), CONST[2].xy) * CONST[2].z */
83 ureg_MUL(ureg
, temp
[0],
84 ureg_scalar(constant
[2], TGSI_SWIZZLE_Y
),
85 ureg_scalar(ureg_src(temp
[4]), TGSI_SWIZZLE_Y
));
86 ureg_MAD(ureg
, temp
[1],
87 ureg_scalar(constant
[2], TGSI_SWIZZLE_X
),
88 ureg_scalar(ureg_src(temp
[4]), TGSI_SWIZZLE_X
),
90 ureg_MUL(ureg
, temp
[2], ureg_src(temp
[1]),
91 ureg_scalar(constant
[2], TGSI_SWIZZLE_Z
));
93 ureg_TEX(ureg
, *out
, TGSI_TEXTURE_1D
, ureg_src(temp
[2]), sampler
[0]);
97 radial_grad( struct ureg_program
*ureg
,
100 struct ureg_src
*sampler
,
101 struct ureg_dst
*temp
,
102 struct ureg_src
*constant
)
107 * Calculate (sqrt(B^2 + AC) - B) / A, where
110 * B is DP2((x, y), CONST[2].xy), and
111 * C is DP2((x, y), (x, y)).
115 ureg_DP2(ureg
, temp
[0], ureg_src(temp
[4]), constant
[2]);
116 ureg_DP2(ureg
, temp
[1], ureg_src(temp
[4]), ureg_src(temp
[4]));
118 /* the square root */
119 ureg_MUL(ureg
, temp
[2], ureg_src(temp
[0]), ureg_src(temp
[0]));
120 ureg_MAD(ureg
, temp
[3], ureg_src(temp
[1]),
121 ureg_scalar(constant
[2], TGSI_SWIZZLE_Z
), ureg_src(temp
[2]));
122 ureg_RSQ(ureg
, temp
[3], ureg_src(temp
[3]));
123 ureg_RCP(ureg
, temp
[3], ureg_src(temp
[3]));
125 ureg_SUB(ureg
, temp
[3], ureg_src(temp
[3]), ureg_src(temp
[0]));
126 ureg_RCP(ureg
, temp
[0], ureg_scalar(constant
[2], TGSI_SWIZZLE_Z
));
127 ureg_MUL(ureg
, temp
[0], ureg_src(temp
[0]), ureg_src(temp
[3]));
129 ureg_TEX(ureg
, *out
, TGSI_TEXTURE_1D
, ureg_src(temp
[0]), sampler
[0]);
134 pattern( struct ureg_program
*ureg
,
135 struct ureg_dst
*out
,
137 struct ureg_src
*sampler
,
138 struct ureg_dst
*temp
,
139 struct ureg_src
*constant
)
143 /* (s, t) = (x / tex_width, y / tex_height) */
144 ureg_RCP(ureg
, temp
[0],
145 ureg_swizzle(constant
[3],
150 ureg_MOV(ureg
, temp
[1], ureg_src(temp
[4]));
152 ureg_writemask(temp
[1], TGSI_WRITEMASK_X
),
156 ureg_writemask(temp
[1], TGSI_WRITEMASK_Y
),
160 ureg_TEX(ureg
, *out
, TGSI_TEXTURE_2D
, ureg_src(temp
[1]), sampler
[0]);
164 paint_degenerate( struct ureg_program
*ureg
,
165 struct ureg_dst
*out
,
167 struct ureg_src
*sampler
,
168 struct ureg_dst
*temp
,
169 struct ureg_src
*constant
)
171 /* CONST[3].y is 1.0f */
172 ureg_MOV(ureg
, temp
[1], ureg_scalar(constant
[3], TGSI_SWIZZLE_Y
));
173 ureg_TEX(ureg
, *out
, TGSI_TEXTURE_1D
, ureg_src(temp
[1]), sampler
[0]);
177 image_normal( struct ureg_program
*ureg
,
178 struct ureg_dst
*out
,
180 struct ureg_src
*sampler
,
181 struct ureg_dst
*temp
,
182 struct ureg_src
*constant
)
184 ureg_TEX(ureg
, *out
, TGSI_TEXTURE_2D
, in
[1], sampler
[3]);
189 image_multiply( struct ureg_program
*ureg
,
190 struct ureg_dst
*out
,
192 struct ureg_src
*sampler
,
193 struct ureg_dst
*temp
,
194 struct ureg_src
*constant
)
196 ureg_TEX(ureg
, temp
[1], TGSI_TEXTURE_2D
, in
[1], sampler
[3]);
197 ureg_MUL(ureg
, *out
, ureg_src(temp
[0]), ureg_src(temp
[1]));
202 image_stencil( struct ureg_program
*ureg
,
203 struct ureg_dst
*out
,
205 struct ureg_src
*sampler
,
206 struct ureg_dst
*temp
,
207 struct ureg_src
*constant
)
209 ureg_TEX(ureg
, temp
[1], TGSI_TEXTURE_2D
, in
[1], sampler
[3]);
210 ureg_MUL(ureg
, *out
, ureg_src(temp
[0]), ureg_src(temp
[1]));
214 color_transform( struct ureg_program
*ureg
,
215 struct ureg_dst
*out
,
217 struct ureg_src
*sampler
,
218 struct ureg_dst
*temp
,
219 struct ureg_src
*constant
)
221 ureg_MAD(ureg
, temp
[1], ureg_src(temp
[0]), constant
[0], constant
[1]);
222 /* clamp to [0.0f, 1.0f] */
223 ureg_CLAMP(ureg
, temp
[1],
225 ureg_scalar(constant
[3], TGSI_SWIZZLE_X
),
226 ureg_scalar(constant
[3], TGSI_SWIZZLE_Y
));
227 ureg_MOV(ureg
, *out
, ureg_src(temp
[1]));
231 * Emit instructions for the specified blend mode. Colors should be
232 * premultiplied. Two temporary registers are required.
234 * XXX callers do not pass premultiplied colors!
237 blend_generic(struct ureg_program
*ureg
,
242 struct ureg_src src_channel_alpha
,
244 struct ureg_dst temp
[2])
248 ureg_MOV(ureg
, out
, src
);
250 case VG_BLEND_SRC_OVER
:
251 /* RGBA_out = RGBA_src + (1 - A_src) * RGBA_dst */
252 ureg_SUB(ureg
, temp
[0], one
, src_channel_alpha
);
253 ureg_MAD(ureg
, out
, ureg_src(temp
[0]), dst
, src
);
255 case VG_BLEND_DST_OVER
:
256 /* RGBA_out = RGBA_dst + (1 - A_dst) * RGBA_src */
257 ureg_SUB(ureg
, temp
[0], one
, ureg_scalar(dst
, TGSI_SWIZZLE_W
));
258 ureg_MAD(ureg
, out
, ureg_src(temp
[0]), src
, dst
);
260 case VG_BLEND_SRC_IN
:
261 ureg_MUL(ureg
, out
, src
, ureg_scalar(dst
, TGSI_SWIZZLE_W
));
263 case VG_BLEND_DST_IN
:
264 ureg_MUL(ureg
, out
, dst
, src_channel_alpha
);
266 case VG_BLEND_MULTIPLY
:
268 * RGB_out = (1 - A_dst) * RGB_src + (1 - A_src) * RGB_dst +
271 ureg_MAD(ureg
, temp
[0],
272 ureg_scalar(dst
, TGSI_SWIZZLE_W
), ureg_negate(src
), src
);
273 ureg_MAD(ureg
, temp
[1],
274 src_channel_alpha
, ureg_negate(dst
), dst
);
275 ureg_MAD(ureg
, temp
[1], src
, dst
, ureg_src(temp
[1]));
276 ureg_ADD(ureg
, out
, ureg_src(temp
[0]), ureg_src(temp
[1]));
277 /* alpha is src over */
278 ureg_ADD(ureg
, ureg_writemask(out
, TGSI_WRITEMASK_W
),
279 src
, ureg_src(temp
[1]));
281 case VG_BLEND_SCREEN
:
282 /* RGBA_out = RGBA_src + (1 - RGBA_src) * RGBA_dst */
283 ureg_SUB(ureg
, temp
[0], one
, src
);
284 ureg_MAD(ureg
, out
, ureg_src(temp
[0]), dst
, src
);
286 case VG_BLEND_DARKEN
:
287 case VG_BLEND_LIGHTEN
:
289 ureg_SUB(ureg
, temp
[0], one
, src_channel_alpha
);
290 ureg_MAD(ureg
, temp
[0], ureg_src(temp
[0]), dst
, src
);
292 ureg_SUB(ureg
, temp
[1], one
, ureg_scalar(dst
, TGSI_SWIZZLE_W
));
293 ureg_MAD(ureg
, temp
[1], ureg_src(temp
[1]), src
, dst
);
294 /* take min/max for colors */
295 if (mode
== VG_BLEND_DARKEN
) {
296 ureg_MIN(ureg
, ureg_writemask(out
, TGSI_WRITEMASK_XYZ
),
297 ureg_src(temp
[0]), ureg_src(temp
[1]));
300 ureg_MAX(ureg
, ureg_writemask(out
, TGSI_WRITEMASK_XYZ
),
301 ureg_src(temp
[0]), ureg_src(temp
[1]));
304 case VG_BLEND_ADDITIVE
:
305 /* RGBA_out = RGBA_src + RGBA_dst */
306 ureg_ADD(ureg
, temp
[0], src
, dst
);
307 ureg_MIN(ureg
, out
, ureg_src(temp
[0]), one
);
316 blend_multiply( struct ureg_program
*ureg
,
317 struct ureg_dst
*out
,
319 struct ureg_src
*sampler
,
320 struct ureg_dst
*temp
,
321 struct ureg_src
*constant
)
323 ureg_TEX(ureg
, temp
[1], TGSI_TEXTURE_2D
, in
[0], sampler
[2]);
324 blend_generic(ureg
, VG_BLEND_MULTIPLY
, *out
,
327 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_W
),
328 ureg_scalar(constant
[3], TGSI_SWIZZLE_Y
),
333 blend_screen( struct ureg_program
*ureg
,
334 struct ureg_dst
*out
,
336 struct ureg_src
*sampler
,
337 struct ureg_dst
*temp
,
338 struct ureg_src
*constant
)
340 ureg_TEX(ureg
, temp
[1], TGSI_TEXTURE_2D
, in
[0], sampler
[2]);
341 blend_generic(ureg
, VG_BLEND_SCREEN
, *out
,
344 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_W
),
345 ureg_scalar(constant
[3], TGSI_SWIZZLE_Y
),
350 blend_darken( struct ureg_program
*ureg
,
351 struct ureg_dst
*out
,
353 struct ureg_src
*sampler
,
354 struct ureg_dst
*temp
,
355 struct ureg_src
*constant
)
357 ureg_TEX(ureg
, temp
[1], TGSI_TEXTURE_2D
, in
[0], sampler
[2]);
358 blend_generic(ureg
, VG_BLEND_DARKEN
, *out
,
361 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_W
),
362 ureg_scalar(constant
[3], TGSI_SWIZZLE_Y
),
367 blend_lighten( struct ureg_program
*ureg
,
368 struct ureg_dst
*out
,
370 struct ureg_src
*sampler
,
371 struct ureg_dst
*temp
,
372 struct ureg_src
*constant
)
374 ureg_TEX(ureg
, temp
[1], TGSI_TEXTURE_2D
, in
[0], sampler
[2]);
375 blend_generic(ureg
, VG_BLEND_LIGHTEN
, *out
,
378 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_W
),
379 ureg_scalar(constant
[3], TGSI_SWIZZLE_Y
),
384 mask( struct ureg_program
*ureg
,
385 struct ureg_dst
*out
,
387 struct ureg_src
*sampler
,
388 struct ureg_dst
*temp
,
389 struct ureg_src
*constant
)
391 ureg_TEX(ureg
, temp
[1], TGSI_TEXTURE_2D
, in
[0], sampler
[1]);
392 ureg_MUL(ureg
, ureg_writemask(temp
[0], TGSI_WRITEMASK_W
),
393 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_W
),
394 ureg_scalar(ureg_src(temp
[1]), TGSI_SWIZZLE_W
));
395 ureg_MOV(ureg
, *out
, ureg_src(temp
[0]));
399 premultiply( struct ureg_program
*ureg
,
400 struct ureg_dst
*out
,
402 struct ureg_src
*sampler
,
403 struct ureg_dst
*temp
,
404 struct ureg_src
*constant
)
407 ureg_writemask(temp
[0], TGSI_WRITEMASK_XYZ
),
409 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_W
));
413 unpremultiply( struct ureg_program
*ureg
,
414 struct ureg_dst
*out
,
416 struct ureg_src
*sampler
,
417 struct ureg_dst
*temp
,
418 struct ureg_src
*constant
)
420 ureg_TEX(ureg
, temp
[0], TGSI_TEXTURE_2D
, in
[0], sampler
[1]);
425 color_bw( struct ureg_program
*ureg
,
426 struct ureg_dst
*out
,
428 struct ureg_src
*sampler
,
429 struct ureg_dst
*temp
,
430 struct ureg_src
*constant
)
432 ureg_ADD(ureg
, temp
[1],
433 ureg_scalar(constant
[3], TGSI_SWIZZLE_Y
),
434 ureg_scalar(constant
[3], TGSI_SWIZZLE_Y
));
435 ureg_RCP(ureg
, temp
[2], ureg_src(temp
[1]));
436 ureg_ADD(ureg
, temp
[1],
437 ureg_scalar(constant
[3], TGSI_SWIZZLE_Y
),
439 ureg_ADD(ureg
, ureg_writemask(temp
[2], TGSI_WRITEMASK_X
),
440 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_X
),
441 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_Y
));
442 ureg_ADD(ureg
, ureg_writemask(temp
[2], TGSI_WRITEMASK_X
),
443 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_Z
),
444 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_X
));
446 ureg_writemask(temp
[0], TGSI_WRITEMASK_XYZ
),
447 ureg_scalar(ureg_src(temp
[2]), TGSI_SWIZZLE_X
),
450 ureg_writemask(temp
[0], TGSI_WRITEMASK_W
),
451 ureg_scalar(ureg_src(temp
[0]), TGSI_SWIZZLE_W
),
452 ureg_scalar(ureg_src(temp
[2]), TGSI_SWIZZLE_Y
));
453 ureg_MOV(ureg
, *out
, ureg_src(temp
[0]));
457 struct shader_asm_info
{
461 VGboolean needs_position
;
475 static const struct shader_asm_info shaders_paint_asm
[] = {
476 {VEGA_SOLID_FILL_SHADER
, solid_fill
,
477 VG_FALSE
, 2, 1, 0, 0, 0, 0},
478 {VEGA_LINEAR_GRADIENT_SHADER
, linear_grad
,
479 VG_TRUE
, 2, 5, 0, 1, 0, 5},
480 {VEGA_RADIAL_GRADIENT_SHADER
, radial_grad
,
481 VG_TRUE
, 2, 5, 0, 1, 0, 5},
482 {VEGA_PATTERN_SHADER
, pattern
,
483 VG_TRUE
, 3, 4, 0, 1, 0, 5},
484 {VEGA_PAINT_DEGENERATE_SHADER
, paint_degenerate
,
485 VG_FALSE
, 3, 1, 0, 1, 0, 2}
488 /* image draw modes */
489 static const struct shader_asm_info shaders_image_asm
[] = {
490 {VEGA_IMAGE_NORMAL_SHADER
, image_normal
,
491 VG_TRUE
, 0, 0, 3, 1, 0, 0},
492 {VEGA_IMAGE_MULTIPLY_SHADER
, image_multiply
,
493 VG_TRUE
, 0, 0, 3, 1, 0, 2},
494 {VEGA_IMAGE_STENCIL_SHADER
, image_stencil
,
495 VG_TRUE
, 0, 0, 3, 1, 0, 2}
498 static const struct shader_asm_info shaders_color_transform_asm
[] = {
499 {VEGA_COLOR_TRANSFORM_SHADER
, color_transform
,
500 VG_FALSE
, 0, 4, 0, 0, 0, 2}
503 /* extra blend modes */
504 static const struct shader_asm_info shaders_blend_asm
[] = {
505 {VEGA_BLEND_MULTIPLY_SHADER
, blend_multiply
,
506 VG_TRUE
, 3, 1, 2, 1, 0, 4},
507 {VEGA_BLEND_SCREEN_SHADER
, blend_screen
,
508 VG_TRUE
, 3, 1, 2, 1, 0, 4},
509 {VEGA_BLEND_DARKEN_SHADER
, blend_darken
,
510 VG_TRUE
, 3, 1, 2, 1, 0, 4},
511 {VEGA_BLEND_LIGHTEN_SHADER
, blend_lighten
,
512 VG_TRUE
, 3, 1, 2, 1, 0, 4},
515 static const struct shader_asm_info shaders_mask_asm
[] = {
516 {VEGA_MASK_SHADER
, mask
,
517 VG_TRUE
, 0, 0, 1, 1, 0, 2}
521 static const struct shader_asm_info shaders_premultiply_asm
[] = {
522 {VEGA_PREMULTIPLY_SHADER
, premultiply
,
523 VG_FALSE
, 0, 0, 0, 0, 0, 1},
524 {VEGA_UNPREMULTIPLY_SHADER
, unpremultiply
,
525 VG_FALSE
, 0, 0, 0, 0, 0, 1},
528 /* color transform to black and white */
529 static const struct shader_asm_info shaders_bw_asm
[] = {
530 {VEGA_BW_SHADER
, color_bw
,
531 VG_FALSE
, 3, 1, 0, 0, 0, 3},