gallium/radeon: stop using "reloc" in a few places
[mesa.git] / src / gallium / drivers / radeonsi / si_hw_context.c
index 313ced7f5d1990b1711659d834717a9665a8fb5c..de95d12f000a65aab7426853cd04969198deeb66 100644 (file)
 #include "si_pipe.h"
 
 /* initialize */
-void si_need_cs_space(struct si_context *ctx, unsigned num_dw,
-                       boolean count_draw_in)
+void si_need_cs_space(struct si_context *ctx)
 {
-       int i;
-
-       /* The number of dwords we already used in the CS so far. */
-       num_dw += ctx->b.rings.gfx.cs->cdw;
-
-       if (count_draw_in) {
-               for (i = 0; i < SI_NUM_ATOMS(ctx); i++) {
-                       if (ctx->atoms.array[i]->dirty) {
-                               num_dw += ctx->atoms.array[i]->num_dw;
-                       }
-               }
-
-               /* The number of dwords all the dirty states would take. */
-               num_dw += si_pm4_dirty_dw(ctx);
-
-               /* The upper-bound of how much a draw command would take. */
-               num_dw += SI_MAX_DRAW_CS_DWORDS;
-       }
-
-       /* Count in queries_suspend. */
-       num_dw += ctx->b.num_cs_dw_nontimer_queries_suspend;
-
-       /* Count in streamout_end at the end of CS. */
-       if (ctx->b.streamout.begin_emitted) {
-               num_dw += ctx->b.streamout.num_dw_for_end;
-       }
-
-       /* Count in render_condition(NULL) at the end of CS. */
-       if (ctx->b.predicate_drawing) {
-               num_dw += 3;
-       }
-
-       /* Count in framebuffer cache flushes at the end of CS. */
-       num_dw += ctx->atoms.s.cache_flush->num_dw;
+       struct radeon_winsys_cs *cs = ctx->b.rings.gfx.cs;
 
-#if SI_TRACE_CS
-       if (ctx->screen->b.trace_bo) {
-               num_dw += SI_TRACE_CS_DWORDS;
+       /* There are two memory usage counters in the winsys for all buffers
+        * that have been added (cs_add_buffer) and two counters in the pipe
+        * driver for those that haven't been added yet.
+        */
+       if (unlikely(!ctx->b.ws->cs_memory_below_limit(ctx->b.rings.gfx.cs,
+                                                      ctx->b.vram, ctx->b.gtt))) {
+               ctx->b.gtt = 0;
+               ctx->b.vram = 0;
+               ctx->b.rings.gfx.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
+               return;
        }
-#endif
+       ctx->b.gtt = 0;
+       ctx->b.vram = 0;
 
-       /* Flush if there's not enough space. */
-       if (num_dw > RADEON_MAX_CMDBUF_DWORDS) {
+       /* If the CS is sufficiently large, don't count the space needed
+        * and just flush if there is not enough space left.
+        */
+       if (unlikely(cs->cdw > cs->max_dw - 2048))
                ctx->b.rings.gfx.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
-       }
 }
 
 void si_context_gfx_flush(void *context, unsigned flags,
@@ -82,9 +57,16 @@ void si_context_gfx_flush(void *context, unsigned flags,
 {
        struct si_context *ctx = context;
        struct radeon_winsys_cs *cs = ctx->b.rings.gfx.cs;
-
-       if (cs->cdw == ctx->b.initial_gfx_cs_size && !fence)
+       struct radeon_winsys *ws = ctx->b.ws;
+
+       if (cs->cdw == ctx->b.initial_gfx_cs_size &&
+           (!fence || ctx->last_gfx_fence)) {
+               if (fence)
+                       ws->fence_reference(fence, ctx->last_gfx_fence);
+               if (!(flags & RADEON_FLUSH_ASYNC))
+                       ws->cs_sync_flush(cs);
                return;
+       }
 
        ctx->b.rings.gfx.flushing = true;
 
@@ -95,42 +77,61 @@ void si_context_gfx_flush(void *context, unsigned flags,
                        SI_CONTEXT_INV_TC_L2 |
                        /* this is probably not needed anymore */
                        SI_CONTEXT_PS_PARTIAL_FLUSH;
-       si_emit_cache_flush(&ctx->b, NULL);
+       si_emit_cache_flush(ctx, NULL);
 
        /* force to keep tiling flags */
        flags |= RADEON_FLUSH_KEEP_TILING_FLAGS;
 
+       if (ctx->trace_buf)
+               si_trace_emit(ctx);
+
+       /* Save the IB for debug contexts. */
+       if (ctx->is_debug) {
+               free(ctx->last_ib);
+               ctx->last_ib_dw_size = cs->cdw;
+               ctx->last_ib = malloc(cs->cdw * 4);
+               memcpy(ctx->last_ib, cs->buf, cs->cdw * 4);
+               r600_resource_reference(&ctx->last_trace_buf, ctx->trace_buf);
+               r600_resource_reference(&ctx->trace_buf, NULL);
+       }
+
        /* Flush the CS. */
-       ctx->b.ws->cs_flush(cs, flags, fence, ctx->screen->b.cs_count++);
+       ws->cs_flush(cs, flags, &ctx->last_gfx_fence,
+                    ctx->screen->b.cs_count++);
        ctx->b.rings.gfx.flushing = false;
 
-#if SI_TRACE_CS
-       if (ctx->screen->b.trace_bo) {
-               struct si_screen *sscreen = ctx->screen;
-               unsigned i;
-
-               for (i = 0; i < 10; i++) {
-                       usleep(5);
-                       if (!ctx->b.ws->buffer_is_busy(sscreen->b.trace_bo->buf, RADEON_USAGE_READWRITE)) {
-                               break;
-                       }
-               }
-               if (i == 10) {
-                       fprintf(stderr, "timeout on cs lockup likely happen at cs %d dw %d\n",
-                               sscreen->b.trace_ptr[1], sscreen->b.trace_ptr[0]);
-               } else {
-                       fprintf(stderr, "cs %d executed in %dms\n", sscreen->b.trace_ptr[1], i * 5);
-               }
-       }
-#endif
+       if (fence)
+               ws->fence_reference(fence, ctx->last_gfx_fence);
+
+       /* Check VM faults if needed. */
+       if (ctx->screen->b.debug_flags & DBG_CHECK_VM)
+               si_check_vm_faults(ctx);
 
        si_begin_new_cs(ctx);
 }
 
 void si_begin_new_cs(struct si_context *ctx)
 {
+       if (ctx->is_debug) {
+               uint32_t zero = 0;
+
+               /* Create a buffer used for writing trace IDs and initialize it to 0. */
+               assert(!ctx->trace_buf);
+               ctx->trace_buf = (struct r600_resource*)
+                                pipe_buffer_create(ctx->b.b.screen, PIPE_BIND_CUSTOM,
+                                                   PIPE_USAGE_STAGING, 4);
+               if (ctx->trace_buf)
+                       pipe_buffer_write_nooverlap(&ctx->b.b, &ctx->trace_buf->b.b,
+                                                   0, sizeof(zero), &zero);
+               ctx->trace_id = 0;
+       }
+
+       if (ctx->trace_buf)
+               si_trace_emit(ctx);
+
        /* Flush read caches at the beginning of CS. */
-       ctx->b.flags |= SI_CONTEXT_INV_TC_L1 |
+       ctx->b.flags |= SI_CONTEXT_FLUSH_AND_INV_FRAMEBUFFER |
+                       SI_CONTEXT_INV_TC_L1 |
                        SI_CONTEXT_INV_TC_L2 |
                        SI_CONTEXT_INV_KCACHE |
                        SI_CONTEXT_INV_ICACHE;
@@ -143,24 +144,46 @@ void si_begin_new_cs(struct si_context *ctx)
        /* The CS initialization should be emitted before everything else. */
        si_pm4_emit(ctx, ctx->init_config);
 
-       ctx->clip_regs.dirty = true;
-       ctx->framebuffer.atom.dirty = true;
-       ctx->msaa_sample_locs.dirty = true;
-       ctx->msaa_config.dirty = true;
-       ctx->db_render_state.dirty = true;
-       ctx->b.streamout.enable_atom.dirty = true;
+       ctx->framebuffer.dirty_cbufs = (1 << 8) - 1;
+       ctx->framebuffer.dirty_zsbuf = true;
+       si_mark_atom_dirty(ctx, &ctx->framebuffer.atom);
+
+       si_mark_atom_dirty(ctx, &ctx->clip_regs);
+       si_mark_atom_dirty(ctx, &ctx->clip_state.atom);
+       si_mark_atom_dirty(ctx, &ctx->msaa_sample_locs);
+       si_mark_atom_dirty(ctx, &ctx->msaa_config);
+       si_mark_atom_dirty(ctx, &ctx->sample_mask.atom);
+       si_mark_atom_dirty(ctx, &ctx->cb_target_mask);
+       si_mark_atom_dirty(ctx, &ctx->blend_color.atom);
+       si_mark_atom_dirty(ctx, &ctx->db_render_state);
+       si_mark_atom_dirty(ctx, &ctx->stencil_ref.atom);
+       si_mark_atom_dirty(ctx, &ctx->spi_map);
+       si_mark_atom_dirty(ctx, &ctx->b.streamout.enable_atom);
        si_all_descriptors_begin_new_cs(ctx);
 
+       ctx->scissors.dirty_mask = (1 << SI_MAX_VIEWPORTS) - 1;
+       ctx->viewports.dirty_mask = (1 << SI_MAX_VIEWPORTS) - 1;
+       si_mark_atom_dirty(ctx, &ctx->scissors.atom);
+       si_mark_atom_dirty(ctx, &ctx->viewports.atom);
+
        r600_postflush_resume_features(&ctx->b);
 
        ctx->b.initial_gfx_cs_size = ctx->b.rings.gfx.cs->cdw;
+
+       /* Invalidate various draw states so that they are emitted before
+        * the first draw call. */
        si_invalidate_draw_sh_constants(ctx);
        ctx->last_primitive_restart_en = -1;
        ctx->last_restart_index = SI_RESTART_INDEX_UNKNOWN;
        ctx->last_gs_out_prim = -1;
        ctx->last_prim = -1;
        ctx->last_multi_vgt_param = -1;
+       ctx->last_ls_hs_config = -1;
        ctx->last_rast_prim = -1;
        ctx->last_sc_line_stipple = ~0;
        ctx->emit_scratch_reloc = true;
+       ctx->last_ls = NULL;
+       ctx->last_tcs = NULL;
+       ctx->last_tes_sh_base = -1;
+       ctx->last_num_tcs_input_cp = -1;
 }