/**************************************************************************
 * 
 * Copyright 2003 VMware, Inc.
 * 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 VMWARE 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 "main/glheader.h"
#include "main/macros.h"
#include "main/mtypes.h"
#include "main/enums.h"
#include "main/mm.h"

#include "intel_screen.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 bool.  When \c 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;
   GLuint numAlphaArgs = combine->_NumArgsA;

   GLuint blendop;
   GLuint ablendop;
   GLuint args_RGB[3];
   GLuint args_A[3];
   GLuint rgb_shift;
   GLuint alpha_shift;
   bool 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", __func__);


   /* 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_DOT4;
      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;
      numAlphaArgs = 2;
      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,
              bool 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", __func__, 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), 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), true);
}

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

   I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND_ALL, false);

   if (ctx->Texture._MaxEnabledTexImageUnit != -1) {
      for (unit = 0; unit <= ctx->Texture._MaxEnabledTexImageUnit; unit++)
         if (ctx->Texture.Unit[unit]._Current)
            emit_texblend(i830, unit, blendunit++,
                          unit == ctx->Texture._MaxEnabledTexImageUnit);
   } else {
      emit_passthrough(i830);
   }
}
