Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | 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. /**
  29.  * Interface between 'draw' module's output and the llvmpipe rasterizer/setup
  30.  * code.  When the 'draw' module has finished filling a vertex buffer, the
  31.  * draw_arrays() functions below will be called.  Loop over the vertices and
  32.  * call the point/line/tri setup functions.
  33.  *
  34.  * Authors
  35.  *  Brian Paul
  36.  */
  37.  
  38.  
  39. #include "lp_setup_context.h"
  40. #include "lp_context.h"
  41. #include "draw/draw_vbuf.h"
  42. #include "draw/draw_vertex.h"
  43. #include "util/u_memory.h"
  44.  
  45.  
  46. #define LP_MAX_VBUF_INDEXES 1024
  47. #define LP_MAX_VBUF_SIZE    4096
  48.  
  49.  
  50.  
  51. /** cast wrapper */
  52. static struct lp_setup_context *
  53. lp_setup_context(struct vbuf_render *vbr)
  54. {
  55.    return (struct lp_setup_context *) vbr;
  56. }
  57.  
  58.  
  59.  
  60. static const struct vertex_info *
  61. lp_setup_get_vertex_info(struct vbuf_render *vbr)
  62. {
  63.    struct lp_setup_context *setup = lp_setup_context(vbr);
  64.  
  65.    /* Vertex size/info depends on the latest state.
  66.     * The draw module may have issued additional state-change commands.
  67.     */
  68.    lp_setup_update_state(setup, FALSE);
  69.  
  70.    return setup->vertex_info;
  71. }
  72.  
  73.  
  74. static boolean
  75. lp_setup_allocate_vertices(struct vbuf_render *vbr,
  76.                           ushort vertex_size, ushort nr_vertices)
  77. {
  78.    struct lp_setup_context *setup = lp_setup_context(vbr);
  79.    unsigned size = vertex_size * nr_vertices;
  80.  
  81.    if (setup->vertex_buffer_size < size) {
  82.       align_free(setup->vertex_buffer);
  83.       setup->vertex_buffer = align_malloc(size, 16);
  84.       setup->vertex_buffer_size = size;
  85.    }
  86.  
  87.    setup->vertex_size = vertex_size;
  88.    setup->nr_vertices = nr_vertices;
  89.    
  90.    return setup->vertex_buffer != NULL;
  91. }
  92.  
  93. static void
  94. lp_setup_release_vertices(struct vbuf_render *vbr)
  95. {
  96.    /* keep the old allocation for next time */
  97. }
  98.  
  99. static void *
  100. lp_setup_map_vertices(struct vbuf_render *vbr)
  101. {
  102.    struct lp_setup_context *setup = lp_setup_context(vbr);
  103.    return setup->vertex_buffer;
  104. }
  105.  
  106. static void
  107. lp_setup_unmap_vertices(struct vbuf_render *vbr,
  108.                        ushort min_index,
  109.                        ushort max_index )
  110. {
  111.    struct lp_setup_context *setup = lp_setup_context(vbr);
  112.    assert( setup->vertex_buffer_size >= (max_index+1) * setup->vertex_size );
  113.    /* do nothing */
  114. }
  115.  
  116.  
  117. static void
  118. lp_setup_set_primitive(struct vbuf_render *vbr, unsigned prim)
  119. {
  120.    lp_setup_context(vbr)->prim = prim;
  121. }
  122.  
  123. typedef const float (*const_float4_ptr)[4];
  124.  
  125. static INLINE const_float4_ptr get_vert( const void *vertex_buffer,
  126.                                          int index,
  127.                                          int stride )
  128. {
  129.    return (const_float4_ptr)((char *)vertex_buffer + index * stride);
  130. }
  131.  
  132. /**
  133.  * draw elements / indexed primitives
  134.  */
  135. static void
  136. lp_setup_draw_elements(struct vbuf_render *vbr, const ushort *indices, uint nr)
  137. {
  138.    struct lp_setup_context *setup = lp_setup_context(vbr);
  139.    const unsigned stride = setup->vertex_info->size * sizeof(float);
  140.    const void *vertex_buffer = setup->vertex_buffer;
  141.    const boolean flatshade_first = setup->flatshade_first;
  142.    unsigned i;
  143.  
  144.    assert(setup->setup.variant);
  145.  
  146.    if (!lp_setup_update_state(setup, TRUE))
  147.       return;
  148.  
  149.    switch (setup->prim) {
  150.    case PIPE_PRIM_POINTS:
  151.       for (i = 0; i < nr; i++) {
  152.          setup->point( setup,
  153.                        get_vert(vertex_buffer, indices[i-0], stride) );
  154.       }
  155.       break;
  156.  
  157.    case PIPE_PRIM_LINES:
  158.       for (i = 1; i < nr; i += 2) {
  159.          setup->line( setup,
  160.                       get_vert(vertex_buffer, indices[i-1], stride),
  161.                       get_vert(vertex_buffer, indices[i-0], stride) );
  162.       }
  163.       break;
  164.  
  165.    case PIPE_PRIM_LINE_STRIP:
  166.       for (i = 1; i < nr; i ++) {
  167.          setup->line( setup,
  168.                       get_vert(vertex_buffer, indices[i-1], stride),
  169.                       get_vert(vertex_buffer, indices[i-0], stride) );
  170.       }
  171.       break;
  172.  
  173.    case PIPE_PRIM_LINE_LOOP:
  174.       for (i = 1; i < nr; i ++) {
  175.          setup->line( setup,
  176.                       get_vert(vertex_buffer, indices[i-1], stride),
  177.                       get_vert(vertex_buffer, indices[i-0], stride) );
  178.       }
  179.       if (nr) {
  180.          setup->line( setup,
  181.                       get_vert(vertex_buffer, indices[nr-1], stride),
  182.                       get_vert(vertex_buffer, indices[0], stride) );
  183.       }
  184.       break;
  185.  
  186.    case PIPE_PRIM_TRIANGLES:
  187.       for (i = 2; i < nr; i += 3) {
  188.          setup->triangle( setup,
  189.                           get_vert(vertex_buffer, indices[i-2], stride),
  190.                           get_vert(vertex_buffer, indices[i-1], stride),
  191.                           get_vert(vertex_buffer, indices[i-0], stride) );
  192.       }
  193.       break;
  194.  
  195.    case PIPE_PRIM_TRIANGLE_STRIP:
  196.       if (flatshade_first) {
  197.          for (i = 2; i < nr; i += 1) {
  198.             /* emit first triangle vertex as first triangle vertex */
  199.             setup->triangle( setup,
  200.                              get_vert(vertex_buffer, indices[i-2], stride),
  201.                              get_vert(vertex_buffer, indices[i+(i&1)-1], stride),
  202.                              get_vert(vertex_buffer, indices[i-(i&1)], stride) );
  203.  
  204.          }
  205.       }
  206.       else {
  207.          for (i = 2; i < nr; i += 1) {
  208.             /* emit last triangle vertex as last triangle vertex */
  209.             setup->triangle( setup,
  210.                              get_vert(vertex_buffer, indices[i+(i&1)-2], stride),
  211.                              get_vert(vertex_buffer, indices[i-(i&1)-1], stride),
  212.                              get_vert(vertex_buffer, indices[i-0], stride) );
  213.          }
  214.       }
  215.       break;
  216.  
  217.    case PIPE_PRIM_TRIANGLE_FAN:
  218.       if (flatshade_first) {
  219.          for (i = 2; i < nr; i += 1) {
  220.             /* emit first non-spoke vertex as first vertex */
  221.             setup->triangle( setup,
  222.                              get_vert(vertex_buffer, indices[i-1], stride),
  223.                              get_vert(vertex_buffer, indices[i-0], stride),
  224.                              get_vert(vertex_buffer, indices[0], stride) );
  225.          }
  226.       }
  227.       else {
  228.          for (i = 2; i < nr; i += 1) {
  229.             /* emit last non-spoke vertex as last vertex */
  230.             setup->triangle( setup,
  231.                              get_vert(vertex_buffer, indices[0], stride),
  232.                              get_vert(vertex_buffer, indices[i-1], stride),
  233.                              get_vert(vertex_buffer, indices[i-0], stride) );
  234.          }
  235.       }
  236.       break;
  237.  
  238.    case PIPE_PRIM_QUADS:
  239.       /* GL quads don't follow provoking vertex convention */
  240.       if (flatshade_first) {
  241.          /* emit last quad vertex as first triangle vertex */
  242.          for (i = 3; i < nr; i += 4) {
  243.             setup->triangle( setup,
  244.                              get_vert(vertex_buffer, indices[i-0], stride),
  245.                              get_vert(vertex_buffer, indices[i-3], stride),
  246.                              get_vert(vertex_buffer, indices[i-2], stride) );
  247.  
  248.             setup->triangle( setup,
  249.                              get_vert(vertex_buffer, indices[i-0], stride),
  250.                              get_vert(vertex_buffer, indices[i-2], stride),
  251.                              get_vert(vertex_buffer, indices[i-1], stride) );
  252.          }
  253.       }
  254.       else {
  255.          /* emit last quad vertex as last triangle vertex */
  256.          for (i = 3; i < nr; i += 4) {
  257.             setup->triangle( setup,
  258.                           get_vert(vertex_buffer, indices[i-3], stride),
  259.                           get_vert(vertex_buffer, indices[i-2], stride),
  260.                           get_vert(vertex_buffer, indices[i-0], stride) );
  261.  
  262.             setup->triangle( setup,
  263.                              get_vert(vertex_buffer, indices[i-2], stride),
  264.                              get_vert(vertex_buffer, indices[i-1], stride),
  265.                              get_vert(vertex_buffer, indices[i-0], stride) );
  266.          }
  267.       }
  268.       break;
  269.  
  270.    case PIPE_PRIM_QUAD_STRIP:
  271.       /* GL quad strips don't follow provoking vertex convention */
  272.       if (flatshade_first) {
  273.          /* emit last quad vertex as first triangle vertex */
  274.          for (i = 3; i < nr; i += 2) {
  275.             setup->triangle( setup,
  276.                              get_vert(vertex_buffer, indices[i-0], stride),
  277.                              get_vert(vertex_buffer, indices[i-3], stride),
  278.                              get_vert(vertex_buffer, indices[i-2], stride) );
  279.             setup->triangle( setup,
  280.                              get_vert(vertex_buffer, indices[i-0], stride),
  281.                              get_vert(vertex_buffer, indices[i-1], stride),
  282.                              get_vert(vertex_buffer, indices[i-3], stride) );
  283.          }
  284.       }
  285.       else {
  286.          /* emit last quad vertex as last triangle vertex */
  287.          for (i = 3; i < nr; i += 2) {
  288.             setup->triangle( setup,
  289.                              get_vert(vertex_buffer, indices[i-3], stride),
  290.                              get_vert(vertex_buffer, indices[i-2], stride),
  291.                              get_vert(vertex_buffer, indices[i-0], stride) );
  292.             setup->triangle( setup,
  293.                              get_vert(vertex_buffer, indices[i-1], stride),
  294.                              get_vert(vertex_buffer, indices[i-3], stride),
  295.                              get_vert(vertex_buffer, indices[i-0], stride) );
  296.          }
  297.       }
  298.       break;
  299.  
  300.    case PIPE_PRIM_POLYGON:
  301.       /* Almost same as tri fan but the _first_ vertex specifies the flat
  302.        * shading color.
  303.        */
  304.       if (flatshade_first) {
  305.          /* emit first polygon  vertex as first triangle vertex */
  306.          for (i = 2; i < nr; i += 1) {
  307.             setup->triangle( setup,
  308.                              get_vert(vertex_buffer, indices[0], stride),
  309.                              get_vert(vertex_buffer, indices[i-1], stride),
  310.                              get_vert(vertex_buffer, indices[i-0], stride) );
  311.          }
  312.       }
  313.       else {
  314.          /* emit first polygon  vertex as last triangle vertex */
  315.          for (i = 2; i < nr; i += 1) {
  316.             setup->triangle( setup,
  317.                              get_vert(vertex_buffer, indices[i-1], stride),
  318.                              get_vert(vertex_buffer, indices[i-0], stride),
  319.                              get_vert(vertex_buffer, indices[0], stride) );
  320.          }
  321.       }
  322.       break;
  323.  
  324.    default:
  325.       assert(0);
  326.    }
  327. }
  328.  
  329.  
  330. /**
  331.  * This function is hit when the draw module is working in pass-through mode.
  332.  * It's up to us to convert the vertex array into point/line/tri prims.
  333.  */
  334. static void
  335. lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
  336. {
  337.    struct lp_setup_context *setup = lp_setup_context(vbr);
  338.    const unsigned stride = setup->vertex_info->size * sizeof(float);
  339.    const void *vertex_buffer =
  340.       (void *) get_vert(setup->vertex_buffer, start, stride);
  341.    const boolean flatshade_first = setup->flatshade_first;
  342.    unsigned i;
  343.  
  344.    if (!lp_setup_update_state(setup, TRUE))
  345.       return;
  346.  
  347.    switch (setup->prim) {
  348.    case PIPE_PRIM_POINTS:
  349.       for (i = 0; i < nr; i++) {
  350.          setup->point( setup,
  351.                        get_vert(vertex_buffer, i-0, stride) );
  352.       }
  353.       break;
  354.  
  355.    case PIPE_PRIM_LINES:
  356.       for (i = 1; i < nr; i += 2) {
  357.          setup->line( setup,
  358.                       get_vert(vertex_buffer, i-1, stride),
  359.                       get_vert(vertex_buffer, i-0, stride) );
  360.       }
  361.       break;
  362.  
  363.    case PIPE_PRIM_LINE_STRIP:
  364.       for (i = 1; i < nr; i ++) {
  365.          setup->line( setup,
  366.                       get_vert(vertex_buffer, i-1, stride),
  367.                       get_vert(vertex_buffer, i-0, stride) );
  368.       }
  369.       break;
  370.  
  371.    case PIPE_PRIM_LINE_LOOP:
  372.       for (i = 1; i < nr; i ++) {
  373.          setup->line( setup,
  374.                       get_vert(vertex_buffer, i-1, stride),
  375.                       get_vert(vertex_buffer, i-0, stride) );
  376.       }
  377.       if (nr) {
  378.          setup->line( setup,
  379.                       get_vert(vertex_buffer, nr-1, stride),
  380.                       get_vert(vertex_buffer, 0, stride) );
  381.       }
  382.       break;
  383.  
  384.    case PIPE_PRIM_TRIANGLES:
  385.       for (i = 2; i < nr; i += 3) {
  386.          setup->triangle( setup,
  387.                           get_vert(vertex_buffer, i-2, stride),
  388.                           get_vert(vertex_buffer, i-1, stride),
  389.                           get_vert(vertex_buffer, i-0, stride) );
  390.       }
  391.       break;
  392.  
  393.    case PIPE_PRIM_TRIANGLE_STRIP:
  394.       if (flatshade_first) {
  395.          for (i = 2; i < nr; i++) {
  396.             /* emit first triangle vertex as first triangle vertex */
  397.             setup->triangle( setup,
  398.                              get_vert(vertex_buffer, i-2, stride),
  399.                              get_vert(vertex_buffer, i+(i&1)-1, stride),
  400.                              get_vert(vertex_buffer, i-(i&1), stride) );
  401.          }
  402.       }
  403.       else {
  404.          for (i = 2; i < nr; i++) {
  405.             /* emit last triangle vertex as last triangle vertex */
  406.             setup->triangle( setup,
  407.                              get_vert(vertex_buffer, i+(i&1)-2, stride),
  408.                              get_vert(vertex_buffer, i-(i&1)-1, stride),
  409.                              get_vert(vertex_buffer, i-0, stride) );
  410.          }
  411.       }
  412.       break;
  413.  
  414.    case PIPE_PRIM_TRIANGLE_FAN:
  415.       if (flatshade_first) {
  416.          for (i = 2; i < nr; i += 1) {
  417.             /* emit first non-spoke vertex as first vertex */
  418.             setup->triangle( setup,
  419.                              get_vert(vertex_buffer, i-1, stride),
  420.                              get_vert(vertex_buffer, i-0, stride),
  421.                              get_vert(vertex_buffer, 0, stride)  );
  422.          }
  423.       }
  424.       else {
  425.          for (i = 2; i < nr; i += 1) {
  426.             /* emit last non-spoke vertex as last vertex */
  427.             setup->triangle( setup,
  428.                              get_vert(vertex_buffer, 0, stride),
  429.                              get_vert(vertex_buffer, i-1, stride),
  430.                              get_vert(vertex_buffer, i-0, stride) );
  431.          }
  432.       }
  433.       break;
  434.  
  435.    case PIPE_PRIM_QUADS:
  436.       /* GL quads don't follow provoking vertex convention */
  437.       if (flatshade_first) {
  438.          /* emit last quad vertex as first triangle vertex */
  439.          for (i = 3; i < nr; i += 4) {
  440.             setup->triangle( setup,
  441.                              get_vert(vertex_buffer, i-0, stride),
  442.                              get_vert(vertex_buffer, i-3, stride),
  443.                              get_vert(vertex_buffer, i-2, stride) );
  444.             setup->triangle( setup,
  445.                              get_vert(vertex_buffer, i-0, stride),
  446.                              get_vert(vertex_buffer, i-2, stride),
  447.                              get_vert(vertex_buffer, i-1, stride) );
  448.          }
  449.       }
  450.       else {
  451.          /* emit last quad vertex as last triangle vertex */
  452.          for (i = 3; i < nr; i += 4) {
  453.             setup->triangle( setup,
  454.                              get_vert(vertex_buffer, i-3, stride),
  455.                              get_vert(vertex_buffer, i-2, stride),
  456.                              get_vert(vertex_buffer, i-0, stride) );
  457.             setup->triangle( setup,
  458.                              get_vert(vertex_buffer, i-2, stride),
  459.                              get_vert(vertex_buffer, i-1, stride),
  460.                              get_vert(vertex_buffer, i-0, stride) );
  461.          }
  462.       }
  463.       break;
  464.  
  465.    case PIPE_PRIM_QUAD_STRIP:
  466.       /* GL quad strips don't follow provoking vertex convention */
  467.       if (flatshade_first) {
  468.          /* emit last quad vertex as first triangle vertex */
  469.          for (i = 3; i < nr; i += 2) {
  470.             setup->triangle( setup,
  471.                              get_vert(vertex_buffer, i-0, stride),
  472.                              get_vert(vertex_buffer, i-3, stride),
  473.                              get_vert(vertex_buffer, i-2, stride) );
  474.             setup->triangle( setup,
  475.                              get_vert(vertex_buffer, i-0, stride),
  476.                              get_vert(vertex_buffer, i-1, stride),
  477.                              get_vert(vertex_buffer, i-3, stride) );
  478.          }
  479.       }
  480.       else {
  481.          /* emit last quad vertex as last triangle vertex */
  482.          for (i = 3; i < nr; i += 2) {
  483.             setup->triangle( setup,
  484.                              get_vert(vertex_buffer, i-3, stride),
  485.                              get_vert(vertex_buffer, i-2, stride),
  486.                              get_vert(vertex_buffer, i-0, stride) );
  487.             setup->triangle( setup,
  488.                              get_vert(vertex_buffer, i-1, stride),
  489.                              get_vert(vertex_buffer, i-3, stride),
  490.                              get_vert(vertex_buffer, i-0, stride) );
  491.          }
  492.       }
  493.       break;
  494.  
  495.    case PIPE_PRIM_POLYGON:
  496.       /* Almost same as tri fan but the _first_ vertex specifies the flat
  497.        * shading color.
  498.        */
  499.       if (flatshade_first) {
  500.          /* emit first polygon  vertex as first triangle vertex */
  501.          for (i = 2; i < nr; i += 1) {
  502.             setup->triangle( setup,
  503.                              get_vert(vertex_buffer, 0, stride),
  504.                              get_vert(vertex_buffer, i-1, stride),
  505.                              get_vert(vertex_buffer, i-0, stride) );
  506.          }
  507.       }
  508.       else {
  509.          /* emit first polygon  vertex as last triangle vertex */
  510.          for (i = 2; i < nr; i += 1) {
  511.             setup->triangle( setup,
  512.                              get_vert(vertex_buffer, i-1, stride),
  513.                              get_vert(vertex_buffer, i-0, stride),
  514.                              get_vert(vertex_buffer, 0, stride) );
  515.          }
  516.       }
  517.       break;
  518.  
  519.    default:
  520.       assert(0);
  521.    }
  522. }
  523.  
  524.  
  525.  
  526. static void
  527. lp_setup_vbuf_destroy(struct vbuf_render *vbr)
  528. {
  529.    struct lp_setup_context *setup = lp_setup_context(vbr);
  530.    if (setup->vertex_buffer) {
  531.       align_free(setup->vertex_buffer);
  532.       setup->vertex_buffer = NULL;
  533.    }
  534.    lp_setup_destroy(setup);
  535. }
  536.  
  537. static void
  538. lp_setup_so_info(struct vbuf_render *vbr, uint primitives, uint vertices,
  539.                 uint prim_generated)
  540. {
  541.    struct lp_setup_context *setup = lp_setup_context(vbr);
  542.    struct llvmpipe_context *lp = llvmpipe_context(setup->pipe);
  543.  
  544.    lp->so_stats.num_primitives_written += primitives;
  545.    lp->so_stats.primitives_storage_needed =
  546.       vertices * 4 /*sizeof(float|int32)*/ * 4 /*x,y,z,w*/;
  547.    lp->num_primitives_generated += prim_generated;
  548. }
  549.  
  550. static void
  551. lp_setup_pipeline_statistics(
  552.    struct vbuf_render *vbr,
  553.    const struct pipe_query_data_pipeline_statistics *stats)
  554. {
  555.    struct lp_setup_context *setup = lp_setup_context(vbr);
  556.    struct llvmpipe_context *llvmpipe = llvmpipe_context(setup->pipe);
  557.  
  558.    llvmpipe->pipeline_statistics.ia_vertices +=
  559.       stats->ia_vertices;
  560.    llvmpipe->pipeline_statistics.ia_primitives +=
  561.       stats->ia_primitives;
  562.    llvmpipe->pipeline_statistics.vs_invocations +=
  563.       stats->vs_invocations;
  564.    llvmpipe->pipeline_statistics.gs_invocations +=
  565.       stats->gs_invocations;
  566.    llvmpipe->pipeline_statistics.gs_primitives +=
  567.       stats->gs_primitives;
  568.    llvmpipe->pipeline_statistics.c_invocations +=
  569.       stats->c_invocations;
  570. }
  571.  
  572. /**
  573.  * Create the post-transform vertex handler for the given context.
  574.  */
  575. void
  576. lp_setup_init_vbuf(struct lp_setup_context *setup)
  577. {
  578.    setup->base.max_indices = LP_MAX_VBUF_INDEXES;
  579.    setup->base.max_vertex_buffer_bytes = LP_MAX_VBUF_SIZE;
  580.  
  581.    setup->base.get_vertex_info = lp_setup_get_vertex_info;
  582.    setup->base.allocate_vertices = lp_setup_allocate_vertices;
  583.    setup->base.map_vertices = lp_setup_map_vertices;
  584.    setup->base.unmap_vertices = lp_setup_unmap_vertices;
  585.    setup->base.set_primitive = lp_setup_set_primitive;
  586.    setup->base.draw_elements = lp_setup_draw_elements;
  587.    setup->base.draw_arrays = lp_setup_draw_arrays;
  588.    setup->base.release_vertices = lp_setup_release_vertices;
  589.    setup->base.destroy = lp_setup_vbuf_destroy;
  590.    setup->base.set_stream_output_info = lp_setup_so_info;
  591.    setup->base.pipeline_statistics = lp_setup_pipeline_statistics;
  592. }
  593.