"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/gallium/auxiliary/draw/draw_pipe.c" (16 Sep 2020, 11865 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "draw_pipe.c" see the Fossies "Dox" file reference documentation.

    1 /**************************************************************************
    2  * 
    3  * Copyright 2007 VMware, Inc.
    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 VMWARE 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 <keithw@vmware.com>
   31   */
   32 
   33 #include "draw/draw_private.h"
   34 #include "draw/draw_pipe.h"
   35 #include "util/u_debug.h"
   36 #include "util/u_math.h"
   37 
   38 
   39 
   40 boolean draw_pipeline_init( struct draw_context *draw )
   41 {
   42    /* create pipeline stages */
   43    draw->pipeline.wide_line  = draw_wide_line_stage( draw );
   44    draw->pipeline.wide_point = draw_wide_point_stage( draw );
   45    draw->pipeline.stipple   = draw_stipple_stage( draw );
   46    draw->pipeline.unfilled  = draw_unfilled_stage( draw );
   47    draw->pipeline.twoside   = draw_twoside_stage( draw );
   48    draw->pipeline.offset    = draw_offset_stage( draw );
   49    draw->pipeline.clip      = draw_clip_stage( draw );
   50    draw->pipeline.flatshade = draw_flatshade_stage( draw );
   51    draw->pipeline.cull      = draw_cull_stage( draw );
   52    draw->pipeline.user_cull = draw_user_cull_stage( draw );
   53    draw->pipeline.validate  = draw_validate_stage( draw );
   54    draw->pipeline.first     = draw->pipeline.validate;
   55 
   56    if (!draw->pipeline.wide_line ||
   57        !draw->pipeline.wide_point ||
   58        !draw->pipeline.stipple ||
   59        !draw->pipeline.unfilled ||
   60        !draw->pipeline.twoside ||
   61        !draw->pipeline.offset ||
   62        !draw->pipeline.clip ||
   63        !draw->pipeline.flatshade ||
   64        !draw->pipeline.cull ||
   65        !draw->pipeline.user_cull ||
   66        !draw->pipeline.validate)
   67       return FALSE;
   68 
   69    /* these defaults are oriented toward the needs of softpipe */
   70    draw->pipeline.wide_point_threshold = 1000000.0f; /* infinity */
   71    draw->pipeline.wide_line_threshold = 1.0f;
   72    draw->pipeline.wide_point_sprites = FALSE;
   73    draw->pipeline.line_stipple = TRUE;
   74    draw->pipeline.point_sprite = TRUE;
   75 
   76    return TRUE;
   77 }
   78 
   79 
   80 void draw_pipeline_destroy( struct draw_context *draw )
   81 {
   82    if (draw->pipeline.wide_line)
   83       draw->pipeline.wide_line->destroy( draw->pipeline.wide_line );
   84    if (draw->pipeline.wide_point)
   85       draw->pipeline.wide_point->destroy( draw->pipeline.wide_point );
   86    if (draw->pipeline.stipple)
   87       draw->pipeline.stipple->destroy( draw->pipeline.stipple );
   88    if (draw->pipeline.unfilled)
   89       draw->pipeline.unfilled->destroy( draw->pipeline.unfilled );
   90    if (draw->pipeline.twoside)
   91       draw->pipeline.twoside->destroy( draw->pipeline.twoside );
   92    if (draw->pipeline.offset)
   93       draw->pipeline.offset->destroy( draw->pipeline.offset );
   94    if (draw->pipeline.clip)
   95       draw->pipeline.clip->destroy( draw->pipeline.clip );
   96    if (draw->pipeline.flatshade)
   97       draw->pipeline.flatshade->destroy( draw->pipeline.flatshade );
   98    if (draw->pipeline.cull)
   99       draw->pipeline.cull->destroy( draw->pipeline.cull );
  100    if (draw->pipeline.user_cull)
  101       draw->pipeline.user_cull->destroy( draw->pipeline.user_cull );
  102    if (draw->pipeline.validate)
  103       draw->pipeline.validate->destroy( draw->pipeline.validate );
  104    if (draw->pipeline.aaline)
  105       draw->pipeline.aaline->destroy( draw->pipeline.aaline );
  106    if (draw->pipeline.aapoint)
  107       draw->pipeline.aapoint->destroy( draw->pipeline.aapoint );
  108    if (draw->pipeline.pstipple)
  109       draw->pipeline.pstipple->destroy( draw->pipeline.pstipple );
  110    if (draw->pipeline.rasterize)
  111       draw->pipeline.rasterize->destroy( draw->pipeline.rasterize );
  112 }
  113 
  114 
  115 
  116 /**
  117  * Build primitive to render a point with vertex at v0.
  118  */
  119 static void do_point( struct draw_context *draw,
  120               const char *v0 )
  121 {
  122    struct prim_header prim;
  123    
  124    prim.flags = 0;
  125    prim.pad = 0;
  126    prim.v[0] = (struct vertex_header *)v0;
  127 
  128    draw->pipeline.first->point( draw->pipeline.first, &prim );
  129 }
  130 
  131 
  132 /**
  133  * Build primitive to render a line with vertices at v0, v1.
  134  * \param flags  bitmask of DRAW_PIPE_EDGE_x, DRAW_PIPE_RESET_STIPPLE
  135  */
  136 static void do_line( struct draw_context *draw,
  137                      ushort flags,
  138              const char *v0,
  139              const char *v1 )
  140 {
  141    struct prim_header prim;
  142    
  143    prim.flags = flags;
  144    prim.pad = 0;
  145    prim.v[0] = (struct vertex_header *)v0;
  146    prim.v[1] = (struct vertex_header *)v1;
  147 
  148    draw->pipeline.first->line( draw->pipeline.first, &prim );
  149 }
  150 
  151 
  152 /**
  153  * Build primitive to render a triangle with vertices at v0, v1, v2.
  154  * \param flags  bitmask of DRAW_PIPE_EDGE_x, DRAW_PIPE_RESET_STIPPLE
  155  */
  156 static void do_triangle( struct draw_context *draw,
  157                          ushort flags,
  158              char *v0,
  159              char *v1,
  160              char *v2 )
  161 {
  162    struct prim_header prim;
  163    
  164    prim.v[0] = (struct vertex_header *)v0;
  165    prim.v[1] = (struct vertex_header *)v1;
  166    prim.v[2] = (struct vertex_header *)v2;
  167    prim.flags = flags;
  168    prim.pad = 0;
  169 
  170    draw->pipeline.first->tri( draw->pipeline.first, &prim );
  171 }
  172 
  173 
  174 /*
  175  * Set up macros for draw_pt_decompose.h template code.
  176  * This code uses vertex indexes / elements.
  177  */
  178 
  179 #define TRIANGLE(flags,i0,i1,i2)                                  \
  180    do {                                                           \
  181       do_triangle( draw,                                          \
  182                    flags,                                         \
  183                    verts + stride * (i0),                         \
  184                    verts + stride * (i1),                         \
  185                    verts + stride * (i2) );                       \
  186    } while (0)
  187 
  188 #define LINE(flags,i0,i1)                                         \
  189    do {                                                           \
  190       do_line( draw,                                              \
  191                flags,                                             \
  192                verts + stride * (i0),                             \
  193                verts + stride * (i1) );                           \
  194    } while (0)
  195 
  196 #define POINT(i0)                               \
  197    do {                                         \
  198       do_point( draw, verts + stride * (i0) );  \
  199    } while (0)
  200 
  201 #define GET_ELT(idx) (MIN2(elts[idx], max_index))
  202 
  203 #define FUNC pipe_run_elts
  204 #define FUNC_VARS                               \
  205     struct draw_context *draw,                  \
  206     unsigned prim,                              \
  207     unsigned prim_flags,                        \
  208     struct vertex_header *vertices,             \
  209     unsigned stride,                            \
  210     const ushort *elts,                         \
  211     unsigned count,                             \
  212     unsigned max_index
  213 
  214 #include "draw_pt_decompose.h"
  215 
  216 
  217 
  218 /**
  219  * Code to run the pipeline on a fairly arbitrary collection of vertices.
  220  * For drawing indexed primitives.
  221  *
  222  * Vertex headers must be pre-initialized with the
  223  * UNDEFINED_VERTEX_ID, this code will cause that id to become
  224  * overwritten, so it may have to be reset if there is the intention
  225  * to reuse the vertices.
  226  *
  227  * This code provides a callback to reset the vertex id's which the
  228  * draw_vbuf.c code uses when it has to perform a flush.
  229  */
  230 void draw_pipeline_run( struct draw_context *draw,
  231                         const struct draw_vertex_info *vert_info,
  232                         const struct draw_prim_info *prim_info)
  233 {
  234    unsigned i, start;
  235 
  236    draw->pipeline.verts = (char *)vert_info->verts;
  237    draw->pipeline.vertex_stride = vert_info->stride;
  238    draw->pipeline.vertex_count = vert_info->count;
  239 
  240    for (start = i = 0;
  241         i < prim_info->primitive_count;
  242         start += prim_info->primitive_lengths[i], i++)
  243    {
  244       const unsigned count = prim_info->primitive_lengths[i];
  245 
  246 #if DEBUG
  247       /* Warn if one of the element indexes go outside the vertex buffer */
  248       {
  249          unsigned max_index = 0x0, i;
  250          /* find the largest element index */
  251          for (i = 0; i < count; i++) {
  252             unsigned int index = prim_info->elts[start + i];
  253             if (index > max_index)
  254                max_index = index;
  255          }
  256          if (max_index >= vert_info->count) {
  257             debug_printf("%s: max_index (%u) outside vertex buffer (%u)\n",
  258                          __FUNCTION__,
  259                          max_index,
  260                          vert_info->count);
  261          }
  262       }
  263 #endif
  264 
  265       pipe_run_elts(draw,
  266                     prim_info->prim,
  267                     prim_info->flags,
  268                     vert_info->verts,
  269                     vert_info->stride,
  270                     prim_info->elts + start,
  271                     count,
  272                     vert_info->count - 1);
  273    }
  274 
  275    draw->pipeline.verts = NULL;
  276    draw->pipeline.vertex_count = 0;
  277 }
  278 
  279 
  280 /*
  281  * Set up macros for draw_pt_decompose.h template code.
  282  * This code is for non-indexed (aka linear) rendering (no elts).
  283  */
  284 
  285 #define TRIANGLE(flags,i0,i1,i2)       \
  286    do_triangle( draw, flags,           \
  287                 verts + stride * (i0), \
  288                 verts + stride * (i1), \
  289                 verts + stride * (i2) )
  290 
  291 #define LINE(flags,i0,i1)              \
  292    do_line( draw, flags,               \
  293             verts + stride * (i0),     \
  294             verts + stride * (i1) )
  295 
  296 #define POINT(i0)                      \
  297    do_point( draw, verts + stride * (i0) )
  298 
  299 
  300 #define GET_ELT(idx) (idx)
  301 
  302 #define FUNC pipe_run_linear
  303 #define FUNC_VARS                      \
  304     struct draw_context *draw,         \
  305     unsigned prim,                     \
  306     unsigned prim_flags,               \
  307     struct vertex_header *vertices,    \
  308     unsigned stride,                   \
  309     unsigned count
  310 
  311 #include "draw_pt_decompose.h"
  312 
  313 
  314 /*
  315  * For drawing non-indexed primitives.
  316  */
  317 void draw_pipeline_run_linear( struct draw_context *draw,
  318                                const struct draw_vertex_info *vert_info,
  319                                const struct draw_prim_info *prim_info)
  320 {
  321    unsigned i, start;
  322 
  323    for (start = i = 0;
  324         i < prim_info->primitive_count;
  325         start += prim_info->primitive_lengths[i], i++)
  326    {
  327       unsigned count = prim_info->primitive_lengths[i];
  328       char *verts = ((char*)vert_info->verts) +
  329                     (start * vert_info->stride);
  330 
  331       draw->pipeline.verts = verts;
  332       draw->pipeline.vertex_stride = vert_info->stride;
  333       draw->pipeline.vertex_count = count;
  334 
  335       assert(count <= vert_info->count);
  336 
  337       pipe_run_linear(draw,
  338                       prim_info->prim,
  339                       prim_info->flags,
  340                       (struct vertex_header*)verts,
  341                       vert_info->stride,
  342                       count);
  343    }
  344 
  345    draw->pipeline.verts = NULL;
  346    draw->pipeline.vertex_count = 0;
  347 }
  348 
  349 
  350 void draw_pipeline_flush( struct draw_context *draw, 
  351                           unsigned flags )
  352 {
  353    draw->pipeline.first->flush( draw->pipeline.first, flags );
  354    if (flags & DRAW_FLUSH_STATE_CHANGE)
  355       draw->pipeline.first = draw->pipeline.validate;
  356 }