gallium/radeon: stop using "reloc" in a few places
[mesa.git] / src / gallium / drivers / radeonsi / si_hw_context.c
index eaefa6a40e9e4c2173732d8cc9a05b95f780e3df..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 += ctx->pm4_dirty_cdwords;
-
-               /* 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,73 +57,84 @@ 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;
 
        r600_preflush_suspend_features(&ctx->b);
 
-       ctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_CB |
-                       R600_CONTEXT_FLUSH_AND_INV_CB_META |
-                       R600_CONTEXT_FLUSH_AND_INV_DB |
-                       R600_CONTEXT_FLUSH_AND_INV_DB_META |
-                       R600_CONTEXT_INV_TEX_CACHE |
+       ctx->b.flags |= SI_CONTEXT_FLUSH_AND_INV_FRAMEBUFFER |
+                       SI_CONTEXT_INV_TC_L1 |
+                       SI_CONTEXT_INV_TC_L2 |
                        /* this is probably not needed anymore */
-                       R600_CONTEXT_PS_PARTIAL_FLUSH;
-       si_emit_cache_flush(&ctx->b, NULL);
+                       SI_CONTEXT_PS_PARTIAL_FLUSH;
+       si_emit_cache_flush(ctx, NULL);
 
        /* force to keep tiling flags */
        flags |= RADEON_FLUSH_KEEP_TILING_FLAGS;
 
-#if SI_TRACE_CS
-       if (ctx->screen->b.trace_bo) {
-               struct si_screen *sscreen = ctx->screen;
-               unsigned i;
-
-               for (i = 0; i < cs->cdw; i++) {
-                       fprintf(stderr, "[%4d] [%5d] 0x%08x\n", sscreen->b.cs_count, i, cs->buf[i]);
-               }
-               sscreen->b.cs_count++;
+       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);
        }
-#endif
 
        /* Flush the CS. */
-       ctx->b.ws->cs_flush(cs, flags, fence, 0);
+       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->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)
 {
-       ctx->pm4_dirty_cdwords = 0;
+       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 |= R600_CONTEXT_INV_TEX_CACHE |
-                       R600_CONTEXT_INV_CONST_CACHE |
-                       R600_CONTEXT_INV_SHADER_CACHE;
+       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;
 
        /* set all valid group as dirty so they get reemited on
         * next draw command
@@ -156,36 +142,48 @@ void si_begin_new_cs(struct si_context *ctx)
        si_pm4_reset_emitted(ctx);
 
        /* The CS initialization should be emitted before everything else. */
-       si_pm4_emit(ctx, ctx->queued.named.init);
-       ctx->emitted.named.init = ctx->queued.named.init;
-
-       ctx->framebuffer.atom.dirty = true;
-       ctx->msaa_config.dirty = true;
-       ctx->db_render_state.dirty = true;
-       ctx->b.streamout.enable_atom.dirty = true;
+       si_pm4_emit(ctx, ctx->init_config);
+
+       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;
-}
 
-#if SI_TRACE_CS
-void si_trace_emit(struct si_context *sctx)
-{
-       struct si_screen *sscreen = sctx->screen;
-       struct radeon_winsys_cs *cs = sctx->cs;
-       uint64_t va;
-
-       va = sscreen->b.trace_bo->gpu_address;
-       r600_context_bo_reloc(sctx, sscreen->b.trace_bo, RADEON_USAGE_READWRITE);
-       cs->buf[cs->cdw++] = PKT3(PKT3_WRITE_DATA, 4, 0);
-       cs->buf[cs->cdw++] = PKT3_WRITE_DATA_DST_SEL(PKT3_WRITE_DATA_DST_SEL_MEM_SYNC) |
-                               PKT3_WRITE_DATA_WR_CONFIRM |
-                               PKT3_WRITE_DATA_ENGINE_SEL(PKT3_WRITE_DATA_ENGINE_SEL_ME);
-       cs->buf[cs->cdw++] = va & 0xFFFFFFFFUL;
-       cs->buf[cs->cdw++] = (va >> 32UL) & 0xFFFFFFFFUL;
-       cs->buf[cs->cdw++] = cs->cdw;
-       cs->buf[cs->cdw++] = sscreen->b.cs_count;
+       /* 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;
 }
-#endif