enum pipe_error
svga_hwtnl_draw_arrays( struct svga_hwtnl *hwtnl,
                        unsigned prim,
                        unsigned start,
                        unsigned count)
{
   unsigned gen_prim, gen_size, gen_nr, gen_type;
   u_generate_func gen_func;
   enum pipe_error ret = PIPE_OK;

   if (hwtnl->api_fillmode != PIPE_POLYGON_MODE_FILL &&
       prim >= PIPE_PRIM_TRIANGLES)
   {
      /* Convert unfilled polygons into points, lines, triangles */
      gen_type = u_unfilled_generator( prim,
                                       start,
                                       count,
                                       hwtnl->api_fillmode,
                                       &gen_prim,
                                       &gen_size,
                                       &gen_nr,
                                       &gen_func );
   }
   else {
      /* Convert PIPE_PRIM_LINE_LOOP to PIPE_PRIM_LINESTRIP,
       * convert PIPE_PRIM_POLYGON to PIPE_PRIM_TRIANGLE_FAN,
       * etc, if needed (as determined by svga_hw_prims mask).
       */
      gen_type = u_index_generator( svga_hw_prims,
                                    prim,
                                    start,
                                    count,
                                    hwtnl->api_pv,
                                    hwtnl->hw_pv,
                                    &gen_prim,
                                    &gen_size,
                                    &gen_nr,
                                    &gen_func );
   }

   if (gen_type == U_GENERATE_LINEAR) {
      return simple_draw_arrays( hwtnl, gen_prim, start, count );
   }
   else {
      struct pipe_resource *gen_buf = NULL;

      /* Need to draw as indexed primitive.
       * Potentially need to run the gen func to build an index buffer.
       */
      ret = retrieve_or_generate_indices( hwtnl,
                                          prim,
                                          gen_type,
                                          gen_nr,
                                          gen_size,
                                          gen_func,
                                          &gen_buf );
      if (ret != PIPE_OK)
         goto done;

      ret = svga_hwtnl_simple_draw_range_elements( hwtnl,
                                                   gen_buf,
                                                   gen_size,
                                                   start,
                                                   0,
                                                   count - 1,
                                                   gen_prim,
                                                   0,
                                                   gen_nr );

      if (ret != PIPE_OK)
         goto done;

   done:
      if (gen_buf)
         pipe_resource_reference( &gen_buf, NULL );

      return ret;
   }
}
enum pipe_error 
svga_hwtnl_draw_arrays( struct svga_hwtnl *hwtnl,
                        unsigned prim, 
                        unsigned start, 
                        unsigned count)
{
   unsigned gen_prim, gen_size, gen_nr, gen_type;
   u_generate_func gen_func;
   enum pipe_error ret = PIPE_OK;

   if (hwtnl->api_fillmode != PIPE_POLYGON_MODE_FILL && 
       prim >= PIPE_PRIM_TRIANGLES) 
   {
      gen_type = u_unfilled_generator( prim,
                                       start,
                                       count,
                                       hwtnl->api_fillmode,
                                       &gen_prim,
                                       &gen_size,
                                       &gen_nr,
                                       &gen_func );
   }
   else {
      gen_type = u_index_generator( svga_hw_prims,
                                    prim,
                                    start,
                                    count,
                                    hwtnl->api_pv,
                                    hwtnl->hw_pv,
                                    &gen_prim,
                                    &gen_size,
                                    &gen_nr,
                                    &gen_func );
   }

   if (gen_type == U_GENERATE_LINEAR) {
      return simple_draw_arrays( hwtnl, gen_prim, start, count );
   }
   else {
      struct pipe_buffer *gen_buf = NULL;

      /* Need to draw as indexed primitive. 
       * Potentially need to run the gen func to build an index buffer.
       */
      ret = retrieve_or_generate_indices( hwtnl,
                                          prim,
                                          gen_type,
                                          gen_nr,
                                          gen_size,
                                          gen_func,
                                          &gen_buf );
      if (ret)
         goto done;

      ret = svga_hwtnl_simple_draw_range_elements( hwtnl,
                                                   gen_buf,
                                                   gen_size,
                                                   0,
                                                   count - 1,
                                                   gen_prim,
                                                   0,
                                                   gen_nr,
                                                   start );
      if (ret)
         goto done;

   done:
      if (gen_buf)
         pipe_buffer_reference( &gen_buf, NULL );

      return ret;
   }
}
Exemple #3
0
enum pipe_error
svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl,
                               struct pipe_resource *index_buffer,
                               unsigned index_size, int index_bias,
                               unsigned min_index, unsigned max_index,
                               unsigned prim, unsigned start, unsigned count,
                               unsigned start_instance, unsigned instance_count)
{
   unsigned gen_prim, gen_size, gen_nr;
   enum indices_mode gen_type;
   u_translate_func gen_func;
   enum pipe_error ret = PIPE_OK;

   if (hwtnl->api_fillmode != PIPE_POLYGON_MODE_FILL &&
       prim >= PIPE_PRIM_TRIANGLES) {
      gen_type = u_unfilled_translator(prim,
                                       index_size,
                                       count,
                                       hwtnl->api_fillmode,
                                       &gen_prim,
                                       &gen_size, &gen_nr, &gen_func);
   }
   else {
      gen_type = u_index_translator(svga_hw_prims,
                                    prim,
                                    index_size,
                                    count,
                                    hwtnl->api_pv,
                                    hwtnl->hw_pv,
                                    PR_DISABLE,
                                    &gen_prim, &gen_size, &gen_nr, &gen_func);
   }

   if (gen_type == U_TRANSLATE_MEMCPY) {
      /* No need for translation, just pass through to hardware:
       */
      return svga_hwtnl_simple_draw_range_elements(hwtnl, index_buffer,
                                                   index_size,
                                                   index_bias,
                                                   min_index,
                                                   max_index,
                                                   gen_prim, start, count,
                                                   start_instance,
                                                   instance_count);
   }
   else {
      struct pipe_resource *gen_buf = NULL;

      /* Need to allocate a new index buffer and run the translate
       * func to populate it.  Could potentially cache this translated
       * index buffer with the original to avoid future
       * re-translations.  Not much point if we're just accelerating
       * GL though, as index buffers are typically used only once
       * there.
       */
      ret = translate_indices(hwtnl,
                              index_buffer,
                              start * index_size,
                              gen_prim, gen_nr, gen_size, gen_func, &gen_buf);
      if (ret != PIPE_OK)
         goto done;

      ret = svga_hwtnl_simple_draw_range_elements(hwtnl,
                                                  gen_buf,
                                                  gen_size,
                                                  index_bias,
                                                  min_index,
                                                  max_index,
                                                  gen_prim, 0, gen_nr,
                                                  start_instance,
                                                  instance_count);
      if (ret != PIPE_OK)
         goto done;

done:
      if (gen_buf)
         pipe_resource_reference(&gen_buf, NULL);

      return ret;
   }
}
Exemple #4
0
enum pipe_error
svga_hwtnl_draw_arrays(struct svga_hwtnl *hwtnl,
                       enum pipe_prim_type prim, unsigned start, unsigned count,
                       unsigned start_instance, unsigned instance_count)
{
   enum pipe_prim_type gen_prim;
   unsigned gen_size, gen_nr;
   enum indices_mode gen_type;
   u_generate_func gen_func;
   enum pipe_error ret = PIPE_OK;
   unsigned api_pv = hwtnl->api_pv;
   struct svga_context *svga = hwtnl->svga;

   if (svga->curr.rast->templ.fill_front !=
       svga->curr.rast->templ.fill_back) {
      assert(hwtnl->api_fillmode == PIPE_POLYGON_MODE_FILL);
   }

   if (svga->curr.rast->templ.flatshade &&
       svga->state.hw_draw.fs->constant_color_output) {
      /* The fragment color is a constant, not per-vertex so the whole
       * primitive will be the same color (except for possible blending).
       * We can ignore the current provoking vertex state and use whatever
       * the hardware wants.
       */
      api_pv = hwtnl->hw_pv;

      if (hwtnl->api_fillmode == PIPE_POLYGON_MODE_FILL) {
         /* Do some simple primitive conversions to avoid index buffer
          * generation below.  Note that polygons and quads are not directly
          * supported by the svga device.  Also note, we can only do this
          * for flat/constant-colored rendering because of provoking vertex.
          */
         if (prim == PIPE_PRIM_POLYGON) {
            prim = PIPE_PRIM_TRIANGLE_FAN;
         }
         else if (prim == PIPE_PRIM_QUADS && count == 4) {
            prim = PIPE_PRIM_TRIANGLE_FAN;
         }
      }
   }

   if (svga_need_unfilled_fallback(hwtnl, prim)) {
      /* Convert unfilled polygons into points, lines, triangles */
      gen_type = u_unfilled_generator(prim,
                                      start,
                                      count,
                                      hwtnl->api_fillmode,
                                      &gen_prim,
                                      &gen_size, &gen_nr, &gen_func);
   }
   else {
      /* Convert PIPE_PRIM_LINE_LOOP to PIPE_PRIM_LINESTRIP,
       * convert PIPE_PRIM_POLYGON to PIPE_PRIM_TRIANGLE_FAN,
       * etc, if needed (as determined by svga_hw_prims mask).
       */
      gen_type = u_index_generator(svga_hw_prims,
                                   prim,
                                   start,
                                   count,
                                   api_pv,
                                   hwtnl->hw_pv,
                                   &gen_prim, &gen_size, &gen_nr, &gen_func);
   }

   if (gen_type == U_GENERATE_LINEAR) {
      return simple_draw_arrays(hwtnl, gen_prim, start, count,
                                start_instance, instance_count);
   }
   else {
      struct pipe_resource *gen_buf = NULL;

      /* Need to draw as indexed primitive.
       * Potentially need to run the gen func to build an index buffer.
       */
      ret = retrieve_or_generate_indices(hwtnl,
                                         prim,
                                         gen_type,
                                         gen_nr,
                                         gen_size, gen_func, &gen_buf);
      if (ret != PIPE_OK)
         goto done;

      pipe_debug_message(&svga->debug.callback, PERF_INFO,
                         "generating temporary index buffer for drawing %s",
                         u_prim_name(prim));

      ret = svga_hwtnl_simple_draw_range_elements(hwtnl,
                                                  gen_buf,
                                                  gen_size,
                                                  start,
                                                  0,
                                                  count - 1,
                                                  gen_prim, 0, gen_nr,
                                                  start_instance,
                                                  instance_count);
      if (ret != PIPE_OK)
         goto done;

done:
      if (gen_buf)
         pipe_resource_reference(&gen_buf, NULL);

      return ret;
   }
}