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