17117f1b4Smrg/* 27117f1b4Smrg * Mesa 3-D graphics library 37117f1b4Smrg * 4c1f859d4Smrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 57117f1b4Smrg * 67117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a 77117f1b4Smrg * copy of this software and associated documentation files (the "Software"), 87117f1b4Smrg * to deal in the Software without restriction, including without limitation 97117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 107117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the 117117f1b4Smrg * Software is furnished to do so, subject to the following conditions: 127117f1b4Smrg * 137117f1b4Smrg * The above copyright notice and this permission notice shall be included 147117f1b4Smrg * in all copies or substantial portions of the Software. 157117f1b4Smrg * 167117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 177117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 187117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE. 237117f1b4Smrg * 247117f1b4Smrg * Authors: 25af69d88dSmrg * Keith Whitwell <keithw@vmware.com> Brian Paul 267117f1b4Smrg */ 277117f1b4Smrg 2801e04c3fSmrg#include "main/errors.h" 297ec681f3Smrg 30c1f859d4Smrg#include "main/bufferobj.h" 31c1f859d4Smrg#include "main/mtypes.h" 32af69d88dSmrg#include "main/samplerobj.h" 3301e04c3fSmrg#include "main/state.h" 3401e04c3fSmrg#include "main/stencil.h" 35c1f859d4Smrg#include "main/teximage.h" 363464ebd5Sriastradh#include "program/prog_parameter.h" 373464ebd5Sriastradh#include "program/prog_statevars.h" 387117f1b4Smrg#include "swrast.h" 397117f1b4Smrg#include "s_blend.h" 407117f1b4Smrg#include "s_context.h" 417117f1b4Smrg#include "s_lines.h" 427117f1b4Smrg#include "s_points.h" 437117f1b4Smrg#include "s_span.h" 44af69d88dSmrg#include "s_texfetch.h" 457117f1b4Smrg#include "s_triangle.h" 467117f1b4Smrg#include "s_texfilter.h" 477117f1b4Smrg 487117f1b4Smrg 497117f1b4Smrg/** 507117f1b4Smrg * Recompute the value of swrast->_RasterMask, etc. according to 517117f1b4Smrg * the current context. The _RasterMask field can be easily tested by 527117f1b4Smrg * drivers to determine certain basic GL state (does the primitive need 537117f1b4Smrg * stenciling, logic-op, fog, etc?). 547117f1b4Smrg */ 557117f1b4Smrgstatic void 563464ebd5Sriastradh_swrast_update_rasterflags( struct gl_context *ctx ) 577117f1b4Smrg{ 587117f1b4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 597117f1b4Smrg GLbitfield rasterMask = 0; 60cdc920a0Smrg GLuint i; 617117f1b4Smrg 627117f1b4Smrg if (ctx->Color.AlphaEnabled) rasterMask |= ALPHATEST_BIT; 637117f1b4Smrg if (ctx->Color.BlendEnabled) rasterMask |= BLEND_BIT; 647117f1b4Smrg if (ctx->Depth.Test) rasterMask |= DEPTH_BIT; 657117f1b4Smrg if (swrast->_FogEnabled) rasterMask |= FOG_BIT; 66af69d88dSmrg if (ctx->Scissor.EnableFlags) rasterMask |= CLIP_BIT; 6701e04c3fSmrg if (_mesa_stencil_is_enabled(ctx)) rasterMask |= STENCIL_BIT; 68cdc920a0Smrg for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { 6901e04c3fSmrg if (GET_COLORMASK(ctx->Color.ColorMask, i) != 0xf) { 70cdc920a0Smrg rasterMask |= MASKING_BIT; 71cdc920a0Smrg break; 72cdc920a0Smrg } 737117f1b4Smrg } 74af69d88dSmrg if (ctx->Color.ColorLogicOpEnabled) rasterMask |= LOGIC_OP_BIT; 75af69d88dSmrg if (ctx->Texture._MaxEnabledTexImageUnit >= 0) rasterMask |= TEXTURE_BIT; 76af69d88dSmrg if ( ctx->ViewportArray[0].X < 0 77af69d88dSmrg || ctx->ViewportArray[0].X + ctx->ViewportArray[0].Width > (GLfloat) ctx->DrawBuffer->Width 78af69d88dSmrg || ctx->ViewportArray[0].Y < 0 79af69d88dSmrg || ctx->ViewportArray[0].Y + ctx->ViewportArray[0].Height > (GLfloat) ctx->DrawBuffer->Height) { 807117f1b4Smrg rasterMask |= CLIP_BIT; 817117f1b4Smrg } 827117f1b4Smrg 837117f1b4Smrg if (ctx->Query.CurrentOcclusionObject) 847117f1b4Smrg rasterMask |= OCCLUSION_BIT; 857117f1b4Smrg 867117f1b4Smrg 877117f1b4Smrg /* If we're not drawing to exactly one color buffer set the 887117f1b4Smrg * MULTI_DRAW_BIT flag. Also set it if we're drawing to no 897117f1b4Smrg * buffers or the RGBA or CI mask disables all writes. 907117f1b4Smrg */ 91c1f859d4Smrg if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) { 927117f1b4Smrg /* more than one color buffer designated for writing (or zero buffers) */ 937117f1b4Smrg rasterMask |= MULTI_DRAW_BIT; 947117f1b4Smrg } 95cdc920a0Smrg 96cdc920a0Smrg for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { 9701e04c3fSmrg if (GET_COLORMASK(ctx->Color.ColorMask, i) == 0) { 98cdc920a0Smrg rasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */ 99cdc920a0Smrg break; 100cdc920a0Smrg } 1017117f1b4Smrg } 1027117f1b4Smrg 103cdc920a0Smrg 104af69d88dSmrg if (_swrast_use_fragment_program(ctx)) { 1057117f1b4Smrg rasterMask |= FRAGPROG_BIT; 1067117f1b4Smrg } 1077117f1b4Smrg 10801e04c3fSmrg if (_mesa_ati_fragment_shader_enabled(ctx)) { 1097117f1b4Smrg rasterMask |= ATIFRAGSHADER_BIT; 1107117f1b4Smrg } 1117117f1b4Smrg 1127117f1b4Smrg#if CHAN_TYPE == GL_FLOAT 1137117f1b4Smrg if (ctx->Color.ClampFragmentColor == GL_TRUE) { 1147117f1b4Smrg rasterMask |= CLAMPING_BIT; 1157117f1b4Smrg } 1167117f1b4Smrg#endif 1177117f1b4Smrg 1187117f1b4Smrg SWRAST_CONTEXT(ctx)->_RasterMask = rasterMask; 1197117f1b4Smrg} 1207117f1b4Smrg 1217117f1b4Smrg 1227117f1b4Smrg/** 123c1f859d4Smrg * Examine polygon cull state to compute the _BackfaceCullSign field. 1247117f1b4Smrg * _BackfaceCullSign will be 0 if no culling, -1 if culling back-faces, 1257117f1b4Smrg * and 1 if culling front-faces. The Polygon FrontFace state also 1267117f1b4Smrg * factors in. 1277117f1b4Smrg */ 1287117f1b4Smrgstatic void 1293464ebd5Sriastradh_swrast_update_polygon( struct gl_context *ctx ) 1307117f1b4Smrg{ 1317117f1b4Smrg GLfloat backface_sign; 1327117f1b4Smrg 1337117f1b4Smrg if (ctx->Polygon.CullFlag) { 1347117f1b4Smrg switch (ctx->Polygon.CullFaceMode) { 1357117f1b4Smrg case GL_BACK: 136cdc920a0Smrg backface_sign = -1.0F; 1377117f1b4Smrg break; 1387117f1b4Smrg case GL_FRONT: 139cdc920a0Smrg backface_sign = 1.0F; 1407117f1b4Smrg break; 1417117f1b4Smrg case GL_FRONT_AND_BACK: 1427ec681f3Smrg FALLTHROUGH; 1437117f1b4Smrg default: 144cdc920a0Smrg backface_sign = 0.0F; 1457117f1b4Smrg } 1467117f1b4Smrg } 1477117f1b4Smrg else { 148cdc920a0Smrg backface_sign = 0.0F; 1497117f1b4Smrg } 1507117f1b4Smrg 1517117f1b4Smrg SWRAST_CONTEXT(ctx)->_BackfaceCullSign = backface_sign; 1527117f1b4Smrg 1537117f1b4Smrg /* This is for front/back-face determination, but not for culling */ 1547117f1b4Smrg SWRAST_CONTEXT(ctx)->_BackfaceSign 155cdc920a0Smrg = (ctx->Polygon.FrontFace == GL_CW) ? -1.0F : 1.0F; 1567117f1b4Smrg} 1577117f1b4Smrg 1587117f1b4Smrg 1597117f1b4Smrg 1607117f1b4Smrg/** 1617117f1b4Smrg * Update the _PreferPixelFog field to indicate if we need to compute 1627117f1b4Smrg * fog blend factors (from the fog coords) per-fragment. 1637117f1b4Smrg */ 1647117f1b4Smrgstatic void 1653464ebd5Sriastradh_swrast_update_fog_hint( struct gl_context *ctx ) 1667117f1b4Smrg{ 1677117f1b4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 1687117f1b4Smrg swrast->_PreferPixelFog = (!swrast->AllowVertexFog || 169af69d88dSmrg _swrast_use_fragment_program(ctx) || 1707117f1b4Smrg (ctx->Hint.Fog == GL_NICEST && 1717117f1b4Smrg swrast->AllowPixelFog)); 1727117f1b4Smrg} 1737117f1b4Smrg 1747117f1b4Smrg 1757117f1b4Smrg 1767117f1b4Smrg/** 1774a49301eSmrg * Update the swrast->_TextureCombinePrimary flag. 1787117f1b4Smrg */ 1797117f1b4Smrgstatic void 1803464ebd5Sriastradh_swrast_update_texture_env( struct gl_context *ctx ) 1817117f1b4Smrg{ 1827117f1b4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 1837117f1b4Smrg GLuint i; 1844a49301eSmrg 1854a49301eSmrg swrast->_TextureCombinePrimary = GL_FALSE; 1864a49301eSmrg 1877117f1b4Smrg for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 1884a49301eSmrg const struct gl_tex_env_combine_state *combine = 18901e04c3fSmrg ctx->Texture.FixedFuncUnit[i]._CurrentCombine; 1904a49301eSmrg GLuint term; 1914a49301eSmrg for (term = 0; term < combine->_NumArgsRGB; term++) { 1924a49301eSmrg if (combine->SourceRGB[term] == GL_PRIMARY_COLOR) { 1934a49301eSmrg swrast->_TextureCombinePrimary = GL_TRUE; 1944a49301eSmrg return; 1954a49301eSmrg } 1964a49301eSmrg if (combine->SourceA[term] == GL_PRIMARY_COLOR) { 1974a49301eSmrg swrast->_TextureCombinePrimary = GL_TRUE; 1984a49301eSmrg return; 1994a49301eSmrg } 2007117f1b4Smrg } 2017117f1b4Smrg } 2027117f1b4Smrg} 2037117f1b4Smrg 2047117f1b4Smrg 205c1f859d4Smrg/** 206c1f859d4Smrg * Determine if we can defer texturing/shading until after Z/stencil 207c1f859d4Smrg * testing. This potentially allows us to skip texturing/shading for 208c1f859d4Smrg * lots of fragments. 209c1f859d4Smrg */ 210c1f859d4Smrgstatic void 2113464ebd5Sriastradh_swrast_update_deferred_texture(struct gl_context *ctx) 212c1f859d4Smrg{ 213c1f859d4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 214c1f859d4Smrg if (ctx->Color.AlphaEnabled) { 215c1f859d4Smrg /* alpha test depends on post-texture/shader colors */ 216c1f859d4Smrg swrast->_DeferredTexture = GL_FALSE; 217c1f859d4Smrg } 218c1f859d4Smrg else { 219af69d88dSmrg GLboolean use_fprog = _swrast_use_fragment_program(ctx); 22001e04c3fSmrg const struct gl_program *fprog = ctx->FragmentProgram._Current; 22101e04c3fSmrg if (use_fprog && 22201e04c3fSmrg (fprog->info.outputs_written & (1 << FRAG_RESULT_DEPTH))) { 223c1f859d4Smrg /* Z comes from fragment program/shader */ 224c1f859d4Smrg swrast->_DeferredTexture = GL_FALSE; 225c1f859d4Smrg } 22601e04c3fSmrg else if (use_fprog && fprog->info.fs.uses_discard) { 2274a49301eSmrg swrast->_DeferredTexture = GL_FALSE; 2284a49301eSmrg } 229c1f859d4Smrg else if (ctx->Query.CurrentOcclusionObject) { 230c1f859d4Smrg /* occlusion query depends on shader discard/kill results */ 231c1f859d4Smrg swrast->_DeferredTexture = GL_FALSE; 232c1f859d4Smrg } 233c1f859d4Smrg else { 234c1f859d4Smrg swrast->_DeferredTexture = GL_TRUE; 235c1f859d4Smrg } 236c1f859d4Smrg } 237c1f859d4Smrg} 238c1f859d4Smrg 239c1f859d4Smrg 2407117f1b4Smrg/** 2417117f1b4Smrg * Update swrast->_FogColor and swrast->_FogEnable values. 2427117f1b4Smrg */ 2437117f1b4Smrgstatic void 2443464ebd5Sriastradh_swrast_update_fog_state( struct gl_context *ctx ) 2457117f1b4Smrg{ 2467117f1b4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 24701e04c3fSmrg const struct gl_program *fp = ctx->FragmentProgram._Current; 2487117f1b4Smrg 24901e04c3fSmrg assert(fp == NULL || fp->Target == GL_FRAGMENT_PROGRAM_ARB); 25001e04c3fSmrg (void) fp; /* silence unused var warning */ 2513464ebd5Sriastradh 2527117f1b4Smrg /* determine if fog is needed, and if so, which fog mode */ 253af69d88dSmrg swrast->_FogEnabled = (!_swrast_use_fragment_program(ctx) && 254af69d88dSmrg ctx->Fog.Enabled); 2557117f1b4Smrg} 2567117f1b4Smrg 2577117f1b4Smrg 2587117f1b4Smrg/** 2597117f1b4Smrg * Update state for running fragment programs. Basically, load the 2607117f1b4Smrg * program parameters with current state values. 2617117f1b4Smrg */ 2627117f1b4Smrgstatic void 2633464ebd5Sriastradh_swrast_update_fragment_program(struct gl_context *ctx, GLbitfield newState) 2647117f1b4Smrg{ 265af69d88dSmrg if (!_swrast_use_fragment_program(ctx)) 266af69d88dSmrg return; 267af69d88dSmrg 268af69d88dSmrg _mesa_load_state_parameters(ctx, 26901e04c3fSmrg ctx->FragmentProgram._Current->Parameters); 2707117f1b4Smrg} 2717117f1b4Smrg 2727117f1b4Smrg 2734a49301eSmrg/** 2744a49301eSmrg * See if we can do early diffuse+specular (primary+secondary) color 2754a49301eSmrg * add per vertex instead of per-fragment. 2764a49301eSmrg */ 2774a49301eSmrgstatic void 2783464ebd5Sriastradh_swrast_update_specular_vertex_add(struct gl_context *ctx) 2794a49301eSmrg{ 2804a49301eSmrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 2814a49301eSmrg GLboolean separateSpecular = ctx->Fog.ColorSumEnabled || 2824a49301eSmrg (ctx->Light.Enabled && 2834a49301eSmrg ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR); 2844a49301eSmrg 2854a49301eSmrg swrast->SpecularVertexAdd = (separateSpecular 286af69d88dSmrg && ctx->Texture._MaxEnabledTexImageUnit == -1 287af69d88dSmrg && !_swrast_use_fragment_program(ctx) 28801e04c3fSmrg && !_mesa_ati_fragment_shader_enabled(ctx)); 2894a49301eSmrg} 2904a49301eSmrg 2917117f1b4Smrg 2927117f1b4Smrg#define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK | \ 2934a49301eSmrg _NEW_PROGRAM_CONSTANTS | \ 2947117f1b4Smrg _NEW_TEXTURE | \ 2957117f1b4Smrg _NEW_HINT | \ 2967117f1b4Smrg _NEW_POLYGON ) 2977117f1b4Smrg 2987117f1b4Smrg/* State referenced by _swrast_choose_triangle, _swrast_choose_line. 2997117f1b4Smrg */ 3007117f1b4Smrg#define _SWRAST_NEW_TRIANGLE (_SWRAST_NEW_DERIVED | \ 3017117f1b4Smrg _NEW_RENDERMODE| \ 3027117f1b4Smrg _NEW_POLYGON| \ 3037117f1b4Smrg _NEW_DEPTH| \ 3047117f1b4Smrg _NEW_STENCIL| \ 3057117f1b4Smrg _NEW_COLOR| \ 3067117f1b4Smrg _NEW_TEXTURE| \ 3077117f1b4Smrg _SWRAST_NEW_RASTERMASK| \ 3087117f1b4Smrg _NEW_LIGHT| \ 3097117f1b4Smrg _NEW_FOG | \ 310af69d88dSmrg _MESA_NEW_SEPARATE_SPECULAR) 3117117f1b4Smrg 3127117f1b4Smrg#define _SWRAST_NEW_LINE (_SWRAST_NEW_DERIVED | \ 3137117f1b4Smrg _NEW_RENDERMODE| \ 3147117f1b4Smrg _NEW_LINE| \ 3157117f1b4Smrg _NEW_TEXTURE| \ 3167117f1b4Smrg _NEW_LIGHT| \ 3177117f1b4Smrg _NEW_FOG| \ 3187117f1b4Smrg _NEW_DEPTH | \ 319af69d88dSmrg _MESA_NEW_SEPARATE_SPECULAR) 3207117f1b4Smrg 3217117f1b4Smrg#define _SWRAST_NEW_POINT (_SWRAST_NEW_DERIVED | \ 3227117f1b4Smrg _NEW_RENDERMODE | \ 3237117f1b4Smrg _NEW_POINT | \ 3247117f1b4Smrg _NEW_TEXTURE | \ 3257117f1b4Smrg _NEW_LIGHT | \ 3267117f1b4Smrg _NEW_FOG | \ 327af69d88dSmrg _MESA_NEW_SEPARATE_SPECULAR) 3287117f1b4Smrg 3297117f1b4Smrg#define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE 3307117f1b4Smrg 3317117f1b4Smrg#define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE 3327117f1b4Smrg 3337117f1b4Smrg#define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR 3347117f1b4Smrg 3357117f1b4Smrg 3367117f1b4Smrg 3377117f1b4Smrg/** 3387117f1b4Smrg * Stub for swrast->Triangle to select a true triangle function 3397117f1b4Smrg * after a state change. 3407117f1b4Smrg */ 3417117f1b4Smrgstatic void 3423464ebd5Sriastradh_swrast_validate_triangle( struct gl_context *ctx, 3437117f1b4Smrg const SWvertex *v0, 3447117f1b4Smrg const SWvertex *v1, 3457117f1b4Smrg const SWvertex *v2 ) 3467117f1b4Smrg{ 3477117f1b4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 3487117f1b4Smrg 3497117f1b4Smrg _swrast_validate_derived( ctx ); 3507117f1b4Smrg swrast->choose_triangle( ctx ); 35101e04c3fSmrg assert(swrast->Triangle); 3527117f1b4Smrg 3534a49301eSmrg if (swrast->SpecularVertexAdd) { 3547117f1b4Smrg /* separate specular color, but no texture */ 3557117f1b4Smrg swrast->SpecTriangle = swrast->Triangle; 3567117f1b4Smrg swrast->Triangle = _swrast_add_spec_terms_triangle; 3577117f1b4Smrg } 3587117f1b4Smrg 3597117f1b4Smrg swrast->Triangle( ctx, v0, v1, v2 ); 3607117f1b4Smrg} 3617117f1b4Smrg 3627117f1b4Smrg/** 3637117f1b4Smrg * Called via swrast->Line. Examine current GL state and choose a software 3647117f1b4Smrg * line routine. Then call it. 3657117f1b4Smrg */ 3667117f1b4Smrgstatic void 3673464ebd5Sriastradh_swrast_validate_line( struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1 ) 3687117f1b4Smrg{ 3697117f1b4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 3707117f1b4Smrg 3717117f1b4Smrg _swrast_validate_derived( ctx ); 3727117f1b4Smrg swrast->choose_line( ctx ); 37301e04c3fSmrg assert(swrast->Line); 3747117f1b4Smrg 3754a49301eSmrg if (swrast->SpecularVertexAdd) { 3767117f1b4Smrg swrast->SpecLine = swrast->Line; 3777117f1b4Smrg swrast->Line = _swrast_add_spec_terms_line; 3787117f1b4Smrg } 3797117f1b4Smrg 3807117f1b4Smrg swrast->Line( ctx, v0, v1 ); 3817117f1b4Smrg} 3827117f1b4Smrg 3837117f1b4Smrg/** 3847117f1b4Smrg * Called via swrast->Point. Examine current GL state and choose a software 3857117f1b4Smrg * point routine. Then call it. 3867117f1b4Smrg */ 3877117f1b4Smrgstatic void 3883464ebd5Sriastradh_swrast_validate_point( struct gl_context *ctx, const SWvertex *v0 ) 3897117f1b4Smrg{ 3907117f1b4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 3917117f1b4Smrg 3927117f1b4Smrg _swrast_validate_derived( ctx ); 3937117f1b4Smrg swrast->choose_point( ctx ); 3947117f1b4Smrg 3954a49301eSmrg if (swrast->SpecularVertexAdd) { 3967117f1b4Smrg swrast->SpecPoint = swrast->Point; 3977117f1b4Smrg swrast->Point = _swrast_add_spec_terms_point; 3987117f1b4Smrg } 3997117f1b4Smrg 4007117f1b4Smrg swrast->Point( ctx, v0 ); 4017117f1b4Smrg} 4027117f1b4Smrg 4037117f1b4Smrg 4047117f1b4Smrg/** 4057117f1b4Smrg * Called via swrast->BlendFunc. Examine GL state to choose a blending 4067117f1b4Smrg * function, then call it. 4077117f1b4Smrg */ 40801e04c3fSmrgstatic void 4093464ebd5Sriastradh_swrast_validate_blend_func(struct gl_context *ctx, GLuint n, const GLubyte mask[], 4107117f1b4Smrg GLvoid *src, const GLvoid *dst, 4117117f1b4Smrg GLenum chanType ) 4127117f1b4Smrg{ 4137117f1b4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 4147117f1b4Smrg 4157117f1b4Smrg _swrast_validate_derived( ctx ); /* why is this needed? */ 4167117f1b4Smrg _swrast_choose_blend_func( ctx, chanType ); 4177117f1b4Smrg 4187117f1b4Smrg swrast->BlendFunc( ctx, n, mask, src, dst, chanType ); 4197117f1b4Smrg} 4207117f1b4Smrg 4217117f1b4Smrgstatic void 4223464ebd5Sriastradh_swrast_sleep( struct gl_context *ctx, GLbitfield new_state ) 4237117f1b4Smrg{ 4247117f1b4Smrg (void) ctx; (void) new_state; 4257117f1b4Smrg} 4267117f1b4Smrg 4277117f1b4Smrg 4287117f1b4Smrgstatic void 4293464ebd5Sriastradh_swrast_invalidate_state( struct gl_context *ctx, GLbitfield new_state ) 4307117f1b4Smrg{ 4317117f1b4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 4327117f1b4Smrg GLuint i; 4337117f1b4Smrg 4347117f1b4Smrg swrast->NewState |= new_state; 4357117f1b4Smrg 4367117f1b4Smrg /* After 10 statechanges without any swrast functions being called, 4377117f1b4Smrg * put the module to sleep. 4387117f1b4Smrg */ 4397117f1b4Smrg if (++swrast->StateChanges > 10) { 4407117f1b4Smrg swrast->InvalidateState = _swrast_sleep; 4417117f1b4Smrg swrast->NewState = ~0; 4427117f1b4Smrg new_state = ~0; 4437117f1b4Smrg } 4447117f1b4Smrg 4457117f1b4Smrg if (new_state & swrast->InvalidateTriangleMask) 4467117f1b4Smrg swrast->Triangle = _swrast_validate_triangle; 4477117f1b4Smrg 4487117f1b4Smrg if (new_state & swrast->InvalidateLineMask) 4497117f1b4Smrg swrast->Line = _swrast_validate_line; 4507117f1b4Smrg 4517117f1b4Smrg if (new_state & swrast->InvalidatePointMask) 4527117f1b4Smrg swrast->Point = _swrast_validate_point; 4537117f1b4Smrg 4547117f1b4Smrg if (new_state & _SWRAST_NEW_BLEND_FUNC) 4557117f1b4Smrg swrast->BlendFunc = _swrast_validate_blend_func; 4567117f1b4Smrg 4577117f1b4Smrg if (new_state & _SWRAST_NEW_TEXTURE_SAMPLE_FUNC) 458af69d88dSmrg for (i = 0 ; i < ARRAY_SIZE(swrast->TextureSample); i++) 4597117f1b4Smrg swrast->TextureSample[i] = NULL; 4607117f1b4Smrg} 4617117f1b4Smrg 4627117f1b4Smrg 4637117f1b4Smrgvoid 4643464ebd5Sriastradh_swrast_update_texture_samplers(struct gl_context *ctx) 4657117f1b4Smrg{ 4667117f1b4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 4677117f1b4Smrg GLuint u; 4687117f1b4Smrg 4694a49301eSmrg if (!swrast) 4704a49301eSmrg return; /* pipe hack */ 4714a49301eSmrg 472af69d88dSmrg for (u = 0; u < ARRAY_SIZE(swrast->TextureSample); u++) { 473af69d88dSmrg struct gl_texture_object *tObj = ctx->Texture.Unit[u]._Current; 4747117f1b4Smrg /* Note: If tObj is NULL, the sample function will be a simple 4757117f1b4Smrg * function that just returns opaque black (0,0,0,1). 4767117f1b4Smrg */ 477af69d88dSmrg _mesa_update_fetch_functions(ctx, u); 478af69d88dSmrg swrast->TextureSample[u] = 479af69d88dSmrg _swrast_choose_texture_sample_func(ctx, tObj, 480af69d88dSmrg _mesa_get_samplerobj(ctx, u)); 4817117f1b4Smrg } 4827117f1b4Smrg} 4837117f1b4Smrg 4847117f1b4Smrg 4857117f1b4Smrg/** 486c1f859d4Smrg * Update swrast->_ActiveAttribs, swrast->_NumActiveAttribs, 487c1f859d4Smrg * swrast->_ActiveAtttribMask. 4887117f1b4Smrg */ 4897117f1b4Smrgstatic void 4903464ebd5Sriastradh_swrast_update_active_attribs(struct gl_context *ctx) 4917117f1b4Smrg{ 4927117f1b4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 493af69d88dSmrg GLbitfield64 attribsMask; 494c1f859d4Smrg 495c1f859d4Smrg /* 496c1f859d4Smrg * Compute _ActiveAttribsMask = which fragment attributes are needed. 497c1f859d4Smrg */ 498af69d88dSmrg if (_swrast_use_fragment_program(ctx)) { 499c1f859d4Smrg /* fragment program/shader */ 50001e04c3fSmrg attribsMask = ctx->FragmentProgram._Current->info.inputs_read; 501af69d88dSmrg attribsMask &= ~VARYING_BIT_POS; /* WPOS is always handled specially */ 502c1f859d4Smrg } 50301e04c3fSmrg else if (_mesa_ati_fragment_shader_enabled(ctx)) { 50401e04c3fSmrg attribsMask = VARYING_BIT_COL0 | VARYING_BIT_COL1 | 50501e04c3fSmrg VARYING_BIT_FOGC | VARYING_BITS_TEX_ANY; 5067117f1b4Smrg } 5077117f1b4Smrg else { 508c1f859d4Smrg /* fixed function */ 5097117f1b4Smrg attribsMask = 0x0; 5107117f1b4Smrg 511c1f859d4Smrg#if CHAN_TYPE == GL_FLOAT 512af69d88dSmrg attribsMask |= VARYING_BIT_COL0; 5137117f1b4Smrg#endif 514c1f859d4Smrg 515c1f859d4Smrg if (ctx->Fog.ColorSumEnabled || 516c1f859d4Smrg (ctx->Light.Enabled && 517c1f859d4Smrg ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { 518af69d88dSmrg attribsMask |= VARYING_BIT_COL1; 519c1f859d4Smrg } 520c1f859d4Smrg 5217117f1b4Smrg if (swrast->_FogEnabled) 522af69d88dSmrg attribsMask |= VARYING_BIT_FOGC; 5237117f1b4Smrg 524af69d88dSmrg attribsMask |= (ctx->Texture._EnabledCoordUnits << VARYING_SLOT_TEX0); 5257117f1b4Smrg } 5267117f1b4Smrg 527c1f859d4Smrg swrast->_ActiveAttribMask = attribsMask; 5287117f1b4Smrg 5297117f1b4Smrg /* Update _ActiveAttribs[] list */ 5307117f1b4Smrg { 5317117f1b4Smrg GLuint i, num = 0; 532af69d88dSmrg for (i = 0; i < VARYING_SLOT_MAX; i++) { 533af69d88dSmrg if (attribsMask & BITFIELD64_BIT(i)) { 5347117f1b4Smrg swrast->_ActiveAttribs[num++] = i; 535c1f859d4Smrg /* how should this attribute be interpolated? */ 536af69d88dSmrg if (i == VARYING_SLOT_COL0 || i == VARYING_SLOT_COL1) 537c1f859d4Smrg swrast->_InterpMode[i] = ctx->Light.ShadeModel; 538c1f859d4Smrg else 539c1f859d4Smrg swrast->_InterpMode[i] = GL_SMOOTH; 5407117f1b4Smrg } 5417117f1b4Smrg } 542c1f859d4Smrg swrast->_NumActiveAttribs = num; 5437117f1b4Smrg } 5447117f1b4Smrg} 5457117f1b4Smrg 5467117f1b4Smrg 5477117f1b4Smrgvoid 5483464ebd5Sriastradh_swrast_validate_derived( struct gl_context *ctx ) 5497117f1b4Smrg{ 5507117f1b4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 5517117f1b4Smrg 5527117f1b4Smrg if (swrast->NewState) { 5537117f1b4Smrg if (swrast->NewState & _NEW_POLYGON) 5547117f1b4Smrg _swrast_update_polygon( ctx ); 5557117f1b4Smrg 5567117f1b4Smrg if (swrast->NewState & (_NEW_HINT | _NEW_PROGRAM)) 5577117f1b4Smrg _swrast_update_fog_hint( ctx ); 5587117f1b4Smrg 5597117f1b4Smrg if (swrast->NewState & _SWRAST_NEW_TEXTURE_ENV_MODE) 5607117f1b4Smrg _swrast_update_texture_env( ctx ); 5617117f1b4Smrg 5627117f1b4Smrg if (swrast->NewState & (_NEW_FOG | _NEW_PROGRAM)) 5637117f1b4Smrg _swrast_update_fog_state( ctx ); 5647117f1b4Smrg 5654a49301eSmrg if (swrast->NewState & (_NEW_PROGRAM_CONSTANTS | _NEW_PROGRAM)) 5667117f1b4Smrg _swrast_update_fragment_program( ctx, swrast->NewState ); 5677117f1b4Smrg 568c1f859d4Smrg if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM)) { 5697117f1b4Smrg _swrast_update_texture_samplers( ctx ); 570c1f859d4Smrg } 5717117f1b4Smrg 572c1f859d4Smrg if (swrast->NewState & (_NEW_COLOR | _NEW_PROGRAM)) 573c1f859d4Smrg _swrast_update_deferred_texture(ctx); 5747117f1b4Smrg 5757117f1b4Smrg if (swrast->NewState & _SWRAST_NEW_RASTERMASK) 5767117f1b4Smrg _swrast_update_rasterflags( ctx ); 5777117f1b4Smrg 5787117f1b4Smrg if (swrast->NewState & (_NEW_DEPTH | 5797117f1b4Smrg _NEW_FOG | 580c1f859d4Smrg _NEW_LIGHT | 5817117f1b4Smrg _NEW_PROGRAM | 5827117f1b4Smrg _NEW_TEXTURE)) 583c1f859d4Smrg _swrast_update_active_attribs(ctx); 5847117f1b4Smrg 5857ec681f3Smrg if (swrast->NewState & (_NEW_FOG | 5864a49301eSmrg _NEW_PROGRAM | 5874a49301eSmrg _NEW_LIGHT | 5884a49301eSmrg _NEW_TEXTURE)) 5894a49301eSmrg _swrast_update_specular_vertex_add(ctx); 5904a49301eSmrg 5917117f1b4Smrg swrast->NewState = 0; 5927117f1b4Smrg swrast->StateChanges = 0; 5937117f1b4Smrg swrast->InvalidateState = _swrast_invalidate_state; 5947117f1b4Smrg } 5957117f1b4Smrg} 5967117f1b4Smrg 5977117f1b4Smrg#define SWRAST_DEBUG 0 5987117f1b4Smrg 599af69d88dSmrg/* Public entrypoints: See also s_bitmap.c, etc. 6007117f1b4Smrg */ 6017117f1b4Smrgvoid 6023464ebd5Sriastradh_swrast_Quad( struct gl_context *ctx, 6037117f1b4Smrg const SWvertex *v0, const SWvertex *v1, 6047117f1b4Smrg const SWvertex *v2, const SWvertex *v3 ) 6057117f1b4Smrg{ 6067117f1b4Smrg if (SWRAST_DEBUG) { 6077117f1b4Smrg _mesa_debug(ctx, "_swrast_Quad\n"); 6087117f1b4Smrg _swrast_print_vertex( ctx, v0 ); 6097117f1b4Smrg _swrast_print_vertex( ctx, v1 ); 6107117f1b4Smrg _swrast_print_vertex( ctx, v2 ); 6117117f1b4Smrg _swrast_print_vertex( ctx, v3 ); 6127117f1b4Smrg } 6137117f1b4Smrg SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v3 ); 6147117f1b4Smrg SWRAST_CONTEXT(ctx)->Triangle( ctx, v1, v2, v3 ); 6157117f1b4Smrg} 6167117f1b4Smrg 6177117f1b4Smrgvoid 6183464ebd5Sriastradh_swrast_Triangle( struct gl_context *ctx, const SWvertex *v0, 6197117f1b4Smrg const SWvertex *v1, const SWvertex *v2 ) 6207117f1b4Smrg{ 6217117f1b4Smrg if (SWRAST_DEBUG) { 6227117f1b4Smrg _mesa_debug(ctx, "_swrast_Triangle\n"); 6237117f1b4Smrg _swrast_print_vertex( ctx, v0 ); 6247117f1b4Smrg _swrast_print_vertex( ctx, v1 ); 6257117f1b4Smrg _swrast_print_vertex( ctx, v2 ); 6267117f1b4Smrg } 6277117f1b4Smrg SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 ); 6287117f1b4Smrg} 6297117f1b4Smrg 6307117f1b4Smrgvoid 6313464ebd5Sriastradh_swrast_Line( struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1 ) 6327117f1b4Smrg{ 6337117f1b4Smrg if (SWRAST_DEBUG) { 6347117f1b4Smrg _mesa_debug(ctx, "_swrast_Line\n"); 6357117f1b4Smrg _swrast_print_vertex( ctx, v0 ); 6367117f1b4Smrg _swrast_print_vertex( ctx, v1 ); 6377117f1b4Smrg } 6387117f1b4Smrg SWRAST_CONTEXT(ctx)->Line( ctx, v0, v1 ); 6397117f1b4Smrg} 6407117f1b4Smrg 6417117f1b4Smrgvoid 6423464ebd5Sriastradh_swrast_Point( struct gl_context *ctx, const SWvertex *v0 ) 6437117f1b4Smrg{ 6447117f1b4Smrg if (SWRAST_DEBUG) { 6457117f1b4Smrg _mesa_debug(ctx, "_swrast_Point\n"); 6467117f1b4Smrg _swrast_print_vertex( ctx, v0 ); 6477117f1b4Smrg } 6487117f1b4Smrg SWRAST_CONTEXT(ctx)->Point( ctx, v0 ); 6497117f1b4Smrg} 6507117f1b4Smrg 6517117f1b4Smrgvoid 6523464ebd5Sriastradh_swrast_InvalidateState( struct gl_context *ctx, GLbitfield new_state ) 6537117f1b4Smrg{ 6547117f1b4Smrg if (SWRAST_DEBUG) { 6557117f1b4Smrg _mesa_debug(ctx, "_swrast_InvalidateState\n"); 6567117f1b4Smrg } 6577117f1b4Smrg SWRAST_CONTEXT(ctx)->InvalidateState( ctx, new_state ); 6587117f1b4Smrg} 6597117f1b4Smrg 6607117f1b4Smrgvoid 6613464ebd5Sriastradh_swrast_ResetLineStipple( struct gl_context *ctx ) 6627117f1b4Smrg{ 6637117f1b4Smrg if (SWRAST_DEBUG) { 6647117f1b4Smrg _mesa_debug(ctx, "_swrast_ResetLineStipple\n"); 6657117f1b4Smrg } 6667117f1b4Smrg SWRAST_CONTEXT(ctx)->StippleCounter = 0; 6677117f1b4Smrg} 6687117f1b4Smrg 6697117f1b4Smrgvoid 6703464ebd5Sriastradh_swrast_SetFacing(struct gl_context *ctx, GLuint facing) 6717117f1b4Smrg{ 6727117f1b4Smrg SWRAST_CONTEXT(ctx)->PointLineFacing = facing; 6737117f1b4Smrg} 6747117f1b4Smrg 6757117f1b4Smrgvoid 6763464ebd5Sriastradh_swrast_allow_vertex_fog( struct gl_context *ctx, GLboolean value ) 6777117f1b4Smrg{ 6787117f1b4Smrg if (SWRAST_DEBUG) { 6797117f1b4Smrg _mesa_debug(ctx, "_swrast_allow_vertex_fog %d\n", value); 6807117f1b4Smrg } 6817117f1b4Smrg SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); 6827117f1b4Smrg SWRAST_CONTEXT(ctx)->AllowVertexFog = value; 6837117f1b4Smrg} 6847117f1b4Smrg 6857117f1b4Smrgvoid 6863464ebd5Sriastradh_swrast_allow_pixel_fog( struct gl_context *ctx, GLboolean value ) 6877117f1b4Smrg{ 6887117f1b4Smrg if (SWRAST_DEBUG) { 6897117f1b4Smrg _mesa_debug(ctx, "_swrast_allow_pixel_fog %d\n", value); 6907117f1b4Smrg } 6917117f1b4Smrg SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); 6927117f1b4Smrg SWRAST_CONTEXT(ctx)->AllowPixelFog = value; 6937117f1b4Smrg} 6947117f1b4Smrg 6957117f1b4Smrg 696af69d88dSmrg/** 697af69d88dSmrg * Initialize native program limits by copying the logical limits. 698af69d88dSmrg * See comments in init_program_limits() in context.c 699af69d88dSmrg */ 700af69d88dSmrgstatic void 701af69d88dSmrginit_program_native_limits(struct gl_program_constants *prog) 702af69d88dSmrg{ 703af69d88dSmrg prog->MaxNativeInstructions = prog->MaxInstructions; 704af69d88dSmrg prog->MaxNativeAluInstructions = prog->MaxAluInstructions; 705af69d88dSmrg prog->MaxNativeTexInstructions = prog->MaxTexInstructions; 706af69d88dSmrg prog->MaxNativeTexIndirections = prog->MaxTexIndirections; 707af69d88dSmrg prog->MaxNativeAttribs = prog->MaxAttribs; 708af69d88dSmrg prog->MaxNativeTemps = prog->MaxTemps; 709af69d88dSmrg prog->MaxNativeAddressRegs = prog->MaxAddressRegs; 710af69d88dSmrg prog->MaxNativeParameters = prog->MaxParameters; 711af69d88dSmrg} 712af69d88dSmrg 713af69d88dSmrg 7147117f1b4SmrgGLboolean 7153464ebd5Sriastradh_swrast_CreateContext( struct gl_context *ctx ) 7167117f1b4Smrg{ 7177117f1b4Smrg GLuint i; 718af69d88dSmrg SWcontext *swrast = calloc(1, sizeof(SWcontext)); 719af69d88dSmrg#ifdef _OPENMP 720af69d88dSmrg const GLuint maxThreads = omp_get_max_threads(); 721af69d88dSmrg#else 722af69d88dSmrg const GLuint maxThreads = 1; 723af69d88dSmrg#endif 724af69d88dSmrg 725af69d88dSmrg assert(ctx->Const.MaxViewportWidth <= SWRAST_MAX_WIDTH); 726af69d88dSmrg assert(ctx->Const.MaxViewportHeight <= SWRAST_MAX_WIDTH); 727af69d88dSmrg 728af69d88dSmrg assert(ctx->Const.MaxRenderbufferSize <= SWRAST_MAX_WIDTH); 729af69d88dSmrg 730af69d88dSmrg /* make sure largest texture image is <= SWRAST_MAX_WIDTH in size */ 7317ec681f3Smrg assert(ctx->Const.MaxTextureSize <= SWRAST_MAX_WIDTH); 732af69d88dSmrg assert((1 << (ctx->Const.MaxCubeTextureLevels - 1)) <= SWRAST_MAX_WIDTH); 733af69d88dSmrg assert((1 << (ctx->Const.Max3DTextureLevels - 1)) <= SWRAST_MAX_WIDTH); 734af69d88dSmrg 735af69d88dSmrg assert(PROG_MAX_WIDTH == SWRAST_MAX_WIDTH); 7367117f1b4Smrg 7377117f1b4Smrg if (SWRAST_DEBUG) { 7387117f1b4Smrg _mesa_debug(ctx, "_swrast_CreateContext\n"); 7397117f1b4Smrg } 7407117f1b4Smrg 7417117f1b4Smrg if (!swrast) 7427117f1b4Smrg return GL_FALSE; 7437117f1b4Smrg 7447117f1b4Smrg swrast->NewState = ~0; 7457117f1b4Smrg 7467117f1b4Smrg swrast->choose_point = _swrast_choose_point; 7477117f1b4Smrg swrast->choose_line = _swrast_choose_line; 7487117f1b4Smrg swrast->choose_triangle = _swrast_choose_triangle; 7497117f1b4Smrg 7507117f1b4Smrg swrast->InvalidatePointMask = _SWRAST_NEW_POINT; 7517117f1b4Smrg swrast->InvalidateLineMask = _SWRAST_NEW_LINE; 7527117f1b4Smrg swrast->InvalidateTriangleMask = _SWRAST_NEW_TRIANGLE; 7537117f1b4Smrg 7547117f1b4Smrg swrast->Point = _swrast_validate_point; 7557117f1b4Smrg swrast->Line = _swrast_validate_line; 7567117f1b4Smrg swrast->Triangle = _swrast_validate_triangle; 7577117f1b4Smrg swrast->InvalidateState = _swrast_sleep; 7587117f1b4Smrg swrast->BlendFunc = _swrast_validate_blend_func; 7597117f1b4Smrg 7607117f1b4Smrg swrast->AllowVertexFog = GL_TRUE; 7617117f1b4Smrg swrast->AllowPixelFog = GL_TRUE; 7627117f1b4Smrg 763af69d88dSmrg swrast->Driver.SpanRenderStart = _swrast_span_render_start; 764af69d88dSmrg swrast->Driver.SpanRenderFinish = _swrast_span_render_finish; 7657117f1b4Smrg 766af69d88dSmrg for (i = 0; i < ARRAY_SIZE(swrast->TextureSample); i++) 7677117f1b4Smrg swrast->TextureSample[i] = NULL; 7687117f1b4Smrg 769af69d88dSmrg /* SpanArrays is global and shared by all SWspan instances. However, when 770af69d88dSmrg * using multiple threads, it is necessary to have one SpanArrays instance 771af69d88dSmrg * per thread. 772af69d88dSmrg */ 773af69d88dSmrg swrast->SpanArrays = malloc(maxThreads * sizeof(SWspanarrays)); 7747117f1b4Smrg if (!swrast->SpanArrays) { 775af69d88dSmrg free(swrast); 7767117f1b4Smrg return GL_FALSE; 7777117f1b4Smrg } 778af69d88dSmrg for(i = 0; i < maxThreads; i++) { 779af69d88dSmrg swrast->SpanArrays[i].ChanType = CHAN_TYPE; 7807117f1b4Smrg#if CHAN_TYPE == GL_UNSIGNED_BYTE 781af69d88dSmrg swrast->SpanArrays[i].rgba = swrast->SpanArrays[i].rgba8; 7827117f1b4Smrg#elif CHAN_TYPE == GL_UNSIGNED_SHORT 783af69d88dSmrg swrast->SpanArrays[i].rgba = swrast->SpanArrays[i].rgba16; 7847117f1b4Smrg#else 785af69d88dSmrg swrast->SpanArrays[i].rgba = swrast->SpanArrays[i].attribs[VARYING_SLOT_COL0]; 7867117f1b4Smrg#endif 787af69d88dSmrg } 7887117f1b4Smrg 7897117f1b4Smrg /* init point span buffer */ 7907117f1b4Smrg swrast->PointSpan.primitive = GL_POINT; 7917117f1b4Smrg swrast->PointSpan.end = 0; 7927117f1b4Smrg swrast->PointSpan.facing = 0; 7937117f1b4Smrg swrast->PointSpan.array = swrast->SpanArrays; 7947117f1b4Smrg 795af69d88dSmrg init_program_native_limits(&ctx->Const.Program[MESA_SHADER_VERTEX]); 796af69d88dSmrg init_program_native_limits(&ctx->Const.Program[MESA_SHADER_GEOMETRY]); 797af69d88dSmrg init_program_native_limits(&ctx->Const.Program[MESA_SHADER_FRAGMENT]); 7987117f1b4Smrg 7997117f1b4Smrg ctx->swrast_context = swrast; 8007117f1b4Smrg 801af69d88dSmrg swrast->stencil_temp.buf1 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte)); 802af69d88dSmrg swrast->stencil_temp.buf2 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte)); 803af69d88dSmrg swrast->stencil_temp.buf3 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte)); 804af69d88dSmrg swrast->stencil_temp.buf4 = malloc(SWRAST_MAX_WIDTH * sizeof(GLubyte)); 805af69d88dSmrg 806af69d88dSmrg if (!swrast->stencil_temp.buf1 || 807af69d88dSmrg !swrast->stencil_temp.buf2 || 808af69d88dSmrg !swrast->stencil_temp.buf3 || 809af69d88dSmrg !swrast->stencil_temp.buf4) { 810af69d88dSmrg _swrast_DestroyContext(ctx); 811af69d88dSmrg return GL_FALSE; 812af69d88dSmrg } 813af69d88dSmrg 8147117f1b4Smrg return GL_TRUE; 8157117f1b4Smrg} 8167117f1b4Smrg 8177117f1b4Smrgvoid 8183464ebd5Sriastradh_swrast_DestroyContext( struct gl_context *ctx ) 8197117f1b4Smrg{ 8207117f1b4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 8217117f1b4Smrg 8227117f1b4Smrg if (SWRAST_DEBUG) { 8237117f1b4Smrg _mesa_debug(ctx, "_swrast_DestroyContext\n"); 8247117f1b4Smrg } 8257117f1b4Smrg 826af69d88dSmrg free( swrast->SpanArrays ); 827af69d88dSmrg free( swrast->ZoomedArrays ); 828af69d88dSmrg free( swrast->TexelBuffer ); 829af69d88dSmrg 830af69d88dSmrg free(swrast->stencil_temp.buf1); 831af69d88dSmrg free(swrast->stencil_temp.buf2); 832af69d88dSmrg free(swrast->stencil_temp.buf3); 833af69d88dSmrg free(swrast->stencil_temp.buf4); 834af69d88dSmrg 835af69d88dSmrg free( swrast ); 8367117f1b4Smrg 8377117f1b4Smrg ctx->swrast_context = 0; 8387117f1b4Smrg} 8397117f1b4Smrg 8407117f1b4Smrg 8417117f1b4Smrgstruct swrast_device_driver * 8423464ebd5Sriastradh_swrast_GetDeviceDriverReference( struct gl_context *ctx ) 8437117f1b4Smrg{ 8447117f1b4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 8457117f1b4Smrg return &swrast->Driver; 8467117f1b4Smrg} 8477117f1b4Smrg 8487117f1b4Smrgvoid 8493464ebd5Sriastradh_swrast_flush( struct gl_context *ctx ) 8507117f1b4Smrg{ 8517117f1b4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 8527117f1b4Smrg /* flush any pending fragments from rendering points */ 8537117f1b4Smrg if (swrast->PointSpan.end > 0) { 854cdc920a0Smrg _swrast_write_rgba_span(ctx, &(swrast->PointSpan)); 8557117f1b4Smrg swrast->PointSpan.end = 0; 8567117f1b4Smrg } 8577117f1b4Smrg} 8587117f1b4Smrg 8597117f1b4Smrgvoid 8603464ebd5Sriastradh_swrast_render_primitive( struct gl_context *ctx, GLenum prim ) 8617117f1b4Smrg{ 8627117f1b4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 8637117f1b4Smrg if (swrast->Primitive == GL_POINTS && prim != GL_POINTS) { 8647117f1b4Smrg _swrast_flush(ctx); 8657117f1b4Smrg } 8667117f1b4Smrg swrast->Primitive = prim; 8677117f1b4Smrg} 8687117f1b4Smrg 8697117f1b4Smrg 870af69d88dSmrg/** called via swrast->Driver.SpanRenderStart() */ 871af69d88dSmrgvoid 872af69d88dSmrg_swrast_span_render_start(struct gl_context *ctx) 873af69d88dSmrg{ 874af69d88dSmrg _swrast_map_textures(ctx); 875af69d88dSmrg _swrast_map_renderbuffers(ctx); 876af69d88dSmrg} 877af69d88dSmrg 878af69d88dSmrg 879af69d88dSmrg/** called via swrast->Driver.SpanRenderFinish() */ 880af69d88dSmrgvoid 881af69d88dSmrg_swrast_span_render_finish(struct gl_context *ctx) 882af69d88dSmrg{ 883af69d88dSmrg _swrast_unmap_textures(ctx); 884af69d88dSmrg _swrast_unmap_renderbuffers(ctx); 885af69d88dSmrg} 886af69d88dSmrg 887af69d88dSmrg 8887117f1b4Smrgvoid 8893464ebd5Sriastradh_swrast_render_start( struct gl_context *ctx ) 8907117f1b4Smrg{ 8917117f1b4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 8927117f1b4Smrg if (swrast->Driver.SpanRenderStart) 8937117f1b4Smrg swrast->Driver.SpanRenderStart( ctx ); 8947117f1b4Smrg swrast->PointSpan.end = 0; 8957117f1b4Smrg} 8967ec681f3Smrg 8977117f1b4Smrgvoid 8983464ebd5Sriastradh_swrast_render_finish( struct gl_context *ctx ) 8997117f1b4Smrg{ 9007117f1b4Smrg SWcontext *swrast = SWRAST_CONTEXT(ctx); 90101e04c3fSmrg struct gl_query_object *query = ctx->Query.CurrentOcclusionObject; 9027117f1b4Smrg 9037117f1b4Smrg _swrast_flush(ctx); 904af69d88dSmrg 905af69d88dSmrg if (swrast->Driver.SpanRenderFinish) 906af69d88dSmrg swrast->Driver.SpanRenderFinish( ctx ); 90701e04c3fSmrg 90801e04c3fSmrg if (query && (query->Target == GL_ANY_SAMPLES_PASSED || 90901e04c3fSmrg query->Target == GL_ANY_SAMPLES_PASSED_CONSERVATIVE)) 91001e04c3fSmrg query->Result = !!query->Result; 9117117f1b4Smrg} 9127117f1b4Smrg 9137117f1b4Smrg 9147117f1b4Smrg#define SWRAST_DEBUG_VERTICES 0 9157117f1b4Smrg 9167117f1b4Smrgvoid 9173464ebd5Sriastradh_swrast_print_vertex( struct gl_context *ctx, const SWvertex *v ) 9187117f1b4Smrg{ 9197117f1b4Smrg GLuint i; 9207117f1b4Smrg 9217117f1b4Smrg if (SWRAST_DEBUG_VERTICES) { 9227117f1b4Smrg _mesa_debug(ctx, "win %f %f %f %f\n", 923af69d88dSmrg v->attrib[VARYING_SLOT_POS][0], 924af69d88dSmrg v->attrib[VARYING_SLOT_POS][1], 925af69d88dSmrg v->attrib[VARYING_SLOT_POS][2], 926af69d88dSmrg v->attrib[VARYING_SLOT_POS][3]); 9277117f1b4Smrg 9287117f1b4Smrg for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) 929af69d88dSmrg if (ctx->Texture.Unit[i]._Current) 9307117f1b4Smrg _mesa_debug(ctx, "texcoord[%d] %f %f %f %f\n", i, 931af69d88dSmrg v->attrib[VARYING_SLOT_TEX0 + i][0], 932af69d88dSmrg v->attrib[VARYING_SLOT_TEX0 + i][1], 933af69d88dSmrg v->attrib[VARYING_SLOT_TEX0 + i][2], 934af69d88dSmrg v->attrib[VARYING_SLOT_TEX0 + i][3]); 9357117f1b4Smrg 9367117f1b4Smrg#if CHAN_TYPE == GL_FLOAT 9377117f1b4Smrg _mesa_debug(ctx, "color %f %f %f %f\n", 9387117f1b4Smrg v->color[0], v->color[1], v->color[2], v->color[3]); 9397117f1b4Smrg#else 9407117f1b4Smrg _mesa_debug(ctx, "color %d %d %d %d\n", 9417117f1b4Smrg v->color[0], v->color[1], v->color[2], v->color[3]); 9427117f1b4Smrg#endif 943c1f859d4Smrg _mesa_debug(ctx, "spec %g %g %g %g\n", 944af69d88dSmrg v->attrib[VARYING_SLOT_COL1][0], 945af69d88dSmrg v->attrib[VARYING_SLOT_COL1][1], 946af69d88dSmrg v->attrib[VARYING_SLOT_COL1][2], 947af69d88dSmrg v->attrib[VARYING_SLOT_COL1][3]); 948af69d88dSmrg _mesa_debug(ctx, "fog %f\n", v->attrib[VARYING_SLOT_FOGC][0]); 949af69d88dSmrg _mesa_debug(ctx, "index %f\n", v->attrib[VARYING_SLOT_CI][0]); 9507117f1b4Smrg _mesa_debug(ctx, "pointsize %f\n", v->pointSize); 9517117f1b4Smrg _mesa_debug(ctx, "\n"); 9527117f1b4Smrg } 9537117f1b4Smrg} 954