Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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. #include "util/u_debug.h"
  27. #include "pipe/p_defines.h"
  28. #include "util/u_memory.h"
  29. #include "draw/draw_context.h"
  30.  
  31. #include "svga_context.h"
  32. #include "svga_screen.h"
  33. #include "svga_state.h"
  34. #include "svga_draw.h"
  35. #include "svga_cmd.h"
  36. #include "svga_hw_reg.h"
  37.  
  38. /* This is just enough to decide whether we need to use the draw
  39.  * module (swtnl) or not.
  40.  */
  41. static const struct svga_tracked_state *need_swtnl_state[] =
  42. {
  43.    &svga_update_need_swvfetch,
  44.    &svga_update_need_pipeline,
  45.    &svga_update_need_swtnl,
  46.    NULL
  47. };
  48.  
  49.  
  50. /* Atoms to update hardware state prior to emitting a clear or draw
  51.  * packet.
  52.  */
  53. static const struct svga_tracked_state *hw_clear_state[] =
  54. {
  55.    &svga_hw_scissor,
  56.    &svga_hw_viewport,
  57.    &svga_hw_framebuffer,
  58.    NULL
  59. };
  60.  
  61.  
  62. /* Atoms to update hardware state prior to emitting a draw packet.
  63.  */
  64. static const struct svga_tracked_state *hw_draw_state[] =
  65. {
  66.    &svga_hw_fs,
  67.    &svga_hw_vs,
  68.    &svga_hw_rss,
  69.    &svga_hw_tss,
  70.    &svga_hw_tss_binding,
  71.    &svga_hw_clip_planes,
  72.    &svga_hw_vdecl,
  73.    &svga_hw_fs_constants,
  74.    &svga_hw_vs_constants,
  75.    NULL
  76. };
  77.  
  78.  
  79. static const struct svga_tracked_state *swtnl_draw_state[] =
  80. {
  81.    &svga_update_swtnl_draw,
  82.    &svga_update_swtnl_vdecl,
  83.    NULL
  84. };
  85.  
  86. /* Flattens the graph of state dependencies.  Could swap the positions
  87.  * of hw_clear_state and need_swtnl_state without breaking anything.
  88.  */
  89. static const struct svga_tracked_state **state_levels[] =
  90. {
  91.    need_swtnl_state,
  92.    hw_clear_state,
  93.    hw_draw_state,
  94.    swtnl_draw_state
  95. };
  96.  
  97.  
  98.  
  99. static unsigned check_state( unsigned a,
  100.                              unsigned b )
  101. {
  102.    return (a & b);
  103. }
  104.  
  105. static void accumulate_state( unsigned *a,
  106.                               unsigned b )
  107. {
  108.    *a |= b;
  109. }
  110.  
  111.  
  112. static void xor_states( unsigned *result,
  113.                         unsigned a,
  114.                         unsigned b )
  115. {
  116.    *result = a ^ b;
  117. }
  118.  
  119.  
  120.  
  121. static enum pipe_error
  122. update_state(struct svga_context *svga,
  123.              const struct svga_tracked_state *atoms[],
  124.              unsigned *state)
  125. {
  126.    boolean debug = TRUE;
  127.    enum pipe_error ret = PIPE_OK;
  128.    unsigned i;
  129.  
  130.    ret = svga_hwtnl_flush( svga->hwtnl );
  131.    if (ret != PIPE_OK)
  132.       return ret;
  133.  
  134.    if (debug) {
  135.       /* Debug version which enforces various sanity checks on the
  136.        * state flags which are generated and checked to help ensure
  137.        * state atoms are ordered correctly in the list.
  138.        */
  139.       unsigned examined, prev;      
  140.  
  141.       examined = 0;
  142.       prev = *state;
  143.  
  144.       for (i = 0; atoms[i] != NULL; i++) {       
  145.          unsigned generated;
  146.  
  147.          assert(atoms[i]->dirty);
  148.          assert(atoms[i]->update);
  149.  
  150.          if (check_state(*state, atoms[i]->dirty)) {
  151.             if (0)
  152.                debug_printf("update: %s\n", atoms[i]->name);
  153.             ret = atoms[i]->update( svga, *state );
  154.             if (ret != PIPE_OK)
  155.                return ret;
  156.          }
  157.  
  158.          /* generated = (prev ^ state)
  159.           * if (examined & generated)
  160.           *     fail;
  161.           */
  162.          xor_states(&generated, prev, *state);
  163.          if (check_state(examined, generated)) {
  164.             debug_printf("state atom %s generated state already examined\n",
  165.                          atoms[i]->name);
  166.             assert(0);
  167.          }
  168.                          
  169.          prev = *state;
  170.          accumulate_state(&examined, atoms[i]->dirty);
  171.       }
  172.    }
  173.    else {
  174.       for (i = 0; atoms[i] != NULL; i++) {       
  175.          if (check_state(*state, atoms[i]->dirty)) {
  176.             ret = atoms[i]->update( svga, *state );
  177.             if (ret != PIPE_OK)
  178.                return ret;
  179.          }
  180.       }
  181.    }
  182.  
  183.    return PIPE_OK;
  184. }
  185.  
  186.  
  187.  
  188. enum pipe_error
  189. svga_update_state(struct svga_context *svga, unsigned max_level)
  190. {
  191.    struct svga_screen *screen = svga_screen(svga->pipe.screen);
  192.    enum pipe_error ret = PIPE_OK;
  193.    unsigned i;
  194.  
  195.    /* Check for updates to bound textures.  This can't be done in an
  196.     * atom as there is no flag which could provoke this test, and we
  197.     * cannot create one.
  198.     */
  199.    if (svga->state.texture_timestamp != screen->texture_timestamp) {
  200.       svga->state.texture_timestamp = screen->texture_timestamp;
  201.       svga->dirty |= SVGA_NEW_TEXTURE;
  202.    }
  203.  
  204.    for (i = 0; i <= max_level; i++) {
  205.       svga->dirty |= svga->state.dirty[i];
  206.  
  207.       if (svga->dirty) {
  208.          ret = update_state( svga,
  209.                              state_levels[i],
  210.                              &svga->dirty );
  211.          if (ret != PIPE_OK)
  212.             return ret;
  213.  
  214.          svga->state.dirty[i] = 0;
  215.       }
  216.    }
  217.    
  218.    for (; i < SVGA_STATE_MAX; i++)
  219.       svga->state.dirty[i] |= svga->dirty;
  220.  
  221.    svga->dirty = 0;
  222.    return PIPE_OK;
  223. }
  224.  
  225.  
  226.  
  227.  
  228. void svga_update_state_retry( struct svga_context *svga,
  229.                               unsigned max_level )
  230. {
  231.    enum pipe_error ret;
  232.  
  233.    ret = svga_update_state( svga, max_level );
  234.  
  235.    if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
  236.       svga_context_flush(svga, NULL);
  237.       ret = svga_update_state( svga, max_level );
  238.    }
  239.  
  240.    assert( ret == PIPE_OK );
  241. }
  242.  
  243.  
  244.  
  245. #define EMIT_RS(_rs, _count, _name, _value)     \
  246. do {                                            \
  247.    _rs[_count].state = _name;                   \
  248.    _rs[_count].uintValue = _value;              \
  249.    _count++;                                    \
  250. } while (0)
  251.  
  252.  
  253. /* Setup any hardware state which will be constant through the life of
  254.  * a context.
  255.  */
  256. enum pipe_error svga_emit_initial_state( struct svga_context *svga )
  257. {
  258.    SVGA3dRenderState *rs;
  259.    unsigned count = 0;
  260.    const unsigned COUNT = 2;
  261.    enum pipe_error ret;
  262.  
  263.    ret = SVGA3D_BeginSetRenderState( svga->swc, &rs, COUNT );
  264.    if (ret != PIPE_OK)
  265.       return ret;
  266.  
  267.    /* Always use D3D style coordinate space as this is the only one
  268.     * which is implemented on all backends.
  269.     */
  270.    EMIT_RS(rs, count, SVGA3D_RS_COORDINATETYPE, SVGA3D_COORDINATE_LEFTHANDED );
  271.    EMIT_RS(rs, count, SVGA3D_RS_FRONTWINDING, SVGA3D_FRONTWINDING_CW );
  272.    
  273.    assert( COUNT == count );
  274.    SVGA_FIFOCommitAll( svga->swc );
  275.  
  276.    return PIPE_OK;
  277. }
  278.