i965: always call dri_emit_reloc when creating clip unit state
[mesa.git] / src / mesa / drivers / dri / unichrome / via_texcombine.c
index b0afb57364ee4cbd5115a71fc45de631c928916c..d604457bfd8c3d5bc97bc47bbc625da8f3534f6d 100644 (file)
 #include "macros.h"
 #include "colormac.h"
 #include "enums.h"
-#include "dd.h"
 
-#include "mm.h"
 #include "via_context.h"
 #include "via_state.h"
 #include "via_tex.h"
-#include "via_tris.h"
-#include "via_ioctl.h"
+#include "via_3d_reg.h"
 
-#include "swrast/swrast.h"
-#include "array_cache/acache.h"
-#include "tnl/tnl.h"
-#include "swrast_setup/swrast_setup.h"
-
-#include "tnl/t_pipeline.h"
 
 #define VIA_USE_ALPHA (HC_XTC_Adif - HC_XTC_Dif)
 
@@ -58,7 +49,6 @@
 #define INPUT_B_SHIFT     7
 #define INPUT_C_SHIFT     0
 #define INPUT_CBias_SHIFT 14
-#define INPUT_ABias_SHIFT 3
 
 #define CONST_ONE         (HC_XTC_0 | HC_XTC_InvTOPC)
 
@@ -73,6 +63,11 @@ static const unsigned alpha_operand_modifier[2] = {
    0, HC_XTA_InvTOPA
 };
 
+static const unsigned bias_alpha_operand_modifier[2] = {
+   0, HC_HTXnTBLAbias_Inv
+};
+
+
 static const unsigned c_shift_table[3] = {
    HC_HTXnTBLCshift_No, HC_HTXnTBLCshift_1, HC_HTXnTBLCshift_2
 };
@@ -86,31 +81,26 @@ static const unsigned  a_shift_table[3] = {
  * Calculate the hardware state for the specified texture combine mode
  *
  * \bug
- * For the alpha combine, \c GL_CONSTANT is still probably wrong.
- *
- * \bug
  * All forms of DOT3 bumpmapping are completely untested, and are most
- * likely wrong.
- *
- * \bug
- * This code still fails progs/demos/texenv for all modes with \c GL_ALPHA
- * textures.  This was also the case with the code that Via supplied.  It
- * also fails for \c GL_REPLACE with \c GL_RGBA textures.  Everything else
- * that texenv tests looks good.
+ * likely wrong.  KW: Looks like it will never be quite right as the
+ * hardware seems to experience overflow in color calculation at the
+ * 4x shift levels, which need to be programed for DOT3.  Maybe newer
+ * hardware fixes these issues.
  *
  * \bug 
  * KW: needs attention to the case where texunit 1 is enabled but
  * texunit 0 is not.
  */
-void
-viaTexCombineState( viaContextPtr vmesa,
+GLboolean
+viaTexCombineState( struct via_context *vmesa,
                    const struct gl_tex_env_combine_state * combine,
                    unsigned unit )
 {
    unsigned color_arg[3];
    unsigned alpha_arg[3];
-   unsigned color = 0;
-   unsigned alpha = 0;
+   unsigned bias_alpha_arg[3];
+   unsigned color = HC_HTXnTBLCsat_MASK;
+   unsigned alpha = HC_HTXnTBLAsat_MASK;
    unsigned bias = 0;
    unsigned op = 0;
    unsigned a_shift = combine->ScaleShiftA;
@@ -118,11 +108,19 @@ viaTexCombineState( viaContextPtr vmesa,
    unsigned i;
    unsigned constant_color[3];
    unsigned ordered_constant_color[4];
-   unsigned constant_alpha = 0;
+   unsigned constant_alpha[3];
    unsigned bias_alpha = 0;
-   const struct gl_texture_unit const * texUnit = & vmesa->glCtx->Texture.Unit[unit];
+   unsigned abc_alpha = 0;
+   const struct gl_texture_unit * texUnit = 
+      &vmesa->glCtx->Texture.Unit[unit];
    unsigned env_color[4];
 
+   /* It seems that the color clamping can be overwhelmed at the 4x
+    * scale settings, necessitating this fallback:
+    */
+   if (c_shift == 2 || a_shift == 2) {
+      return GL_FALSE;
+   }
 
    CLAMPED_FLOAT_TO_UBYTE(env_color[0], texUnit->EnvColor[0]);
    CLAMPED_FLOAT_TO_UBYTE(env_color[1], texUnit->EnvColor[1]);
@@ -131,6 +129,7 @@ viaTexCombineState( viaContextPtr vmesa,
 
    (void) memset( constant_color, 0, sizeof( constant_color ) );
    (void) memset( ordered_constant_color, 0, sizeof( ordered_constant_color ) );
+   (void) memset( constant_alpha, 0, sizeof( constant_alpha ) );
 
    for ( i = 0 ; i < combine->_NumArgsRGB ; i++ ) {
       const GLint op = combine->OperandRGB[i] - GL_SRC_COLOR;
@@ -177,30 +176,6 @@ viaTexCombineState( viaContextPtr vmesa,
       }
    }
        
-   for ( i = 0 ; i < combine->_NumArgsA ; i++ ) {
-      const GLint op = combine->OperandA[i] - GL_SRC_ALPHA;
-
-      switch ( combine->SourceA[i] ) {
-      case GL_TEXTURE:
-        alpha_arg[i] = HC_XTA_Atex;
-        alpha_arg[i] += alpha_operand_modifier[op];
-        break;
-      case GL_CONSTANT:
-        alpha_arg[i] = HC_XTA_HTXnTBLRA;
-        constant_alpha = (op == 0) 
-          ? env_color[3] : ~(env_color[3]) & 0x000000ff;
-        break;
-      case GL_PRIMARY_COLOR:
-        alpha_arg[i] = HC_XTA_Adif;
-        alpha_arg[i] += alpha_operand_modifier[op];
-        break;
-      case GL_PREVIOUS:
-        alpha_arg[i] = (unit == 0) ? HC_XTA_Adif : HC_XTA_Acur;
-        alpha_arg[i] += alpha_operand_modifier[op];
-        break;
-      }
-   }
-
    
    /* On the Unichrome, all combine operations take on some form of:
     *
@@ -210,30 +185,32 @@ viaTexCombineState( viaContextPtr vmesa,
     * and mask modes are currently unused.  With the exception of DOT3, all
     * standard GL_COMBINE modes can be implemented simply by selecting the
     * correct inputs for A, B, C, and Bias and the correct operation for op.
+    *
+    * NOTE: xBias (when read from the constant registers) is signed,
+    * and scaled to fit -255..255 in 8 bits, ie 0x1 == 2.
     */
 
-   color = HC_HTXnTBLCsat_MASK;
-   alpha = HC_HTXnTBLAsat_MASK;
-
    switch( combine->ModeRGB ) {
-   /* Ca = 0, Cb = 0, Cc = 0, Cbias = arg0
+   /* Ca = 1.0, Cb = arg0, Cc = 0, Cbias = 0
     */
    case GL_REPLACE:
-      bias |= (color_arg[0] << INPUT_CBias_SHIFT); 
-      ordered_constant_color[3] = constant_color[0];
+      color |= ((CONST_ONE << INPUT_A_SHIFT) |
+               (color_arg[0] << INPUT_B_SHIFT));
+               
+      ordered_constant_color[1] = constant_color[0];
       break;
       
    /* Ca = arg[0], Cb = arg[1], Cc = 0, Cbias = 0
     */
    case GL_MODULATE:
-      color |= (color_arg[0] << INPUT_A_SHIFT)
-       | (color_arg[1] << INPUT_B_SHIFT);
+      color |= ((color_arg[0] << INPUT_A_SHIFT) | 
+               (color_arg[1] << INPUT_B_SHIFT));
 
       ordered_constant_color[0] = constant_color[0];
       ordered_constant_color[1] = constant_color[1];
       break;
 
-   /* Ca = 1.0, Cb = arg[0], Cc = 0, Cbias = arg[1]
+   /* Ca = 1.0, Cb = arg[0], Cc = arg[1], Cbias = 0
     */
    case GL_ADD:
    case GL_SUBTRACT:
@@ -241,25 +218,26 @@ viaTexCombineState( viaContextPtr vmesa,
         op |= HC_HTXnTBLCop_Sub;
       }
 
-      color |= (color_arg[0] << INPUT_B_SHIFT)
-       | (CONST_ONE << INPUT_A_SHIFT);
+      color |= ((CONST_ONE << INPUT_A_SHIFT) |
+               (color_arg[0] << INPUT_B_SHIFT) |
+               (color_arg[1] << INPUT_C_SHIFT));
 
-      bias |= (color_arg[1] << INPUT_CBias_SHIFT);
       ordered_constant_color[1] = constant_color[0];
-      ordered_constant_color[3] = constant_color[1];
+      ordered_constant_color[2] = constant_color[1];
       break;
 
-   /* Ca = 0, Cb = arg[0], Cc = arg[1], Cbias = 0.5
+   /* Ca = 1.0, Cb = arg[0], Cc = arg[1], Cbias = -0.5
     */
    case GL_ADD_SIGNED:
-      color |= (color_arg[0] << INPUT_B_SHIFT)
-       | (color_arg[1] << INPUT_C_SHIFT);
+      color |= ((CONST_ONE << INPUT_A_SHIFT) |
+               (color_arg[0] << INPUT_B_SHIFT) | 
+               (color_arg[1] << INPUT_C_SHIFT));
+
       bias |= HC_HTXnTBLCbias_HTXnTBLRC;
-      op |= HC_HTXnTBLCop_Sub;
 
       ordered_constant_color[1] = constant_color[0];
       ordered_constant_color[2] = constant_color[1];
-      ordered_constant_color[3] = 0x00808080;
+      ordered_constant_color[3] = 0x00bfbfbf; /* -.5 */
       break;
 
    /* Ca = arg[2], Cb = arg[0], Cc = arg[1], Cbias = arg[1]
@@ -267,17 +245,19 @@ viaTexCombineState( viaContextPtr vmesa,
    case GL_INTERPOLATE:
       op |= HC_HTXnTBLCop_Sub;
 
-      color |= (color_arg[2] << INPUT_A_SHIFT) |
-       (color_arg[0] << INPUT_B_SHIFT) |
-       (color_arg[1] << INPUT_C_SHIFT);
+      color |= ((color_arg[2] << INPUT_A_SHIFT) |
+               (color_arg[0] << INPUT_B_SHIFT) |
+               (color_arg[1] << INPUT_C_SHIFT));
+
       bias |= (color_arg[1] << INPUT_CBias_SHIFT);
 
       ordered_constant_color[0] = constant_color[2];
       ordered_constant_color[1] = constant_color[0];
       ordered_constant_color[2] = constant_color[1];
-      ordered_constant_color[3] = constant_color[1];
+      ordered_constant_color[3] = (constant_color[1] >> 1) & 0x7f7f7f;
       break;
 
+#if 0
    /* At this point this code is completely untested.  It appears that the
     * Unichrome has the same limitation as the Radeon R100.  The only
     * supported post-scale when doing DOT3 bumpmapping is 1x.
@@ -288,41 +268,90 @@ viaTexCombineState( viaContextPtr vmesa,
    case GL_DOT3_RGBA:
       c_shift = 2;
       a_shift = 2;
-      color |= (color_arg[0] << INPUT_A_SHIFT) |
-       (color_arg[1] << INPUT_B_SHIFT);
+      color |= ((color_arg[0] << INPUT_A_SHIFT) |
+               (color_arg[1] << INPUT_B_SHIFT));
       op |= HC_HTXnTBLDOT4;
       break;
+#endif
+
+   default:
+      assert(0);
+      break;
    }
 
 
+
+
    /* The alpha blend stage has the annoying quirk of not having a
     * hard-wired 0 input, like the color stage.  As a result, we have
     * to program the constant register with 0 and use that as our
     * 0 input.
+    *
+    *     (xA * (xB op xC) + xBias) << xShift
+    *
     */
 
+   for ( i = 0 ; i < combine->_NumArgsA ; i++ ) {
+      const GLint op = combine->OperandA[i] - GL_SRC_ALPHA;
+
+      switch ( combine->SourceA[i] ) {
+      case GL_TEXTURE:
+        alpha_arg[i] = HC_XTA_Atex;
+        alpha_arg[i] += alpha_operand_modifier[op];
+        bias_alpha_arg[i] = HC_HTXnTBLAbias_Atex;
+        bias_alpha_arg[i] += bias_alpha_operand_modifier[op];
+        break;
+      case GL_CONSTANT:
+        alpha_arg[i] = HC_XTA_HTXnTBLRA;
+        bias_alpha_arg[i] = HC_HTXnTBLAbias_HTXnTBLRAbias;
+        constant_alpha[i] = (op == 0) ? env_color[3] : (~env_color[3] & 0xff);
+        break;
+      case GL_PRIMARY_COLOR:
+        alpha_arg[i] = HC_XTA_Adif;
+        alpha_arg[i] += alpha_operand_modifier[op];
+        bias_alpha_arg[i] = HC_HTXnTBLAbias_Adif;
+        bias_alpha_arg[i] += bias_alpha_operand_modifier[op];
+        break;
+      case GL_PREVIOUS:
+        alpha_arg[i] = (unit == 0) ? HC_XTA_Adif : HC_XTA_Acur;
+        alpha_arg[i] += alpha_operand_modifier[op];
+        bias_alpha_arg[i] = (unit == 0 ? 
+                             HC_HTXnTBLAbias_Adif : 
+                             HC_HTXnTBLAbias_Acur);
+        bias_alpha_arg[i] += bias_alpha_operand_modifier[op];
+        break;
+      }
+   }
+
    switch( combine->ModeA ) {
    /* Aa = 0, Ab = 0, Ac = 0, Abias = arg0
     */
    case GL_REPLACE:
-      bias |= (alpha_arg[0] << INPUT_ABias_SHIFT);
+      alpha |= ((HC_XTA_HTXnTBLRA << INPUT_A_SHIFT) |
+               (HC_XTA_HTXnTBLRA << INPUT_B_SHIFT) |
+               (HC_XTA_HTXnTBLRA << INPUT_C_SHIFT));
+      abc_alpha = 0;
 
-      alpha |= (HC_XTA_HTXnTBLRA << INPUT_A_SHIFT) |
-       (HC_XTA_HTXnTBLRA << INPUT_B_SHIFT) |
-       (HC_XTA_HTXnTBLRA << INPUT_C_SHIFT);
+      bias |= bias_alpha_arg[0];
+      bias_alpha = constant_alpha[0] >> 1;
       break;
       
    /* Aa = arg[0], Ab = arg[1], Ac = 0, Abias = 0
     */
    case GL_MODULATE:
-      alpha |= (alpha_arg[1] << INPUT_A_SHIFT)
-        | (alpha_arg[0] << INPUT_B_SHIFT)
-        | (HC_XTA_HTXnTBLRA << INPUT_C_SHIFT);
+      alpha |= ((alpha_arg[1] << INPUT_A_SHIFT) | 
+               (alpha_arg[0] << INPUT_B_SHIFT) | 
+               (HC_XTA_HTXnTBLRA << INPUT_C_SHIFT));
+
+      abc_alpha = ((constant_alpha[1] << HC_HTXnTBLRAa_SHIFT) |
+                  (constant_alpha[0] << HC_HTXnTBLRAb_SHIFT) |
+                  (0 << HC_HTXnTBLRAc_SHIFT));
 
-      bias |= (HC_XTA_HTXnTBLRA << INPUT_ABias_SHIFT);
+      bias |= HC_HTXnTBLAbias_HTXnTBLRAbias;
+      bias_alpha = 0;
       break;
 
-   /* Aa = 0, Ab = arg[0], Ac = 0, Abias = arg[1]
+   /* Aa = 1.0, Ab = arg[0], Ac = arg[1], Abias = 0
     */
    case GL_ADD:
    case GL_SUBTRACT:
@@ -330,22 +359,30 @@ viaTexCombineState( viaContextPtr vmesa,
         op |= HC_HTXnTBLAop_Sub;
       }
 
-      alpha |= (HC_XTA_HTXnTBLRA << INPUT_A_SHIFT) |
-       (alpha_arg[0] << INPUT_B_SHIFT) |
-       (HC_XTA_HTXnTBLRA << INPUT_C_SHIFT);
-      bias |= (alpha_arg[1] << INPUT_ABias_SHIFT);
+      alpha |= ((HC_XTA_HTXnTBLRA << INPUT_A_SHIFT) |
+               (alpha_arg[0] << INPUT_B_SHIFT) |
+               (alpha_arg[1] << INPUT_C_SHIFT));
+
+      abc_alpha = ((0xff << HC_HTXnTBLRAa_SHIFT) |
+                  (constant_alpha[0] << HC_HTXnTBLRAb_SHIFT) |
+                  (constant_alpha[1] << HC_HTXnTBLRAc_SHIFT));
+
+      bias |= HC_HTXnTBLAbias_HTXnTBLRAbias;
+      bias_alpha = 0;
       break;
 
-   /* Aa = 0, Ab = arg[0], Ac = arg[1], Abias = 0.5
+   /* Aa = 1.0, Ab = arg[0], Ac = arg[1], Abias = -0.5
     */
    case GL_ADD_SIGNED:
-      op |= HC_HTXnTBLAop_Sub;
-
-      alpha |= (alpha_arg[0] << INPUT_B_SHIFT)
-       | (alpha_arg[1] << INPUT_C_SHIFT);
-      bias |= (HC_XTA_HTXnTBLRA << INPUT_ABias_SHIFT);
-
-      bias_alpha = 0x00000080;
+      alpha |= ((HC_XTA_HTXnTBLRA << INPUT_A_SHIFT) |
+               (alpha_arg[0] << INPUT_B_SHIFT) | 
+               (alpha_arg[1] << INPUT_C_SHIFT));
+      abc_alpha = ((0xff << HC_HTXnTBLRAa_SHIFT) |
+                  (constant_alpha[0] << HC_HTXnTBLRAb_SHIFT) |
+                  (constant_alpha[1] << HC_HTXnTBLRAc_SHIFT));
+
+      bias |= HC_HTXnTBLAbias_HTXnTBLRAbias;
+      bias_alpha = 0xbf;
       break;
 
    /* Aa = arg[2], Ab = arg[0], Ac = arg[1], Abias = arg[1]
@@ -353,10 +390,15 @@ viaTexCombineState( viaContextPtr vmesa,
    case GL_INTERPOLATE:
       op |= HC_HTXnTBLAop_Sub;
 
-      alpha |= (alpha_arg[2] << INPUT_A_SHIFT) |
-       (alpha_arg[0] << INPUT_B_SHIFT) |
-       (alpha_arg[1] << INPUT_C_SHIFT);
-      bias |= (alpha_arg[1] << INPUT_ABias_SHIFT);
+      alpha |= ((alpha_arg[2] << INPUT_A_SHIFT) |
+               (alpha_arg[0] << INPUT_B_SHIFT) |
+               (alpha_arg[1] << INPUT_C_SHIFT));
+      abc_alpha = ((constant_alpha[2] << HC_HTXnTBLRAa_SHIFT) |
+                  (constant_alpha[0] << HC_HTXnTBLRAb_SHIFT) |
+                  (constant_alpha[1] << HC_HTXnTBLRAc_SHIFT));
+
+      bias |= bias_alpha_arg[1];
+      bias_alpha = constant_alpha[1] >> 1;
       break;
    }
    
@@ -364,31 +406,19 @@ viaTexCombineState( viaContextPtr vmesa,
    op |= c_shift_table[ c_shift ] | a_shift_table[ a_shift ];
 
 
-   if ( unit == 0 ) {
-      vmesa->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_Fog;
+   vmesa->regHTXnTBLMPfog[unit] = HC_HTXnTBLMPfog_Fog;
 
-      vmesa->regHTXnTBLCsat_0 = color;
-      vmesa->regHTXnTBLAsat_0 = alpha;
-      vmesa->regHTXnTBLCop_0 = op | bias;
-      vmesa->regHTXnTBLRAa_0 = bias_alpha | (constant_alpha << 16);
+   vmesa->regHTXnTBLCsat[unit] = color;
+   vmesa->regHTXnTBLAsat[unit] = alpha;
+   vmesa->regHTXnTBLCop[unit] = op | bias;
+   vmesa->regHTXnTBLRAa[unit] = abc_alpha;
+   vmesa->regHTXnTBLRFog[unit] = bias_alpha;
 
-      vmesa->regHTXnTBLRCa_0 = ordered_constant_color[0];
-      vmesa->regHTXnTBLRCb_0 = ordered_constant_color[1];
-      vmesa->regHTXnTBLRCc_0 = ordered_constant_color[2];
-      vmesa->regHTXnTBLRCbias_0 = ordered_constant_color[3];
-   }
-   else {
-      vmesa->regHTXnTBLMPfog_1 = HC_HTXnTBLMPfog_Fog;
-
-      vmesa->regHTXnTBLCsat_1 = color;
-      vmesa->regHTXnTBLAsat_1 = alpha;
-      vmesa->regHTXnTBLCop_1 = op | bias;
-      vmesa->regHTXnTBLRAa_1 = bias_alpha | (constant_alpha << 16);
-
-      vmesa->regHTXnTBLRCa_1 = ordered_constant_color[0];
-      vmesa->regHTXnTBLRCb_1 = ordered_constant_color[1];
-      vmesa->regHTXnTBLRCc_1 = ordered_constant_color[2];
-      vmesa->regHTXnTBLRCbias_1 = ordered_constant_color[3];
-   }
+   vmesa->regHTXnTBLRCa[unit] = ordered_constant_color[0];
+   vmesa->regHTXnTBLRCb[unit] = ordered_constant_color[1];
+   vmesa->regHTXnTBLRCc[unit] = ordered_constant_color[2];
+   vmesa->regHTXnTBLRCbias[unit] = ordered_constant_color[3];
+
+   return GL_TRUE;
 }