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(&reg->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