Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2004 David Airlie
  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 DAVID AIRLIE 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/atifragshader.h"
  30. #include "main/macros.h"
  31. #include "main/enums.h"
  32. #include "tnl/t_context.h"
  33. #include "program/program.h"
  34. #include "r200_context.h"
  35. #include "r200_ioctl.h"
  36. #include "r200_tex.h"
  37.  
  38. #define SET_INST(inst, type) afs_cmd[((inst<<2) + (type<<1) + 1)]
  39. #define SET_INST_2(inst, type) afs_cmd[((inst<<2) + (type<<1) + 2)]
  40.  
  41. static void r200SetFragShaderArg( GLuint *afs_cmd, GLuint opnum, GLuint optype,
  42.                                 const struct atifragshader_src_register srcReg,
  43.                                 GLuint argPos, GLuint *tfactor )
  44. {
  45.    const GLuint index = srcReg.Index;
  46.    const GLuint srcmod = srcReg.argMod;
  47.    const GLuint srcrep = srcReg.argRep;
  48.    GLuint reg0 = 0;
  49.    GLuint reg2 = 0;
  50.    GLuint useOddSrc = 0;
  51.  
  52.    switch(srcrep) {
  53.    case GL_RED:
  54.       reg2 |= R200_TXC_REPL_RED << (R200_TXC_REPL_ARG_A_SHIFT + (2*argPos));
  55.       if (optype)
  56.          useOddSrc = 1;
  57.       break;
  58.    case GL_GREEN:
  59.       reg2 |= R200_TXC_REPL_GREEN << (R200_TXC_REPL_ARG_A_SHIFT + (2*argPos));
  60.       if (optype)
  61.          useOddSrc = 1;
  62.       break;
  63.    case GL_BLUE:
  64.       if (!optype)
  65.          reg2 |= R200_TXC_REPL_BLUE << (R200_TXC_REPL_ARG_A_SHIFT + (2*argPos));
  66.       else
  67.          useOddSrc = 1;
  68.       break;
  69.    case GL_ALPHA:
  70.       if (!optype)
  71.          useOddSrc = 1;
  72.       break;
  73.    }
  74.  
  75.    if (index >= GL_REG_0_ATI && index <= GL_REG_5_ATI)
  76.       reg0 |= (((index - GL_REG_0_ATI)*2) + 10 + useOddSrc) << (5*argPos);
  77.    else if (index >= GL_CON_0_ATI && index <= GL_CON_7_ATI) {
  78.       if ((*tfactor == 0) || (index == *tfactor)) {
  79.          reg0 |= (R200_TXC_ARG_A_TFACTOR_COLOR + useOddSrc) << (5*argPos);
  80.          reg2 |= (index - GL_CON_0_ATI) << R200_TXC_TFACTOR_SEL_SHIFT;
  81.          *tfactor = index;
  82.       }
  83.       else {
  84.          reg0 |= (R200_TXC_ARG_A_TFACTOR1_COLOR + useOddSrc) << (5*argPos);
  85.          reg2 |= (index - GL_CON_0_ATI) << R200_TXC_TFACTOR1_SEL_SHIFT;
  86.       }
  87.    }
  88.    else if (index == GL_PRIMARY_COLOR_EXT) {
  89.       reg0 |= (R200_TXC_ARG_A_DIFFUSE_COLOR + useOddSrc) << (5*argPos);
  90.    }
  91.    else if (index == GL_SECONDARY_INTERPOLATOR_ATI) {
  92.       reg0 |= (R200_TXC_ARG_A_SPECULAR_COLOR + useOddSrc) << (5*argPos);
  93.    }
  94.    /* GL_ZERO is a noop, for GL_ONE we set the complement */
  95.    else if (index == GL_ONE) {
  96.       reg0 |= R200_TXC_COMP_ARG_A << (4*argPos);
  97.    }
  98.  
  99.    if (srcmod & GL_COMP_BIT_ATI)
  100.       reg0 ^= R200_TXC_COMP_ARG_A << (4*argPos);
  101.    if (srcmod & GL_BIAS_BIT_ATI)
  102.       reg0 |= R200_TXC_BIAS_ARG_A << (4*argPos);
  103.    if (srcmod & GL_2X_BIT_ATI)
  104.       reg0 |= R200_TXC_SCALE_ARG_A << (4*argPos);
  105.    if (srcmod & GL_NEGATE_BIT_ATI)
  106.       reg0 ^= R200_TXC_NEG_ARG_A << (4*argPos);
  107.  
  108.    SET_INST(opnum, optype) |= reg0;
  109.    SET_INST_2(opnum, optype) |= reg2;
  110. }
  111.  
  112. static GLuint dstmask_table[8] =
  113. {
  114.    R200_TXC_OUTPUT_MASK_RGB,
  115.    R200_TXC_OUTPUT_MASK_R,
  116.    R200_TXC_OUTPUT_MASK_G,
  117.    R200_TXC_OUTPUT_MASK_RG,
  118.    R200_TXC_OUTPUT_MASK_B,
  119.    R200_TXC_OUTPUT_MASK_RB,
  120.    R200_TXC_OUTPUT_MASK_GB,
  121.    R200_TXC_OUTPUT_MASK_RGB
  122. };
  123.  
  124. static void r200UpdateFSArith( struct gl_context *ctx )
  125. {
  126.    r200ContextPtr rmesa = R200_CONTEXT(ctx);
  127.    GLuint *afs_cmd;
  128.    const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current;
  129.    GLuint pass;
  130.  
  131.    R200_STATECHANGE( rmesa, afs[0] );
  132.    R200_STATECHANGE( rmesa, afs[1] );
  133.  
  134.    if (shader->NumPasses < 2) {
  135.       afs_cmd = (GLuint *) rmesa->hw.afs[1].cmd;
  136.    }
  137.    else {
  138.       afs_cmd = (GLuint *) rmesa->hw.afs[0].cmd;
  139.    }
  140.    for (pass = 0; pass < shader->NumPasses; pass++) {
  141.       GLuint opnum = 0;
  142.       GLuint pc;
  143.       for (pc = 0; pc < shader->numArithInstr[pass]; pc++) {
  144.          GLuint optype;
  145.          struct atifs_instruction *inst = &shader->Instructions[pass][pc];
  146.  
  147.          SET_INST(opnum, 0) = 0;
  148.          SET_INST_2(opnum, 0) = 0;
  149.          SET_INST(opnum, 1) = 0;
  150.          SET_INST_2(opnum, 1) = 0;
  151.  
  152.          for (optype = 0; optype < 2; optype++) {
  153.             GLuint tfactor = 0;
  154.  
  155.             if (inst->Opcode[optype]) {
  156.                switch (inst->Opcode[optype]) {
  157.                /* these are all MADD in disguise
  158.                   MADD is A * B + C
  159.                   so for GL_ADD use arg B/C and make A complement 0
  160.                   for GL_SUB use arg B/C, negate C and make A complement 0
  161.                   for GL_MOV use arg C
  162.                   for GL_MUL use arg A
  163.                   for GL_MAD all good */
  164.                case GL_SUB_ATI:
  165.                   /* negate C */
  166.                   SET_INST(opnum, optype) |= R200_TXC_NEG_ARG_C;
  167.                   /* fallthrough */
  168.                case GL_ADD_ATI:
  169.                   r200SetFragShaderArg(afs_cmd, opnum, optype,
  170.                                         inst->SrcReg[optype][0], 1, &tfactor);
  171.                   r200SetFragShaderArg(afs_cmd, opnum, optype,
  172.                                         inst->SrcReg[optype][1], 2, &tfactor);
  173.                   /* A = complement 0 */
  174.                   SET_INST(opnum, optype) |= R200_TXC_COMP_ARG_A;
  175.                   SET_INST(opnum, optype) |= R200_TXC_OP_MADD;
  176.                   break;
  177.                case GL_MOV_ATI:
  178.                   /* put arg0 in C */
  179.                   r200SetFragShaderArg(afs_cmd, opnum, optype,
  180.                                         inst->SrcReg[optype][0], 2, &tfactor);
  181.                   SET_INST(opnum, optype) |= R200_TXC_OP_MADD;
  182.                   break;
  183.                case GL_MAD_ATI:
  184.                   r200SetFragShaderArg(afs_cmd, opnum, optype,
  185.                                         inst->SrcReg[optype][2], 2, &tfactor);
  186.                   /* fallthrough */
  187.                case GL_MUL_ATI:
  188.                   r200SetFragShaderArg(afs_cmd, opnum, optype,
  189.                                         inst->SrcReg[optype][0], 0, &tfactor);
  190.                   r200SetFragShaderArg(afs_cmd, opnum, optype,
  191.                                         inst->SrcReg[optype][1], 1, &tfactor);
  192.                   SET_INST(opnum, optype) |= R200_TXC_OP_MADD;
  193.                   break;
  194.                case GL_LERP_ATI:
  195.                   /* arg order is not native chip order, swap A and C */
  196.                   r200SetFragShaderArg(afs_cmd, opnum, optype,
  197.                                         inst->SrcReg[optype][0], 2, &tfactor);
  198.                   r200SetFragShaderArg(afs_cmd, opnum, optype,
  199.                                         inst->SrcReg[optype][1], 1, &tfactor);
  200.                   r200SetFragShaderArg(afs_cmd, opnum, optype,
  201.                                         inst->SrcReg[optype][2], 0, &tfactor);
  202.                   SET_INST(opnum, optype) |= R200_TXC_OP_LERP;
  203.                   break;
  204.                case GL_CND_ATI:
  205.                   r200SetFragShaderArg(afs_cmd, opnum, optype,
  206.                                         inst->SrcReg[optype][0], 0, &tfactor);
  207.                   r200SetFragShaderArg(afs_cmd, opnum, optype,
  208.                                         inst->SrcReg[optype][1], 1, &tfactor);
  209.                   r200SetFragShaderArg(afs_cmd, opnum, optype,
  210.                                         inst->SrcReg[optype][2], 2, &tfactor);
  211.                   SET_INST(opnum, optype) |= R200_TXC_OP_CONDITIONAL;
  212.                   break;
  213.                case GL_CND0_ATI:
  214.                   r200SetFragShaderArg(afs_cmd, opnum, optype,
  215.                                         inst->SrcReg[optype][0], 0, &tfactor);
  216.                   r200SetFragShaderArg(afs_cmd, opnum, optype,
  217.                                         inst->SrcReg[optype][1], 1, &tfactor);
  218.                   r200SetFragShaderArg(afs_cmd, opnum, optype,
  219.                                         inst->SrcReg[optype][2], 2, &tfactor);
  220.                   SET_INST(opnum, optype) |= R200_TXC_OP_CND0;
  221.                   break;
  222.                   /* cannot specify dot ops as alpha ops directly */
  223.                case GL_DOT2_ADD_ATI:
  224.                   if (optype)
  225.                      SET_INST_2(opnum, 1) |= R200_TXA_DOT_ALPHA;
  226.                   else {
  227.                      r200SetFragShaderArg(afs_cmd, opnum, 0,
  228.                                         inst->SrcReg[0][0], 0, &tfactor);
  229.                      r200SetFragShaderArg(afs_cmd, opnum, 0,
  230.                                         inst->SrcReg[0][1], 1, &tfactor);
  231.                      r200SetFragShaderArg(afs_cmd, opnum, 0,
  232.                                         inst->SrcReg[0][2], 2, &tfactor);
  233.                      SET_INST(opnum, 0) |= R200_TXC_OP_DOT2_ADD;
  234.                   }
  235.                   break;
  236.                case GL_DOT3_ATI:
  237.                   if (optype)
  238.                      SET_INST_2(opnum, 1) |= R200_TXA_DOT_ALPHA;
  239.                   else {
  240.                      r200SetFragShaderArg(afs_cmd, opnum, 0,
  241.                                         inst->SrcReg[0][0], 0, &tfactor);
  242.                      r200SetFragShaderArg(afs_cmd, opnum, 0,
  243.                                         inst->SrcReg[0][1], 1, &tfactor);
  244.                      SET_INST(opnum, 0) |= R200_TXC_OP_DOT3;
  245.                   }
  246.                   break;
  247.                case GL_DOT4_ATI:
  248.                /* experimental verification: for dot4 setup of alpha args is needed
  249.                   (dstmod is ignored, though, so dot2/dot3 should be safe)
  250.                   the hardware apparently does R1*R2 + G1*G2 + B1*B2 + A3*A4
  251.                   but the API doesn't allow it */
  252.                   if (optype)
  253.                      SET_INST_2(opnum, 1) |= R200_TXA_DOT_ALPHA;
  254.                   else {
  255.                      r200SetFragShaderArg(afs_cmd, opnum, 0,
  256.                                         inst->SrcReg[0][0], 0, &tfactor);
  257.                      r200SetFragShaderArg(afs_cmd, opnum, 0,
  258.                                         inst->SrcReg[0][1], 1, &tfactor);
  259.                      r200SetFragShaderArg(afs_cmd, opnum, 1,
  260.                                         inst->SrcReg[0][0], 0, &tfactor);
  261.                      r200SetFragShaderArg(afs_cmd, opnum, 1,
  262.                                         inst->SrcReg[0][1], 1, &tfactor);
  263.                      SET_INST(opnum, optype) |= R200_TXC_OP_DOT4;
  264.                   }
  265.                   break;
  266.                }
  267.             }
  268.  
  269.             /* destination */
  270.             if (inst->DstReg[optype].Index) {
  271.                GLuint dstreg = inst->DstReg[optype].Index - GL_REG_0_ATI;
  272.                GLuint dstmask = inst->DstReg[optype].dstMask;
  273.                GLuint sat = inst->DstReg[optype].dstMod & GL_SATURATE_BIT_ATI;
  274.                GLuint dstmod = inst->DstReg[optype].dstMod;
  275.  
  276.                dstmod &= ~GL_SATURATE_BIT_ATI;
  277.  
  278.                SET_INST_2(opnum, optype) |= (dstreg + 1) << R200_TXC_OUTPUT_REG_SHIFT;
  279.                SET_INST_2(opnum, optype) |= dstmask_table[dstmask];
  280.  
  281.                 /* fglrx does clamp the last instructions to 0_1 it seems */
  282.                 /* this won't necessarily catch the last instruction
  283.                    which writes to reg0 */
  284.                if (sat || (pc == (shader->numArithInstr[pass] - 1) &&
  285.                         ((pass == 1) || (shader->NumPasses == 1))))
  286.                   SET_INST_2(opnum, optype) |= R200_TXC_CLAMP_0_1;
  287.                else
  288.                 /*should we clamp or not? spec is vague, I would suppose yes but fglrx doesn't */
  289.                   SET_INST_2(opnum, optype) |= R200_TXC_CLAMP_8_8;
  290. /*                SET_INST_2(opnum, optype) |= R200_TXC_CLAMP_WRAP;*/
  291.                switch(dstmod) {
  292.                case GL_2X_BIT_ATI:
  293.                   SET_INST_2(opnum, optype) |= R200_TXC_SCALE_2X;
  294.                   break;
  295.                case GL_4X_BIT_ATI:
  296.                   SET_INST_2(opnum, optype) |= R200_TXC_SCALE_4X;
  297.                   break;
  298.                case GL_8X_BIT_ATI:
  299.                   SET_INST_2(opnum, optype) |= R200_TXC_SCALE_8X;
  300.                   break;
  301.                case GL_HALF_BIT_ATI:
  302.                   SET_INST_2(opnum, optype) |= R200_TXC_SCALE_INV2;
  303.                   break;
  304.                case GL_QUARTER_BIT_ATI:
  305.                   SET_INST_2(opnum, optype) |= R200_TXC_SCALE_INV4;
  306.                   break;
  307.                case GL_EIGHTH_BIT_ATI:
  308.                   SET_INST_2(opnum, optype) |= R200_TXC_SCALE_INV8;
  309.                   break;
  310.                default:
  311.                   break;
  312.                }
  313.             }
  314.          }
  315. /*       fprintf(stderr, "pass %d nr %d inst 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
  316.                 pass, opnum, SET_INST(opnum, 0), SET_INST_2(opnum, 0),
  317.                 SET_INST(opnum, 1), SET_INST_2(opnum, 1));*/
  318.          opnum++;
  319.       }
  320.       afs_cmd = (GLuint *) rmesa->hw.afs[1].cmd;
  321.    }
  322.    rmesa->afs_loaded = ctx->ATIFragmentShader.Current;
  323. }
  324.  
  325. static void r200UpdateFSRouting( struct gl_context *ctx ) {
  326.    r200ContextPtr rmesa = R200_CONTEXT(ctx);
  327.    const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current;
  328.    GLuint reg;
  329.  
  330.    R200_STATECHANGE( rmesa, ctx );
  331.    R200_STATECHANGE( rmesa, cst );
  332.  
  333.    for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) {
  334.       if (shader->swizzlerq & (1 << (2 * reg)))
  335.          /* r coord */
  336.          set_re_cntl_d3d( ctx, reg, 1);
  337.          /* q coord */
  338.       else set_re_cntl_d3d( ctx, reg, 0);
  339.    }
  340.  
  341.    rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_MULTI_PASS_ENABLE |
  342.                                        R200_TEX_BLEND_ENABLE_MASK |
  343.                                        R200_TEX_ENABLE_MASK);
  344.    rmesa->hw.cst.cmd[CST_PP_CNTL_X] &= ~(R200_PPX_PFS_INST_ENABLE_MASK |
  345.                                          R200_PPX_TEX_ENABLE_MASK |
  346.                                          R200_PPX_OUTPUT_REG_MASK);
  347.  
  348.    /* first pass registers use slots 8 - 15
  349.       but single pass shaders use slots 0 - 7 */
  350.    if (shader->NumPasses < 2) {
  351.       rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= shader->numArithInstr[0] == 8 ?
  352.          0xff << (R200_TEX_BLEND_0_ENABLE_SHIFT - 1) :
  353.          (0xff >> (8 - shader->numArithInstr[0])) << R200_TEX_BLEND_0_ENABLE_SHIFT;
  354.    } else {
  355.       rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_MULTI_PASS_ENABLE;
  356.       rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= shader->numArithInstr[1] == 8 ?
  357.          0xff << (R200_TEX_BLEND_0_ENABLE_SHIFT - 1) :
  358.          (0xff >> (8 - shader->numArithInstr[1])) << R200_TEX_BLEND_0_ENABLE_SHIFT;
  359.       rmesa->hw.cst.cmd[CST_PP_CNTL_X] |=
  360.          (0xff >> (8 - shader->numArithInstr[0])) << R200_PPX_FPS_INST0_ENABLE_SHIFT;
  361.    }
  362.  
  363.    if (shader->NumPasses < 2) {
  364.       for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) {
  365.          GLbitfield targetbit = ctx->Texture.Unit[reg]._ReallyEnabled;
  366.          R200_STATECHANGE( rmesa, tex[reg] );
  367.          rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = 0;
  368.          if (shader->SetupInst[0][reg].Opcode) {
  369.             GLuint txformat = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT]
  370.                 & ~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);
  371.             GLuint txformat_x = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] & ~R200_TEXCOORD_MASK;
  372.             txformat |= (shader->SetupInst[0][reg].src - GL_TEXTURE0_ARB)
  373.                 << R200_TXFORMAT_ST_ROUTE_SHIFT;
  374.             /* fix up texcoords for proj/non-proj 2d (3d and cube are not defined when
  375.                using projection so don't have to worry there).
  376.                When passing coords, need R200_TEXCOORD_VOLUME, otherwise loose a coord */
  377.             /* FIXME: someone might rely on default tex coords r/q, which we unfortunately
  378.                don't provide (we have the same problem without shaders) */
  379.             if (shader->SetupInst[0][reg].Opcode == ATI_FRAGMENT_SHADER_PASS_OP) {
  380.                txformat |= R200_TXFORMAT_LOOKUP_DISABLE;
  381.                if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||
  382.                   shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
  383.                   txformat_x |= R200_TEXCOORD_VOLUME;
  384.                }
  385.                else {
  386.                   txformat_x |= R200_TEXCOORD_PROJ;
  387.                }
  388.                rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
  389.             }
  390.             else if (targetbit == TEXTURE_3D_BIT) {
  391.                txformat_x |= R200_TEXCOORD_VOLUME;
  392.             }
  393.             else if (targetbit == TEXTURE_CUBE_BIT) {
  394.                txformat_x |= R200_TEXCOORD_CUBIC_ENV;
  395.             }
  396.             else if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||
  397.                shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
  398.                txformat_x |= R200_TEXCOORD_NONPROJ;
  399.             }
  400.             else {
  401.                txformat_x |= R200_TEXCOORD_PROJ;
  402.             }
  403.             rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT] = txformat;
  404.             rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] = txformat_x;
  405.             /* enabling texturing when unit isn't correctly configured may not be safe */
  406.             if (targetbit)
  407.                rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
  408.          }
  409.       }
  410.  
  411.    } else {
  412.       /* setup 1st pass */
  413.       for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) {
  414.          GLbitfield targetbit = ctx->Texture.Unit[reg]._ReallyEnabled;
  415.          R200_STATECHANGE( rmesa, tex[reg] );
  416.          GLuint txformat_multi = 0;
  417.          if (shader->SetupInst[0][reg].Opcode) {
  418.             txformat_multi |= (shader->SetupInst[0][reg].src - GL_TEXTURE0_ARB)
  419.                 << R200_PASS1_ST_ROUTE_SHIFT;
  420.             if (shader->SetupInst[0][reg].Opcode == ATI_FRAGMENT_SHADER_PASS_OP) {
  421.                txformat_multi |= R200_PASS1_TXFORMAT_LOOKUP_DISABLE;
  422.                if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||
  423.                   shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
  424.                   txformat_multi |= R200_PASS1_TEXCOORD_VOLUME;
  425.                }
  426.                else {
  427.                   txformat_multi |= R200_PASS1_TEXCOORD_PROJ;
  428.                }
  429.                rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_0_ENABLE << reg;
  430.             }
  431.             else if (targetbit == TEXTURE_3D_BIT) {
  432.                txformat_multi |= R200_PASS1_TEXCOORD_VOLUME;
  433.             }
  434.             else if (targetbit == TEXTURE_CUBE_BIT) {
  435.                txformat_multi |= R200_PASS1_TEXCOORD_CUBIC_ENV;
  436.             }
  437.             else if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||
  438.                   shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
  439.                   txformat_multi |= R200_PASS1_TEXCOORD_NONPROJ;
  440.             }
  441.             else {
  442.                txformat_multi |= R200_PASS1_TEXCOORD_PROJ;
  443.             }
  444.             if (targetbit)
  445.                rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_0_ENABLE << reg;
  446.          }
  447.          rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = txformat_multi;
  448.       }
  449.  
  450.       /* setup 2nd pass */
  451.       for (reg=0; reg < R200_MAX_TEXTURE_UNITS; reg++) {
  452.          GLbitfield targetbit = ctx->Texture.Unit[reg]._ReallyEnabled;
  453.          if (shader->SetupInst[1][reg].Opcode) {
  454.             GLuint coord = shader->SetupInst[1][reg].src;
  455.             GLuint txformat = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT]
  456.                 & ~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);
  457.             GLuint txformat_x = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] & ~R200_TEXCOORD_MASK;
  458.             R200_STATECHANGE( rmesa, tex[reg] );
  459.             if (shader->SetupInst[1][reg].Opcode == ATI_FRAGMENT_SHADER_PASS_OP) {
  460.                txformat |= R200_TXFORMAT_LOOKUP_DISABLE;
  461.                txformat_x |= R200_TEXCOORD_VOLUME;
  462.                if (shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STR_ATI ||
  463.                   shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
  464.                   txformat_x |= R200_TEXCOORD_VOLUME;
  465.                }
  466.                else {
  467.                   txformat_x |= R200_TEXCOORD_PROJ;
  468.                }
  469.                rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
  470.             }
  471.             else if (targetbit == TEXTURE_3D_BIT) {
  472.                txformat_x |= R200_TEXCOORD_VOLUME;
  473.             }
  474.             else if (targetbit == TEXTURE_CUBE_BIT) {
  475.                txformat_x |= R200_TEXCOORD_CUBIC_ENV;
  476.             }
  477.             else if (shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STR_ATI ||
  478.                shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
  479.                txformat_x |= R200_TEXCOORD_NONPROJ;
  480.             }
  481.             else {
  482.                txformat_x |= R200_TEXCOORD_PROJ;
  483.             }
  484.             if (coord >= GL_REG_0_ATI) {
  485.                GLuint txformat_multi = rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL];
  486.                txformat_multi |= (coord - GL_REG_0_ATI + 2) << R200_PASS2_COORDS_REG_SHIFT;
  487.                rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = txformat_multi;
  488.                rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= 1 <<
  489.                   (R200_PPX_OUTPUT_REG_0_SHIFT + coord - GL_REG_0_ATI);
  490.             } else {
  491.                txformat |= (coord - GL_TEXTURE0_ARB) << R200_TXFORMAT_ST_ROUTE_SHIFT;
  492.             }
  493.             rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] = txformat_x;
  494.             rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT] = txformat;
  495.             if (targetbit)
  496.                rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
  497.          }
  498.       }
  499.    }
  500. }
  501.  
  502. static void r200UpdateFSConstants( struct gl_context *ctx )
  503. {
  504.    r200ContextPtr rmesa = R200_CONTEXT(ctx);
  505.    const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current;
  506.    GLuint i;
  507.  
  508.    /* update constants */
  509.    R200_STATECHANGE(rmesa, atf);
  510.    for (i = 0; i < 8; i++)
  511.    {
  512.       GLubyte con_byte[4];
  513.       if ((shader->LocalConstDef >> i) & 1) {
  514.          CLAMPED_FLOAT_TO_UBYTE(con_byte[0], shader->Constants[i][0]);
  515.          CLAMPED_FLOAT_TO_UBYTE(con_byte[1], shader->Constants[i][1]);
  516.          CLAMPED_FLOAT_TO_UBYTE(con_byte[2], shader->Constants[i][2]);
  517.          CLAMPED_FLOAT_TO_UBYTE(con_byte[3], shader->Constants[i][3]);
  518.       }
  519.       else {
  520.          CLAMPED_FLOAT_TO_UBYTE(con_byte[0], ctx->ATIFragmentShader.GlobalConstants[i][0]);
  521.          CLAMPED_FLOAT_TO_UBYTE(con_byte[1], ctx->ATIFragmentShader.GlobalConstants[i][1]);
  522.          CLAMPED_FLOAT_TO_UBYTE(con_byte[2], ctx->ATIFragmentShader.GlobalConstants[i][2]);
  523.          CLAMPED_FLOAT_TO_UBYTE(con_byte[3], ctx->ATIFragmentShader.GlobalConstants[i][3]);
  524.       }
  525.       rmesa->hw.atf.cmd[ATF_TFACTOR_0 + i] = radeonPackColor (
  526.          4, con_byte[0], con_byte[1], con_byte[2], con_byte[3] );
  527.    }
  528. }
  529.  
  530. /* update routing, constants and arithmetic
  531.  * constants need to be updated always (globals can change, no separate notification)
  532.  * routing needs to be updated always too (non-shader code will overwrite state, plus
  533.  * some of the routing depends on what sort of texture is bound)
  534.  * for both of them, we need to update anyway because of disabling/enabling ati_fs which
  535.  * we'd need to track otherwise
  536.  * arithmetic is only updated if current shader changes (and probably the data should be
  537.  * stored in some DriverData object attached to the mesa atifs object, i.e. binding a
  538.  * shader wouldn't force us to "recompile" the shader).
  539.  */
  540. void r200UpdateFragmentShader( struct gl_context *ctx )
  541. {
  542.    r200ContextPtr rmesa = R200_CONTEXT(ctx);
  543.  
  544.    r200UpdateFSConstants( ctx );
  545.    r200UpdateFSRouting( ctx );
  546.    if (rmesa->afs_loaded != ctx->ATIFragmentShader.Current)
  547.       r200UpdateFSArith( ctx );
  548. }
  549.