Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * on the rights to use, copy, modify, merge, publish, distribute, sub
  8.  * license, and/or sell copies of the Software, and to permit persons to whom
  9.  * the Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  18.  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  19.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  20.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  21.  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  22.  *
  23.  * Authors:
  24.  *      Jerome Glisse
  25.  */
  26.  
  27. #include "si_pipe.h"
  28.  
  29. /* initialize */
  30. void si_need_cs_space(struct si_context *ctx, unsigned num_dw,
  31.                         boolean count_draw_in)
  32. {
  33.         int i;
  34.  
  35.         /* The number of dwords we already used in the CS so far. */
  36.         num_dw += ctx->b.rings.gfx.cs->cdw;
  37.  
  38.         if (count_draw_in) {
  39.                 for (i = 0; i < SI_NUM_ATOMS(ctx); i++) {
  40.                         if (ctx->atoms.array[i]->dirty) {
  41.                                 num_dw += ctx->atoms.array[i]->num_dw;
  42.                         }
  43.                 }
  44.  
  45.                 /* The number of dwords all the dirty states would take. */
  46.                 num_dw += si_pm4_dirty_dw(ctx);
  47.  
  48.                 /* The upper-bound of how much a draw command would take. */
  49.                 num_dw += SI_MAX_DRAW_CS_DWORDS;
  50.         }
  51.  
  52.         /* Count in queries_suspend. */
  53.         num_dw += ctx->b.num_cs_dw_nontimer_queries_suspend;
  54.  
  55.         /* Count in streamout_end at the end of CS. */
  56.         if (ctx->b.streamout.begin_emitted) {
  57.                 num_dw += ctx->b.streamout.num_dw_for_end;
  58.         }
  59.  
  60.         /* Count in render_condition(NULL) at the end of CS. */
  61.         if (ctx->b.predicate_drawing) {
  62.                 num_dw += 3;
  63.         }
  64.  
  65.         /* Count in framebuffer cache flushes at the end of CS. */
  66.         num_dw += ctx->atoms.s.cache_flush->num_dw;
  67.  
  68. #if SI_TRACE_CS
  69.         if (ctx->screen->b.trace_bo) {
  70.                 num_dw += SI_TRACE_CS_DWORDS;
  71.         }
  72. #endif
  73.  
  74.         /* Flush if there's not enough space. */
  75.         if (num_dw > RADEON_MAX_CMDBUF_DWORDS) {
  76.                 ctx->b.rings.gfx.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
  77.         }
  78. }
  79.  
  80. void si_context_gfx_flush(void *context, unsigned flags,
  81.                           struct pipe_fence_handle **fence)
  82. {
  83.         struct si_context *ctx = context;
  84.         struct radeon_winsys_cs *cs = ctx->b.rings.gfx.cs;
  85.  
  86.         if (cs->cdw == ctx->b.initial_gfx_cs_size && !fence)
  87.                 return;
  88.  
  89.         ctx->b.rings.gfx.flushing = true;
  90.  
  91.         r600_preflush_suspend_features(&ctx->b);
  92.  
  93.         ctx->b.flags |= SI_CONTEXT_FLUSH_AND_INV_FRAMEBUFFER |
  94.                         SI_CONTEXT_INV_TC_L1 |
  95.                         SI_CONTEXT_INV_TC_L2 |
  96.                         /* this is probably not needed anymore */
  97.                         SI_CONTEXT_PS_PARTIAL_FLUSH;
  98.         si_emit_cache_flush(&ctx->b, NULL);
  99.  
  100.         /* force to keep tiling flags */
  101.         flags |= RADEON_FLUSH_KEEP_TILING_FLAGS;
  102.  
  103.         /* Flush the CS. */
  104.         ctx->b.ws->cs_flush(cs, flags, fence, ctx->screen->b.cs_count++);
  105.         ctx->b.rings.gfx.flushing = false;
  106.  
  107. #if SI_TRACE_CS
  108.         if (ctx->screen->b.trace_bo) {
  109.                 struct si_screen *sscreen = ctx->screen;
  110.                 unsigned i;
  111.  
  112.                 for (i = 0; i < 10; i++) {
  113.                         usleep(5);
  114.                         if (!ctx->b.ws->buffer_is_busy(sscreen->b.trace_bo->buf, RADEON_USAGE_READWRITE)) {
  115.                                 break;
  116.                         }
  117.                 }
  118.                 if (i == 10) {
  119.                         fprintf(stderr, "timeout on cs lockup likely happen at cs %d dw %d\n",
  120.                                 sscreen->b.trace_ptr[1], sscreen->b.trace_ptr[0]);
  121.                 } else {
  122.                         fprintf(stderr, "cs %d executed in %dms\n", sscreen->b.trace_ptr[1], i * 5);
  123.                 }
  124.         }
  125. #endif
  126.  
  127.         si_begin_new_cs(ctx);
  128. }
  129.  
  130. void si_begin_new_cs(struct si_context *ctx)
  131. {
  132.         /* Flush read caches at the beginning of CS. */
  133.         ctx->b.flags |= SI_CONTEXT_INV_TC_L1 |
  134.                         SI_CONTEXT_INV_TC_L2 |
  135.                         SI_CONTEXT_INV_KCACHE |
  136.                         SI_CONTEXT_INV_ICACHE;
  137.  
  138.         /* set all valid group as dirty so they get reemited on
  139.          * next draw command
  140.          */
  141.         si_pm4_reset_emitted(ctx);
  142.  
  143.         /* The CS initialization should be emitted before everything else. */
  144.         si_pm4_emit(ctx, ctx->init_config);
  145.  
  146.         ctx->clip_regs.dirty = true;
  147.         ctx->framebuffer.atom.dirty = true;
  148.         ctx->msaa_sample_locs.dirty = true;
  149.         ctx->msaa_config.dirty = true;
  150.         ctx->db_render_state.dirty = true;
  151.         ctx->b.streamout.enable_atom.dirty = true;
  152.         si_all_descriptors_begin_new_cs(ctx);
  153.  
  154.         r600_postflush_resume_features(&ctx->b);
  155.  
  156.         ctx->b.initial_gfx_cs_size = ctx->b.rings.gfx.cs->cdw;
  157.         si_invalidate_draw_sh_constants(ctx);
  158.         ctx->last_primitive_restart_en = -1;
  159.         ctx->last_restart_index = SI_RESTART_INDEX_UNKNOWN;
  160.         ctx->last_gs_out_prim = -1;
  161.         ctx->last_prim = -1;
  162.         ctx->last_multi_vgt_param = -1;
  163.         ctx->last_rast_prim = -1;
  164.         ctx->last_sc_line_stipple = ~0;
  165.         ctx->emit_scratch_reloc = true;
  166. }
  167.