1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2007 VMware, Inc. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "util/u_debug.h" 29bf215546Sopenharmony_ci#include "pipe/p_shader_tokens.h" 30bf215546Sopenharmony_ci#include "tgsi_info.h" 31bf215546Sopenharmony_ci#include "tgsi_parse.h" 32bf215546Sopenharmony_ci#include "tgsi_util.h" 33bf215546Sopenharmony_ci#include "tgsi_exec.h" 34bf215546Sopenharmony_ci#include "util/bitscan.h" 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ciunion pointer_hack 37bf215546Sopenharmony_ci{ 38bf215546Sopenharmony_ci void *pointer; 39bf215546Sopenharmony_ci uint64_t uint64; 40bf215546Sopenharmony_ci}; 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_civoid * 43bf215546Sopenharmony_citgsi_align_128bit(void *unaligned) 44bf215546Sopenharmony_ci{ 45bf215546Sopenharmony_ci union pointer_hack ph; 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ci ph.uint64 = 0; 48bf215546Sopenharmony_ci ph.pointer = unaligned; 49bf215546Sopenharmony_ci ph.uint64 = (ph.uint64 + 15) & ~15; 50bf215546Sopenharmony_ci return ph.pointer; 51bf215546Sopenharmony_ci} 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_ciunsigned 54bf215546Sopenharmony_citgsi_util_get_src_register_swizzle(const struct tgsi_src_register *reg, 55bf215546Sopenharmony_ci unsigned component) 56bf215546Sopenharmony_ci{ 57bf215546Sopenharmony_ci switch (component) { 58bf215546Sopenharmony_ci case TGSI_CHAN_X: 59bf215546Sopenharmony_ci return reg->SwizzleX; 60bf215546Sopenharmony_ci case TGSI_CHAN_Y: 61bf215546Sopenharmony_ci return reg->SwizzleY; 62bf215546Sopenharmony_ci case TGSI_CHAN_Z: 63bf215546Sopenharmony_ci return reg->SwizzleZ; 64bf215546Sopenharmony_ci case TGSI_CHAN_W: 65bf215546Sopenharmony_ci return reg->SwizzleW; 66bf215546Sopenharmony_ci default: 67bf215546Sopenharmony_ci assert(0); 68bf215546Sopenharmony_ci } 69bf215546Sopenharmony_ci return 0; 70bf215546Sopenharmony_ci} 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_ciunsigned 74bf215546Sopenharmony_citgsi_util_get_full_src_register_swizzle( 75bf215546Sopenharmony_ci const struct tgsi_full_src_register *reg, 76bf215546Sopenharmony_ci unsigned component) 77bf215546Sopenharmony_ci{ 78bf215546Sopenharmony_ci return tgsi_util_get_src_register_swizzle(®->Register, component); 79bf215546Sopenharmony_ci} 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_civoid 83bf215546Sopenharmony_citgsi_util_set_src_register_swizzle(struct tgsi_src_register *reg, 84bf215546Sopenharmony_ci unsigned swizzle, 85bf215546Sopenharmony_ci unsigned component) 86bf215546Sopenharmony_ci{ 87bf215546Sopenharmony_ci switch (component) { 88bf215546Sopenharmony_ci case 0: 89bf215546Sopenharmony_ci reg->SwizzleX = swizzle; 90bf215546Sopenharmony_ci break; 91bf215546Sopenharmony_ci case 1: 92bf215546Sopenharmony_ci reg->SwizzleY = swizzle; 93bf215546Sopenharmony_ci break; 94bf215546Sopenharmony_ci case 2: 95bf215546Sopenharmony_ci reg->SwizzleZ = swizzle; 96bf215546Sopenharmony_ci break; 97bf215546Sopenharmony_ci case 3: 98bf215546Sopenharmony_ci reg->SwizzleW = swizzle; 99bf215546Sopenharmony_ci break; 100bf215546Sopenharmony_ci default: 101bf215546Sopenharmony_ci assert(0); 102bf215546Sopenharmony_ci } 103bf215546Sopenharmony_ci} 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci/** 107bf215546Sopenharmony_ci * Determine which channels of the specificed src register are effectively 108bf215546Sopenharmony_ci * used by this instruction. 109bf215546Sopenharmony_ci */ 110bf215546Sopenharmony_ciunsigned 111bf215546Sopenharmony_citgsi_util_get_src_usage_mask(enum tgsi_opcode opcode, 112bf215546Sopenharmony_ci unsigned src_idx, 113bf215546Sopenharmony_ci uint8_t write_mask, 114bf215546Sopenharmony_ci uint8_t swizzle_x, 115bf215546Sopenharmony_ci uint8_t swizzle_y, 116bf215546Sopenharmony_ci uint8_t swizzle_z, 117bf215546Sopenharmony_ci uint8_t swizzle_w, 118bf215546Sopenharmony_ci enum tgsi_texture_type tex_target, 119bf215546Sopenharmony_ci enum tgsi_texture_type mem_target) 120bf215546Sopenharmony_ci{ 121bf215546Sopenharmony_ci unsigned read_mask; 122bf215546Sopenharmony_ci unsigned usage_mask; 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci switch (opcode) { 125bf215546Sopenharmony_ci case TGSI_OPCODE_IF: 126bf215546Sopenharmony_ci case TGSI_OPCODE_UIF: 127bf215546Sopenharmony_ci case TGSI_OPCODE_EMIT: 128bf215546Sopenharmony_ci case TGSI_OPCODE_ENDPRIM: 129bf215546Sopenharmony_ci case TGSI_OPCODE_RCP: 130bf215546Sopenharmony_ci case TGSI_OPCODE_RSQ: 131bf215546Sopenharmony_ci case TGSI_OPCODE_SQRT: 132bf215546Sopenharmony_ci case TGSI_OPCODE_EX2: 133bf215546Sopenharmony_ci case TGSI_OPCODE_LG2: 134bf215546Sopenharmony_ci case TGSI_OPCODE_SIN: 135bf215546Sopenharmony_ci case TGSI_OPCODE_COS: 136bf215546Sopenharmony_ci case TGSI_OPCODE_POW: /* reads src0.x and src1.x */ 137bf215546Sopenharmony_ci case TGSI_OPCODE_UP2H: 138bf215546Sopenharmony_ci case TGSI_OPCODE_UP2US: 139bf215546Sopenharmony_ci case TGSI_OPCODE_UP4B: 140bf215546Sopenharmony_ci case TGSI_OPCODE_UP4UB: 141bf215546Sopenharmony_ci case TGSI_OPCODE_MEMBAR: 142bf215546Sopenharmony_ci case TGSI_OPCODE_BALLOT: 143bf215546Sopenharmony_ci read_mask = TGSI_WRITEMASK_X; 144bf215546Sopenharmony_ci break; 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ci case TGSI_OPCODE_DP2: 147bf215546Sopenharmony_ci case TGSI_OPCODE_PK2H: 148bf215546Sopenharmony_ci case TGSI_OPCODE_PK2US: 149bf215546Sopenharmony_ci case TGSI_OPCODE_DFRACEXP: 150bf215546Sopenharmony_ci case TGSI_OPCODE_F2D: 151bf215546Sopenharmony_ci case TGSI_OPCODE_I2D: 152bf215546Sopenharmony_ci case TGSI_OPCODE_U2D: 153bf215546Sopenharmony_ci case TGSI_OPCODE_F2U64: 154bf215546Sopenharmony_ci case TGSI_OPCODE_F2I64: 155bf215546Sopenharmony_ci case TGSI_OPCODE_U2I64: 156bf215546Sopenharmony_ci case TGSI_OPCODE_I2I64: 157bf215546Sopenharmony_ci case TGSI_OPCODE_TXQS: /* bindless handle possible */ 158bf215546Sopenharmony_ci case TGSI_OPCODE_RESQ: /* bindless handle possible */ 159bf215546Sopenharmony_ci read_mask = TGSI_WRITEMASK_XY; 160bf215546Sopenharmony_ci break; 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci case TGSI_OPCODE_TXQ: 163bf215546Sopenharmony_ci if (src_idx == 0) 164bf215546Sopenharmony_ci read_mask = TGSI_WRITEMASK_X; 165bf215546Sopenharmony_ci else 166bf215546Sopenharmony_ci read_mask = TGSI_WRITEMASK_XY; /* bindless handle possible */ 167bf215546Sopenharmony_ci break; 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci case TGSI_OPCODE_DP3: 170bf215546Sopenharmony_ci read_mask = TGSI_WRITEMASK_XYZ; 171bf215546Sopenharmony_ci break; 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_ci case TGSI_OPCODE_DSEQ: 174bf215546Sopenharmony_ci case TGSI_OPCODE_DSNE: 175bf215546Sopenharmony_ci case TGSI_OPCODE_DSLT: 176bf215546Sopenharmony_ci case TGSI_OPCODE_DSGE: 177bf215546Sopenharmony_ci case TGSI_OPCODE_DP4: 178bf215546Sopenharmony_ci case TGSI_OPCODE_PK4B: 179bf215546Sopenharmony_ci case TGSI_OPCODE_PK4UB: 180bf215546Sopenharmony_ci case TGSI_OPCODE_D2F: 181bf215546Sopenharmony_ci case TGSI_OPCODE_D2I: 182bf215546Sopenharmony_ci case TGSI_OPCODE_D2U: 183bf215546Sopenharmony_ci case TGSI_OPCODE_I2F: 184bf215546Sopenharmony_ci case TGSI_OPCODE_U2F: 185bf215546Sopenharmony_ci case TGSI_OPCODE_U64SEQ: 186bf215546Sopenharmony_ci case TGSI_OPCODE_U64SNE: 187bf215546Sopenharmony_ci case TGSI_OPCODE_U64SLT: 188bf215546Sopenharmony_ci case TGSI_OPCODE_U64SGE: 189bf215546Sopenharmony_ci case TGSI_OPCODE_U642F: 190bf215546Sopenharmony_ci case TGSI_OPCODE_I64SLT: 191bf215546Sopenharmony_ci case TGSI_OPCODE_I64SGE: 192bf215546Sopenharmony_ci case TGSI_OPCODE_I642F: 193bf215546Sopenharmony_ci read_mask = TGSI_WRITEMASK_XYZW; 194bf215546Sopenharmony_ci break; 195bf215546Sopenharmony_ci 196bf215546Sopenharmony_ci case TGSI_OPCODE_LIT: 197bf215546Sopenharmony_ci read_mask = write_mask & TGSI_WRITEMASK_YZ ? 198bf215546Sopenharmony_ci TGSI_WRITEMASK_XY | TGSI_WRITEMASK_W : 0; 199bf215546Sopenharmony_ci break; 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_ci case TGSI_OPCODE_EXP: 202bf215546Sopenharmony_ci case TGSI_OPCODE_LOG: 203bf215546Sopenharmony_ci read_mask = write_mask & TGSI_WRITEMASK_XYZ ? TGSI_WRITEMASK_X : 0; 204bf215546Sopenharmony_ci break; 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci case TGSI_OPCODE_DST: 207bf215546Sopenharmony_ci if (src_idx == 0) 208bf215546Sopenharmony_ci read_mask = TGSI_WRITEMASK_YZ; 209bf215546Sopenharmony_ci else 210bf215546Sopenharmony_ci read_mask = TGSI_WRITEMASK_YW; 211bf215546Sopenharmony_ci break; 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci case TGSI_OPCODE_DLDEXP: 214bf215546Sopenharmony_ci if (src_idx == 0) { 215bf215546Sopenharmony_ci read_mask = write_mask; 216bf215546Sopenharmony_ci } else { 217bf215546Sopenharmony_ci read_mask = 218bf215546Sopenharmony_ci (write_mask & TGSI_WRITEMASK_XY ? TGSI_WRITEMASK_X : 0) | 219bf215546Sopenharmony_ci (write_mask & TGSI_WRITEMASK_ZW ? TGSI_WRITEMASK_Z : 0); 220bf215546Sopenharmony_ci } 221bf215546Sopenharmony_ci break; 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci case TGSI_OPCODE_READ_INVOC: 224bf215546Sopenharmony_ci if (src_idx == 0) 225bf215546Sopenharmony_ci read_mask = write_mask; 226bf215546Sopenharmony_ci else 227bf215546Sopenharmony_ci read_mask = TGSI_WRITEMASK_X; 228bf215546Sopenharmony_ci break; 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci case TGSI_OPCODE_FBFETCH: 231bf215546Sopenharmony_ci read_mask = 0; /* not a real register read */ 232bf215546Sopenharmony_ci break; 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci case TGSI_OPCODE_TEX: 235bf215546Sopenharmony_ci case TGSI_OPCODE_TEX_LZ: 236bf215546Sopenharmony_ci case TGSI_OPCODE_TXF_LZ: 237bf215546Sopenharmony_ci case TGSI_OPCODE_TXF: 238bf215546Sopenharmony_ci case TGSI_OPCODE_TXB: 239bf215546Sopenharmony_ci case TGSI_OPCODE_TXL: 240bf215546Sopenharmony_ci case TGSI_OPCODE_TXP: 241bf215546Sopenharmony_ci case TGSI_OPCODE_TXD: 242bf215546Sopenharmony_ci case TGSI_OPCODE_TEX2: 243bf215546Sopenharmony_ci case TGSI_OPCODE_TXB2: 244bf215546Sopenharmony_ci case TGSI_OPCODE_TXL2: 245bf215546Sopenharmony_ci case TGSI_OPCODE_LODQ: 246bf215546Sopenharmony_ci case TGSI_OPCODE_TG4: { 247bf215546Sopenharmony_ci unsigned dim_layer = 248bf215546Sopenharmony_ci tgsi_util_get_texture_coord_dim(tex_target); 249bf215546Sopenharmony_ci unsigned dim_layer_shadow, dim; 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci /* Add shadow. */ 252bf215546Sopenharmony_ci if (tgsi_is_shadow_target(tex_target)) { 253bf215546Sopenharmony_ci dim_layer_shadow = dim_layer + 1; 254bf215546Sopenharmony_ci if (tex_target == TGSI_TEXTURE_SHADOW1D) 255bf215546Sopenharmony_ci dim_layer_shadow = 3; 256bf215546Sopenharmony_ci } else { 257bf215546Sopenharmony_ci dim_layer_shadow = dim_layer; 258bf215546Sopenharmony_ci } 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_ci /* Remove layer. */ 261bf215546Sopenharmony_ci if (tgsi_is_array_sampler(tex_target)) 262bf215546Sopenharmony_ci dim = dim_layer - 1; 263bf215546Sopenharmony_ci else 264bf215546Sopenharmony_ci dim = dim_layer; 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci read_mask = TGSI_WRITEMASK_XY; /* bindless handle in the last operand */ 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci switch (src_idx) { 269bf215546Sopenharmony_ci case 0: 270bf215546Sopenharmony_ci if (opcode == TGSI_OPCODE_LODQ) 271bf215546Sopenharmony_ci read_mask = u_bit_consecutive(0, dim); 272bf215546Sopenharmony_ci else 273bf215546Sopenharmony_ci read_mask = u_bit_consecutive(0, dim_layer_shadow) & 0xf; 274bf215546Sopenharmony_ci 275bf215546Sopenharmony_ci if (tex_target == TGSI_TEXTURE_SHADOW1D) 276bf215546Sopenharmony_ci read_mask &= ~TGSI_WRITEMASK_Y; 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci if (opcode == TGSI_OPCODE_TXF || 279bf215546Sopenharmony_ci opcode == TGSI_OPCODE_TXB || 280bf215546Sopenharmony_ci opcode == TGSI_OPCODE_TXL || 281bf215546Sopenharmony_ci opcode == TGSI_OPCODE_TXP) 282bf215546Sopenharmony_ci read_mask |= TGSI_WRITEMASK_W; 283bf215546Sopenharmony_ci break; 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_ci case 1: 286bf215546Sopenharmony_ci if (opcode == TGSI_OPCODE_TXD) 287bf215546Sopenharmony_ci read_mask = u_bit_consecutive(0, dim); 288bf215546Sopenharmony_ci else if (opcode == TGSI_OPCODE_TEX2 || 289bf215546Sopenharmony_ci opcode == TGSI_OPCODE_TXB2 || 290bf215546Sopenharmony_ci opcode == TGSI_OPCODE_TXL2 || 291bf215546Sopenharmony_ci opcode == TGSI_OPCODE_TG4) 292bf215546Sopenharmony_ci read_mask = TGSI_WRITEMASK_X; 293bf215546Sopenharmony_ci break; 294bf215546Sopenharmony_ci 295bf215546Sopenharmony_ci case 2: 296bf215546Sopenharmony_ci if (opcode == TGSI_OPCODE_TXD) 297bf215546Sopenharmony_ci read_mask = u_bit_consecutive(0, dim); 298bf215546Sopenharmony_ci break; 299bf215546Sopenharmony_ci } 300bf215546Sopenharmony_ci break; 301bf215546Sopenharmony_ci } 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ci case TGSI_OPCODE_LOAD: 304bf215546Sopenharmony_ci if (src_idx == 0) { 305bf215546Sopenharmony_ci read_mask = TGSI_WRITEMASK_XY; /* bindless handle possible */ 306bf215546Sopenharmony_ci } else { 307bf215546Sopenharmony_ci unsigned dim = tgsi_util_get_texture_coord_dim(mem_target); 308bf215546Sopenharmony_ci read_mask = u_bit_consecutive(0, dim); 309bf215546Sopenharmony_ci } 310bf215546Sopenharmony_ci break; 311bf215546Sopenharmony_ci 312bf215546Sopenharmony_ci case TGSI_OPCODE_STORE: 313bf215546Sopenharmony_ci if (src_idx == 0) { 314bf215546Sopenharmony_ci unsigned dim = tgsi_util_get_texture_coord_dim(mem_target); 315bf215546Sopenharmony_ci read_mask = u_bit_consecutive(0, dim); 316bf215546Sopenharmony_ci } else { 317bf215546Sopenharmony_ci read_mask = TGSI_WRITEMASK_XYZW; 318bf215546Sopenharmony_ci } 319bf215546Sopenharmony_ci break; 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_ci case TGSI_OPCODE_ATOMUADD: 322bf215546Sopenharmony_ci case TGSI_OPCODE_ATOMXCHG: 323bf215546Sopenharmony_ci case TGSI_OPCODE_ATOMCAS: 324bf215546Sopenharmony_ci case TGSI_OPCODE_ATOMAND: 325bf215546Sopenharmony_ci case TGSI_OPCODE_ATOMOR: 326bf215546Sopenharmony_ci case TGSI_OPCODE_ATOMXOR: 327bf215546Sopenharmony_ci case TGSI_OPCODE_ATOMUMIN: 328bf215546Sopenharmony_ci case TGSI_OPCODE_ATOMUMAX: 329bf215546Sopenharmony_ci case TGSI_OPCODE_ATOMIMIN: 330bf215546Sopenharmony_ci case TGSI_OPCODE_ATOMIMAX: 331bf215546Sopenharmony_ci case TGSI_OPCODE_ATOMFADD: 332bf215546Sopenharmony_ci if (src_idx == 0) { 333bf215546Sopenharmony_ci read_mask = TGSI_WRITEMASK_XY; /* bindless handle possible */ 334bf215546Sopenharmony_ci } else if (src_idx == 1) { 335bf215546Sopenharmony_ci unsigned dim = tgsi_util_get_texture_coord_dim(mem_target); 336bf215546Sopenharmony_ci read_mask = u_bit_consecutive(0, dim); 337bf215546Sopenharmony_ci } else { 338bf215546Sopenharmony_ci read_mask = TGSI_WRITEMASK_XYZW; 339bf215546Sopenharmony_ci } 340bf215546Sopenharmony_ci break; 341bf215546Sopenharmony_ci 342bf215546Sopenharmony_ci case TGSI_OPCODE_INTERP_CENTROID: 343bf215546Sopenharmony_ci case TGSI_OPCODE_INTERP_SAMPLE: 344bf215546Sopenharmony_ci case TGSI_OPCODE_INTERP_OFFSET: 345bf215546Sopenharmony_ci if (src_idx == 0) 346bf215546Sopenharmony_ci read_mask = write_mask; 347bf215546Sopenharmony_ci else if (opcode == TGSI_OPCODE_INTERP_OFFSET) 348bf215546Sopenharmony_ci read_mask = TGSI_WRITEMASK_XY; /* offset */ 349bf215546Sopenharmony_ci else 350bf215546Sopenharmony_ci read_mask = TGSI_WRITEMASK_X; /* sample */ 351bf215546Sopenharmony_ci break; 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci default: 354bf215546Sopenharmony_ci if (tgsi_get_opcode_info(opcode)->output_mode == 355bf215546Sopenharmony_ci TGSI_OUTPUT_COMPONENTWISE) 356bf215546Sopenharmony_ci read_mask = write_mask; 357bf215546Sopenharmony_ci else 358bf215546Sopenharmony_ci read_mask = TGSI_WRITEMASK_XYZW; /* assume all channels are read */ 359bf215546Sopenharmony_ci break; 360bf215546Sopenharmony_ci } 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci usage_mask = 0; 363bf215546Sopenharmony_ci if (read_mask & TGSI_WRITEMASK_X) 364bf215546Sopenharmony_ci usage_mask |= 1 << swizzle_x; 365bf215546Sopenharmony_ci if (read_mask & TGSI_WRITEMASK_Y) 366bf215546Sopenharmony_ci usage_mask |= 1 << swizzle_y; 367bf215546Sopenharmony_ci if (read_mask & TGSI_WRITEMASK_Z) 368bf215546Sopenharmony_ci usage_mask |= 1 << swizzle_z; 369bf215546Sopenharmony_ci if (read_mask & TGSI_WRITEMASK_W) 370bf215546Sopenharmony_ci usage_mask |= 1 << swizzle_w; 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_ci return usage_mask; 373bf215546Sopenharmony_ci} 374bf215546Sopenharmony_ci 375bf215546Sopenharmony_ciunsigned 376bf215546Sopenharmony_citgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst, 377bf215546Sopenharmony_ci unsigned src_idx) 378bf215546Sopenharmony_ci{ 379bf215546Sopenharmony_ci return tgsi_util_get_src_usage_mask(inst->Instruction.Opcode, src_idx, 380bf215546Sopenharmony_ci inst->Dst[0].Register.WriteMask, 381bf215546Sopenharmony_ci inst->Src[src_idx].Register.SwizzleX, 382bf215546Sopenharmony_ci inst->Src[src_idx].Register.SwizzleY, 383bf215546Sopenharmony_ci inst->Src[src_idx].Register.SwizzleZ, 384bf215546Sopenharmony_ci inst->Src[src_idx].Register.SwizzleW, 385bf215546Sopenharmony_ci inst->Texture.Texture, 386bf215546Sopenharmony_ci inst->Memory.Texture); 387bf215546Sopenharmony_ci} 388bf215546Sopenharmony_ci 389bf215546Sopenharmony_ci/** 390bf215546Sopenharmony_ci * Convert a tgsi_ind_register into a tgsi_src_register 391bf215546Sopenharmony_ci */ 392bf215546Sopenharmony_cistruct tgsi_src_register 393bf215546Sopenharmony_citgsi_util_get_src_from_ind(const struct tgsi_ind_register *reg) 394bf215546Sopenharmony_ci{ 395bf215546Sopenharmony_ci struct tgsi_src_register src = { 0 }; 396bf215546Sopenharmony_ci 397bf215546Sopenharmony_ci src.File = reg->File; 398bf215546Sopenharmony_ci src.Index = reg->Index; 399bf215546Sopenharmony_ci src.SwizzleX = reg->Swizzle; 400bf215546Sopenharmony_ci src.SwizzleY = reg->Swizzle; 401bf215546Sopenharmony_ci src.SwizzleZ = reg->Swizzle; 402bf215546Sopenharmony_ci src.SwizzleW = reg->Swizzle; 403bf215546Sopenharmony_ci 404bf215546Sopenharmony_ci return src; 405bf215546Sopenharmony_ci} 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci/** 408bf215546Sopenharmony_ci * Return the dimension of the texture coordinates (layer included for array 409bf215546Sopenharmony_ci * textures), as well as the location of the shadow reference value or the 410bf215546Sopenharmony_ci * sample index. 411bf215546Sopenharmony_ci */ 412bf215546Sopenharmony_ciint 413bf215546Sopenharmony_citgsi_util_get_texture_coord_dim(enum tgsi_texture_type tgsi_tex) 414bf215546Sopenharmony_ci{ 415bf215546Sopenharmony_ci /* 416bf215546Sopenharmony_ci * Depending on the texture target, (src0.xyzw, src1.x) is interpreted 417bf215546Sopenharmony_ci * differently: 418bf215546Sopenharmony_ci * 419bf215546Sopenharmony_ci * (s, X, X, X, X), for BUFFER 420bf215546Sopenharmony_ci * (s, X, X, X, X), for 1D 421bf215546Sopenharmony_ci * (s, t, X, X, X), for 2D, RECT 422bf215546Sopenharmony_ci * (s, t, r, X, X), for 3D, CUBE 423bf215546Sopenharmony_ci * 424bf215546Sopenharmony_ci * (s, layer, X, X, X), for 1D_ARRAY 425bf215546Sopenharmony_ci * (s, t, layer, X, X), for 2D_ARRAY 426bf215546Sopenharmony_ci * (s, t, r, layer, X), for CUBE_ARRAY 427bf215546Sopenharmony_ci * 428bf215546Sopenharmony_ci * (s, X, shadow, X, X), for SHADOW1D 429bf215546Sopenharmony_ci * (s, t, shadow, X, X), for SHADOW2D, SHADOWRECT 430bf215546Sopenharmony_ci * (s, t, r, shadow, X), for SHADOWCUBE 431bf215546Sopenharmony_ci * 432bf215546Sopenharmony_ci * (s, layer, shadow, X, X), for SHADOW1D_ARRAY 433bf215546Sopenharmony_ci * (s, t, layer, shadow, X), for SHADOW2D_ARRAY 434bf215546Sopenharmony_ci * (s, t, r, layer, shadow), for SHADOWCUBE_ARRAY 435bf215546Sopenharmony_ci * 436bf215546Sopenharmony_ci * (s, t, sample, X, X), for 2D_MSAA 437bf215546Sopenharmony_ci * (s, t, layer, sample, X), for 2D_ARRAY_MSAA 438bf215546Sopenharmony_ci */ 439bf215546Sopenharmony_ci switch (tgsi_tex) { 440bf215546Sopenharmony_ci case TGSI_TEXTURE_BUFFER: 441bf215546Sopenharmony_ci case TGSI_TEXTURE_1D: 442bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOW1D: 443bf215546Sopenharmony_ci return 1; 444bf215546Sopenharmony_ci case TGSI_TEXTURE_2D: 445bf215546Sopenharmony_ci case TGSI_TEXTURE_RECT: 446bf215546Sopenharmony_ci case TGSI_TEXTURE_1D_ARRAY: 447bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOW2D: 448bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOWRECT: 449bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOW1D_ARRAY: 450bf215546Sopenharmony_ci case TGSI_TEXTURE_2D_MSAA: 451bf215546Sopenharmony_ci return 2; 452bf215546Sopenharmony_ci case TGSI_TEXTURE_3D: 453bf215546Sopenharmony_ci case TGSI_TEXTURE_CUBE: 454bf215546Sopenharmony_ci case TGSI_TEXTURE_2D_ARRAY: 455bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOWCUBE: 456bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOW2D_ARRAY: 457bf215546Sopenharmony_ci case TGSI_TEXTURE_2D_ARRAY_MSAA: 458bf215546Sopenharmony_ci return 3; 459bf215546Sopenharmony_ci case TGSI_TEXTURE_CUBE_ARRAY: 460bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOWCUBE_ARRAY: 461bf215546Sopenharmony_ci return 4; 462bf215546Sopenharmony_ci default: 463bf215546Sopenharmony_ci assert(!"unknown texture target"); 464bf215546Sopenharmony_ci return 0; 465bf215546Sopenharmony_ci } 466bf215546Sopenharmony_ci} 467bf215546Sopenharmony_ci 468bf215546Sopenharmony_ci 469bf215546Sopenharmony_ci/** 470bf215546Sopenharmony_ci * Given a TGSI_TEXTURE_x target, return register component where the 471bf215546Sopenharmony_ci * shadow reference/distance coordinate is found. Typically, components 472bf215546Sopenharmony_ci * 0 and 1 are the (s,t) texcoords and component 2 or 3 hold the shadow 473bf215546Sopenharmony_ci * reference value. But if we return 4, it means the reference value is 474bf215546Sopenharmony_ci * found in the 0th component of the second coordinate argument to the 475bf215546Sopenharmony_ci * TEX2 instruction. 476bf215546Sopenharmony_ci */ 477bf215546Sopenharmony_ciint 478bf215546Sopenharmony_citgsi_util_get_shadow_ref_src_index(enum tgsi_texture_type tgsi_tex) 479bf215546Sopenharmony_ci{ 480bf215546Sopenharmony_ci switch (tgsi_tex) { 481bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOW1D: 482bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOW2D: 483bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOWRECT: 484bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOW1D_ARRAY: 485bf215546Sopenharmony_ci return 2; 486bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOWCUBE: 487bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOW2D_ARRAY: 488bf215546Sopenharmony_ci case TGSI_TEXTURE_2D_MSAA: 489bf215546Sopenharmony_ci case TGSI_TEXTURE_2D_ARRAY_MSAA: 490bf215546Sopenharmony_ci return 3; 491bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOWCUBE_ARRAY: 492bf215546Sopenharmony_ci return 4; 493bf215546Sopenharmony_ci default: 494bf215546Sopenharmony_ci /* no shadow nor sample */ 495bf215546Sopenharmony_ci return -1; 496bf215546Sopenharmony_ci } 497bf215546Sopenharmony_ci} 498bf215546Sopenharmony_ci 499bf215546Sopenharmony_ci 500bf215546Sopenharmony_cibool 501bf215546Sopenharmony_citgsi_is_shadow_target(enum tgsi_texture_type target) 502bf215546Sopenharmony_ci{ 503bf215546Sopenharmony_ci switch (target) { 504bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOW1D: 505bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOW2D: 506bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOWRECT: 507bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOW1D_ARRAY: 508bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOW2D_ARRAY: 509bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOWCUBE: 510bf215546Sopenharmony_ci case TGSI_TEXTURE_SHADOWCUBE_ARRAY: 511bf215546Sopenharmony_ci return TRUE; 512bf215546Sopenharmony_ci default: 513bf215546Sopenharmony_ci return FALSE; 514bf215546Sopenharmony_ci } 515bf215546Sopenharmony_ci} 516