Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  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@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.