17ec681f3Smrg/********************************************************** 27ec681f3Smrg * Copyright 2009-2011 VMware, Inc. All rights reserved. 37ec681f3Smrg * 47ec681f3Smrg * Permission is hereby granted, free of charge, to any person 57ec681f3Smrg * obtaining a copy of this software and associated documentation 67ec681f3Smrg * files (the "Software"), to deal in the Software without 77ec681f3Smrg * restriction, including without limitation the rights to use, copy, 87ec681f3Smrg * modify, merge, publish, distribute, sublicense, and/or sell copies 97ec681f3Smrg * of the Software, and to permit persons to whom the Software is 107ec681f3Smrg * furnished to do so, subject to the following conditions: 117ec681f3Smrg * 127ec681f3Smrg * The above copyright notice and this permission notice shall be 137ec681f3Smrg * included in all copies or substantial portions of the Software. 147ec681f3Smrg * 157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 167ec681f3Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 177ec681f3Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 187ec681f3Smrg * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 197ec681f3Smrg * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 207ec681f3Smrg * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 217ec681f3Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 227ec681f3Smrg * SOFTWARE. 237ec681f3Smrg * 247ec681f3Smrg ********************************************************* 257ec681f3Smrg * Authors: 267ec681f3Smrg * Zack Rusin <zackr-at-vmware-dot-com> 277ec681f3Smrg */ 287ec681f3Smrg#include "xa_priv.h" 297ec681f3Smrg 307ec681f3Smrg#include "pipe/p_format.h" 317ec681f3Smrg#include "pipe/p_context.h" 327ec681f3Smrg#include "pipe/p_state.h" 337ec681f3Smrg#include "pipe/p_shader_tokens.h" 347ec681f3Smrg 357ec681f3Smrg#include "util/u_memory.h" 367ec681f3Smrg 377ec681f3Smrg#include "tgsi/tgsi_ureg.h" 387ec681f3Smrg 397ec681f3Smrg#include "cso_cache/cso_context.h" 407ec681f3Smrg#include "cso_cache/cso_hash.h" 417ec681f3Smrg 427ec681f3Smrg/* Vertex shader: 437ec681f3Smrg * IN[0] = vertex pos 447ec681f3Smrg * IN[1] = src tex coord | solid fill color 457ec681f3Smrg * IN[2] = mask tex coord 467ec681f3Smrg * IN[3] = dst tex coord 477ec681f3Smrg * CONST[0] = (2/dst_width, 2/dst_height, 1, 1) 487ec681f3Smrg * CONST[1] = (-1, -1, 0, 0) 497ec681f3Smrg * 507ec681f3Smrg * OUT[0] = vertex pos 517ec681f3Smrg * OUT[1] = src tex coord 527ec681f3Smrg * OUT[2] = mask tex coord 537ec681f3Smrg * OUT[3] = dst tex coord 547ec681f3Smrg */ 557ec681f3Smrg 567ec681f3Smrg/* Fragment shader. Samplers are allocated when needed. 577ec681f3Smrg * SAMP[0] = sampler for first texture (src or mask if src is solid) 587ec681f3Smrg * SAMP[1] = sampler for second texture (mask or none) 597ec681f3Smrg * IN[0] = first texture coordinates if present 607ec681f3Smrg * IN[1] = second texture coordinates if present 617ec681f3Smrg * CONST[0] = Solid color (src if src solid or mask if mask solid 627ec681f3Smrg * or src in mask if both solid). 637ec681f3Smrg * 647ec681f3Smrg * OUT[0] = color 657ec681f3Smrg */ 667ec681f3Smrg 677ec681f3Smrgstatic void 687ec681f3Smrgprint_fs_traits(int fs_traits) 697ec681f3Smrg{ 707ec681f3Smrg const char *strings[] = { 717ec681f3Smrg "FS_COMPOSITE", /* = 1 << 0, */ 727ec681f3Smrg "FS_MASK", /* = 1 << 1, */ 737ec681f3Smrg "FS_SRC_SRC", /* = 1 << 2, */ 747ec681f3Smrg "FS_MASK_SRC", /* = 1 << 3, */ 757ec681f3Smrg "FS_YUV", /* = 1 << 4, */ 767ec681f3Smrg "FS_SRC_REPEAT_NONE", /* = 1 << 5, */ 777ec681f3Smrg "FS_MASK_REPEAT_NONE", /* = 1 << 6, */ 787ec681f3Smrg "FS_SRC_SWIZZLE_RGB", /* = 1 << 7, */ 797ec681f3Smrg "FS_MASK_SWIZZLE_RGB", /* = 1 << 8, */ 807ec681f3Smrg "FS_SRC_SET_ALPHA", /* = 1 << 9, */ 817ec681f3Smrg "FS_MASK_SET_ALPHA", /* = 1 << 10, */ 827ec681f3Smrg "FS_SRC_LUMINANCE", /* = 1 << 11, */ 837ec681f3Smrg "FS_MASK_LUMINANCE", /* = 1 << 12, */ 847ec681f3Smrg "FS_DST_LUMINANCE", /* = 1 << 13, */ 857ec681f3Smrg "FS_CA", /* = 1 << 14, */ 867ec681f3Smrg }; 877ec681f3Smrg int i, k; 887ec681f3Smrg 897ec681f3Smrg debug_printf("%s: ", __func__); 907ec681f3Smrg 917ec681f3Smrg for (i = 0, k = 1; k < (1 << 16); i++, k <<= 1) { 927ec681f3Smrg if (fs_traits & k) 937ec681f3Smrg debug_printf("%s, ", strings[i]); 947ec681f3Smrg } 957ec681f3Smrg 967ec681f3Smrg debug_printf("\n"); 977ec681f3Smrg} 987ec681f3Smrg 997ec681f3Smrgstruct xa_shaders { 1007ec681f3Smrg struct xa_context *r; 1017ec681f3Smrg 1027ec681f3Smrg struct cso_hash vs_hash; 1037ec681f3Smrg struct cso_hash fs_hash; 1047ec681f3Smrg}; 1057ec681f3Smrg 1067ec681f3Smrgstatic inline void 1077ec681f3Smrgsrc_in_mask(struct ureg_program *ureg, 1087ec681f3Smrg struct ureg_dst dst, 1097ec681f3Smrg struct ureg_src src, 1107ec681f3Smrg struct ureg_src mask, 1117ec681f3Smrg unsigned mask_luminance, boolean component_alpha) 1127ec681f3Smrg{ 1137ec681f3Smrg if (mask_luminance) 1147ec681f3Smrg if (component_alpha) { 1157ec681f3Smrg ureg_MOV(ureg, dst, src); 1167ec681f3Smrg ureg_MUL(ureg, ureg_writemask(dst, TGSI_WRITEMASK_W), 1177ec681f3Smrg src, ureg_scalar(mask, TGSI_SWIZZLE_X)); 1187ec681f3Smrg } else { 1197ec681f3Smrg ureg_MUL(ureg, dst, src, ureg_scalar(mask, TGSI_SWIZZLE_X)); 1207ec681f3Smrg } 1217ec681f3Smrg else if (!component_alpha) 1227ec681f3Smrg ureg_MUL(ureg, dst, src, ureg_scalar(mask, TGSI_SWIZZLE_W)); 1237ec681f3Smrg else 1247ec681f3Smrg ureg_MUL(ureg, dst, src, mask); 1257ec681f3Smrg} 1267ec681f3Smrg 1277ec681f3Smrgstatic struct ureg_src 1287ec681f3Smrgvs_normalize_coords(struct ureg_program *ureg, 1297ec681f3Smrg struct ureg_src coords, 1307ec681f3Smrg struct ureg_src const0, struct ureg_src const1) 1317ec681f3Smrg{ 1327ec681f3Smrg struct ureg_dst tmp = ureg_DECL_temporary(ureg); 1337ec681f3Smrg struct ureg_src ret; 1347ec681f3Smrg 1357ec681f3Smrg ureg_MAD(ureg, tmp, coords, const0, const1); 1367ec681f3Smrg ret = ureg_src(tmp); 1377ec681f3Smrg ureg_release_temporary(ureg, tmp); 1387ec681f3Smrg return ret; 1397ec681f3Smrg} 1407ec681f3Smrg 1417ec681f3Smrgstatic void * 1427ec681f3Smrgcreate_vs(struct pipe_context *pipe, unsigned vs_traits) 1437ec681f3Smrg{ 1447ec681f3Smrg struct ureg_program *ureg; 1457ec681f3Smrg struct ureg_src src; 1467ec681f3Smrg struct ureg_dst dst; 1477ec681f3Smrg struct ureg_src const0, const1; 1487ec681f3Smrg boolean is_composite = (vs_traits & VS_COMPOSITE) != 0; 1497ec681f3Smrg boolean has_mask = (vs_traits & VS_MASK) != 0; 1507ec681f3Smrg boolean is_yuv = (vs_traits & VS_YUV) != 0; 1517ec681f3Smrg boolean is_src_src = (vs_traits & VS_SRC_SRC) != 0; 1527ec681f3Smrg boolean is_mask_src = (vs_traits & VS_MASK_SRC) != 0; 1537ec681f3Smrg unsigned input_slot = 0; 1547ec681f3Smrg 1557ec681f3Smrg ureg = ureg_create(PIPE_SHADER_VERTEX); 1567ec681f3Smrg if (ureg == NULL) 1577ec681f3Smrg return 0; 1587ec681f3Smrg 1597ec681f3Smrg const0 = ureg_DECL_constant(ureg, 0); 1607ec681f3Smrg const1 = ureg_DECL_constant(ureg, 1); 1617ec681f3Smrg 1627ec681f3Smrg /* it has to be either a fill or a composite op */ 1637ec681f3Smrg src = ureg_DECL_vs_input(ureg, input_slot++); 1647ec681f3Smrg dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); 1657ec681f3Smrg src = vs_normalize_coords(ureg, src, const0, const1); 1667ec681f3Smrg ureg_MOV(ureg, dst, src); 1677ec681f3Smrg 1687ec681f3Smrg if (is_yuv) { 1697ec681f3Smrg src = ureg_DECL_vs_input(ureg, input_slot++); 1707ec681f3Smrg dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0); 1717ec681f3Smrg ureg_MOV(ureg, dst, src); 1727ec681f3Smrg } 1737ec681f3Smrg 1747ec681f3Smrg if (is_composite) { 1757ec681f3Smrg if (!is_src_src || (has_mask && !is_mask_src)) { 1767ec681f3Smrg src = ureg_DECL_vs_input(ureg, input_slot++); 1777ec681f3Smrg dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0); 1787ec681f3Smrg ureg_MOV(ureg, dst, src); 1797ec681f3Smrg } 1807ec681f3Smrg 1817ec681f3Smrg if (!is_src_src && (has_mask && !is_mask_src)) { 1827ec681f3Smrg src = ureg_DECL_vs_input(ureg, input_slot++); 1837ec681f3Smrg dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1); 1847ec681f3Smrg ureg_MOV(ureg, dst, src); 1857ec681f3Smrg } 1867ec681f3Smrg } 1877ec681f3Smrg 1887ec681f3Smrg ureg_END(ureg); 1897ec681f3Smrg 1907ec681f3Smrg return ureg_create_shader_and_destroy(ureg, pipe); 1917ec681f3Smrg} 1927ec681f3Smrg 1937ec681f3Smrgstatic void * 1947ec681f3Smrgcreate_yuv_shader(struct pipe_context *pipe, struct ureg_program *ureg) 1957ec681f3Smrg{ 1967ec681f3Smrg struct ureg_src y_sampler, u_sampler, v_sampler; 1977ec681f3Smrg struct ureg_src pos; 1987ec681f3Smrg struct ureg_src matrow0, matrow1, matrow2, matrow3; 1997ec681f3Smrg struct ureg_dst y, u, v, rgb; 2007ec681f3Smrg struct ureg_dst out = ureg_DECL_output(ureg, 2017ec681f3Smrg TGSI_SEMANTIC_COLOR, 2027ec681f3Smrg 0); 2037ec681f3Smrg 2047ec681f3Smrg pos = ureg_DECL_fs_input(ureg, 2057ec681f3Smrg TGSI_SEMANTIC_GENERIC, 0, 2067ec681f3Smrg TGSI_INTERPOLATE_PERSPECTIVE); 2077ec681f3Smrg 2087ec681f3Smrg rgb = ureg_DECL_temporary(ureg); 2097ec681f3Smrg y = ureg_DECL_temporary(ureg); 2107ec681f3Smrg u = ureg_DECL_temporary(ureg); 2117ec681f3Smrg v = ureg_DECL_temporary(ureg); 2127ec681f3Smrg 2137ec681f3Smrg y_sampler = ureg_DECL_sampler(ureg, 0); 2147ec681f3Smrg u_sampler = ureg_DECL_sampler(ureg, 1); 2157ec681f3Smrg v_sampler = ureg_DECL_sampler(ureg, 2); 2167ec681f3Smrg 2177ec681f3Smrg ureg_DECL_sampler_view(ureg, 0, TGSI_TEXTURE_2D, 2187ec681f3Smrg TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT, 2197ec681f3Smrg TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT); 2207ec681f3Smrg ureg_DECL_sampler_view(ureg, 1, TGSI_TEXTURE_2D, 2217ec681f3Smrg TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT, 2227ec681f3Smrg TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT); 2237ec681f3Smrg ureg_DECL_sampler_view(ureg, 2, TGSI_TEXTURE_2D, 2247ec681f3Smrg TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT, 2257ec681f3Smrg TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT); 2267ec681f3Smrg 2277ec681f3Smrg matrow0 = ureg_DECL_constant(ureg, 0); 2287ec681f3Smrg matrow1 = ureg_DECL_constant(ureg, 1); 2297ec681f3Smrg matrow2 = ureg_DECL_constant(ureg, 2); 2307ec681f3Smrg matrow3 = ureg_DECL_constant(ureg, 3); 2317ec681f3Smrg 2327ec681f3Smrg ureg_TEX(ureg, y, TGSI_TEXTURE_2D, pos, y_sampler); 2337ec681f3Smrg ureg_TEX(ureg, u, TGSI_TEXTURE_2D, pos, u_sampler); 2347ec681f3Smrg ureg_TEX(ureg, v, TGSI_TEXTURE_2D, pos, v_sampler); 2357ec681f3Smrg 2367ec681f3Smrg ureg_MOV(ureg, rgb, matrow3); 2377ec681f3Smrg ureg_MAD(ureg, rgb, 2387ec681f3Smrg ureg_scalar(ureg_src(y), TGSI_SWIZZLE_X), matrow0, ureg_src(rgb)); 2397ec681f3Smrg ureg_MAD(ureg, rgb, 2407ec681f3Smrg ureg_scalar(ureg_src(u), TGSI_SWIZZLE_X), matrow1, ureg_src(rgb)); 2417ec681f3Smrg ureg_MAD(ureg, rgb, 2427ec681f3Smrg ureg_scalar(ureg_src(v), TGSI_SWIZZLE_X), matrow2, ureg_src(rgb)); 2437ec681f3Smrg 2447ec681f3Smrg ureg_MOV(ureg, out, ureg_src(rgb)); 2457ec681f3Smrg 2467ec681f3Smrg ureg_release_temporary(ureg, rgb); 2477ec681f3Smrg ureg_release_temporary(ureg, y); 2487ec681f3Smrg ureg_release_temporary(ureg, u); 2497ec681f3Smrg ureg_release_temporary(ureg, v); 2507ec681f3Smrg 2517ec681f3Smrg ureg_END(ureg); 2527ec681f3Smrg 2537ec681f3Smrg return ureg_create_shader_and_destroy(ureg, pipe); 2547ec681f3Smrg} 2557ec681f3Smrg 2567ec681f3Smrgstatic inline void 2577ec681f3Smrgxrender_tex(struct ureg_program *ureg, 2587ec681f3Smrg struct ureg_dst dst, 2597ec681f3Smrg struct ureg_src coords, 2607ec681f3Smrg struct ureg_src sampler, 2617ec681f3Smrg const struct ureg_src *imm0, 2627ec681f3Smrg boolean repeat_none, boolean swizzle, boolean set_alpha) 2637ec681f3Smrg{ 2647ec681f3Smrg if (repeat_none) { 2657ec681f3Smrg struct ureg_dst tmp0 = ureg_DECL_temporary(ureg); 2667ec681f3Smrg struct ureg_dst tmp1 = ureg_DECL_temporary(ureg); 2677ec681f3Smrg 2687ec681f3Smrg ureg_SGT(ureg, tmp1, ureg_swizzle(coords, 2697ec681f3Smrg TGSI_SWIZZLE_X, 2707ec681f3Smrg TGSI_SWIZZLE_Y, 2717ec681f3Smrg TGSI_SWIZZLE_X, 2727ec681f3Smrg TGSI_SWIZZLE_Y), ureg_scalar(*imm0, 2737ec681f3Smrg TGSI_SWIZZLE_X)); 2747ec681f3Smrg ureg_SLT(ureg, tmp0, 2757ec681f3Smrg ureg_swizzle(coords, TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, 2767ec681f3Smrg TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y), ureg_scalar(*imm0, 2777ec681f3Smrg TGSI_SWIZZLE_W)); 2787ec681f3Smrg ureg_MIN(ureg, tmp0, ureg_src(tmp0), ureg_src(tmp1)); 2797ec681f3Smrg ureg_MIN(ureg, tmp0, ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_X), 2807ec681f3Smrg ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_Y)); 2817ec681f3Smrg ureg_TEX(ureg, tmp1, TGSI_TEXTURE_2D, coords, sampler); 2827ec681f3Smrg if (swizzle) 2837ec681f3Smrg ureg_MOV(ureg, tmp1, ureg_swizzle(ureg_src(tmp1), 2847ec681f3Smrg TGSI_SWIZZLE_Z, 2857ec681f3Smrg TGSI_SWIZZLE_Y, TGSI_SWIZZLE_X, 2867ec681f3Smrg TGSI_SWIZZLE_W)); 2877ec681f3Smrg if (set_alpha) 2887ec681f3Smrg ureg_MOV(ureg, 2897ec681f3Smrg ureg_writemask(tmp1, TGSI_WRITEMASK_W), 2907ec681f3Smrg ureg_scalar(*imm0, TGSI_SWIZZLE_W)); 2917ec681f3Smrg ureg_MUL(ureg, dst, ureg_src(tmp1), ureg_src(tmp0)); 2927ec681f3Smrg ureg_release_temporary(ureg, tmp0); 2937ec681f3Smrg ureg_release_temporary(ureg, tmp1); 2947ec681f3Smrg } else { 2957ec681f3Smrg if (swizzle) { 2967ec681f3Smrg struct ureg_dst tmp = ureg_DECL_temporary(ureg); 2977ec681f3Smrg 2987ec681f3Smrg ureg_TEX(ureg, tmp, TGSI_TEXTURE_2D, coords, sampler); 2997ec681f3Smrg ureg_MOV(ureg, dst, ureg_swizzle(ureg_src(tmp), 3007ec681f3Smrg TGSI_SWIZZLE_Z, 3017ec681f3Smrg TGSI_SWIZZLE_Y, TGSI_SWIZZLE_X, 3027ec681f3Smrg TGSI_SWIZZLE_W)); 3037ec681f3Smrg ureg_release_temporary(ureg, tmp); 3047ec681f3Smrg } else { 3057ec681f3Smrg ureg_TEX(ureg, dst, TGSI_TEXTURE_2D, coords, sampler); 3067ec681f3Smrg } 3077ec681f3Smrg if (set_alpha) 3087ec681f3Smrg ureg_MOV(ureg, 3097ec681f3Smrg ureg_writemask(dst, TGSI_WRITEMASK_W), 3107ec681f3Smrg ureg_scalar(*imm0, TGSI_SWIZZLE_W)); 3117ec681f3Smrg } 3127ec681f3Smrg} 3137ec681f3Smrg 3147ec681f3Smrgstatic void 3157ec681f3Smrgread_input(struct ureg_program *ureg, 3167ec681f3Smrg struct ureg_dst dst, 3177ec681f3Smrg const struct ureg_src *imm0, 3187ec681f3Smrg boolean repeat_none, boolean swizzle, boolean set_alpha, 3197ec681f3Smrg boolean is_src, unsigned *cur_constant, unsigned *cur_sampler) 3207ec681f3Smrg{ 3217ec681f3Smrg struct ureg_src input, sampler; 3227ec681f3Smrg 3237ec681f3Smrg if (is_src) { 3247ec681f3Smrg input = ureg_DECL_constant(ureg, (*cur_constant)++); 3257ec681f3Smrg ureg_MOV(ureg, dst, input); 3267ec681f3Smrg } else { 3277ec681f3Smrg sampler = ureg_DECL_sampler(ureg, *cur_sampler); 3287ec681f3Smrg ureg_DECL_sampler_view(ureg, *cur_sampler, TGSI_TEXTURE_2D, 3297ec681f3Smrg TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT, 3307ec681f3Smrg TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT); 3317ec681f3Smrg input = ureg_DECL_fs_input(ureg, 3327ec681f3Smrg TGSI_SEMANTIC_GENERIC, (*cur_sampler)++, 3337ec681f3Smrg TGSI_INTERPOLATE_PERSPECTIVE); 3347ec681f3Smrg xrender_tex(ureg, dst, input, sampler, imm0, 3357ec681f3Smrg repeat_none, swizzle, set_alpha); 3367ec681f3Smrg } 3377ec681f3Smrg} 3387ec681f3Smrg 3397ec681f3Smrgstatic void * 3407ec681f3Smrgcreate_fs(struct pipe_context *pipe, unsigned fs_traits) 3417ec681f3Smrg{ 3427ec681f3Smrg struct ureg_program *ureg; 3437ec681f3Smrg struct ureg_dst src, mask; 3447ec681f3Smrg struct ureg_dst out; 3457ec681f3Smrg struct ureg_src imm0 = { 0 }; 3467ec681f3Smrg unsigned has_mask = (fs_traits & FS_MASK) != 0; 3477ec681f3Smrg unsigned is_yuv = (fs_traits & FS_YUV) != 0; 3487ec681f3Smrg unsigned src_repeat_none = (fs_traits & FS_SRC_REPEAT_NONE) != 0; 3497ec681f3Smrg unsigned mask_repeat_none = (fs_traits & FS_MASK_REPEAT_NONE) != 0; 3507ec681f3Smrg unsigned src_swizzle = (fs_traits & FS_SRC_SWIZZLE_RGB) != 0; 3517ec681f3Smrg unsigned mask_swizzle = (fs_traits & FS_MASK_SWIZZLE_RGB) != 0; 3527ec681f3Smrg unsigned src_set_alpha = (fs_traits & FS_SRC_SET_ALPHA) != 0; 3537ec681f3Smrg unsigned mask_set_alpha = (fs_traits & FS_MASK_SET_ALPHA) != 0; 3547ec681f3Smrg unsigned src_luminance = (fs_traits & FS_SRC_LUMINANCE) != 0; 3557ec681f3Smrg unsigned mask_luminance = (fs_traits & FS_MASK_LUMINANCE) != 0; 3567ec681f3Smrg unsigned dst_luminance = (fs_traits & FS_DST_LUMINANCE) != 0; 3577ec681f3Smrg unsigned is_src_src = (fs_traits & FS_SRC_SRC) != 0; 3587ec681f3Smrg unsigned is_mask_src = (fs_traits & FS_MASK_SRC) != 0; 3597ec681f3Smrg boolean component_alpha = (fs_traits & FS_CA) != 0; 3607ec681f3Smrg unsigned cur_sampler = 0; 3617ec681f3Smrg unsigned cur_constant = 0; 3627ec681f3Smrg 3637ec681f3Smrg#if 0 3647ec681f3Smrg print_fs_traits(fs_traits); 3657ec681f3Smrg#else 3667ec681f3Smrg (void)print_fs_traits; 3677ec681f3Smrg#endif 3687ec681f3Smrg 3697ec681f3Smrg ureg = ureg_create(PIPE_SHADER_FRAGMENT); 3707ec681f3Smrg if (ureg == NULL) 3717ec681f3Smrg return 0; 3727ec681f3Smrg 3737ec681f3Smrg if (is_yuv) 3747ec681f3Smrg return create_yuv_shader(pipe, ureg); 3757ec681f3Smrg 3767ec681f3Smrg out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); 3777ec681f3Smrg 3787ec681f3Smrg if (src_repeat_none || mask_repeat_none || 3797ec681f3Smrg src_set_alpha || mask_set_alpha || src_luminance) { 3807ec681f3Smrg imm0 = ureg_imm4f(ureg, 0, 0, 0, 1); 3817ec681f3Smrg } 3827ec681f3Smrg 3837ec681f3Smrg src = (has_mask || src_luminance || dst_luminance) ? 3847ec681f3Smrg ureg_DECL_temporary(ureg) : out; 3857ec681f3Smrg 3867ec681f3Smrg read_input(ureg, src, &imm0, src_repeat_none, src_swizzle, 3877ec681f3Smrg src_set_alpha, is_src_src, &cur_constant, &cur_sampler); 3887ec681f3Smrg 3897ec681f3Smrg if (src_luminance) { 3907ec681f3Smrg ureg_MOV(ureg, src, ureg_scalar(ureg_src(src), TGSI_SWIZZLE_X)); 3917ec681f3Smrg ureg_MOV(ureg, ureg_writemask(src, TGSI_WRITEMASK_XYZ), 3927ec681f3Smrg ureg_scalar(imm0, TGSI_SWIZZLE_X)); 3937ec681f3Smrg if (!has_mask && !dst_luminance) 3947ec681f3Smrg ureg_MOV(ureg, out, ureg_src(src)); 3957ec681f3Smrg } 3967ec681f3Smrg 3977ec681f3Smrg if (has_mask) { 3987ec681f3Smrg mask = ureg_DECL_temporary(ureg); 3997ec681f3Smrg read_input(ureg, mask, &imm0, mask_repeat_none, 4007ec681f3Smrg mask_swizzle, mask_set_alpha, is_mask_src, &cur_constant, 4017ec681f3Smrg &cur_sampler); 4027ec681f3Smrg 4037ec681f3Smrg src_in_mask(ureg, (dst_luminance) ? src : out, ureg_src(src), 4047ec681f3Smrg ureg_src(mask), mask_luminance, component_alpha); 4057ec681f3Smrg 4067ec681f3Smrg ureg_release_temporary(ureg, mask); 4077ec681f3Smrg } 4087ec681f3Smrg 4097ec681f3Smrg if (dst_luminance) { 4107ec681f3Smrg /* 4117ec681f3Smrg * Make sure the alpha channel goes into the output L8 surface. 4127ec681f3Smrg */ 4137ec681f3Smrg ureg_MOV(ureg, out, ureg_scalar(ureg_src(src), TGSI_SWIZZLE_W)); 4147ec681f3Smrg } 4157ec681f3Smrg 4167ec681f3Smrg ureg_END(ureg); 4177ec681f3Smrg 4187ec681f3Smrg return ureg_create_shader_and_destroy(ureg, pipe); 4197ec681f3Smrg} 4207ec681f3Smrg 4217ec681f3Smrgstruct xa_shaders * 4227ec681f3Smrgxa_shaders_create(struct xa_context *r) 4237ec681f3Smrg{ 4247ec681f3Smrg struct xa_shaders *sc = CALLOC_STRUCT(xa_shaders); 4257ec681f3Smrg 4267ec681f3Smrg sc->r = r; 4277ec681f3Smrg cso_hash_init(&sc->vs_hash); 4287ec681f3Smrg cso_hash_init(&sc->fs_hash); 4297ec681f3Smrg 4307ec681f3Smrg return sc; 4317ec681f3Smrg} 4327ec681f3Smrg 4337ec681f3Smrgstatic void 4347ec681f3Smrgcache_destroy(struct pipe_context *pipe, 4357ec681f3Smrg struct cso_hash *hash, unsigned processor) 4367ec681f3Smrg{ 4377ec681f3Smrg struct cso_hash_iter iter = cso_hash_first_node(hash); 4387ec681f3Smrg 4397ec681f3Smrg while (!cso_hash_iter_is_null(iter)) { 4407ec681f3Smrg void *shader = (void *)cso_hash_iter_data(iter); 4417ec681f3Smrg 4427ec681f3Smrg if (processor == PIPE_SHADER_FRAGMENT) { 4437ec681f3Smrg pipe->delete_fs_state(pipe, shader); 4447ec681f3Smrg } else if (processor == PIPE_SHADER_VERTEX) { 4457ec681f3Smrg pipe->delete_vs_state(pipe, shader); 4467ec681f3Smrg } 4477ec681f3Smrg iter = cso_hash_erase(hash, iter); 4487ec681f3Smrg } 4497ec681f3Smrg cso_hash_deinit(hash); 4507ec681f3Smrg} 4517ec681f3Smrg 4527ec681f3Smrgvoid 4537ec681f3Smrgxa_shaders_destroy(struct xa_shaders *sc) 4547ec681f3Smrg{ 4557ec681f3Smrg cache_destroy(sc->r->pipe, &sc->vs_hash, PIPE_SHADER_VERTEX); 4567ec681f3Smrg cache_destroy(sc->r->pipe, &sc->fs_hash, PIPE_SHADER_FRAGMENT); 4577ec681f3Smrg 4587ec681f3Smrg FREE(sc); 4597ec681f3Smrg} 4607ec681f3Smrg 4617ec681f3Smrgstatic inline void * 4627ec681f3Smrgshader_from_cache(struct pipe_context *pipe, 4637ec681f3Smrg unsigned type, struct cso_hash *hash, unsigned key) 4647ec681f3Smrg{ 4657ec681f3Smrg void *shader = 0; 4667ec681f3Smrg 4677ec681f3Smrg struct cso_hash_iter iter = cso_hash_find(hash, key); 4687ec681f3Smrg 4697ec681f3Smrg if (cso_hash_iter_is_null(iter)) { 4707ec681f3Smrg if (type == PIPE_SHADER_VERTEX) 4717ec681f3Smrg shader = create_vs(pipe, key); 4727ec681f3Smrg else 4737ec681f3Smrg shader = create_fs(pipe, key); 4747ec681f3Smrg cso_hash_insert(hash, key, shader); 4757ec681f3Smrg } else 4767ec681f3Smrg shader = (void *)cso_hash_iter_data(iter); 4777ec681f3Smrg 4787ec681f3Smrg return shader; 4797ec681f3Smrg} 4807ec681f3Smrg 4817ec681f3Smrgstruct xa_shader 4827ec681f3Smrgxa_shaders_get(struct xa_shaders *sc, unsigned vs_traits, unsigned fs_traits) 4837ec681f3Smrg{ 4847ec681f3Smrg struct xa_shader shader = { NULL, NULL }; 4857ec681f3Smrg void *vs, *fs; 4867ec681f3Smrg 4877ec681f3Smrg vs = shader_from_cache(sc->r->pipe, PIPE_SHADER_VERTEX, 4887ec681f3Smrg &sc->vs_hash, vs_traits); 4897ec681f3Smrg fs = shader_from_cache(sc->r->pipe, PIPE_SHADER_FRAGMENT, 4907ec681f3Smrg &sc->fs_hash, fs_traits); 4917ec681f3Smrg 4927ec681f3Smrg debug_assert(vs && fs); 4937ec681f3Smrg if (!vs || !fs) 4947ec681f3Smrg return shader; 4957ec681f3Smrg 4967ec681f3Smrg shader.vs = vs; 4977ec681f3Smrg shader.fs = fs; 4987ec681f3Smrg 4997ec681f3Smrg return shader; 5007ec681f3Smrg} 501