Home | History | Annotate | Download | only in state_tracker
      1 /**************************************************************************
      2  *
      3  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
      4  * 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
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the
     15  * next paragraph) shall be included in all copies or substantial portions
     16  * of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     21  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
     22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  *
     26  **************************************************************************/
     27 
     28  /*
     29   * Authors:
     30   *   Keith Whitwell <keith (at) tungstengraphics.com>
     31   */
     32 
     33 #include "main/macros.h"
     34 #include "st_context.h"
     35 #include "st_atom.h"
     36 #include "pipe/p_context.h"
     37 #include "pipe/p_defines.h"
     38 #include "cso_cache/cso_context.h"
     39 
     40 
     41 static GLuint translate_fill( GLenum mode )
     42 {
     43    switch (mode) {
     44    case GL_POINT:
     45       return PIPE_POLYGON_MODE_POINT;
     46    case GL_LINE:
     47       return PIPE_POLYGON_MODE_LINE;
     48    case GL_FILL:
     49       return PIPE_POLYGON_MODE_FILL;
     50    default:
     51       assert(0);
     52       return 0;
     53    }
     54 }
     55 
     56 
     57 
     58 static void update_raster_state( struct st_context *st )
     59 {
     60    struct gl_context *ctx = st->ctx;
     61    struct pipe_rasterizer_state *raster = &st->state.rasterizer;
     62    const struct gl_vertex_program *vertProg = ctx->VertexProgram._Current;
     63    const struct gl_fragment_program *fragProg = ctx->FragmentProgram._Current;
     64    uint i;
     65 
     66    memset(raster, 0, sizeof(*raster));
     67 
     68    /* _NEW_POLYGON, _NEW_BUFFERS
     69     */
     70    {
     71       raster->front_ccw = (ctx->Polygon.FrontFace == GL_CCW);
     72 
     73       /*
     74        * Gallium's surfaces are Y=0=TOP orientation.  OpenGL is the
     75        * opposite.  Window system surfaces are Y=0=TOP.  Mesa's FBOs
     76        * must match OpenGL conventions so FBOs use Y=0=BOTTOM.  In that
     77        * case, we must invert Y and flip the notion of front vs. back.
     78        */
     79       if (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM) {
     80          /* Drawing to an FBO.  The viewport will be inverted. */
     81          raster->front_ccw ^= 1;
     82       }
     83    }
     84 
     85    /* _NEW_LIGHT
     86     */
     87    if (ctx->Light.ShadeModel == GL_FLAT)
     88       raster->flatshade = 1;
     89 
     90    if (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION_EXT)
     91       raster->flatshade_first = 1;
     92 
     93    /* _NEW_LIGHT | _NEW_PROGRAM */
     94    raster->light_twoside = ctx->VertexProgram._TwoSideEnabled;
     95 
     96    /*_NEW_LIGHT | _NEW_BUFFERS */
     97    raster->clamp_vertex_color = !st->clamp_vert_color_in_shader &&
     98                                 ctx->Light._ClampVertexColor;
     99 
    100    /* _NEW_POLYGON
    101     */
    102    if (ctx->Polygon.CullFlag) {
    103       switch (ctx->Polygon.CullFaceMode) {
    104       case GL_FRONT:
    105 	 raster->cull_face = PIPE_FACE_FRONT;
    106          break;
    107       case GL_BACK:
    108 	 raster->cull_face = PIPE_FACE_BACK;
    109          break;
    110       case GL_FRONT_AND_BACK:
    111 	 raster->cull_face = PIPE_FACE_FRONT_AND_BACK;
    112          break;
    113       }
    114    }
    115    else {
    116       raster->cull_face = PIPE_FACE_NONE;
    117    }
    118 
    119    /* _NEW_POLYGON
    120     */
    121    {
    122       raster->fill_front = translate_fill( ctx->Polygon.FrontMode );
    123       raster->fill_back = translate_fill( ctx->Polygon.BackMode );
    124 
    125       /* Simplify when culling is active:
    126        */
    127       if (raster->cull_face & PIPE_FACE_FRONT) {
    128 	 raster->fill_front = raster->fill_back;
    129       }
    130 
    131       if (raster->cull_face & PIPE_FACE_BACK) {
    132 	 raster->fill_back = raster->fill_front;
    133       }
    134    }
    135 
    136    /* _NEW_POLYGON
    137     */
    138    if (ctx->Polygon.OffsetUnits != 0.0 ||
    139        ctx->Polygon.OffsetFactor != 0.0) {
    140       raster->offset_point = ctx->Polygon.OffsetPoint;
    141       raster->offset_line = ctx->Polygon.OffsetLine;
    142       raster->offset_tri = ctx->Polygon.OffsetFill;
    143    }
    144 
    145    if (ctx->Polygon.OffsetPoint ||
    146        ctx->Polygon.OffsetLine ||
    147        ctx->Polygon.OffsetFill) {
    148       raster->offset_units = ctx->Polygon.OffsetUnits;
    149       raster->offset_scale = ctx->Polygon.OffsetFactor;
    150    }
    151 
    152    if (ctx->Polygon.SmoothFlag)
    153       raster->poly_smooth = 1;
    154 
    155    if (ctx->Polygon.StippleFlag)
    156       raster->poly_stipple_enable = 1;
    157 
    158    /* _NEW_POINT
    159     */
    160    raster->point_size = ctx->Point.Size;
    161 
    162    if (!ctx->Point.PointSprite && ctx->Point.SmoothFlag)
    163       raster->point_smooth = 1;
    164 
    165    /* _NEW_POINT | _NEW_PROGRAM
    166     */
    167    if (ctx->Point.PointSprite) {
    168       /* origin */
    169       if ((ctx->Point.SpriteOrigin == GL_UPPER_LEFT) ^
    170           (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM))
    171          raster->sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT;
    172       else
    173          raster->sprite_coord_mode = PIPE_SPRITE_COORD_LOWER_LEFT;
    174 
    175       /* Coord replacement flags.  If bit 'k' is set that means
    176        * that we need to replace GENERIC[k] attrib with an automatically
    177        * computed texture coord.
    178        */
    179       for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
    180          if (ctx->Point.CoordReplace[i]) {
    181             raster->sprite_coord_enable |= 1 << i;
    182          }
    183       }
    184       if (fragProg->Base.InputsRead & FRAG_BIT_PNTC) {
    185          raster->sprite_coord_enable |=
    186             1 << (FRAG_ATTRIB_PNTC - FRAG_ATTRIB_TEX0);
    187       }
    188 
    189       raster->point_quad_rasterization = 1;
    190    }
    191 
    192    /* ST_NEW_VERTEX_PROGRAM
    193     */
    194    if (vertProg) {
    195       if (vertProg->Base.Id == 0) {
    196          if (vertProg->Base.OutputsWritten & BITFIELD64_BIT(VERT_RESULT_PSIZ)) {
    197             /* generated program which emits point size */
    198             raster->point_size_per_vertex = TRUE;
    199          }
    200       }
    201       else if (ctx->VertexProgram.PointSizeEnabled) {
    202          /* user-defined program and GL_VERTEX_PROGRAM_POINT_SIZE set */
    203          raster->point_size_per_vertex = ctx->VertexProgram.PointSizeEnabled;
    204       }
    205    }
    206    if (!raster->point_size_per_vertex) {
    207       /* clamp size now */
    208       raster->point_size = CLAMP(ctx->Point.Size,
    209                                  ctx->Point.MinSize,
    210                                  ctx->Point.MaxSize);
    211    }
    212 
    213    /* _NEW_LINE
    214     */
    215    raster->line_smooth = ctx->Line.SmoothFlag;
    216    if (ctx->Line.SmoothFlag) {
    217       raster->line_width = CLAMP(ctx->Line.Width,
    218                                 ctx->Const.MinLineWidthAA,
    219                                 ctx->Const.MaxLineWidthAA);
    220    }
    221    else {
    222       raster->line_width = CLAMP(ctx->Line.Width,
    223                                 ctx->Const.MinLineWidth,
    224                                 ctx->Const.MaxLineWidth);
    225    }
    226 
    227    raster->line_stipple_enable = ctx->Line.StippleFlag;
    228    raster->line_stipple_pattern = ctx->Line.StipplePattern;
    229    /* GL stipple factor is in [1,256], remap to [0, 255] here */
    230    raster->line_stipple_factor = ctx->Line.StippleFactor - 1;
    231 
    232    /* _NEW_MULTISAMPLE */
    233    if (ctx->Multisample._Enabled || st->force_msaa)
    234       raster->multisample = 1;
    235 
    236    /* _NEW_SCISSOR */
    237    if (ctx->Scissor.Enabled)
    238       raster->scissor = 1;
    239 
    240    /* _NEW_FRAG_CLAMP */
    241    raster->clamp_fragment_color = !st->clamp_frag_color_in_shader &&
    242                                   ctx->Color._ClampFragmentColor &&
    243                                   !ctx->DrawBuffer->_IntegerColor;
    244    raster->gl_rasterization_rules = 1;
    245 
    246    /* _NEW_RASTERIZER_DISCARD */
    247    raster->rasterizer_discard = ctx->RasterDiscard;
    248 
    249    /* _NEW_TRANSFORM */
    250    raster->depth_clip = ctx->Transform.DepthClamp == GL_FALSE;
    251    raster->clip_plane_enable = ctx->Transform.ClipPlanesEnabled;
    252 
    253    cso_set_rasterizer(st->cso_context, raster);
    254 }
    255 
    256 const struct st_tracked_state st_update_rasterizer = {
    257    "st_update_rasterizer",    /* name */
    258    {
    259       (_NEW_BUFFERS |
    260        _NEW_LIGHT |
    261        _NEW_LINE |
    262        _NEW_MULTISAMPLE |
    263        _NEW_POINT |
    264        _NEW_POLYGON |
    265        _NEW_PROGRAM |
    266        _NEW_SCISSOR |
    267        _NEW_FRAG_CLAMP |
    268        _NEW_RASTERIZER_DISCARD |
    269        _NEW_TRANSFORM),      /* mesa state dependencies*/
    270       ST_NEW_VERTEX_PROGRAM,  /* state tracker dependencies */
    271    },
    272    update_raster_state     /* update function */
    273 };
    274