1bf215546Sopenharmony_ci/********************************************************** 2bf215546Sopenharmony_ci * Copyright 2009-2011 VMware, Inc. All rights reserved. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person 5bf215546Sopenharmony_ci * obtaining a copy of this software and associated documentation 6bf215546Sopenharmony_ci * files (the "Software"), to deal in the Software without 7bf215546Sopenharmony_ci * restriction, including without limitation the rights to use, copy, 8bf215546Sopenharmony_ci * modify, merge, publish, distribute, sublicense, and/or sell copies 9bf215546Sopenharmony_ci * of the Software, and to permit persons to whom the Software is 10bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be 13bf215546Sopenharmony_ci * included in all copies or substantial portions of the Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16bf215546Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18bf215546Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19bf215546Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20bf215546Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21bf215546Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22bf215546Sopenharmony_ci * SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci ********************************************************* 25bf215546Sopenharmony_ci * Authors: 26bf215546Sopenharmony_ci * Zack Rusin <zackr-at-vmware-dot-com> 27bf215546Sopenharmony_ci */ 28bf215546Sopenharmony_ci#include "xa_priv.h" 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "pipe/p_format.h" 31bf215546Sopenharmony_ci#include "pipe/p_context.h" 32bf215546Sopenharmony_ci#include "pipe/p_state.h" 33bf215546Sopenharmony_ci#include "pipe/p_shader_tokens.h" 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_ci#include "util/u_memory.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#include "tgsi/tgsi_ureg.h" 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_ci#include "cso_cache/cso_context.h" 40bf215546Sopenharmony_ci#include "cso_cache/cso_hash.h" 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci/* Vertex shader: 43bf215546Sopenharmony_ci * IN[0] = vertex pos 44bf215546Sopenharmony_ci * IN[1] = src tex coord | solid fill color 45bf215546Sopenharmony_ci * IN[2] = mask tex coord 46bf215546Sopenharmony_ci * IN[3] = dst tex coord 47bf215546Sopenharmony_ci * CONST[0] = (2/dst_width, 2/dst_height, 1, 1) 48bf215546Sopenharmony_ci * CONST[1] = (-1, -1, 0, 0) 49bf215546Sopenharmony_ci * 50bf215546Sopenharmony_ci * OUT[0] = vertex pos 51bf215546Sopenharmony_ci * OUT[1] = src tex coord 52bf215546Sopenharmony_ci * OUT[2] = mask tex coord 53bf215546Sopenharmony_ci * OUT[3] = dst tex coord 54bf215546Sopenharmony_ci */ 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci/* Fragment shader. Samplers are allocated when needed. 57bf215546Sopenharmony_ci * SAMP[0] = sampler for first texture (src or mask if src is solid) 58bf215546Sopenharmony_ci * SAMP[1] = sampler for second texture (mask or none) 59bf215546Sopenharmony_ci * IN[0] = first texture coordinates if present 60bf215546Sopenharmony_ci * IN[1] = second texture coordinates if present 61bf215546Sopenharmony_ci * CONST[0] = Solid color (src if src solid or mask if mask solid 62bf215546Sopenharmony_ci * or src in mask if both solid). 63bf215546Sopenharmony_ci * 64bf215546Sopenharmony_ci * OUT[0] = color 65bf215546Sopenharmony_ci */ 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_cistatic void 68bf215546Sopenharmony_ciprint_fs_traits(int fs_traits) 69bf215546Sopenharmony_ci{ 70bf215546Sopenharmony_ci const char *strings[] = { 71bf215546Sopenharmony_ci "FS_COMPOSITE", /* = 1 << 0, */ 72bf215546Sopenharmony_ci "FS_MASK", /* = 1 << 1, */ 73bf215546Sopenharmony_ci "FS_SRC_SRC", /* = 1 << 2, */ 74bf215546Sopenharmony_ci "FS_MASK_SRC", /* = 1 << 3, */ 75bf215546Sopenharmony_ci "FS_YUV", /* = 1 << 4, */ 76bf215546Sopenharmony_ci "FS_SRC_REPEAT_NONE", /* = 1 << 5, */ 77bf215546Sopenharmony_ci "FS_MASK_REPEAT_NONE", /* = 1 << 6, */ 78bf215546Sopenharmony_ci "FS_SRC_SWIZZLE_RGB", /* = 1 << 7, */ 79bf215546Sopenharmony_ci "FS_MASK_SWIZZLE_RGB", /* = 1 << 8, */ 80bf215546Sopenharmony_ci "FS_SRC_SET_ALPHA", /* = 1 << 9, */ 81bf215546Sopenharmony_ci "FS_MASK_SET_ALPHA", /* = 1 << 10, */ 82bf215546Sopenharmony_ci "FS_SRC_LUMINANCE", /* = 1 << 11, */ 83bf215546Sopenharmony_ci "FS_MASK_LUMINANCE", /* = 1 << 12, */ 84bf215546Sopenharmony_ci "FS_DST_LUMINANCE", /* = 1 << 13, */ 85bf215546Sopenharmony_ci "FS_CA", /* = 1 << 14, */ 86bf215546Sopenharmony_ci }; 87bf215546Sopenharmony_ci int i, k; 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci debug_printf("%s: ", __func__); 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci for (i = 0, k = 1; k < (1 << 16); i++, k <<= 1) { 92bf215546Sopenharmony_ci if (fs_traits & k) 93bf215546Sopenharmony_ci debug_printf("%s, ", strings[i]); 94bf215546Sopenharmony_ci } 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci debug_printf("\n"); 97bf215546Sopenharmony_ci} 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_cistruct xa_shaders { 100bf215546Sopenharmony_ci struct xa_context *r; 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci struct cso_hash vs_hash; 103bf215546Sopenharmony_ci struct cso_hash fs_hash; 104bf215546Sopenharmony_ci}; 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_cistatic inline void 107bf215546Sopenharmony_cisrc_in_mask(struct ureg_program *ureg, 108bf215546Sopenharmony_ci struct ureg_dst dst, 109bf215546Sopenharmony_ci struct ureg_src src, 110bf215546Sopenharmony_ci struct ureg_src mask, 111bf215546Sopenharmony_ci unsigned mask_luminance, boolean component_alpha) 112bf215546Sopenharmony_ci{ 113bf215546Sopenharmony_ci if (mask_luminance) 114bf215546Sopenharmony_ci if (component_alpha) { 115bf215546Sopenharmony_ci ureg_MOV(ureg, dst, src); 116bf215546Sopenharmony_ci ureg_MUL(ureg, ureg_writemask(dst, TGSI_WRITEMASK_W), 117bf215546Sopenharmony_ci src, ureg_scalar(mask, TGSI_SWIZZLE_X)); 118bf215546Sopenharmony_ci } else { 119bf215546Sopenharmony_ci ureg_MUL(ureg, dst, src, ureg_scalar(mask, TGSI_SWIZZLE_X)); 120bf215546Sopenharmony_ci } 121bf215546Sopenharmony_ci else if (!component_alpha) 122bf215546Sopenharmony_ci ureg_MUL(ureg, dst, src, ureg_scalar(mask, TGSI_SWIZZLE_W)); 123bf215546Sopenharmony_ci else 124bf215546Sopenharmony_ci ureg_MUL(ureg, dst, src, mask); 125bf215546Sopenharmony_ci} 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_cistatic struct ureg_src 128bf215546Sopenharmony_civs_normalize_coords(struct ureg_program *ureg, 129bf215546Sopenharmony_ci struct ureg_src coords, 130bf215546Sopenharmony_ci struct ureg_src const0, struct ureg_src const1) 131bf215546Sopenharmony_ci{ 132bf215546Sopenharmony_ci struct ureg_dst tmp = ureg_DECL_temporary(ureg); 133bf215546Sopenharmony_ci struct ureg_src ret; 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci ureg_MAD(ureg, tmp, coords, const0, const1); 136bf215546Sopenharmony_ci ret = ureg_src(tmp); 137bf215546Sopenharmony_ci ureg_release_temporary(ureg, tmp); 138bf215546Sopenharmony_ci return ret; 139bf215546Sopenharmony_ci} 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_cistatic void * 142bf215546Sopenharmony_cicreate_vs(struct pipe_context *pipe, unsigned vs_traits) 143bf215546Sopenharmony_ci{ 144bf215546Sopenharmony_ci struct ureg_program *ureg; 145bf215546Sopenharmony_ci struct ureg_src src; 146bf215546Sopenharmony_ci struct ureg_dst dst; 147bf215546Sopenharmony_ci struct ureg_src const0, const1; 148bf215546Sopenharmony_ci boolean is_composite = (vs_traits & VS_COMPOSITE) != 0; 149bf215546Sopenharmony_ci boolean has_mask = (vs_traits & VS_MASK) != 0; 150bf215546Sopenharmony_ci boolean is_yuv = (vs_traits & VS_YUV) != 0; 151bf215546Sopenharmony_ci boolean is_src_src = (vs_traits & VS_SRC_SRC) != 0; 152bf215546Sopenharmony_ci boolean is_mask_src = (vs_traits & VS_MASK_SRC) != 0; 153bf215546Sopenharmony_ci unsigned input_slot = 0; 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci ureg = ureg_create(PIPE_SHADER_VERTEX); 156bf215546Sopenharmony_ci if (ureg == NULL) 157bf215546Sopenharmony_ci return NULL; 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci const0 = ureg_DECL_constant(ureg, 0); 160bf215546Sopenharmony_ci const1 = ureg_DECL_constant(ureg, 1); 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci /* it has to be either a fill or a composite op */ 163bf215546Sopenharmony_ci src = ureg_DECL_vs_input(ureg, input_slot++); 164bf215546Sopenharmony_ci dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); 165bf215546Sopenharmony_ci src = vs_normalize_coords(ureg, src, const0, const1); 166bf215546Sopenharmony_ci ureg_MOV(ureg, dst, src); 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci if (is_yuv) { 169bf215546Sopenharmony_ci src = ureg_DECL_vs_input(ureg, input_slot++); 170bf215546Sopenharmony_ci dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0); 171bf215546Sopenharmony_ci ureg_MOV(ureg, dst, src); 172bf215546Sopenharmony_ci } 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci if (is_composite) { 175bf215546Sopenharmony_ci if (!is_src_src || (has_mask && !is_mask_src)) { 176bf215546Sopenharmony_ci src = ureg_DECL_vs_input(ureg, input_slot++); 177bf215546Sopenharmony_ci dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0); 178bf215546Sopenharmony_ci ureg_MOV(ureg, dst, src); 179bf215546Sopenharmony_ci } 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci if (!is_src_src && (has_mask && !is_mask_src)) { 182bf215546Sopenharmony_ci src = ureg_DECL_vs_input(ureg, input_slot++); 183bf215546Sopenharmony_ci dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1); 184bf215546Sopenharmony_ci ureg_MOV(ureg, dst, src); 185bf215546Sopenharmony_ci } 186bf215546Sopenharmony_ci } 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci ureg_END(ureg); 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci return ureg_create_shader_and_destroy(ureg, pipe); 191bf215546Sopenharmony_ci} 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_cistatic void * 194bf215546Sopenharmony_cicreate_yuv_shader(struct pipe_context *pipe, struct ureg_program *ureg) 195bf215546Sopenharmony_ci{ 196bf215546Sopenharmony_ci struct ureg_src y_sampler, u_sampler, v_sampler; 197bf215546Sopenharmony_ci struct ureg_src pos; 198bf215546Sopenharmony_ci struct ureg_src matrow0, matrow1, matrow2, matrow3; 199bf215546Sopenharmony_ci struct ureg_dst y, u, v, rgb; 200bf215546Sopenharmony_ci struct ureg_dst out = ureg_DECL_output(ureg, 201bf215546Sopenharmony_ci TGSI_SEMANTIC_COLOR, 202bf215546Sopenharmony_ci 0); 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci pos = ureg_DECL_fs_input(ureg, 205bf215546Sopenharmony_ci TGSI_SEMANTIC_GENERIC, 0, 206bf215546Sopenharmony_ci TGSI_INTERPOLATE_PERSPECTIVE); 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci rgb = ureg_DECL_temporary(ureg); 209bf215546Sopenharmony_ci y = ureg_DECL_temporary(ureg); 210bf215546Sopenharmony_ci u = ureg_DECL_temporary(ureg); 211bf215546Sopenharmony_ci v = ureg_DECL_temporary(ureg); 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci y_sampler = ureg_DECL_sampler(ureg, 0); 214bf215546Sopenharmony_ci u_sampler = ureg_DECL_sampler(ureg, 1); 215bf215546Sopenharmony_ci v_sampler = ureg_DECL_sampler(ureg, 2); 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_ci ureg_DECL_sampler_view(ureg, 0, TGSI_TEXTURE_2D, 218bf215546Sopenharmony_ci TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT, 219bf215546Sopenharmony_ci TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT); 220bf215546Sopenharmony_ci ureg_DECL_sampler_view(ureg, 1, TGSI_TEXTURE_2D, 221bf215546Sopenharmony_ci TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT, 222bf215546Sopenharmony_ci TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT); 223bf215546Sopenharmony_ci ureg_DECL_sampler_view(ureg, 2, TGSI_TEXTURE_2D, 224bf215546Sopenharmony_ci TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT, 225bf215546Sopenharmony_ci TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT); 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_ci matrow0 = ureg_DECL_constant(ureg, 0); 228bf215546Sopenharmony_ci matrow1 = ureg_DECL_constant(ureg, 1); 229bf215546Sopenharmony_ci matrow2 = ureg_DECL_constant(ureg, 2); 230bf215546Sopenharmony_ci matrow3 = ureg_DECL_constant(ureg, 3); 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ci ureg_TEX(ureg, y, TGSI_TEXTURE_2D, pos, y_sampler); 233bf215546Sopenharmony_ci ureg_TEX(ureg, u, TGSI_TEXTURE_2D, pos, u_sampler); 234bf215546Sopenharmony_ci ureg_TEX(ureg, v, TGSI_TEXTURE_2D, pos, v_sampler); 235bf215546Sopenharmony_ci 236bf215546Sopenharmony_ci ureg_MOV(ureg, rgb, matrow3); 237bf215546Sopenharmony_ci ureg_MAD(ureg, rgb, 238bf215546Sopenharmony_ci ureg_scalar(ureg_src(y), TGSI_SWIZZLE_X), matrow0, ureg_src(rgb)); 239bf215546Sopenharmony_ci ureg_MAD(ureg, rgb, 240bf215546Sopenharmony_ci ureg_scalar(ureg_src(u), TGSI_SWIZZLE_X), matrow1, ureg_src(rgb)); 241bf215546Sopenharmony_ci ureg_MAD(ureg, rgb, 242bf215546Sopenharmony_ci ureg_scalar(ureg_src(v), TGSI_SWIZZLE_X), matrow2, ureg_src(rgb)); 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci ureg_MOV(ureg, out, ureg_src(rgb)); 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci ureg_release_temporary(ureg, rgb); 247bf215546Sopenharmony_ci ureg_release_temporary(ureg, y); 248bf215546Sopenharmony_ci ureg_release_temporary(ureg, u); 249bf215546Sopenharmony_ci ureg_release_temporary(ureg, v); 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci ureg_END(ureg); 252bf215546Sopenharmony_ci 253bf215546Sopenharmony_ci return ureg_create_shader_and_destroy(ureg, pipe); 254bf215546Sopenharmony_ci} 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_cistatic inline void 257bf215546Sopenharmony_cixrender_tex(struct ureg_program *ureg, 258bf215546Sopenharmony_ci struct ureg_dst dst, 259bf215546Sopenharmony_ci struct ureg_src coords, 260bf215546Sopenharmony_ci struct ureg_src sampler, 261bf215546Sopenharmony_ci const struct ureg_src *imm0, 262bf215546Sopenharmony_ci boolean repeat_none, boolean swizzle, boolean set_alpha) 263bf215546Sopenharmony_ci{ 264bf215546Sopenharmony_ci if (repeat_none) { 265bf215546Sopenharmony_ci struct ureg_dst tmp0 = ureg_DECL_temporary(ureg); 266bf215546Sopenharmony_ci struct ureg_dst tmp1 = ureg_DECL_temporary(ureg); 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci ureg_SGT(ureg, tmp1, ureg_swizzle(coords, 269bf215546Sopenharmony_ci TGSI_SWIZZLE_X, 270bf215546Sopenharmony_ci TGSI_SWIZZLE_Y, 271bf215546Sopenharmony_ci TGSI_SWIZZLE_X, 272bf215546Sopenharmony_ci TGSI_SWIZZLE_Y), ureg_scalar(*imm0, 273bf215546Sopenharmony_ci TGSI_SWIZZLE_X)); 274bf215546Sopenharmony_ci ureg_SLT(ureg, tmp0, 275bf215546Sopenharmony_ci ureg_swizzle(coords, TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, 276bf215546Sopenharmony_ci TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y), ureg_scalar(*imm0, 277bf215546Sopenharmony_ci TGSI_SWIZZLE_W)); 278bf215546Sopenharmony_ci ureg_MIN(ureg, tmp0, ureg_src(tmp0), ureg_src(tmp1)); 279bf215546Sopenharmony_ci ureg_MIN(ureg, tmp0, ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_X), 280bf215546Sopenharmony_ci ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_Y)); 281bf215546Sopenharmony_ci ureg_TEX(ureg, tmp1, TGSI_TEXTURE_2D, coords, sampler); 282bf215546Sopenharmony_ci if (swizzle) 283bf215546Sopenharmony_ci ureg_MOV(ureg, tmp1, ureg_swizzle(ureg_src(tmp1), 284bf215546Sopenharmony_ci TGSI_SWIZZLE_Z, 285bf215546Sopenharmony_ci TGSI_SWIZZLE_Y, TGSI_SWIZZLE_X, 286bf215546Sopenharmony_ci TGSI_SWIZZLE_W)); 287bf215546Sopenharmony_ci if (set_alpha) 288bf215546Sopenharmony_ci ureg_MOV(ureg, 289bf215546Sopenharmony_ci ureg_writemask(tmp1, TGSI_WRITEMASK_W), 290bf215546Sopenharmony_ci ureg_scalar(*imm0, TGSI_SWIZZLE_W)); 291bf215546Sopenharmony_ci ureg_MUL(ureg, dst, ureg_src(tmp1), ureg_src(tmp0)); 292bf215546Sopenharmony_ci ureg_release_temporary(ureg, tmp0); 293bf215546Sopenharmony_ci ureg_release_temporary(ureg, tmp1); 294bf215546Sopenharmony_ci } else { 295bf215546Sopenharmony_ci if (swizzle) { 296bf215546Sopenharmony_ci struct ureg_dst tmp = ureg_DECL_temporary(ureg); 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci ureg_TEX(ureg, tmp, TGSI_TEXTURE_2D, coords, sampler); 299bf215546Sopenharmony_ci ureg_MOV(ureg, dst, ureg_swizzle(ureg_src(tmp), 300bf215546Sopenharmony_ci TGSI_SWIZZLE_Z, 301bf215546Sopenharmony_ci TGSI_SWIZZLE_Y, TGSI_SWIZZLE_X, 302bf215546Sopenharmony_ci TGSI_SWIZZLE_W)); 303bf215546Sopenharmony_ci ureg_release_temporary(ureg, tmp); 304bf215546Sopenharmony_ci } else { 305bf215546Sopenharmony_ci ureg_TEX(ureg, dst, TGSI_TEXTURE_2D, coords, sampler); 306bf215546Sopenharmony_ci } 307bf215546Sopenharmony_ci if (set_alpha) 308bf215546Sopenharmony_ci ureg_MOV(ureg, 309bf215546Sopenharmony_ci ureg_writemask(dst, TGSI_WRITEMASK_W), 310bf215546Sopenharmony_ci ureg_scalar(*imm0, TGSI_SWIZZLE_W)); 311bf215546Sopenharmony_ci } 312bf215546Sopenharmony_ci} 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_cistatic void 315bf215546Sopenharmony_ciread_input(struct ureg_program *ureg, 316bf215546Sopenharmony_ci struct ureg_dst dst, 317bf215546Sopenharmony_ci const struct ureg_src *imm0, 318bf215546Sopenharmony_ci boolean repeat_none, boolean swizzle, boolean set_alpha, 319bf215546Sopenharmony_ci boolean is_src, unsigned *cur_constant, unsigned *cur_sampler) 320bf215546Sopenharmony_ci{ 321bf215546Sopenharmony_ci struct ureg_src input, sampler; 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci if (is_src) { 324bf215546Sopenharmony_ci input = ureg_DECL_constant(ureg, (*cur_constant)++); 325bf215546Sopenharmony_ci ureg_MOV(ureg, dst, input); 326bf215546Sopenharmony_ci } else { 327bf215546Sopenharmony_ci sampler = ureg_DECL_sampler(ureg, *cur_sampler); 328bf215546Sopenharmony_ci ureg_DECL_sampler_view(ureg, *cur_sampler, TGSI_TEXTURE_2D, 329bf215546Sopenharmony_ci TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT, 330bf215546Sopenharmony_ci TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT); 331bf215546Sopenharmony_ci input = ureg_DECL_fs_input(ureg, 332bf215546Sopenharmony_ci TGSI_SEMANTIC_GENERIC, (*cur_sampler)++, 333bf215546Sopenharmony_ci TGSI_INTERPOLATE_PERSPECTIVE); 334bf215546Sopenharmony_ci xrender_tex(ureg, dst, input, sampler, imm0, 335bf215546Sopenharmony_ci repeat_none, swizzle, set_alpha); 336bf215546Sopenharmony_ci } 337bf215546Sopenharmony_ci} 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_cistatic void * 340bf215546Sopenharmony_cicreate_fs(struct pipe_context *pipe, unsigned fs_traits) 341bf215546Sopenharmony_ci{ 342bf215546Sopenharmony_ci struct ureg_program *ureg; 343bf215546Sopenharmony_ci struct ureg_dst src, mask; 344bf215546Sopenharmony_ci struct ureg_dst out; 345bf215546Sopenharmony_ci struct ureg_src imm0 = { 0 }; 346bf215546Sopenharmony_ci unsigned has_mask = (fs_traits & FS_MASK) != 0; 347bf215546Sopenharmony_ci unsigned is_yuv = (fs_traits & FS_YUV) != 0; 348bf215546Sopenharmony_ci unsigned src_repeat_none = (fs_traits & FS_SRC_REPEAT_NONE) != 0; 349bf215546Sopenharmony_ci unsigned mask_repeat_none = (fs_traits & FS_MASK_REPEAT_NONE) != 0; 350bf215546Sopenharmony_ci unsigned src_swizzle = (fs_traits & FS_SRC_SWIZZLE_RGB) != 0; 351bf215546Sopenharmony_ci unsigned mask_swizzle = (fs_traits & FS_MASK_SWIZZLE_RGB) != 0; 352bf215546Sopenharmony_ci unsigned src_set_alpha = (fs_traits & FS_SRC_SET_ALPHA) != 0; 353bf215546Sopenharmony_ci unsigned mask_set_alpha = (fs_traits & FS_MASK_SET_ALPHA) != 0; 354bf215546Sopenharmony_ci unsigned src_luminance = (fs_traits & FS_SRC_LUMINANCE) != 0; 355bf215546Sopenharmony_ci unsigned mask_luminance = (fs_traits & FS_MASK_LUMINANCE) != 0; 356bf215546Sopenharmony_ci unsigned dst_luminance = (fs_traits & FS_DST_LUMINANCE) != 0; 357bf215546Sopenharmony_ci unsigned is_src_src = (fs_traits & FS_SRC_SRC) != 0; 358bf215546Sopenharmony_ci unsigned is_mask_src = (fs_traits & FS_MASK_SRC) != 0; 359bf215546Sopenharmony_ci boolean component_alpha = (fs_traits & FS_CA) != 0; 360bf215546Sopenharmony_ci unsigned cur_sampler = 0; 361bf215546Sopenharmony_ci unsigned cur_constant = 0; 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_ci#if 0 364bf215546Sopenharmony_ci print_fs_traits(fs_traits); 365bf215546Sopenharmony_ci#else 366bf215546Sopenharmony_ci (void)print_fs_traits; 367bf215546Sopenharmony_ci#endif 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_ci ureg = ureg_create(PIPE_SHADER_FRAGMENT); 370bf215546Sopenharmony_ci if (ureg == NULL) 371bf215546Sopenharmony_ci return NULL; 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_ci if (is_yuv) 374bf215546Sopenharmony_ci return create_yuv_shader(pipe, ureg); 375bf215546Sopenharmony_ci 376bf215546Sopenharmony_ci out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci if (src_repeat_none || mask_repeat_none || 379bf215546Sopenharmony_ci src_set_alpha || mask_set_alpha || src_luminance) { 380bf215546Sopenharmony_ci imm0 = ureg_imm4f(ureg, 0, 0, 0, 1); 381bf215546Sopenharmony_ci } 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_ci src = (has_mask || src_luminance || dst_luminance) ? 384bf215546Sopenharmony_ci ureg_DECL_temporary(ureg) : out; 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ci read_input(ureg, src, &imm0, src_repeat_none, src_swizzle, 387bf215546Sopenharmony_ci src_set_alpha, is_src_src, &cur_constant, &cur_sampler); 388bf215546Sopenharmony_ci 389bf215546Sopenharmony_ci if (src_luminance) { 390bf215546Sopenharmony_ci ureg_MOV(ureg, src, ureg_scalar(ureg_src(src), TGSI_SWIZZLE_X)); 391bf215546Sopenharmony_ci ureg_MOV(ureg, ureg_writemask(src, TGSI_WRITEMASK_XYZ), 392bf215546Sopenharmony_ci ureg_scalar(imm0, TGSI_SWIZZLE_X)); 393bf215546Sopenharmony_ci if (!has_mask && !dst_luminance) 394bf215546Sopenharmony_ci ureg_MOV(ureg, out, ureg_src(src)); 395bf215546Sopenharmony_ci } 396bf215546Sopenharmony_ci 397bf215546Sopenharmony_ci if (has_mask) { 398bf215546Sopenharmony_ci mask = ureg_DECL_temporary(ureg); 399bf215546Sopenharmony_ci read_input(ureg, mask, &imm0, mask_repeat_none, 400bf215546Sopenharmony_ci mask_swizzle, mask_set_alpha, is_mask_src, &cur_constant, 401bf215546Sopenharmony_ci &cur_sampler); 402bf215546Sopenharmony_ci 403bf215546Sopenharmony_ci src_in_mask(ureg, (dst_luminance) ? src : out, ureg_src(src), 404bf215546Sopenharmony_ci ureg_src(mask), mask_luminance, component_alpha); 405bf215546Sopenharmony_ci 406bf215546Sopenharmony_ci ureg_release_temporary(ureg, mask); 407bf215546Sopenharmony_ci } 408bf215546Sopenharmony_ci 409bf215546Sopenharmony_ci if (dst_luminance) { 410bf215546Sopenharmony_ci /* 411bf215546Sopenharmony_ci * Make sure the alpha channel goes into the output L8 surface. 412bf215546Sopenharmony_ci */ 413bf215546Sopenharmony_ci ureg_MOV(ureg, out, ureg_scalar(ureg_src(src), TGSI_SWIZZLE_W)); 414bf215546Sopenharmony_ci } 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_ci ureg_END(ureg); 417bf215546Sopenharmony_ci 418bf215546Sopenharmony_ci return ureg_create_shader_and_destroy(ureg, pipe); 419bf215546Sopenharmony_ci} 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_cistruct xa_shaders * 422bf215546Sopenharmony_cixa_shaders_create(struct xa_context *r) 423bf215546Sopenharmony_ci{ 424bf215546Sopenharmony_ci struct xa_shaders *sc = CALLOC_STRUCT(xa_shaders); 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci sc->r = r; 427bf215546Sopenharmony_ci cso_hash_init(&sc->vs_hash); 428bf215546Sopenharmony_ci cso_hash_init(&sc->fs_hash); 429bf215546Sopenharmony_ci 430bf215546Sopenharmony_ci return sc; 431bf215546Sopenharmony_ci} 432bf215546Sopenharmony_ci 433bf215546Sopenharmony_cistatic void 434bf215546Sopenharmony_cicache_destroy(struct pipe_context *pipe, 435bf215546Sopenharmony_ci struct cso_hash *hash, unsigned processor) 436bf215546Sopenharmony_ci{ 437bf215546Sopenharmony_ci struct cso_hash_iter iter = cso_hash_first_node(hash); 438bf215546Sopenharmony_ci 439bf215546Sopenharmony_ci while (!cso_hash_iter_is_null(iter)) { 440bf215546Sopenharmony_ci void *shader = (void *)cso_hash_iter_data(iter); 441bf215546Sopenharmony_ci 442bf215546Sopenharmony_ci if (processor == PIPE_SHADER_FRAGMENT) { 443bf215546Sopenharmony_ci pipe->delete_fs_state(pipe, shader); 444bf215546Sopenharmony_ci } else if (processor == PIPE_SHADER_VERTEX) { 445bf215546Sopenharmony_ci pipe->delete_vs_state(pipe, shader); 446bf215546Sopenharmony_ci } 447bf215546Sopenharmony_ci iter = cso_hash_erase(hash, iter); 448bf215546Sopenharmony_ci } 449bf215546Sopenharmony_ci cso_hash_deinit(hash); 450bf215546Sopenharmony_ci} 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_civoid 453bf215546Sopenharmony_cixa_shaders_destroy(struct xa_shaders *sc) 454bf215546Sopenharmony_ci{ 455bf215546Sopenharmony_ci cache_destroy(sc->r->pipe, &sc->vs_hash, PIPE_SHADER_VERTEX); 456bf215546Sopenharmony_ci cache_destroy(sc->r->pipe, &sc->fs_hash, PIPE_SHADER_FRAGMENT); 457bf215546Sopenharmony_ci 458bf215546Sopenharmony_ci FREE(sc); 459bf215546Sopenharmony_ci} 460bf215546Sopenharmony_ci 461bf215546Sopenharmony_cistatic inline void * 462bf215546Sopenharmony_cishader_from_cache(struct pipe_context *pipe, 463bf215546Sopenharmony_ci unsigned type, struct cso_hash *hash, unsigned key) 464bf215546Sopenharmony_ci{ 465bf215546Sopenharmony_ci void *shader = NULL; 466bf215546Sopenharmony_ci 467bf215546Sopenharmony_ci struct cso_hash_iter iter = cso_hash_find(hash, key); 468bf215546Sopenharmony_ci 469bf215546Sopenharmony_ci if (cso_hash_iter_is_null(iter)) { 470bf215546Sopenharmony_ci if (type == PIPE_SHADER_VERTEX) 471bf215546Sopenharmony_ci shader = create_vs(pipe, key); 472bf215546Sopenharmony_ci else 473bf215546Sopenharmony_ci shader = create_fs(pipe, key); 474bf215546Sopenharmony_ci cso_hash_insert(hash, key, shader); 475bf215546Sopenharmony_ci } else 476bf215546Sopenharmony_ci shader = (void *)cso_hash_iter_data(iter); 477bf215546Sopenharmony_ci 478bf215546Sopenharmony_ci return shader; 479bf215546Sopenharmony_ci} 480bf215546Sopenharmony_ci 481bf215546Sopenharmony_cistruct xa_shader 482bf215546Sopenharmony_cixa_shaders_get(struct xa_shaders *sc, unsigned vs_traits, unsigned fs_traits) 483bf215546Sopenharmony_ci{ 484bf215546Sopenharmony_ci struct xa_shader shader = { NULL, NULL }; 485bf215546Sopenharmony_ci void *vs, *fs; 486bf215546Sopenharmony_ci 487bf215546Sopenharmony_ci vs = shader_from_cache(sc->r->pipe, PIPE_SHADER_VERTEX, 488bf215546Sopenharmony_ci &sc->vs_hash, vs_traits); 489bf215546Sopenharmony_ci fs = shader_from_cache(sc->r->pipe, PIPE_SHADER_FRAGMENT, 490bf215546Sopenharmony_ci &sc->fs_hash, fs_traits); 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_ci assert(vs && fs); 493bf215546Sopenharmony_ci if (!vs || !fs) 494bf215546Sopenharmony_ci return shader; 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_ci shader.vs = vs; 497bf215546Sopenharmony_ci shader.fs = fs; 498bf215546Sopenharmony_ci 499bf215546Sopenharmony_ci return shader; 500bf215546Sopenharmony_ci} 501