[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