[Intel-gfx] [PATCH]fix for large texture with GEM-classic mode (bug#17964)

Xiang, Haihao haihao.xiang at intel.com
Wed Oct 22 09:22:58 CEST 2008


On Wed, 2008-10-22 at 10:49 +0800, Xiang, Haihao wrote:
> On Tue, 2008-10-21 at 10:32 -0700, Eric Anholt wrote:
> > On Tue, 2008-10-21 at 17:31 +0800, Xiang, Haihao wrote:
> > > Hi, 
> > >    Here are 2 patch for bug#17964. Sometimes a large texture(such as
> > > 2048x2048) works incorrectly under GEM-classic mode. There are two
> > > problems. Firstly there is an endless loop in intelEmitCopyBlit when
> > > using BLT to copy large texture image to mipmap tree. Secondly
> > > aperture_check only counts the first 3 level BOs, 
> > > The BO for texture is always ignored
> > > (batchbuffer_BO->bind_table_BO->surface_states_BO->texture_BO). 
> > 
> > Could you use git-send-email to send your patches, so they can be
> > reviewed inline?
> I didn't know this command before. I will learn to how use it.
> > 
> > @@ -263,8 +263,10 @@ got_flushed:
> >          if (check_state(state, &atom->dirty)) {
> >             if (atom->emit) {
> >                atom->emit( brw );
> > -              if (intel->batch->buf != last_batch_bo)
> > +              if (intel->batch->buf != last_batch_bo) {
> > +                 intel_batchbuffer_flush(intel->batch);
> >                   goto got_flushed;
> > +               }
> >             }
> >          }
> > 
> > The batchbuffer has already been flushed by somebody here.  Why flush it
> > again?

> The batchbuffer is filled with some commands after flushed, and the BOs
> referenced by these commands are counted by emit_reloc.  These BOs will
> be counted again when pass is 1. If the size of these BOs is greater
> than bufmgr_fake->size/2, aperture_check still fails.
> 
> Flush again to ensure the batchbuffer is unfilled, or return at once
> after flushing in emit function.
> 
> > 
> > +   if (pass >= 2) {
> > +       intel->Fallback = 1;
> > +       return;
> >     }
> > 
> > Where does that Fallback value get cleared?
> > 
> >     if (intelImage->mt) {
> >        /* Copy potentially with the blitter:
> >         */
> > +      useBlitter = GL_TRUE; 
> > +      intel->Fallback = 0;
> >        intel_miptree_image_copy(intel,
> >                                 intelObj->mt,
> >                                 intelImage->face,
> >                                 intelImage->level, intelImage->mt);
> > 
> > Can't clear the fallback value like that, as you'll wipe out 915's
> > fallback state.  Just return a boolean from the function of whether
> > blitting was successful.  (even better, just do the fallback right in
> > the function)
> Oh, I forgot 915. I will send out the update.
Here is the update.
                                                                                                                           
 src/mesa/drivers/dri/i965/brw_curbe.c      |    4 ++-
 src/mesa/drivers/dri/i965/brw_misc_state.c |   12 +++++--
 src/mesa/drivers/dri/intel/intel_blit.c    |   49
++++++++++++++++++++++------
 3 files changed, 51 insertions(+), 14 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c
b/src/mesa/drivers/dri/i965/brw_curbe.c
index 7cddd3a..6ffa221 100644
--- a/src/mesa/drivers/dri/i965/brw_curbe.c
+++ b/src/mesa/drivers/dri/i965/brw_curbe.c
@@ -333,8 +333,10 @@ static void emit_constant_buffer(struct brw_context
*brw)
       brw->curbe.curbe_bo,
    };
 
-   if (dri_bufmgr_check_aperture_space(aper_array,
ARRAY_SIZE(aper_array)))
+   if (dri_bufmgr_check_aperture_space(aper_array,
ARRAY_SIZE(aper_array))) {
       intel_batchbuffer_flush(intel->batch);
+      return;
+   }
 
    BEGIN_BATCH(2, IGNORE_CLIPRECTS);
    if (sz == 0) {
diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c
b/src/mesa/drivers/dri/i965/brw_misc_state.c
index 487c638..ea4551f 100644
--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -86,8 +86,10 @@ static void upload_binding_table_pointers(struct
brw_context *brw)
       brw->wm.bind_bo,
    };
 
-   if (dri_bufmgr_check_aperture_space(aper_array,
ARRAY_SIZE(aper_array)))
+   if (dri_bufmgr_check_aperture_space(aper_array,
ARRAY_SIZE(aper_array))) {
       intel_batchbuffer_flush(intel->batch);
+      return;
+   }
 
    BEGIN_BATCH(6, IGNORE_CLIPRECTS);
    OUT_BATCH(CMD_BINDING_TABLE_PTRS << 16 | (6 - 2));
@@ -152,8 +154,10 @@ static void upload_psp_urb_cbs(struct brw_context
*brw )
       brw->cc.state_bo,
    };
 
-   if (dri_bufmgr_check_aperture_space(aper_array,
ARRAY_SIZE(aper_array)))
+   if (dri_bufmgr_check_aperture_space(aper_array,
ARRAY_SIZE(aper_array))) {
       intel_batchbuffer_flush(intel->batch);
+      return;
+   }
 
    upload_pipelined_state_pointers(brw);
    brw_upload_urb_fence(brw);
@@ -216,8 +220,10 @@ static void emit_depthbuffer(struct brw_context
*brw)
         return;
       }
 
-      if (dri_bufmgr_check_aperture_space(aper_array,
ARRAY_SIZE(aper_array)))
+      if (dri_bufmgr_check_aperture_space(aper_array,
ARRAY_SIZE(aper_array))) {
         intel_batchbuffer_flush(intel->batch);
+         return;
+      }
 
       BEGIN_BATCH(len, IGNORE_CLIPRECTS);
       OUT_BATCH(CMD_DEPTH_BUFFER << 16 | (len - 2));
diff --git a/src/mesa/drivers/dri/intel/intel_blit.c
b/src/mesa/drivers/dri/intel/intel_blit.c
index 2917401..081d1dd 100644
--- a/src/mesa/drivers/dri/intel/intel_blit.c
+++ b/src/mesa/drivers/dri/intel/intel_blit.c
@@ -272,24 +272,53 @@ intelEmitCopyBlit(struct intel_context *intel,
                  GLshort w, GLshort h,
                  GLenum logic_op)
 {
-   GLuint CMD, BR13;
+   GLuint CMD, BR13, pass = 0;
    int dst_y2 = dst_y + h;
    int dst_x2 = dst_x + w;
    dri_bo *aper_array[3];
    BATCH_LOCALS;
 
    /* do space/cliprects check before going any further */
-   intel_batchbuffer_require_space(intel->batch, 8 * 4,
NO_LOOP_CLIPRECTS);
- again:
-   aper_array[0] = intel->batch->buf;
-   aper_array[1] = dst_buffer;
-   aper_array[2] = src_buffer;
-
-   if (dri_bufmgr_check_aperture_space(aper_array, 3) != 0) {
-      intel_batchbuffer_flush(intel->batch);
-      goto again;
+   do {
+       aper_array[0] = intel->batch->buf;
+       aper_array[1] = dst_buffer;
+       aper_array[2] = src_buffer;
+
+       if (dri_bufmgr_check_aperture_space(aper_array, 3) != 0) {
+           intel_batchbuffer_flush(intel->batch);
+           pass++;
+       } else
+           break;
+   } while (pass < 2);
+
+   if (pass >= 2) {
+       GLboolean locked = GL_FALSE;       
+       if (!intel->locked) {
+           LOCK_HARDWARE(intel);
+           locked = GL_TRUE;
+       }
+
+       dri_bo_map(dst_buffer, GL_TRUE);
+       dri_bo_map(src_buffer, GL_TRUE);
+       _mesa_copy_rect((GLubyte *)dst_buffer->virtual + dst_offset,
+                       cpp,
+                       dst_pitch,
+                       dst_x, dst_y, 
+                       w, h, 
+                       (GLubyte *)src_buffer->virtual + src_offset, 
+                       src_pitch,
+                       src_x, src_y);
+       
+       dri_bo_unmap(src_buffer);
+       dri_bo_unmap(dst_buffer);
+       
+       if (locked)
+           UNLOCK_HARDWARE(intel);
+
+       return;
    }
 
+   intel_batchbuffer_require_space(intel->batch, 8 * 4,
NO_LOOP_CLIPRECTS);
    DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
        __FUNCTION__,
        src_buffer, src_pitch, src_offset, src_x, src_y,




> > The second patch looks good.
> > 
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx




More information about the Intel-gfx mailing list