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