1848b8605Smrg/************************************************************************** 2848b8605Smrg * 3848b8605Smrg * Copyright 2007 VMware, Inc. 4848b8605Smrg * All Rights Reserved. 5848b8605Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the 8848b8605Smrg * "Software"), to deal in the Software without restriction, including 9848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish, 10848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to 11848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to 12848b8605Smrg * the following conditions: 13848b8605Smrg * 14848b8605Smrg * The above copyright notice and this permission notice (including the 15848b8605Smrg * next paragraph) shall be included in all copies or substantial portions 16848b8605Smrg * of the Software. 17848b8605Smrg * 18848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20848b8605Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21848b8605Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22848b8605Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23848b8605Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24848b8605Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25848b8605Smrg * 26848b8605Smrg **************************************************************************/ 27848b8605Smrg 28848b8605Smrg#include "util/u_debug.h" 29848b8605Smrg#include "pipe/p_shader_tokens.h" 30b8e80941Smrg#include "tgsi_info.h" 31848b8605Smrg#include "tgsi_parse.h" 32848b8605Smrg#include "tgsi_util.h" 33b8e80941Smrg#include "tgsi_exec.h" 34b8e80941Smrg#include "util/bitscan.h" 35848b8605Smrg 36848b8605Smrgunion pointer_hack 37848b8605Smrg{ 38848b8605Smrg void *pointer; 39848b8605Smrg uint64_t uint64; 40848b8605Smrg}; 41848b8605Smrg 42848b8605Smrgvoid * 43b8e80941Smrgtgsi_align_128bit(void *unaligned) 44848b8605Smrg{ 45848b8605Smrg union pointer_hack ph; 46848b8605Smrg 47848b8605Smrg ph.uint64 = 0; 48848b8605Smrg ph.pointer = unaligned; 49848b8605Smrg ph.uint64 = (ph.uint64 + 15) & ~15; 50848b8605Smrg return ph.pointer; 51848b8605Smrg} 52848b8605Smrg 53848b8605Smrgunsigned 54b8e80941Smrgtgsi_util_get_src_register_swizzle(const struct tgsi_src_register *reg, 55b8e80941Smrg unsigned component) 56848b8605Smrg{ 57b8e80941Smrg switch (component) { 58b8e80941Smrg case TGSI_CHAN_X: 59848b8605Smrg return reg->SwizzleX; 60b8e80941Smrg case TGSI_CHAN_Y: 61848b8605Smrg return reg->SwizzleY; 62b8e80941Smrg case TGSI_CHAN_Z: 63848b8605Smrg return reg->SwizzleZ; 64b8e80941Smrg case TGSI_CHAN_W: 65848b8605Smrg return reg->SwizzleW; 66848b8605Smrg default: 67b8e80941Smrg assert(0); 68848b8605Smrg } 69848b8605Smrg return 0; 70848b8605Smrg} 71848b8605Smrg 72848b8605Smrg 73848b8605Smrgunsigned 74848b8605Smrgtgsi_util_get_full_src_register_swizzle( 75b8e80941Smrg const struct tgsi_full_src_register *reg, 76b8e80941Smrg unsigned component) 77848b8605Smrg{ 78b8e80941Smrg return tgsi_util_get_src_register_swizzle(®->Register, component); 79848b8605Smrg} 80848b8605Smrg 81b8e80941Smrg 82848b8605Smrgvoid 83b8e80941Smrgtgsi_util_set_src_register_swizzle(struct tgsi_src_register *reg, 84b8e80941Smrg unsigned swizzle, 85b8e80941Smrg unsigned component) 86848b8605Smrg{ 87b8e80941Smrg switch (component) { 88848b8605Smrg case 0: 89848b8605Smrg reg->SwizzleX = swizzle; 90848b8605Smrg break; 91848b8605Smrg case 1: 92848b8605Smrg reg->SwizzleY = swizzle; 93848b8605Smrg break; 94848b8605Smrg case 2: 95848b8605Smrg reg->SwizzleZ = swizzle; 96848b8605Smrg break; 97848b8605Smrg case 3: 98848b8605Smrg reg->SwizzleW = swizzle; 99848b8605Smrg break; 100848b8605Smrg default: 101b8e80941Smrg assert(0); 102848b8605Smrg } 103848b8605Smrg} 104848b8605Smrg 105b8e80941Smrg 106848b8605Smrgunsigned 107848b8605Smrgtgsi_util_get_full_src_register_sign_mode( 108b8e80941Smrg const struct tgsi_full_src_register *reg, 109b8e80941Smrg UNUSED unsigned component) 110848b8605Smrg{ 111848b8605Smrg unsigned sign_mode; 112848b8605Smrg 113b8e80941Smrg if (reg->Register.Absolute) { 114848b8605Smrg /* Consider only the post-abs negation. */ 115848b8605Smrg 116b8e80941Smrg if (reg->Register.Negate) { 117848b8605Smrg sign_mode = TGSI_UTIL_SIGN_SET; 118848b8605Smrg } 119848b8605Smrg else { 120848b8605Smrg sign_mode = TGSI_UTIL_SIGN_CLEAR; 121848b8605Smrg } 122848b8605Smrg } 123848b8605Smrg else { 124b8e80941Smrg if (reg->Register.Negate) { 125848b8605Smrg sign_mode = TGSI_UTIL_SIGN_TOGGLE; 126848b8605Smrg } 127848b8605Smrg else { 128848b8605Smrg sign_mode = TGSI_UTIL_SIGN_KEEP; 129848b8605Smrg } 130848b8605Smrg } 131848b8605Smrg 132848b8605Smrg return sign_mode; 133848b8605Smrg} 134848b8605Smrg 135b8e80941Smrg 136848b8605Smrgvoid 137b8e80941Smrgtgsi_util_set_full_src_register_sign_mode(struct tgsi_full_src_register *reg, 138b8e80941Smrg unsigned sign_mode) 139848b8605Smrg{ 140b8e80941Smrg switch (sign_mode) { 141848b8605Smrg case TGSI_UTIL_SIGN_CLEAR: 142848b8605Smrg reg->Register.Negate = 0; 143848b8605Smrg reg->Register.Absolute = 1; 144848b8605Smrg break; 145848b8605Smrg 146848b8605Smrg case TGSI_UTIL_SIGN_SET: 147848b8605Smrg reg->Register.Absolute = 1; 148848b8605Smrg reg->Register.Negate = 1; 149848b8605Smrg break; 150848b8605Smrg 151848b8605Smrg case TGSI_UTIL_SIGN_TOGGLE: 152848b8605Smrg reg->Register.Negate = 1; 153848b8605Smrg reg->Register.Absolute = 0; 154848b8605Smrg break; 155848b8605Smrg 156848b8605Smrg case TGSI_UTIL_SIGN_KEEP: 157848b8605Smrg reg->Register.Negate = 0; 158848b8605Smrg reg->Register.Absolute = 0; 159848b8605Smrg break; 160848b8605Smrg 161848b8605Smrg default: 162b8e80941Smrg assert(0); 163848b8605Smrg } 164848b8605Smrg} 165848b8605Smrg 166b8e80941Smrg 167848b8605Smrg/** 168848b8605Smrg * Determine which channels of the specificed src register are effectively 169848b8605Smrg * used by this instruction. 170848b8605Smrg */ 171848b8605Smrgunsigned 172848b8605Smrgtgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst, 173848b8605Smrg unsigned src_idx) 174848b8605Smrg{ 175848b8605Smrg const struct tgsi_full_src_register *src = &inst->Src[src_idx]; 176848b8605Smrg unsigned write_mask = inst->Dst[0].Register.WriteMask; 177848b8605Smrg unsigned read_mask; 178848b8605Smrg unsigned usage_mask; 179848b8605Smrg unsigned chan; 180848b8605Smrg 181848b8605Smrg switch (inst->Instruction.Opcode) { 182b8e80941Smrg case TGSI_OPCODE_IF: 183b8e80941Smrg case TGSI_OPCODE_UIF: 184b8e80941Smrg case TGSI_OPCODE_EMIT: 185b8e80941Smrg case TGSI_OPCODE_ENDPRIM: 186848b8605Smrg case TGSI_OPCODE_RCP: 187b8e80941Smrg case TGSI_OPCODE_RSQ: 188b8e80941Smrg case TGSI_OPCODE_SQRT: 189848b8605Smrg case TGSI_OPCODE_EX2: 190848b8605Smrg case TGSI_OPCODE_LG2: 191b8e80941Smrg case TGSI_OPCODE_SIN: 192b8e80941Smrg case TGSI_OPCODE_COS: 193b8e80941Smrg case TGSI_OPCODE_POW: /* reads src0.x and src1.x */ 194b8e80941Smrg case TGSI_OPCODE_UP2H: 195b8e80941Smrg case TGSI_OPCODE_UP2US: 196b8e80941Smrg case TGSI_OPCODE_UP4B: 197b8e80941Smrg case TGSI_OPCODE_UP4UB: 198b8e80941Smrg case TGSI_OPCODE_MEMBAR: 199b8e80941Smrg case TGSI_OPCODE_BALLOT: 200848b8605Smrg read_mask = TGSI_WRITEMASK_X; 201848b8605Smrg break; 202848b8605Smrg 203b8e80941Smrg case TGSI_OPCODE_DP2: 204b8e80941Smrg case TGSI_OPCODE_PK2H: 205b8e80941Smrg case TGSI_OPCODE_PK2US: 206b8e80941Smrg case TGSI_OPCODE_DFRACEXP: 207b8e80941Smrg case TGSI_OPCODE_F2D: 208b8e80941Smrg case TGSI_OPCODE_I2D: 209b8e80941Smrg case TGSI_OPCODE_U2D: 210b8e80941Smrg case TGSI_OPCODE_F2U64: 211b8e80941Smrg case TGSI_OPCODE_F2I64: 212b8e80941Smrg case TGSI_OPCODE_U2I64: 213b8e80941Smrg case TGSI_OPCODE_I2I64: 214b8e80941Smrg case TGSI_OPCODE_TXQS: /* bindless handle possible */ 215b8e80941Smrg case TGSI_OPCODE_RESQ: /* bindless handle possible */ 216b8e80941Smrg read_mask = TGSI_WRITEMASK_XY; 217b8e80941Smrg break; 218b8e80941Smrg 219b8e80941Smrg case TGSI_OPCODE_TXQ: 220b8e80941Smrg if (src_idx == 0) 221b8e80941Smrg read_mask = TGSI_WRITEMASK_X; 222b8e80941Smrg else 223b8e80941Smrg read_mask = TGSI_WRITEMASK_XY; /* bindless handle possible */ 224b8e80941Smrg break; 225b8e80941Smrg 226b8e80941Smrg case TGSI_OPCODE_DP3: 227b8e80941Smrg read_mask = TGSI_WRITEMASK_XYZ; 228b8e80941Smrg break; 229b8e80941Smrg 230b8e80941Smrg case TGSI_OPCODE_DSEQ: 231b8e80941Smrg case TGSI_OPCODE_DSNE: 232b8e80941Smrg case TGSI_OPCODE_DSLT: 233b8e80941Smrg case TGSI_OPCODE_DSGE: 234b8e80941Smrg case TGSI_OPCODE_DP4: 235b8e80941Smrg case TGSI_OPCODE_PK4B: 236b8e80941Smrg case TGSI_OPCODE_PK4UB: 237b8e80941Smrg case TGSI_OPCODE_D2F: 238b8e80941Smrg case TGSI_OPCODE_D2I: 239b8e80941Smrg case TGSI_OPCODE_D2U: 240b8e80941Smrg case TGSI_OPCODE_I2F: 241b8e80941Smrg case TGSI_OPCODE_U2F: 242b8e80941Smrg case TGSI_OPCODE_U64SEQ: 243b8e80941Smrg case TGSI_OPCODE_U64SNE: 244b8e80941Smrg case TGSI_OPCODE_U64SLT: 245b8e80941Smrg case TGSI_OPCODE_U64SGE: 246b8e80941Smrg case TGSI_OPCODE_U642F: 247b8e80941Smrg case TGSI_OPCODE_I64SLT: 248b8e80941Smrg case TGSI_OPCODE_I64SGE: 249b8e80941Smrg case TGSI_OPCODE_I642F: 250b8e80941Smrg read_mask = TGSI_WRITEMASK_XYZW; 251b8e80941Smrg break; 252b8e80941Smrg 253b8e80941Smrg case TGSI_OPCODE_LIT: 254b8e80941Smrg read_mask = write_mask & TGSI_WRITEMASK_YZ ? 255b8e80941Smrg TGSI_WRITEMASK_XY | TGSI_WRITEMASK_W : 0; 256848b8605Smrg break; 257848b8605Smrg 258848b8605Smrg case TGSI_OPCODE_EXP: 259848b8605Smrg case TGSI_OPCODE_LOG: 260848b8605Smrg read_mask = write_mask & TGSI_WRITEMASK_XYZ ? TGSI_WRITEMASK_X : 0; 261848b8605Smrg break; 262848b8605Smrg 263b8e80941Smrg case TGSI_OPCODE_DST: 264b8e80941Smrg if (src_idx == 0) 265b8e80941Smrg read_mask = TGSI_WRITEMASK_YZ; 266b8e80941Smrg else 267b8e80941Smrg read_mask = TGSI_WRITEMASK_YW; 268848b8605Smrg break; 269848b8605Smrg 270b8e80941Smrg case TGSI_OPCODE_DLDEXP: 271b8e80941Smrg if (src_idx == 0) { 272b8e80941Smrg read_mask = write_mask; 273b8e80941Smrg } else { 274b8e80941Smrg read_mask = 275b8e80941Smrg (write_mask & TGSI_WRITEMASK_XY ? TGSI_WRITEMASK_X : 0) | 276b8e80941Smrg (write_mask & TGSI_WRITEMASK_ZW ? TGSI_WRITEMASK_Z : 0); 277b8e80941Smrg } 278848b8605Smrg break; 279848b8605Smrg 280b8e80941Smrg case TGSI_OPCODE_READ_INVOC: 281b8e80941Smrg if (src_idx == 0) 282b8e80941Smrg read_mask = write_mask; 283b8e80941Smrg else 284b8e80941Smrg read_mask = TGSI_WRITEMASK_X; 285848b8605Smrg break; 286848b8605Smrg 287b8e80941Smrg case TGSI_OPCODE_FBFETCH: 288b8e80941Smrg read_mask = 0; /* not a real register read */ 289848b8605Smrg break; 290848b8605Smrg 291848b8605Smrg case TGSI_OPCODE_TEX: 292b8e80941Smrg case TGSI_OPCODE_TEX_LZ: 293b8e80941Smrg case TGSI_OPCODE_TXF_LZ: 294b8e80941Smrg case TGSI_OPCODE_TXF: 295848b8605Smrg case TGSI_OPCODE_TXB: 296848b8605Smrg case TGSI_OPCODE_TXL: 297848b8605Smrg case TGSI_OPCODE_TXP: 298b8e80941Smrg case TGSI_OPCODE_TXD: 299b8e80941Smrg case TGSI_OPCODE_TEX2: 300b8e80941Smrg case TGSI_OPCODE_TXB2: 301b8e80941Smrg case TGSI_OPCODE_TXL2: 302b8e80941Smrg case TGSI_OPCODE_LODQ: 303b8e80941Smrg case TGSI_OPCODE_TG4: { 304b8e80941Smrg unsigned dim_layer = 305b8e80941Smrg tgsi_util_get_texture_coord_dim(inst->Texture.Texture); 306b8e80941Smrg unsigned dim_layer_shadow, dim; 307b8e80941Smrg 308b8e80941Smrg /* Add shadow. */ 309b8e80941Smrg if (tgsi_is_shadow_target(inst->Texture.Texture)) { 310b8e80941Smrg dim_layer_shadow = dim_layer + 1; 311b8e80941Smrg if (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D) 312b8e80941Smrg dim_layer_shadow = 3; 313b8e80941Smrg } else { 314b8e80941Smrg dim_layer_shadow = dim_layer; 315b8e80941Smrg } 316b8e80941Smrg 317b8e80941Smrg /* Remove layer. */ 318b8e80941Smrg if (tgsi_is_array_sampler(inst->Texture.Texture)) 319b8e80941Smrg dim = dim_layer - 1; 320b8e80941Smrg else 321b8e80941Smrg dim = dim_layer; 322b8e80941Smrg 323b8e80941Smrg read_mask = TGSI_WRITEMASK_XY; /* bindless handle in the last operand */ 324b8e80941Smrg 325b8e80941Smrg switch (src_idx) { 326b8e80941Smrg case 0: 327b8e80941Smrg if (inst->Instruction.Opcode == TGSI_OPCODE_LODQ) 328b8e80941Smrg read_mask = u_bit_consecutive(0, dim); 329b8e80941Smrg else 330b8e80941Smrg read_mask = u_bit_consecutive(0, dim_layer_shadow) & 0xf; 331b8e80941Smrg 332b8e80941Smrg if (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D) 333b8e80941Smrg read_mask &= ~TGSI_WRITEMASK_Y; 334b8e80941Smrg 335b8e80941Smrg if (inst->Instruction.Opcode == TGSI_OPCODE_TXF || 336b8e80941Smrg inst->Instruction.Opcode == TGSI_OPCODE_TXB || 337b8e80941Smrg inst->Instruction.Opcode == TGSI_OPCODE_TXL || 338b8e80941Smrg inst->Instruction.Opcode == TGSI_OPCODE_TXP) 339848b8605Smrg read_mask |= TGSI_WRITEMASK_W; 340b8e80941Smrg break; 341b8e80941Smrg 342b8e80941Smrg case 1: 343b8e80941Smrg if (inst->Instruction.Opcode == TGSI_OPCODE_TXD) 344b8e80941Smrg read_mask = u_bit_consecutive(0, dim); 345b8e80941Smrg else if (inst->Instruction.Opcode == TGSI_OPCODE_TEX2 || 346b8e80941Smrg inst->Instruction.Opcode == TGSI_OPCODE_TXB2 || 347b8e80941Smrg inst->Instruction.Opcode == TGSI_OPCODE_TXL2 || 348b8e80941Smrg inst->Instruction.Opcode == TGSI_OPCODE_TG4) 349b8e80941Smrg read_mask = TGSI_WRITEMASK_X; 350b8e80941Smrg break; 351b8e80941Smrg 352b8e80941Smrg case 2: 353b8e80941Smrg if (inst->Instruction.Opcode == TGSI_OPCODE_TXD) 354b8e80941Smrg read_mask = u_bit_consecutive(0, dim); 355b8e80941Smrg break; 356b8e80941Smrg } 357b8e80941Smrg break; 358b8e80941Smrg } 359b8e80941Smrg 360b8e80941Smrg case TGSI_OPCODE_LOAD: 361b8e80941Smrg if (src_idx == 0) { 362b8e80941Smrg read_mask = TGSI_WRITEMASK_XY; /* bindless handle possible */ 363b8e80941Smrg } else { 364b8e80941Smrg unsigned dim = tgsi_util_get_texture_coord_dim(inst->Memory.Texture); 365b8e80941Smrg read_mask = u_bit_consecutive(0, dim); 366b8e80941Smrg } 367b8e80941Smrg break; 368b8e80941Smrg 369b8e80941Smrg case TGSI_OPCODE_STORE: 370b8e80941Smrg if (src_idx == 0) { 371b8e80941Smrg unsigned dim = tgsi_util_get_texture_coord_dim(inst->Memory.Texture); 372b8e80941Smrg read_mask = u_bit_consecutive(0, dim); 373b8e80941Smrg } else { 374b8e80941Smrg read_mask = TGSI_WRITEMASK_XYZW; 375b8e80941Smrg } 376b8e80941Smrg break; 377b8e80941Smrg 378b8e80941Smrg case TGSI_OPCODE_ATOMUADD: 379b8e80941Smrg case TGSI_OPCODE_ATOMXCHG: 380b8e80941Smrg case TGSI_OPCODE_ATOMCAS: 381b8e80941Smrg case TGSI_OPCODE_ATOMAND: 382b8e80941Smrg case TGSI_OPCODE_ATOMOR: 383b8e80941Smrg case TGSI_OPCODE_ATOMXOR: 384b8e80941Smrg case TGSI_OPCODE_ATOMUMIN: 385b8e80941Smrg case TGSI_OPCODE_ATOMUMAX: 386b8e80941Smrg case TGSI_OPCODE_ATOMIMIN: 387b8e80941Smrg case TGSI_OPCODE_ATOMIMAX: 388b8e80941Smrg case TGSI_OPCODE_ATOMFADD: 389b8e80941Smrg if (src_idx == 0) { 390b8e80941Smrg read_mask = TGSI_WRITEMASK_XY; /* bindless handle possible */ 391b8e80941Smrg } else if (src_idx == 1) { 392b8e80941Smrg unsigned dim = tgsi_util_get_texture_coord_dim(inst->Memory.Texture); 393b8e80941Smrg read_mask = u_bit_consecutive(0, dim); 394848b8605Smrg } else { 395848b8605Smrg read_mask = TGSI_WRITEMASK_XYZW; 396848b8605Smrg } 397848b8605Smrg break; 398848b8605Smrg 399b8e80941Smrg case TGSI_OPCODE_INTERP_CENTROID: 400b8e80941Smrg case TGSI_OPCODE_INTERP_SAMPLE: 401b8e80941Smrg case TGSI_OPCODE_INTERP_OFFSET: 402b8e80941Smrg if (src_idx == 0) 403b8e80941Smrg read_mask = write_mask; 404b8e80941Smrg else if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_OFFSET) 405b8e80941Smrg read_mask = TGSI_WRITEMASK_XY; /* offset */ 406b8e80941Smrg else 407b8e80941Smrg read_mask = TGSI_WRITEMASK_X; /* sample */ 408b8e80941Smrg break; 409b8e80941Smrg 410848b8605Smrg default: 411b8e80941Smrg if (tgsi_get_opcode_info(inst->Instruction.Opcode)->output_mode == 412b8e80941Smrg TGSI_OUTPUT_COMPONENTWISE) 413b8e80941Smrg read_mask = write_mask; 414b8e80941Smrg else 415b8e80941Smrg read_mask = TGSI_WRITEMASK_XYZW; /* assume all channels are read */ 416848b8605Smrg break; 417848b8605Smrg } 418848b8605Smrg 419848b8605Smrg usage_mask = 0; 420848b8605Smrg for (chan = 0; chan < 4; ++chan) { 421848b8605Smrg if (read_mask & (1 << chan)) { 422848b8605Smrg usage_mask |= 1 << tgsi_util_get_full_src_register_swizzle(src, chan); 423848b8605Smrg } 424848b8605Smrg } 425848b8605Smrg 426848b8605Smrg return usage_mask; 427848b8605Smrg} 428848b8605Smrg 429848b8605Smrg/** 430848b8605Smrg * Convert a tgsi_ind_register into a tgsi_src_register 431848b8605Smrg */ 432848b8605Smrgstruct tgsi_src_register 433848b8605Smrgtgsi_util_get_src_from_ind(const struct tgsi_ind_register *reg) 434848b8605Smrg{ 435848b8605Smrg struct tgsi_src_register src = { 0 }; 436848b8605Smrg 437848b8605Smrg src.File = reg->File; 438848b8605Smrg src.Index = reg->Index; 439848b8605Smrg src.SwizzleX = reg->Swizzle; 440848b8605Smrg src.SwizzleY = reg->Swizzle; 441848b8605Smrg src.SwizzleZ = reg->Swizzle; 442848b8605Smrg src.SwizzleW = reg->Swizzle; 443848b8605Smrg 444848b8605Smrg return src; 445848b8605Smrg} 446848b8605Smrg 447848b8605Smrg/** 448848b8605Smrg * Return the dimension of the texture coordinates (layer included for array 449848b8605Smrg * textures), as well as the location of the shadow reference value or the 450848b8605Smrg * sample index. 451848b8605Smrg */ 452848b8605Smrgint 453b8e80941Smrgtgsi_util_get_texture_coord_dim(enum tgsi_texture_type tgsi_tex) 454848b8605Smrg{ 455848b8605Smrg /* 456848b8605Smrg * Depending on the texture target, (src0.xyzw, src1.x) is interpreted 457848b8605Smrg * differently: 458848b8605Smrg * 459848b8605Smrg * (s, X, X, X, X), for BUFFER 460848b8605Smrg * (s, X, X, X, X), for 1D 461848b8605Smrg * (s, t, X, X, X), for 2D, RECT 462848b8605Smrg * (s, t, r, X, X), for 3D, CUBE 463848b8605Smrg * 464848b8605Smrg * (s, layer, X, X, X), for 1D_ARRAY 465848b8605Smrg * (s, t, layer, X, X), for 2D_ARRAY 466848b8605Smrg * (s, t, r, layer, X), for CUBE_ARRAY 467848b8605Smrg * 468848b8605Smrg * (s, X, shadow, X, X), for SHADOW1D 469848b8605Smrg * (s, t, shadow, X, X), for SHADOW2D, SHADOWRECT 470848b8605Smrg * (s, t, r, shadow, X), for SHADOWCUBE 471848b8605Smrg * 472848b8605Smrg * (s, layer, shadow, X, X), for SHADOW1D_ARRAY 473848b8605Smrg * (s, t, layer, shadow, X), for SHADOW2D_ARRAY 474848b8605Smrg * (s, t, r, layer, shadow), for SHADOWCUBE_ARRAY 475848b8605Smrg * 476848b8605Smrg * (s, t, sample, X, X), for 2D_MSAA 477848b8605Smrg * (s, t, layer, sample, X), for 2D_ARRAY_MSAA 478848b8605Smrg */ 479848b8605Smrg switch (tgsi_tex) { 480848b8605Smrg case TGSI_TEXTURE_BUFFER: 481848b8605Smrg case TGSI_TEXTURE_1D: 482848b8605Smrg case TGSI_TEXTURE_SHADOW1D: 483b8e80941Smrg return 1; 484848b8605Smrg case TGSI_TEXTURE_2D: 485848b8605Smrg case TGSI_TEXTURE_RECT: 486848b8605Smrg case TGSI_TEXTURE_1D_ARRAY: 487848b8605Smrg case TGSI_TEXTURE_SHADOW2D: 488848b8605Smrg case TGSI_TEXTURE_SHADOWRECT: 489848b8605Smrg case TGSI_TEXTURE_SHADOW1D_ARRAY: 490848b8605Smrg case TGSI_TEXTURE_2D_MSAA: 491b8e80941Smrg return 2; 492848b8605Smrg case TGSI_TEXTURE_3D: 493848b8605Smrg case TGSI_TEXTURE_CUBE: 494848b8605Smrg case TGSI_TEXTURE_2D_ARRAY: 495848b8605Smrg case TGSI_TEXTURE_SHADOWCUBE: 496848b8605Smrg case TGSI_TEXTURE_SHADOW2D_ARRAY: 497848b8605Smrg case TGSI_TEXTURE_2D_ARRAY_MSAA: 498b8e80941Smrg return 3; 499848b8605Smrg case TGSI_TEXTURE_CUBE_ARRAY: 500848b8605Smrg case TGSI_TEXTURE_SHADOWCUBE_ARRAY: 501b8e80941Smrg return 4; 502848b8605Smrg default: 503848b8605Smrg assert(!"unknown texture target"); 504b8e80941Smrg return 0; 505848b8605Smrg } 506b8e80941Smrg} 507848b8605Smrg 508b8e80941Smrg 509b8e80941Smrg/** 510b8e80941Smrg * Given a TGSI_TEXTURE_x target, return register component where the 511b8e80941Smrg * shadow reference/distance coordinate is found. Typically, components 512b8e80941Smrg * 0 and 1 are the (s,t) texcoords and component 2 or 3 hold the shadow 513b8e80941Smrg * reference value. But if we return 4, it means the reference value is 514b8e80941Smrg * found in the 0th component of the second coordinate argument to the 515b8e80941Smrg * TEX2 instruction. 516b8e80941Smrg */ 517b8e80941Smrgint 518b8e80941Smrgtgsi_util_get_shadow_ref_src_index(enum tgsi_texture_type tgsi_tex) 519b8e80941Smrg{ 520b8e80941Smrg switch (tgsi_tex) { 521b8e80941Smrg case TGSI_TEXTURE_SHADOW1D: 522b8e80941Smrg case TGSI_TEXTURE_SHADOW2D: 523b8e80941Smrg case TGSI_TEXTURE_SHADOWRECT: 524b8e80941Smrg case TGSI_TEXTURE_SHADOW1D_ARRAY: 525b8e80941Smrg return 2; 526b8e80941Smrg case TGSI_TEXTURE_SHADOWCUBE: 527b8e80941Smrg case TGSI_TEXTURE_SHADOW2D_ARRAY: 528b8e80941Smrg case TGSI_TEXTURE_2D_MSAA: 529b8e80941Smrg case TGSI_TEXTURE_2D_ARRAY_MSAA: 530b8e80941Smrg return 3; 531b8e80941Smrg case TGSI_TEXTURE_SHADOWCUBE_ARRAY: 532b8e80941Smrg return 4; 533b8e80941Smrg default: 534b8e80941Smrg /* no shadow nor sample */ 535b8e80941Smrg return -1; 536848b8605Smrg } 537b8e80941Smrg} 538b8e80941Smrg 539848b8605Smrg 540b8e80941Smrgboolean 541b8e80941Smrgtgsi_is_shadow_target(enum tgsi_texture_type target) 542b8e80941Smrg{ 543b8e80941Smrg switch (target) { 544b8e80941Smrg case TGSI_TEXTURE_SHADOW1D: 545b8e80941Smrg case TGSI_TEXTURE_SHADOW2D: 546b8e80941Smrg case TGSI_TEXTURE_SHADOWRECT: 547b8e80941Smrg case TGSI_TEXTURE_SHADOW1D_ARRAY: 548b8e80941Smrg case TGSI_TEXTURE_SHADOW2D_ARRAY: 549b8e80941Smrg case TGSI_TEXTURE_SHADOWCUBE: 550b8e80941Smrg case TGSI_TEXTURE_SHADOWCUBE_ARRAY: 551b8e80941Smrg return TRUE; 552b8e80941Smrg default: 553b8e80941Smrg return FALSE; 554b8e80941Smrg } 555848b8605Smrg} 556