Merge branch '7.8' into master
[mesa.git] / src / mesa / drivers / dri / r600 / r700_state.c
index 98f116d0a6a1a48f58e3612443a1b44a7c38438c..1ff233d91ee86bcdf11e92beb770a14f42963b67 100644 (file)
@@ -26,7 +26,6 @@
 
 #include "main/glheader.h"
 #include "main/mtypes.h"
-#include "main/state.h"
 #include "main/imports.h"
 #include "main/enums.h"
 #include "main/macros.h"
 
 #include "tnl/tnl.h"
 #include "tnl/t_pipeline.h"
-#include "tnl/t_vp_build.h"
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
 #include "main/api_arrayelt.h"
-#include "main/state.h"
 #include "main/framebuffer.h"
+#include "drivers/common/meta.h"
 
 #include "shader/prog_parameter.h"
 #include "shader/prog_statevars.h"
 #include "vbo/vbo.h"
-#include "main/texformat.h"
 
 #include "r600_context.h"
 
 #include "r700_fragprog.h"
 #include "r700_vertprog.h"
 
-
+void r600UpdateTextureState(GLcontext * ctx);
 static void r700SetClipPlaneState(GLcontext * ctx, GLenum cap, GLboolean state);
 static void r700UpdatePolygonMode(GLcontext * ctx);
 static void r700SetPolygonOffsetState(GLcontext * ctx, GLboolean state);
 static void r700SetStencilState(GLcontext * ctx, GLboolean state);
+static void r700UpdateWindow(GLcontext * ctx, int id);
 
-void r700UpdateShaders (GLcontext * ctx)  //----------------------------------
+void r700UpdateShaders(GLcontext * ctx)
 {
     context_t *context = R700_CONTEXT(ctx);
-    GLvector4f dummy_attrib[_TNL_ATTRIB_MAX];
-    GLvector4f *temp_attrib[_TNL_ATTRIB_MAX];
-    int i;
 
     /* should only happenen once, just after context is created */
     /* TODO: shouldn't we fallback to sw here? */
     if (!ctx->FragmentProgram._Current) {
-           _mesa_fprintf(stderr, "No ctx->FragmentProgram._Current!!\n");
+           fprintf(stderr, "No ctx->FragmentProgram._Current!!\n");
            return;
     }
 
     r700SelectFragmentShader(ctx);
 
-    if (context->radeon.NewGLState) {
-           for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
-                   /* mat states from state var not array for sw */
-                   dummy_attrib[i].stride = 0;
-                   temp_attrib[i] = TNL_CONTEXT(ctx)->vb.AttribPtr[i];
-                   TNL_CONTEXT(ctx)->vb.AttribPtr[i] = &(dummy_attrib[i]);
-           }
-
-           _tnl_UpdateFixedFunctionProgram(ctx);
-
-           for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
-                   TNL_CONTEXT(ctx)->vb.AttribPtr[i] = temp_attrib[i];
-           }
-    }
-
     r700SelectVertexShader(ctx);
     r700UpdateStateParameters(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
     context->radeon.NewGLState = 0;
@@ -104,7 +84,7 @@ void r700UpdateViewportOffset(GLcontext * ctx) //------------------
 {
        context_t *context = R700_CONTEXT(ctx);
        R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
-       __DRIdrawablePrivate *dPriv = radeon_get_drawable(&context->radeon);
+       __DRIdrawable *dPriv = radeon_get_drawable(&context->radeon);
        GLfloat xoffset = (GLfloat) dPriv->x;
        GLfloat yoffset = (GLfloat) dPriv->y + dPriv->h;
        const GLfloat *v = ctx->Viewport._WindowMap.m;
@@ -171,6 +151,14 @@ static void r700InvalidateState(GLcontext * ctx, GLuint new_state) //-----------
            R600_STATECHANGE(context, db_target);
     }
 
+    if (new_state & (_NEW_LIGHT)) {
+           R600_STATECHANGE(context, su);
+           if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION)
+                   SETbit(r700->PA_SU_SC_MODE_CNTL.u32All, PROVOKING_VTX_LAST_bit);
+           else
+                   CLEARbit(r700->PA_SU_SC_MODE_CNTL.u32All, PROVOKING_VTX_LAST_bit);
+    }
+
     r700UpdateStateParameters(ctx, new_state);
 
     R600_STATECHANGE(context, cl);
@@ -202,6 +190,67 @@ static void r700InvalidateState(GLcontext * ctx, GLuint new_state) //-----------
     context->radeon.NewGLState |= new_state;
 }
 
+static void r700SetDBRenderState(GLcontext * ctx)
+{
+       context_t *context = R700_CONTEXT(ctx);
+       R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+       struct r700_fragment_program *fp = (struct r700_fragment_program *)
+               (ctx->FragmentProgram._Current);
+
+       R600_STATECHANGE(context, db);
+
+       SETbit(r700->DB_SHADER_CONTROL.u32All, DUAL_EXPORT_ENABLE_bit);
+       SETfield(r700->DB_SHADER_CONTROL.u32All, EARLY_Z_THEN_LATE_Z, Z_ORDER_shift, Z_ORDER_mask);
+       /* XXX need to enable htile for hiz/s */
+       SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIZ_ENABLE_shift, FORCE_HIZ_ENABLE_mask);
+       SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIS_ENABLE0_shift, FORCE_HIS_ENABLE0_mask);
+       SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIS_ENABLE1_shift, FORCE_HIS_ENABLE1_mask);
+
+       if (context->radeon.query.current)
+       {
+               SETbit(r700->DB_RENDER_OVERRIDE.u32All, NOOP_CULL_DISABLE_bit);
+               if (context->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV770)
+               {
+                       SETbit(r700->DB_RENDER_CONTROL.u32All, PERFECT_ZPASS_COUNTS_bit);
+               }
+       }
+       else
+       {
+               CLEARbit(r700->DB_RENDER_OVERRIDE.u32All, NOOP_CULL_DISABLE_bit);
+               if (context->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV770)
+               {
+                       CLEARbit(r700->DB_RENDER_CONTROL.u32All, PERFECT_ZPASS_COUNTS_bit);
+               }
+       }
+
+       if (fp)
+       {
+               if (fp->r700Shader.killIsUsed)
+               {
+                       SETbit(r700->DB_SHADER_CONTROL.u32All, KILL_ENABLE_bit);
+               }
+               else
+               {
+                       CLEARbit(r700->DB_SHADER_CONTROL.u32All, KILL_ENABLE_bit);
+               }
+
+               if (fp->r700Shader.depthIsExported)
+               {
+                       SETbit(r700->DB_SHADER_CONTROL.u32All, Z_EXPORT_ENABLE_bit);
+               }
+               else
+               {
+                       CLEARbit(r700->DB_SHADER_CONTROL.u32All, Z_EXPORT_ENABLE_bit);
+               }
+       }
+}
+
+void r700UpdateShaderStates(GLcontext * ctx)
+{
+       r700SetDBRenderState(ctx);
+       r600UpdateTextureState(ctx);
+}
+
 static void r700SetDepthState(GLcontext * ctx)
 {
        context_t *context = R700_CONTEXT(ctx);
@@ -467,10 +516,10 @@ static void r700SetBlendState(GLcontext * ctx)
                 eqn, COLOR_COMB_FCN_shift, COLOR_COMB_FCN_mask);
 
        SETfield(blend_reg,
-                blend_factor(ctx->Color.BlendSrcRGB, GL_TRUE),
+                blend_factor(ctx->Color.BlendSrcA, GL_TRUE),
                 ALPHA_SRCBLEND_shift, ALPHA_SRCBLEND_mask);
        SETfield(blend_reg,
-                blend_factor(ctx->Color.BlendDstRGB, GL_FALSE),
+                blend_factor(ctx->Color.BlendDstA, GL_FALSE),
                 ALPHA_DESTBLEND_shift, ALPHA_DESTBLEND_mask);
 
        switch (ctx->Color.BlendEquationA) {
@@ -566,7 +615,7 @@ static GLuint translate_logicop(GLenum logicop)
        case GL_XOR:
                return 0x66;
        case GL_EQUIV:
-               return 0xaa;
+               return 0x99;
        case GL_AND_REVERSE:
                return 0x44;
        case GL_AND_INVERTED:
@@ -655,6 +704,10 @@ static void r700UpdateCulling(GLcontext * ctx)
             CLEARbit(r700->PA_SU_SC_MODE_CNTL.u32All, FACE_bit); /* default: ccw */
             break;
     }
+
+    /* Winding is inverted when rendering to FBO */
+    if (ctx->DrawBuffer && ctx->DrawBuffer->Name)
+           r700->PA_SU_SC_MODE_CNTL.u32All ^= FACE_bit;
 }
 
 static void r700UpdateLineStipple(GLcontext * ctx)
@@ -726,6 +779,9 @@ static void r700Enable(GLcontext * ctx, GLenum cap, GLboolean state) //---------
        case GL_LINE_STIPPLE:
                r700UpdateLineStipple(ctx);
                break;
+       case GL_DEPTH_CLAMP:
+               r700UpdateWindow(ctx, 0);
+               break;
        default:
                break;
        }
@@ -745,9 +801,9 @@ static void r700ColorMask(GLcontext * ctx,
                             (b ? 4 : 0) |
                             (a ? 8 : 0));
 
-       if (mask != r700->CB_SHADER_MASK.u32All) {
+       if (mask != r700->CB_TARGET_MASK.u32All) {
                R600_STATECHANGE(context, cb);
-               SETfield(r700->CB_SHADER_MASK.u32All, mask, OUTPUT0_ENABLE_shift, OUTPUT0_ENABLE_mask);
+               SETfield(r700->CB_TARGET_MASK.u32All, mask, TARGET0_ENABLE_shift, TARGET0_ENABLE_mask);
        }
 }
 
@@ -856,10 +912,12 @@ static void r700PointParameter(GLcontext * ctx, GLenum pname, const GLfloat * pa
        case GL_POINT_SIZE_MIN:
                SETfield(r700->PA_SU_POINT_MINMAX.u32All, (int)(ctx->Point.MinSize * 8.0),
                         MIN_SIZE_shift, MIN_SIZE_mask);
+               r700PointSize(ctx, ctx->Point.Size);
                break;
        case GL_POINT_SIZE_MAX:
                SETfield(r700->PA_SU_POINT_MINMAX.u32All, (int)(ctx->Point.MaxSize * 8.0),
                         MAX_SIZE_shift, MAX_SIZE_mask);
+               r700PointSize(ctx, ctx->Point.Size);
                break;
        case GL_POINT_DISTANCE_ATTENUATION:
                break;
@@ -1017,7 +1075,7 @@ static void r700UpdateWindow(GLcontext * ctx, int id) //--------------------
 {
        context_t *context = R700_CONTEXT(ctx);
        R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
-       __DRIdrawablePrivate *dPriv = radeon_get_drawable(&context->radeon);
+       __DRIdrawable *dPriv = radeon_get_drawable(&context->radeon);
        GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
        GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
        const GLfloat *v = ctx->Viewport._WindowMap.m;
@@ -1041,6 +1099,7 @@ static void r700UpdateWindow(GLcontext * ctx, int id) //--------------------
        GLfloat tz = v[MAT_TZ] * depthScale;
 
        R600_STATECHANGE(context, vpt);
+       R600_STATECHANGE(context, cl);
 
        r700->viewport[id].PA_CL_VPORT_XSCALE.f32All  = sx;
        r700->viewport[id].PA_CL_VPORT_XOFFSET.f32All = tx;
@@ -1051,6 +1110,18 @@ static void r700UpdateWindow(GLcontext * ctx, int id) //--------------------
        r700->viewport[id].PA_CL_VPORT_ZSCALE.f32All  = sz;
        r700->viewport[id].PA_CL_VPORT_ZOFFSET.f32All = tz;
 
+       if (ctx->Transform.DepthClamp) {
+               r700->viewport[id].PA_SC_VPORT_ZMIN_0.f32All = MIN2(ctx->Viewport.Near, ctx->Viewport.Far);
+               r700->viewport[id].PA_SC_VPORT_ZMAX_0.f32All = MAX2(ctx->Viewport.Near, ctx->Viewport.Far);
+               SETbit(r700->PA_CL_CLIP_CNTL.u32All, ZCLIP_NEAR_DISABLE_bit);
+               SETbit(r700->PA_CL_CLIP_CNTL.u32All, ZCLIP_FAR_DISABLE_bit);
+       } else {
+               r700->viewport[id].PA_SC_VPORT_ZMIN_0.f32All = 0.0;
+               r700->viewport[id].PA_SC_VPORT_ZMAX_0.f32All = 1.0;
+               CLEARbit(r700->PA_CL_CLIP_CNTL.u32All, ZCLIP_NEAR_DISABLE_bit);
+               CLEARbit(r700->PA_CL_CLIP_CNTL.u32All, ZCLIP_FAR_DISABLE_bit);
+       }
+
        r700->viewport[id].enabled = GL_TRUE;
 
        r700SetScissor(context);
@@ -1164,13 +1235,8 @@ static void r700UpdatePolygonMode(GLcontext * ctx)
                /* Handle GL_CW (clock wise and GL_CCW (counter clock wise)
                 * correctly by selecting the correct front and back face
                 */
-               if (ctx->Polygon.FrontFace == GL_CCW) {
-                       f = ctx->Polygon.FrontMode;
-                       b = ctx->Polygon.BackMode;
-               } else {
-                       f = ctx->Polygon.BackMode;
-                       b = ctx->Polygon.FrontMode;
-               }
+               f = ctx->Polygon.FrontMode;
+               b = ctx->Polygon.BackMode;
 
                /* Enable polygon mode */
                SETfield(r700->PA_SU_SC_MODE_CNTL.u32All, X_DUAL_MODE, POLY_MODE_shift, POLY_MODE_mask);
@@ -1356,8 +1422,6 @@ void r700SetScissor(context_t *context) //---------------
        SETfield(r700->viewport[id].PA_SC_VPORT_SCISSOR_0_BR.u32All, y2,
                 PA_SC_VPORT_SCISSOR_0_BR__BR_Y_shift, PA_SC_VPORT_SCISSOR_0_BR__BR_Y_mask);
 
-       r700->viewport[id].PA_SC_VPORT_ZMIN_0.u32All = 0;
-       r700->viewport[id].PA_SC_VPORT_ZMAX_0.u32All = 0x3F800000;
        r700->viewport[id].enabled = GL_TRUE;
 }
 
@@ -1516,9 +1580,9 @@ static void r700InitSQConfig(GLcontext * ctx)
     SETbit(r700->sq_config.SQ_CONFIG.u32All, DX9_CONSTS_bit);
     SETbit(r700->sq_config.SQ_CONFIG.u32All, ALU_INST_PREFER_VECTOR_bit);
     SETfield(r700->sq_config.SQ_CONFIG.u32All, ps_prio, PS_PRIO_shift, PS_PRIO_mask);
-    SETfield(r700->sq_config.SQ_CONFIG.u32All, ps_prio, VS_PRIO_shift, VS_PRIO_mask);
-    SETfield(r700->sq_config.SQ_CONFIG.u32All, ps_prio, GS_PRIO_shift, GS_PRIO_mask);
-    SETfield(r700->sq_config.SQ_CONFIG.u32All, ps_prio, ES_PRIO_shift, ES_PRIO_mask);
+    SETfield(r700->sq_config.SQ_CONFIG.u32All, vs_prio, VS_PRIO_shift, VS_PRIO_mask);
+    SETfield(r700->sq_config.SQ_CONFIG.u32All, gs_prio, GS_PRIO_shift, GS_PRIO_mask);
+    SETfield(r700->sq_config.SQ_CONFIG.u32All, es_prio, ES_PRIO_shift, ES_PRIO_mask);
 
     r700->sq_config.SQ_GPR_RESOURCE_MGMT_1.u32All = 0;
     SETfield(r700->sq_config.SQ_GPR_RESOURCE_MGMT_1.u32All, num_ps_gprs, NUM_PS_GPRS_shift, NUM_PS_GPRS_mask);
@@ -1565,8 +1629,6 @@ void r700InitState(GLcontext * ctx) //-------------------
     R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
     int id = 0;
 
-    radeon_firevertices(&context->radeon);
-
     r700->TA_CNTL_AUX.u32All = 0;
     SETfield(r700->TA_CNTL_AUX.u32All, 28, TD_FIFO_CREDIT_shift, TD_FIFO_CREDIT_mask);
     r700->VC_ENHANCE.u32All = 0;
@@ -1664,27 +1726,18 @@ void r700InitState(GLcontext * ctx) //-------------------
     r700InitSQConfig(ctx);
 
     r700ColorMask(ctx,
-                 ctx->Color.ColorMask[RCOMP],
-                 ctx->Color.ColorMask[GCOMP],
-                 ctx->Color.ColorMask[BCOMP],
-                 ctx->Color.ColorMask[ACOMP]);
+                 ctx->Color.ColorMask[0][RCOMP],
+                 ctx->Color.ColorMask[0][GCOMP],
+                 ctx->Color.ColorMask[0][BCOMP],
+                 ctx->Color.ColorMask[0][ACOMP]);
 
     r700Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test);
     r700DepthMask(ctx, ctx->Depth.Mask);
     r700DepthFunc(ctx, ctx->Depth.Func);
-    SETbit(r700->DB_SHADER_CONTROL.u32All, DUAL_EXPORT_ENABLE_bit);
-
     r700->DB_DEPTH_CLEAR.u32All     = 0x3F800000;
-
-    r700->DB_RENDER_CONTROL.u32All  = 0;
     SETbit(r700->DB_RENDER_CONTROL.u32All, STENCIL_COMPRESS_DISABLE_bit);
     SETbit(r700->DB_RENDER_CONTROL.u32All, DEPTH_COMPRESS_DISABLE_bit);
-    r700->DB_RENDER_OVERRIDE.u32All = 0;
-    if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
-           SETbit(r700->DB_RENDER_OVERRIDE.u32All, FORCE_SHADER_Z_ORDER_bit);
-    SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIZ_ENABLE_shift, FORCE_HIZ_ENABLE_mask);
-    SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIS_ENABLE0_shift, FORCE_HIS_ENABLE0_mask);
-    SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIS_ENABLE1_shift, FORCE_HIS_ENABLE1_mask);
+    r700SetDBRenderState(ctx);
 
     r700->DB_ALPHA_TO_MASK.u32All = 0;
     SETfield(r700->DB_ALPHA_TO_MASK.u32All, 2, ALPHA_TO_MASK_OFFSET0_shift, ALPHA_TO_MASK_OFFSET0_mask);
@@ -1758,13 +1811,13 @@ void r700InitState(GLcontext * ctx) //-------------------
     r700->CB_CLRCMP_MSK.u32All = 0xFFFFFFFF;
 
     /* screen/window/view */
-    SETfield(r700->CB_TARGET_MASK.u32All, 0xF, (4 * id), TARGET0_ENABLE_mask);
+    SETfield(r700->CB_SHADER_MASK.u32All, 0xF, (4 * id), OUTPUT0_ENABLE_mask);
 
     context->radeon.hw.all_dirty = GL_TRUE;
 
 }
 
-void r700InitStateFuncs(struct dd_function_table *functions) //-----------------
+void r700InitStateFuncs(radeonContextPtr radeon, struct dd_function_table *functions)
 {
        functions->UpdateState = r700InvalidateState;
        functions->AlphaFunc = r700AlphaFunc;
@@ -1805,8 +1858,13 @@ void r700InitStateFuncs(struct dd_function_table *functions) //-----------------
 
        functions->Scissor = radeonScissor;
 
-       functions->DrawBuffer           = radeonDrawBuffer;
-       functions->ReadBuffer           = radeonReadBuffer;
+       functions->DrawBuffer = radeonDrawBuffer;
+       functions->ReadBuffer = radeonReadBuffer;
 
+       if (radeon->radeonScreen->kernel_mm) {
+               functions->CopyPixels = _mesa_meta_CopyPixels;
+               functions->DrawPixels = _mesa_meta_DrawPixels;
+               functions->ReadPixels = radeonReadPixels;
+       }
 }