Subversion Repositories Kolibri OS

Rev

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.  
  27. #include "util/u_format.h"
  28. #include "util/u_inlines.h"
  29. #include "util/u_prim.h"
  30. #include "util/u_time.h"
  31. #include "indices/u_indices.h"
  32.  
  33. #include "svga_hw_reg.h"
  34. #include "svga_cmd.h"
  35. #include "svga_context.h"
  36. #include "svga_screen.h"
  37. #include "svga_draw.h"
  38. #include "svga_state.h"
  39. #include "svga_swtnl.h"
  40. #include "svga_debug.h"
  41. #include "svga_resource_buffer.h"
  42.  
  43.  
  44. static enum pipe_error
  45. retry_draw_range_elements( struct svga_context *svga,
  46.                            struct pipe_resource *index_buffer,
  47.                            unsigned index_size,
  48.                            int index_bias,
  49.                            unsigned min_index,
  50.                            unsigned max_index,
  51.                            unsigned prim,
  52.                            unsigned start,
  53.                            unsigned count,
  54.                            unsigned instance_count,
  55.                            boolean do_retry )
  56. {
  57.    enum pipe_error ret = PIPE_OK;
  58.  
  59.    svga_hwtnl_set_unfilled( svga->hwtnl,
  60.                             svga->curr.rast->hw_unfilled );
  61.  
  62.    svga_hwtnl_set_flatshade( svga->hwtnl,
  63.                              svga->curr.rast->templ.flatshade,
  64.                              svga->curr.rast->templ.flatshade_first );
  65.  
  66.    ret = svga_update_state( svga, SVGA_STATE_HW_DRAW );
  67.    if (ret != PIPE_OK)
  68.       goto retry;
  69.  
  70.    ret = svga_hwtnl_draw_range_elements( svga->hwtnl,
  71.                                          index_buffer, index_size, index_bias,
  72.                                          min_index, max_index,
  73.                                          prim, start, count );
  74.    if (ret != PIPE_OK)
  75.       goto retry;
  76.  
  77.    return PIPE_OK;
  78.  
  79. retry:
  80.    svga_context_flush( svga, NULL );
  81.  
  82.    if (do_retry)
  83.    {
  84.       return retry_draw_range_elements( svga,
  85.                                         index_buffer, index_size, index_bias,
  86.                                         min_index, max_index,
  87.                                         prim, start, count,
  88.                                         instance_count, FALSE );
  89.    }
  90.  
  91.    return ret;
  92. }
  93.  
  94.  
  95. static enum pipe_error
  96. retry_draw_arrays( struct svga_context *svga,
  97.                    unsigned prim,
  98.                    unsigned start,
  99.                    unsigned count,
  100.                    unsigned instance_count,
  101.                    boolean do_retry )
  102. {
  103.    enum pipe_error ret;
  104.  
  105.    svga_hwtnl_set_unfilled( svga->hwtnl,
  106.                             svga->curr.rast->hw_unfilled );
  107.  
  108.    svga_hwtnl_set_flatshade( svga->hwtnl,
  109.                              svga->curr.rast->templ.flatshade,
  110.                              svga->curr.rast->templ.flatshade_first );
  111.  
  112.    ret = svga_update_state( svga, SVGA_STATE_HW_DRAW );
  113.    if (ret != PIPE_OK)
  114.       goto retry;
  115.  
  116.    ret = svga_hwtnl_draw_arrays( svga->hwtnl, prim,
  117.                                  start, count );
  118.    if (ret != PIPE_OK)
  119.       goto retry;
  120.  
  121.    return PIPE_OK;
  122.  
  123. retry:
  124.    if (ret == PIPE_ERROR_OUT_OF_MEMORY && do_retry)
  125.    {
  126.       svga_context_flush( svga, NULL );
  127.  
  128.       return retry_draw_arrays( svga,
  129.                                 prim,
  130.                                 start,
  131.                                 count,
  132.                                 instance_count,
  133.                                 FALSE );
  134.    }
  135.  
  136.    return ret;
  137. }
  138.  
  139.  
  140. static void
  141. svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
  142. {
  143.    struct svga_context *svga = svga_context( pipe );
  144.    unsigned reduced_prim = u_reduced_prim( info->mode );
  145.    unsigned count = info->count;
  146.    enum pipe_error ret = 0;
  147.    boolean needed_swtnl;
  148.  
  149.    svga->num_draw_calls++;  /* for SVGA_QUERY_DRAW_CALLS */
  150.  
  151.    if (!u_trim_pipe_prim( info->mode, &count ))
  152.       return;
  153.  
  154.    /*
  155.     * Mark currently bound target surfaces as dirty
  156.     * doesn't really matter if it is done before drawing.
  157.     *
  158.     * TODO If we ever normaly return something other then
  159.     * true we should not mark it as dirty then.
  160.     */
  161.    svga_mark_surfaces_dirty(svga_context(pipe));
  162.  
  163.    if (svga->curr.reduced_prim != reduced_prim) {
  164.       svga->curr.reduced_prim = reduced_prim;
  165.       svga->dirty |= SVGA_NEW_REDUCED_PRIMITIVE;
  166.    }
  167.  
  168.    needed_swtnl = svga->state.sw.need_swtnl;
  169.  
  170.    svga_update_state_retry( svga, SVGA_STATE_NEED_SWTNL );
  171.  
  172. #ifdef DEBUG
  173.    if (svga->curr.vs->base.id == svga->debug.disable_shader ||
  174.        svga->curr.fs->base.id == svga->debug.disable_shader)
  175.       return;
  176. #endif
  177.  
  178.    if (svga->state.sw.need_swtnl) {
  179.       svga->num_fallbacks++;  /* for SVGA_QUERY_FALLBACKS */
  180.       if (!needed_swtnl) {
  181.          /*
  182.           * We're switching from HW to SW TNL.  SW TNL will require mapping all
  183.           * currently bound vertex buffers, some of which may already be
  184.           * referenced in the current command buffer as result of previous HW
  185.           * TNL. So flush now, to prevent the context to flush while a referred
  186.           * vertex buffer is mapped.
  187.           */
  188.  
  189.          svga_context_flush(svga, NULL);
  190.       }
  191.  
  192.       /* Avoid leaking the previous hwtnl bias to swtnl */
  193.       svga_hwtnl_set_index_bias( svga->hwtnl, 0 );
  194.       ret = svga_swtnl_draw_vbo( svga, info );
  195.    }
  196.    else {
  197.       if (info->indexed && svga->curr.ib.buffer) {
  198.          unsigned offset;
  199.  
  200.          assert(svga->curr.ib.offset % svga->curr.ib.index_size == 0);
  201.          offset = svga->curr.ib.offset / svga->curr.ib.index_size;
  202.  
  203.          ret = retry_draw_range_elements( svga,
  204.                                           svga->curr.ib.buffer,
  205.                                           svga->curr.ib.index_size,
  206.                                           info->index_bias,
  207.                                           info->min_index,
  208.                                           info->max_index,
  209.                                           info->mode,
  210.                                           info->start + offset,
  211.                                           info->count,
  212.                                           info->instance_count,
  213.                                           TRUE );
  214.       }
  215.       else {
  216.          ret = retry_draw_arrays( svga,
  217.                                   info->mode,
  218.                                   info->start,
  219.                                   info->count,
  220.                                   info->instance_count,
  221.                                   TRUE );
  222.       }
  223.    }
  224.  
  225.    /* XXX: Silence warnings, do something sensible here? */
  226.    (void)ret;
  227.  
  228.    if (SVGA_DEBUG & DEBUG_FLUSH) {
  229.       svga_hwtnl_flush_retry( svga );
  230.       svga_context_flush(svga, NULL);
  231.    }
  232. }
  233.  
  234.  
  235. void svga_init_draw_functions( struct svga_context *svga )
  236. {
  237.    svga->pipe.draw_vbo = svga_draw_vbo;
  238. }
  239.