asm_fill.h revision a09baf166826aba5be7dcf2347047129730f1628
1/**************************************************************************
2 *
3 * Copyright 2009 VMware, Inc.  All Rights Reserved.
4 *
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:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
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.
24 *
25 **************************************************************************/
26
27#ifndef ASM_FILL_H
28#define ASM_FILL_H
29
30#include "tgsi/tgsi_ureg.h"
31
32typedef void (* ureg_func)( struct ureg_program *ureg,
33                            struct ureg_dst *out,
34                            struct ureg_src *in,
35                            struct ureg_src *sampler,
36                            struct ureg_dst *temp,
37                            struct ureg_src *constant);
38
39static INLINE void
40solid_fill( struct ureg_program *ureg,
41            struct ureg_dst *out,
42            struct ureg_src *in,
43            struct ureg_src *sampler,
44            struct ureg_dst *temp,
45            struct ureg_src *constant)
46{
47   ureg_MOV(ureg, *out, constant[2]);
48}
49
50/**
51 * Perform frag-coord-to-paint-coord transform.  The transformation is in
52 * CONST[4..6].
53 */
54#define PAINT_TRANSFORM                                                 \
55   ureg_MOV(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_XY), in[0]);   \
56   ureg_MOV(ureg,                                                       \
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]));       \
65   ureg_MOV(ureg,                                                       \
66            ureg_writemask(temp[4], TGSI_WRITEMASK_X),                  \
67            ureg_src(temp[1]));                                         \
68   ureg_MOV(ureg,                                                       \
69            ureg_writemask(temp[4], TGSI_WRITEMASK_Y),                  \
70            ureg_src(temp[2]));
71
72static INLINE void
73linear_grad( struct ureg_program *ureg,
74             struct ureg_dst *out,
75             struct ureg_src *in,
76             struct ureg_src *sampler,
77             struct ureg_dst *temp,
78             struct ureg_src *constant)
79{
80   PAINT_TRANSFORM
81
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),
89            ureg_src(temp[0]));
90   ureg_MUL(ureg, temp[2], ureg_src(temp[1]),
91            ureg_scalar(constant[2], TGSI_SWIZZLE_Z));
92
93   ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[2]), sampler[0]);
94}
95
96static INLINE void
97radial_grad( struct ureg_program *ureg,
98             struct ureg_dst *out,
99             struct ureg_src *in,
100             struct ureg_src *sampler,
101             struct ureg_dst *temp,
102             struct ureg_src *constant)
103{
104   PAINT_TRANSFORM
105
106   /*
107    * Calculate (sqrt(B^2 + AC) - B) / A, where
108    *
109    *   A is CONST[2].z,
110    *   B is DP2((x, y), CONST[2].xy), and
111    *   C is DP2((x, y), (x, y)).
112    */
113
114   /* B and C */
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]));
117
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]));
124
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]));
128
129   ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[0]), sampler[0]);
130}
131
132
133static INLINE void
134pattern( struct ureg_program *ureg,
135         struct ureg_dst     *out,
136         struct ureg_src     *in,
137         struct ureg_src     *sampler,
138         struct ureg_dst     *temp,
139         struct ureg_src     *constant)
140{
141   PAINT_TRANSFORM
142
143   /* (s, t) = (x / tex_width, y / tex_height) */
144   ureg_RCP(ureg, temp[0],
145            ureg_swizzle(constant[3],
146                         TGSI_SWIZZLE_Z,
147                         TGSI_SWIZZLE_W,
148                         TGSI_SWIZZLE_Z,
149                         TGSI_SWIZZLE_W));
150   ureg_MOV(ureg, temp[1], ureg_src(temp[4]));
151   ureg_MUL(ureg,
152            ureg_writemask(temp[1], TGSI_WRITEMASK_X),
153            ureg_src(temp[1]),
154            ureg_src(temp[0]));
155   ureg_MUL(ureg,
156            ureg_writemask(temp[1], TGSI_WRITEMASK_Y),
157            ureg_src(temp[1]),
158            ureg_src(temp[0]));
159
160   ureg_TEX(ureg, *out, TGSI_TEXTURE_2D, ureg_src(temp[1]), sampler[0]);
161}
162
163static INLINE void
164paint_degenerate( struct ureg_program *ureg,
165                  struct ureg_dst *out,
166                  struct ureg_src *in,
167                  struct ureg_src *sampler,
168                  struct ureg_dst *temp,
169                  struct ureg_src *constant)
170{
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]);
174}
175
176static INLINE void
177color_transform( struct ureg_program *ureg,
178                 struct ureg_dst *out,
179                 struct ureg_src *in,
180                 struct ureg_src *sampler,
181                 struct ureg_dst *temp,
182                 struct ureg_src *constant)
183{
184   ureg_MAD(ureg, temp[1], ureg_src(temp[0]), constant[0], constant[1]);
185   /* clamp to [0.0f, 1.0f] */
186   ureg_CLAMP(ureg, temp[1],
187              ureg_src(temp[1]),
188              ureg_scalar(constant[3], TGSI_SWIZZLE_X),
189              ureg_scalar(constant[3], TGSI_SWIZZLE_Y));
190   ureg_MOV(ureg, *out, ureg_src(temp[1]));
191}
192
193static INLINE void
194mask( struct ureg_program *ureg,
195      struct ureg_dst *out,
196      struct ureg_src *in,
197      struct ureg_src *sampler,
198      struct ureg_dst *temp,
199      struct ureg_src *constant)
200{
201   ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[1]);
202   ureg_MUL(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_W),
203            ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
204            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
205   ureg_MOV(ureg, *out, ureg_src(temp[0]));
206}
207
208static INLINE void
209image_normal( struct ureg_program *ureg,
210              struct ureg_dst *out,
211              struct ureg_src *in,
212              struct ureg_src *sampler,
213              struct ureg_dst *temp,
214              struct ureg_src *constant)
215{
216   ureg_TEX(ureg, *out, TGSI_TEXTURE_2D, in[1], sampler[3]);
217}
218
219
220static INLINE void
221image_multiply( struct ureg_program *ureg,
222                struct ureg_dst *out,
223                struct ureg_src *in,
224                struct ureg_src *sampler,
225                struct ureg_dst *temp,
226                struct ureg_src *constant)
227{
228   ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]);
229   ureg_MUL(ureg, *out, ureg_src(temp[0]), ureg_src(temp[1]));
230}
231
232
233static INLINE void
234image_stencil( struct ureg_program *ureg,
235               struct ureg_dst *out,
236               struct ureg_src *in,
237               struct ureg_src *sampler,
238               struct ureg_dst *temp,
239               struct ureg_src *constant)
240{
241   ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]);
242   ureg_MUL(ureg, *out, ureg_src(temp[0]), ureg_src(temp[1]));
243}
244
245#define EXTENDED_BLENDER_OVER_FUNC                                      \
246   ureg_SUB(ureg, temp[3],                                              \
247            ureg_scalar(constant[3], TGSI_SWIZZLE_Y),                   \
248            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));            \
249   ureg_SUB(ureg, temp[4],                                              \
250            ureg_scalar(constant[3], TGSI_SWIZZLE_Y),                   \
251            ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));            \
252   ureg_MUL(ureg, temp[3], ureg_src(temp[0]), ureg_src(temp[3]));       \
253   ureg_MUL(ureg, temp[4], ureg_src(temp[1]), ureg_src(temp[4]));       \
254   ureg_ADD(ureg, temp[3], ureg_src(temp[3]), ureg_src(temp[4]));
255
256
257static INLINE void
258blend_multiply( struct ureg_program *ureg,
259                struct ureg_dst *out,
260                struct ureg_src *in,
261                struct ureg_src *sampler,
262                struct ureg_dst *temp,
263                struct ureg_src *constant)
264{
265   ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]);
266   EXTENDED_BLENDER_OVER_FUNC
267   ureg_MUL(ureg, temp[4], ureg_src(temp[0]), ureg_src(temp[1]));
268   ureg_ADD(ureg, temp[1], ureg_src(temp[4]), ureg_src(temp[3]));
269
270   ureg_MUL(ureg, temp[2], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
271            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
272   ureg_ADD(ureg, temp[3], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
273            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
274   ureg_SUB(ureg, ureg_writemask(temp[1], TGSI_WRITEMASK_W),
275            ureg_src(temp[3]), ureg_src(temp[2]));
276
277   ureg_MOV(ureg, *out, ureg_src(temp[1]));
278}
279
280static INLINE void
281blend_screen( struct ureg_program *ureg,
282              struct ureg_dst     *out,
283              struct ureg_src     *in,
284              struct ureg_src     *sampler,
285              struct ureg_dst     *temp,
286              struct ureg_src     *constant)
287{
288   ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]);
289   ureg_ADD(ureg, temp[3], ureg_src(temp[0]), ureg_src(temp[1]));
290   ureg_MUL(ureg, temp[2], ureg_src(temp[0]), ureg_src(temp[1]));
291   ureg_SUB(ureg, *out, ureg_src(temp[3]), ureg_src(temp[2]));
292}
293
294static INLINE void
295blend_darken( struct ureg_program *ureg,
296              struct ureg_dst     *out,
297              struct ureg_src     *in,
298              struct ureg_src     *sampler,
299              struct ureg_dst     *temp,
300              struct ureg_src     *constant)
301{
302   ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]);
303   EXTENDED_BLENDER_OVER_FUNC
304   ureg_MUL(ureg, temp[4], ureg_src(temp[0]),
305            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
306   ureg_MUL(ureg, temp[5], ureg_src(temp[1]),
307            ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
308   ureg_MIN(ureg, temp[4], ureg_src(temp[4]), ureg_src(temp[5]));
309   ureg_ADD(ureg, temp[1], ureg_src(temp[3]), ureg_src(temp[4]));
310
311   ureg_MUL(ureg, temp[2], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
312            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
313   ureg_ADD(ureg, temp[3], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
314            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
315   ureg_SUB(ureg, ureg_writemask(temp[1], TGSI_WRITEMASK_W),
316            ureg_src(temp[3]), ureg_src(temp[2]));
317
318   ureg_MOV(ureg, *out, ureg_src(temp[1]));
319}
320
321static INLINE void
322blend_lighten( struct ureg_program *ureg,
323               struct ureg_dst     *out,
324               struct ureg_src     *in,
325               struct ureg_src     *sampler,
326               struct ureg_dst *temp,
327               struct ureg_src     *constant)
328{
329   ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]);
330   EXTENDED_BLENDER_OVER_FUNC
331   ureg_MUL(ureg, temp[4], ureg_src(temp[0]),
332            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
333   ureg_MUL(ureg, temp[5], ureg_src(temp[1]),
334            ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
335   ureg_MAX(ureg, temp[4], ureg_src(temp[4]), ureg_src(temp[5]));
336   ureg_ADD(ureg, temp[1], ureg_src(temp[3]), ureg_src(temp[4]));
337
338   ureg_MUL(ureg, temp[2], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
339            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
340   ureg_ADD(ureg, temp[3], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
341            ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
342   ureg_SUB(ureg, ureg_writemask(temp[1], TGSI_WRITEMASK_W),
343            ureg_src(temp[3]), ureg_src(temp[2]));
344
345   ureg_MOV(ureg, *out, ureg_src(temp[1]));
346}
347
348static INLINE void
349premultiply( struct ureg_program *ureg,
350                struct ureg_dst *out,
351                struct ureg_src *in,
352                struct ureg_src *sampler,
353                struct ureg_dst *temp,
354                struct ureg_src *constant)
355{
356   ureg_MUL(ureg,
357            ureg_writemask(temp[0], TGSI_WRITEMASK_XYZ),
358            ureg_src(temp[0]),
359            ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
360}
361
362static INLINE void
363unpremultiply( struct ureg_program *ureg,
364                struct ureg_dst *out,
365                struct ureg_src *in,
366                struct ureg_src *sampler,
367                struct ureg_dst *temp,
368                struct ureg_src *constant)
369{
370   ureg_TEX(ureg, temp[0], TGSI_TEXTURE_2D, in[0], sampler[1]);
371}
372
373
374static INLINE void
375color_bw( struct ureg_program *ureg,
376                struct ureg_dst *out,
377                struct ureg_src *in,
378                struct ureg_src *sampler,
379                struct ureg_dst *temp,
380                struct ureg_src *constant)
381{
382   ureg_ADD(ureg, temp[1],
383            ureg_scalar(constant[3], TGSI_SWIZZLE_Y),
384            ureg_scalar(constant[3], TGSI_SWIZZLE_Y));
385   ureg_RCP(ureg, temp[2], ureg_src(temp[1]));
386   ureg_ADD(ureg, temp[1],
387            ureg_scalar(constant[3], TGSI_SWIZZLE_Y),
388            ureg_src(temp[2]));
389   ureg_ADD(ureg, ureg_writemask(temp[2], TGSI_WRITEMASK_X),
390            ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_X),
391            ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_Y));
392   ureg_ADD(ureg, ureg_writemask(temp[2], TGSI_WRITEMASK_X),
393            ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_Z),
394            ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_X));
395   ureg_SGE(ureg,
396            ureg_writemask(temp[0], TGSI_WRITEMASK_XYZ),
397            ureg_scalar(ureg_src(temp[2]), TGSI_SWIZZLE_X),
398            ureg_src(temp[1]));
399  ureg_SGE(ureg,
400           ureg_writemask(temp[0], TGSI_WRITEMASK_W),
401           ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
402           ureg_scalar(ureg_src(temp[2]), TGSI_SWIZZLE_Y));
403  ureg_MOV(ureg, *out, ureg_src(temp[0]));
404}
405
406
407struct shader_asm_info {
408   VGint id;
409   ureg_func func;
410
411   VGboolean needs_position;
412
413   VGint start_const;
414   VGint num_consts;
415
416   VGint start_sampler;
417   VGint num_samplers;
418
419   VGint start_temp;
420   VGint num_temps;
421};
422
423
424/* paint types */
425static const struct shader_asm_info shaders_paint_asm[] = {
426   {VEGA_SOLID_FILL_SHADER, solid_fill,
427    VG_FALSE, 2, 1, 0, 0, 0, 0},
428   {VEGA_LINEAR_GRADIENT_SHADER, linear_grad,
429    VG_TRUE,  2, 5, 0, 1, 0, 5},
430   {VEGA_RADIAL_GRADIENT_SHADER, radial_grad,
431    VG_TRUE,  2, 5, 0, 1, 0, 5},
432   {VEGA_PATTERN_SHADER, pattern,
433    VG_TRUE,  3, 4, 0, 1, 0, 5},
434   {VEGA_PAINT_DEGENERATE_SHADER, paint_degenerate,
435    VG_FALSE,  3, 1, 0, 1, 0, 2}
436};
437
438/* image draw modes */
439static const struct shader_asm_info shaders_image_asm[] = {
440   {VEGA_IMAGE_NORMAL_SHADER, image_normal,
441    VG_TRUE,  0, 0, 3, 1, 0, 0},
442   {VEGA_IMAGE_MULTIPLY_SHADER, image_multiply,
443    VG_TRUE,  0, 0, 3, 1, 0, 2},
444   {VEGA_IMAGE_STENCIL_SHADER, image_stencil,
445    VG_TRUE,  0, 0, 3, 1, 0, 2}
446};
447
448static const struct shader_asm_info shaders_color_transform_asm[] = {
449   {VEGA_COLOR_TRANSFORM_SHADER, color_transform,
450    VG_FALSE, 0, 4, 0, 0, 0, 2}
451};
452
453static const struct shader_asm_info shaders_mask_asm[] = {
454   {VEGA_MASK_SHADER, mask,
455    VG_TRUE,  0, 0, 1, 1, 0, 2}
456};
457
458/* extra blend modes */
459static const struct shader_asm_info shaders_blend_asm[] = {
460   {VEGA_BLEND_MULTIPLY_SHADER, blend_multiply,
461    VG_TRUE,  3, 1, 2, 1, 0, 5},
462   {VEGA_BLEND_SCREEN_SHADER, blend_screen,
463    VG_TRUE,  0, 0, 2, 1, 0, 4},
464   {VEGA_BLEND_DARKEN_SHADER, blend_darken,
465    VG_TRUE,  3, 1, 2, 1, 0, 6},
466   {VEGA_BLEND_LIGHTEN_SHADER, blend_lighten,
467    VG_TRUE,  3, 1, 2, 1, 0, 6},
468};
469
470/* premultiply */
471static const struct shader_asm_info shaders_premultiply_asm[] = {
472   {VEGA_PREMULTIPLY_SHADER, premultiply,
473    VG_FALSE,  0, 0, 0, 0, 0, 1},
474   {VEGA_UNPREMULTIPLY_SHADER, unpremultiply,
475    VG_FALSE,  0, 0, 0, 0, 0, 1},
476};
477
478/* color transform to black and white */
479static const struct shader_asm_info shaders_bw_asm[] = {
480   {VEGA_BW_SHADER, color_bw,
481    VG_FALSE,  3, 1, 0, 0, 0, 3},
482};
483
484#endif
485