14a49301eSmrg/************************************************************************** 24a49301eSmrg * 3af69d88dSmrg * Copyright 2007 VMware, Inc. 44a49301eSmrg * All Rights Reserved. 54a49301eSmrg * 64a49301eSmrg * Permission is hereby granted, free of charge, to any person obtaining a 74a49301eSmrg * copy of this software and associated documentation files (the 84a49301eSmrg * "Software"), to deal in the Software without restriction, including 94a49301eSmrg * without limitation the rights to use, copy, modify, merge, publish, 104a49301eSmrg * distribute, sub license, and/or sell copies of the Software, and to 114a49301eSmrg * permit persons to whom the Software is furnished to do so, subject to 124a49301eSmrg * the following conditions: 134a49301eSmrg * 144a49301eSmrg * The above copyright notice and this permission notice (including the 154a49301eSmrg * next paragraph) shall be included in all copies or substantial portions 164a49301eSmrg * of the Software. 174a49301eSmrg * 184a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 194a49301eSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 204a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21af69d88dSmrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 224a49301eSmrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 234a49301eSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 244a49301eSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 254a49301eSmrg * 264a49301eSmrg **************************************************************************/ 274a49301eSmrg 284a49301eSmrg#include "util/u_debug.h" 294a49301eSmrg#include "pipe/p_shader_tokens.h" 3001e04c3fSmrg#include "tgsi_info.h" 314a49301eSmrg#include "tgsi_parse.h" 324a49301eSmrg#include "tgsi_util.h" 3301e04c3fSmrg#include "tgsi_exec.h" 3401e04c3fSmrg#include "util/bitscan.h" 354a49301eSmrg 364a49301eSmrgunion pointer_hack 374a49301eSmrg{ 384a49301eSmrg void *pointer; 394a49301eSmrg uint64_t uint64; 404a49301eSmrg}; 414a49301eSmrg 424a49301eSmrgvoid * 4301e04c3fSmrgtgsi_align_128bit(void *unaligned) 444a49301eSmrg{ 454a49301eSmrg union pointer_hack ph; 464a49301eSmrg 474a49301eSmrg ph.uint64 = 0; 484a49301eSmrg ph.pointer = unaligned; 494a49301eSmrg ph.uint64 = (ph.uint64 + 15) & ~15; 504a49301eSmrg return ph.pointer; 514a49301eSmrg} 524a49301eSmrg 534a49301eSmrgunsigned 5401e04c3fSmrgtgsi_util_get_src_register_swizzle(const struct tgsi_src_register *reg, 5501e04c3fSmrg unsigned component) 564a49301eSmrg{ 5701e04c3fSmrg switch (component) { 5801e04c3fSmrg case TGSI_CHAN_X: 594a49301eSmrg return reg->SwizzleX; 6001e04c3fSmrg case TGSI_CHAN_Y: 614a49301eSmrg return reg->SwizzleY; 6201e04c3fSmrg case TGSI_CHAN_Z: 634a49301eSmrg return reg->SwizzleZ; 6401e04c3fSmrg case TGSI_CHAN_W: 654a49301eSmrg return reg->SwizzleW; 664a49301eSmrg default: 6701e04c3fSmrg assert(0); 684a49301eSmrg } 694a49301eSmrg return 0; 704a49301eSmrg} 714a49301eSmrg 724a49301eSmrg 734a49301eSmrgunsigned 744a49301eSmrgtgsi_util_get_full_src_register_swizzle( 7501e04c3fSmrg const struct tgsi_full_src_register *reg, 7601e04c3fSmrg unsigned component) 774a49301eSmrg{ 7801e04c3fSmrg return tgsi_util_get_src_register_swizzle(®->Register, component); 794a49301eSmrg} 804a49301eSmrg 8101e04c3fSmrg 824a49301eSmrgvoid 8301e04c3fSmrgtgsi_util_set_src_register_swizzle(struct tgsi_src_register *reg, 8401e04c3fSmrg unsigned swizzle, 8501e04c3fSmrg unsigned component) 864a49301eSmrg{ 8701e04c3fSmrg switch (component) { 884a49301eSmrg case 0: 894a49301eSmrg reg->SwizzleX = swizzle; 904a49301eSmrg break; 914a49301eSmrg case 1: 924a49301eSmrg reg->SwizzleY = swizzle; 934a49301eSmrg break; 944a49301eSmrg case 2: 954a49301eSmrg reg->SwizzleZ = swizzle; 964a49301eSmrg break; 974a49301eSmrg case 3: 984a49301eSmrg reg->SwizzleW = swizzle; 994a49301eSmrg break; 1004a49301eSmrg default: 10101e04c3fSmrg assert(0); 1024a49301eSmrg } 1034a49301eSmrg} 1044a49301eSmrg 10501e04c3fSmrg 1063464ebd5Sriastradh/** 1073464ebd5Sriastradh * Determine which channels of the specificed src register are effectively 1083464ebd5Sriastradh * used by this instruction. 1093464ebd5Sriastradh */ 1103464ebd5Sriastradhunsigned 1113464ebd5Sriastradhtgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst, 1123464ebd5Sriastradh unsigned src_idx) 1133464ebd5Sriastradh{ 1143464ebd5Sriastradh const struct tgsi_full_src_register *src = &inst->Src[src_idx]; 1153464ebd5Sriastradh unsigned write_mask = inst->Dst[0].Register.WriteMask; 1163464ebd5Sriastradh unsigned read_mask; 1173464ebd5Sriastradh unsigned usage_mask; 1183464ebd5Sriastradh unsigned chan; 1193464ebd5Sriastradh 1203464ebd5Sriastradh switch (inst->Instruction.Opcode) { 12101e04c3fSmrg case TGSI_OPCODE_IF: 12201e04c3fSmrg case TGSI_OPCODE_UIF: 12301e04c3fSmrg case TGSI_OPCODE_EMIT: 12401e04c3fSmrg case TGSI_OPCODE_ENDPRIM: 1253464ebd5Sriastradh case TGSI_OPCODE_RCP: 12601e04c3fSmrg case TGSI_OPCODE_RSQ: 12701e04c3fSmrg case TGSI_OPCODE_SQRT: 1283464ebd5Sriastradh case TGSI_OPCODE_EX2: 1293464ebd5Sriastradh case TGSI_OPCODE_LG2: 13001e04c3fSmrg case TGSI_OPCODE_SIN: 13101e04c3fSmrg case TGSI_OPCODE_COS: 13201e04c3fSmrg case TGSI_OPCODE_POW: /* reads src0.x and src1.x */ 13301e04c3fSmrg case TGSI_OPCODE_UP2H: 13401e04c3fSmrg case TGSI_OPCODE_UP2US: 13501e04c3fSmrg case TGSI_OPCODE_UP4B: 13601e04c3fSmrg case TGSI_OPCODE_UP4UB: 13701e04c3fSmrg case TGSI_OPCODE_MEMBAR: 13801e04c3fSmrg case TGSI_OPCODE_BALLOT: 1393464ebd5Sriastradh read_mask = TGSI_WRITEMASK_X; 1403464ebd5Sriastradh break; 1413464ebd5Sriastradh 14201e04c3fSmrg case TGSI_OPCODE_DP2: 14301e04c3fSmrg case TGSI_OPCODE_PK2H: 14401e04c3fSmrg case TGSI_OPCODE_PK2US: 14501e04c3fSmrg case TGSI_OPCODE_DFRACEXP: 14601e04c3fSmrg case TGSI_OPCODE_F2D: 14701e04c3fSmrg case TGSI_OPCODE_I2D: 14801e04c3fSmrg case TGSI_OPCODE_U2D: 14901e04c3fSmrg case TGSI_OPCODE_F2U64: 15001e04c3fSmrg case TGSI_OPCODE_F2I64: 15101e04c3fSmrg case TGSI_OPCODE_U2I64: 15201e04c3fSmrg case TGSI_OPCODE_I2I64: 15301e04c3fSmrg case TGSI_OPCODE_TXQS: /* bindless handle possible */ 15401e04c3fSmrg case TGSI_OPCODE_RESQ: /* bindless handle possible */ 15501e04c3fSmrg read_mask = TGSI_WRITEMASK_XY; 15601e04c3fSmrg break; 15701e04c3fSmrg 15801e04c3fSmrg case TGSI_OPCODE_TXQ: 15901e04c3fSmrg if (src_idx == 0) 16001e04c3fSmrg read_mask = TGSI_WRITEMASK_X; 16101e04c3fSmrg else 16201e04c3fSmrg read_mask = TGSI_WRITEMASK_XY; /* bindless handle possible */ 16301e04c3fSmrg break; 16401e04c3fSmrg 16501e04c3fSmrg case TGSI_OPCODE_DP3: 16601e04c3fSmrg read_mask = TGSI_WRITEMASK_XYZ; 16701e04c3fSmrg break; 16801e04c3fSmrg 16901e04c3fSmrg case TGSI_OPCODE_DSEQ: 17001e04c3fSmrg case TGSI_OPCODE_DSNE: 17101e04c3fSmrg case TGSI_OPCODE_DSLT: 17201e04c3fSmrg case TGSI_OPCODE_DSGE: 17301e04c3fSmrg case TGSI_OPCODE_DP4: 17401e04c3fSmrg case TGSI_OPCODE_PK4B: 17501e04c3fSmrg case TGSI_OPCODE_PK4UB: 17601e04c3fSmrg case TGSI_OPCODE_D2F: 17701e04c3fSmrg case TGSI_OPCODE_D2I: 17801e04c3fSmrg case TGSI_OPCODE_D2U: 17901e04c3fSmrg case TGSI_OPCODE_I2F: 18001e04c3fSmrg case TGSI_OPCODE_U2F: 18101e04c3fSmrg case TGSI_OPCODE_U64SEQ: 18201e04c3fSmrg case TGSI_OPCODE_U64SNE: 18301e04c3fSmrg case TGSI_OPCODE_U64SLT: 18401e04c3fSmrg case TGSI_OPCODE_U64SGE: 18501e04c3fSmrg case TGSI_OPCODE_U642F: 18601e04c3fSmrg case TGSI_OPCODE_I64SLT: 18701e04c3fSmrg case TGSI_OPCODE_I64SGE: 18801e04c3fSmrg case TGSI_OPCODE_I642F: 18901e04c3fSmrg read_mask = TGSI_WRITEMASK_XYZW; 19001e04c3fSmrg break; 19101e04c3fSmrg 19201e04c3fSmrg case TGSI_OPCODE_LIT: 19301e04c3fSmrg read_mask = write_mask & TGSI_WRITEMASK_YZ ? 19401e04c3fSmrg TGSI_WRITEMASK_XY | TGSI_WRITEMASK_W : 0; 1953464ebd5Sriastradh break; 1963464ebd5Sriastradh 1973464ebd5Sriastradh case TGSI_OPCODE_EXP: 1983464ebd5Sriastradh case TGSI_OPCODE_LOG: 1993464ebd5Sriastradh read_mask = write_mask & TGSI_WRITEMASK_XYZ ? TGSI_WRITEMASK_X : 0; 2003464ebd5Sriastradh break; 2013464ebd5Sriastradh 20201e04c3fSmrg case TGSI_OPCODE_DST: 20301e04c3fSmrg if (src_idx == 0) 20401e04c3fSmrg read_mask = TGSI_WRITEMASK_YZ; 20501e04c3fSmrg else 20601e04c3fSmrg read_mask = TGSI_WRITEMASK_YW; 2073464ebd5Sriastradh break; 2083464ebd5Sriastradh 20901e04c3fSmrg case TGSI_OPCODE_DLDEXP: 21001e04c3fSmrg if (src_idx == 0) { 21101e04c3fSmrg read_mask = write_mask; 21201e04c3fSmrg } else { 21301e04c3fSmrg read_mask = 21401e04c3fSmrg (write_mask & TGSI_WRITEMASK_XY ? TGSI_WRITEMASK_X : 0) | 21501e04c3fSmrg (write_mask & TGSI_WRITEMASK_ZW ? TGSI_WRITEMASK_Z : 0); 21601e04c3fSmrg } 2173464ebd5Sriastradh break; 2183464ebd5Sriastradh 21901e04c3fSmrg case TGSI_OPCODE_READ_INVOC: 22001e04c3fSmrg if (src_idx == 0) 22101e04c3fSmrg read_mask = write_mask; 22201e04c3fSmrg else 22301e04c3fSmrg read_mask = TGSI_WRITEMASK_X; 2243464ebd5Sriastradh break; 2253464ebd5Sriastradh 22601e04c3fSmrg case TGSI_OPCODE_FBFETCH: 22701e04c3fSmrg read_mask = 0; /* not a real register read */ 2283464ebd5Sriastradh break; 2293464ebd5Sriastradh 2303464ebd5Sriastradh case TGSI_OPCODE_TEX: 23101e04c3fSmrg case TGSI_OPCODE_TEX_LZ: 23201e04c3fSmrg case TGSI_OPCODE_TXF_LZ: 23301e04c3fSmrg case TGSI_OPCODE_TXF: 2343464ebd5Sriastradh case TGSI_OPCODE_TXB: 2353464ebd5Sriastradh case TGSI_OPCODE_TXL: 2363464ebd5Sriastradh case TGSI_OPCODE_TXP: 23701e04c3fSmrg case TGSI_OPCODE_TXD: 23801e04c3fSmrg case TGSI_OPCODE_TEX2: 23901e04c3fSmrg case TGSI_OPCODE_TXB2: 24001e04c3fSmrg case TGSI_OPCODE_TXL2: 24101e04c3fSmrg case TGSI_OPCODE_LODQ: 24201e04c3fSmrg case TGSI_OPCODE_TG4: { 24301e04c3fSmrg unsigned dim_layer = 24401e04c3fSmrg tgsi_util_get_texture_coord_dim(inst->Texture.Texture); 24501e04c3fSmrg unsigned dim_layer_shadow, dim; 24601e04c3fSmrg 24701e04c3fSmrg /* Add shadow. */ 24801e04c3fSmrg if (tgsi_is_shadow_target(inst->Texture.Texture)) { 24901e04c3fSmrg dim_layer_shadow = dim_layer + 1; 25001e04c3fSmrg if (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D) 25101e04c3fSmrg dim_layer_shadow = 3; 25201e04c3fSmrg } else { 25301e04c3fSmrg dim_layer_shadow = dim_layer; 25401e04c3fSmrg } 25501e04c3fSmrg 25601e04c3fSmrg /* Remove layer. */ 25701e04c3fSmrg if (tgsi_is_array_sampler(inst->Texture.Texture)) 25801e04c3fSmrg dim = dim_layer - 1; 25901e04c3fSmrg else 26001e04c3fSmrg dim = dim_layer; 26101e04c3fSmrg 26201e04c3fSmrg read_mask = TGSI_WRITEMASK_XY; /* bindless handle in the last operand */ 26301e04c3fSmrg 26401e04c3fSmrg switch (src_idx) { 26501e04c3fSmrg case 0: 26601e04c3fSmrg if (inst->Instruction.Opcode == TGSI_OPCODE_LODQ) 26701e04c3fSmrg read_mask = u_bit_consecutive(0, dim); 26801e04c3fSmrg else 26901e04c3fSmrg read_mask = u_bit_consecutive(0, dim_layer_shadow) & 0xf; 27001e04c3fSmrg 27101e04c3fSmrg if (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D) 27201e04c3fSmrg read_mask &= ~TGSI_WRITEMASK_Y; 27301e04c3fSmrg 27401e04c3fSmrg if (inst->Instruction.Opcode == TGSI_OPCODE_TXF || 27501e04c3fSmrg inst->Instruction.Opcode == TGSI_OPCODE_TXB || 27601e04c3fSmrg inst->Instruction.Opcode == TGSI_OPCODE_TXL || 27701e04c3fSmrg inst->Instruction.Opcode == TGSI_OPCODE_TXP) 2783464ebd5Sriastradh read_mask |= TGSI_WRITEMASK_W; 27901e04c3fSmrg break; 28001e04c3fSmrg 28101e04c3fSmrg case 1: 28201e04c3fSmrg if (inst->Instruction.Opcode == TGSI_OPCODE_TXD) 28301e04c3fSmrg read_mask = u_bit_consecutive(0, dim); 28401e04c3fSmrg else if (inst->Instruction.Opcode == TGSI_OPCODE_TEX2 || 28501e04c3fSmrg inst->Instruction.Opcode == TGSI_OPCODE_TXB2 || 28601e04c3fSmrg inst->Instruction.Opcode == TGSI_OPCODE_TXL2 || 28701e04c3fSmrg inst->Instruction.Opcode == TGSI_OPCODE_TG4) 28801e04c3fSmrg read_mask = TGSI_WRITEMASK_X; 28901e04c3fSmrg break; 29001e04c3fSmrg 29101e04c3fSmrg case 2: 29201e04c3fSmrg if (inst->Instruction.Opcode == TGSI_OPCODE_TXD) 29301e04c3fSmrg read_mask = u_bit_consecutive(0, dim); 29401e04c3fSmrg break; 29501e04c3fSmrg } 29601e04c3fSmrg break; 29701e04c3fSmrg } 29801e04c3fSmrg 29901e04c3fSmrg case TGSI_OPCODE_LOAD: 30001e04c3fSmrg if (src_idx == 0) { 30101e04c3fSmrg read_mask = TGSI_WRITEMASK_XY; /* bindless handle possible */ 30201e04c3fSmrg } else { 30301e04c3fSmrg unsigned dim = tgsi_util_get_texture_coord_dim(inst->Memory.Texture); 30401e04c3fSmrg read_mask = u_bit_consecutive(0, dim); 30501e04c3fSmrg } 30601e04c3fSmrg break; 30701e04c3fSmrg 30801e04c3fSmrg case TGSI_OPCODE_STORE: 30901e04c3fSmrg if (src_idx == 0) { 31001e04c3fSmrg unsigned dim = tgsi_util_get_texture_coord_dim(inst->Memory.Texture); 31101e04c3fSmrg read_mask = u_bit_consecutive(0, dim); 31201e04c3fSmrg } else { 31301e04c3fSmrg read_mask = TGSI_WRITEMASK_XYZW; 31401e04c3fSmrg } 31501e04c3fSmrg break; 31601e04c3fSmrg 31701e04c3fSmrg case TGSI_OPCODE_ATOMUADD: 31801e04c3fSmrg case TGSI_OPCODE_ATOMXCHG: 31901e04c3fSmrg case TGSI_OPCODE_ATOMCAS: 32001e04c3fSmrg case TGSI_OPCODE_ATOMAND: 32101e04c3fSmrg case TGSI_OPCODE_ATOMOR: 32201e04c3fSmrg case TGSI_OPCODE_ATOMXOR: 32301e04c3fSmrg case TGSI_OPCODE_ATOMUMIN: 32401e04c3fSmrg case TGSI_OPCODE_ATOMUMAX: 32501e04c3fSmrg case TGSI_OPCODE_ATOMIMIN: 32601e04c3fSmrg case TGSI_OPCODE_ATOMIMAX: 327361fc4cbSmaya case TGSI_OPCODE_ATOMFADD: 32801e04c3fSmrg if (src_idx == 0) { 32901e04c3fSmrg read_mask = TGSI_WRITEMASK_XY; /* bindless handle possible */ 33001e04c3fSmrg } else if (src_idx == 1) { 33101e04c3fSmrg unsigned dim = tgsi_util_get_texture_coord_dim(inst->Memory.Texture); 33201e04c3fSmrg read_mask = u_bit_consecutive(0, dim); 3333464ebd5Sriastradh } else { 3343464ebd5Sriastradh read_mask = TGSI_WRITEMASK_XYZW; 3353464ebd5Sriastradh } 3363464ebd5Sriastradh break; 3373464ebd5Sriastradh 33801e04c3fSmrg case TGSI_OPCODE_INTERP_CENTROID: 33901e04c3fSmrg case TGSI_OPCODE_INTERP_SAMPLE: 34001e04c3fSmrg case TGSI_OPCODE_INTERP_OFFSET: 34101e04c3fSmrg if (src_idx == 0) 34201e04c3fSmrg read_mask = write_mask; 34301e04c3fSmrg else if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_OFFSET) 34401e04c3fSmrg read_mask = TGSI_WRITEMASK_XY; /* offset */ 34501e04c3fSmrg else 34601e04c3fSmrg read_mask = TGSI_WRITEMASK_X; /* sample */ 34701e04c3fSmrg break; 34801e04c3fSmrg 3493464ebd5Sriastradh default: 35001e04c3fSmrg if (tgsi_get_opcode_info(inst->Instruction.Opcode)->output_mode == 35101e04c3fSmrg TGSI_OUTPUT_COMPONENTWISE) 35201e04c3fSmrg read_mask = write_mask; 35301e04c3fSmrg else 35401e04c3fSmrg read_mask = TGSI_WRITEMASK_XYZW; /* assume all channels are read */ 3553464ebd5Sriastradh break; 3563464ebd5Sriastradh } 3573464ebd5Sriastradh 3583464ebd5Sriastradh usage_mask = 0; 3593464ebd5Sriastradh for (chan = 0; chan < 4; ++chan) { 3603464ebd5Sriastradh if (read_mask & (1 << chan)) { 3613464ebd5Sriastradh usage_mask |= 1 << tgsi_util_get_full_src_register_swizzle(src, chan); 3623464ebd5Sriastradh } 3633464ebd5Sriastradh } 3643464ebd5Sriastradh 3653464ebd5Sriastradh return usage_mask; 3663464ebd5Sriastradh} 367af69d88dSmrg 368af69d88dSmrg/** 369af69d88dSmrg * Convert a tgsi_ind_register into a tgsi_src_register 370af69d88dSmrg */ 371af69d88dSmrgstruct tgsi_src_register 372af69d88dSmrgtgsi_util_get_src_from_ind(const struct tgsi_ind_register *reg) 373af69d88dSmrg{ 374af69d88dSmrg struct tgsi_src_register src = { 0 }; 375af69d88dSmrg 376af69d88dSmrg src.File = reg->File; 377af69d88dSmrg src.Index = reg->Index; 378af69d88dSmrg src.SwizzleX = reg->Swizzle; 379af69d88dSmrg src.SwizzleY = reg->Swizzle; 380af69d88dSmrg src.SwizzleZ = reg->Swizzle; 381af69d88dSmrg src.SwizzleW = reg->Swizzle; 382af69d88dSmrg 383af69d88dSmrg return src; 384af69d88dSmrg} 385af69d88dSmrg 386af69d88dSmrg/** 387af69d88dSmrg * Return the dimension of the texture coordinates (layer included for array 388af69d88dSmrg * textures), as well as the location of the shadow reference value or the 389af69d88dSmrg * sample index. 390af69d88dSmrg */ 391af69d88dSmrgint 39201e04c3fSmrgtgsi_util_get_texture_coord_dim(enum tgsi_texture_type tgsi_tex) 393af69d88dSmrg{ 394af69d88dSmrg /* 395af69d88dSmrg * Depending on the texture target, (src0.xyzw, src1.x) is interpreted 396af69d88dSmrg * differently: 397af69d88dSmrg * 398af69d88dSmrg * (s, X, X, X, X), for BUFFER 399af69d88dSmrg * (s, X, X, X, X), for 1D 400af69d88dSmrg * (s, t, X, X, X), for 2D, RECT 401af69d88dSmrg * (s, t, r, X, X), for 3D, CUBE 402af69d88dSmrg * 403af69d88dSmrg * (s, layer, X, X, X), for 1D_ARRAY 404af69d88dSmrg * (s, t, layer, X, X), for 2D_ARRAY 405af69d88dSmrg * (s, t, r, layer, X), for CUBE_ARRAY 406af69d88dSmrg * 407af69d88dSmrg * (s, X, shadow, X, X), for SHADOW1D 408af69d88dSmrg * (s, t, shadow, X, X), for SHADOW2D, SHADOWRECT 409af69d88dSmrg * (s, t, r, shadow, X), for SHADOWCUBE 410af69d88dSmrg * 411af69d88dSmrg * (s, layer, shadow, X, X), for SHADOW1D_ARRAY 412af69d88dSmrg * (s, t, layer, shadow, X), for SHADOW2D_ARRAY 413af69d88dSmrg * (s, t, r, layer, shadow), for SHADOWCUBE_ARRAY 414af69d88dSmrg * 415af69d88dSmrg * (s, t, sample, X, X), for 2D_MSAA 416af69d88dSmrg * (s, t, layer, sample, X), for 2D_ARRAY_MSAA 417af69d88dSmrg */ 418af69d88dSmrg switch (tgsi_tex) { 419af69d88dSmrg case TGSI_TEXTURE_BUFFER: 420af69d88dSmrg case TGSI_TEXTURE_1D: 421af69d88dSmrg case TGSI_TEXTURE_SHADOW1D: 42201e04c3fSmrg return 1; 423af69d88dSmrg case TGSI_TEXTURE_2D: 424af69d88dSmrg case TGSI_TEXTURE_RECT: 425af69d88dSmrg case TGSI_TEXTURE_1D_ARRAY: 426af69d88dSmrg case TGSI_TEXTURE_SHADOW2D: 427af69d88dSmrg case TGSI_TEXTURE_SHADOWRECT: 428af69d88dSmrg case TGSI_TEXTURE_SHADOW1D_ARRAY: 429af69d88dSmrg case TGSI_TEXTURE_2D_MSAA: 43001e04c3fSmrg return 2; 431af69d88dSmrg case TGSI_TEXTURE_3D: 432af69d88dSmrg case TGSI_TEXTURE_CUBE: 433af69d88dSmrg case TGSI_TEXTURE_2D_ARRAY: 434af69d88dSmrg case TGSI_TEXTURE_SHADOWCUBE: 435af69d88dSmrg case TGSI_TEXTURE_SHADOW2D_ARRAY: 436af69d88dSmrg case TGSI_TEXTURE_2D_ARRAY_MSAA: 43701e04c3fSmrg return 3; 438af69d88dSmrg case TGSI_TEXTURE_CUBE_ARRAY: 439af69d88dSmrg case TGSI_TEXTURE_SHADOWCUBE_ARRAY: 44001e04c3fSmrg return 4; 441af69d88dSmrg default: 442af69d88dSmrg assert(!"unknown texture target"); 44301e04c3fSmrg return 0; 444af69d88dSmrg } 44501e04c3fSmrg} 446af69d88dSmrg 44701e04c3fSmrg 44801e04c3fSmrg/** 44901e04c3fSmrg * Given a TGSI_TEXTURE_x target, return register component where the 45001e04c3fSmrg * shadow reference/distance coordinate is found. Typically, components 45101e04c3fSmrg * 0 and 1 are the (s,t) texcoords and component 2 or 3 hold the shadow 45201e04c3fSmrg * reference value. But if we return 4, it means the reference value is 45301e04c3fSmrg * found in the 0th component of the second coordinate argument to the 45401e04c3fSmrg * TEX2 instruction. 45501e04c3fSmrg */ 45601e04c3fSmrgint 45701e04c3fSmrgtgsi_util_get_shadow_ref_src_index(enum tgsi_texture_type tgsi_tex) 45801e04c3fSmrg{ 45901e04c3fSmrg switch (tgsi_tex) { 46001e04c3fSmrg case TGSI_TEXTURE_SHADOW1D: 46101e04c3fSmrg case TGSI_TEXTURE_SHADOW2D: 46201e04c3fSmrg case TGSI_TEXTURE_SHADOWRECT: 46301e04c3fSmrg case TGSI_TEXTURE_SHADOW1D_ARRAY: 46401e04c3fSmrg return 2; 46501e04c3fSmrg case TGSI_TEXTURE_SHADOWCUBE: 46601e04c3fSmrg case TGSI_TEXTURE_SHADOW2D_ARRAY: 46701e04c3fSmrg case TGSI_TEXTURE_2D_MSAA: 46801e04c3fSmrg case TGSI_TEXTURE_2D_ARRAY_MSAA: 46901e04c3fSmrg return 3; 47001e04c3fSmrg case TGSI_TEXTURE_SHADOWCUBE_ARRAY: 47101e04c3fSmrg return 4; 47201e04c3fSmrg default: 47301e04c3fSmrg /* no shadow nor sample */ 47401e04c3fSmrg return -1; 475af69d88dSmrg } 47601e04c3fSmrg} 47701e04c3fSmrg 478af69d88dSmrg 4797ec681f3Smrgbool 48001e04c3fSmrgtgsi_is_shadow_target(enum tgsi_texture_type target) 48101e04c3fSmrg{ 48201e04c3fSmrg switch (target) { 48301e04c3fSmrg case TGSI_TEXTURE_SHADOW1D: 48401e04c3fSmrg case TGSI_TEXTURE_SHADOW2D: 48501e04c3fSmrg case TGSI_TEXTURE_SHADOWRECT: 48601e04c3fSmrg case TGSI_TEXTURE_SHADOW1D_ARRAY: 48701e04c3fSmrg case TGSI_TEXTURE_SHADOW2D_ARRAY: 48801e04c3fSmrg case TGSI_TEXTURE_SHADOWCUBE: 48901e04c3fSmrg case TGSI_TEXTURE_SHADOWCUBE_ARRAY: 49001e04c3fSmrg return TRUE; 49101e04c3fSmrg default: 49201e04c3fSmrg return FALSE; 49301e04c3fSmrg } 494af69d88dSmrg} 495