/*
 Copyright (C) Intel Corp.  2006.  All Rights Reserved.
 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
 develop this 3D driver.
 
 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, sublicense, 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 NONINFRINGEMENT.
 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
 
 **********************************************************************/
 /*
  * Authors:
  *   Keith Whitwell <keith@tungstengraphics.com>
  */
                  

#include "brw_context.h"
#include "brw_wm.h"


static GLuint get_tracked_mask(struct brw_wm_compile *c,
			       struct brw_wm_instruction *inst)
{
   GLuint i;
   for (i = 0; i < 4; i++) {
      if (inst->writemask & (1<<i)) {
	 if (!inst->dst[i]->contributes_to_output) {
	    inst->writemask &= ~(1<<i);
	    inst->dst[i] = 0;
	 }
      }
   }

   return inst->writemask;
}

/* Remove a reference from a value's usage chain.
 */
static void unlink_ref(struct brw_wm_ref *ref)
{
   struct brw_wm_value *value = ref->value;

   if (ref == value->lastuse) {
      value->lastuse = ref->prevuse;
   } else {
      struct brw_wm_ref *i = value->lastuse;
      while (i->prevuse != ref) i = i->prevuse;
      i->prevuse = ref->prevuse;
   }
}

static void track_arg(struct brw_wm_compile *c,
		      struct brw_wm_instruction *inst,
		      GLuint arg,
		      GLuint readmask)
{
   GLuint i;

   for (i = 0; i < 4; i++) {
      struct brw_wm_ref *ref = inst->src[arg][i];
      if (ref) {
	 if (readmask & (1<<i)) 
	    ref->value->contributes_to_output = 1;
	 else {
	    unlink_ref(ref);
	    inst->src[arg][i] = NULL;
	 }
      }
   }
}

static GLuint get_texcoord_mask( GLuint tex_idx )
{
   switch (tex_idx) {
   case TEXTURE_1D_INDEX: return WRITEMASK_X;
   case TEXTURE_2D_INDEX: return WRITEMASK_XY;
   case TEXTURE_3D_INDEX: return WRITEMASK_XYZ;
   case TEXTURE_CUBE_INDEX: return WRITEMASK_XYZ;
   case TEXTURE_RECT_INDEX: return WRITEMASK_XY;
   default: return 0;
   }
}

/* Step two: Basically this is dead code elimination.  
 *
 * Iterate backwards over instructions, noting which values
 * contribute to the final result.  Adjust writemasks to only
 * calculate these values.
 */
void brw_wm_pass1( struct brw_wm_compile *c )
{
   GLint insn;

   for (insn = c->nr_insns-1; insn >= 0; insn--) {
      struct brw_wm_instruction *inst = &c->instruction[insn];
      GLuint writemask;
      GLuint read0, read1, read2;

      if (inst->opcode == OPCODE_KIL) {
	 track_arg(c, inst, 0, WRITEMASK_XYZW); /* All args contribute to final */
	 continue;
      }

      if (inst->opcode == WM_FB_WRITE) {
	 track_arg(c, inst, 0, WRITEMASK_XYZW); 
	 track_arg(c, inst, 1, WRITEMASK_XYZW); 
	 if (c->key.source_depth_to_render_target &&
	     c->key.computes_depth)
	    track_arg(c, inst, 2, WRITEMASK_Z); 
	 else
	    track_arg(c, inst, 2, 0); 
	 continue;
      }

      /* Lookup all the registers which were written by this
       * instruction and get a mask of those that contribute to the output:
       */
      writemask = get_tracked_mask(c, inst);
      if (!writemask) {
	 GLuint arg;
	 for (arg = 0; arg < 3; arg++)
	    track_arg(c, inst, arg, 0);
	 continue;
      }

      read0 = 0;
      read1 = 0;
      read2 = 0;

      /* Mark all inputs which contribute to the marked outputs:
       */
      switch (inst->opcode) {
      case OPCODE_ABS:
      case OPCODE_FLR:
      case OPCODE_FRC:
      case OPCODE_MOV:
      case OPCODE_SWZ:
	 read0 = writemask;
	 break;

      case OPCODE_SUB:
      case OPCODE_SLT:
      case OPCODE_SLE:
      case OPCODE_SGE:
      case OPCODE_SGT:
      case OPCODE_SEQ:
      case OPCODE_SNE:
      case OPCODE_ADD:
      case OPCODE_MAX:
      case OPCODE_MIN:
      case OPCODE_MUL:
	 read0 = writemask;
	 read1 = writemask;
	 break;

      case OPCODE_MAD:	
      case OPCODE_CMP:
      case OPCODE_LRP:
	 read0 = writemask;
	 read1 = writemask;	
	 read2 = writemask;	
	 break;

      case OPCODE_XPD: 
	 if (writemask & WRITEMASK_X) read0 |= WRITEMASK_YZ;	 
	 if (writemask & WRITEMASK_Y) read0 |= WRITEMASK_XZ;	 
	 if (writemask & WRITEMASK_Z) read0 |= WRITEMASK_XY;
	 read1 = read0;
	 break;

      case OPCODE_COS:
      case OPCODE_EX2:
      case OPCODE_LG2:
      case OPCODE_RCP:
      case OPCODE_RSQ:
      case OPCODE_SIN:
      case OPCODE_SCS:
      case WM_CINTERP:
      case WM_PIXELXY:
	 read0 = WRITEMASK_X;
	 break;

      case OPCODE_POW:
	 read0 = WRITEMASK_X;
	 read1 = WRITEMASK_X;
	 break;

      case OPCODE_TEX:
	 read0 = get_texcoord_mask(inst->tex_idx);

	 if (c->key.shadowtex_mask & (1<<inst->tex_unit))
	    read0 |= WRITEMASK_Z;
	 break;

      case OPCODE_TXB:
	 /* Shadow ignored for txb.
	  */
	 read0 = get_texcoord_mask(inst->tex_idx) | WRITEMASK_W;
	 break;

      case WM_WPOSXY:
	 read0 = writemask & WRITEMASK_XY;
	 break;

      case WM_DELTAXY:
	 read0 = writemask & WRITEMASK_XY;
	 read1 = WRITEMASK_X;
	 break;

      case WM_PIXELW:
	 read0 = WRITEMASK_X;
	 read1 = WRITEMASK_XY;
	 break;

      case WM_LINTERP:
	 read0 = WRITEMASK_X;
	 read1 = WRITEMASK_XY;
	 break;

      case WM_PINTERP:
	 read0 = WRITEMASK_X; /* interpolant */
	 read1 = WRITEMASK_XY; /* deltas */
	 read2 = WRITEMASK_W; /* pixel w */
	 break;

      case OPCODE_DP3:	
	 read0 = WRITEMASK_XYZ;
	 read1 = WRITEMASK_XYZ;
	 break;

      case OPCODE_DPH:
	 read0 = WRITEMASK_XYZ;
	 read1 = WRITEMASK_XYZW;
	 break;

      case OPCODE_DP4:
	 read0 = WRITEMASK_XYZW;
	 read1 = WRITEMASK_XYZW;
	 break;

      case OPCODE_LIT: 
	 read0 = WRITEMASK_XYW;
	 break;

      case OPCODE_DST:
      case OPCODE_TXP:
      default:
	 break;
      }

      track_arg(c, inst, 0, read0);
      track_arg(c, inst, 1, read1);
      track_arg(c, inst, 2, read2);
   }

   if (INTEL_DEBUG & DEBUG_WM) {
      brw_wm_print_program(c, "pass1");
   }
}



