Beispiel #1
0
/* Overall we split things into:
 *     - frontend -- prepare fetch_elts, draw_elts - eg vcache
 *     - middle   -- fetch, shade, cliptest, viewport
 *     - pipeline -- the prim pipeline: clipping, wide lines, etc 
 *     - backend  -- the vbuf_render provided by the driver.
 */
static boolean
draw_pt_arrays(struct draw_context *draw, 
               unsigned prim,
               unsigned start, 
               unsigned count)
{
   struct draw_pt_front_end *frontend = NULL;
   struct draw_pt_middle_end *middle = NULL;
   unsigned opt = 0;

   /* Sanitize primitive length:
    */
   {
      unsigned first, incr;
      draw_pt_split_prim(prim, &first, &incr);
      count = trim(count, first, incr); 
      if (count < first)
         return TRUE;
   }


   if (!draw->render) {
      opt |= PT_PIPELINE;
   }

   if (draw_need_pipeline(draw,
                          draw->rasterizer,
                          prim)) {
      opt |= PT_PIPELINE;
   }

   if (!draw->bypass_clipping && !draw->pt.test_fse) {
      opt |= PT_CLIPTEST;
   }

   if (!draw->rasterizer->bypass_vs) {
      opt |= PT_SHADE;
   }


   if (opt == 0) 
      middle = draw->pt.middle.fetch_emit;
   else if (opt == PT_SHADE && !draw->pt.no_fse)
      middle = draw->pt.middle.fetch_shade_emit;
   else
      middle = draw->pt.middle.general;


   /* Pick the right frontend
    */
   if (draw->pt.user.elts || (opt & PT_PIPELINE)) {
      frontend = draw->pt.front.vcache;
   } else {
      frontend = draw->pt.front.varray;
   }

   frontend->prepare( frontend, prim, middle, opt );

   frontend->run(frontend, 
                 draw_pt_elt_func(draw),
                 draw_pt_elt_ptr(draw, start),
                 count);

   frontend->finish( frontend );

   return TRUE;
}
Beispiel #2
0
/* Overall we split things into:
 *     - frontend -- prepare fetch_elts, draw_elts - eg vsplit
 *     - middle   -- fetch, shade, cliptest, viewport
 *     - pipeline -- the prim pipeline: clipping, wide lines, etc 
 *     - backend  -- the vbuf_render provided by the driver.
 */
static boolean
draw_pt_arrays(struct draw_context *draw,
               unsigned prim,
               unsigned start, 
               unsigned count)
{
   struct draw_pt_front_end *frontend = NULL;
   struct draw_pt_middle_end *middle = NULL;
   unsigned opt = 0;

   /* Sanitize primitive length:
    */
   {
      unsigned first, incr;
      draw_pt_split_prim(prim, &first, &incr);
      count = draw_pt_trim_count(count, first, incr);
      if (count < first)
         return TRUE;
   }

   if (!draw->force_passthrough) {
      unsigned gs_out_prim = (draw->gs.geometry_shader ? 
                              draw->gs.geometry_shader->output_primitive :
                              prim);

      if (!draw->render) {
         opt |= PT_PIPELINE;
      }

      if (draw_need_pipeline(draw,
                             draw->rasterizer,
                             gs_out_prim)) {
         opt |= PT_PIPELINE;
      }

      if ((draw->clip_xy ||
           draw->clip_z ||
           draw->clip_user) && !draw->pt.test_fse) {
         opt |= PT_CLIPTEST;
      }

      opt |= PT_SHADE;
   }

   if (draw->pt.middle.llvm) {
      middle = draw->pt.middle.llvm;
   } else {
      if (opt == 0)
         middle = draw->pt.middle.fetch_emit;
      else if (opt == PT_SHADE && !draw->pt.no_fse)
         middle = draw->pt.middle.fetch_shade_emit;
      else
         middle = draw->pt.middle.general;
   }

   frontend = draw->pt.frontend;

   if (frontend ) {
      if (draw->pt.prim != prim || draw->pt.opt != opt) {
         /* In certain conditions switching primitives requires us to flush
          * and validate the different stages. One example is when smooth
          * lines are active but first drawn with triangles and then with
          * lines.
          */
         draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
         frontend = NULL;
      } else if (draw->pt.eltSize != draw->pt.user.eltSize) {
         /* Flush draw state if eltSize changed.
          * This could be improved so only the frontend is flushed since it
          * converts all indices to ushorts and the fetch part of the middle
          * always perpares both linear and indexed.
          */
         frontend->flush( frontend, DRAW_FLUSH_STATE_CHANGE );
         frontend = NULL;
      }
   }

   if (!frontend) {
      frontend = draw->pt.front.vsplit;

      frontend->prepare( frontend, prim, middle, opt );

      draw->pt.frontend = frontend;
      draw->pt.eltSize = draw->pt.user.eltSize;
      draw->pt.prim = prim;
      draw->pt.opt = opt;
   }

   frontend->run( frontend, start, count );

   return TRUE;
}