Home | History | Annotate | Download | only in swrast_setup
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 1999-2007  Brian Paul   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 "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included
     14  * in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors:
     25  *    Keith Whitwell <keithw (at) vmware.com>
     26  */
     27 
     28 #include "c99_math.h"
     29 #include "main/glheader.h"
     30 #include "main/macros.h"
     31 #include "main/mtypes.h"
     32 #include "main/stencil.h"
     33 #include "main/state.h"
     34 
     35 #include "tnl/t_context.h"
     36 
     37 #include "ss_triangle.h"
     38 #include "ss_context.h"
     39 
     40 #define SS_OFFSET_BIT	    0x1
     41 #define SS_TWOSIDE_BIT	    0x2
     42 #define SS_UNFILLED_BIT	    0x4
     43 #define SS_MAX_TRIFUNC      0x8
     44 
     45 static tnl_triangle_func tri_tab[SS_MAX_TRIFUNC];
     46 static tnl_quad_func     quad_tab[SS_MAX_TRIFUNC];
     47 
     48 
     49 /*
     50  * Render a triangle respecting edge flags.
     51  */
     52 typedef void (* swsetup_edge_render_prim_tri)(struct gl_context *ctx,
     53                                               const GLubyte *ef,
     54                                               GLuint e0,
     55                                               GLuint e1,
     56                                               GLuint e2,
     57                                               const SWvertex *v0,
     58                                               const SWvertex *v1,
     59                                               const SWvertex *v2);
     60 
     61 /*
     62  * Render a triangle using lines and respecting edge flags.
     63  */
     64 static void
     65 _swsetup_edge_render_line_tri(struct gl_context *ctx,
     66                               const GLubyte *ef,
     67                               GLuint e0,
     68                               GLuint e1,
     69                               GLuint e2,
     70                               const SWvertex *v0,
     71                               const SWvertex *v1,
     72                               const SWvertex *v2)
     73 {
     74    SScontext *swsetup = SWSETUP_CONTEXT(ctx);
     75 
     76    if (swsetup->render_prim == GL_POLYGON) {
     77       if (ef[e2]) _swrast_Line( ctx, v2, v0 );
     78       if (ef[e0]) _swrast_Line( ctx, v0, v1 );
     79       if (ef[e1]) _swrast_Line( ctx, v1, v2 );
     80    } else {
     81       if (ef[e0]) _swrast_Line( ctx, v0, v1 );
     82       if (ef[e1]) _swrast_Line( ctx, v1, v2 );
     83       if (ef[e2]) _swrast_Line( ctx, v2, v0 );
     84    }
     85 }
     86 
     87 /*
     88  * Render a triangle using points and respecting edge flags.
     89  */
     90 static void
     91 _swsetup_edge_render_point_tri(struct gl_context *ctx,
     92                                const GLubyte *ef,
     93                                GLuint e0,
     94                                GLuint e1,
     95                                GLuint e2,
     96                                const SWvertex *v0,
     97                                const SWvertex *v1,
     98                                const SWvertex *v2)
     99 {
    100    if (ef[e0]) _swrast_Point( ctx, v0 );
    101    if (ef[e1]) _swrast_Point( ctx, v1 );
    102    if (ef[e2]) _swrast_Point( ctx, v2 );
    103 
    104    _swrast_flush(ctx);
    105 }
    106 
    107 /*
    108  * Render a triangle respecting cull and shade model.
    109  */
    110 static void _swsetup_render_tri(struct gl_context *ctx,
    111                                 GLuint e0,
    112                                 GLuint e1,
    113                                 GLuint e2,
    114                                 GLuint facing,
    115                                 swsetup_edge_render_prim_tri render)
    116 {
    117    SScontext *swsetup = SWSETUP_CONTEXT(ctx);
    118    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
    119    GLubyte *ef = VB->EdgeFlag;
    120    SWvertex *verts = swsetup->verts;
    121    SWvertex *v0 = &verts[e0];
    122    SWvertex *v1 = &verts[e1];
    123    SWvertex *v2 = &verts[e2];
    124 
    125    /* cull testing */
    126    if (ctx->Polygon.CullFlag) {
    127       if (facing == 1 && ctx->Polygon.CullFaceMode != GL_FRONT)
    128          return;
    129       if (facing == 0 && ctx->Polygon.CullFaceMode != GL_BACK)
    130          return;
    131    }
    132 
    133    _swrast_SetFacing(ctx, facing);
    134 
    135    if (ctx->Light.ShadeModel == GL_FLAT) {
    136       GLchan c[2][4];
    137       GLfloat s[2][4];
    138 
    139       /* save colors/indexes for v0, v1 vertices */
    140       COPY_CHAN4(c[0], v0->color);
    141       COPY_CHAN4(c[1], v1->color);
    142       COPY_4V(s[0], v0->attrib[VARYING_SLOT_COL1]);
    143       COPY_4V(s[1], v1->attrib[VARYING_SLOT_COL1]);
    144 
    145       /* copy v2 color/indexes to v0, v1 indexes */
    146       COPY_CHAN4(v0->color, v2->color);
    147       COPY_CHAN4(v1->color, v2->color);
    148       COPY_4V(v0->attrib[VARYING_SLOT_COL1], v2->attrib[VARYING_SLOT_COL1]);
    149       COPY_4V(v1->attrib[VARYING_SLOT_COL1], v2->attrib[VARYING_SLOT_COL1]);
    150 
    151       render(ctx, ef, e0, e1, e2, v0, v1, v2);
    152 
    153       COPY_CHAN4(v0->color, c[0]);
    154       COPY_CHAN4(v1->color, c[1]);
    155       COPY_4V(v0->attrib[VARYING_SLOT_COL1], s[0]);
    156       COPY_4V(v1->attrib[VARYING_SLOT_COL1], s[1]);
    157    }
    158    else {
    159       render(ctx, ef, e0, e1, e2, v0, v1, v2);
    160    }
    161 }
    162 
    163 #define SS_COLOR(a,b) UNCLAMPED_FLOAT_TO_RGBA_CHAN(a,b)
    164 #define SS_SPEC(a,b) COPY_4V(a,b)
    165 #define SS_IND(a,b) (a = b)
    166 
    167 #define IND (0)
    168 #define TAG(x) x##_rgba
    169 #include "ss_tritmp.h"
    170 
    171 #define IND (SS_OFFSET_BIT)
    172 #define TAG(x) x##_offset_rgba
    173 #include "ss_tritmp.h"
    174 
    175 #define IND (SS_TWOSIDE_BIT)
    176 #define TAG(x) x##_twoside_rgba
    177 #include "ss_tritmp.h"
    178 
    179 #define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT)
    180 #define TAG(x) x##_offset_twoside_rgba
    181 #include "ss_tritmp.h"
    182 
    183 #define IND (SS_UNFILLED_BIT)
    184 #define TAG(x) x##_unfilled_rgba
    185 #include "ss_tritmp.h"
    186 
    187 #define IND (SS_OFFSET_BIT|SS_UNFILLED_BIT)
    188 #define TAG(x) x##_offset_unfilled_rgba
    189 #include "ss_tritmp.h"
    190 
    191 #define IND (SS_TWOSIDE_BIT|SS_UNFILLED_BIT)
    192 #define TAG(x) x##_twoside_unfilled_rgba
    193 #include "ss_tritmp.h"
    194 
    195 #define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT|SS_UNFILLED_BIT)
    196 #define TAG(x) x##_offset_twoside_unfilled_rgba
    197 #include "ss_tritmp.h"
    198 
    199 
    200 void _swsetup_trifuncs_init( struct gl_context *ctx )
    201 {
    202    (void) ctx;
    203 
    204    init_rgba();
    205    init_offset_rgba();
    206    init_twoside_rgba();
    207    init_offset_twoside_rgba();
    208    init_unfilled_rgba();
    209    init_offset_unfilled_rgba();
    210    init_twoside_unfilled_rgba();
    211    init_offset_twoside_unfilled_rgba();
    212 }
    213 
    214 
    215 static void swsetup_points( struct gl_context *ctx, GLuint first, GLuint last )
    216 {
    217    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
    218    SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts;
    219    GLuint i;
    220 
    221    if (VB->Elts) {
    222       for (i = first; i < last; i++)
    223 	 if (VB->ClipMask[VB->Elts[i]] == 0)
    224 	    _swrast_Point( ctx, &verts[VB->Elts[i]] );
    225    }
    226    else {
    227       for (i = first; i < last; i++)
    228 	 if (VB->ClipMask[i] == 0)
    229 	    _swrast_Point( ctx, &verts[i] );
    230    }
    231 }
    232 
    233 static void swsetup_line( struct gl_context *ctx, GLuint v0, GLuint v1 )
    234 {
    235    SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts;
    236    _swrast_Line( ctx, &verts[v0], &verts[v1] );
    237 }
    238 
    239 
    240 
    241 void _swsetup_choose_trifuncs( struct gl_context *ctx )
    242 {
    243    TNLcontext *tnl = TNL_CONTEXT(ctx);
    244    GLuint ind = 0;
    245 
    246    if (ctx->Polygon.OffsetPoint ||
    247        ctx->Polygon.OffsetLine ||
    248        ctx->Polygon.OffsetFill)
    249       ind |= SS_OFFSET_BIT;
    250 
    251    if ((ctx->Light.Enabled && ctx->Light.Model.TwoSide) ||
    252        (ctx->VertexProgram._Current && ctx->VertexProgram.TwoSideEnabled))
    253       ind |= SS_TWOSIDE_BIT;
    254 
    255    /* We piggyback the two-sided stencil front/back determination on the
    256     * unfilled triangle path.
    257     */
    258    if (ctx->Polygon.FrontMode != GL_FILL ||
    259        ctx->Polygon.BackMode != GL_FILL ||
    260        (ctx->Stencil.Enabled && _mesa_stencil_is_two_sided(ctx)))
    261       ind |= SS_UNFILLED_BIT;
    262 
    263    tnl->Driver.Render.Triangle = tri_tab[ind];
    264    tnl->Driver.Render.Quad = quad_tab[ind];
    265    tnl->Driver.Render.Line = swsetup_line;
    266    tnl->Driver.Render.Points = swsetup_points;
    267 }
    268