Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  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 TUNGSTEN GRAPHICS 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_CND:
  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.       /* Channel-wise operations */
  221.       read_mask = write_mask;
  222.       break;
  223.  
  224.    case TGSI_OPCODE_EX2:
  225.    case TGSI_OPCODE_LG2:
  226.    case TGSI_OPCODE_RCC:
  227.       read_mask = TGSI_WRITEMASK_X;
  228.       break;
  229.  
  230.    case TGSI_OPCODE_SCS:
  231.       read_mask = write_mask & TGSI_WRITEMASK_XY ? TGSI_WRITEMASK_X : 0;
  232.       break;
  233.  
  234.    case TGSI_OPCODE_EXP:
  235.    case TGSI_OPCODE_LOG:
  236.       read_mask = write_mask & TGSI_WRITEMASK_XYZ ? TGSI_WRITEMASK_X : 0;
  237.       break;
  238.  
  239.    case TGSI_OPCODE_DP2A:
  240.       read_mask = src_idx == 2 ? TGSI_WRITEMASK_X : TGSI_WRITEMASK_XY;
  241.       break;
  242.  
  243.    case TGSI_OPCODE_DP2:
  244.       read_mask = TGSI_WRITEMASK_XY;
  245.       break;
  246.  
  247.    case TGSI_OPCODE_DP3:
  248.       read_mask = TGSI_WRITEMASK_XYZ;
  249.       break;
  250.  
  251.    case TGSI_OPCODE_DP4:
  252.       read_mask = TGSI_WRITEMASK_XYZW;
  253.       break;
  254.  
  255.    case TGSI_OPCODE_DPH:
  256.       read_mask = src_idx == 0 ? TGSI_WRITEMASK_XYZ : TGSI_WRITEMASK_XYZW;
  257.       break;
  258.  
  259.    case TGSI_OPCODE_TEX:
  260.    case TGSI_OPCODE_TXD:
  261.    case TGSI_OPCODE_TXB:
  262.    case TGSI_OPCODE_TXL:
  263.    case TGSI_OPCODE_TXP:
  264.       if (src_idx == 0) {
  265.          /* Note that the SHADOW variants use the Z component too */
  266.          switch (inst->Texture.Texture) {
  267.          case TGSI_TEXTURE_1D:
  268.             read_mask = TGSI_WRITEMASK_X;
  269.             break;
  270.          case TGSI_TEXTURE_SHADOW1D:
  271.             read_mask = TGSI_WRITEMASK_XZ;
  272.             break;
  273.          case TGSI_TEXTURE_1D_ARRAY:
  274.          case TGSI_TEXTURE_2D:
  275.          case TGSI_TEXTURE_RECT:
  276.             read_mask = TGSI_WRITEMASK_XY;
  277.             break;
  278.          case TGSI_TEXTURE_SHADOW1D_ARRAY:
  279.          case TGSI_TEXTURE_SHADOW2D:
  280.          case TGSI_TEXTURE_SHADOWRECT:
  281.          case TGSI_TEXTURE_2D_ARRAY:
  282.          case TGSI_TEXTURE_3D:
  283.          case TGSI_TEXTURE_CUBE:
  284.          case TGSI_TEXTURE_2D_MSAA:
  285.             read_mask = TGSI_WRITEMASK_XYZ;
  286.             break;
  287.          case TGSI_TEXTURE_SHADOW2D_ARRAY:
  288.          case TGSI_TEXTURE_CUBE_ARRAY:
  289.          case TGSI_TEXTURE_SHADOWCUBE:
  290.          case TGSI_TEXTURE_2D_ARRAY_MSAA:
  291.          case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
  292.             read_mask = TGSI_WRITEMASK_XYZW;
  293.             break;
  294.          default:
  295.             assert(0);
  296.             read_mask = 0;
  297.          }
  298.  
  299.          if (inst->Instruction.Opcode != TGSI_OPCODE_TEX) {
  300.             read_mask |= TGSI_WRITEMASK_W;
  301.          }
  302.       } else {
  303.          /* A safe approximation */
  304.          read_mask = TGSI_WRITEMASK_XYZW;
  305.       }
  306.       break;
  307.  
  308.    default:
  309.       /* Assume all channels are read */
  310.       read_mask = TGSI_WRITEMASK_XYZW;
  311.       break;
  312.    }
  313.  
  314.    usage_mask = 0;
  315.    for (chan = 0; chan < 4; ++chan) {
  316.       if (read_mask & (1 << chan)) {
  317.          usage_mask |= 1 << tgsi_util_get_full_src_register_swizzle(src, chan);
  318.       }
  319.    }
  320.  
  321.    return usage_mask;
  322. }
  323.  
  324. /**
  325.  * Convert a tgsi_ind_register into a tgsi_src_register
  326.  */
  327. struct tgsi_src_register
  328. tgsi_util_get_src_from_ind(const struct tgsi_ind_register *reg)
  329. {
  330.    struct tgsi_src_register src = { 0 };
  331.  
  332.    src.File = reg->File;
  333.    src.Index = reg->Index;
  334.    src.SwizzleX = reg->Swizzle;
  335.    src.SwizzleY = reg->Swizzle;
  336.    src.SwizzleZ = reg->Swizzle;
  337.    src.SwizzleW = reg->Swizzle;
  338.  
  339.    return src;
  340. }
  341.  
  342. /**
  343.  * Return the dimension of the texture coordinates (layer included for array
  344.  * textures), as well as the location of the shadow reference value or the
  345.  * sample index.
  346.  */
  347. int
  348. tgsi_util_get_texture_coord_dim(int tgsi_tex, int *shadow_or_sample)
  349. {
  350.    int dim;
  351.  
  352.    /*
  353.     * Depending on the texture target, (src0.xyzw, src1.x) is interpreted
  354.     * differently:
  355.     *
  356.     *   (s, X, X, X, X),               for BUFFER
  357.     *   (s, X, X, X, X),               for 1D
  358.     *   (s, t, X, X, X),               for 2D, RECT
  359.     *   (s, t, r, X, X),               for 3D, CUBE
  360.     *
  361.     *   (s, layer, X, X, X),           for 1D_ARRAY
  362.     *   (s, t, layer, X, X),           for 2D_ARRAY
  363.     *   (s, t, r, layer, X),           for CUBE_ARRAY
  364.     *
  365.     *   (s, X, shadow, X, X),          for SHADOW1D
  366.     *   (s, t, shadow, X, X),          for SHADOW2D, SHADOWRECT
  367.     *   (s, t, r, shadow, X),          for SHADOWCUBE
  368.     *
  369.     *   (s, layer, shadow, X, X),      for SHADOW1D_ARRAY
  370.     *   (s, t, layer, shadow, X),      for SHADOW2D_ARRAY
  371.     *   (s, t, r, layer, shadow),      for SHADOWCUBE_ARRAY
  372.     *
  373.     *   (s, t, sample, X, X),          for 2D_MSAA
  374.     *   (s, t, layer, sample, X),      for 2D_ARRAY_MSAA
  375.     */
  376.    switch (tgsi_tex) {
  377.    case TGSI_TEXTURE_BUFFER:
  378.    case TGSI_TEXTURE_1D:
  379.    case TGSI_TEXTURE_SHADOW1D:
  380.       dim = 1;
  381.       break;
  382.    case TGSI_TEXTURE_2D:
  383.    case TGSI_TEXTURE_RECT:
  384.    case TGSI_TEXTURE_1D_ARRAY:
  385.    case TGSI_TEXTURE_SHADOW2D:
  386.    case TGSI_TEXTURE_SHADOWRECT:
  387.    case TGSI_TEXTURE_SHADOW1D_ARRAY:
  388.    case TGSI_TEXTURE_2D_MSAA:
  389.       dim = 2;
  390.       break;
  391.    case TGSI_TEXTURE_3D:
  392.    case TGSI_TEXTURE_CUBE:
  393.    case TGSI_TEXTURE_2D_ARRAY:
  394.    case TGSI_TEXTURE_SHADOWCUBE:
  395.    case TGSI_TEXTURE_SHADOW2D_ARRAY:
  396.    case TGSI_TEXTURE_2D_ARRAY_MSAA:
  397.       dim = 3;
  398.       break;
  399.    case TGSI_TEXTURE_CUBE_ARRAY:
  400.    case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
  401.       dim = 4;
  402.       break;
  403.    default:
  404.       assert(!"unknown texture target");
  405.       dim = 0;
  406.       break;
  407.    }
  408.  
  409.    if (shadow_or_sample) {
  410.       switch (tgsi_tex) {
  411.       case TGSI_TEXTURE_SHADOW1D:
  412.          /* there is a gap */
  413.          *shadow_or_sample = 2;
  414.          break;
  415.       case TGSI_TEXTURE_SHADOW2D:
  416.       case TGSI_TEXTURE_SHADOWRECT:
  417.       case TGSI_TEXTURE_SHADOWCUBE:
  418.       case TGSI_TEXTURE_SHADOW1D_ARRAY:
  419.       case TGSI_TEXTURE_SHADOW2D_ARRAY:
  420.       case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
  421.       case TGSI_TEXTURE_2D_MSAA:
  422.       case TGSI_TEXTURE_2D_ARRAY_MSAA:
  423.          *shadow_or_sample = dim;
  424.          break;
  425.       default:
  426.          /* no shadow nor sample */
  427.          *shadow_or_sample = -1;
  428.          break;
  429.       }
  430.    }
  431.  
  432.    return dim;
  433. }
  434.