Home | History | Annotate | Download | only in i915
      1 /**************************************************************************
      2  *
      3  * Copyright 2003 VMware, Inc.
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the
     15  * next paragraph) shall be included in all copies or substantial portions
     16  * of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
     22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  *
     26  **************************************************************************/
     27 
     28 
     29 #include "main/glheader.h"
     30 #include "main/context.h"
     31 #include "main/macros.h"
     32 #include "main/enums.h"
     33 #include "main/fbobject.h"
     34 #include "main/dd.h"
     35 #include "main/state.h"
     36 
     37 #include "drivers/common/driverfuncs.h"
     38 
     39 #include "intel_screen.h"
     40 #include "intel_batchbuffer.h"
     41 #include "intel_mipmap_tree.h"
     42 #include "intel_fbo.h"
     43 #include "intel_buffers.h"
     44 
     45 #include "i830_context.h"
     46 #include "i830_reg.h"
     47 
     48 #define FILE_DEBUG_FLAG DEBUG_STATE
     49 
     50 static void
     51 i830StencilFuncSeparate(struct gl_context * ctx, GLenum face, GLenum func, GLint ref,
     52                         GLuint mask)
     53 {
     54    struct i830_context *i830 = i830_context(ctx);
     55    int test = intel_translate_compare_func(func);
     56 
     57    mask = mask & 0xff;
     58 
     59    DBG("%s : func: %s, ref : 0x%x, mask: 0x%x\n", __func__,
     60        _mesa_enum_to_string(func), ref, mask);
     61 
     62 
     63    I830_STATECHANGE(i830, I830_UPLOAD_CTX);
     64    i830->state.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK;
     65    i830->state.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK |
     66                                            STENCIL_TEST_MASK(mask));
     67    i830->state.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK |
     68                                                 ENABLE_STENCIL_TEST_FUNC_MASK);
     69    i830->state.Ctx[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_REF_VALUE |
     70                                                ENABLE_STENCIL_TEST_FUNC |
     71                                                STENCIL_REF_VALUE(ref) |
     72                                                STENCIL_TEST_FUNC(test));
     73 }
     74 
     75 static void
     76 i830StencilMaskSeparate(struct gl_context * ctx, GLenum face, GLuint mask)
     77 {
     78    struct i830_context *i830 = i830_context(ctx);
     79 
     80    DBG("%s : mask 0x%x\n", __func__, mask);
     81 
     82    mask = mask & 0xff;
     83 
     84    I830_STATECHANGE(i830, I830_UPLOAD_CTX);
     85    i830->state.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK;
     86    i830->state.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK |
     87                                            STENCIL_WRITE_MASK(mask));
     88 }
     89 
     90 static void
     91 i830StencilOpSeparate(struct gl_context * ctx, GLenum face, GLenum fail, GLenum zfail,
     92                       GLenum zpass)
     93 {
     94    struct i830_context *i830 = i830_context(ctx);
     95    int fop, dfop, dpop;
     96 
     97    DBG("%s: fail : %s, zfail: %s, zpass : %s\n", __func__,
     98        _mesa_enum_to_string(fail),
     99        _mesa_enum_to_string(zfail),
    100        _mesa_enum_to_string(zpass));
    101 
    102    fop = 0;
    103    dfop = 0;
    104    dpop = 0;
    105 
    106    switch (fail) {
    107    case GL_KEEP:
    108       fop = STENCILOP_KEEP;
    109       break;
    110    case GL_ZERO:
    111       fop = STENCILOP_ZERO;
    112       break;
    113    case GL_REPLACE:
    114       fop = STENCILOP_REPLACE;
    115       break;
    116    case GL_INCR:
    117       fop = STENCILOP_INCRSAT;
    118       break;
    119    case GL_DECR:
    120       fop = STENCILOP_DECRSAT;
    121       break;
    122    case GL_INCR_WRAP:
    123       fop = STENCILOP_INCR;
    124       break;
    125    case GL_DECR_WRAP:
    126       fop = STENCILOP_DECR;
    127       break;
    128    case GL_INVERT:
    129       fop = STENCILOP_INVERT;
    130       break;
    131    default:
    132       break;
    133    }
    134    switch (zfail) {
    135    case GL_KEEP:
    136       dfop = STENCILOP_KEEP;
    137       break;
    138    case GL_ZERO:
    139       dfop = STENCILOP_ZERO;
    140       break;
    141    case GL_REPLACE:
    142       dfop = STENCILOP_REPLACE;
    143       break;
    144    case GL_INCR:
    145       dfop = STENCILOP_INCRSAT;
    146       break;
    147    case GL_DECR:
    148       dfop = STENCILOP_DECRSAT;
    149       break;
    150    case GL_INCR_WRAP:
    151       dfop = STENCILOP_INCR;
    152       break;
    153    case GL_DECR_WRAP:
    154       dfop = STENCILOP_DECR;
    155       break;
    156    case GL_INVERT:
    157       dfop = STENCILOP_INVERT;
    158       break;
    159    default:
    160       break;
    161    }
    162    switch (zpass) {
    163    case GL_KEEP:
    164       dpop = STENCILOP_KEEP;
    165       break;
    166    case GL_ZERO:
    167       dpop = STENCILOP_ZERO;
    168       break;
    169    case GL_REPLACE:
    170       dpop = STENCILOP_REPLACE;
    171       break;
    172    case GL_INCR:
    173       dpop = STENCILOP_INCRSAT;
    174       break;
    175    case GL_DECR:
    176       dpop = STENCILOP_DECRSAT;
    177       break;
    178    case GL_INCR_WRAP:
    179       dpop = STENCILOP_INCR;
    180       break;
    181    case GL_DECR_WRAP:
    182       dpop = STENCILOP_DECR;
    183       break;
    184    case GL_INVERT:
    185       dpop = STENCILOP_INVERT;
    186       break;
    187    default:
    188       break;
    189    }
    190 
    191 
    192    I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    193    i830->state.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK);
    194    i830->state.Ctx[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_PARMS |
    195                                                STENCIL_FAIL_OP(fop) |
    196                                                STENCIL_PASS_DEPTH_FAIL_OP
    197                                                (dfop) |
    198                                                STENCIL_PASS_DEPTH_PASS_OP
    199                                                (dpop));
    200 }
    201 
    202 static void
    203 i830AlphaFunc(struct gl_context * ctx, GLenum func, GLfloat ref)
    204 {
    205    struct i830_context *i830 = i830_context(ctx);
    206    int test = intel_translate_compare_func(func);
    207    GLubyte refByte;
    208    GLuint refInt;
    209 
    210    UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref);
    211    refInt = (GLuint) refByte;
    212 
    213    I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    214    i830->state.Ctx[I830_CTXREG_STATE2] &= ~ALPHA_TEST_REF_MASK;
    215    i830->state.Ctx[I830_CTXREG_STATE2] |= (ENABLE_ALPHA_TEST_FUNC |
    216                                            ENABLE_ALPHA_REF_VALUE |
    217                                            ALPHA_TEST_FUNC(test) |
    218                                            ALPHA_REF_VALUE(refInt));
    219 }
    220 
    221 /**
    222  * Makes sure that the proper enables are set for LogicOp, Independent Alpha
    223  * Blend, and Blending.  It needs to be called from numerous places where we
    224  * could change the LogicOp or Independent Alpha Blend without subsequent
    225  * calls to glEnable.
    226  *
    227  * \todo
    228  * This function is substantially different from the old i830-specific driver.
    229  * I'm not sure which is correct.
    230  */
    231 static void
    232 i830EvalLogicOpBlendState(struct gl_context * ctx)
    233 {
    234    struct i830_context *i830 = i830_context(ctx);
    235 
    236    I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    237 
    238    if (ctx->Color.ColorLogicOpEnabled) {
    239       i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND |
    240                                                   ENABLE_LOGIC_OP_MASK);
    241       i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND |
    242                                                  ENABLE_LOGIC_OP);
    243    }
    244    else if (ctx->Color.BlendEnabled) {
    245       i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND |
    246                                                   ENABLE_LOGIC_OP_MASK);
    247       i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (ENABLE_COLOR_BLEND |
    248                                                  DISABLE_LOGIC_OP);
    249    }
    250    else {
    251       i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND |
    252                                                   ENABLE_LOGIC_OP_MASK);
    253       i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND |
    254                                                  DISABLE_LOGIC_OP);
    255    }
    256 }
    257 
    258 static void
    259 i830BlendColor(struct gl_context * ctx, const GLfloat color[4])
    260 {
    261    struct i830_context *i830 = i830_context(ctx);
    262    GLubyte r, g, b, a;
    263 
    264    DBG("%s\n", __func__);
    265 
    266    UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]);
    267    UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]);
    268    UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]);
    269    UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]);
    270 
    271    I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    272    i830->state.Ctx[I830_CTXREG_BLENDCOLOR1] =
    273       (a << 24) | (r << 16) | (g << 8) | b;
    274 }
    275 
    276 /**
    277  * Sets both the blend equation (called "function" in i830 docs) and the
    278  * blend function (called "factor" in i830 docs).  This is done in a single
    279  * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
    280  * change the interpretation of the blend function.
    281  */
    282 static void
    283 i830_set_blend_state(struct gl_context * ctx)
    284 {
    285    struct i830_context *i830 = i830_context(ctx);
    286    int funcA;
    287    int funcRGB;
    288    int eqnA;
    289    int eqnRGB;
    290    int iab;
    291    int s1;
    292 
    293 
    294    funcRGB =
    295       SRC_BLND_FACT(intel_translate_blend_factor(ctx->Color.Blend[0].SrcRGB))
    296       | DST_BLND_FACT(intel_translate_blend_factor(ctx->Color.Blend[0].DstRGB));
    297 
    298    switch (ctx->Color.Blend[0].EquationRGB) {
    299    case GL_FUNC_ADD:
    300       eqnRGB = BLENDFUNC_ADD;
    301       break;
    302    case GL_MIN:
    303       eqnRGB = BLENDFUNC_MIN;
    304       funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE);
    305       break;
    306    case GL_MAX:
    307       eqnRGB = BLENDFUNC_MAX;
    308       funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE);
    309       break;
    310    case GL_FUNC_SUBTRACT:
    311       eqnRGB = BLENDFUNC_SUB;
    312       break;
    313    case GL_FUNC_REVERSE_SUBTRACT:
    314       eqnRGB = BLENDFUNC_RVRSE_SUB;
    315       break;
    316    default:
    317       fprintf(stderr, "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
    318               __func__, __LINE__, ctx->Color.Blend[0].EquationRGB);
    319       return;
    320    }
    321 
    322 
    323    funcA = SRC_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.Blend[0].SrcA))
    324       | DST_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.Blend[0].DstA));
    325 
    326    switch (ctx->Color.Blend[0].EquationA) {
    327    case GL_FUNC_ADD:
    328       eqnA = BLENDFUNC_ADD;
    329       break;
    330    case GL_MIN:
    331       eqnA = BLENDFUNC_MIN;
    332       funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE);
    333       break;
    334    case GL_MAX:
    335       eqnA = BLENDFUNC_MAX;
    336       funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE);
    337       break;
    338    case GL_FUNC_SUBTRACT:
    339       eqnA = BLENDFUNC_SUB;
    340       break;
    341    case GL_FUNC_REVERSE_SUBTRACT:
    342       eqnA = BLENDFUNC_RVRSE_SUB;
    343       break;
    344    default:
    345       fprintf(stderr, "[%s:%u] Invalid alpha blend equation (0x%04x).\n",
    346               __func__, __LINE__, ctx->Color.Blend[0].EquationA);
    347       return;
    348    }
    349 
    350    iab = eqnA | funcA
    351       | _3DSTATE_INDPT_ALPHA_BLEND_CMD
    352       | ENABLE_SRC_ABLEND_FACTOR | ENABLE_DST_ABLEND_FACTOR
    353       | ENABLE_ALPHA_BLENDFUNC;
    354    s1 = eqnRGB | funcRGB
    355       | _3DSTATE_MODES_1_CMD
    356       | ENABLE_SRC_BLND_FACTOR | ENABLE_DST_BLND_FACTOR
    357       | ENABLE_COLR_BLND_FUNC;
    358 
    359    if ((eqnA | funcA) != (eqnRGB | funcRGB))
    360       iab |= ENABLE_INDPT_ALPHA_BLEND;
    361    else
    362       iab |= DISABLE_INDPT_ALPHA_BLEND;
    363 
    364    if (iab != i830->state.Ctx[I830_CTXREG_IALPHAB] ||
    365        s1 != i830->state.Ctx[I830_CTXREG_STATE1]) {
    366       I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    367       i830->state.Ctx[I830_CTXREG_IALPHAB] = iab;
    368       i830->state.Ctx[I830_CTXREG_STATE1] = s1;
    369    }
    370 
    371    /* This will catch a logicop blend equation.  It will also ensure
    372     * independent alpha blend is really in the correct state (either enabled
    373     * or disabled) if blending is already enabled.
    374     */
    375 
    376    i830EvalLogicOpBlendState(ctx);
    377 
    378    if (0) {
    379       fprintf(stderr,
    380               "[%s:%u] STATE1: 0x%08x IALPHAB: 0x%08x blend is %sabled\n",
    381               __func__, __LINE__, i830->state.Ctx[I830_CTXREG_STATE1],
    382               i830->state.Ctx[I830_CTXREG_IALPHAB],
    383               (ctx->Color.BlendEnabled) ? "en" : "dis");
    384    }
    385 }
    386 
    387 
    388 static void
    389 i830BlendEquationSeparate(struct gl_context * ctx, GLenum modeRGB, GLenum modeA)
    390 {
    391    DBG("%s -> %s, %s\n", __func__,
    392        _mesa_enum_to_string(modeRGB),
    393        _mesa_enum_to_string(modeA));
    394 
    395    (void) modeRGB;
    396    (void) modeA;
    397    i830_set_blend_state(ctx);
    398 }
    399 
    400 
    401 static void
    402 i830BlendFuncSeparate(struct gl_context * ctx, GLenum sfactorRGB,
    403                       GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA)
    404 {
    405    DBG("%s -> RGB(%s, %s) A(%s, %s)\n", __func__,
    406        _mesa_enum_to_string(sfactorRGB),
    407        _mesa_enum_to_string(dfactorRGB),
    408        _mesa_enum_to_string(sfactorA),
    409        _mesa_enum_to_string(dfactorA));
    410 
    411    (void) sfactorRGB;
    412    (void) dfactorRGB;
    413    (void) sfactorA;
    414    (void) dfactorA;
    415    i830_set_blend_state(ctx);
    416 }
    417 
    418 
    419 
    420 static void
    421 i830DepthFunc(struct gl_context * ctx, GLenum func)
    422 {
    423    struct i830_context *i830 = i830_context(ctx);
    424    int test = intel_translate_compare_func(func);
    425 
    426    DBG("%s\n", __func__);
    427 
    428    I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    429    i830->state.Ctx[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK;
    430    i830->state.Ctx[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC |
    431                                            DEPTH_TEST_FUNC(test));
    432 }
    433 
    434 static void
    435 i830DepthMask(struct gl_context * ctx, GLboolean flag)
    436 {
    437    struct i830_context *i830 = i830_context(ctx);
    438 
    439    DBG("%s flag (%d)\n", __func__, flag);
    440 
    441    if (!ctx->DrawBuffer || !ctx->DrawBuffer->Visual.depthBits)
    442       flag = false;
    443 
    444    I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    445 
    446    i830->state.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK;
    447 
    448    if (flag && ctx->Depth.Test)
    449       i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE;
    450    else
    451       i830->state.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE;
    452 }
    453 
    454 /** Called from ctx->Driver.DepthRange() */
    455 static void
    456 i830DepthRange(struct gl_context *ctx)
    457 {
    458    intelCalcViewport(ctx);
    459 }
    460 
    461 /* =============================================================
    462  * Polygon stipple
    463  *
    464  * The i830 supports a 4x4 stipple natively, GL wants 32x32.
    465  * Fortunately stipple is usually a repeating pattern.
    466  */
    467 static void
    468 i830PolygonStipple(struct gl_context * ctx, const GLubyte * mask)
    469 {
    470    struct i830_context *i830 = i830_context(ctx);
    471    const GLubyte *m;
    472    GLubyte p[4];
    473    int i, j, k;
    474    int active = (ctx->Polygon.StippleFlag &&
    475                  i830->intel.reduced_primitive == GL_TRIANGLES);
    476    GLuint newMask;
    477 
    478    if (active) {
    479       I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE);
    480       i830->state.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE;
    481    }
    482 
    483    /* Use the already unpacked stipple data from the context rather than the
    484     * uninterpreted mask passed in.
    485     */
    486    mask = (const GLubyte *)ctx->PolygonStipple;
    487    m = mask;
    488 
    489    p[0] = mask[12] & 0xf;
    490    p[0] |= p[0] << 4;
    491    p[1] = mask[8] & 0xf;
    492    p[1] |= p[1] << 4;
    493    p[2] = mask[4] & 0xf;
    494    p[2] |= p[2] << 4;
    495    p[3] = mask[0] & 0xf;
    496    p[3] |= p[3] << 4;
    497 
    498    for (k = 0; k < 8; k++)
    499       for (j = 3; j >= 0; j--)
    500          for (i = 0; i < 4; i++, m++)
    501             if (*m != p[j]) {
    502                i830->intel.hw_stipple = 0;
    503                return;
    504             }
    505 
    506    newMask = (((p[0] & 0xf) << 0) |
    507               ((p[1] & 0xf) << 4) |
    508               ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12));
    509 
    510 
    511    if (newMask == 0xffff || newMask == 0x0) {
    512       /* this is needed to make conform pass */
    513       i830->intel.hw_stipple = 0;
    514       return;
    515    }
    516 
    517    i830->state.Stipple[I830_STPREG_ST1] &= ~0xffff;
    518    i830->state.Stipple[I830_STPREG_ST1] |= newMask;
    519    i830->intel.hw_stipple = 1;
    520 
    521    if (active)
    522       i830->state.Stipple[I830_STPREG_ST1] |= ST1_ENABLE;
    523 }
    524 
    525 
    526 /* =============================================================
    527  * Hardware clipping
    528  */
    529 static void
    530 i830Scissor(struct gl_context * ctx)
    531 {
    532    struct i830_context *i830 = i830_context(ctx);
    533    int x1, y1, x2, y2;
    534 
    535    if (!ctx->DrawBuffer)
    536       return;
    537 
    538    DBG("%s %d,%d %dx%d\n", __func__,
    539        ctx->Scissor.ScissorArray[0].X,     ctx->Scissor.ScissorArray[0].Y,
    540        ctx->Scissor.ScissorArray[0].Width, ctx->Scissor.ScissorArray[0].Height);
    541 
    542    if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
    543       x1 = ctx->Scissor.ScissorArray[0].X;
    544       y1 = ctx->DrawBuffer->Height - (ctx->Scissor.ScissorArray[0].Y
    545                                       + ctx->Scissor.ScissorArray[0].Height);
    546       x2 = ctx->Scissor.ScissorArray[0].X
    547          + ctx->Scissor.ScissorArray[0].Width - 1;
    548       y2 = y1 + ctx->Scissor.ScissorArray[0].Height - 1;
    549       DBG("%s %d..%d,%d..%d (inverted)\n", __func__, x1, x2, y1, y2);
    550    }
    551    else {
    552       /* FBO - not inverted
    553        */
    554       x1 = ctx->Scissor.ScissorArray[0].X;
    555       y1 = ctx->Scissor.ScissorArray[0].Y;
    556       x2 = ctx->Scissor.ScissorArray[0].X
    557          + ctx->Scissor.ScissorArray[0].Width - 1;
    558       y2 = ctx->Scissor.ScissorArray[0].Y
    559          + ctx->Scissor.ScissorArray[0].Height - 1;
    560       DBG("%s %d..%d,%d..%d (not inverted)\n", __func__, x1, x2, y1, y2);
    561    }
    562 
    563    x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1);
    564    y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1);
    565    x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1);
    566    y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1);
    567 
    568    DBG("%s %d..%d,%d..%d (clamped)\n", __func__, x1, x2, y1, y2);
    569 
    570    I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS);
    571    i830->state.Buffer[I830_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff);
    572    i830->state.Buffer[I830_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff);
    573 }
    574 
    575 static void
    576 i830LogicOp(struct gl_context * ctx, GLenum opcode)
    577 {
    578    struct i830_context *i830 = i830_context(ctx);
    579    int tmp = intel_translate_logic_op(opcode);
    580 
    581    DBG("%s\n", __func__);
    582 
    583    I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    584    i830->state.Ctx[I830_CTXREG_STATE4] &= ~LOGICOP_MASK;
    585    i830->state.Ctx[I830_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp);
    586 }
    587 
    588 
    589 
    590 static void
    591 i830CullFaceFrontFace(struct gl_context * ctx, GLenum unused)
    592 {
    593    struct i830_context *i830 = i830_context(ctx);
    594    GLuint mode;
    595 
    596    DBG("%s\n", __func__);
    597 
    598    if (!ctx->Polygon.CullFlag) {
    599       mode = CULLMODE_NONE;
    600    }
    601    else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) {
    602       mode = CULLMODE_CW;
    603 
    604       if (ctx->DrawBuffer && _mesa_is_user_fbo(ctx->DrawBuffer))
    605          mode ^= (CULLMODE_CW ^ CULLMODE_CCW);
    606       if (ctx->Polygon.CullFaceMode == GL_FRONT)
    607          mode ^= (CULLMODE_CW ^ CULLMODE_CCW);
    608       if (ctx->Polygon.FrontFace != GL_CCW)
    609          mode ^= (CULLMODE_CW ^ CULLMODE_CCW);
    610    }
    611    else {
    612       mode = CULLMODE_BOTH;
    613    }
    614 
    615    I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    616    i830->state.Ctx[I830_CTXREG_STATE3] &= ~CULLMODE_MASK;
    617    i830->state.Ctx[I830_CTXREG_STATE3] |= ENABLE_CULL_MODE | mode;
    618 }
    619 
    620 static void
    621 i830LineWidth(struct gl_context * ctx, GLfloat widthf)
    622 {
    623    struct i830_context *i830 = i830_context(ctx);
    624    int width;
    625    int state5;
    626 
    627    DBG("%s\n", __func__);
    628 
    629    width = (int) (widthf * 2);
    630    width = CLAMP(width, 1, 15);
    631 
    632    state5 = i830->state.Ctx[I830_CTXREG_STATE5] & ~FIXED_LINE_WIDTH_MASK;
    633    state5 |= (ENABLE_FIXED_LINE_WIDTH | FIXED_LINE_WIDTH(width));
    634 
    635    if (state5 != i830->state.Ctx[I830_CTXREG_STATE5]) {
    636       I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    637       i830->state.Ctx[I830_CTXREG_STATE5] = state5;
    638    }
    639 }
    640 
    641 static void
    642 i830PointSize(struct gl_context * ctx, GLfloat size)
    643 {
    644    struct i830_context *i830 = i830_context(ctx);
    645    GLint point_size = (int) size;
    646 
    647    DBG("%s\n", __func__);
    648 
    649    point_size = CLAMP(point_size, 1, 256);
    650    I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    651    i830->state.Ctx[I830_CTXREG_STATE5] &= ~FIXED_POINT_WIDTH_MASK;
    652    i830->state.Ctx[I830_CTXREG_STATE5] |= (ENABLE_FIXED_POINT_WIDTH |
    653                                            FIXED_POINT_WIDTH(point_size));
    654 }
    655 
    656 
    657 /* =============================================================
    658  * Color masks
    659  */
    660 
    661 static void
    662 i830ColorMask(struct gl_context * ctx,
    663               GLboolean r, GLboolean g, GLboolean b, GLboolean a)
    664 {
    665    struct i830_context *i830 = i830_context(ctx);
    666    GLuint tmp = 0;
    667 
    668    DBG("%s r(%d) g(%d) b(%d) a(%d)\n", __func__, r, g, b, a);
    669 
    670    tmp = ((i830->state.Ctx[I830_CTXREG_ENABLES_2] & ~WRITEMASK_MASK) |
    671           ENABLE_COLOR_MASK |
    672           ENABLE_COLOR_WRITE |
    673           ((!r) << WRITEMASK_RED_SHIFT) |
    674           ((!g) << WRITEMASK_GREEN_SHIFT) |
    675           ((!b) << WRITEMASK_BLUE_SHIFT) | ((!a) << WRITEMASK_ALPHA_SHIFT));
    676 
    677    if (tmp != i830->state.Ctx[I830_CTXREG_ENABLES_2]) {
    678       I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    679       i830->state.Ctx[I830_CTXREG_ENABLES_2] = tmp;
    680    }
    681 }
    682 
    683 static void
    684 update_specular(struct gl_context * ctx)
    685 {
    686    struct i830_context *i830 = i830_context(ctx);
    687 
    688    I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    689    i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK;
    690 
    691    if (_mesa_need_secondary_color(ctx))
    692       i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_SPEC_ADD;
    693    else
    694       i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_SPEC_ADD;
    695 }
    696 
    697 static void
    698 i830LightModelfv(struct gl_context * ctx, GLenum pname, const GLfloat * param)
    699 {
    700    DBG("%s\n", __func__);
    701 
    702    if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
    703       update_specular(ctx);
    704    }
    705 }
    706 
    707 /* In Mesa 3.5 we can reliably do native flatshading.
    708  */
    709 static void
    710 i830ShadeModel(struct gl_context * ctx, GLenum mode)
    711 {
    712    struct i830_context *i830 = i830_context(ctx);
    713    I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    714 
    715 
    716 #define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4))
    717 
    718    i830->state.Ctx[I830_CTXREG_STATE3] &= ~SHADE_MODE_MASK;
    719 
    720    if (mode == GL_FLAT) {
    721       i830->state.Ctx[I830_CTXREG_STATE3] |=
    722          (ALPHA_SHADE_MODE(SHADE_MODE_FLAT) | FOG_SHADE_MODE(SHADE_MODE_FLAT)
    723           | SPEC_SHADE_MODE(SHADE_MODE_FLAT) |
    724           COLOR_SHADE_MODE(SHADE_MODE_FLAT));
    725    }
    726    else {
    727       i830->state.Ctx[I830_CTXREG_STATE3] |=
    728          (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) |
    729           FOG_SHADE_MODE(SHADE_MODE_LINEAR) |
    730           SPEC_SHADE_MODE(SHADE_MODE_LINEAR) |
    731           COLOR_SHADE_MODE(SHADE_MODE_LINEAR));
    732    }
    733 }
    734 
    735 /* =============================================================
    736  * Fog
    737  */
    738 static void
    739 i830Fogfv(struct gl_context * ctx, GLenum pname, const GLfloat * param)
    740 {
    741    struct i830_context *i830 = i830_context(ctx);
    742 
    743    DBG("%s\n", __func__);
    744 
    745    if (pname == GL_FOG_COLOR) {
    746       GLuint color = (((GLubyte) (ctx->Fog.Color[0] * 255.0F) << 16) |
    747                       ((GLubyte) (ctx->Fog.Color[1] * 255.0F) << 8) |
    748                       ((GLubyte) (ctx->Fog.Color[2] * 255.0F) << 0));
    749 
    750       I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    751       i830->state.Ctx[I830_CTXREG_FOGCOLOR] =
    752          (_3DSTATE_FOG_COLOR_CMD | color);
    753    }
    754 }
    755 
    756 /* =============================================================
    757  */
    758 
    759 static void
    760 i830Enable(struct gl_context * ctx, GLenum cap, GLboolean state)
    761 {
    762    struct i830_context *i830 = i830_context(ctx);
    763 
    764    switch (cap) {
    765    case GL_LIGHTING:
    766    case GL_COLOR_SUM:
    767       update_specular(ctx);
    768       break;
    769 
    770    case GL_ALPHA_TEST:
    771       I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    772       i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_ALPHA_TEST_MASK;
    773       if (state)
    774          i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_ALPHA_TEST;
    775       else
    776          i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_ALPHA_TEST;
    777 
    778       break;
    779 
    780    case GL_BLEND:
    781       i830EvalLogicOpBlendState(ctx);
    782       break;
    783 
    784    case GL_COLOR_LOGIC_OP:
    785       i830EvalLogicOpBlendState(ctx);
    786 
    787       /* Logicop doesn't seem to work at 16bpp:
    788        */
    789       if (i830->intel.ctx.Visual.rgbBits == 16)
    790          FALLBACK(&i830->intel, I830_FALLBACK_LOGICOP, state);
    791       break;
    792 
    793    case GL_DITHER:
    794       I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    795       i830->state.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DITHER;
    796 
    797       if (state)
    798          i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DITHER;
    799       else
    800          i830->state.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DITHER;
    801       break;
    802 
    803    case GL_DEPTH_TEST:
    804       I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    805       i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK;
    806 
    807       if (!ctx->DrawBuffer || !ctx->DrawBuffer->Visual.depthBits)
    808 	 state = false;
    809 
    810       if (state)
    811          i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST;
    812       else
    813          i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST;
    814 
    815       /* Also turn off depth writes when GL_DEPTH_TEST is disabled:
    816        */
    817       i830DepthMask(ctx, ctx->Depth.Mask);
    818       break;
    819 
    820    case GL_SCISSOR_TEST:
    821       I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS);
    822 
    823       if (state)
    824          i830->state.Buffer[I830_DESTREG_SENABLE] =
    825             (_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT);
    826       else
    827          i830->state.Buffer[I830_DESTREG_SENABLE] =
    828             (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
    829 
    830       break;
    831 
    832    case GL_LINE_SMOOTH:
    833       I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    834 
    835       i830->state.Ctx[I830_CTXREG_AA] &= ~AA_LINE_ENABLE;
    836       if (state)
    837          i830->state.Ctx[I830_CTXREG_AA] |= AA_LINE_ENABLE;
    838       else
    839          i830->state.Ctx[I830_CTXREG_AA] |= AA_LINE_DISABLE;
    840       break;
    841 
    842    case GL_FOG:
    843       I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    844       i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_FOG_MASK;
    845       if (state)
    846          i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_FOG;
    847       else
    848          i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_FOG;
    849       break;
    850 
    851    case GL_CULL_FACE:
    852       i830CullFaceFrontFace(ctx, 0);
    853       break;
    854 
    855    case GL_TEXTURE_2D:
    856       break;
    857 
    858    case GL_STENCIL_TEST:
    859       {
    860          bool hw_stencil = false;
    861          if (ctx->DrawBuffer) {
    862             struct intel_renderbuffer *irbStencil
    863                = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
    864             hw_stencil = (irbStencil && irbStencil->mt);
    865          }
    866          if (hw_stencil) {
    867             I830_STATECHANGE(i830, I830_UPLOAD_CTX);
    868 
    869             if (state) {
    870                i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST;
    871                i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE;
    872             }
    873             else {
    874                i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST;
    875                i830->state.Ctx[I830_CTXREG_ENABLES_2] &=
    876                   ~ENABLE_STENCIL_WRITE;
    877                i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST;
    878                i830->state.Ctx[I830_CTXREG_ENABLES_2] |=
    879                   DISABLE_STENCIL_WRITE;
    880             }
    881          }
    882          else {
    883             FALLBACK(&i830->intel, I830_FALLBACK_STENCIL, state);
    884          }
    885       }
    886       break;
    887 
    888    case GL_POLYGON_STIPPLE:
    889       /* The stipple command worked on my 855GM box, but not my 845G.
    890        * I'll do more testing later to find out exactly which hardware
    891        * supports it.  Disabled for now.
    892        */
    893       if (i830->intel.hw_stipple &&
    894           i830->intel.reduced_primitive == GL_TRIANGLES) {
    895          I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE);
    896          i830->state.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE;
    897          if (state)
    898             i830->state.Stipple[I830_STPREG_ST1] |= ST1_ENABLE;
    899       }
    900       break;
    901 
    902    default:
    903       ;
    904    }
    905 }
    906 
    907 
    908 static void
    909 i830_init_packets(struct i830_context *i830)
    910 {
    911    /* Zero all state */
    912    memset(&i830->state, 0, sizeof(i830->state));
    913 
    914    /* Set default blend state */
    915    i830->state.TexBlend[0][0] = (_3DSTATE_MAP_BLEND_OP_CMD(0) |
    916                                  TEXPIPE_COLOR |
    917                                  ENABLE_TEXOUTPUT_WRT_SEL |
    918                                  TEXOP_OUTPUT_CURRENT |
    919                                  DISABLE_TEX_CNTRL_STAGE |
    920                                  TEXOP_SCALE_1X |
    921                                  TEXOP_MODIFY_PARMS |
    922                                  TEXOP_LAST_STAGE | TEXBLENDOP_ARG1);
    923    i830->state.TexBlend[0][1] = (_3DSTATE_MAP_BLEND_OP_CMD(0) |
    924                                  TEXPIPE_ALPHA |
    925                                  ENABLE_TEXOUTPUT_WRT_SEL |
    926                                  TEXOP_OUTPUT_CURRENT |
    927                                  TEXOP_SCALE_1X |
    928                                  TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1);
    929    i830->state.TexBlend[0][2] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) |
    930                                  TEXPIPE_COLOR |
    931                                  TEXBLEND_ARG1 |
    932                                  TEXBLENDARG_MODIFY_PARMS |
    933                                  TEXBLENDARG_DIFFUSE);
    934    i830->state.TexBlend[0][3] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) |
    935                                  TEXPIPE_ALPHA |
    936                                  TEXBLEND_ARG1 |
    937                                  TEXBLENDARG_MODIFY_PARMS |
    938                                  TEXBLENDARG_DIFFUSE);
    939 
    940    i830->state.TexBlendWordsUsed[0] = 4;
    941 
    942 
    943    i830->state.Ctx[I830_CTXREG_VF] = 0;
    944    i830->state.Ctx[I830_CTXREG_VF2] = 0;
    945 
    946    i830->state.Ctx[I830_CTXREG_AA] = (_3DSTATE_AA_CMD |
    947                                       AA_LINE_ECAAR_WIDTH_ENABLE |
    948                                       AA_LINE_ECAAR_WIDTH_1_0 |
    949                                       AA_LINE_REGION_WIDTH_ENABLE |
    950                                       AA_LINE_REGION_WIDTH_1_0 |
    951                                       AA_LINE_DISABLE);
    952 
    953    i830->state.Ctx[I830_CTXREG_ENABLES_1] = (_3DSTATE_ENABLES_1_CMD |
    954                                              DISABLE_LOGIC_OP |
    955                                              DISABLE_STENCIL_TEST |
    956                                              DISABLE_DEPTH_BIAS |
    957                                              DISABLE_SPEC_ADD |
    958                                              DISABLE_FOG |
    959                                              DISABLE_ALPHA_TEST |
    960                                              DISABLE_COLOR_BLEND |
    961                                              DISABLE_DEPTH_TEST);
    962 
    963 #if 000                         /* XXX all the stencil enable state is set in i830Enable(), right? */
    964    if (i830->intel.hw_stencil) {
    965       i830->state.Ctx[I830_CTXREG_ENABLES_2] = (_3DSTATE_ENABLES_2_CMD |
    966                                                 ENABLE_STENCIL_WRITE |
    967                                                 ENABLE_TEX_CACHE |
    968                                                 ENABLE_DITHER |
    969                                                 ENABLE_COLOR_MASK |
    970                                                 /* set no color comps disabled */
    971                                                 ENABLE_COLOR_WRITE |
    972                                                 ENABLE_DEPTH_WRITE);
    973    }
    974    else
    975 #endif
    976    {
    977       i830->state.Ctx[I830_CTXREG_ENABLES_2] = (_3DSTATE_ENABLES_2_CMD |
    978                                                 DISABLE_STENCIL_WRITE |
    979                                                 ENABLE_TEX_CACHE |
    980                                                 ENABLE_DITHER |
    981                                                 ENABLE_COLOR_MASK |
    982                                                 /* set no color comps disabled */
    983                                                 ENABLE_COLOR_WRITE |
    984                                                 ENABLE_DEPTH_WRITE);
    985    }
    986 
    987    i830->state.Ctx[I830_CTXREG_STATE1] = (_3DSTATE_MODES_1_CMD |
    988                                           ENABLE_COLR_BLND_FUNC |
    989                                           BLENDFUNC_ADD |
    990                                           ENABLE_SRC_BLND_FACTOR |
    991                                           SRC_BLND_FACT(BLENDFACT_ONE) |
    992                                           ENABLE_DST_BLND_FACTOR |
    993                                           DST_BLND_FACT(BLENDFACT_ZERO));
    994 
    995    i830->state.Ctx[I830_CTXREG_STATE2] = (_3DSTATE_MODES_2_CMD |
    996                                           ENABLE_GLOBAL_DEPTH_BIAS |
    997                                           GLOBAL_DEPTH_BIAS(0) |
    998                                           ENABLE_ALPHA_TEST_FUNC |
    999                                           ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS)
   1000                                           | ALPHA_REF_VALUE(0));
   1001 
   1002    i830->state.Ctx[I830_CTXREG_STATE3] = (_3DSTATE_MODES_3_CMD |
   1003                                           ENABLE_DEPTH_TEST_FUNC |
   1004                                           DEPTH_TEST_FUNC(COMPAREFUNC_LESS) |
   1005                                           ENABLE_ALPHA_SHADE_MODE |
   1006                                           ALPHA_SHADE_MODE(SHADE_MODE_LINEAR)
   1007                                           | ENABLE_FOG_SHADE_MODE |
   1008                                           FOG_SHADE_MODE(SHADE_MODE_LINEAR) |
   1009                                           ENABLE_SPEC_SHADE_MODE |
   1010                                           SPEC_SHADE_MODE(SHADE_MODE_LINEAR) |
   1011                                           ENABLE_COLOR_SHADE_MODE |
   1012                                           COLOR_SHADE_MODE(SHADE_MODE_LINEAR)
   1013                                           | ENABLE_CULL_MODE | CULLMODE_NONE);
   1014 
   1015    i830->state.Ctx[I830_CTXREG_STATE4] = (_3DSTATE_MODES_4_CMD |
   1016                                           ENABLE_LOGIC_OP_FUNC |
   1017                                           LOGIC_OP_FUNC(LOGICOP_COPY) |
   1018                                           ENABLE_STENCIL_TEST_MASK |
   1019                                           STENCIL_TEST_MASK(0xff) |
   1020                                           ENABLE_STENCIL_WRITE_MASK |
   1021                                           STENCIL_WRITE_MASK(0xff));
   1022 
   1023    i830->state.Ctx[I830_CTXREG_STENCILTST] = (_3DSTATE_STENCIL_TEST_CMD |
   1024                                               ENABLE_STENCIL_PARMS |
   1025                                               STENCIL_FAIL_OP(STENCILOP_KEEP)
   1026                                               |
   1027                                               STENCIL_PASS_DEPTH_FAIL_OP
   1028                                               (STENCILOP_KEEP) |
   1029                                               STENCIL_PASS_DEPTH_PASS_OP
   1030                                               (STENCILOP_KEEP) |
   1031                                               ENABLE_STENCIL_TEST_FUNC |
   1032                                               STENCIL_TEST_FUNC
   1033                                               (COMPAREFUNC_ALWAYS) |
   1034                                               ENABLE_STENCIL_REF_VALUE |
   1035                                               STENCIL_REF_VALUE(0));
   1036 
   1037    i830->state.Ctx[I830_CTXREG_STATE5] = (_3DSTATE_MODES_5_CMD | FLUSH_TEXTURE_CACHE | ENABLE_SPRITE_POINT_TEX | SPRITE_POINT_TEX_OFF | ENABLE_FIXED_LINE_WIDTH | FIXED_LINE_WIDTH(0x2) |       /* 1.0 */
   1038                                           ENABLE_FIXED_POINT_WIDTH |
   1039                                           FIXED_POINT_WIDTH(1));
   1040 
   1041    i830->state.Ctx[I830_CTXREG_IALPHAB] = (_3DSTATE_INDPT_ALPHA_BLEND_CMD |
   1042                                            DISABLE_INDPT_ALPHA_BLEND |
   1043                                            ENABLE_ALPHA_BLENDFUNC |
   1044                                            ABLENDFUNC_ADD);
   1045 
   1046    i830->state.Ctx[I830_CTXREG_FOGCOLOR] = (_3DSTATE_FOG_COLOR_CMD |
   1047                                             FOG_COLOR_RED(0) |
   1048                                             FOG_COLOR_GREEN(0) |
   1049                                             FOG_COLOR_BLUE(0));
   1050 
   1051    i830->state.Ctx[I830_CTXREG_BLENDCOLOR0] = _3DSTATE_CONST_BLEND_COLOR_CMD;
   1052    i830->state.Ctx[I830_CTXREG_BLENDCOLOR1] = 0;
   1053 
   1054    i830->state.Ctx[I830_CTXREG_MCSB0] = _3DSTATE_MAP_COORD_SETBIND_CMD;
   1055    i830->state.Ctx[I830_CTXREG_MCSB1] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) |
   1056                                          TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) |
   1057                                          TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) |
   1058                                          TEXBIND_SET0(TEXCOORDSRC_VTXSET_0));
   1059 
   1060    i830->state.RasterRules[I830_RASTER_RULES] = (_3DSTATE_RASTER_RULES_CMD |
   1061 						 ENABLE_POINT_RASTER_RULE |
   1062 						 OGL_POINT_RASTER_RULE |
   1063 						 ENABLE_LINE_STRIP_PROVOKE_VRTX |
   1064 						 ENABLE_TRI_FAN_PROVOKE_VRTX |
   1065 						 ENABLE_TRI_STRIP_PROVOKE_VRTX |
   1066 						 LINE_STRIP_PROVOKE_VRTX(1) |
   1067 						 TRI_FAN_PROVOKE_VRTX(2) |
   1068 						 TRI_STRIP_PROVOKE_VRTX(2));
   1069 
   1070 
   1071    i830->state.Stipple[I830_STPREG_ST0] = _3DSTATE_STIPPLE;
   1072 
   1073    i830->state.Buffer[I830_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD;
   1074    i830->state.Buffer[I830_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD;
   1075    i830->state.Buffer[I830_DESTREG_SR1] = 0;
   1076    i830->state.Buffer[I830_DESTREG_SR2] = 0;
   1077    i830->state.Buffer[I830_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD |
   1078                                                DISABLE_SCISSOR_RECT);
   1079 }
   1080 
   1081 void
   1082 i830_update_provoking_vertex(struct gl_context * ctx)
   1083 {
   1084    struct i830_context *i830 = i830_context(ctx);
   1085 
   1086    I830_STATECHANGE(i830, I830_UPLOAD_RASTER_RULES);
   1087    i830->state.RasterRules[I830_RASTER_RULES] &= ~(LINE_STRIP_PROVOKE_VRTX_MASK |
   1088 						   TRI_FAN_PROVOKE_VRTX_MASK |
   1089 						   TRI_STRIP_PROVOKE_VRTX_MASK);
   1090 
   1091    /* _NEW_LIGHT */
   1092    if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION) {
   1093       i830->state.RasterRules[I830_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(1) |
   1094 						     TRI_FAN_PROVOKE_VRTX(2) |
   1095 						     TRI_STRIP_PROVOKE_VRTX(2));
   1096    } else {
   1097       i830->state.RasterRules[I830_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(0) |
   1098 						     TRI_FAN_PROVOKE_VRTX(1) |
   1099 						     TRI_STRIP_PROVOKE_VRTX(0));
   1100     }
   1101 }
   1102 
   1103 /* Fallback to swrast for select and feedback.
   1104  */
   1105 static void
   1106 i830RenderMode(struct gl_context *ctx, GLenum mode)
   1107 {
   1108    struct intel_context *intel = intel_context(ctx);
   1109    FALLBACK(intel, INTEL_FALLBACK_RENDERMODE, (mode != GL_RENDER));
   1110 }
   1111 
   1112 void
   1113 i830InitStateFuncs(struct dd_function_table *functions)
   1114 {
   1115    functions->AlphaFunc = i830AlphaFunc;
   1116    functions->BlendColor = i830BlendColor;
   1117    functions->BlendEquationSeparate = i830BlendEquationSeparate;
   1118    functions->BlendFuncSeparate = i830BlendFuncSeparate;
   1119    functions->ColorMask = i830ColorMask;
   1120    functions->CullFace = i830CullFaceFrontFace;
   1121    functions->DepthFunc = i830DepthFunc;
   1122    functions->DepthMask = i830DepthMask;
   1123    functions->Enable = i830Enable;
   1124    functions->Fogfv = i830Fogfv;
   1125    functions->FrontFace = i830CullFaceFrontFace;
   1126    functions->LightModelfv = i830LightModelfv;
   1127    functions->LineWidth = i830LineWidth;
   1128    functions->LogicOpcode = i830LogicOp;
   1129    functions->PointSize = i830PointSize;
   1130    functions->PolygonStipple = i830PolygonStipple;
   1131    functions->RenderMode = i830RenderMode;
   1132    functions->Scissor = i830Scissor;
   1133    functions->ShadeModel = i830ShadeModel;
   1134    functions->StencilFuncSeparate = i830StencilFuncSeparate;
   1135    functions->StencilMaskSeparate = i830StencilMaskSeparate;
   1136    functions->StencilOpSeparate = i830StencilOpSeparate;
   1137    functions->DepthRange = i830DepthRange;
   1138 }
   1139 
   1140 void
   1141 i830InitState(struct i830_context *i830)
   1142 {
   1143    struct gl_context *ctx = &i830->intel.ctx;
   1144 
   1145    i830_init_packets(i830);
   1146 
   1147    _mesa_init_driver_state(ctx);
   1148 
   1149    i830->state.emitted = 0;
   1150    i830->state.active = (I830_UPLOAD_INVARIENT |
   1151                          I830_UPLOAD_RASTER_RULES |
   1152                          I830_UPLOAD_TEXBLEND(0) |
   1153                          I830_UPLOAD_STIPPLE |
   1154                          I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS);
   1155 }
   1156