Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 VMware, Inc.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28. #include "util/u_debug.h"
  29. #include "pipe/p_shader_tokens.h"
  30. #include "tgsi_parse.h"
  31. #include "tgsi_util.h"
  32.  
  33. union pointer_hack
  34. {
  35.    void *pointer;
  36.    uint64_t uint64;
  37. };
  38.  
  39. void *
  40. tgsi_align_128bit(
  41.    void *unaligned )
  42. {
  43.    union pointer_hack ph;
  44.  
  45.    ph.uint64 = 0;
  46.    ph.pointer = unaligned;
  47.    ph.uint64 = (ph.uint64 + 15) & ~15;
  48.    return ph.pointer;
  49. }
  50.  
  51. unsigned
  52. tgsi_util_get_src_register_swizzle(
  53.    const struct tgsi_src_register *reg,
  54.    unsigned component )
  55. {
  56.    switch( component ) {
  57.    case 0:
  58.       return reg->SwizzleX;
  59.    case 1:
  60.       return reg->SwizzleY;
  61.    case 2:
  62.       return reg->SwizzleZ;
  63.    case 3:
  64.       return reg->SwizzleW;
  65.    default:
  66.       assert( 0 );
  67.    }
  68.    return 0;
  69. }
  70.  
  71.  
  72. unsigned
  73. tgsi_util_get_full_src_register_swizzle(
  74.    const struct tgsi_full_src_register  *reg,
  75.    unsigned component )
  76. {
  77.    return tgsi_util_get_src_register_swizzle(
  78.       &reg->Register,
  79.       component );
  80. }
  81.  
  82. void
  83. tgsi_util_set_src_register_swizzle(
  84.    struct tgsi_src_register *reg,
  85.    unsigned swizzle,
  86.    unsigned component )
  87. {
  88.    switch( component ) {
  89.    case 0:
  90.       reg->SwizzleX = swizzle;
  91.       break;
  92.    case 1:
  93.       reg->SwizzleY = swizzle;
  94.       break;
  95.    case 2:
  96.       reg->SwizzleZ = swizzle;
  97.       break;
  98.    case 3:
  99.       reg->SwizzleW = swizzle;
  100.       break;
  101.    default:
  102.       assert( 0 );
  103.    }
  104. }
  105.  
  106. unsigned
  107. tgsi_util_get_full_src_register_sign_mode(
  108.    const struct  tgsi_full_src_register *reg,
  109.    unsigned component )
  110. {
  111.    unsigned sign_mode;
  112.  
  113.    if( reg->Register.Absolute ) {
  114.       /* Consider only the post-abs negation. */
  115.  
  116.       if( reg->Register.Negate ) {
  117.          sign_mode = TGSI_UTIL_SIGN_SET;
  118.       }
  119.       else {
  120.          sign_mode = TGSI_UTIL_SIGN_CLEAR;
  121.       }
  122.    }
  123.    else {
  124.       if( reg->Register.Negate ) {
  125.          sign_mode = TGSI_UTIL_SIGN_TOGGLE;
  126.       }
  127.       else {
  128.          sign_mode = TGSI_UTIL_SIGN_KEEP;
  129.       }
  130.    }
  131.  
  132.    return sign_mode;
  133. }
  134.  
  135. void
  136. tgsi_util_set_full_src_register_sign_mode(
  137.    struct tgsi_full_src_register *reg,
  138.    unsigned sign_mode )
  139. {
  140.    switch (sign_mode)
  141.    {
  142.    case TGSI_UTIL_SIGN_CLEAR:
  143.       reg->Register.Negate = 0;
  144.       reg->Register.Absolute = 1;
  145.       break;
  146.  
  147.    case TGSI_UTIL_SIGN_SET:
  148.       reg->Register.Absolute = 1;
  149.       reg->Register.Negate = 1;
  150.       break;
  151.  
  152.    case TGSI_UTIL_SIGN_TOGGLE:
  153.       reg->Register.Negate = 1;
  154.       reg->Register.Absolute = 0;
  155.       break;
  156.  
  157.    case TGSI_UTIL_SIGN_KEEP:
  158.       reg->Register.Negate = 0;
  159.       reg->Register.Absolute = 0;
  160.       break;
  161.  
  162.    default:
  163.       assert( 0 );
  164.    }
  165. }
  166.  
  167. /**
  168.  * Determine which channels of the specificed src register are effectively
  169.  * used by this instruction.
  170.  */
  171. unsigned
  172. tgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst,
  173.                               unsigned src_idx)
  174. {
  175.    const struct tgsi_full_src_register *src = &inst->Src[src_idx];
  176.    unsigned write_mask = inst->Dst[0].Register.WriteMask;
  177.    unsigned read_mask;
  178.    unsigned usage_mask;
  179.    unsigned chan;
  180.  
  181.    switch (inst->Instruction.Opcode) {
  182.    case TGSI_OPCODE_MOV:
  183.    case TGSI_OPCODE_ARL:
  184.    case TGSI_OPCODE_ARR:
  185.    case TGSI_OPCODE_RCP:
  186.    case TGSI_OPCODE_MUL:
  187.    case TGSI_OPCODE_DIV:
  188.    case TGSI_OPCODE_ADD:
  189.    case TGSI_OPCODE_MIN:
  190.    case TGSI_OPCODE_MAX:
  191.    case TGSI_OPCODE_SLT:
  192.    case TGSI_OPCODE_SGE:
  193.    case TGSI_OPCODE_MAD:
  194.    case TGSI_OPCODE_SUB:
  195.    case TGSI_OPCODE_LRP:
  196.    case TGSI_OPCODE_FMA:
  197.    case TGSI_OPCODE_FRC:
  198.    case TGSI_OPCODE_CEIL:
  199.    case TGSI_OPCODE_CLAMP:
  200.    case TGSI_OPCODE_FLR:
  201.    case TGSI_OPCODE_ROUND:
  202.    case TGSI_OPCODE_POW:
  203.    case TGSI_OPCODE_ABS:
  204.    case TGSI_OPCODE_COS:
  205.    case TGSI_OPCODE_SIN:
  206.    case TGSI_OPCODE_DDX:
  207.    case TGSI_OPCODE_DDY:
  208.    case TGSI_OPCODE_SEQ:
  209.    case TGSI_OPCODE_SGT:
  210.    case TGSI_OPCODE_SLE:
  211.    case TGSI_OPCODE_SNE:
  212.    case TGSI_OPCODE_SSG:
  213.    case TGSI_OPCODE_CMP:
  214.    case TGSI_OPCODE_TRUNC:
  215.    case TGSI_OPCODE_NOT:
  216.    case TGSI_OPCODE_AND:
  217.    case TGSI_OPCODE_OR:
  218.    case TGSI_OPCODE_XOR:
  219.    case TGSI_OPCODE_SAD:
  220.    case TGSI_OPCODE_FSEQ:
  221.    case TGSI_OPCODE_FSGE:
  222.    case TGSI_OPCODE_FSLT:
  223.    case TGSI_OPCODE_FSNE:
  224.    case TGSI_OPCODE_F2I:
  225.    case TGSI_OPCODE_IDIV:
  226.    case TGSI_OPCODE_IMAX:
  227.    case TGSI_OPCODE_IMIN:
  228.    case TGSI_OPCODE_INEG:
  229.    case TGSI_OPCODE_ISGE:
  230.    case TGSI_OPCODE_ISHR:
  231.    case TGSI_OPCODE_ISLT:
  232.    case TGSI_OPCODE_F2U:
  233.    case TGSI_OPCODE_U2F:
  234.    case TGSI_OPCODE_UADD:
  235.    case TGSI_OPCODE_UDIV:
  236.    case TGSI_OPCODE_UMAD:
  237.    case TGSI_OPCODE_UMAX:
  238.    case TGSI_OPCODE_UMIN:
  239.    case TGSI_OPCODE_UMOD:
  240.    case TGSI_OPCODE_UMUL:
  241.    case TGSI_OPCODE_USEQ:
  242.    case TGSI_OPCODE_USGE:
  243.    case TGSI_OPCODE_USHR:
  244.    case TGSI_OPCODE_USLT:
  245.    case TGSI_OPCODE_USNE:
  246.    case TGSI_OPCODE_IMUL_HI:
  247.    case TGSI_OPCODE_UMUL_HI:
  248.    case TGSI_OPCODE_DDX_FINE:
  249.    case TGSI_OPCODE_DDY_FINE:
  250.       /* Channel-wise operations */
  251.       read_mask = write_mask;
  252.       break;
  253.  
  254.    case TGSI_OPCODE_EX2:
  255.    case TGSI_OPCODE_LG2:
  256.       read_mask = TGSI_WRITEMASK_X;
  257.       break;
  258.  
  259.    case TGSI_OPCODE_SCS:
  260.       read_mask = write_mask & TGSI_WRITEMASK_XY ? TGSI_WRITEMASK_X : 0;
  261.       break;
  262.  
  263.    case TGSI_OPCODE_EXP:
  264.    case TGSI_OPCODE_LOG:
  265.       read_mask = write_mask & TGSI_WRITEMASK_XYZ ? TGSI_WRITEMASK_X : 0;
  266.       break;
  267.  
  268.    case TGSI_OPCODE_DP2A:
  269.       read_mask = src_idx == 2 ? TGSI_WRITEMASK_X : TGSI_WRITEMASK_XY;
  270.       break;
  271.  
  272.    case TGSI_OPCODE_DP2:
  273.       read_mask = TGSI_WRITEMASK_XY;
  274.       break;
  275.  
  276.    case TGSI_OPCODE_DP3:
  277.       read_mask = TGSI_WRITEMASK_XYZ;
  278.       break;
  279.  
  280.    case TGSI_OPCODE_DP4:
  281.       read_mask = TGSI_WRITEMASK_XYZW;
  282.       break;
  283.  
  284.    case TGSI_OPCODE_DPH:
  285.       read_mask = src_idx == 0 ? TGSI_WRITEMASK_XYZ : TGSI_WRITEMASK_XYZW;
  286.       break;
  287.  
  288.    case TGSI_OPCODE_TEX:
  289.    case TGSI_OPCODE_TXD:
  290.    case TGSI_OPCODE_TXB:
  291.    case TGSI_OPCODE_TXL:
  292.    case TGSI_OPCODE_TXP:
  293.       if (src_idx == 0) {
  294.          /* Note that the SHADOW variants use the Z component too */
  295.          switch (inst->Texture.Texture) {
  296.          case TGSI_TEXTURE_1D:
  297.             read_mask = TGSI_WRITEMASK_X;
  298.             break;
  299.          case TGSI_TEXTURE_SHADOW1D:
  300.             read_mask = TGSI_WRITEMASK_XZ;
  301.             break;
  302.          case TGSI_TEXTURE_1D_ARRAY:
  303.          case TGSI_TEXTURE_2D:
  304.          case TGSI_TEXTURE_RECT:
  305.             read_mask = TGSI_WRITEMASK_XY;
  306.             break;
  307.          case TGSI_TEXTURE_SHADOW1D_ARRAY:
  308.          case TGSI_TEXTURE_SHADOW2D:
  309.          case TGSI_TEXTURE_SHADOWRECT:
  310.          case TGSI_TEXTURE_2D_ARRAY:
  311.          case TGSI_TEXTURE_3D:
  312.          case TGSI_TEXTURE_CUBE:
  313.          case TGSI_TEXTURE_2D_MSAA:
  314.             read_mask = TGSI_WRITEMASK_XYZ;
  315.             break;
  316.          case TGSI_TEXTURE_SHADOW2D_ARRAY:
  317.          case TGSI_TEXTURE_CUBE_ARRAY:
  318.          case TGSI_TEXTURE_SHADOWCUBE:
  319.          case TGSI_TEXTURE_2D_ARRAY_MSAA:
  320.          case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
  321.             read_mask = TGSI_WRITEMASK_XYZW;
  322.             break;
  323.          default:
  324.             assert(0);
  325.             read_mask = 0;
  326.          }
  327.  
  328.          if (inst->Instruction.Opcode != TGSI_OPCODE_TEX) {
  329.             read_mask |= TGSI_WRITEMASK_W;
  330.          }
  331.       } else {
  332.          /* A safe approximation */
  333.          read_mask = TGSI_WRITEMASK_XYZW;
  334.       }
  335.       break;
  336.  
  337.    default:
  338.       /* Assume all channels are read */
  339.       read_mask = TGSI_WRITEMASK_XYZW;
  340.       break;
  341.    }
  342.  
  343.    usage_mask = 0;
  344.    for (chan = 0; chan < 4; ++chan) {
  345.       if (read_mask & (1 << chan)) {
  346.          usage_mask |= 1 << tgsi_util_get_full_src_register_swizzle(src, chan);
  347.       }
  348.    }
  349.  
  350.    return usage_mask;
  351. }
  352.  
  353. /**
  354.  * Convert a tgsi_ind_register into a tgsi_src_register
  355.  */
  356. struct tgsi_src_register
  357. tgsi_util_get_src_from_ind(const struct tgsi_ind_register *reg)
  358. {
  359.    struct tgsi_src_register src = { 0 };
  360.  
  361.    src.File = reg->File;
  362.    src.Index = reg->Index;
  363.    src.SwizzleX = reg->Swizzle;
  364.    src.SwizzleY = reg->Swizzle;
  365.    src.SwizzleZ = reg->Swizzle;
  366.    src.SwizzleW = reg->Swizzle;
  367.  
  368.    return src;
  369. }
  370.  
  371. /**
  372.  * Return the dimension of the texture coordinates (layer included for array
  373.  * textures), as well as the location of the shadow reference value or the
  374.  * sample index.
  375.  */
  376. int
  377. tgsi_util_get_texture_coord_dim(int tgsi_tex, int *shadow_or_sample)
  378. {
  379.    int dim;
  380.  
  381.    /*
  382.     * Depending on the texture target, (src0.xyzw, src1.x) is interpreted
  383.     * differently:
  384.     *
  385.     *   (s, X, X, X, X),               for BUFFER
  386.     *   (s, X, X, X, X),               for 1D
  387.     *   (s, t, X, X, X),               for 2D, RECT
  388.     *   (s, t, r, X, X),               for 3D, CUBE
  389.     *
  390.     *   (s, layer, X, X, X),           for 1D_ARRAY
  391.     *   (s, t, layer, X, X),           for 2D_ARRAY
  392.     *   (s, t, r, layer, X),           for CUBE_ARRAY
  393.     *
  394.     *   (s, X, shadow, X, X),          for SHADOW1D
  395.     *   (s, t, shadow, X, X),          for SHADOW2D, SHADOWRECT
  396.     *   (s, t, r, shadow, X),          for SHADOWCUBE
  397.     *
  398.     *   (s, layer, shadow, X, X),      for SHADOW1D_ARRAY
  399.     *   (s, t, layer, shadow, X),      for SHADOW2D_ARRAY
  400.     *   (s, t, r, layer, shadow),      for SHADOWCUBE_ARRAY
  401.     *
  402.     *   (s, t, sample, X, X),          for 2D_MSAA
  403.     *   (s, t, layer, sample, X),      for 2D_ARRAY_MSAA
  404.     */
  405.    switch (tgsi_tex) {
  406.    case TGSI_TEXTURE_BUFFER:
  407.    case TGSI_TEXTURE_1D:
  408.    case TGSI_TEXTURE_SHADOW1D:
  409.       dim = 1;
  410.       break;
  411.    case TGSI_TEXTURE_2D:
  412.    case TGSI_TEXTURE_RECT:
  413.    case TGSI_TEXTURE_1D_ARRAY:
  414.    case TGSI_TEXTURE_SHADOW2D:
  415.    case TGSI_TEXTURE_SHADOWRECT:
  416.    case TGSI_TEXTURE_SHADOW1D_ARRAY:
  417.    case TGSI_TEXTURE_2D_MSAA:
  418.       dim = 2;
  419.       break;
  420.    case TGSI_TEXTURE_3D:
  421.    case TGSI_TEXTURE_CUBE:
  422.    case TGSI_TEXTURE_2D_ARRAY:
  423.    case TGSI_TEXTURE_SHADOWCUBE:
  424.    case TGSI_TEXTURE_SHADOW2D_ARRAY:
  425.    case TGSI_TEXTURE_2D_ARRAY_MSAA:
  426.       dim = 3;
  427.       break;
  428.    case TGSI_TEXTURE_CUBE_ARRAY:
  429.    case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
  430.       dim = 4;
  431.       break;
  432.    default:
  433.       assert(!"unknown texture target");
  434.       dim = 0;
  435.       break;
  436.    }
  437.  
  438.    if (shadow_or_sample) {
  439.       switch (tgsi_tex) {
  440.       case TGSI_TEXTURE_SHADOW1D:
  441.          /* there is a gap */
  442.          *shadow_or_sample = 2;
  443.          break;
  444.       case TGSI_TEXTURE_SHADOW2D:
  445.       case TGSI_TEXTURE_SHADOWRECT:
  446.       case TGSI_TEXTURE_SHADOWCUBE:
  447.       case TGSI_TEXTURE_SHADOW1D_ARRAY:
  448.       case TGSI_TEXTURE_SHADOW2D_ARRAY:
  449.       case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
  450.          *shadow_or_sample = dim;
  451.          break;
  452.       case TGSI_TEXTURE_2D_MSAA:
  453.       case TGSI_TEXTURE_2D_ARRAY_MSAA:
  454.          *shadow_or_sample = 3;
  455.          break;
  456.       default:
  457.          /* no shadow nor sample */
  458.          *shadow_or_sample = -1;
  459.          break;
  460.       }
  461.    }
  462.  
  463.    return dim;
  464. }
  465.