Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2012 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21.  * IN THE SOFTWARE.
  22.  */
  23.  
  24. /** @file brw_fs_fp.cpp
  25.  *
  26.  * Implementation of the compiler for GL_ARB_fragment_program shaders on top
  27.  * of the GLSL compiler backend.
  28.  */
  29.  
  30. #include "brw_context.h"
  31. #include "brw_fs.h"
  32.  
  33. void
  34. fs_visitor::emit_fp_alu1(enum opcode opcode,
  35.                          const struct prog_instruction *fpi,
  36.                          fs_reg dst, fs_reg src)
  37. {
  38.    for (int i = 0; i < 4; i++) {
  39.       if (fpi->DstReg.WriteMask & (1 << i))
  40.          emit(opcode, offset(dst, i), offset(src, i));
  41.    }
  42. }
  43.  
  44. void
  45. fs_visitor::emit_fp_alu2(enum opcode opcode,
  46.                          const struct prog_instruction *fpi,
  47.                          fs_reg dst, fs_reg src0, fs_reg src1)
  48. {
  49.    for (int i = 0; i < 4; i++) {
  50.       if (fpi->DstReg.WriteMask & (1 << i))
  51.          emit(opcode, offset(dst, i),
  52.               offset(src0, i), offset(src1, i));
  53.    }
  54. }
  55.  
  56. void
  57. fs_visitor::emit_fp_minmax(const prog_instruction *fpi,
  58.                            fs_reg dst, fs_reg src0, fs_reg src1)
  59. {
  60.    enum brw_conditional_mod conditionalmod;
  61.    if (fpi->Opcode == OPCODE_MIN)
  62.       conditionalmod = BRW_CONDITIONAL_L;
  63.    else
  64.       conditionalmod = BRW_CONDITIONAL_GE;
  65.  
  66.    for (int i = 0; i < 4; i++) {
  67.       if (fpi->DstReg.WriteMask & (1 << i)) {
  68.          emit_minmax(conditionalmod, offset(dst, i),
  69.                      offset(src0, i), offset(src1, i));
  70.       }
  71.    }
  72. }
  73.  
  74. void
  75. fs_visitor::emit_fp_sop(enum brw_conditional_mod conditional_mod,
  76.                         const struct prog_instruction *fpi,
  77.                         fs_reg dst, fs_reg src0, fs_reg src1,
  78.                         fs_reg one)
  79. {
  80.    for (int i = 0; i < 4; i++) {
  81.       if (fpi->DstReg.WriteMask & (1 << i)) {
  82.          fs_inst *inst;
  83.  
  84.          emit(CMP(reg_null_d, offset(src0, i), offset(src1, i),
  85.                   conditional_mod));
  86.  
  87.          inst = emit(BRW_OPCODE_SEL, offset(dst, i), one, fs_reg(0.0f));
  88.          inst->predicate = BRW_PREDICATE_NORMAL;
  89.       }
  90.    }
  91. }
  92.  
  93. void
  94. fs_visitor::emit_fp_scalar_write(const struct prog_instruction *fpi,
  95.                                  fs_reg dst, fs_reg src)
  96. {
  97.    for (int i = 0; i < 4; i++) {
  98.       if (fpi->DstReg.WriteMask & (1 << i))
  99.          emit(MOV(offset(dst, i), src));
  100.    }
  101. }
  102.  
  103. void
  104. fs_visitor::emit_fp_scalar_math(enum opcode opcode,
  105.                                 const struct prog_instruction *fpi,
  106.                                 fs_reg dst, fs_reg src)
  107. {
  108.    fs_reg temp = vgrf(glsl_type::float_type);
  109.    emit_math(opcode, temp, src);
  110.    emit_fp_scalar_write(fpi, dst, temp);
  111. }
  112.  
  113. void
  114. fs_visitor::emit_fragment_program_code()
  115. {
  116.    setup_fp_regs();
  117.  
  118.    /* Keep a reg with 1.0 around, for reuse by emit_fp_sop so that it can just
  119.     * be:
  120.     *
  121.     * sel.f0 dst 1.0 0.0
  122.     *
  123.     * instead of
  124.     *
  125.     * mov    dst 0.0
  126.     * mov.f0 dst 1.0
  127.     */
  128.    fs_reg one = vgrf(glsl_type::float_type);
  129.    emit(MOV(one, fs_reg(1.0f)));
  130.  
  131.    for (unsigned int insn = 0; insn < prog->NumInstructions; insn++) {
  132.       const struct prog_instruction *fpi = &prog->Instructions[insn];
  133.       base_ir = fpi;
  134.  
  135.       fs_reg dst;
  136.       fs_reg src[3];
  137.  
  138.       /* We always emit into a temporary destination register to avoid
  139.        * aliasing issues.
  140.        */
  141.       dst = vgrf(glsl_type::vec4_type);
  142.  
  143.       for (int i = 0; i < 3; i++)
  144.          src[i] = get_fp_src_reg(&fpi->SrcReg[i]);
  145.  
  146.       switch (fpi->Opcode) {
  147.       case OPCODE_ABS:
  148.          src[0].abs = true;
  149.          src[0].negate = false;
  150.          emit_fp_alu1(BRW_OPCODE_MOV, fpi, dst, src[0]);
  151.          break;
  152.  
  153.       case OPCODE_ADD:
  154.          emit_fp_alu2(BRW_OPCODE_ADD, fpi, dst, src[0], src[1]);
  155.          break;
  156.  
  157.       case OPCODE_CMP:
  158.          for (int i = 0; i < 4; i++) {
  159.             if (fpi->DstReg.WriteMask & (1 << i)) {
  160.                fs_inst *inst;
  161.  
  162.                emit(CMP(reg_null_f, offset(src[0], i), fs_reg(0.0f),
  163.                         BRW_CONDITIONAL_L));
  164.  
  165.                inst = emit(BRW_OPCODE_SEL, offset(dst, i),
  166.                            offset(src[1], i), offset(src[2], i));
  167.                inst->predicate = BRW_PREDICATE_NORMAL;
  168.             }
  169.          }
  170.          break;
  171.  
  172.       case OPCODE_COS:
  173.          emit_fp_scalar_math(SHADER_OPCODE_COS, fpi, dst, src[0]);
  174.          break;
  175.  
  176.       case OPCODE_DP2:
  177.       case OPCODE_DP3:
  178.       case OPCODE_DP4:
  179.       case OPCODE_DPH: {
  180.          fs_reg mul = vgrf(glsl_type::float_type);
  181.          fs_reg acc = vgrf(glsl_type::float_type);
  182.          int count;
  183.  
  184.          switch (fpi->Opcode) {
  185.          case OPCODE_DP2: count = 2; break;
  186.          case OPCODE_DP3: count = 3; break;
  187.          case OPCODE_DP4: count = 4; break;
  188.          case OPCODE_DPH: count = 3; break;
  189.          default: unreachable("not reached");
  190.          }
  191.  
  192.          emit(MUL(acc, offset(src[0], 0), offset(src[1], 0)));
  193.          for (int i = 1; i < count; i++) {
  194.             emit(MUL(mul, offset(src[0], i), offset(src[1], i)));
  195.             emit(ADD(acc, acc, mul));
  196.          }
  197.  
  198.          if (fpi->Opcode == OPCODE_DPH)
  199.             emit(ADD(acc, acc, offset(src[1], 3)));
  200.  
  201.          emit_fp_scalar_write(fpi, dst, acc);
  202.          break;
  203.       }
  204.  
  205.       case OPCODE_DST:
  206.          if (fpi->DstReg.WriteMask & WRITEMASK_X)
  207.             emit(MOV(dst, fs_reg(1.0f)));
  208.          if (fpi->DstReg.WriteMask & WRITEMASK_Y) {
  209.             emit(MUL(offset(dst, 1),
  210.                      offset(src[0], 1), offset(src[1], 1)));
  211.          }
  212.          if (fpi->DstReg.WriteMask & WRITEMASK_Z)
  213.             emit(MOV(offset(dst, 2), offset(src[0], 2)));
  214.          if (fpi->DstReg.WriteMask & WRITEMASK_W)
  215.             emit(MOV(offset(dst, 3), offset(src[1], 3)));
  216.          break;
  217.  
  218.       case OPCODE_EX2:
  219.          emit_fp_scalar_math(SHADER_OPCODE_EXP2, fpi, dst, src[0]);
  220.          break;
  221.  
  222.       case OPCODE_FLR:
  223.          emit_fp_alu1(BRW_OPCODE_RNDD, fpi, dst, src[0]);
  224.          break;
  225.  
  226.       case OPCODE_FRC:
  227.          emit_fp_alu1(BRW_OPCODE_FRC, fpi, dst, src[0]);
  228.          break;
  229.  
  230.       case OPCODE_KIL: {
  231.          for (int i = 0; i < 4; i++) {
  232.             /* In most cases the argument to a KIL will be something like
  233.              * TEMP[0].wwww, so there's no point in checking whether .w is < 0
  234.              * 4 times in a row.
  235.              */
  236.             if (i > 0 &&
  237.                 GET_SWZ(fpi->SrcReg[0].Swizzle, i) ==
  238.                 GET_SWZ(fpi->SrcReg[0].Swizzle, i - 1) &&
  239.                 ((fpi->SrcReg[0].Negate >> i) & 1) ==
  240.                 ((fpi->SrcReg[0].Negate >> (i - 1)) & 1)) {
  241.                continue;
  242.             }
  243.  
  244.  
  245.             /* Emit an instruction that's predicated on the current
  246.              * undiscarded pixels, and updates just those pixels to be
  247.              * turned off.
  248.              */
  249.             fs_inst *cmp = emit(CMP(reg_null_f, offset(src[0], i),
  250.                                     fs_reg(0.0f), BRW_CONDITIONAL_GE));
  251.             cmp->predicate = BRW_PREDICATE_NORMAL;
  252.             cmp->flag_subreg = 1;
  253.  
  254.             if (devinfo->gen >= 6)
  255.                emit_discard_jump();
  256.          }
  257.          break;
  258.       }
  259.  
  260.       case OPCODE_LG2:
  261.          emit_fp_scalar_math(SHADER_OPCODE_LOG2, fpi, dst, src[0]);
  262.          break;
  263.  
  264.       case OPCODE_LIT:
  265.          /* From the ARB_fragment_program spec:
  266.           *
  267.           *      tmp = VectorLoad(op0);
  268.           *      if (tmp.x < 0) tmp.x = 0;
  269.           *      if (tmp.y < 0) tmp.y = 0;
  270.           *      if (tmp.w < -(128.0-epsilon)) tmp.w = -(128.0-epsilon);
  271.           *      else if (tmp.w > 128-epsilon) tmp.w = 128-epsilon;
  272.           *      result.x = 1.0;
  273.           *      result.y = tmp.x;
  274.           *      result.z = (tmp.x > 0) ? RoughApproxPower(tmp.y, tmp.w) : 0.0;
  275.           *      result.w = 1.0;
  276.           *
  277.           * Note that we don't do the clamping to +/- 128.  We didn't in
  278.           * brw_wm_emit.c either.
  279.           */
  280.          if (fpi->DstReg.WriteMask & WRITEMASK_X)
  281.             emit(MOV(offset(dst, 0), fs_reg(1.0f)));
  282.  
  283.          if (fpi->DstReg.WriteMask & WRITEMASK_YZ) {
  284.             fs_inst *inst;
  285.             emit(CMP(reg_null_f, offset(src[0], 0), fs_reg(0.0f),
  286.                      BRW_CONDITIONAL_LE));
  287.  
  288.             if (fpi->DstReg.WriteMask & WRITEMASK_Y) {
  289.                emit(MOV(offset(dst, 1), offset(src[0], 0)));
  290.                inst = emit(MOV(offset(dst, 1), fs_reg(0.0f)));
  291.                inst->predicate = BRW_PREDICATE_NORMAL;
  292.             }
  293.  
  294.             if (fpi->DstReg.WriteMask & WRITEMASK_Z) {
  295.                emit_math(SHADER_OPCODE_POW, offset(dst, 2),
  296.                          offset(src[0], 1), offset(src[0], 3));
  297.  
  298.                inst = emit(MOV(offset(dst, 2), fs_reg(0.0f)));
  299.                inst->predicate = BRW_PREDICATE_NORMAL;
  300.             }
  301.          }
  302.  
  303.          if (fpi->DstReg.WriteMask & WRITEMASK_W)
  304.             emit(MOV(offset(dst, 3), fs_reg(1.0f)));
  305.  
  306.          break;
  307.  
  308.       case OPCODE_LRP:
  309.          for (int i = 0; i < 4; i++) {
  310.             if (fpi->DstReg.WriteMask & (1 << i)) {
  311.                fs_reg a = offset(src[0], i);
  312.                fs_reg y = offset(src[1], i);
  313.                fs_reg x = offset(src[2], i);
  314.                emit_lrp(offset(dst, i), x, y, a);
  315.             }
  316.          }
  317.          break;
  318.  
  319.       case OPCODE_MAD:
  320.          for (int i = 0; i < 4; i++) {
  321.             if (fpi->DstReg.WriteMask & (1 << i)) {
  322.                if (devinfo->gen >= 6) {
  323.                   emit(MAD(offset(dst, i), offset(src[2], i),
  324.                            offset(src[1], i), offset(src[0], i)));
  325.                } else {
  326.                   fs_reg temp = vgrf(glsl_type::float_type);
  327.                   emit(MUL(temp, offset(src[0], i), offset(src[1], i)));
  328.                   emit(ADD(offset(dst, i), temp, offset(src[2], i)));
  329.                }
  330.             }
  331.          }
  332.          break;
  333.  
  334.       case OPCODE_MAX:
  335.          emit_fp_minmax(fpi, dst, src[0], src[1]);
  336.          break;
  337.  
  338.       case OPCODE_MOV:
  339.          emit_fp_alu1(BRW_OPCODE_MOV, fpi, dst, src[0]);
  340.          break;
  341.  
  342.       case OPCODE_MIN:
  343.          emit_fp_minmax(fpi, dst, src[0], src[1]);
  344.          break;
  345.  
  346.       case OPCODE_MUL:
  347.          emit_fp_alu2(BRW_OPCODE_MUL, fpi, dst, src[0], src[1]);
  348.          break;
  349.  
  350.       case OPCODE_POW: {
  351.          fs_reg temp = vgrf(glsl_type::float_type);
  352.          emit_math(SHADER_OPCODE_POW, temp, src[0], src[1]);
  353.          emit_fp_scalar_write(fpi, dst, temp);
  354.          break;
  355.       }
  356.  
  357.       case OPCODE_RCP:
  358.          emit_fp_scalar_math(SHADER_OPCODE_RCP, fpi, dst, src[0]);
  359.          break;
  360.  
  361.       case OPCODE_RSQ:
  362.          emit_fp_scalar_math(SHADER_OPCODE_RSQ, fpi, dst, src[0]);
  363.          break;
  364.  
  365.       case OPCODE_SCS:
  366.          if (fpi->DstReg.WriteMask & WRITEMASK_X) {
  367.             emit_math(SHADER_OPCODE_COS, offset(dst, 0),
  368.                       offset(src[0], 0));
  369.          }
  370.  
  371.          if (fpi->DstReg.WriteMask & WRITEMASK_Y) {
  372.             emit_math(SHADER_OPCODE_SIN, offset(dst, 1),
  373.                       offset(src[0], 1));
  374.          }
  375.          break;
  376.  
  377.       case OPCODE_SGE:
  378.          emit_fp_sop(BRW_CONDITIONAL_GE, fpi, dst, src[0], src[1], one);
  379.          break;
  380.  
  381.       case OPCODE_SIN:
  382.          emit_fp_scalar_math(SHADER_OPCODE_SIN, fpi, dst, src[0]);
  383.          break;
  384.  
  385.       case OPCODE_SLT:
  386.          emit_fp_sop(BRW_CONDITIONAL_L, fpi, dst, src[0], src[1], one);
  387.          break;
  388.  
  389.       case OPCODE_SUB: {
  390.          fs_reg neg_src1 = src[1];
  391.          neg_src1.negate = !src[1].negate;
  392.  
  393.          emit_fp_alu2(BRW_OPCODE_ADD, fpi, dst, src[0], neg_src1);
  394.          break;
  395.       }
  396.  
  397.       case OPCODE_TEX:
  398.       case OPCODE_TXB:
  399.       case OPCODE_TXP: {
  400.          ir_texture_opcode op;
  401.          fs_reg lod;
  402.          fs_reg dpdy;
  403.          fs_reg coordinate = src[0];
  404.          fs_reg shadow_c;
  405.          fs_reg sample_index;
  406.          fs_reg texel_offset; /* No offsets; leave as BAD_FILE. */
  407.  
  408.          switch (fpi->Opcode) {
  409.          case OPCODE_TEX:
  410.             op = ir_tex;
  411.             break;
  412.          case OPCODE_TXP: {
  413.             op = ir_tex;
  414.  
  415.             coordinate = vgrf(glsl_type::vec3_type);
  416.             fs_reg invproj = vgrf(glsl_type::float_type);
  417.             emit_math(SHADER_OPCODE_RCP, invproj, offset(src[0], 3));
  418.             for (int i = 0; i < 3; i++) {
  419.                emit(MUL(offset(coordinate, i),
  420.                         offset(src[0], i), invproj));
  421.             }
  422.             break;
  423.          }
  424.          case OPCODE_TXB:
  425.             op = ir_txb;
  426.             lod = offset(src[0], 3);
  427.             break;
  428.          default:
  429.             unreachable("not reached");
  430.          }
  431.  
  432.          int coord_components;
  433.          switch (fpi->TexSrcTarget) {
  434.          case TEXTURE_1D_INDEX:
  435.             coord_components = 1;
  436.             break;
  437.  
  438.          case TEXTURE_2D_INDEX:
  439.          case TEXTURE_1D_ARRAY_INDEX:
  440.          case TEXTURE_RECT_INDEX:
  441.          case TEXTURE_EXTERNAL_INDEX:
  442.             coord_components = 2;
  443.             break;
  444.  
  445.          case TEXTURE_3D_INDEX:
  446.          case TEXTURE_2D_ARRAY_INDEX:
  447.             coord_components = 3;
  448.             break;
  449.  
  450.          case TEXTURE_CUBE_INDEX: {
  451.             coord_components = 3;
  452.  
  453.             fs_reg temp = vgrf(glsl_type::float_type);
  454.             fs_reg cubecoord = vgrf(glsl_type::vec3_type);
  455.             fs_reg abscoord = coordinate;
  456.             abscoord.negate = false;
  457.             abscoord.abs = true;
  458.             emit_minmax(BRW_CONDITIONAL_GE, temp,
  459.                         offset(abscoord, 0), offset(abscoord, 1));
  460.             emit_minmax(BRW_CONDITIONAL_GE, temp,
  461.                         temp, offset(abscoord, 2));
  462.             emit_math(SHADER_OPCODE_RCP, temp, temp);
  463.             for (int i = 0; i < 3; i++) {
  464.                emit(MUL(offset(cubecoord, i),
  465.                         offset(coordinate, i), temp));
  466.             }
  467.  
  468.             coordinate = cubecoord;
  469.             break;
  470.          }
  471.  
  472.          default:
  473.             unreachable("not reached");
  474.          }
  475.  
  476.          if (fpi->TexShadow)
  477.             shadow_c = offset(coordinate, 2);
  478.  
  479.          emit_texture(op, glsl_type::vec4_type, coordinate, coord_components,
  480.                       shadow_c, lod, dpdy, 0, sample_index,
  481.                       reg_undef, /* offset */
  482.                       reg_undef, /* mcs */
  483.                       0, /* gather component */
  484.                       false, /* is cube array */
  485.                       fpi->TexSrcTarget == TEXTURE_RECT_INDEX,
  486.                       fpi->TexSrcUnit, fs_reg(fpi->TexSrcUnit),
  487.                       fpi->TexSrcUnit);
  488.          dst = this->result;
  489.  
  490.          break;
  491.       }
  492.  
  493.       case OPCODE_SWZ:
  494.          /* Note that SWZ's extended swizzles are handled in the general
  495.           * get_src_reg() code.
  496.           */
  497.          emit_fp_alu1(BRW_OPCODE_MOV, fpi, dst, src[0]);
  498.          break;
  499.  
  500.       case OPCODE_XPD:
  501.          for (int i = 0; i < 3; i++) {
  502.             if (fpi->DstReg.WriteMask & (1 << i)) {
  503.                int i1 = (i + 1) % 3;
  504.                int i2 = (i + 2) % 3;
  505.  
  506.                fs_reg temp = vgrf(glsl_type::float_type);
  507.                fs_reg neg_src1_1 = offset(src[1], i1);
  508.                neg_src1_1.negate = !neg_src1_1.negate;
  509.                emit(MUL(temp, offset(src[0], i2), neg_src1_1));
  510.                emit(MUL(offset(dst, i),
  511.                         offset(src[0], i1), offset(src[1], i2)));
  512.                emit(ADD(offset(dst, i), offset(dst, i), temp));
  513.             }
  514.          }
  515.          break;
  516.  
  517.       case OPCODE_END:
  518.          break;
  519.  
  520.       default:
  521.          _mesa_problem(ctx, "Unsupported opcode %s in fragment program\n",
  522.                        _mesa_opcode_string(fpi->Opcode));
  523.       }
  524.  
  525.       /* To handle saturates, we emit a MOV with a saturate bit, which
  526.        * optimization should fold into the preceding instructions when safe.
  527.        */
  528.       if (_mesa_num_inst_dst_regs(fpi->Opcode) != 0) {
  529.          fs_reg real_dst = get_fp_dst_reg(&fpi->DstReg);
  530.  
  531.          for (int i = 0; i < 4; i++) {
  532.             if (fpi->DstReg.WriteMask & (1 << i)) {
  533.                fs_inst *inst = emit(MOV(offset(real_dst, i),
  534.                                         offset(dst, i)));
  535.                inst->saturate = fpi->SaturateMode;
  536.             }
  537.          }
  538.       }
  539.    }
  540.  
  541.    /* Epilogue:
  542.     *
  543.     * Fragment depth has this strange convention of being the .z component of
  544.     * a vec4.  emit_fb_write() wants to see a float value, instead.
  545.     */
  546.    this->current_annotation = "result.depth write";
  547.    if (frag_depth.file != BAD_FILE) {
  548.       fs_reg temp = vgrf(glsl_type::float_type);
  549.       emit(MOV(temp, offset(frag_depth, 2)));
  550.       frag_depth = temp;
  551.    }
  552. }
  553.  
  554. void
  555. fs_visitor::setup_fp_regs()
  556. {
  557.    /* PROGRAM_TEMPORARY */
  558.    int num_temp = prog->NumTemporaries;
  559.    fp_temp_regs = rzalloc_array(mem_ctx, fs_reg, num_temp);
  560.    for (int i = 0; i < num_temp; i++)
  561.       fp_temp_regs[i] = vgrf(glsl_type::vec4_type);
  562.  
  563.    /* PROGRAM_STATE_VAR etc. */
  564.    if (dispatch_width == 8) {
  565.       for (unsigned p = 0;
  566.            p < prog->Parameters->NumParameters; p++) {
  567.          for (unsigned int i = 0; i < 4; i++) {
  568.             stage_prog_data->param[uniforms++] =
  569.                &prog->Parameters->ParameterValues[p][i];
  570.          }
  571.       }
  572.    }
  573.  
  574.    fp_input_regs = rzalloc_array(mem_ctx, fs_reg, VARYING_SLOT_MAX);
  575.    for (int i = 0; i < VARYING_SLOT_MAX; i++) {
  576.       if (prog->InputsRead & BITFIELD64_BIT(i)) {
  577.          this->current_annotation = ralloc_asprintf(ctx, "interpolate input %d",
  578.                                                     i);
  579.  
  580.          switch (i) {
  581.          case VARYING_SLOT_POS:
  582.             {
  583.                assert(stage == MESA_SHADER_FRAGMENT);
  584.                gl_fragment_program *fp = (gl_fragment_program*) prog;
  585.                fp_input_regs[i] =
  586.                   *emit_fragcoord_interpolation(fp->PixelCenterInteger,
  587.                                                 fp->OriginUpperLeft);
  588.             }
  589.             break;
  590.          case VARYING_SLOT_FACE:
  591.             fp_input_regs[i] = *emit_frontfacing_interpolation();
  592.             break;
  593.          default:
  594.             fp_input_regs[i] = vgrf(glsl_type::vec4_type);
  595.             emit_general_interpolation(fp_input_regs[i], "fp_input",
  596.                                        glsl_type::vec4_type,
  597.                                        INTERP_QUALIFIER_NONE,
  598.                                        i, false, false);
  599.  
  600.             if (i == VARYING_SLOT_FOGC) {
  601.                emit(MOV(offset(fp_input_regs[i], 1), fs_reg(0.0f)));
  602.                emit(MOV(offset(fp_input_regs[i], 2), fs_reg(0.0f)));
  603.                emit(MOV(offset(fp_input_regs[i], 3), fs_reg(1.0f)));
  604.             }
  605.  
  606.             break;
  607.          }
  608.  
  609.          this->current_annotation = NULL;
  610.       }
  611.    }
  612. }
  613.  
  614. fs_reg
  615. fs_visitor::get_fp_dst_reg(const prog_dst_register *dst)
  616. {
  617.    assert(stage == MESA_SHADER_FRAGMENT);
  618.    brw_wm_prog_key *key = (brw_wm_prog_key*) this->key;
  619.  
  620.    switch (dst->File) {
  621.    case PROGRAM_TEMPORARY:
  622.       return fp_temp_regs[dst->Index];
  623.  
  624.    case PROGRAM_OUTPUT:
  625.       if (dst->Index == FRAG_RESULT_DEPTH) {
  626.          if (frag_depth.file == BAD_FILE)
  627.             frag_depth = vgrf(glsl_type::vec4_type);
  628.          return frag_depth;
  629.       } else if (dst->Index == FRAG_RESULT_COLOR) {
  630.          if (outputs[0].file == BAD_FILE) {
  631.             outputs[0] = vgrf(glsl_type::vec4_type);
  632.             output_components[0] = 4;
  633.  
  634.             /* Tell emit_fb_writes() to smear fragment.color across all the
  635.              * color attachments.
  636.              */
  637.             for (int i = 1; i < key->nr_color_regions; i++) {
  638.                outputs[i] = outputs[0];
  639.                output_components[i] = output_components[0];
  640.             }
  641.          }
  642.          return outputs[0];
  643.       } else {
  644.          int output_index = dst->Index - FRAG_RESULT_DATA0;
  645.          if (outputs[output_index].file == BAD_FILE) {
  646.             outputs[output_index] = vgrf(glsl_type::vec4_type);
  647.          }
  648.          output_components[output_index] = 4;
  649.          return outputs[output_index];
  650.       }
  651.  
  652.    case PROGRAM_UNDEFINED:
  653.       return fs_reg();
  654.  
  655.    default:
  656.       _mesa_problem(ctx, "bad dst register file: %s\n",
  657.                     _mesa_register_file_name((gl_register_file)dst->File));
  658.       return vgrf(glsl_type::vec4_type);
  659.    }
  660. }
  661.  
  662. fs_reg
  663. fs_visitor::get_fp_src_reg(const prog_src_register *src)
  664. {
  665.    struct gl_program_parameter_list *plist = prog->Parameters;
  666.  
  667.    fs_reg result;
  668.  
  669.    assert(!src->Abs);
  670.  
  671.    switch (src->File) {
  672.    case PROGRAM_UNDEFINED:
  673.       return fs_reg();
  674.    case PROGRAM_TEMPORARY:
  675.       result = fp_temp_regs[src->Index];
  676.       break;
  677.  
  678.    case PROGRAM_INPUT:
  679.       result = fp_input_regs[src->Index];
  680.       break;
  681.  
  682.    case PROGRAM_STATE_VAR:
  683.    case PROGRAM_UNIFORM:
  684.    case PROGRAM_CONSTANT:
  685.       /* We actually want to look at the type in the Parameters list for this,
  686.        * because this lets us upload constant builtin uniforms, as actual
  687.        * constants.
  688.        */
  689.       switch (plist->Parameters[src->Index].Type) {
  690.       case PROGRAM_CONSTANT: {
  691.          result = vgrf(glsl_type::vec4_type);
  692.  
  693.          for (int i = 0; i < 4; i++) {
  694.             emit(MOV(offset(result, i),
  695.                      fs_reg(plist->ParameterValues[src->Index][i].f)));
  696.          }
  697.          break;
  698.       }
  699.  
  700.       case PROGRAM_STATE_VAR:
  701.       case PROGRAM_UNIFORM:
  702.          result = fs_reg(UNIFORM, src->Index * 4);
  703.          break;
  704.  
  705.       default:
  706.          _mesa_problem(ctx, "bad uniform src register file: %s\n",
  707.                        _mesa_register_file_name((gl_register_file)src->File));
  708.          return vgrf(glsl_type::vec4_type);
  709.       }
  710.       break;
  711.  
  712.    default:
  713.       _mesa_problem(ctx, "bad src register file: %s\n",
  714.                     _mesa_register_file_name((gl_register_file)src->File));
  715.       return vgrf(glsl_type::vec4_type);
  716.    }
  717.  
  718.    if (src->Swizzle != SWIZZLE_NOOP || src->Negate) {
  719.       fs_reg unswizzled = result;
  720.       result = vgrf(glsl_type::vec4_type);
  721.       for (int i = 0; i < 4; i++) {
  722.          bool negate = src->Negate & (1 << i);
  723.          /* The ZERO, ONE, and Negate options are only used for OPCODE_SWZ,
  724.           * but it costs us nothing to support it.
  725.           */
  726.          int src_swiz = GET_SWZ(src->Swizzle, i);
  727.          if (src_swiz == SWIZZLE_ZERO) {
  728.             emit(MOV(offset(result, i), fs_reg(0.0f)));
  729.          } else if (src_swiz == SWIZZLE_ONE) {
  730.             emit(MOV(offset(result, i),
  731.                      negate ? fs_reg(-1.0f) : fs_reg(1.0f)));
  732.          } else {
  733.             fs_reg src = offset(unswizzled, src_swiz);
  734.             if (negate)
  735.                src.negate = !src.negate;
  736.             emit(MOV(offset(result, i), src));
  737.          }
  738.       }
  739.    }
  740.  
  741.    return result;
  742. }
  743.