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