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