diff options
Diffstat (limited to 'src/gallium/state_trackers/xorg/xorg_exa_tgsi.c')
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa_tgsi.c | 106 |
1 files changed, 95 insertions, 11 deletions
diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c index f8557755ef..3bf64b6331 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c +++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c @@ -43,6 +43,38 @@ * OUT[0] = color */ +static void +print_fs_traits(int fs_traits) +{ + const char *strings[] = { + "FS_COMPOSITE", // = 1 << 0, + "FS_MASK", // = 1 << 1, + "FS_SOLID_FILL", // = 1 << 2, + "FS_LINGRAD_FILL", // = 1 << 3, + "FS_RADGRAD_FILL", // = 1 << 4, + "FS_CA_FULL", // = 1 << 5, /* src.rgba * mask.rgba */ + "FS_CA_SRCALPHA", // = 1 << 6, /* src.aaaa * mask.rgba */ + "FS_YUV", // = 1 << 7, + "FS_SRC_REPEAT_NONE", // = 1 << 8, + "FS_MASK_REPEAT_NONE",// = 1 << 9, + "FS_SRC_SWIZZLE_RGB", // = 1 << 10, + "FS_MASK_SWIZZLE_RGB",// = 1 << 11, + "FS_SRC_SET_ALPHA", // = 1 << 12, + "FS_MASK_SET_ALPHA", // = 1 << 13, + "FS_SRC_LUMINANCE", // = 1 << 14, + "FS_MASK_LUMINANCE", // = 1 << 15, + }; + int i, k; + debug_printf("%s: ", __func__); + + for (i = 0, k = 1; k < (1 << 16); i++, k <<= 1) { + if (fs_traits & k) + debug_printf("%s, ", strings[i]); + } + + debug_printf("\n"); +} + struct xorg_shaders { struct xorg_renderer *r; @@ -55,7 +87,8 @@ src_in_mask(struct ureg_program *ureg, struct ureg_dst dst, struct ureg_src src, struct ureg_src mask, - int component_alpha) + unsigned component_alpha, + unsigned mask_luminance) { if (component_alpha == FS_CA_FULL) { ureg_MUL(ureg, dst, src, mask); @@ -64,8 +97,12 @@ src_in_mask(struct ureg_program *ureg, ureg_scalar(src, TGSI_SWIZZLE_W), mask); } else { - ureg_MUL(ureg, dst, src, - ureg_scalar(mask, TGSI_SWIZZLE_X)); + if (mask_luminance) + ureg_MUL(ureg, dst, src, + ureg_scalar(mask, TGSI_SWIZZLE_X)); + else + ureg_MUL(ureg, dst, src, + ureg_scalar(mask, TGSI_SWIZZLE_W)); } } @@ -359,12 +396,18 @@ xrender_tex(struct ureg_program *ureg, struct ureg_dst dst, struct ureg_src coords, struct ureg_src sampler, - boolean repeat_none) + boolean repeat_none, + boolean swizzle, + boolean set_alpha) { + struct ureg_src imm0 = { 0 }; + + if (repeat_none || set_alpha) + imm0 = ureg_imm4f(ureg, 0, 0, 0, 1); + if (repeat_none) { struct ureg_dst tmp0 = ureg_DECL_temporary(ureg); struct ureg_dst tmp1 = ureg_DECL_temporary(ureg); - struct ureg_src imm0 = ureg_imm4f(ureg, 0, 0, 0, 1); ureg_SGT(ureg, tmp1, ureg_swizzle(coords, TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, @@ -381,11 +424,37 @@ xrender_tex(struct ureg_program *ureg, ureg_MIN(ureg, tmp0, ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_X), ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_Y)); ureg_TEX(ureg, tmp1, TGSI_TEXTURE_2D, coords, sampler); + if (swizzle) + ureg_MOV(ureg, tmp1, ureg_swizzle(ureg_src(tmp1), + TGSI_SWIZZLE_Z, + TGSI_SWIZZLE_Y, + TGSI_SWIZZLE_X, + TGSI_SWIZZLE_W)); + if (set_alpha) + ureg_MOV(ureg, + ureg_writemask(tmp1, TGSI_WRITEMASK_W), + ureg_scalar(imm0, TGSI_SWIZZLE_W)); ureg_MUL(ureg, dst, ureg_src(tmp1), ureg_src(tmp0)); ureg_release_temporary(ureg, tmp0); ureg_release_temporary(ureg, tmp1); - } else - ureg_TEX(ureg, dst, TGSI_TEXTURE_2D, coords, sampler); + } else { + if (swizzle) { + struct ureg_dst tmp = ureg_DECL_temporary(ureg); + ureg_TEX(ureg, tmp, TGSI_TEXTURE_2D, coords, sampler); + ureg_MOV(ureg, dst, ureg_swizzle(ureg_src(tmp), + TGSI_SWIZZLE_Z, + TGSI_SWIZZLE_Y, + TGSI_SWIZZLE_X, + TGSI_SWIZZLE_W)); + ureg_release_temporary(ureg, tmp); + } else { + ureg_TEX(ureg, dst, TGSI_TEXTURE_2D, coords, sampler); + } + if (set_alpha) + ureg_MOV(ureg, + ureg_writemask(dst, TGSI_WRITEMASK_W), + ureg_scalar(imm0, TGSI_SWIZZLE_W)); + } } static void * @@ -403,10 +472,24 @@ create_fs(struct pipe_context *pipe, unsigned is_solid = (fs_traits & FS_SOLID_FILL) != 0; unsigned is_lingrad = (fs_traits & FS_LINGRAD_FILL) != 0; unsigned is_radgrad = (fs_traits & FS_RADGRAD_FILL) != 0; - unsigned comp_alpha = (fs_traits & FS_COMPONENT_ALPHA) != 0; + unsigned comp_alpha_mask = fs_traits & FS_COMPONENT_ALPHA; unsigned is_yuv = (fs_traits & FS_YUV) != 0; unsigned src_repeat_none = (fs_traits & FS_SRC_REPEAT_NONE) != 0; unsigned mask_repeat_none = (fs_traits & FS_MASK_REPEAT_NONE) != 0; + unsigned src_swizzle = (fs_traits & FS_SRC_SWIZZLE_RGB) != 0; + unsigned mask_swizzle = (fs_traits & FS_MASK_SWIZZLE_RGB) != 0; + unsigned src_set_alpha = (fs_traits & FS_SRC_SET_ALPHA) != 0; + unsigned mask_set_alpha = (fs_traits & FS_MASK_SET_ALPHA) != 0; + unsigned src_luminance = (fs_traits & FS_SRC_LUMINANCE) != 0; + unsigned mask_luminance = (fs_traits & FS_MASK_LUMINANCE) != 0; + + if (src_luminance) + assert(!"src_luminance not supported"); +#if 0 + print_fs_traits(fs_traits); +#else + (void)print_fs_traits; +#endif ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); if (ureg == NULL) @@ -463,7 +546,7 @@ create_fs(struct pipe_context *pipe, else src = out; xrender_tex(ureg, src, src_input, src_sampler, - src_repeat_none); + src_repeat_none, src_swizzle, src_set_alpha); } else if (is_fill) { if (is_solid) { if (has_mask) @@ -503,9 +586,10 @@ create_fs(struct pipe_context *pipe, if (has_mask) { mask = ureg_DECL_temporary(ureg); xrender_tex(ureg, mask, mask_pos, mask_sampler, - mask_repeat_none); + mask_repeat_none, mask_swizzle, mask_set_alpha); /* src IN mask */ - src_in_mask(ureg, out, ureg_src(src), ureg_src(mask), comp_alpha); + src_in_mask(ureg, out, ureg_src(src), ureg_src(mask), + comp_alpha_mask, mask_luminance); ureg_release_temporary(ureg, mask); } |