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