Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**********************************************************
  2.  * Copyright 2008-2009 VMware, Inc.  All rights reserved.
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person
  5.  * obtaining a copy of this software and associated documentation
  6.  * files (the "Software"), to deal in the Software without
  7.  * restriction, including without limitation the rights to use, copy,
  8.  * modify, merge, publish, distribute, sublicense, and/or sell copies
  9.  * of the Software, and to permit persons to whom the Software is
  10.  * furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice shall be
  13.  * included in all copies or substantial portions of the Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16.  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18.  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  19.  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  20.  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22.  * SOFTWARE.
  23.  *
  24.  **********************************************************/
  25.  
  26. #include "draw/draw_context.h"
  27. #include "util/u_inlines.h"
  28. #include "pipe/p_defines.h"
  29. #include "util/u_math.h"
  30. #include "util/u_memory.h"
  31.  
  32. #include "svga_context.h"
  33.  
  34. #include "svga_hw_reg.h"
  35.  
  36. /* Hardware frontwinding is always set up as SVGA3D_FRONTWINDING_CW.
  37.  */
  38. static SVGA3dFace svga_translate_cullmode( unsigned mode,
  39.                                            unsigned front_ccw )
  40. {
  41.    const int hw_front_ccw = 0;  /* hardware is always CW */
  42.    switch (mode) {
  43.    case PIPE_FACE_NONE:
  44.       return SVGA3D_FACE_NONE;
  45.    case PIPE_FACE_FRONT:
  46.       return front_ccw == hw_front_ccw ? SVGA3D_FACE_FRONT : SVGA3D_FACE_BACK;
  47.    case PIPE_FACE_BACK:
  48.       return front_ccw == hw_front_ccw ? SVGA3D_FACE_BACK : SVGA3D_FACE_FRONT;
  49.    case PIPE_FACE_FRONT_AND_BACK:
  50.       return SVGA3D_FACE_FRONT_BACK;
  51.    default:
  52.       assert(0);
  53.       return SVGA3D_FACE_NONE;
  54.    }
  55. }
  56.  
  57. static SVGA3dShadeMode svga_translate_flatshade( unsigned mode )
  58. {
  59.    return mode ? SVGA3D_SHADEMODE_FLAT : SVGA3D_SHADEMODE_SMOOTH;
  60. }
  61.  
  62.  
  63. static void *
  64. svga_create_rasterizer_state(struct pipe_context *pipe,
  65.                              const struct pipe_rasterizer_state *templ)
  66. {
  67.    struct svga_context *svga = svga_context(pipe);
  68.    struct svga_rasterizer_state *rast = CALLOC_STRUCT( svga_rasterizer_state );
  69.  
  70.    /* need this for draw module. */
  71.    rast->templ = *templ;
  72.  
  73.    /* light_twoside          - XXX: need fragment shader variant */
  74.    /* poly_smooth            - XXX: no fallback available */
  75.    /* poly_stipple_enable    - draw module */
  76.    /* sprite_coord_enable    - ? */
  77.    /* point_quad_rasterization - ? */
  78.    /* point_size_per_vertex  - ? */
  79.    /* sprite_coord_mode      - ??? */
  80.    /* flatshade_first        - handled by index translation */
  81.    /* half_pixel_center      - XXX - viewport code */
  82.    /* line_width             - draw module */
  83.    /* fill_cw, fill_ccw      - draw module or index translation */
  84.  
  85.    rast->shademode = svga_translate_flatshade( templ->flatshade );
  86.    rast->cullmode = svga_translate_cullmode( templ->cull_face,
  87.                                              templ->front_ccw );
  88.    rast->scissortestenable = templ->scissor;
  89.    rast->multisampleantialias = templ->multisample;
  90.    rast->antialiasedlineenable = templ->line_smooth;
  91.    rast->lastpixel = templ->line_last_pixel;
  92.    rast->pointsprite = templ->sprite_coord_enable != 0x0;
  93.    rast->pointsize = templ->point_size;
  94.    rast->hw_unfilled = PIPE_POLYGON_MODE_FILL;
  95.  
  96.    /* Use swtnl + decomposition implement these:
  97.     */
  98.    if (templ->poly_stipple_enable) {
  99.       rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
  100.       rast->need_pipeline_tris_str = "poly stipple";
  101.    }
  102.  
  103.    if (templ->line_width >= 1.5f &&
  104.        !svga->debug.no_line_width) {
  105.       rast->need_pipeline |= SVGA_PIPELINE_FLAG_LINES;
  106.       rast->need_pipeline_lines_str = "line width";
  107.    }
  108.  
  109.    if (templ->line_stipple_enable) {
  110.       /* XXX: LinePattern not implemented on all backends, and there is no
  111.        * mechanism to query it.
  112.        */
  113.       if (!svga->debug.force_hw_line_stipple) {
  114.          SVGA3dLinePattern lp;
  115.          lp.repeat = templ->line_stipple_factor + 1;
  116.          lp.pattern = templ->line_stipple_pattern;
  117.          rast->linepattern = lp.uintValue;
  118.       }
  119.       else {
  120.          rast->need_pipeline |= SVGA_PIPELINE_FLAG_LINES;
  121.          rast->need_pipeline_lines_str = "line stipple";
  122.       }
  123.    }
  124.  
  125.    if (templ->point_smooth) {
  126.       rast->need_pipeline |= SVGA_PIPELINE_FLAG_POINTS;
  127.       rast->need_pipeline_points_str = "smooth points";
  128.    }
  129.  
  130.    if (templ->line_smooth) {
  131.       rast->need_pipeline |= SVGA_PIPELINE_FLAG_LINES;
  132.       rast->need_pipeline_lines_str = "smooth lines";
  133.    }
  134.  
  135.    {
  136.       int fill_front = templ->fill_front;
  137.       int fill_back = templ->fill_back;
  138.       int fill = PIPE_POLYGON_MODE_FILL;
  139.       boolean offset_front = util_get_offset(templ, fill_front);
  140.       boolean offset_back = util_get_offset(templ, fill_back);
  141.       boolean offset  = 0;
  142.  
  143.       switch (templ->cull_face) {
  144.       case PIPE_FACE_FRONT_AND_BACK:
  145.          offset = 0;
  146.          fill = PIPE_POLYGON_MODE_FILL;
  147.          break;
  148.  
  149.       case PIPE_FACE_FRONT:
  150.          offset = offset_front;
  151.          fill = fill_front;
  152.          break;
  153.  
  154.       case PIPE_FACE_BACK:
  155.          offset = offset_back;
  156.          fill = fill_back;
  157.          break;
  158.  
  159.       case PIPE_FACE_NONE:
  160.          if (fill_front != fill_back || offset_front != offset_back)
  161.          {
  162.             /* Always need the draw module to work out different
  163.              * front/back fill modes:
  164.              */
  165.             rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
  166.             rast->need_pipeline_tris_str = "different front/back fillmodes";
  167.          }
  168.          else {
  169.             offset = offset_front;
  170.             fill = fill_front;
  171.          }
  172.          break;
  173.  
  174.       default:
  175.          assert(0);
  176.          break;
  177.       }
  178.  
  179.       /* Unfilled primitive modes aren't implemented on all virtual
  180.        * hardware.  We can do some unfilled processing with index
  181.        * translation, but otherwise need the draw module:
  182.        */
  183.       if (fill != PIPE_POLYGON_MODE_FILL &&
  184.           (templ->flatshade ||
  185.            templ->light_twoside ||
  186.            offset ||
  187.            templ->cull_face != PIPE_FACE_NONE))
  188.       {
  189.          fill = PIPE_POLYGON_MODE_FILL;
  190.          rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
  191.          rast->need_pipeline_tris_str = "unfilled primitives with no index manipulation";
  192.       }
  193.  
  194.       /* If we are decomposing to lines, and lines need the pipeline,
  195.        * then we also need the pipeline for tris.
  196.        */
  197.       if (fill == PIPE_POLYGON_MODE_LINE &&
  198.           (rast->need_pipeline & SVGA_PIPELINE_FLAG_LINES))
  199.       {
  200.          fill = PIPE_POLYGON_MODE_FILL;
  201.          rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
  202.          rast->need_pipeline_tris_str = "decomposing lines";
  203.       }
  204.  
  205.       /* Similarly for points:
  206.        */
  207.       if (fill == PIPE_POLYGON_MODE_POINT &&
  208.           (rast->need_pipeline & SVGA_PIPELINE_FLAG_POINTS))
  209.       {
  210.          fill = PIPE_POLYGON_MODE_FILL;
  211.          rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
  212.          rast->need_pipeline_tris_str = "decomposing points";
  213.       }
  214.  
  215.       if (offset) {
  216.          rast->slopescaledepthbias = templ->offset_scale;
  217.          rast->depthbias = templ->offset_units;
  218.       }
  219.  
  220.       rast->hw_unfilled = fill;
  221.    }
  222.  
  223.    if (rast->need_pipeline & SVGA_PIPELINE_FLAG_TRIS) {
  224.       /* Turn off stuff which will get done in the draw module:
  225.        */
  226.       rast->hw_unfilled = PIPE_POLYGON_MODE_FILL;
  227.       rast->slopescaledepthbias = 0;
  228.       rast->depthbias = 0;
  229.    }
  230.  
  231.    return rast;
  232. }
  233.  
  234. static void svga_bind_rasterizer_state( struct pipe_context *pipe,
  235.                                         void *state )
  236. {
  237.    struct svga_context *svga = svga_context(pipe);
  238.    struct svga_rasterizer_state *raster = (struct svga_rasterizer_state *)state;
  239.  
  240.  
  241.    draw_set_rasterizer_state(svga->swtnl.draw, raster ? &raster->templ : NULL,
  242.                              state);
  243.    svga->curr.rast = raster;
  244.  
  245.    svga->dirty |= SVGA_NEW_RAST;
  246. }
  247.  
  248. static void svga_delete_rasterizer_state(struct pipe_context *pipe,
  249.                                          void *raster)
  250. {
  251.    FREE(raster);
  252. }
  253.  
  254.  
  255. void svga_init_rasterizer_functions( struct svga_context *svga )
  256. {
  257.    svga->pipe.create_rasterizer_state = svga_create_rasterizer_state;
  258.    svga->pipe.bind_rasterizer_state = svga_bind_rasterizer_state;
  259.    svga->pipe.delete_rasterizer_state = svga_delete_rasterizer_state;
  260. }
  261.  
  262.  
  263. /***********************************************************************
  264.  * Hardware state update
  265.  */
  266.  
  267.