From 6057d7b7b58102bf7c3c4ecb08c1b7261f299efa Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 13 Jun 2013 10:10:17 +0800 Subject: [PATCH] ilo: re-emit states that involve resources Even with hardware contexts, since we do not pin resources, we have to re-emit the states so that the resources are referenced (by cp->bo) and their offsets are updated in case they are moved. This also allows us to elimiate cp flush in is_bo_busy(). --- .../drivers/ilo/ilo_3d_pipeline_gen6.c | 23 +++++++++++++++---- .../drivers/ilo/ilo_3d_pipeline_gen6.h | 1 + .../drivers/ilo/ilo_3d_pipeline_gen7.c | 12 +++------- src/gallium/drivers/ilo/ilo_transfer.c | 8 ------- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c index e4315df804f..c60fc014005 100644 --- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c +++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c @@ -210,7 +210,8 @@ gen6_pipeline_common_base_address(struct ilo_3d_pipeline *p, struct gen6_pipeline_session *session) { /* STATE_BASE_ADDRESS */ - if (session->state_bo_changed || session->instruction_bo_changed) { + if (session->state_bo_changed || session->instruction_bo_changed || + session->batch_bo_changed) { if (p->dev->gen == ILO_GEN(6)) gen6_wa_pipe_control_post_sync(p, false); @@ -396,13 +397,14 @@ gen6_pipeline_vf(struct ilo_3d_pipeline *p, struct gen6_pipeline_session *session) { /* 3DSTATE_INDEX_BUFFER */ - if (DIRTY(INDEX_BUFFER)) { + if (DIRTY(INDEX_BUFFER) || session->batch_bo_changed) { p->gen6_3DSTATE_INDEX_BUFFER(p->dev, &ilo->ib.state, session->info->primitive_restart, p->cp); } /* 3DSTATE_VERTEX_BUFFERS */ - if (DIRTY(VERTEX_BUFFERS) || DIRTY(VERTEX_ELEMENTS)) { + if (DIRTY(VERTEX_BUFFERS) || DIRTY(VERTEX_ELEMENTS) || + session->batch_bo_changed) { p->gen6_3DSTATE_VERTEX_BUFFERS(p->dev, ilo->vb.states, ilo->vb.enabled_mask, ilo->ve, p->cp); } @@ -714,7 +716,7 @@ gen6_pipeline_wm_depth(struct ilo_3d_pipeline *p, struct gen6_pipeline_session *session) { /* 3DSTATE_DEPTH_BUFFER and 3DSTATE_CLEAR_PARAMS */ - if (DIRTY(FRAMEBUFFER)) { + if (DIRTY(FRAMEBUFFER) || session->batch_bo_changed) { if (p->dev->gen == ILO_GEN(6)) { gen6_wa_pipe_control_post_sync(p, false); gen6_wa_pipe_control_wm_depth_flush(p); @@ -1298,11 +1300,24 @@ gen6_pipeline_prepare(const struct ilo_3d_pipeline *p, if (session->hw_ctx_changed) { /* these should be enough to make everything uploaded */ + session->batch_bo_changed = true; session->state_bo_changed = true; session->instruction_bo_changed = true; session->prim_changed = true; } else { + /* + * Any state that involves resources needs to be re-emitted when the + * batch bo changed. This is because we do not pin the resources and + * their offsets (or existence) may change between batch buffers. + * + * Since we messed around with ILO_3D_PIPELINE_INVALIDATE_BATCH_BO in + * handle_invalid_batch_bo(), use ILO_3D_PIPELINE_INVALIDATE_STATE_BO as + * a temporary workaround. + */ + session->batch_bo_changed = + (p->invalidate_flags & ILO_3D_PIPELINE_INVALIDATE_STATE_BO); + session->state_bo_changed = (p->invalidate_flags & ILO_3D_PIPELINE_INVALIDATE_STATE_BO); session->instruction_bo_changed = diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.h b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.h index 34d43206231..18d9309953d 100644 --- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.h +++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.h @@ -42,6 +42,7 @@ struct gen6_pipeline_session { int init_cp_space; bool hw_ctx_changed; + bool batch_bo_changed; bool state_bo_changed; bool instruction_bo_changed; bool prim_changed; diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c index 2811edf04c0..96e2e187427 100644 --- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c +++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c @@ -394,7 +394,8 @@ gen7_pipeline_sol(struct ilo_3d_pipeline *p, gen6_pipeline_update_max_svbi(p, ilo, session); /* 3DSTATE_SO_BUFFER */ - if ((DIRTY(STREAM_OUTPUT_TARGETS) || dirty_sh) && ilo->so.enabled) { + if ((DIRTY(STREAM_OUTPUT_TARGETS) || dirty_sh || + session->batch_bo_changed) && ilo->so.enabled) { int i; for (i = 0; i < ilo->so.count; i++) { @@ -529,15 +530,8 @@ gen7_pipeline_wm(struct ilo_3d_pipeline *p, gen7_wa_pipe_control_wm_depth_stall(p, emit_3dstate_depth_buffer); } - /* - * glCopyPixels() with GL_DEPTH, which flushes the context before copying - * the depth buffer to a temporary texture, could not update the depth - * buffer _sometimes_. Reissuing 3DSTATE_DEPTH_BUFFER in the new batch - * makes the problem gone. - */ - /* 3DSTATE_DEPTH_BUFFER and 3DSTATE_CLEAR_PARAMS */ - if (DIRTY(FRAMEBUFFER) || session->state_bo_changed) { + if (DIRTY(FRAMEBUFFER) || session->batch_bo_changed) { p->gen7_3DSTATE_DEPTH_BUFFER(p->dev, ilo->fb.state.zsbuf, p->cp); p->gen6_3DSTATE_HIER_DEPTH_BUFFER(p->dev, ilo->fb.state.zsbuf, p->cp); p->gen6_3DSTATE_STENCIL_BUFFER(p->dev, ilo->fb.state.zsbuf, p->cp); diff --git a/src/gallium/drivers/ilo/ilo_transfer.c b/src/gallium/drivers/ilo/ilo_transfer.c index d18dc8ca2ff..dcb9ab96d8b 100644 --- a/src/gallium/drivers/ilo/ilo_transfer.c +++ b/src/gallium/drivers/ilo/ilo_transfer.c @@ -45,14 +45,6 @@ is_bo_busy(struct ilo_context *ilo, struct intel_bo *bo, bool *need_flush) if (referenced) return true; - /* - * XXX With hardware context support, the bo may be needed by GPU - * without being referenced by ilo->cp->bo. We have to flush - * unconditionally, and that is bad. - */ - if (ilo->cp->render_ctx) - ilo_cp_flush(ilo->cp); - return intel_bo_is_busy(bo); } -- 2.30.2