ilo: re-emit states that involve resources
authorChia-I Wu <olvaffe@gmail.com>
Thu, 13 Jun 2013 02:10:17 +0000 (10:10 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Thu, 13 Jun 2013 04:58:47 +0000 (12:58 +0800)
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().

src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.h
src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c
src/gallium/drivers/ilo/ilo_transfer.c

index e4315df804f6b0a84c78ccabb9da23023c61853b..c60fc014005779176350f367853aee837dcd8e85 100644 (file)
@@ -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 =
index 34d43206231958761d721d3e3b8c414c44133015..18d9309953da6a1e467d3481a9bd54bc2138067b 100644 (file)
@@ -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;
index 2811edf04c099e427fd02a9abd817afdf5d30436..96e2e187427a23dccf2b983e99ee85459ced4094 100644 (file)
@@ -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);
index d18dc8ca2ff8d45a2a654d3ef2aa1414361ea72a..dcb9ab96d8bc257a8a84273735a8a95548f25721 100644 (file)
@@ -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);
 }