Merge branch 'master' of git+ssh://keithw@git.freedesktop.org/git/mesa/mesa into...
[mesa.git] / src / mesa / drivers / dri / nouveau / nouveau_state.c
index c88b33b88477d038971836198de506fed2189066..8d3c018dffaec12ed092832f27dfbee790e487de 100644 (file)
@@ -26,39 +26,55 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include "nouveau_context.h"
 #include "nouveau_state.h"
-#include "nouveau_ioctl.h"
-#include "nouveau_tris.h"
+#include "nouveau_swtcl.h"
+#include "nouveau_fifo.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"
 
+#include "mtypes.h"
+#include "colormac.h"
+
+static __inline__ GLuint nouveauPackColor(GLuint format,
+                                      GLubyte r, GLubyte g,
+                                      GLubyte b, GLubyte a)
+{
+   switch (format) {
+   case 2:
+      return PACK_COLOR_565( r, g, b );
+   case 4:
+      return PACK_COLOR_8888( r, g, b, a);
+   default:
+      fprintf(stderr, "unknown format %d\n", (int)format);
+      return 0;
+   }
+}
+
 static void nouveauCalcViewport(GLcontext *ctx)
 {
     /* Calculate the Viewport Matrix */
     
-/* Taken from the intel driver
     nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
     const GLfloat *v = ctx->Viewport._WindowMap.m;
-    GLfloat *m = nmesa->ViewportMatrix.m;
-    GLint h = 0;
-    
-    if (nmesa->driDrawable) 
-       h = nmesa->driDrawable->h + SUBPIXEL_Y;
-    
+    GLfloat *m = nmesa->viewport.m;
+    GLfloat xoffset = nmesa->drawX, yoffset = nmesa->drawY;
+  
+    nmesa->depth_scale = 1.0 / ctx->DrawBuffer->_DepthMaxF;
+
     m[MAT_SX] =   v[MAT_SX];
-    m[MAT_TX] =   v[MAT_TX] + SUBPIXEL_X;
+    m[MAT_TX] =   v[MAT_TX] + xoffset + SUBPIXEL_X;
     m[MAT_SY] = - v[MAT_SY];
-    m[MAT_TY] = - v[MAT_TY] + h;
+    m[MAT_TY] =   v[MAT_TY] + yoffset + SUBPIXEL_Y;
     m[MAT_SZ] =   v[MAT_SZ] * nmesa->depth_scale;
     m[MAT_TZ] =   v[MAT_TZ] * nmesa->depth_scale;
-*/
+
+    nmesa->hw_func.WindowMoved(nmesa);
 }
 
-static nouveauViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+static void nouveauViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
 {
     /* 
      * Need to send (at least on an nv35 the following:
@@ -75,19 +91,96 @@ static nouveauViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
      * 44c   0x03000000  <-- (Height_from_glViewport << 16) | (win_height - height - y)
      *
      */
+    
+    nouveauCalcViewport(ctx);
+}
 
+static void nouveauDepthRange(GLcontext *ctx, GLclampd near, GLclampd far)
+{
+    nouveauCalcViewport(ctx);
+}
+
+static void nouveauDDUpdateHWState(GLcontext *ctx)
+{
+    nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+    int new_state = nmesa->new_state;
+
+    if ( new_state || nmesa->new_render_state & _NEW_TEXTURE )
+    {
+        nmesa->new_state = 0;
+
+        /* Update the various parts of the context's state.
+        */
+        /*
+        if ( new_state & NOUVEAU_NEW_ALPHA )
+            nouveauUpdateAlphaMode( ctx );
+
+        if ( new_state & NOUVEAU_NEW_DEPTH )
+            nouveauUpdateZMode( ctx );
+
+        if ( new_state & NOUVEAU_NEW_FOG )
+            nouveauUpdateFogAttrib( ctx );
+
+        if ( new_state & NOUVEAU_NEW_CLIP )
+            nouveauUpdateClipping( ctx );
+
+        if ( new_state & NOUVEAU_NEW_CULL )
+            nouveauUpdateCull( ctx );
+
+        if ( new_state & NOUVEAU_NEW_MASKS )
+            nouveauUpdateMasks( ctx );
+
+        if ( new_state & NOUVEAU_NEW_WINDOW )
+            nouveauUpdateWindow( ctx );
+
+        if ( nmesa->new_render_state & _NEW_TEXTURE ) {
+            nouveauUpdateTextureState( ctx );
+        }*/
+    }
+}
+
+static void nouveauDDInvalidateState(GLcontext *ctx, GLuint new_state)
+{
+    _swrast_InvalidateState( ctx, new_state );
+    _swsetup_InvalidateState( ctx, new_state );
+    _vbo_InvalidateState( ctx, new_state );
+    _tnl_InvalidateState( ctx, new_state );
+    NOUVEAU_CONTEXT(ctx)->new_render_state |= new_state;
 }
 
 /* Initialize the context's hardware state. */
 void nouveauDDInitState(nouveauContextPtr nmesa)
 {
-
+    uint32_t type = nmesa->screen->card->type;
+    switch(type)
+    {
+        case NV_03:
+        case NV_04:
+        case NV_05:
+            /* No TCL engines for these ones */
+            break;
+        case NV_10:
+            nv10InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
+            break;
+        case NV_20:
+            nv20InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
+            break;
+        case NV_30:
+        case NV_40:
+        case NV_44:
+        case NV_50:
+            nv30InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver);
+            break;
+        default:
+            break;
+    }
+    nouveau_state_cache_init(nmesa);
 }
 
 /* Initialize the driver's state functions */
 void nouveauDDInitStateFuncs(GLcontext *ctx)
 {
-   ctx->Driver.UpdateState             = NULL; //nouveauDDInvalidateState;
+   ctx->Driver.UpdateState             = nouveauDDInvalidateState;
 
    ctx->Driver.ClearIndex              = NULL;
    ctx->Driver.ClearColor              = NULL; //nouveauDDClearColor;
@@ -120,7 +213,7 @@ void nouveauDDInitStateFuncs(GLcontext *ctx)
    ctx->Driver.StencilMaskSeparate     = NULL; //nouveauDDStencilMaskSeparate;
    ctx->Driver.StencilOpSeparate       = NULL; //nouveauDDStencilOpSeparate;
 
-   ctx->Driver.DepthRange               = NULL; //nouveauDepthRange;
+   ctx->Driver.DepthRange               = nouveauDepthRange;
    ctx->Driver.Viewport                 = nouveauViewport;
 
    /* Pixel path fallbacks.
@@ -138,3 +231,111 @@ void nouveauDDInitStateFuncs(GLcontext *ctx)
    ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
    ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
 }
+
+#define STATE_INIT(a) if (ctx->Driver.a) ctx->Driver.a
+
+void nouveauInitState(GLcontext *ctx)
+{
+    /*
+     * Mesa should do this for us:
+     */
+
+    STATE_INIT(AlphaFunc)( ctx, 
+            ctx->Color.AlphaFunc,
+            ctx->Color.AlphaRef);
+
+    STATE_INIT(BlendColor)( ctx,
+            ctx->Color.BlendColor );
+
+    STATE_INIT(BlendEquationSeparate)( ctx, 
+            ctx->Color.BlendEquationRGB,
+            ctx->Color.BlendEquationA);
+
+    STATE_INIT(BlendFuncSeparate)( ctx,
+            ctx->Color.BlendSrcRGB,
+            ctx->Color.BlendDstRGB,
+            ctx->Color.BlendSrcA,
+            ctx->Color.BlendDstA);
+
+    STATE_INIT(ClearColor)( ctx, ctx->Color.ClearColor);
+    STATE_INIT(ClearDepth)( ctx, ctx->Depth.Clear);
+    STATE_INIT(ClearStencil)( ctx, ctx->Stencil.Clear);
+
+    STATE_INIT(ColorMask)( ctx, 
+            ctx->Color.ColorMask[RCOMP],
+            ctx->Color.ColorMask[GCOMP],
+            ctx->Color.ColorMask[BCOMP],
+            ctx->Color.ColorMask[ACOMP]);
+
+    STATE_INIT(CullFace)( ctx, ctx->Polygon.CullFaceMode );
+    STATE_INIT(DepthFunc)( ctx, ctx->Depth.Func );
+    STATE_INIT(DepthMask)( ctx, ctx->Depth.Mask );
+
+    STATE_INIT(Enable)( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled );
+    STATE_INIT(Enable)( ctx, GL_BLEND, ctx->Color.BlendEnabled );
+    STATE_INIT(Enable)( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled );
+    STATE_INIT(Enable)( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled );
+    STATE_INIT(Enable)( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag );
+    STATE_INIT(Enable)( ctx, GL_DEPTH_TEST, ctx->Depth.Test );
+    STATE_INIT(Enable)( ctx, GL_DITHER, ctx->Color.DitherFlag );
+    STATE_INIT(Enable)( ctx, GL_FOG, ctx->Fog.Enabled );
+    STATE_INIT(Enable)( ctx, GL_LIGHTING, ctx->Light.Enabled );
+    STATE_INIT(Enable)( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag );
+    STATE_INIT(Enable)( ctx, GL_LINE_STIPPLE, ctx->Line.StippleFlag );
+    STATE_INIT(Enable)( ctx, GL_POINT_SMOOTH, ctx->Point.SmoothFlag );
+    STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_FILL, ctx->Polygon.OffsetFill);
+    STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_LINE, ctx->Polygon.OffsetLine);
+    STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_POINT, ctx->Polygon.OffsetPoint);
+    STATE_INIT(Enable)( ctx, GL_POLYGON_SMOOTH, ctx->Polygon.SmoothFlag );
+    STATE_INIT(Enable)( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag );
+    STATE_INIT(Enable)( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled );
+    STATE_INIT(Enable)( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled );
+    STATE_INIT(Enable)( ctx, GL_TEXTURE_1D, GL_FALSE );
+    STATE_INIT(Enable)( ctx, GL_TEXTURE_2D, GL_FALSE );
+    STATE_INIT(Enable)( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE );
+    STATE_INIT(Enable)( ctx, GL_TEXTURE_3D, GL_FALSE );
+    STATE_INIT(Enable)( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE );
+
+    STATE_INIT(Fogfv)( ctx, GL_FOG_COLOR, ctx->Fog.Color );
+    STATE_INIT(Fogfv)( ctx, GL_FOG_MODE, 0 );
+    STATE_INIT(Fogfv)( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
+    STATE_INIT(Fogfv)( ctx, GL_FOG_START, &ctx->Fog.Start );
+    STATE_INIT(Fogfv)( ctx, GL_FOG_END, &ctx->Fog.End );
+
+    STATE_INIT(FrontFace)( ctx, ctx->Polygon.FrontFace );
+
+    {
+        GLfloat f = (GLfloat)ctx->Light.Model.ColorControl;
+        STATE_INIT(LightModelfv)( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f );
+    }
+
+    STATE_INIT(LineStipple)( ctx, ctx->Line.StippleFactor, ctx->Line.StipplePattern );
+    STATE_INIT(LineWidth)( ctx, ctx->Line.Width );
+    STATE_INIT(LogicOpcode)( ctx, ctx->Color.LogicOp );
+    STATE_INIT(PointSize)( ctx, ctx->Point.Size );
+    STATE_INIT(PolygonMode)( ctx, GL_FRONT, ctx->Polygon.FrontMode );
+    STATE_INIT(PolygonMode)( ctx, GL_BACK, ctx->Polygon.BackMode );
+    STATE_INIT(PolygonOffset)( ctx,
+           ctx->Polygon.OffsetFactor,
+           ctx->Polygon.OffsetUnits );
+    STATE_INIT(PolygonStipple)( ctx, (const GLubyte *)ctx->PolygonStipple );
+    STATE_INIT(ShadeModel)( ctx, ctx->Light.ShadeModel );
+    STATE_INIT(StencilFuncSeparate)( ctx, GL_FRONT,
+            ctx->Stencil.Function[0],
+            ctx->Stencil.Ref[0],
+            ctx->Stencil.ValueMask[0] );
+    STATE_INIT(StencilFuncSeparate)( ctx, GL_BACK,
+            ctx->Stencil.Function[1],
+            ctx->Stencil.Ref[1],
+            ctx->Stencil.ValueMask[1] );
+    STATE_INIT(StencilMaskSeparate)( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] );
+    STATE_INIT(StencilMaskSeparate)( ctx, GL_BACK, ctx->Stencil.WriteMask[1] );
+    STATE_INIT(StencilOpSeparate)( ctx, GL_FRONT,
+            ctx->Stencil.FailFunc[0],
+            ctx->Stencil.ZFailFunc[0],
+            ctx->Stencil.ZPassFunc[0]);
+    STATE_INIT(StencilOpSeparate)( ctx, GL_BACK,
+            ctx->Stencil.FailFunc[1],
+            ctx->Stencil.ZFailFunc[1],
+            ctx->Stencil.ZPassFunc[1]);
+}