/**************************************************************************
 * 
 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
 * All Rights Reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * 
 **************************************************************************/

#include "glheader.h"
#include "macros.h"
#include "mtypes.h"
#include "simple_list.h"
#include "enums.h"
#include "texformat.h"
#include "texstore.h"

#include "mm.h"

#include "intel_screen.h"
#include "intel_ioctl.h"
#include "intel_tex.h"

#include "i830_context.h"
#include "i830_reg.h"


/* ================================================================
 * Texture combine functions
 */
static GLuint
pass_through(GLuint * state, GLuint blendUnit)
{
   state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
               TEXPIPE_COLOR |
               ENABLE_TEXOUTPUT_WRT_SEL |
               TEXOP_OUTPUT_CURRENT |
               DISABLE_TEX_CNTRL_STAGE |
               TEXOP_SCALE_1X | TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1);
   state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
               TEXPIPE_ALPHA |
               ENABLE_TEXOUTPUT_WRT_SEL |
               TEXOP_OUTPUT_CURRENT |
               TEXOP_SCALE_1X | TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1);
   state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
               TEXPIPE_COLOR |
               TEXBLEND_ARG1 |
               TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_CURRENT);
   state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
               TEXPIPE_ALPHA |
               TEXBLEND_ARG1 |
               TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_CURRENT);

   return 4;
}

static GLuint
emit_factor(GLuint blendUnit, GLuint * state, GLuint count,
            const GLfloat * factor)
{
   GLubyte r, g, b, a;
   GLuint col;

   if (0)
      fprintf(stderr, "emit constant %d: %.2f %.2f %.2f %.2f\n",
              blendUnit, factor[0], factor[1], factor[2], factor[3]);

   UNCLAMPED_FLOAT_TO_UBYTE(r, factor[0]);
   UNCLAMPED_FLOAT_TO_UBYTE(g, factor[1]);
   UNCLAMPED_FLOAT_TO_UBYTE(b, factor[2]);
   UNCLAMPED_FLOAT_TO_UBYTE(a, factor[3]);

   col = ((a << 24) | (r << 16) | (g << 8) | b);

   state[count++] = _3DSTATE_COLOR_FACTOR_N_CMD(blendUnit);
   state[count++] = col;

   return count;
}


static INLINE GLuint
GetTexelOp(GLint unit)
{
   switch (unit) {
   case 0:
      return TEXBLENDARG_TEXEL0;
   case 1:
      return TEXBLENDARG_TEXEL1;
   case 2:
      return TEXBLENDARG_TEXEL2;
   case 3:
      return TEXBLENDARG_TEXEL3;
   default:
      return TEXBLENDARG_TEXEL0;
   }
}


/**
 * Calculate the hardware instuctions to setup the current texture enviromnemt
 * settings.  Since \c gl_texture_unit::_CurrentCombine is used, both
 * "classic" texture enviroments and GL_ARB_texture_env_combine type texture
 * environments are treated identically.
 *
 * \todo
 * This function should return \c GLboolean.  When \c GL_FALSE is returned,
 * it means that an environment is selected that the hardware cannot do.  This
 * is the way the Radeon and R200 drivers work.
 * 
 * \todo
 * Looking at i830_3d_regs.h, it seems the i830 can do part of
 * GL_ATI_texture_env_combine3.  It can handle using \c GL_ONE and
 * \c GL_ZERO as combine inputs (which the code already supports).  It can
 * also handle the \c GL_MODULATE_ADD_ATI mode.  Is it worth investigating
 * partial support for the extension?
 */
GLuint
i830SetTexEnvCombine(struct i830_context * i830,
                     const struct gl_tex_env_combine_state * combine,
                     GLint blendUnit,
                     GLuint texel_op, GLuint * state, const GLfloat * factor)
{
   const GLuint numColorArgs = combine->_NumArgsRGB;
   const GLuint numAlphaArgs = combine->_NumArgsA;

   GLuint blendop;
   GLuint ablendop;
   GLuint args_RGB[3];
   GLuint args_A[3];
   GLuint rgb_shift;
   GLuint alpha_shift;
   GLboolean need_factor = 0;
   int i;
   unsigned used;
   static const GLuint tex_blend_rgb[3] = {
      TEXPIPE_COLOR | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS,
      TEXPIPE_COLOR | TEXBLEND_ARG2 | TEXBLENDARG_MODIFY_PARMS,
      TEXPIPE_COLOR | TEXBLEND_ARG0 | TEXBLENDARG_MODIFY_PARMS,
   };
   static const GLuint tex_blend_a[3] = {
      TEXPIPE_ALPHA | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS,
      TEXPIPE_ALPHA | TEXBLEND_ARG2 | TEXBLENDARG_MODIFY_PARMS,
      TEXPIPE_ALPHA | TEXBLEND_ARG0 | TEXBLENDARG_MODIFY_PARMS,
   };

   if (INTEL_DEBUG & DEBUG_TEXTURE)
      fprintf(stderr, "%s\n", __FUNCTION__);


   /* The EXT version of the DOT3 extension does not support the
    * scale factor, but the ARB version (and the version in OpenGL
    * 1.3) does.
    */
   switch (combine->ModeRGB) {
   case GL_DOT3_RGB_EXT:
      alpha_shift = combine->ScaleShiftA;
      rgb_shift = 0;
      break;

   case GL_DOT3_RGBA_EXT:
      alpha_shift = 0;
      rgb_shift = 0;
      break;

   default:
      rgb_shift = combine->ScaleShiftRGB;
      alpha_shift = combine->ScaleShiftA;
      break;
   }


   switch (combine->ModeRGB) {
   case GL_REPLACE:
      blendop = TEXBLENDOP_ARG1;
      break;
   case GL_MODULATE:
      blendop = TEXBLENDOP_MODULATE;
      break;
   case GL_ADD:
      blendop = TEXBLENDOP_ADD;
      break;
   case GL_ADD_SIGNED:
      blendop = TEXBLENDOP_ADDSIGNED;
      break;
   case GL_INTERPOLATE:
      blendop = TEXBLENDOP_BLEND;
      break;
   case GL_SUBTRACT:
      blendop = TEXBLENDOP_SUBTRACT;
      break;
   case GL_DOT3_RGB_EXT:
   case GL_DOT3_RGB:
      blendop = TEXBLENDOP_DOT3;
      break;
   case GL_DOT3_RGBA_EXT:
   case GL_DOT3_RGBA:
      blendop = TEXBLENDOP_DOT3;
      break;
   default:
      return pass_through(state, blendUnit);
   }

   blendop |= (rgb_shift << TEXOP_SCALE_SHIFT);


   /* Handle RGB args */
   for (i = 0; i < 3; i++) {
      switch (combine->SourceRGB[i]) {
      case GL_TEXTURE:
         args_RGB[i] = texel_op;
         break;
      case GL_TEXTURE0:
      case GL_TEXTURE1:
      case GL_TEXTURE2:
      case GL_TEXTURE3:
         args_RGB[i] = GetTexelOp(combine->SourceRGB[i] - GL_TEXTURE0);
         break;
      case GL_CONSTANT:
         args_RGB[i] = TEXBLENDARG_FACTOR_N;
         need_factor = 1;
         break;
      case GL_PRIMARY_COLOR:
         args_RGB[i] = TEXBLENDARG_DIFFUSE;
         break;
      case GL_PREVIOUS:
         args_RGB[i] = TEXBLENDARG_CURRENT;
         break;
      default:
         return pass_through(state, blendUnit);
      }

      switch (combine->OperandRGB[i]) {
      case GL_SRC_COLOR:
         args_RGB[i] |= 0;
         break;
      case GL_ONE_MINUS_SRC_COLOR:
         args_RGB[i] |= TEXBLENDARG_INV_ARG;
         break;
      case GL_SRC_ALPHA:
         args_RGB[i] |= TEXBLENDARG_REPLICATE_ALPHA;
         break;
      case GL_ONE_MINUS_SRC_ALPHA:
         args_RGB[i] |= (TEXBLENDARG_REPLICATE_ALPHA | TEXBLENDARG_INV_ARG);
         break;
      default:
         return pass_through(state, blendUnit);
      }
   }


   /* Need to knobble the alpha calculations of TEXBLENDOP_DOT4 to
    * match the spec.  Can't use DOT3 as it won't propogate values
    * into alpha as required:
    *
    * Note - the global factor is set up with alpha == .5, so 
    * the alpha part of the DOT4 calculation should be zero.
    */
   if (combine->ModeRGB == GL_DOT3_RGBA_EXT ||
       combine->ModeRGB == GL_DOT3_RGBA) {
      ablendop = TEXBLENDOP_DOT4;
      args_A[0] = TEXBLENDARG_FACTOR;   /* the global factor */
      args_A[1] = TEXBLENDARG_FACTOR;
      args_A[2] = TEXBLENDARG_FACTOR;
   }
   else {
      switch (combine->ModeA) {
      case GL_REPLACE:
         ablendop = TEXBLENDOP_ARG1;
         break;
      case GL_MODULATE:
         ablendop = TEXBLENDOP_MODULATE;
         break;
      case GL_ADD:
         ablendop = TEXBLENDOP_ADD;
         break;
      case GL_ADD_SIGNED:
         ablendop = TEXBLENDOP_ADDSIGNED;
         break;
      case GL_INTERPOLATE:
         ablendop = TEXBLENDOP_BLEND;
         break;
      case GL_SUBTRACT:
         ablendop = TEXBLENDOP_SUBTRACT;
         break;
      default:
         return pass_through(state, blendUnit);
      }


      ablendop |= (alpha_shift << TEXOP_SCALE_SHIFT);

      /* Handle A args */
      for (i = 0; i < 3; i++) {
         switch (combine->SourceA[i]) {
         case GL_TEXTURE:
            args_A[i] = texel_op;
            break;
         case GL_TEXTURE0:
         case GL_TEXTURE1:
         case GL_TEXTURE2:
         case GL_TEXTURE3:
            args_A[i] = GetTexelOp(combine->SourceA[i] - GL_TEXTURE0);
            break;
         case GL_CONSTANT:
            args_A[i] = TEXBLENDARG_FACTOR_N;
            need_factor = 1;
            break;
         case GL_PRIMARY_COLOR:
            args_A[i] = TEXBLENDARG_DIFFUSE;
            break;
         case GL_PREVIOUS:
            args_A[i] = TEXBLENDARG_CURRENT;
            break;
         default:
            return pass_through(state, blendUnit);
         }

         switch (combine->OperandA[i]) {
         case GL_SRC_ALPHA:
            args_A[i] |= 0;
            break;
         case GL_ONE_MINUS_SRC_ALPHA:
            args_A[i] |= TEXBLENDARG_INV_ARG;
            break;
         default:
            return pass_through(state, blendUnit);
         }
      }
   }



   /* Native Arg1 == Arg0 in GL_EXT_texture_env_combine spec */
   /* Native Arg2 == Arg1 in GL_EXT_texture_env_combine spec */
   /* Native Arg0 == Arg2 in GL_EXT_texture_env_combine spec */

   /* When we render we need to figure out which is the last really enabled
    * tex unit, and put last stage on it
    */


   /* Build color & alpha pipelines */

   used = 0;
   state[used++] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
                    TEXPIPE_COLOR |
                    ENABLE_TEXOUTPUT_WRT_SEL |
                    TEXOP_OUTPUT_CURRENT |
                    DISABLE_TEX_CNTRL_STAGE | TEXOP_MODIFY_PARMS | blendop);
   state[used++] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) |
                    TEXPIPE_ALPHA |
                    ENABLE_TEXOUTPUT_WRT_SEL |
                    TEXOP_OUTPUT_CURRENT | TEXOP_MODIFY_PARMS | ablendop);

   for (i = 0; i < numColorArgs; i++) {
      state[used++] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
                       tex_blend_rgb[i] | args_RGB[i]);
   }

   for (i = 0; i < numAlphaArgs; i++) {
      state[used++] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) |
                       tex_blend_a[i] | args_A[i]);
   }


   if (need_factor)
      return emit_factor(blendUnit, state, used, factor);
   else
      return used;
}


static void
emit_texblend(struct i830_context *i830, GLuint unit, GLuint blendUnit,
              GLboolean last_stage)
{
   struct gl_texture_unit *texUnit = &i830->intel.ctx.Texture.Unit[unit];
   GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz;


   if (0)
      fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit);

   /* Update i830->state.TexBlend
    */
   tmp_sz = i830SetTexEnvCombine(i830, texUnit->_CurrentCombine, blendUnit,
                                 GetTexelOp(unit), tmp, texUnit->EnvColor);

   if (last_stage)
      tmp[0] |= TEXOP_LAST_STAGE;

   if (tmp_sz != i830->state.TexBlendWordsUsed[blendUnit] ||
       memcmp(tmp, i830->state.TexBlend[blendUnit],
              tmp_sz * sizeof(GLuint))) {

      I830_STATECHANGE(i830, I830_UPLOAD_TEXBLEND(blendUnit));
      memcpy(i830->state.TexBlend[blendUnit], tmp, tmp_sz * sizeof(GLuint));
      i830->state.TexBlendWordsUsed[blendUnit] = tmp_sz;
   }

   I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(blendUnit), GL_TRUE);
}

static void
emit_passthrough(struct i830_context *i830)
{
   GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz;
   GLuint unit = 0;

   tmp_sz = pass_through(tmp, unit);
   tmp[0] |= TEXOP_LAST_STAGE;

   if (tmp_sz != i830->state.TexBlendWordsUsed[unit] ||
       memcmp(tmp, i830->state.TexBlend[unit], tmp_sz * sizeof(GLuint))) {

      I830_STATECHANGE(i830, I830_UPLOAD_TEXBLEND(unit));
      memcpy(i830->state.TexBlend[unit], tmp, tmp_sz * sizeof(GLuint));
      i830->state.TexBlendWordsUsed[unit] = tmp_sz;
   }

   I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(unit), GL_TRUE);
}

void
i830EmitTextureBlend(struct i830_context *i830)
{
   GLcontext *ctx = &i830->intel.ctx;
   GLuint unit, last_stage = 0, blendunit = 0;

   I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND_ALL, GL_FALSE);

   if (ctx->Texture._EnabledUnits) {
      for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++)
         if (ctx->Texture.Unit[unit]._ReallyEnabled)
            last_stage = unit;

      for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++)
         if (ctx->Texture.Unit[unit]._ReallyEnabled)
            emit_texblend(i830, unit, blendunit++, last_stage == unit);
   }
   else {
      emit_passthrough(i830);
   }
}
