Home | History | Annotate | Download | only in swrast
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 1999-2008  Brian Paul   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 "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included
     14  * in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors:
     25  *    Keith Whitwell <keithw (at) vmware.com> Brian Paul
     26  */
     27 
     28 #include "main/imports.h"
     29 #include "main/bufferobj.h"
     30 #include "main/mtypes.h"
     31 #include "main/samplerobj.h"
     32 #include "main/teximage.h"
     33 #include "program/prog_parameter.h"
     34 #include "program/prog_statevars.h"
     35 #include "swrast.h"
     36 #include "s_blend.h"
     37 #include "s_context.h"
     38 #include "s_lines.h"
     39 #include "s_points.h"
     40 #include "s_span.h"
     41 #include "s_texfetch.h"
     42 #include "s_triangle.h"
     43 #include "s_texfilter.h"
     44 
     45 
     46 /**
     47  * Recompute the value of swrast->_RasterMask, etc. according to
     48  * the current context.  The _RasterMask field can be easily tested by
     49  * drivers to determine certain basic GL state (does the primitive need
     50  * stenciling, logic-op, fog, etc?).
     51  */
     52 static void
     53 _swrast_update_rasterflags( struct gl_context *ctx )
     54 {
     55    SWcontext *swrast = SWRAST_CONTEXT(ctx);
     56    GLbitfield rasterMask = 0;
     57    GLuint i;
     58 
     59    if (ctx->Color.AlphaEnabled)           rasterMask |= ALPHATEST_BIT;
     60    if (ctx->Color.BlendEnabled)           rasterMask |= BLEND_BIT;
     61    if (ctx->Depth.Test)                   rasterMask |= DEPTH_BIT;
     62    if (swrast->_FogEnabled)               rasterMask |= FOG_BIT;
     63    if (ctx->Scissor.EnableFlags)          rasterMask |= CLIP_BIT;
     64    if (ctx->Stencil._Enabled)             rasterMask |= STENCIL_BIT;
     65    for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
     66       if (!ctx->Color.ColorMask[i][0] ||
     67           !ctx->Color.ColorMask[i][1] ||
     68           !ctx->Color.ColorMask[i][2] ||
     69           !ctx->Color.ColorMask[i][3]) {
     70          rasterMask |= MASKING_BIT;
     71          break;
     72       }
     73    }
     74    if (ctx->Color.ColorLogicOpEnabled) rasterMask |= LOGIC_OP_BIT;
     75    if (ctx->Texture._MaxEnabledTexImageUnit >= 0) rasterMask |= TEXTURE_BIT;
     76    if (   ctx->ViewportArray[0].X < 0
     77        || ctx->ViewportArray[0].X + ctx->ViewportArray[0].Width > (GLfloat) ctx->DrawBuffer->Width
     78        || ctx->ViewportArray[0].Y < 0
     79        || ctx->ViewportArray[0].Y + ctx->ViewportArray[0].Height > (GLfloat) ctx->DrawBuffer->Height) {
     80       rasterMask |= CLIP_BIT;
     81    }
     82 
     83    if (ctx->Query.CurrentOcclusionObject)
     84       rasterMask |= OCCLUSION_BIT;
     85 
     86 
     87    /* If we're not drawing to exactly one color buffer set the
     88     * MULTI_DRAW_BIT flag.  Also set it if we're drawing to no
     89     * buffers or the RGBA or CI mask disables all writes.
     90     */
     91    if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {
     92       /* more than one color buffer designated for writing (or zero buffers) */
     93       rasterMask |= MULTI_DRAW_BIT;
     94    }
     95 
     96    for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
     97       if (ctx->Color.ColorMask[i][0] +
     98           ctx->Color.ColorMask[i][1] +
     99           ctx->Color.ColorMask[i][2] +
    100           ctx->Color.ColorMask[i][3] == 0) {
    101          rasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */
    102          break;
    103       }
    104    }
    105 
    106 
    107    if (_swrast_use_fragment_program(ctx)) {
    108       rasterMask |= FRAGPROG_BIT;
    109    }
    110 
    111    if (ctx->ATIFragmentShader._Enabled) {
    112       rasterMask |= ATIFRAGSHADER_BIT;
    113    }
    114 
    115 #if CHAN_TYPE == GL_FLOAT
    116    if (ctx->Color.ClampFragmentColor == GL_TRUE) {
    117       rasterMask |= CLAMPING_BIT;
    118    }
    119 #endif
    120 
    121    SWRAST_CONTEXT(ctx)->_RasterMask = rasterMask;
    122 }
    123 
    124 
    125 /**
    126  * Examine polygon cull state to compute the _BackfaceCullSign field.
    127  * _BackfaceCullSign will be 0 if no culling, -1 if culling back-faces,
    128  * and 1 if culling front-faces.  The Polygon FrontFace state also
    129  * factors in.
    130  */
    131 static void
    132 _swrast_update_polygon( struct gl_context *ctx )
    133 {
    134    GLfloat backface_sign;
    135 
    136    if (ctx->Polygon.CullFlag) {
    137       switch (ctx->Polygon.CullFaceMode) {
    138       case GL_BACK:
    139          backface_sign = -1.0F;
    140 	 break;
    141       case GL_FRONT:
    142          backface_sign = 1.0F;
    143 	 break;
    144       case GL_FRONT_AND_BACK:
    145          /* fallthrough */
    146       default:
    147 	 backface_sign = 0.0F;
    148       }
    149    }
    150    else {
    151       backface_sign = 0.0F;
    152    }
    153 
    154    SWRAST_CONTEXT(ctx)->_BackfaceCullSign = backface_sign;
    155 
    156    /* This is for front/back-face determination, but not for culling */
    157    SWRAST_CONTEXT(ctx)->_BackfaceSign
    158       = (ctx->Polygon.FrontFace == GL_CW) ? -1.0F : 1.0F;
    159 }
    160 
    161 
    162 
    163 /**
    164  * Update the _PreferPixelFog field to indicate if we need to compute
    165  * fog blend factors (from the fog coords) per-fragment.
    166  */
    167 static void
    168 _swrast_update_fog_hint( struct gl_context *ctx )
    169 {
    170    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    171    swrast->_PreferPixelFog = (!swrast->AllowVertexFog ||
    172 			      _swrast_use_fragment_program(ctx) ||
    173 			      (ctx->Hint.Fog == GL_NICEST &&
    174 			       swrast->AllowPixelFog));
    175 }
    176 
    177 
    178 
    179 /**
    180  * Update the swrast->_TextureCombinePrimary flag.
    181  */
    182 static void
    183 _swrast_update_texture_env( struct gl_context *ctx )
    184 {
    185    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    186    GLuint i;
    187 
    188    swrast->_TextureCombinePrimary = GL_FALSE;
    189 
    190    for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
    191       const struct gl_tex_env_combine_state *combine =
    192          ctx->Texture.Unit[i]._CurrentCombine;
    193       GLuint term;
    194       for (term = 0; term < combine->_NumArgsRGB; term++) {
    195          if (combine->SourceRGB[term] == GL_PRIMARY_COLOR) {
    196             swrast->_TextureCombinePrimary = GL_TRUE;
    197             return;
    198          }
    199          if (combine->SourceA[term] == GL_PRIMARY_COLOR) {
    200             swrast->_TextureCombinePrimary = GL_TRUE;
    201             return;
    202          }
    203       }
    204    }
    205 }
    206 
    207 
    208 /**
    209  * Determine if we can defer texturing/shading until after Z/stencil
    210  * testing.  This potentially allows us to skip texturing/shading for
    211  * lots of fragments.
    212  */
    213 static void
    214 _swrast_update_deferred_texture(struct gl_context *ctx)
    215 {
    216    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    217    if (ctx->Color.AlphaEnabled) {
    218       /* alpha test depends on post-texture/shader colors */
    219       swrast->_DeferredTexture = GL_FALSE;
    220    }
    221    else {
    222       GLboolean use_fprog = _swrast_use_fragment_program(ctx);
    223       const struct gl_program *fprog = ctx->FragmentProgram._Current;
    224       if (use_fprog &&
    225           (fprog->info.outputs_written & (1 << FRAG_RESULT_DEPTH))) {
    226          /* Z comes from fragment program/shader */
    227          swrast->_DeferredTexture = GL_FALSE;
    228       }
    229       else if (use_fprog && fprog->info.fs.uses_discard) {
    230          swrast->_DeferredTexture = GL_FALSE;
    231       }
    232       else if (ctx->Query.CurrentOcclusionObject) {
    233          /* occlusion query depends on shader discard/kill results */
    234          swrast->_DeferredTexture = GL_FALSE;
    235       }
    236       else {
    237          swrast->_DeferredTexture = GL_TRUE;
    238       }
    239    }
    240 }
    241 
    242 
    243 /**
    244  * Update swrast->_FogColor and swrast->_FogEnable values.
    245  */
    246 static void
    247 _swrast_update_fog_state( struct gl_context *ctx )
    248 {
    249    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    250    const struct gl_program *fp = ctx->FragmentProgram._Current;
    251 
    252    assert(fp == NULL || fp->Target == GL_FRAGMENT_PROGRAM_ARB);
    253    (void) fp; /* silence unused var warning */
    254 
    255    /* determine if fog is needed, and if so, which fog mode */
    256    swrast->_FogEnabled = (!_swrast_use_fragment_program(ctx) &&
    257 			  ctx->Fog.Enabled);
    258 }
    259 
    260 
    261 /**
    262  * Update state for running fragment programs.  Basically, load the
    263  * program parameters with current state values.
    264  */
    265 static void
    266 _swrast_update_fragment_program(struct gl_context *ctx, GLbitfield newState)
    267 {
    268    if (!_swrast_use_fragment_program(ctx))
    269       return;
    270 
    271    _mesa_load_state_parameters(ctx,
    272                                ctx->FragmentProgram._Current->Parameters);
    273 }
    274 
    275 
    276 /**
    277  * See if we can do early diffuse+specular (primary+secondary) color
    278  * add per vertex instead of per-fragment.
    279  */
    280 static void
    281 _swrast_update_specular_vertex_add(struct gl_context *ctx)
    282 {
    283    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    284    GLboolean separateSpecular = ctx->Fog.ColorSumEnabled ||
    285       (ctx->Light.Enabled &&
    286        ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR);
    287 
    288    swrast->SpecularVertexAdd = (separateSpecular
    289                                 && ctx->Texture._MaxEnabledTexImageUnit == -1
    290                                 && !_swrast_use_fragment_program(ctx)
    291                                 && !ctx->ATIFragmentShader._Enabled);
    292 }
    293 
    294 
    295 #define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK |	\
    296                              _NEW_PROGRAM_CONSTANTS |   \
    297 			     _NEW_TEXTURE |		\
    298 			     _NEW_HINT |		\
    299 			     _NEW_POLYGON )
    300 
    301 /* State referenced by _swrast_choose_triangle, _swrast_choose_line.
    302  */
    303 #define _SWRAST_NEW_TRIANGLE (_SWRAST_NEW_DERIVED |		\
    304 			      _NEW_RENDERMODE|			\
    305                               _NEW_POLYGON|			\
    306                               _NEW_DEPTH|			\
    307                               _NEW_STENCIL|			\
    308                               _NEW_COLOR|			\
    309                               _NEW_TEXTURE|			\
    310                               _SWRAST_NEW_RASTERMASK|		\
    311                               _NEW_LIGHT|			\
    312                               _NEW_FOG |			\
    313 			      _MESA_NEW_SEPARATE_SPECULAR)
    314 
    315 #define _SWRAST_NEW_LINE (_SWRAST_NEW_DERIVED |		\
    316 			  _NEW_RENDERMODE|		\
    317                           _NEW_LINE|			\
    318                           _NEW_TEXTURE|			\
    319                           _NEW_LIGHT|			\
    320                           _NEW_FOG|			\
    321                           _NEW_DEPTH |			\
    322                           _MESA_NEW_SEPARATE_SPECULAR)
    323 
    324 #define _SWRAST_NEW_POINT (_SWRAST_NEW_DERIVED |	\
    325 			   _NEW_RENDERMODE |		\
    326 			   _NEW_POINT |			\
    327 			   _NEW_TEXTURE |		\
    328 			   _NEW_LIGHT |			\
    329 			   _NEW_FOG |			\
    330                            _MESA_NEW_SEPARATE_SPECULAR)
    331 
    332 #define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE
    333 
    334 #define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE
    335 
    336 #define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR
    337 
    338 
    339 
    340 /**
    341  * Stub for swrast->Triangle to select a true triangle function
    342  * after a state change.
    343  */
    344 static void
    345 _swrast_validate_triangle( struct gl_context *ctx,
    346 			   const SWvertex *v0,
    347                            const SWvertex *v1,
    348                            const SWvertex *v2 )
    349 {
    350    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    351 
    352    _swrast_validate_derived( ctx );
    353    swrast->choose_triangle( ctx );
    354    assert(swrast->Triangle);
    355 
    356    if (swrast->SpecularVertexAdd) {
    357       /* separate specular color, but no texture */
    358       swrast->SpecTriangle = swrast->Triangle;
    359       swrast->Triangle = _swrast_add_spec_terms_triangle;
    360    }
    361 
    362    swrast->Triangle( ctx, v0, v1, v2 );
    363 }
    364 
    365 /**
    366  * Called via swrast->Line.  Examine current GL state and choose a software
    367  * line routine.  Then call it.
    368  */
    369 static void
    370 _swrast_validate_line( struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1 )
    371 {
    372    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    373 
    374    _swrast_validate_derived( ctx );
    375    swrast->choose_line( ctx );
    376    assert(swrast->Line);
    377 
    378    if (swrast->SpecularVertexAdd) {
    379       swrast->SpecLine = swrast->Line;
    380       swrast->Line = _swrast_add_spec_terms_line;
    381    }
    382 
    383    swrast->Line( ctx, v0, v1 );
    384 }
    385 
    386 /**
    387  * Called via swrast->Point.  Examine current GL state and choose a software
    388  * point routine.  Then call it.
    389  */
    390 static void
    391 _swrast_validate_point( struct gl_context *ctx, const SWvertex *v0 )
    392 {
    393    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    394 
    395    _swrast_validate_derived( ctx );
    396    swrast->choose_point( ctx );
    397 
    398    if (swrast->SpecularVertexAdd) {
    399       swrast->SpecPoint = swrast->Point;
    400       swrast->Point = _swrast_add_spec_terms_point;
    401    }
    402 
    403    swrast->Point( ctx, v0 );
    404 }
    405 
    406 
    407 /**
    408  * Called via swrast->BlendFunc.  Examine GL state to choose a blending
    409  * function, then call it.
    410  */
    411 static void
    412 _swrast_validate_blend_func(struct gl_context *ctx, GLuint n, const GLubyte mask[],
    413                             GLvoid *src, const GLvoid *dst,
    414                             GLenum chanType )
    415 {
    416    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    417 
    418    _swrast_validate_derived( ctx ); /* why is this needed? */
    419    _swrast_choose_blend_func( ctx, chanType );
    420 
    421    swrast->BlendFunc( ctx, n, mask, src, dst, chanType );
    422 }
    423 
    424 static void
    425 _swrast_sleep( struct gl_context *ctx, GLbitfield new_state )
    426 {
    427    (void) ctx; (void) new_state;
    428 }
    429 
    430 
    431 static void
    432 _swrast_invalidate_state( struct gl_context *ctx, GLbitfield new_state )
    433 {
    434    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    435    GLuint i;
    436 
    437    swrast->NewState |= new_state;
    438 
    439    /* After 10 statechanges without any swrast functions being called,
    440     * put the module to sleep.
    441     */
    442    if (++swrast->StateChanges > 10) {
    443       swrast->InvalidateState = _swrast_sleep;
    444       swrast->NewState = ~0;
    445       new_state = ~0;
    446    }
    447 
    448    if (new_state & swrast->InvalidateTriangleMask)
    449       swrast->Triangle = _swrast_validate_triangle;
    450 
    451    if (new_state & swrast->InvalidateLineMask)
    452       swrast->Line = _swrast_validate_line;
    453 
    454    if (new_state & swrast->InvalidatePointMask)
    455       swrast->Point = _swrast_validate_point;
    456 
    457    if (new_state & _SWRAST_NEW_BLEND_FUNC)
    458       swrast->BlendFunc = _swrast_validate_blend_func;
    459 
    460    if (new_state & _SWRAST_NEW_TEXTURE_SAMPLE_FUNC)
    461       for (i = 0 ; i < ARRAY_SIZE(swrast->TextureSample); i++)
    462 	 swrast->TextureSample[i] = NULL;
    463 }
    464 
    465 
    466 void
    467 _swrast_update_texture_samplers(struct gl_context *ctx)
    468 {
    469    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    470    GLuint u;
    471 
    472    if (!swrast)
    473       return; /* pipe hack */
    474 
    475    for (u = 0; u < ARRAY_SIZE(swrast->TextureSample); u++) {
    476       struct gl_texture_object *tObj = ctx->Texture.Unit[u]._Current;
    477       /* Note: If tObj is NULL, the sample function will be a simple
    478        * function that just returns opaque black (0,0,0,1).
    479        */
    480       _mesa_update_fetch_functions(ctx, u);
    481       swrast->TextureSample[u] =
    482          _swrast_choose_texture_sample_func(ctx, tObj,
    483                                             _mesa_get_samplerobj(ctx, u));
    484    }
    485 }
    486 
    487 
    488 /**
    489  * Update swrast->_ActiveAttribs, swrast->_NumActiveAttribs,
    490  * swrast->_ActiveAtttribMask.
    491  */
    492 static void
    493 _swrast_update_active_attribs(struct gl_context *ctx)
    494 {
    495    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    496    GLbitfield64 attribsMask;
    497 
    498    /*
    499     * Compute _ActiveAttribsMask = which fragment attributes are needed.
    500     */
    501    if (_swrast_use_fragment_program(ctx)) {
    502       /* fragment program/shader */
    503       attribsMask = ctx->FragmentProgram._Current->info.inputs_read;
    504       attribsMask &= ~VARYING_BIT_POS; /* WPOS is always handled specially */
    505    }
    506    else if (ctx->ATIFragmentShader._Enabled) {
    507       attribsMask = VARYING_BIT_COL0 | VARYING_BIT_COL1 |
    508                     VARYING_BIT_FOGC | VARYING_BITS_TEX_ANY;
    509    }
    510    else {
    511       /* fixed function */
    512       attribsMask = 0x0;
    513 
    514 #if CHAN_TYPE == GL_FLOAT
    515       attribsMask |= VARYING_BIT_COL0;
    516 #endif
    517 
    518       if (ctx->Fog.ColorSumEnabled ||
    519           (ctx->Light.Enabled &&
    520            ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
    521          attribsMask |= VARYING_BIT_COL1;
    522       }
    523 
    524       if (swrast->_FogEnabled)
    525          attribsMask |= VARYING_BIT_FOGC;
    526 
    527       attribsMask |= (ctx->Texture._EnabledCoordUnits << VARYING_SLOT_TEX0);
    528    }
    529 
    530    swrast->_ActiveAttribMask = attribsMask;
    531 
    532    /* Update _ActiveAttribs[] list */
    533    {
    534       GLuint i, num = 0;
    535       for (i = 0; i < VARYING_SLOT_MAX; i++) {
    536          if (attribsMask & BITFIELD64_BIT(i)) {
    537             swrast->_ActiveAttribs[num++] = i;
    538             /* how should this attribute be interpolated? */
    539             if (i == VARYING_SLOT_COL0 || i == VARYING_SLOT_COL1)
    540                swrast->_InterpMode[i] = ctx->Light.ShadeModel;
    541             else
    542                swrast->_InterpMode[i] = GL_SMOOTH;
    543          }
    544       }
    545       swrast->_NumActiveAttribs = num;
    546    }
    547 }
    548 
    549 
    550 void
    551 _swrast_validate_derived( struct gl_context *ctx )
    552 {
    553    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    554 
    555    if (swrast->NewState) {
    556       if (swrast->NewState & _NEW_POLYGON)
    557 	 _swrast_update_polygon( ctx );
    558 
    559       if (swrast->NewState & (_NEW_HINT | _NEW_PROGRAM))
    560 	 _swrast_update_fog_hint( ctx );
    561 
    562       if (swrast->NewState & _SWRAST_NEW_TEXTURE_ENV_MODE)
    563 	 _swrast_update_texture_env( ctx );
    564 
    565       if (swrast->NewState & (_NEW_FOG | _NEW_PROGRAM))
    566          _swrast_update_fog_state( ctx );
    567 
    568       if (swrast->NewState & (_NEW_PROGRAM_CONSTANTS | _NEW_PROGRAM))
    569 	 _swrast_update_fragment_program( ctx, swrast->NewState );
    570 
    571       if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM)) {
    572          _swrast_update_texture_samplers( ctx );
    573       }
    574 
    575       if (swrast->NewState & (_NEW_COLOR | _NEW_PROGRAM))
    576          _swrast_update_deferred_texture(ctx);
    577 
    578       if (swrast->NewState & _SWRAST_NEW_RASTERMASK)
    579  	 _swrast_update_rasterflags( ctx );
    580 
    581       if (swrast->NewState & (_NEW_DEPTH |
    582                               _NEW_FOG |
    583                               _NEW_LIGHT |
    584                               _NEW_PROGRAM |
    585                               _NEW_TEXTURE))
    586          _swrast_update_active_attribs(ctx);
    587 
    588       if (swrast->NewState & (_NEW_FOG |
    589                               _NEW_PROGRAM |
    590                               _NEW_LIGHT |
    591                               _NEW_TEXTURE))
    592          _swrast_update_specular_vertex_add(ctx);
    593 
    594       swrast->NewState = 0;
    595       swrast->StateChanges = 0;
    596       swrast->InvalidateState = _swrast_invalidate_state;
    597    }
    598 }
    599 
    600 #define SWRAST_DEBUG 0
    601 
    602 /* Public entrypoints:  See also s_bitmap.c, etc.
    603  */
    604 void
    605 _swrast_Quad( struct gl_context *ctx,
    606 	      const SWvertex *v0, const SWvertex *v1,
    607               const SWvertex *v2, const SWvertex *v3 )
    608 {
    609    if (SWRAST_DEBUG) {
    610       _mesa_debug(ctx, "_swrast_Quad\n");
    611       _swrast_print_vertex( ctx, v0 );
    612       _swrast_print_vertex( ctx, v1 );
    613       _swrast_print_vertex( ctx, v2 );
    614       _swrast_print_vertex( ctx, v3 );
    615    }
    616    SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v3 );
    617    SWRAST_CONTEXT(ctx)->Triangle( ctx, v1, v2, v3 );
    618 }
    619 
    620 void
    621 _swrast_Triangle( struct gl_context *ctx, const SWvertex *v0,
    622                   const SWvertex *v1, const SWvertex *v2 )
    623 {
    624    if (SWRAST_DEBUG) {
    625       _mesa_debug(ctx, "_swrast_Triangle\n");
    626       _swrast_print_vertex( ctx, v0 );
    627       _swrast_print_vertex( ctx, v1 );
    628       _swrast_print_vertex( ctx, v2 );
    629    }
    630    SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 );
    631 }
    632 
    633 void
    634 _swrast_Line( struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1 )
    635 {
    636    if (SWRAST_DEBUG) {
    637       _mesa_debug(ctx, "_swrast_Line\n");
    638       _swrast_print_vertex( ctx, v0 );
    639       _swrast_print_vertex( ctx, v1 );
    640    }
    641    SWRAST_CONTEXT(ctx)->Line( ctx, v0, v1 );
    642 }
    643 
    644 void
    645 _swrast_Point( struct gl_context *ctx, const SWvertex *v0 )
    646 {
    647    if (SWRAST_DEBUG) {
    648       _mesa_debug(ctx, "_swrast_Point\n");
    649       _swrast_print_vertex( ctx, v0 );
    650    }
    651    SWRAST_CONTEXT(ctx)->Point( ctx, v0 );
    652 }
    653 
    654 void
    655 _swrast_InvalidateState( struct gl_context *ctx, GLbitfield new_state )
    656 {
    657    if (SWRAST_DEBUG) {
    658       _mesa_debug(ctx, "_swrast_InvalidateState\n");
    659    }
    660    SWRAST_CONTEXT(ctx)->InvalidateState( ctx, new_state );
    661 }
    662 
    663 void
    664 _swrast_ResetLineStipple( struct gl_context *ctx )
    665 {
    666    if (SWRAST_DEBUG) {
    667       _mesa_debug(ctx, "_swrast_ResetLineStipple\n");
    668    }
    669    SWRAST_CONTEXT(ctx)->StippleCounter = 0;
    670 }
    671 
    672 void
    673 _swrast_SetFacing(struct gl_context *ctx, GLuint facing)
    674 {
    675    SWRAST_CONTEXT(ctx)->PointLineFacing = facing;
    676 }
    677 
    678 void
    679 _swrast_allow_vertex_fog( struct gl_context *ctx, GLboolean value )
    680 {
    681    if (SWRAST_DEBUG) {
    682       _mesa_debug(ctx, "_swrast_allow_vertex_fog %d\n", value);
    683    }
    684    SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT );
    685    SWRAST_CONTEXT(ctx)->AllowVertexFog = value;
    686 }
    687 
    688 void
    689 _swrast_allow_pixel_fog( struct gl_context *ctx, GLboolean value )
    690 {
    691    if (SWRAST_DEBUG) {
    692       _mesa_debug(ctx, "_swrast_allow_pixel_fog %d\n", value);
    693    }
    694    SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT );
    695    SWRAST_CONTEXT(ctx)->AllowPixelFog = value;
    696 }
    697 
    698 
    699 /**
    700  * Initialize native program limits by copying the logical limits.
    701  * See comments in init_program_limits() in context.c
    702  */
    703 static void
    704 init_program_native_limits(struct gl_program_constants *prog)
    705 {
    706    prog->MaxNativeInstructions = prog->MaxInstructions;
    707    prog->MaxNativeAluInstructions = prog->MaxAluInstructions;
    708    prog->MaxNativeTexInstructions = prog->MaxTexInstructions;
    709    prog->MaxNativeTexIndirections = prog->MaxTexIndirections;
    710    prog->MaxNativeAttribs = prog->MaxAttribs;
    711    prog->MaxNativeTemps = prog->MaxTemps;
    712    prog->MaxNativeAddressRegs = prog->MaxAddressRegs;
    713    prog->MaxNativeParameters = prog->MaxParameters;
    714 }
    715 
    716 
    717 GLboolean
    718 _swrast_CreateContext( struct gl_context *ctx )
    719 {
    720    GLuint i;
    721    SWcontext *swrast = calloc(1, sizeof(SWcontext));
    722 #ifdef _OPENMP
    723    const GLuint maxThreads = omp_get_max_threads();
    724 #else
    725    const GLuint maxThreads = 1;
    726 #endif
    727 
    728    assert(ctx->Const.MaxViewportWidth <= SWRAST_MAX_WIDTH);
    729    assert(ctx->Const.MaxViewportHeight <= SWRAST_MAX_WIDTH);
    730 
    731    assert(ctx->Const.MaxRenderbufferSize <= SWRAST_MAX_WIDTH);
    732 
    733    /* make sure largest texture image is <= SWRAST_MAX_WIDTH in size */
    734    assert((1 << (ctx->Const.MaxTextureLevels - 1)) <= SWRAST_MAX_WIDTH);
    735    assert((1 << (ctx->Const.MaxCubeTextureLevels - 1)) <= SWRAST_MAX_WIDTH);
    736    assert((1 << (ctx->Const.Max3DTextureLevels - 1)) <= SWRAST_MAX_WIDTH);
    737 
    738    assert(PROG_MAX_WIDTH == SWRAST_MAX_WIDTH);
    739 
    740    if (SWRAST_DEBUG) {
    741       _mesa_debug(ctx, "_swrast_CreateContext\n");
    742    }
    743 
    744    if (!swrast)
    745       return GL_FALSE;
    746 
    747    swrast->NewState = ~0;
    748 
    749    swrast->choose_point = _swrast_choose_point;
    750    swrast->choose_line = _swrast_choose_line;
    751    swrast->choose_triangle = _swrast_choose_triangle;
    752 
    753    swrast->InvalidatePointMask = _SWRAST_NEW_POINT;
    754    swrast->InvalidateLineMask = _SWRAST_NEW_LINE;
    755    swrast->InvalidateTriangleMask = _SWRAST_NEW_TRIANGLE;
    756 
    757    swrast->Point = _swrast_validate_point;
    758    swrast->Line = _swrast_validate_line;
    759    swrast->Triangle = _swrast_validate_triangle;
    760    swrast->InvalidateState = _swrast_sleep;
    761    swrast->BlendFunc = _swrast_validate_blend_func;
    762 
    763    swrast->AllowVertexFog = GL_TRUE;
    764    swrast->AllowPixelFog = GL_TRUE;
    765 
    766    swrast->Driver.SpanRenderStart = _swrast_span_render_start;
    767    swrast->Driver.SpanRenderFinish = _swrast_span_render_finish;
    768 
    769    for (i = 0; i < ARRAY_SIZE(swrast->TextureSample); i++)
    770       swrast->TextureSample[i] = NULL;
    771 
    772    /* SpanArrays is global and shared by all SWspan instances. However, when
    773     * using multiple threads, it is necessary to have one SpanArrays instance
    774     * per thread.
    775     */
    776    swrast->SpanArrays = malloc(maxThreads * sizeof(SWspanarrays));
    777    if (!swrast->SpanArrays) {
    778       free(swrast);
    779       return GL_FALSE;
    780    }
    781    for(i = 0; i < maxThreads; i++) {
    782       swrast->SpanArrays[i].ChanType = CHAN_TYPE;
    783 #if CHAN_TYPE == GL_UNSIGNED_BYTE
    784       swrast->SpanArrays[i].rgba = swrast->SpanArrays[i].rgba8;
    785 #elif CHAN_TYPE == GL_UNSIGNED_SHORT
    786       swrast->SpanArrays[i].rgba = swrast->SpanArrays[i].rgba16;
    787 #else
    788       swrast->SpanArrays[i].rgba = swrast->SpanArrays[i].attribs[VARYING_SLOT_COL0];
    789 #endif
    790    }
    791 
    792    /* init point span buffer */
    793    swrast->PointSpan.primitive = GL_POINT;
    794    swrast->PointSpan.end = 0;
    795    swrast->PointSpan.facing = 0;
    796    swrast->PointSpan.array = swrast->SpanArrays;
    797 
    798    init_program_native_limits(&ctx->Const.Program[MESA_SHADER_VERTEX]);
    799    init_program_native_limits(&ctx->Const.Program[MESA_SHADER_GEOMETRY]);
    800    init_program_native_limits(&ctx->Const.Program[MESA_SHADER_FRAGMENT]);
    801 
    802    ctx->swrast_context = swrast;
    803 
    804    swrast->stencil_temp.buf1 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte));
    805    swrast->stencil_temp.buf2 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte));
    806    swrast->stencil_temp.buf3 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte));
    807    swrast->stencil_temp.buf4 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte));
    808 
    809    if (!swrast->stencil_temp.buf1 ||
    810        !swrast->stencil_temp.buf2 ||
    811        !swrast->stencil_temp.buf3 ||
    812        !swrast->stencil_temp.buf4) {
    813       _swrast_DestroyContext(ctx);
    814       return GL_FALSE;
    815    }
    816 
    817    return GL_TRUE;
    818 }
    819 
    820 void
    821 _swrast_DestroyContext( struct gl_context *ctx )
    822 {
    823    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    824 
    825    if (SWRAST_DEBUG) {
    826       _mesa_debug(ctx, "_swrast_DestroyContext\n");
    827    }
    828 
    829    free( swrast->SpanArrays );
    830    free( swrast->ZoomedArrays );
    831    free( swrast->TexelBuffer );
    832 
    833    free(swrast->stencil_temp.buf1);
    834    free(swrast->stencil_temp.buf2);
    835    free(swrast->stencil_temp.buf3);
    836    free(swrast->stencil_temp.buf4);
    837 
    838    free( swrast );
    839 
    840    ctx->swrast_context = 0;
    841 }
    842 
    843 
    844 struct swrast_device_driver *
    845 _swrast_GetDeviceDriverReference( struct gl_context *ctx )
    846 {
    847    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    848    return &swrast->Driver;
    849 }
    850 
    851 void
    852 _swrast_flush( struct gl_context *ctx )
    853 {
    854    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    855    /* flush any pending fragments from rendering points */
    856    if (swrast->PointSpan.end > 0) {
    857       _swrast_write_rgba_span(ctx, &(swrast->PointSpan));
    858       swrast->PointSpan.end = 0;
    859    }
    860 }
    861 
    862 void
    863 _swrast_render_primitive( struct gl_context *ctx, GLenum prim )
    864 {
    865    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    866    if (swrast->Primitive == GL_POINTS && prim != GL_POINTS) {
    867       _swrast_flush(ctx);
    868    }
    869    swrast->Primitive = prim;
    870 }
    871 
    872 
    873 /** called via swrast->Driver.SpanRenderStart() */
    874 void
    875 _swrast_span_render_start(struct gl_context *ctx)
    876 {
    877    _swrast_map_textures(ctx);
    878    _swrast_map_renderbuffers(ctx);
    879 }
    880 
    881 
    882 /** called via swrast->Driver.SpanRenderFinish() */
    883 void
    884 _swrast_span_render_finish(struct gl_context *ctx)
    885 {
    886    _swrast_unmap_textures(ctx);
    887    _swrast_unmap_renderbuffers(ctx);
    888 }
    889 
    890 
    891 void
    892 _swrast_render_start( struct gl_context *ctx )
    893 {
    894    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    895    if (swrast->Driver.SpanRenderStart)
    896       swrast->Driver.SpanRenderStart( ctx );
    897    swrast->PointSpan.end = 0;
    898 }
    899 
    900 void
    901 _swrast_render_finish( struct gl_context *ctx )
    902 {
    903    SWcontext *swrast = SWRAST_CONTEXT(ctx);
    904    struct gl_query_object *query = ctx->Query.CurrentOcclusionObject;
    905 
    906    _swrast_flush(ctx);
    907 
    908    if (swrast->Driver.SpanRenderFinish)
    909       swrast->Driver.SpanRenderFinish( ctx );
    910 
    911    if (query && (query->Target == GL_ANY_SAMPLES_PASSED ||
    912                  query->Target == GL_ANY_SAMPLES_PASSED_CONSERVATIVE))
    913       query->Result = !!query->Result;
    914 }
    915 
    916 
    917 #define SWRAST_DEBUG_VERTICES 0
    918 
    919 void
    920 _swrast_print_vertex( struct gl_context *ctx, const SWvertex *v )
    921 {
    922    GLuint i;
    923 
    924    if (SWRAST_DEBUG_VERTICES) {
    925       _mesa_debug(ctx, "win %f %f %f %f\n",
    926                   v->attrib[VARYING_SLOT_POS][0],
    927                   v->attrib[VARYING_SLOT_POS][1],
    928                   v->attrib[VARYING_SLOT_POS][2],
    929                   v->attrib[VARYING_SLOT_POS][3]);
    930 
    931       for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
    932 	 if (ctx->Texture.Unit[i]._Current)
    933 	    _mesa_debug(ctx, "texcoord[%d] %f %f %f %f\n", i,
    934                         v->attrib[VARYING_SLOT_TEX0 + i][0],
    935                         v->attrib[VARYING_SLOT_TEX0 + i][1],
    936                         v->attrib[VARYING_SLOT_TEX0 + i][2],
    937                         v->attrib[VARYING_SLOT_TEX0 + i][3]);
    938 
    939 #if CHAN_TYPE == GL_FLOAT
    940       _mesa_debug(ctx, "color %f %f %f %f\n",
    941                   v->color[0], v->color[1], v->color[2], v->color[3]);
    942 #else
    943       _mesa_debug(ctx, "color %d %d %d %d\n",
    944                   v->color[0], v->color[1], v->color[2], v->color[3]);
    945 #endif
    946       _mesa_debug(ctx, "spec %g %g %g %g\n",
    947                   v->attrib[VARYING_SLOT_COL1][0],
    948                   v->attrib[VARYING_SLOT_COL1][1],
    949                   v->attrib[VARYING_SLOT_COL1][2],
    950                   v->attrib[VARYING_SLOT_COL1][3]);
    951       _mesa_debug(ctx, "fog %f\n", v->attrib[VARYING_SLOT_FOGC][0]);
    952       _mesa_debug(ctx, "index %f\n", v->attrib[VARYING_SLOT_CI][0]);
    953       _mesa_debug(ctx, "pointsize %f\n", v->pointSize);
    954       _mesa_debug(ctx, "\n");
    955    }
    956 }
    957