st_atom_rasterizer.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  * 
00003  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  * 
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  * 
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  * 
00026  **************************************************************************/
00027 
00028  /*
00029   * Authors:
00030   *   Keith Whitwell <keith@tungstengraphics.com>
00031   */
00032  
00033 #include "main/macros.h"
00034 #include "st_context.h"
00035 #include "st_atom.h"
00036 #include "pipe/p_context.h"
00037 #include "pipe/p_defines.h"
00038 #include "cso_cache/cso_context.h"
00039 
00040 
00041 static GLuint translate_fill( GLenum mode )
00042 {
00043    switch (mode) {
00044    case GL_POINT:
00045       return PIPE_POLYGON_MODE_POINT;
00046    case GL_LINE:
00047       return PIPE_POLYGON_MODE_LINE;
00048    case GL_FILL:
00049       return PIPE_POLYGON_MODE_FILL;
00050    default:
00051       assert(0);
00052       return 0;
00053    }
00054 }
00055 
00056 static GLboolean get_offset_flag( GLuint fill_mode, 
00057                                   const struct gl_polygon_attrib *p )
00058 {
00059    switch (fill_mode) {
00060    case PIPE_POLYGON_MODE_POINT:
00061       return p->OffsetPoint;
00062    case PIPE_POLYGON_MODE_LINE:
00063       return p->OffsetLine;
00064    case PIPE_POLYGON_MODE_FILL:
00065       return p->OffsetFill;
00066    default:
00067       assert(0);
00068       return 0;
00069    }
00070 }
00071 
00072 
00073 static void update_raster_state( struct st_context *st )
00074 {
00075    GLcontext *ctx = st->ctx;
00076    struct pipe_rasterizer_state *raster = &st->state.rasterizer;
00077    const struct gl_vertex_program *vertProg = ctx->VertexProgram._Current;
00078    uint i;
00079 
00080    memset(raster, 0, sizeof(*raster));
00081 
00082    raster->origin_lower_left = 1; /* Always true for OpenGL */
00083    
00084    /* _NEW_POLYGON, _NEW_BUFFERS
00085     */
00086    {
00087       if (ctx->Polygon.FrontFace == GL_CCW)
00088          raster->front_winding = PIPE_WINDING_CCW;
00089       else
00090          raster->front_winding = PIPE_WINDING_CW;
00091 
00092       /* XXX
00093        * I think the intention here is that user-created framebuffer objects
00094        * use Y=0=TOP layout instead of OpenGL's normal Y=0=bottom layout.
00095        * Flipping Y changes CW to CCW and vice-versa.
00096        * But this is an implementation/driver-specific artifact - remove...
00097        */
00098       if (ctx->DrawBuffer && ctx->DrawBuffer->Name != 0)
00099          raster->front_winding ^= PIPE_WINDING_BOTH;
00100    }
00101 
00102    /* _NEW_LIGHT
00103     */
00104    if (ctx->Light.ShadeModel == GL_FLAT)
00105       raster->flatshade = 1;
00106 
00107    /* _NEW_LIGHT | _NEW_PROGRAM
00108     *
00109     * Back-face colors can come from traditional lighting (when
00110     * GL_LIGHT_MODEL_TWO_SIDE is set) or from vertex programs/shaders (when
00111     * GL_VERTEX_PROGRAM_TWO_SIDE is set).  Note the logic here.
00112     */
00113    if (ctx->VertexProgram._Current) {
00114       if (ctx->VertexProgram._Enabled ||
00115           (ctx->Shader.CurrentProgram &&
00116            ctx->Shader.CurrentProgram->VertexProgram &&
00117            ctx->Shader.CurrentProgram->LinkStatus)) {
00118          /* user-defined vertex program or shader */
00119          raster->light_twoside = ctx->VertexProgram.TwoSideEnabled;
00120       }
00121       else {
00122          /* TNL-generated program */
00123          raster->light_twoside = ctx->Light.Enabled && ctx->Light.Model.TwoSide;
00124       }
00125    }
00126    else if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
00127       raster->light_twoside = 1;
00128    }
00129 
00130    /* _NEW_POLYGON
00131     */
00132    if (ctx->Polygon.CullFlag) {
00133       if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) {
00134          raster->cull_mode = PIPE_WINDING_BOTH;
00135       }
00136       else if (ctx->Polygon.CullFaceMode == GL_FRONT) {
00137          raster->cull_mode = raster->front_winding;
00138       }
00139       else {
00140          raster->cull_mode = raster->front_winding ^ PIPE_WINDING_BOTH;
00141       }
00142    }
00143 
00144    /* _NEW_POLYGON
00145     */
00146    {
00147       GLuint fill_front = translate_fill( ctx->Polygon.FrontMode );
00148       GLuint fill_back = translate_fill( ctx->Polygon.BackMode );
00149       
00150       if (raster->front_winding == PIPE_WINDING_CW) {
00151          raster->fill_cw = fill_front;
00152          raster->fill_ccw = fill_back;
00153       }
00154       else {
00155          raster->fill_cw = fill_back;
00156          raster->fill_ccw = fill_front;
00157       }
00158 
00159       /* Simplify when culling is active:
00160        */
00161       if (raster->cull_mode & PIPE_WINDING_CW) {
00162          raster->fill_cw = raster->fill_ccw;
00163       }
00164       
00165       if (raster->cull_mode & PIPE_WINDING_CCW) {
00166          raster->fill_ccw = raster->fill_cw;
00167       }
00168    }
00169 
00170    /* _NEW_POLYGON 
00171     */
00172    if (ctx->Polygon.OffsetUnits != 0.0 ||
00173        ctx->Polygon.OffsetFactor != 0.0) {
00174       raster->offset_cw = get_offset_flag( raster->fill_cw, &ctx->Polygon );
00175       raster->offset_ccw = get_offset_flag( raster->fill_ccw, &ctx->Polygon );
00176       raster->offset_units = ctx->Polygon.OffsetUnits;
00177       raster->offset_scale = ctx->Polygon.OffsetFactor;
00178    }
00179 
00180    if (ctx->Polygon.SmoothFlag)
00181       raster->poly_smooth = 1;
00182 
00183    if (ctx->Polygon.StippleFlag)
00184       raster->poly_stipple_enable = 1;
00185 
00186 
00187    /* _NEW_BUFFERS, _NEW_POLYGON
00188     */
00189    if (raster->fill_cw != PIPE_POLYGON_MODE_FILL ||
00190        raster->fill_ccw != PIPE_POLYGON_MODE_FILL)
00191    {
00192       GLfloat mrd = (ctx->DrawBuffer ? 
00193                      ctx->DrawBuffer->_MRD : 
00194                      1.0f);
00195 
00196       raster->offset_units = ctx->Polygon.OffsetFactor * mrd;
00197       raster->offset_scale = (ctx->Polygon.OffsetUnits * mrd *
00198                             st->polygon_offset_scale);
00199    }
00200       
00201    /* _NEW_POINT
00202     */
00203    raster->point_size = ctx->Point.Size;
00204 
00205    raster->point_size_min = 0;    /* temporary, will go away */
00206    raster->point_size_max = 1000; /* temporary, will go away */
00207 
00208    raster->point_smooth = ctx->Point.SmoothFlag;
00209    raster->point_sprite = ctx->Point.PointSprite;
00210    for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
00211       if (ctx->Point.CoordReplace[i]) {
00212          if (ctx->Point.SpriteOrigin == GL_UPPER_LEFT)
00213             raster->sprite_coord_mode[i] = PIPE_SPRITE_COORD_UPPER_LEFT;
00214          else 
00215             raster->sprite_coord_mode[i] = PIPE_SPRITE_COORD_LOWER_LEFT;
00216       }
00217       else {
00218          raster->sprite_coord_mode[i] = PIPE_SPRITE_COORD_NONE;
00219       }
00220    }
00221 
00222    /* ST_NEW_VERTEX_PROGRAM
00223     */
00224    if (vertProg) {
00225       if (vertProg->Base.Id == 0) {
00226          if (vertProg->Base.OutputsWritten & (1 << VERT_RESULT_PSIZ)) {
00227             /* generated program which emits point size */
00228             raster->point_size_per_vertex = TRUE;
00229          }
00230       }
00231       else if (ctx->VertexProgram.PointSizeEnabled) {
00232          /* user-defined program and GL_VERTEX_PROGRAM_POINT_SIZE set */
00233          raster->point_size_per_vertex = ctx->VertexProgram.PointSizeEnabled;
00234       }
00235    }
00236    if (!raster->point_size_per_vertex) {
00237       /* clamp size now */
00238       raster->point_size = CLAMP(ctx->Point.Size,
00239                                  ctx->Point.MinSize,
00240                                  ctx->Point.MaxSize);
00241    }
00242 
00243    /* _NEW_LINE
00244     */
00245    raster->line_smooth = ctx->Line.SmoothFlag;
00246    if (ctx->Line.SmoothFlag) {
00247       raster->line_width = CLAMP(ctx->Line.Width,
00248                                 ctx->Const.MinLineWidthAA,
00249                                 ctx->Const.MaxLineWidthAA);
00250    }
00251    else {
00252       raster->line_width = CLAMP(ctx->Line.Width,
00253                                 ctx->Const.MinLineWidth,
00254                                 ctx->Const.MaxLineWidth);
00255    }
00256 
00257    raster->line_stipple_enable = ctx->Line.StippleFlag;
00258    raster->line_stipple_pattern = ctx->Line.StipplePattern;
00259    /* GL stipple factor is in [1,256], remap to [0, 255] here */
00260    raster->line_stipple_factor = ctx->Line.StippleFactor - 1;
00261 
00262    /* _NEW_MULTISAMPLE */
00263    if (ctx->Multisample._Enabled || st->force_msaa)
00264       raster->multisample = 1;
00265 
00266    /* _NEW_SCISSOR */
00267    if (ctx->Scissor.Enabled)
00268       raster->scissor = 1;
00269 
00270    raster->gl_rasterization_rules = 1;
00271 
00272    cso_set_rasterizer(st->cso_context, raster);
00273 }
00274 
00275 const struct st_tracked_state st_update_rasterizer = {
00276    "st_update_rasterizer",    /* name */
00277    {
00278       (_NEW_BUFFERS |
00279        _NEW_LIGHT |
00280        _NEW_LINE |
00281        _NEW_MULTISAMPLE |
00282        _NEW_POINT |
00283        _NEW_POLYGON |
00284        _NEW_PROGRAM |
00285        _NEW_SCISSOR),      /* mesa state dependencies*/
00286       ST_NEW_VERTEX_PROGRAM,  /* state tracker dependencies */
00287    },
00288    update_raster_state     /* update function */
00289 };

Generated on Tue Sep 29 06:25:18 2009 for Gallium3D by  doxygen 1.5.4