Home | History | Annotate | Download | only in draw
      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 /* Authors:  Keith Whitwell <keith (at) tungstengraphics.com>
     29  */
     30 
     31 #include "util/u_math.h"
     32 #include "util/u_memory.h"
     33 
     34 #include "pipe/p_shader_tokens.h"
     35 #include "draw_vs.h"
     36 #include "draw_pipe.h"
     37 
     38 
     39 /** subclass of draw_stage */
     40 struct flat_stage
     41 {
     42    struct draw_stage stage;
     43 
     44    uint num_color_attribs;
     45    uint color_attribs[2];  /* front/back primary colors */
     46 
     47    uint num_spec_attribs;
     48    uint spec_attribs[2];  /* front/back secondary colors */
     49 };
     50 
     51 #define COPY_3FV( DST, SRC )         \
     52 do {                                \
     53    (DST)[0] = (SRC)[0];             \
     54    (DST)[1] = (SRC)[1];             \
     55    (DST)[2] = (SRC)[2];             \
     56 } while (0)
     57 
     58 
     59 static INLINE struct flat_stage *
     60 flat_stage(struct draw_stage *stage)
     61 {
     62    return (struct flat_stage *) stage;
     63 }
     64 
     65 
     66 /** Copy all the color attributes from 'src' vertex to 'dst' vertex */
     67 static INLINE void copy_colors( struct draw_stage *stage,
     68                                 struct vertex_header *dst,
     69                                 const struct vertex_header *src )
     70 {
     71    const struct flat_stage *flat = flat_stage(stage);
     72    uint i;
     73 
     74    for (i = 0; i < flat->num_color_attribs; i++) {
     75       const uint attr = flat->color_attribs[i];
     76       COPY_4FV(dst->data[attr], src->data[attr]);
     77    }
     78 
     79    for (i = 0; i < flat->num_spec_attribs; i++) {
     80       const uint attr = flat->spec_attribs[i];
     81       COPY_3FV(dst->data[attr], src->data[attr]);
     82    }
     83 }
     84 
     85 
     86 /** Copy all the color attributes from src vertex to dst0 & dst1 vertices */
     87 static INLINE void copy_colors2( struct draw_stage *stage,
     88                                  struct vertex_header *dst0,
     89                                  struct vertex_header *dst1,
     90                                  const struct vertex_header *src )
     91 {
     92    const struct flat_stage *flat = flat_stage(stage);
     93    uint i;
     94    for (i = 0; i < flat->num_color_attribs; i++) {
     95       const uint attr = flat->color_attribs[i];
     96       COPY_4FV(dst0->data[attr], src->data[attr]);
     97       COPY_4FV(dst1->data[attr], src->data[attr]);
     98    }
     99 
    100    for (i = 0; i < flat->num_spec_attribs; i++) {
    101       const uint attr = flat->spec_attribs[i];
    102       COPY_3FV(dst0->data[attr], src->data[attr]);
    103       COPY_3FV(dst1->data[attr], src->data[attr]);
    104    }
    105 }
    106 
    107 
    108 /**
    109  * Flatshade tri.  Required for clipping and when unfilled tris are
    110  * active, otherwise handled by hardware.
    111  */
    112 static void flatshade_tri_0( struct draw_stage *stage,
    113                              struct prim_header *header )
    114 {
    115    struct prim_header tmp;
    116 
    117    tmp.det = header->det;
    118    tmp.flags = header->flags;
    119    tmp.pad = header->pad;
    120    tmp.v[0] = header->v[0];
    121    tmp.v[1] = dup_vert(stage, header->v[1], 0);
    122    tmp.v[2] = dup_vert(stage, header->v[2], 1);
    123 
    124    copy_colors2(stage, tmp.v[1], tmp.v[2], tmp.v[0]);
    125 
    126    stage->next->tri( stage->next, &tmp );
    127 }
    128 
    129 
    130 static void flatshade_tri_2( struct draw_stage *stage,
    131                              struct prim_header *header )
    132 {
    133    struct prim_header tmp;
    134 
    135    tmp.det = header->det;
    136    tmp.flags = header->flags;
    137    tmp.pad = header->pad;
    138    tmp.v[0] = dup_vert(stage, header->v[0], 0);
    139    tmp.v[1] = dup_vert(stage, header->v[1], 1);
    140    tmp.v[2] = header->v[2];
    141 
    142    copy_colors2(stage, tmp.v[0], tmp.v[1], tmp.v[2]);
    143 
    144    stage->next->tri( stage->next, &tmp );
    145 }
    146 
    147 
    148 
    149 
    150 
    151 /**
    152  * Flatshade line.  Required for clipping.
    153  */
    154 static void flatshade_line_0( struct draw_stage *stage,
    155                               struct prim_header *header )
    156 {
    157    struct prim_header tmp;
    158 
    159    tmp.v[0] = header->v[0];
    160    tmp.v[1] = dup_vert(stage, header->v[1], 0);
    161 
    162    copy_colors(stage, tmp.v[1], tmp.v[0]);
    163 
    164    stage->next->line( stage->next, &tmp );
    165 }
    166 
    167 static void flatshade_line_1( struct draw_stage *stage,
    168                               struct prim_header *header )
    169 {
    170    struct prim_header tmp;
    171 
    172    tmp.v[0] = dup_vert(stage, header->v[0], 0);
    173    tmp.v[1] = header->v[1];
    174 
    175    copy_colors(stage, tmp.v[0], tmp.v[1]);
    176 
    177    stage->next->line( stage->next, &tmp );
    178 }
    179 
    180 
    181 
    182 
    183 static void flatshade_init_state( struct draw_stage *stage )
    184 {
    185    struct flat_stage *flat = flat_stage(stage);
    186    const struct draw_vertex_shader *vs = stage->draw->vs.vertex_shader;
    187    uint i;
    188 
    189    /* Find which vertex shader outputs are colors, make a list */
    190    flat->num_color_attribs = 0;
    191    flat->num_spec_attribs = 0;
    192    for (i = 0; i < vs->info.num_outputs; i++) {
    193       if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR ||
    194           vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
    195          if (vs->info.output_semantic_index[i] == 0)
    196             flat->color_attribs[flat->num_color_attribs++] = i;
    197          else
    198             flat->spec_attribs[flat->num_spec_attribs++] = i;
    199       }
    200    }
    201 
    202    /* Choose flatshade routine according to provoking vertex:
    203     */
    204    if (stage->draw->rasterizer->flatshade_first) {
    205       stage->line = flatshade_line_0;
    206       stage->tri = flatshade_tri_0;
    207    }
    208    else {
    209       stage->line = flatshade_line_1;
    210       stage->tri = flatshade_tri_2;
    211    }
    212 }
    213 
    214 static void flatshade_first_tri( struct draw_stage *stage,
    215 				 struct prim_header *header )
    216 {
    217    flatshade_init_state( stage );
    218    stage->tri( stage, header );
    219 }
    220 
    221 static void flatshade_first_line( struct draw_stage *stage,
    222 				  struct prim_header *header )
    223 {
    224    flatshade_init_state( stage );
    225    stage->line( stage, header );
    226 }
    227 
    228 
    229 static void flatshade_flush( struct draw_stage *stage,
    230 			     unsigned flags )
    231 {
    232    stage->tri = flatshade_first_tri;
    233    stage->line = flatshade_first_line;
    234    stage->next->flush( stage->next, flags );
    235 }
    236 
    237 
    238 static void flatshade_reset_stipple_counter( struct draw_stage *stage )
    239 {
    240    stage->next->reset_stipple_counter( stage->next );
    241 }
    242 
    243 
    244 static void flatshade_destroy( struct draw_stage *stage )
    245 {
    246    draw_free_temp_verts( stage );
    247    FREE( stage );
    248 }
    249 
    250 
    251 /**
    252  * Create flatshading drawing stage.
    253  */
    254 struct draw_stage *draw_flatshade_stage( struct draw_context *draw )
    255 {
    256    struct flat_stage *flatshade = CALLOC_STRUCT(flat_stage);
    257    if (flatshade == NULL)
    258       goto fail;
    259 
    260    flatshade->stage.draw = draw;
    261    flatshade->stage.name = "flatshade";
    262    flatshade->stage.next = NULL;
    263    flatshade->stage.point = draw_pipe_passthrough_point;
    264    flatshade->stage.line = flatshade_first_line;
    265    flatshade->stage.tri = flatshade_first_tri;
    266    flatshade->stage.flush = flatshade_flush;
    267    flatshade->stage.reset_stipple_counter = flatshade_reset_stipple_counter;
    268    flatshade->stage.destroy = flatshade_destroy;
    269 
    270    if (!draw_alloc_temp_verts( &flatshade->stage, 2 ))
    271       goto fail;
    272 
    273    return &flatshade->stage;
    274 
    275  fail:
    276    if (flatshade)
    277       flatshade->stage.destroy( &flatshade->stage );
    278 
    279    return NULL;
    280 }
    281 
    282 
    283