intel: When subdataing a busy buffer, use a temporary and blit in.
authorEric Anholt <eric@anholt.net>
Thu, 12 Nov 2009 18:45:05 +0000 (10:45 -0800)
committerEric Anholt <eric@anholt.net>
Fri, 13 Nov 2009 21:18:56 +0000 (13:18 -0800)
This cuts a massive number of waits in ET:QW, which uses a VBO ringbuffer.
Unfortunately it doesn't BufferData when wrapping back to 0, so we can't
be clever with tracking what's been initialized.

src/mesa/drivers/dri/intel/intel_buffer_objects.c

index ea9d5a6276e50e892b3226be304ceb86d1292839..669becdab45f6fb434c99705b4dca7b1666ffd7b 100644 (file)
@@ -209,10 +209,23 @@ intel_bufferobj_subdata(GLcontext * ctx,
       memcpy((char *)intel_obj->sys_buffer + offset, data, size);
    else {
       /* Flush any existing batchbuffer that might reference this data. */
-      if (drm_intel_bo_references(intel->batch->buf, intel_obj->buffer))
-        intelFlush(ctx);
+      if (drm_intel_bo_busy(intel_obj->buffer) ||
+         drm_intel_bo_references(intel->batch->buf, intel_obj->buffer)) {
+        drm_intel_bo *temp_bo;
 
-      dri_bo_subdata(intel_obj->buffer, offset, size, data);
+        temp_bo = drm_intel_bo_alloc(intel->bufmgr, "subdata temp", size, 64);
+
+        drm_intel_bo_subdata(temp_bo, 0, size, data);
+
+        intel_emit_linear_blit(intel,
+                               intel_obj->buffer, offset,
+                               temp_bo, 0,
+                               size);
+
+        drm_intel_bo_unreference(temp_bo);
+      } else {
+        dri_bo_subdata(intel_obj->buffer, offset, size, data);
+      }
    }
 }