Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2003 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 "main/glheader.h"
  29. #include "main/macros.h"
  30. #include "main/enums.h"
  31.  
  32. #include "program/prog_instruction.h"
  33. #include "program/prog_parameter.h"
  34. #include "program/program.h"
  35. #include "program/programopt.h"
  36. #include "program/prog_print.h"
  37.  
  38. #include "tnl/tnl.h"
  39. #include "tnl/t_context.h"
  40.  
  41. #include "intel_batchbuffer.h"
  42.  
  43. #include "i915_reg.h"
  44. #include "i915_context.h"
  45. #include "i915_program.h"
  46.  
  47. static const GLfloat sin_quad_constants[2][4] = {
  48.    {
  49.       2.0,
  50.       -1.0,
  51.       .5,
  52.       .75
  53.    },
  54.    {
  55.       4.0,
  56.       -4.0,
  57.       1.0 / (2.0 * M_PI),
  58.       .2225
  59.    }
  60. };
  61.  
  62. static const GLfloat sin_constants[4] = { 1.0,
  63.    -1.0 / (3 * 2 * 1),
  64.    1.0 / (5 * 4 * 3 * 2 * 1),
  65.    -1.0 / (7 * 6 * 5 * 4 * 3 * 2 * 1)
  66. };
  67.  
  68. /* 1, -1/2!, 1/4!, -1/6! */
  69. static const GLfloat cos_constants[4] = { 1.0,
  70.    -1.0 / (2 * 1),
  71.    1.0 / (4 * 3 * 2 * 1),
  72.    -1.0 / (6 * 5 * 4 * 3 * 2 * 1)
  73. };
  74.  
  75. /**
  76.  * Retrieve a ureg for the given source register.  Will emit
  77.  * constants, apply swizzling and negation as needed.
  78.  */
  79. static GLuint
  80. src_vector(struct i915_fragment_program *p,
  81.            const struct prog_src_register *source,
  82.            const struct gl_fragment_program *program)
  83. {
  84.    GLuint src;
  85.  
  86.    switch (source->File) {
  87.  
  88.       /* Registers:
  89.        */
  90.    case PROGRAM_TEMPORARY:
  91.       if (source->Index >= I915_MAX_TEMPORARY) {
  92.          i915_program_error(p, "Exceeded max temporary reg: %d/%d",
  93.                             source->Index, I915_MAX_TEMPORARY);
  94.          return 0;
  95.       }
  96.       src = UREG(REG_TYPE_R, source->Index);
  97.       break;
  98.    case PROGRAM_INPUT:
  99.       switch (source->Index) {
  100.       case VARYING_SLOT_POS:
  101.          src = i915_emit_decl(p, REG_TYPE_T, p->wpos_tex, D0_CHANNEL_ALL);
  102.          break;
  103.       case VARYING_SLOT_COL0:
  104.          src = i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL);
  105.          break;
  106.       case VARYING_SLOT_COL1:
  107.          src = i915_emit_decl(p, REG_TYPE_T, T_SPECULAR, D0_CHANNEL_XYZ);
  108.          src = swizzle(src, X, Y, Z, ONE);
  109.          break;
  110.       case VARYING_SLOT_FOGC:
  111.          src = i915_emit_decl(p, REG_TYPE_T, T_FOG_W, D0_CHANNEL_W);
  112.          src = swizzle(src, W, ZERO, ZERO, ONE);
  113.          break;
  114.       case VARYING_SLOT_TEX0:
  115.       case VARYING_SLOT_TEX1:
  116.       case VARYING_SLOT_TEX2:
  117.       case VARYING_SLOT_TEX3:
  118.       case VARYING_SLOT_TEX4:
  119.       case VARYING_SLOT_TEX5:
  120.       case VARYING_SLOT_TEX6:
  121.       case VARYING_SLOT_TEX7:
  122.          src = i915_emit_decl(p, REG_TYPE_T,
  123.                               T_TEX0 + (source->Index - VARYING_SLOT_TEX0),
  124.                               D0_CHANNEL_ALL);
  125.          break;
  126.  
  127.       case VARYING_SLOT_VAR0:
  128.       case VARYING_SLOT_VAR0 + 1:
  129.       case VARYING_SLOT_VAR0 + 2:
  130.       case VARYING_SLOT_VAR0 + 3:
  131.       case VARYING_SLOT_VAR0 + 4:
  132.       case VARYING_SLOT_VAR0 + 5:
  133.       case VARYING_SLOT_VAR0 + 6:
  134.       case VARYING_SLOT_VAR0 + 7:
  135.          src = i915_emit_decl(p, REG_TYPE_T,
  136.                               T_TEX0 + (source->Index - VARYING_SLOT_VAR0),
  137.                               D0_CHANNEL_ALL);
  138.          break;
  139.  
  140.       default:
  141.          i915_program_error(p, "Bad source->Index: %d", source->Index);
  142.          return 0;
  143.       }
  144.       break;
  145.  
  146.    case PROGRAM_OUTPUT:
  147.       switch (source->Index) {
  148.       case FRAG_RESULT_COLOR:
  149.       case FRAG_RESULT_DATA0:
  150.          src = UREG(REG_TYPE_OC, 0);
  151.          break;
  152.       case FRAG_RESULT_DEPTH:
  153.          src = UREG(REG_TYPE_OD, 0);
  154.          break;
  155.       default:
  156.          i915_program_error(p, "Bad source->Index: %d", source->Index);
  157.          return 0;
  158.       }
  159.       break;
  160.  
  161.       /* Various paramters and env values.  All emitted to
  162.        * hardware as program constants.
  163.        */
  164.    case PROGRAM_CONSTANT:
  165.    case PROGRAM_STATE_VAR:
  166.    case PROGRAM_UNIFORM:
  167.       src = i915_emit_param4fv(p,
  168.          &program->Base.Parameters->ParameterValues[source->Index][0].f);
  169.       break;
  170.  
  171.    default:
  172.       i915_program_error(p, "Bad source->File: %d", source->File);
  173.       return 0;
  174.    }
  175.  
  176.    src = swizzle(src,
  177.                  GET_SWZ(source->Swizzle, 0),
  178.                  GET_SWZ(source->Swizzle, 1),
  179.                  GET_SWZ(source->Swizzle, 2), GET_SWZ(source->Swizzle, 3));
  180.  
  181.    if (source->Negate)
  182.       src = negate(src,
  183.                    GET_BIT(source->Negate, 0),
  184.                    GET_BIT(source->Negate, 1),
  185.                    GET_BIT(source->Negate, 2),
  186.                    GET_BIT(source->Negate, 3));
  187.  
  188.    return src;
  189. }
  190.  
  191.  
  192. static GLuint
  193. get_result_vector(struct i915_fragment_program *p,
  194.                   const struct prog_instruction *inst)
  195. {
  196.    switch (inst->DstReg.File) {
  197.    case PROGRAM_OUTPUT:
  198.       switch (inst->DstReg.Index) {
  199.       case FRAG_RESULT_COLOR:
  200.       case FRAG_RESULT_DATA0:
  201.          return UREG(REG_TYPE_OC, 0);
  202.       case FRAG_RESULT_DEPTH:
  203.          p->depth_written = 1;
  204.          return UREG(REG_TYPE_OD, 0);
  205.       default:
  206.          i915_program_error(p, "Bad inst->DstReg.Index: %d",
  207.                             inst->DstReg.Index);
  208.          return 0;
  209.       }
  210.    case PROGRAM_TEMPORARY:
  211.       return UREG(REG_TYPE_R, inst->DstReg.Index);
  212.    default:
  213.       i915_program_error(p, "Bad inst->DstReg.File: %d", inst->DstReg.File);
  214.       return 0;
  215.    }
  216. }
  217.  
  218. static GLuint
  219. get_result_flags(const struct prog_instruction *inst)
  220. {
  221.    GLuint flags = 0;
  222.  
  223.    if (inst->SaturateMode == SATURATE_ZERO_ONE)
  224.       flags |= A0_DEST_SATURATE;
  225.    if (inst->DstReg.WriteMask & WRITEMASK_X)
  226.       flags |= A0_DEST_CHANNEL_X;
  227.    if (inst->DstReg.WriteMask & WRITEMASK_Y)
  228.       flags |= A0_DEST_CHANNEL_Y;
  229.    if (inst->DstReg.WriteMask & WRITEMASK_Z)
  230.       flags |= A0_DEST_CHANNEL_Z;
  231.    if (inst->DstReg.WriteMask & WRITEMASK_W)
  232.       flags |= A0_DEST_CHANNEL_W;
  233.  
  234.    return flags;
  235. }
  236.  
  237. static GLuint
  238. translate_tex_src_target(struct i915_fragment_program *p, GLubyte bit)
  239. {
  240.    switch (bit) {
  241.    case TEXTURE_1D_INDEX:
  242.       return D0_SAMPLE_TYPE_2D;
  243.    case TEXTURE_2D_INDEX:
  244.       return D0_SAMPLE_TYPE_2D;
  245.    case TEXTURE_RECT_INDEX:
  246.       return D0_SAMPLE_TYPE_2D;
  247.    case TEXTURE_3D_INDEX:
  248.       return D0_SAMPLE_TYPE_VOLUME;
  249.    case TEXTURE_CUBE_INDEX:
  250.       return D0_SAMPLE_TYPE_CUBE;
  251.    default:
  252.       i915_program_error(p, "TexSrcBit: %d", bit);
  253.       return 0;
  254.    }
  255. }
  256.  
  257. #define EMIT_TEX( OP )                                          \
  258. do {                                                            \
  259.    GLuint dim = translate_tex_src_target( p, inst->TexSrcTarget );      \
  260.    const struct gl_fragment_program *program = &p->FragProg;    \
  261.    GLuint unit = program->Base.SamplerUnits[inst->TexSrcUnit];  \
  262.    GLuint sampler = i915_emit_decl(p, REG_TYPE_S,               \
  263.                                    unit, dim);                  \
  264.    GLuint coord = src_vector( p, &inst->SrcReg[0], program);    \
  265.    /* Texel lookup */                                           \
  266.                                                                 \
  267.    i915_emit_texld( p, get_live_regs(p, inst),                                          \
  268.                get_result_vector( p, inst ),                    \
  269.                get_result_flags( inst ),                        \
  270.                sampler,                                         \
  271.                coord,                                           \
  272.                OP);                                             \
  273. } while (0)
  274.  
  275. #define EMIT_ARITH( OP, N )                                             \
  276. do {                                                                    \
  277.    i915_emit_arith( p,                                                  \
  278.                OP,                                                      \
  279.                get_result_vector( p, inst ),                            \
  280.                get_result_flags( inst ), 0,                     \
  281.                (N<1)?0:src_vector( p, &inst->SrcReg[0], program),       \
  282.                (N<2)?0:src_vector( p, &inst->SrcReg[1], program),       \
  283.                (N<3)?0:src_vector( p, &inst->SrcReg[2], program));      \
  284. } while (0)
  285.  
  286. #define EMIT_1ARG_ARITH( OP ) EMIT_ARITH( OP, 1 )
  287. #define EMIT_2ARG_ARITH( OP ) EMIT_ARITH( OP, 2 )
  288. #define EMIT_3ARG_ARITH( OP ) EMIT_ARITH( OP, 3 )
  289.  
  290. /*
  291.  * TODO: consider moving this into core
  292.  */
  293. static bool calc_live_regs( struct i915_fragment_program *p )
  294. {
  295.     const struct gl_fragment_program *program = &p->FragProg;
  296.     GLuint regsUsed = ~((1 << I915_MAX_TEMPORARY) - 1);
  297.     uint8_t live_components[I915_MAX_TEMPORARY] = { 0, };
  298.     GLint i;
  299.    
  300.     for (i = program->Base.NumInstructions - 1; i >= 0; i--) {
  301.         struct prog_instruction *inst = &program->Base.Instructions[i];
  302.         int opArgs = _mesa_num_inst_src_regs(inst->Opcode);
  303.         int a;
  304.  
  305.         /* Register is written to: unmark as live for this and preceeding ops */
  306.         if (inst->DstReg.File == PROGRAM_TEMPORARY) {
  307.             if (inst->DstReg.Index >= I915_MAX_TEMPORARY)
  308.                return false;
  309.  
  310.             live_components[inst->DstReg.Index] &= ~inst->DstReg.WriteMask;
  311.             if (live_components[inst->DstReg.Index] == 0)
  312.                 regsUsed &= ~(1 << inst->DstReg.Index);
  313.         }
  314.  
  315.         for (a = 0; a < opArgs; a++) {
  316.             /* Register is read from: mark as live for this and preceeding ops */
  317.             if (inst->SrcReg[a].File == PROGRAM_TEMPORARY) {
  318.                 unsigned c;
  319.  
  320.                 if (inst->SrcReg[a].Index >= I915_MAX_TEMPORARY)
  321.                    return false;
  322.  
  323.                 regsUsed |= 1 << inst->SrcReg[a].Index;
  324.  
  325.                 for (c = 0; c < 4; c++) {
  326.                     const unsigned field = GET_SWZ(inst->SrcReg[a].Swizzle, c);
  327.  
  328.                     if (field <= SWIZZLE_W)
  329.                         live_components[inst->SrcReg[a].Index] |= (1U << field);
  330.                 }
  331.             }
  332.         }
  333.  
  334.         p->usedRegs[i] = regsUsed;
  335.     }
  336.  
  337.     return true;
  338. }
  339.  
  340. static GLuint get_live_regs( struct i915_fragment_program *p,
  341.                              const struct prog_instruction *inst )
  342. {
  343.     const struct gl_fragment_program *program = &p->FragProg;
  344.     GLuint nr = inst - program->Base.Instructions;
  345.  
  346.     return p->usedRegs[nr];
  347. }
  348.  
  349.  
  350. /* Possible concerns:
  351.  *
  352.  * SIN, COS -- could use another taylor step?
  353.  * LIT      -- results seem a little different to sw mesa
  354.  * LOG      -- different to mesa on negative numbers, but this is conformant.
  355.  *
  356.  * Parse failures -- Mesa doesn't currently give a good indication
  357.  * internally whether a particular program string parsed or not.  This
  358.  * can lead to confusion -- hopefully we cope with it ok now.
  359.  *
  360.  */
  361. static void
  362. upload_program(struct i915_fragment_program *p)
  363. {
  364.    const struct gl_fragment_program *program = &p->FragProg;
  365.    const struct prog_instruction *inst = program->Base.Instructions;
  366.  
  367.    if (INTEL_DEBUG & DEBUG_WM)
  368.       _mesa_print_program(&program->Base);
  369.  
  370.    /* Is this a parse-failed program?  Ensure a valid program is
  371.     * loaded, as the flagging of an error isn't sufficient to stop
  372.     * this being uploaded to hardware.
  373.     */
  374.    if (inst[0].Opcode == OPCODE_END) {
  375.       GLuint tmp = i915_get_utemp(p);
  376.       i915_emit_arith(p,
  377.                       A0_MOV,
  378.                       UREG(REG_TYPE_OC, 0),
  379.                       A0_DEST_CHANNEL_ALL, 0,
  380.                       swizzle(tmp, ONE, ZERO, ONE, ONE), 0, 0);
  381.       return;
  382.    }
  383.  
  384.    if (program->Base.NumInstructions > I915_MAX_INSN) {
  385.       i915_program_error(p, "Exceeded max instructions (%d out of %d)",
  386.                          program->Base.NumInstructions, I915_MAX_INSN);
  387.       return;
  388.    }
  389.  
  390.    /* Not always needed:
  391.     */
  392.    if (!calc_live_regs(p)) {
  393.       i915_program_error(p, "Could not allocate registers");
  394.       return;
  395.    }
  396.  
  397.    while (1) {
  398.       GLuint src0, src1, src2, flags;
  399.       GLuint tmp = 0, dst, consts0 = 0, consts1 = 0;
  400.  
  401.       switch (inst->Opcode) {
  402.       case OPCODE_ABS:
  403.          src0 = src_vector(p, &inst->SrcReg[0], program);
  404.          i915_emit_arith(p,
  405.                          A0_MAX,
  406.                          get_result_vector(p, inst),
  407.                          get_result_flags(inst), 0,
  408.                          src0, negate(src0, 1, 1, 1, 1), 0);
  409.          break;
  410.  
  411.       case OPCODE_ADD:
  412.          EMIT_2ARG_ARITH(A0_ADD);
  413.          break;
  414.  
  415.       case OPCODE_CMP:
  416.          src0 = src_vector(p, &inst->SrcReg[0], program);
  417.          src1 = src_vector(p, &inst->SrcReg[1], program);
  418.          src2 = src_vector(p, &inst->SrcReg[2], program);
  419.          i915_emit_arith(p, A0_CMP, get_result_vector(p, inst), get_result_flags(inst), 0, src0, src2, src1);   /* NOTE: order of src2, src1 */
  420.          break;
  421.  
  422.       case OPCODE_COS:
  423.          src0 = src_vector(p, &inst->SrcReg[0], program);
  424.          tmp = i915_get_utemp(p);
  425.          consts0 = i915_emit_const4fv(p, sin_quad_constants[0]);
  426.          consts1 = i915_emit_const4fv(p, sin_quad_constants[1]);
  427.  
  428.          /* Reduce range from repeating about [-pi,pi] to [-1,1] */
  429.          i915_emit_arith(p,
  430.                          A0_MAD,
  431.                          tmp, A0_DEST_CHANNEL_X, 0,
  432.                          src0,
  433.                          swizzle(consts1, Z, ZERO, ZERO, ZERO), /* 1/(2pi) */
  434.                          swizzle(consts0, W, ZERO, ZERO, ZERO)); /* .75 */
  435.  
  436.          i915_emit_arith(p, A0_FRC, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0);
  437.  
  438.          i915_emit_arith(p,
  439.                          A0_MAD,
  440.                          tmp, A0_DEST_CHANNEL_X, 0,
  441.                          tmp,
  442.                          swizzle(consts0, X, ZERO, ZERO, ZERO), /* 2 */
  443.                          swizzle(consts0, Y, ZERO, ZERO, ZERO)); /* -1 */
  444.  
  445.          /* Compute COS with the same calculation used for SIN, but a
  446.           * different source range has been mapped to [-1,1] this time.
  447.           */
  448.  
  449.          /* tmp.y = abs(tmp.x); {x, abs(x), 0, 0} */
  450.          i915_emit_arith(p,
  451.                          A0_MAX,
  452.                          tmp, A0_DEST_CHANNEL_Y, 0,
  453.                          swizzle(tmp, ZERO, X, ZERO, ZERO),
  454.                          negate(swizzle(tmp, ZERO, X, ZERO, ZERO), 0, 1, 0, 0),
  455.                          0);
  456.  
  457.          /* tmp.y = tmp.y * tmp.x; {x, x * abs(x), 0, 0} */
  458.          i915_emit_arith(p,
  459.                          A0_MUL,
  460.                          tmp, A0_DEST_CHANNEL_Y, 0,
  461.                          swizzle(tmp, ZERO, X, ZERO, ZERO),
  462.                          tmp,
  463.                          0);
  464.  
  465.          /* tmp.x = tmp.xy DP sin_quad_constants[2].xy */
  466.          i915_emit_arith(p,
  467.                          A0_DP3,
  468.                          tmp, A0_DEST_CHANNEL_X, 0,
  469.                          tmp,
  470.                          swizzle(consts1, X, Y, ZERO, ZERO),
  471.                          0);
  472.  
  473.          /* tmp.x now contains a first approximation (y).  Now, weight it
  474.           * against tmp.y**2 to get closer.
  475.           */
  476.          i915_emit_arith(p,
  477.                          A0_MAX,
  478.                          tmp, A0_DEST_CHANNEL_Y, 0,
  479.                          swizzle(tmp, ZERO, X, ZERO, ZERO),
  480.                          negate(swizzle(tmp, ZERO, X, ZERO, ZERO), 0, 1, 0, 0),
  481.                          0);
  482.  
  483.          /* tmp.y = tmp.x * tmp.y - tmp.x; {y, y * abs(y) - y, 0, 0} */
  484.          i915_emit_arith(p,
  485.                          A0_MAD,
  486.                          tmp, A0_DEST_CHANNEL_Y, 0,
  487.                          swizzle(tmp, ZERO, X, ZERO, ZERO),
  488.                          swizzle(tmp, ZERO, Y, ZERO, ZERO),
  489.                          negate(swizzle(tmp, ZERO, X, ZERO, ZERO), 0, 1, 0, 0));
  490.  
  491.          /* result = .2225 * tmp.y + tmp.x =.2225(y * abs(y) - y) + y= */
  492.          i915_emit_arith(p,
  493.                          A0_MAD,
  494.                          get_result_vector(p, inst),
  495.                          get_result_flags(inst), 0,
  496.                          swizzle(consts1, W, W, W, W),
  497.                          swizzle(tmp, Y, Y, Y, Y),
  498.                          swizzle(tmp, X, X, X, X));
  499.          break;
  500.  
  501.       case OPCODE_DP2:
  502.          src0 = src_vector(p, &inst->SrcReg[0], program);
  503.          src1 = src_vector(p, &inst->SrcReg[1], program);
  504.          i915_emit_arith(p,
  505.                          A0_DP3,
  506.                          get_result_vector(p, inst),
  507.                          get_result_flags(inst), 0,
  508.                          swizzle(src0, X, Y, ZERO, ZERO),
  509.                          swizzle(src1, X, Y, ZERO, ZERO),
  510.                          0);
  511.          break;
  512.  
  513.       case OPCODE_DP3:
  514.          EMIT_2ARG_ARITH(A0_DP3);
  515.          break;
  516.  
  517.       case OPCODE_DP4:
  518.          EMIT_2ARG_ARITH(A0_DP4);
  519.          break;
  520.  
  521.       case OPCODE_DPH:
  522.          src0 = src_vector(p, &inst->SrcReg[0], program);
  523.          src1 = src_vector(p, &inst->SrcReg[1], program);
  524.  
  525.          i915_emit_arith(p,
  526.                          A0_DP4,
  527.                          get_result_vector(p, inst),
  528.                          get_result_flags(inst), 0,
  529.                          swizzle(src0, X, Y, Z, ONE), src1, 0);
  530.          break;
  531.  
  532.       case OPCODE_DST:
  533.          src0 = src_vector(p, &inst->SrcReg[0], program);
  534.          src1 = src_vector(p, &inst->SrcReg[1], program);
  535.  
  536.          /* result[0] = 1    * 1;
  537.           * result[1] = a[1] * b[1];
  538.           * result[2] = a[2] * 1;
  539.           * result[3] = 1    * b[3];
  540.           */
  541.          i915_emit_arith(p,
  542.                          A0_MUL,
  543.                          get_result_vector(p, inst),
  544.                          get_result_flags(inst), 0,
  545.                          swizzle(src0, ONE, Y, Z, ONE),
  546.                          swizzle(src1, ONE, Y, ONE, W), 0);
  547.          break;
  548.  
  549.       case OPCODE_EX2:
  550.          src0 = src_vector(p, &inst->SrcReg[0], program);
  551.  
  552.          i915_emit_arith(p,
  553.                          A0_EXP,
  554.                          get_result_vector(p, inst),
  555.                          get_result_flags(inst), 0,
  556.                          swizzle(src0, X, X, X, X), 0, 0);
  557.          break;
  558.  
  559.       case OPCODE_FLR:
  560.          EMIT_1ARG_ARITH(A0_FLR);
  561.          break;
  562.  
  563.       case OPCODE_TRUNC:
  564.          EMIT_1ARG_ARITH(A0_TRC);
  565.          break;
  566.  
  567.       case OPCODE_FRC:
  568.          EMIT_1ARG_ARITH(A0_FRC);
  569.          break;
  570.  
  571.       case OPCODE_KIL:
  572.          src0 = src_vector(p, &inst->SrcReg[0], program);
  573.          tmp = i915_get_utemp(p);
  574.  
  575.          i915_emit_texld(p, get_live_regs(p, inst),
  576.                          tmp, A0_DEST_CHANNEL_ALL,   /* use a dummy dest reg */
  577.                          0, src0, T0_TEXKILL);
  578.          break;
  579.  
  580.       case OPCODE_KIL_NV:
  581.          if (inst->DstReg.CondMask == COND_TR) {
  582.             tmp = i915_get_utemp(p);
  583.  
  584.             /* The KIL instruction discards the fragment if any component of
  585.              * the source is < 0.  Emit an immediate operand of {-1}.xywz.
  586.              */
  587.             i915_emit_texld(p, get_live_regs(p, inst),
  588.                             tmp, A0_DEST_CHANNEL_ALL,
  589.                             0, /* use a dummy dest reg */
  590.                             negate(swizzle(tmp, ONE, ONE, ONE, ONE),
  591.                                    1, 1, 1, 1),
  592.                             T0_TEXKILL);
  593.          } else {
  594.             p->error = 1;
  595.             i915_program_error(p, "Unsupported KIL_NV condition code: %d",
  596.                                inst->DstReg.CondMask);
  597.          }
  598.          break;
  599.  
  600.       case OPCODE_LG2:
  601.          src0 = src_vector(p, &inst->SrcReg[0], program);
  602.  
  603.          i915_emit_arith(p,
  604.                          A0_LOG,
  605.                          get_result_vector(p, inst),
  606.                          get_result_flags(inst), 0,
  607.                          swizzle(src0, X, X, X, X), 0, 0);
  608.          break;
  609.  
  610.       case OPCODE_LIT:
  611.          src0 = src_vector(p, &inst->SrcReg[0], program);
  612.          tmp = i915_get_utemp(p);
  613.  
  614.          /* tmp = max( a.xyzw, a.00zw )
  615.           * XXX: Clamp tmp.w to -128..128
  616.           * tmp.y = log(tmp.y)
  617.           * tmp.y = tmp.w * tmp.y
  618.           * tmp.y = exp(tmp.y)
  619.           * result = cmp (a.11-x1, a.1x01, a.1xy1 )
  620.           */
  621.          i915_emit_arith(p, A0_MAX, tmp, A0_DEST_CHANNEL_ALL, 0,
  622.                          src0, swizzle(src0, ZERO, ZERO, Z, W), 0);
  623.  
  624.          i915_emit_arith(p, A0_LOG, tmp, A0_DEST_CHANNEL_Y, 0,
  625.                          swizzle(tmp, Y, Y, Y, Y), 0, 0);
  626.  
  627.          i915_emit_arith(p, A0_MUL, tmp, A0_DEST_CHANNEL_Y, 0,
  628.                          swizzle(tmp, ZERO, Y, ZERO, ZERO),
  629.                          swizzle(tmp, ZERO, W, ZERO, ZERO), 0);
  630.  
  631.          i915_emit_arith(p, A0_EXP, tmp, A0_DEST_CHANNEL_Y, 0,
  632.                          swizzle(tmp, Y, Y, Y, Y), 0, 0);
  633.  
  634.          i915_emit_arith(p, A0_CMP,
  635.                          get_result_vector(p, inst),
  636.                          get_result_flags(inst), 0,
  637.                          negate(swizzle(tmp, ONE, ONE, X, ONE), 0, 0, 1, 0),
  638.                          swizzle(tmp, ONE, X, ZERO, ONE),
  639.                          swizzle(tmp, ONE, X, Y, ONE));
  640.  
  641.          break;
  642.  
  643.       case OPCODE_LRP:
  644.          src0 = src_vector(p, &inst->SrcReg[0], program);
  645.          src1 = src_vector(p, &inst->SrcReg[1], program);
  646.          src2 = src_vector(p, &inst->SrcReg[2], program);
  647.          flags = get_result_flags(inst);
  648.          tmp = i915_get_utemp(p);
  649.  
  650.          /* b*a + c*(1-a)
  651.           *
  652.           * b*a + c - ca
  653.           *
  654.           * tmp = b*a + c,
  655.           * result = (-c)*a + tmp
  656.           */
  657.          i915_emit_arith(p, A0_MAD, tmp,
  658.                          flags & A0_DEST_CHANNEL_ALL, 0, src1, src0, src2);
  659.  
  660.          i915_emit_arith(p, A0_MAD,
  661.                          get_result_vector(p, inst),
  662.                          flags, 0, negate(src2, 1, 1, 1, 1), src0, tmp);
  663.          break;
  664.  
  665.       case OPCODE_MAD:
  666.          EMIT_3ARG_ARITH(A0_MAD);
  667.          break;
  668.  
  669.       case OPCODE_MAX:
  670.          EMIT_2ARG_ARITH(A0_MAX);
  671.          break;
  672.  
  673.       case OPCODE_MIN:
  674.          EMIT_2ARG_ARITH(A0_MIN);
  675.          break;
  676.  
  677.       case OPCODE_MOV:
  678.          EMIT_1ARG_ARITH(A0_MOV);
  679.          break;
  680.  
  681.       case OPCODE_MUL:
  682.          EMIT_2ARG_ARITH(A0_MUL);
  683.          break;
  684.  
  685.       case OPCODE_POW:
  686.          src0 = src_vector(p, &inst->SrcReg[0], program);
  687.          src1 = src_vector(p, &inst->SrcReg[1], program);
  688.          tmp = i915_get_utemp(p);
  689.          flags = get_result_flags(inst);
  690.  
  691.          /* XXX: masking on intermediate values, here and elsewhere.
  692.           */
  693.          i915_emit_arith(p,
  694.                          A0_LOG,
  695.                          tmp, A0_DEST_CHANNEL_X, 0,
  696.                          swizzle(src0, X, X, X, X), 0, 0);
  697.  
  698.          i915_emit_arith(p, A0_MUL, tmp, A0_DEST_CHANNEL_X, 0, tmp, src1, 0);
  699.  
  700.  
  701.          i915_emit_arith(p,
  702.                          A0_EXP,
  703.                          get_result_vector(p, inst),
  704.                          flags, 0, swizzle(tmp, X, X, X, X), 0, 0);
  705.  
  706.          break;
  707.  
  708.       case OPCODE_RCP:
  709.          src0 = src_vector(p, &inst->SrcReg[0], program);
  710.  
  711.          i915_emit_arith(p,
  712.                          A0_RCP,
  713.                          get_result_vector(p, inst),
  714.                          get_result_flags(inst), 0,
  715.                          swizzle(src0, X, X, X, X), 0, 0);
  716.          break;
  717.  
  718.       case OPCODE_RSQ:
  719.  
  720.          src0 = src_vector(p, &inst->SrcReg[0], program);
  721.  
  722.          i915_emit_arith(p,
  723.                          A0_RSQ,
  724.                          get_result_vector(p, inst),
  725.                          get_result_flags(inst), 0,
  726.                          swizzle(src0, X, X, X, X), 0, 0);
  727.          break;
  728.  
  729.       case OPCODE_SCS:
  730.          src0 = src_vector(p, &inst->SrcReg[0], program);
  731.          tmp = i915_get_utemp(p);
  732.  
  733.          /*
  734.           * t0.xy = MUL x.xx11, x.x1111  ; x^2, x, 1, 1
  735.           * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x
  736.           * t1 = MUL t0.xyyw t0.yz11    ; x^7 x^5 x^3 x
  737.           * scs.x = DP4 t1, sin_constants
  738.           * t1 = MUL t0.xxz1 t0.z111    ; x^6 x^4 x^2 1
  739.           * scs.y = DP4 t1, cos_constants
  740.           */
  741.          i915_emit_arith(p,
  742.                          A0_MUL,
  743.                          tmp, A0_DEST_CHANNEL_XY, 0,
  744.                          swizzle(src0, X, X, ONE, ONE),
  745.                          swizzle(src0, X, ONE, ONE, ONE), 0);
  746.  
  747.          i915_emit_arith(p,
  748.                          A0_MUL,
  749.                          tmp, A0_DEST_CHANNEL_ALL, 0,
  750.                          swizzle(tmp, X, Y, X, Y),
  751.                          swizzle(tmp, X, X, ONE, ONE), 0);
  752.  
  753.          if (inst->DstReg.WriteMask & WRITEMASK_Y) {
  754.             GLuint tmp1;
  755.  
  756.             if (inst->DstReg.WriteMask & WRITEMASK_X)
  757.                tmp1 = i915_get_utemp(p);
  758.             else
  759.                tmp1 = tmp;
  760.  
  761.             i915_emit_arith(p,
  762.                             A0_MUL,
  763.                             tmp1, A0_DEST_CHANNEL_ALL, 0,
  764.                             swizzle(tmp, X, Y, Y, W),
  765.                             swizzle(tmp, X, Z, ONE, ONE), 0);
  766.  
  767.             i915_emit_arith(p,
  768.                             A0_DP4,
  769.                             get_result_vector(p, inst),
  770.                             A0_DEST_CHANNEL_Y, 0,
  771.                             swizzle(tmp1, W, Z, Y, X),
  772.                             i915_emit_const4fv(p, sin_constants), 0);
  773.          }
  774.  
  775.          if (inst->DstReg.WriteMask & WRITEMASK_X) {
  776.             i915_emit_arith(p,
  777.                             A0_MUL,
  778.                             tmp, A0_DEST_CHANNEL_XYZ, 0,
  779.                             swizzle(tmp, X, X, Z, ONE),
  780.                             swizzle(tmp, Z, ONE, ONE, ONE), 0);
  781.  
  782.             i915_emit_arith(p,
  783.                             A0_DP4,
  784.                             get_result_vector(p, inst),
  785.                             A0_DEST_CHANNEL_X, 0,
  786.                             swizzle(tmp, ONE, Z, Y, X),
  787.                             i915_emit_const4fv(p, cos_constants), 0);
  788.          }
  789.          break;
  790.  
  791.       case OPCODE_SEQ:
  792.          tmp = i915_get_utemp(p);
  793.          flags = get_result_flags(inst);
  794.          dst = get_result_vector(p, inst);
  795.  
  796.          /* If both operands are uniforms or constants, we get 5 instructions
  797.           * like:
  798.           *
  799.           *     U[1] = MOV CONST[1]
  800.           *     U[0].xyz = SGE CONST[0].xxxx, U[1]
  801.           *     U[1] = MOV CONST[1].-x-y-z-w
  802.           *     R[0].xyz = SGE CONST[0].-x-x-x-x, U[1]
  803.           *     R[0].xyz = MUL R[0], U[0]
  804.           *
  805.           * This code is stupid.  Instead of having the individual calls to
  806.           * i915_emit_arith generate the moves to utemps, do it in the caller.
  807.           * This results in code like:
  808.           *
  809.           *     U[1] = MOV CONST[1]
  810.           *     U[0].xyz = SGE CONST[0].xxxx, U[1]
  811.           *     R[0].xyz = SGE CONST[0].-x-x-x-x, U[1].-x-y-z-w
  812.           *     R[0].xyz = MUL R[0], U[0]
  813.           */
  814.          src0 = src_vector(p, &inst->SrcReg[0], program);
  815.          src1 = src_vector(p, &inst->SrcReg[1], program);
  816.  
  817.          if (GET_UREG_TYPE(src0) == REG_TYPE_CONST
  818.              && GET_UREG_TYPE(src1) == REG_TYPE_CONST) {
  819.             unsigned tmp = i915_get_utemp(p);
  820.  
  821.             i915_emit_arith(p, A0_MOV, tmp, A0_DEST_CHANNEL_ALL, 0,
  822.                             src1, 0, 0);
  823.  
  824.             src1 = tmp;
  825.          }
  826.  
  827.          /* tmp = src1 >= src2 */
  828.          i915_emit_arith(p,
  829.                          A0_SGE,
  830.                          tmp,
  831.                          flags, 0,
  832.                          src0,
  833.                          src1,
  834.                          0);
  835.          /* dst = src1 <= src2 */
  836.          i915_emit_arith(p,
  837.                          A0_SGE,
  838.                          dst,
  839.                          flags, 0,
  840.                          negate(src0, 1, 1, 1, 1),
  841.                          negate(src1, 1, 1, 1, 1),
  842.                          0);
  843.          /* dst = tmp && dst */
  844.          i915_emit_arith(p,
  845.                          A0_MUL,
  846.                          dst,
  847.                          flags, 0,
  848.                          dst,
  849.                          tmp,
  850.                          0);
  851.          break;
  852.  
  853.       case OPCODE_SIN:
  854.          src0 = src_vector(p, &inst->SrcReg[0], program);
  855.          tmp = i915_get_utemp(p);
  856.          consts0 = i915_emit_const4fv(p, sin_quad_constants[0]);
  857.          consts1 = i915_emit_const4fv(p, sin_quad_constants[1]);
  858.  
  859.          /* Reduce range from repeating about [-pi,pi] to [-1,1] */
  860.          i915_emit_arith(p,
  861.                          A0_MAD,
  862.                          tmp, A0_DEST_CHANNEL_X, 0,
  863.                          src0,
  864.                          swizzle(consts1, Z, ZERO, ZERO, ZERO), /* 1/(2pi) */
  865.                          swizzle(consts0, Z, ZERO, ZERO, ZERO)); /* .5 */
  866.  
  867.          i915_emit_arith(p, A0_FRC, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0);
  868.  
  869.          i915_emit_arith(p,
  870.                          A0_MAD,
  871.                          tmp, A0_DEST_CHANNEL_X, 0,
  872.                          tmp,
  873.                          swizzle(consts0, X, ZERO, ZERO, ZERO), /* 2 */
  874.                          swizzle(consts0, Y, ZERO, ZERO, ZERO)); /* -1 */
  875.  
  876.          /* Compute sin using a quadratic and quartic.  It gives continuity
  877.           * that repeating the Taylor series lacks every 2*pi, and has
  878.           * reduced error.
  879.           *
  880.           * The idea was described at:
  881.           * http://www.devmaster.net/forums/showthread.php?t=5784
  882.           */
  883.  
  884.          /* tmp.y = abs(tmp.x); {x, abs(x), 0, 0} */
  885.          i915_emit_arith(p,
  886.                          A0_MAX,
  887.                          tmp, A0_DEST_CHANNEL_Y, 0,
  888.                          swizzle(tmp, ZERO, X, ZERO, ZERO),
  889.                          negate(swizzle(tmp, ZERO, X, ZERO, ZERO), 0, 1, 0, 0),
  890.                          0);
  891.  
  892.          /* tmp.y = tmp.y * tmp.x; {x, x * abs(x), 0, 0} */
  893.          i915_emit_arith(p,
  894.                          A0_MUL,
  895.                          tmp, A0_DEST_CHANNEL_Y, 0,
  896.                          swizzle(tmp, ZERO, X, ZERO, ZERO),
  897.                          tmp,
  898.                          0);
  899.  
  900.          /* tmp.x = tmp.xy DP sin_quad_constants[2].xy */
  901.          i915_emit_arith(p,
  902.                          A0_DP3,
  903.                          tmp, A0_DEST_CHANNEL_X, 0,
  904.                          tmp,
  905.                          swizzle(consts1, X, Y, ZERO, ZERO),
  906.                          0);
  907.  
  908.          /* tmp.x now contains a first approximation (y).  Now, weight it
  909.           * against tmp.y**2 to get closer.
  910.           */
  911.          i915_emit_arith(p,
  912.                          A0_MAX,
  913.                          tmp, A0_DEST_CHANNEL_Y, 0,
  914.                          swizzle(tmp, ZERO, X, ZERO, ZERO),
  915.                          negate(swizzle(tmp, ZERO, X, ZERO, ZERO), 0, 1, 0, 0),
  916.                          0);
  917.  
  918.          /* tmp.y = tmp.x * tmp.y - tmp.x; {y, y * abs(y) - y, 0, 0} */
  919.          i915_emit_arith(p,
  920.                          A0_MAD,
  921.                          tmp, A0_DEST_CHANNEL_Y, 0,
  922.                          swizzle(tmp, ZERO, X, ZERO, ZERO),
  923.                          swizzle(tmp, ZERO, Y, ZERO, ZERO),
  924.                          negate(swizzle(tmp, ZERO, X, ZERO, ZERO), 0, 1, 0, 0));
  925.  
  926.          /* result = .2225 * tmp.y + tmp.x =.2225(y * abs(y) - y) + y= */
  927.          i915_emit_arith(p,
  928.                          A0_MAD,
  929.                          get_result_vector(p, inst),
  930.                          get_result_flags(inst), 0,
  931.                          swizzle(consts1, W, W, W, W),
  932.                          swizzle(tmp, Y, Y, Y, Y),
  933.                          swizzle(tmp, X, X, X, X));
  934.  
  935.          break;
  936.  
  937.       case OPCODE_SGE:
  938.          EMIT_2ARG_ARITH(A0_SGE);
  939.          break;
  940.  
  941.       case OPCODE_SGT:
  942.          i915_emit_arith(p,
  943.                          A0_SLT,
  944.                          get_result_vector( p, inst ),
  945.                          get_result_flags( inst ), 0,
  946.                          negate(src_vector( p, &inst->SrcReg[0], program),
  947.                                 1, 1, 1, 1),
  948.                          negate(src_vector( p, &inst->SrcReg[1], program),
  949.                                 1, 1, 1, 1),
  950.                          0);
  951.          break;
  952.  
  953.       case OPCODE_SLE:
  954.          i915_emit_arith(p,
  955.                          A0_SGE,
  956.                          get_result_vector( p, inst ),
  957.                          get_result_flags( inst ), 0,
  958.                          negate(src_vector( p, &inst->SrcReg[0], program),
  959.                                 1, 1, 1, 1),
  960.                          negate(src_vector( p, &inst->SrcReg[1], program),
  961.                                 1, 1, 1, 1),
  962.                          0);
  963.          break;
  964.  
  965.       case OPCODE_SLT:
  966.          EMIT_2ARG_ARITH(A0_SLT);
  967.          break;
  968.  
  969.       case OPCODE_SNE:
  970.          tmp = i915_get_utemp(p);
  971.          flags = get_result_flags(inst);
  972.          dst = get_result_vector(p, inst);
  973.  
  974.          /* If both operands are uniforms or constants, we get 5 instructions
  975.           * like:
  976.           *
  977.           *     U[1] = MOV CONST[1]
  978.           *     U[0].xyz = SLT CONST[0].xxxx, U[1]
  979.           *     U[1] = MOV CONST[1].-x-y-z-w
  980.           *     R[0].xyz = SLT CONST[0].-x-x-x-x, U[1]
  981.           *     R[0].xyz = MUL R[0], U[0]
  982.           *
  983.           * This code is stupid.  Instead of having the individual calls to
  984.           * i915_emit_arith generate the moves to utemps, do it in the caller.
  985.           * This results in code like:
  986.           *
  987.           *     U[1] = MOV CONST[1]
  988.           *     U[0].xyz = SLT CONST[0].xxxx, U[1]
  989.           *     R[0].xyz = SLT CONST[0].-x-x-x-x, U[1].-x-y-z-w
  990.           *     R[0].xyz = MUL R[0], U[0]
  991.           */
  992.          src0 = src_vector(p, &inst->SrcReg[0], program);
  993.          src1 = src_vector(p, &inst->SrcReg[1], program);
  994.  
  995.          if (GET_UREG_TYPE(src0) == REG_TYPE_CONST
  996.              && GET_UREG_TYPE(src1) == REG_TYPE_CONST) {
  997.             unsigned tmp = i915_get_utemp(p);
  998.  
  999.             i915_emit_arith(p, A0_MOV, tmp, A0_DEST_CHANNEL_ALL, 0,
  1000.                             src1, 0, 0);
  1001.  
  1002.             src1 = tmp;
  1003.          }
  1004.  
  1005.          /* tmp = src1 < src2 */
  1006.          i915_emit_arith(p,
  1007.                          A0_SLT,
  1008.                          tmp,
  1009.                          flags, 0,
  1010.                          src0,
  1011.                          src1,
  1012.                          0);
  1013.          /* dst = src1 > src2 */
  1014.          i915_emit_arith(p,
  1015.                          A0_SLT,
  1016.                          dst,
  1017.                          flags, 0,
  1018.                          negate(src0, 1, 1, 1, 1),
  1019.                          negate(src1, 1, 1, 1, 1),
  1020.                          0);
  1021.          /* dst = tmp || dst */
  1022.          i915_emit_arith(p,
  1023.                          A0_ADD,
  1024.                          dst,
  1025.                          flags | A0_DEST_SATURATE, 0,
  1026.                          dst,
  1027.                          tmp,
  1028.                          0);
  1029.          break;
  1030.  
  1031.       case OPCODE_SSG:
  1032.          dst = get_result_vector(p, inst);
  1033.          flags = get_result_flags(inst);
  1034.          src0 = src_vector(p, &inst->SrcReg[0], program);
  1035.          tmp = i915_get_utemp(p);
  1036.  
  1037.          /* tmp = (src < 0.0) */
  1038.          i915_emit_arith(p,
  1039.                          A0_SLT,
  1040.                          tmp,
  1041.                          flags, 0,
  1042.                          src0,
  1043.                          swizzle(src0, ZERO, ZERO, ZERO, ZERO),
  1044.                          0);
  1045.  
  1046.          /* dst = (0.0 < src) */
  1047.          i915_emit_arith(p,
  1048.                          A0_SLT,
  1049.                          dst,
  1050.                          flags, 0,
  1051.                          swizzle(src0, ZERO, ZERO, ZERO, ZERO),
  1052.                          src0,
  1053.                          0);
  1054.  
  1055.          /* dst = (src > 0.0) - (src < 0.0) */
  1056.          i915_emit_arith(p,
  1057.                          A0_ADD,
  1058.                          dst,
  1059.                          flags, 0,
  1060.                          dst,
  1061.                          negate(tmp, 1, 1, 1, 1),
  1062.                          0);
  1063.  
  1064.          break;
  1065.  
  1066.       case OPCODE_SUB:
  1067.          src0 = src_vector(p, &inst->SrcReg[0], program);
  1068.          src1 = src_vector(p, &inst->SrcReg[1], program);
  1069.  
  1070.          i915_emit_arith(p,
  1071.                          A0_ADD,
  1072.                          get_result_vector(p, inst),
  1073.                          get_result_flags(inst), 0,
  1074.                          src0, negate(src1, 1, 1, 1, 1), 0);
  1075.          break;
  1076.  
  1077.       case OPCODE_SWZ:
  1078.          EMIT_1ARG_ARITH(A0_MOV);       /* extended swizzle handled natively */
  1079.          break;
  1080.  
  1081.       case OPCODE_TEX:
  1082.          EMIT_TEX(T0_TEXLD);
  1083.          break;
  1084.  
  1085.       case OPCODE_TXB:
  1086.          EMIT_TEX(T0_TEXLDB);
  1087.          break;
  1088.  
  1089.       case OPCODE_TXP:
  1090.          EMIT_TEX(T0_TEXLDP);
  1091.          break;
  1092.  
  1093.       case OPCODE_XPD:
  1094.          /* Cross product:
  1095.           *      result.x = src0.y * src1.z - src0.z * src1.y;
  1096.           *      result.y = src0.z * src1.x - src0.x * src1.z;
  1097.           *      result.z = src0.x * src1.y - src0.y * src1.x;
  1098.           *      result.w = undef;
  1099.           */
  1100.          src0 = src_vector(p, &inst->SrcReg[0], program);
  1101.          src1 = src_vector(p, &inst->SrcReg[1], program);
  1102.          tmp = i915_get_utemp(p);
  1103.  
  1104.          i915_emit_arith(p,
  1105.                          A0_MUL,
  1106.                          tmp, A0_DEST_CHANNEL_ALL, 0,
  1107.                          swizzle(src0, Z, X, Y, ONE),
  1108.                          swizzle(src1, Y, Z, X, ONE), 0);
  1109.  
  1110.          i915_emit_arith(p,
  1111.                          A0_MAD,
  1112.                          get_result_vector(p, inst),
  1113.                          get_result_flags(inst), 0,
  1114.                          swizzle(src0, Y, Z, X, ONE),
  1115.                          swizzle(src1, Z, X, Y, ONE),
  1116.                          negate(tmp, 1, 1, 1, 0));
  1117.          break;
  1118.  
  1119.       case OPCODE_END:
  1120.          return;
  1121.  
  1122.       case OPCODE_BGNLOOP:
  1123.       case OPCODE_BGNSUB:
  1124.       case OPCODE_BRK:
  1125.       case OPCODE_CAL:
  1126.       case OPCODE_CONT:
  1127.       case OPCODE_DDX:
  1128.       case OPCODE_DDY:
  1129.       case OPCODE_ELSE:
  1130.       case OPCODE_ENDIF:
  1131.       case OPCODE_ENDLOOP:
  1132.       case OPCODE_ENDSUB:
  1133.       case OPCODE_IF:
  1134.       case OPCODE_RET:
  1135.          p->error = 1;
  1136.          i915_program_error(p, "Unsupported opcode: %s",
  1137.                             _mesa_opcode_string(inst->Opcode));
  1138.          return;
  1139.  
  1140.       case OPCODE_EXP:
  1141.       case OPCODE_LOG:
  1142.          /* These opcodes are claimed as GLSL, NV_vp, and ARB_vp in
  1143.           * prog_instruction.h, but apparently GLSL doesn't ever emit them.
  1144.           * Instead, it translates to EX2 or LG2.
  1145.           */
  1146.       case OPCODE_TXD:
  1147.       case OPCODE_TXL:
  1148.          /* These opcodes are claimed by GLSL in prog_instruction.h, but
  1149.           * only NV_vp/fp appears to emit them.
  1150.           */
  1151.       default:
  1152.          i915_program_error(p, "bad opcode: %s",
  1153.                             _mesa_opcode_string(inst->Opcode));
  1154.          return;
  1155.       }
  1156.  
  1157.       inst++;
  1158.       i915_release_utemps(p);
  1159.    }
  1160. }
  1161.  
  1162. /* Rather than trying to intercept and jiggle depth writes during
  1163.  * emit, just move the value into its correct position at the end of
  1164.  * the program:
  1165.  */
  1166. static void
  1167. fixup_depth_write(struct i915_fragment_program *p)
  1168. {
  1169.    if (p->depth_written) {
  1170.       GLuint depth = UREG(REG_TYPE_OD, 0);
  1171.  
  1172.       i915_emit_arith(p,
  1173.                       A0_MOV,
  1174.                       depth, A0_DEST_CHANNEL_W, 0,
  1175.                       swizzle(depth, X, Y, Z, Z), 0, 0);
  1176.    }
  1177. }
  1178.  
  1179.  
  1180. static void
  1181. check_wpos(struct i915_fragment_program *p)
  1182. {
  1183.    GLbitfield64 inputs = p->FragProg.Base.InputsRead;
  1184.    GLint i;
  1185.  
  1186.    p->wpos_tex = -1;
  1187.  
  1188.    for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) {
  1189.       if (inputs & (VARYING_BIT_TEX(i) | VARYING_BIT_VAR(i)))
  1190.          continue;
  1191.       else if (inputs & VARYING_BIT_POS) {
  1192.          p->wpos_tex = i;
  1193.          inputs &= ~VARYING_BIT_POS;
  1194.       }
  1195.    }
  1196.  
  1197.    if (inputs & VARYING_BIT_POS) {
  1198.       i915_program_error(p, "No free texcoord for wpos value");
  1199.    }
  1200. }
  1201.  
  1202.  
  1203. static void
  1204. translate_program(struct i915_fragment_program *p)
  1205. {
  1206.    struct i915_context *i915 = I915_CONTEXT(p->ctx);
  1207.  
  1208.    if (INTEL_DEBUG & DEBUG_WM) {
  1209.       printf("fp:\n");
  1210.       _mesa_print_program(&p->FragProg.Base);
  1211.       printf("\n");
  1212.    }
  1213.  
  1214.    i915_init_program(i915, p);
  1215.    check_wpos(p);
  1216.    upload_program(p);
  1217.    fixup_depth_write(p);
  1218.    i915_fini_program(p);
  1219.  
  1220.    p->translated = 1;
  1221. }
  1222.  
  1223.  
  1224. static void
  1225. track_params(struct i915_fragment_program *p)
  1226. {
  1227.    GLint i;
  1228.  
  1229.    if (p->nr_params)
  1230.       _mesa_load_state_parameters(p->ctx, p->FragProg.Base.Parameters);
  1231.  
  1232.    for (i = 0; i < p->nr_params; i++) {
  1233.       GLint reg = p->param[i].reg;
  1234.       COPY_4V(p->constant[reg], p->param[i].values);
  1235.    }
  1236.  
  1237.    p->params_uptodate = 1;
  1238.    p->on_hardware = 0;          /* overkill */
  1239. }
  1240.  
  1241.  
  1242. static void
  1243. i915BindProgram(struct gl_context * ctx, GLenum target, struct gl_program *prog)
  1244. {
  1245.    if (target == GL_FRAGMENT_PROGRAM_ARB) {
  1246.       struct i915_context *i915 = I915_CONTEXT(ctx);
  1247.       struct i915_fragment_program *p = (struct i915_fragment_program *) prog;
  1248.  
  1249.       if (i915->current_program == p)
  1250.          return;
  1251.  
  1252.       if (i915->current_program) {
  1253.          i915->current_program->on_hardware = 0;
  1254.          i915->current_program->params_uptodate = 0;
  1255.       }
  1256.  
  1257.       i915->current_program = p;
  1258.  
  1259.       assert(p->on_hardware == 0);
  1260.       assert(p->params_uptodate == 0);
  1261.  
  1262.    }
  1263. }
  1264.  
  1265. static struct gl_program *
  1266. i915NewProgram(struct gl_context * ctx, GLenum target, GLuint id)
  1267. {
  1268.    switch (target) {
  1269.    case GL_VERTEX_PROGRAM_ARB:
  1270.       return _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program),
  1271.                                        target, id);
  1272.  
  1273.    case GL_FRAGMENT_PROGRAM_ARB:{
  1274.          struct i915_fragment_program *prog =
  1275.             CALLOC_STRUCT(i915_fragment_program);
  1276.          if (prog) {
  1277.             i915_init_program(I915_CONTEXT(ctx), prog);
  1278.  
  1279.             return _mesa_init_fragment_program(ctx, &prog->FragProg,
  1280.                                                target, id);
  1281.          }
  1282.          else
  1283.             return NULL;
  1284.       }
  1285.  
  1286.    default:
  1287.       /* Just fallback:
  1288.        */
  1289.       return _mesa_new_program(ctx, target, id);
  1290.    }
  1291. }
  1292.  
  1293. static void
  1294. i915DeleteProgram(struct gl_context * ctx, struct gl_program *prog)
  1295. {
  1296.    if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
  1297.       struct i915_context *i915 = I915_CONTEXT(ctx);
  1298.       struct i915_fragment_program *p = (struct i915_fragment_program *) prog;
  1299.  
  1300.       if (i915->current_program == p)
  1301.          i915->current_program = 0;
  1302.    }
  1303.  
  1304.    _mesa_delete_program(ctx, prog);
  1305. }
  1306.  
  1307.  
  1308. static GLboolean
  1309. i915IsProgramNative(struct gl_context * ctx, GLenum target, struct gl_program *prog)
  1310. {
  1311.    if (target == GL_FRAGMENT_PROGRAM_ARB) {
  1312.       struct i915_fragment_program *p = (struct i915_fragment_program *) prog;
  1313.  
  1314.       if (!p->translated)
  1315.          translate_program(p);
  1316.  
  1317.       return !p->error;
  1318.    }
  1319.    else
  1320.       return true;
  1321. }
  1322.  
  1323. static GLboolean
  1324. i915ProgramStringNotify(struct gl_context * ctx,
  1325.                         GLenum target, struct gl_program *prog)
  1326. {
  1327.    if (target == GL_FRAGMENT_PROGRAM_ARB) {
  1328.       struct i915_fragment_program *p = (struct i915_fragment_program *) prog;
  1329.       p->translated = 0;
  1330.    }
  1331.  
  1332.    (void) _tnl_program_string(ctx, target, prog);
  1333.  
  1334.    /* XXX check if program is legal, within limits */
  1335.    return true;
  1336. }
  1337.  
  1338. static void
  1339. i915SamplerUniformChange(struct gl_context *ctx,
  1340.                          GLenum target, struct gl_program *prog)
  1341. {
  1342.    i915ProgramStringNotify(ctx, target, prog);
  1343. }
  1344.  
  1345. void
  1346. i915_update_program(struct gl_context *ctx)
  1347. {
  1348.    struct intel_context *intel = intel_context(ctx);
  1349.    struct i915_context *i915 = i915_context(&intel->ctx);
  1350.    struct i915_fragment_program *fp =
  1351.       (struct i915_fragment_program *) ctx->FragmentProgram._Current;
  1352.  
  1353.    if (i915->current_program != fp) {
  1354.       if (i915->current_program) {
  1355.          i915->current_program->on_hardware = 0;
  1356.          i915->current_program->params_uptodate = 0;
  1357.       }
  1358.  
  1359.       i915->current_program = fp;
  1360.    }
  1361.  
  1362.    if (!fp->translated)
  1363.       translate_program(fp);
  1364.  
  1365.    FALLBACK(&i915->intel, I915_FALLBACK_PROGRAM, fp->error);
  1366. }
  1367.  
  1368. void
  1369. i915ValidateFragmentProgram(struct i915_context *i915)
  1370. {
  1371.    struct gl_context *ctx = &i915->intel.ctx;
  1372.    struct intel_context *intel = intel_context(ctx);
  1373.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  1374.    struct vertex_buffer *VB = &tnl->vb;
  1375.  
  1376.    struct i915_fragment_program *p =
  1377.       (struct i915_fragment_program *) ctx->FragmentProgram._Current;
  1378.  
  1379.    const GLbitfield64 inputsRead = p->FragProg.Base.InputsRead;
  1380.    GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK;
  1381.    GLuint s2 = S2_TEXCOORD_NONE;
  1382.    int i, offset = 0;
  1383.  
  1384.    /* Important:
  1385.     */
  1386.    VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
  1387.  
  1388.    if (!p->translated)
  1389.       translate_program(p);
  1390.  
  1391.    intel->vertex_attr_count = 0;
  1392.    intel->wpos_offset = 0;
  1393.    intel->coloroffset = 0;
  1394.    intel->specoffset = 0;
  1395.  
  1396.    if (inputsRead & VARYING_BITS_TEX_ANY || p->wpos_tex != -1) {
  1397.       EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16);
  1398.    }
  1399.    else {
  1400.       EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, S4_VFMT_XYZ, 12);
  1401.    }
  1402.  
  1403.    /* Handle gl_PointSize builtin var here */
  1404.    if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled)
  1405.       EMIT_ATTR(_TNL_ATTRIB_POINTSIZE, EMIT_1F, S4_VFMT_POINT_WIDTH, 4);
  1406.  
  1407.    if (inputsRead & VARYING_BIT_COL0) {
  1408.       intel->coloroffset = offset / 4;
  1409.       EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, S4_VFMT_COLOR, 4);
  1410.    }
  1411.  
  1412.    if (inputsRead & VARYING_BIT_COL1) {
  1413.        intel->specoffset = offset / 4;
  1414.        EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_4UB_4F_BGRA, S4_VFMT_SPEC_FOG, 4);
  1415.    }
  1416.  
  1417.    if ((inputsRead & VARYING_BIT_FOGC)) {
  1418.       EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1F, S4_VFMT_FOG_PARAM, 4);
  1419.    }
  1420.  
  1421.    for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) {
  1422.       if (inputsRead & VARYING_BIT_TEX(i)) {
  1423.          int sz = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]->size;
  1424.  
  1425.          s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
  1426.          s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz));
  1427.  
  1428.          EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, EMIT_SZ(sz), 0, sz * 4);
  1429.       }
  1430.       else if (inputsRead & VARYING_BIT_VAR(i)) {
  1431.          int sz = VB->AttribPtr[_TNL_ATTRIB_GENERIC0 + i]->size;
  1432.  
  1433.          s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
  1434.          s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz));
  1435.  
  1436.          EMIT_ATTR(_TNL_ATTRIB_GENERIC0 + i, EMIT_SZ(sz), 0, sz * 4);
  1437.       }
  1438.       else if (i == p->wpos_tex) {
  1439.          int wpos_size = 4 * sizeof(float);
  1440.          /* If WPOS is required, duplicate the XYZ position data in an
  1441.           * unused texture coordinate:
  1442.           */
  1443.          s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
  1444.          s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(wpos_size));
  1445.  
  1446.          intel->wpos_offset = offset;
  1447.          EMIT_PAD(wpos_size);
  1448.       }
  1449.    }
  1450.  
  1451.    if (s2 != i915->state.Ctx[I915_CTXREG_LIS2] ||
  1452.        s4 != i915->state.Ctx[I915_CTXREG_LIS4]) {
  1453.       I915_STATECHANGE(i915, I915_UPLOAD_CTX);
  1454.  
  1455.       /* Must do this *after* statechange, so as not to affect
  1456.        * buffered vertices reliant on the old state:
  1457.        */
  1458.       intel->vertex_size = _tnl_install_attrs(&intel->ctx,
  1459.                                               intel->vertex_attrs,
  1460.                                               intel->vertex_attr_count,
  1461.                                               intel->ViewportMatrix.m, 0);
  1462.  
  1463.       assert(intel->prim.current_offset == intel->prim.start_offset);
  1464.       intel->prim.start_offset = (intel->prim.current_offset + intel->vertex_size-1) / intel->vertex_size * intel->vertex_size;
  1465.       intel->prim.current_offset = intel->prim.start_offset;
  1466.  
  1467.       intel->vertex_size >>= 2;
  1468.  
  1469.       i915->state.Ctx[I915_CTXREG_LIS2] = s2;
  1470.       i915->state.Ctx[I915_CTXREG_LIS4] = s4;
  1471.  
  1472.       assert(intel->vtbl.check_vertex_size(intel, intel->vertex_size));
  1473.    }
  1474.  
  1475.    if (!p->params_uptodate)
  1476.       track_params(p);
  1477.  
  1478.    if (!p->on_hardware)
  1479.       i915_upload_program(i915, p);
  1480.  
  1481.    if (INTEL_DEBUG & DEBUG_WM) {
  1482.       printf("i915:\n");
  1483.       i915_disassemble_program(i915->state.Program, i915->state.ProgramSize);
  1484.    }
  1485. }
  1486.  
  1487. void
  1488. i915InitFragProgFuncs(struct dd_function_table *functions)
  1489. {
  1490.    functions->BindProgram = i915BindProgram;
  1491.    functions->NewProgram = i915NewProgram;
  1492.    functions->DeleteProgram = i915DeleteProgram;
  1493.    functions->IsProgramNative = i915IsProgramNative;
  1494.    functions->ProgramStringNotify = i915ProgramStringNotify;
  1495.    functions->SamplerUniformChange = i915SamplerUniformChange;
  1496. }
  1497.