From: Jerome Glisse <jgli...@redhat.com> We are now seing cs that can go over the vram+gtt size to avoid failing flush early cs that goes over 70% (gtt+vram) usage. 70% is use to allow some fragmentation.
Signed-off-by: Jerome Glisse <jgli...@redhat.com> --- src/gallium/drivers/r600/evergreen_state.c | 4 ++++ src/gallium/drivers/r600/r600.h | 1 + src/gallium/drivers/r600/r600_buffer.c | 1 + src/gallium/drivers/r600/r600_hw_context.c | 12 ++++++++++++ src/gallium/drivers/r600/r600_pipe.c | 3 +++ src/gallium/drivers/r600/r600_pipe.h | 21 +++++++++++++++++++++ src/gallium/drivers/r600/r600_state.c | 3 +++ src/gallium/drivers/r600/r600_state_common.c | 17 ++++++++++++++++- src/gallium/winsys/radeon/drm/radeon_drm_cs.c | 11 +++++++++++ src/gallium/winsys/radeon/drm/radeon_winsys.h | 10 ++++++++++ 10 files changed, 82 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index be1c427..84f8dce 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -1668,6 +1668,8 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx, surf = (struct r600_surface*)state->cbufs[i]; rtex = (struct r600_texture*)surf->base.texture; + r600_context_add_resource_size(ctx, state->cbufs[i]->texture); + if (!surf->color_initialized) { evergreen_init_color_surface(rctx, surf); } @@ -1699,6 +1701,8 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx, if (state->zsbuf) { surf = (struct r600_surface*)state->zsbuf; + r600_context_add_resource_size(ctx, state->zsbuf->texture); + if (!surf->depth_initialized) { evergreen_init_depth_surface(rctx, surf); } diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index a383c90..b9f7d3d 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -50,6 +50,7 @@ struct r600_resource { /* Resource state. */ unsigned domains; + uint64_t size; }; #define R600_BLOCK_MAX_BO 32 diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index 6df0d91..92f549a 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -250,6 +250,7 @@ bool r600_init_resource(struct r600_screen *rscreen, break; } + res->size = size; res->buf = rscreen->ws->buffer_create(rscreen->ws, size, alignment, use_reusable_pool, initial_domain); diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c index ebafd97..44d3b4d 100644 --- a/src/gallium/drivers/r600/r600_hw_context.c +++ b/src/gallium/drivers/r600/r600_hw_context.c @@ -359,6 +359,16 @@ out_err: void r600_need_cs_space(struct r600_context *ctx, unsigned num_dw, boolean count_draw_in) { + if (!ctx->ws->cs_memory_below_limit(ctx->rings.gfx.cs, ctx->vram, ctx->gtt)) { + ctx->gtt = 0; + ctx->vram = 0; + ctx->rings.gfx.flush(ctx, RADEON_FLUSH_ASYNC); + return; + } + /* all will be accounted once relocation are emited */ + ctx->gtt = 0; + ctx->vram = 0; + /* The number of dwords we already used in the CS so far. */ num_dw += ctx->rings.gfx.cs->cdw; @@ -784,6 +794,8 @@ void r600_begin_new_cs(struct r600_context *ctx) ctx->pm4_dirty_cdwords = 0; ctx->flags = 0; + ctx->gtt = 0; + ctx->vram = 0; /* Begin a new CS. */ r600_emit_command_buffer(ctx->rings.gfx.cs, &ctx->start_cs_cmd); diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index a59578d..cb50cfe 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -333,6 +333,9 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void rctx->chip_class = rscreen->chip_class; rctx->keep_tiling_flags = rscreen->info.drm_minor >= 12; + rctx->gtt = 0; + rctx->vram = 0; + LIST_INITHEAD(&rctx->active_nontimer_queries); LIST_INITHEAD(&rctx->dirty); LIST_INITHEAD(&rctx->enable_list); diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 3ff42d3..beb4b33 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -447,6 +447,10 @@ struct r600_context { unsigned backend_mask; unsigned max_db; /* for OQ */ + /* current unaccounted memory usage */ + uint64_t vram; + uint64_t gtt; + /* Miscellaneous state objects. */ void *custom_dsa_flush; void *custom_blend_resolve; @@ -998,4 +1002,21 @@ static INLINE unsigned u_max_layer(struct pipe_resource *r, unsigned level) } } +static INLINE void r600_context_add_resource_size(struct pipe_context *ctx, struct pipe_resource *r) +{ + struct r600_context *rctx = (struct r600_context *)ctx; + struct r600_resource *rr = (struct r600_resource *)r; + + if (r == NULL) { + return; + } + + if (rr->domains & RADEON_DOMAIN_GTT) { + rctx->gtt += rr->size; + } + if (rr->domains & RADEON_DOMAIN_VRAM) { + rctx->vram += rr->size; + } +} + #endif diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 6b4b2c3..58b5aaa 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -1544,6 +1544,7 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx, surf = (struct r600_surface*)state->cbufs[i]; rtex = (struct r600_texture*)surf->base.texture; + r600_context_add_resource_size(ctx, state->cbufs[i]->texture); if (!surf->color_initialized || force_cmask_fmask) { r600_init_color_surface(rctx, surf, force_cmask_fmask); @@ -1576,6 +1577,8 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx, if (state->zsbuf) { surf = (struct r600_surface*)state->zsbuf; + r600_context_add_resource_size(ctx, state->zsbuf->texture); + if (!surf->depth_initialized) { r600_init_depth_surface(rctx, surf); } diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 9386f61..fce2537 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -479,7 +479,8 @@ static void r600_set_index_buffer(struct pipe_context *ctx, if (ib) { pipe_resource_reference(&rctx->index_buffer.buffer, ib->buffer); - memcpy(&rctx->index_buffer, ib, sizeof(*ib)); + memcpy(&rctx->index_buffer, ib, sizeof(*ib)); + r600_context_add_resource_size(ctx, ib->buffer); } else { pipe_resource_reference(&rctx->index_buffer.buffer, NULL); } @@ -516,6 +517,7 @@ static void r600_set_vertex_buffers(struct pipe_context *ctx, vb[i].buffer_offset = input[i].buffer_offset; pipe_resource_reference(&vb[i].buffer, input[i].buffer); new_buffer_mask |= 1 << i; + r600_context_add_resource_size(ctx, input[i].buffer); } else { pipe_resource_reference(&vb[i].buffer, NULL); disable_mask |= 1 << i; @@ -613,6 +615,7 @@ static void r600_set_sampler_views(struct pipe_context *pipe, unsigned shader, pipe_sampler_view_reference((struct pipe_sampler_view **)&dst->views.views[i], views[i]); new_mask |= 1 << i; + r600_context_add_resource_size(pipe, views[i]->texture); } else { pipe_sampler_view_reference((struct pipe_sampler_view **)&dst->views.views[i], NULL); disable_mask |= 1 << i; @@ -806,6 +809,10 @@ static void r600_bind_ps_state(struct pipe_context *ctx, void *state) rctx->ps_shader = (struct r600_pipe_shader_selector *)state; r600_context_pipe_state_set(rctx, &rctx->ps_shader->current->rstate); + if (rctx->ps_shader->current) { + r600_context_add_resource_size(ctx, (struct pipe_resource *)rctx->ps_shader->current->bo); + } + if (rctx->chip_class <= R700) { bool multiwrite = rctx->ps_shader->current->shader.fs_write_all; @@ -835,6 +842,10 @@ static void r600_bind_vs_state(struct pipe_context *ctx, void *state) if (state) { r600_context_pipe_state_set(rctx, &rctx->vs_shader->current->rstate); + if (rctx->ps_shader->current) { + r600_context_add_resource_size(ctx, (struct pipe_resource *)rctx->ps_shader->current->bo); + } + /* Update clip misc state. */ if (rctx->vs_shader->current->pa_cl_vs_out_cntl != rctx->clip_misc_state.pa_cl_vs_out_cntl || rctx->vs_shader->current->shader.clip_dist_write != rctx->clip_misc_state.clip_dist_write) { @@ -938,10 +949,13 @@ static void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint } else { u_upload_data(rctx->uploader, 0, input->buffer_size, ptr, &cb->buffer_offset, &cb->buffer); } + /* account it in gtt */ + rctx->gtt += input->buffer_size; } else { /* Setup the hw buffer. */ cb->buffer_offset = input->buffer_offset; pipe_resource_reference(&cb->buffer, input->buffer); + r600_context_add_resource_size(ctx, input->buffer); } state->enabled_mask |= 1 << index; @@ -1004,6 +1018,7 @@ static void r600_set_so_targets(struct pipe_context *ctx, /* Set the new targets. */ for (i = 0; i < num_targets; i++) { pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->so_targets[i], targets[i]); + r600_context_add_resource_size(ctx, targets[i]->buffer); } for (; i < rctx->num_so_targets; i++) { pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->so_targets[i], NULL); diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c index cab2704..6a7115b 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c @@ -383,6 +383,16 @@ static boolean radeon_drm_cs_validate(struct radeon_winsys_cs *rcs) return status; } +static boolean radeon_drm_cs_memory_below_limit(struct radeon_winsys_cs *rcs, uint64_t vram, uint64_t gtt) +{ + struct radeon_drm_cs *cs = radeon_drm_cs(rcs); + boolean status = + (cs->csc->used_gart + gtt) < cs->ws->info.gart_size * 0.7 && + (cs->csc->used_vram + vram) < cs->ws->info.vram_size * 0.7; + + return status; +} + static void radeon_drm_cs_write_reloc(struct radeon_winsys_cs *rcs, struct radeon_winsys_cs_handle *buf) { @@ -575,6 +585,7 @@ void radeon_drm_cs_init_functions(struct radeon_drm_winsys *ws) ws->base.cs_destroy = radeon_drm_cs_destroy; ws->base.cs_add_reloc = radeon_drm_cs_add_reloc; ws->base.cs_validate = radeon_drm_cs_validate; + ws->base.cs_memory_below_limit = radeon_drm_cs_memory_below_limit; ws->base.cs_write_reloc = radeon_drm_cs_write_reloc; ws->base.cs_flush = radeon_drm_cs_flush; ws->base.cs_set_flush_callback = radeon_drm_cs_set_flush; diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h index 7fdef3f..8b64ef2 100644 --- a/src/gallium/winsys/radeon/drm/radeon_winsys.h +++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h @@ -393,6 +393,16 @@ struct radeon_winsys { boolean (*cs_validate)(struct radeon_winsys_cs *cs); /** + * Return TRUE if there is enough memory in VRAM and GTT for the relocs + * added so far. + * + * \param cs A command stream to validate. + * \param vram VRAM memory size pending to be use + * \param gtt GTT memory size pending to be use + */ + boolean (*cs_memory_below_limit)(struct radeon_winsys_cs *cs, uint64_t vram, uint64_t gtt); + + /** * Write a relocated dword to a command buffer. * * \param cs A command stream the relocation is written to. -- 1.8.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev