Home | History | Annotate | Download | only in tnl
      1 /*
      2  * Mesa 3-D graphics library
      3  * Version:  7.2
      4  *
      5  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the "Software"),
      9  * to deal in the Software without restriction, including without limitation
     10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     11  * and/or sell copies of the Software, and to permit persons to whom the
     12  * Software is furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included
     15  * in all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     21  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors:
     25  *    Keith Whitwell <keith (at) tungstengraphics.com>
     26  */
     27 
     28 
     29 #include "main/glheader.h"
     30 #include "main/imports.h"
     31 #include "main/context.h"
     32 #include "main/macros.h"
     33 #include "main/mtypes.h"
     34 #include "main/light.h"
     35 #include "math/m_translate.h"
     36 #include "math/m_xform.h"
     37 #include "main/state.h"
     38 
     39 #include "tnl.h"
     40 #include "t_context.h"
     41 #include "t_pipeline.h"
     42 
     43 #include "vbo/vbo.h"
     44 
     45 GLboolean
     46 _tnl_CreateContext( struct gl_context *ctx )
     47 {
     48    TNLcontext *tnl;
     49    GLuint i;
     50 
     51    /* Create the TNLcontext structure
     52     */
     53    ctx->swtnl_context = tnl = (TNLcontext *) CALLOC( sizeof(TNLcontext) );
     54 
     55    if (!tnl) {
     56       return GL_FALSE;
     57    }
     58 
     59    /* Initialize the VB.
     60     */
     61    tnl->vb.Size = ctx->Const.MaxArrayLockSize + MAX_CLIPPED_VERTICES;
     62 
     63 
     64    /* Initialize tnl state.
     65     */
     66    if (ctx->VertexProgram._MaintainTnlProgram) {
     67       _tnl_install_pipeline( ctx, _tnl_vp_pipeline );
     68    } else {
     69       _tnl_install_pipeline( ctx, _tnl_default_pipeline );
     70    }
     71 
     72    tnl->NeedNdcCoords = GL_TRUE;
     73    tnl->AllowVertexFog = GL_TRUE;
     74    tnl->AllowPixelFog = GL_TRUE;
     75 
     76    /* Set a few default values in the driver struct.
     77     */
     78    tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
     79    tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
     80    tnl->Driver.NotifyMaterialChange = _tnl_validate_shine_tables;
     81 
     82    tnl->nr_blocks = 0;
     83 
     84    /* Lighting miscellaneous */
     85    tnl->_ShineTabList = MALLOC_STRUCT( tnl_shine_tab );
     86    make_empty_list( tnl->_ShineTabList );
     87    /* Allocate 10 (arbitrary) shininess lookup tables */
     88    for (i = 0 ; i < 10 ; i++) {
     89       struct tnl_shine_tab *s = MALLOC_STRUCT( tnl_shine_tab );
     90       s->shininess = -1;
     91       s->refcount = 0;
     92       insert_at_tail( tnl->_ShineTabList, s );
     93    }
     94 
     95    /* plug in the VBO drawing function */
     96    vbo_set_draw_func(ctx, _tnl_vbo_draw_prims);
     97 
     98    _math_init_transformation();
     99    _math_init_translate();
    100 
    101    return GL_TRUE;
    102 }
    103 
    104 
    105 void
    106 _tnl_DestroyContext( struct gl_context *ctx )
    107 {
    108    struct tnl_shine_tab *s, *tmps;
    109    TNLcontext *tnl = TNL_CONTEXT(ctx);
    110 
    111    /* Free lighting shininess exponentiation table */
    112    foreach_s( s, tmps, tnl->_ShineTabList ) {
    113       free( s );
    114    }
    115    free( tnl->_ShineTabList );
    116 
    117    _tnl_destroy_pipeline( ctx );
    118 
    119    FREE(tnl);
    120    ctx->swtnl_context = NULL;
    121 }
    122 
    123 
    124 void
    125 _tnl_InvalidateState( struct gl_context *ctx, GLuint new_state )
    126 {
    127    TNLcontext *tnl = TNL_CONTEXT(ctx);
    128    const struct gl_vertex_program *vp = ctx->VertexProgram._Current;
    129    const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
    130    GLuint i;
    131 
    132    if (new_state & (_NEW_HINT | _NEW_PROGRAM)) {
    133       ASSERT(tnl->AllowVertexFog || tnl->AllowPixelFog);
    134       tnl->_DoVertexFog = ((tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST))
    135          || !tnl->AllowPixelFog) && !fp;
    136    }
    137 
    138    tnl->pipeline.new_state |= new_state;
    139 
    140    /* Calculate tnl->render_inputs.  This bitmask indicates which vertex
    141     * attributes need to be emitted to the rasterizer.
    142     */
    143    tnl->render_inputs_bitset = BITFIELD64_BIT(_TNL_ATTRIB_POS);
    144 
    145    if (!fp || (fp->Base.InputsRead & FRAG_BIT_COL0)) {
    146      tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_COLOR0);
    147    }
    148 
    149    if (_mesa_need_secondary_color(ctx))
    150      tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_COLOR1);
    151 
    152    for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
    153      if (ctx->Texture._EnabledCoordUnits & (1 << i) ||
    154 	 (fp && fp->Base.InputsRead & FRAG_BIT_TEX(i))) {
    155        tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_TEX(i));
    156      }
    157    }
    158 
    159    if (ctx->Fog.Enabled
    160        || (fp != NULL && (fp->Base.InputsRead & FRAG_BIT_FOGC) != 0)) {
    161       /* Either fixed-function fog or a fragment program needs fog coord.
    162        */
    163       tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_FOG);
    164    }
    165 
    166    if (ctx->Polygon.FrontMode != GL_FILL ||
    167        ctx->Polygon.BackMode != GL_FILL)
    168       tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_EDGEFLAG);
    169 
    170    if (ctx->RenderMode == GL_FEEDBACK)
    171       tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_TEX0);
    172 
    173    if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled)
    174       tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_POINTSIZE);
    175 
    176    /* check for varying vars which are written by the vertex program */
    177    if (vp) {
    178       GLuint i;
    179       for (i = 0; i < MAX_VARYING; i++) {
    180 	 if (vp->Base.OutputsWritten & BITFIELD64_BIT(VERT_RESULT_VAR0 + i)) {
    181             tnl->render_inputs_bitset |= BITFIELD64_BIT(_TNL_ATTRIB_GENERIC(i));
    182          }
    183       }
    184    }
    185 }
    186 
    187 
    188 void
    189 _tnl_wakeup( struct gl_context *ctx )
    190 {
    191    /* Assume we haven't been getting state updates either:
    192     */
    193    _tnl_InvalidateState( ctx, ~0 );
    194 
    195 #if 0
    196    if (ctx->Light.ColorMaterialEnabled) {
    197       _mesa_update_color_material( ctx,
    198 				   ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
    199    }
    200 #endif
    201 }
    202 
    203 
    204 
    205 
    206 /**
    207  * Drivers call this function to tell the TCL module whether or not
    208  * it wants Normalized Device Coords (NDC) computed.  I.e. whether
    209  * we should "Divide-by-W".  Software renders will want that.
    210  */
    211 void
    212 _tnl_need_projected_coords( struct gl_context *ctx, GLboolean mode )
    213 {
    214    TNLcontext *tnl = TNL_CONTEXT(ctx);
    215    tnl->NeedNdcCoords = mode;
    216 }
    217 
    218 void
    219 _tnl_allow_vertex_fog( struct gl_context *ctx, GLboolean value )
    220 {
    221    TNLcontext *tnl = TNL_CONTEXT(ctx);
    222    tnl->AllowVertexFog = value;
    223    tnl->_DoVertexFog = ((tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST))
    224       || !tnl->AllowPixelFog) && !ctx->FragmentProgram._Current;
    225 
    226 }
    227 
    228 void
    229 _tnl_allow_pixel_fog( struct gl_context *ctx, GLboolean value )
    230 {
    231    TNLcontext *tnl = TNL_CONTEXT(ctx);
    232    tnl->AllowPixelFog = value;
    233    tnl->_DoVertexFog = ((tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST))
    234       || !tnl->AllowPixelFog) && !ctx->FragmentProgram._Current;
    235 }
    236 
    237