Add back a mostly-correct glFinish for GEM and fake.
authorEric Anholt <eric@anholt.net>
Mon, 19 May 2008 22:42:00 +0000 (15:42 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 22 May 2008 17:46:58 +0000 (10:46 -0700)
The right solution would probably be keeping a list of regions which have been
rendered to.

src/mesa/drivers/dri/common/dri_bufmgr.c
src/mesa/drivers/dri/common/dri_bufmgr.h
src/mesa/drivers/dri/intel/intel_bufmgr_fake.c
src/mesa/drivers/dri/intel/intel_bufmgr_gem.c
src/mesa/drivers/dri/intel/intel_context.c

index 19ea2a8f86d5c6177f362d150351e0837d87c611..be2a7b740c361a19d9aa68cd3cc3f9278fa098f4 100644 (file)
@@ -127,6 +127,12 @@ dri_bo_get_subdata(dri_bo *bo, unsigned long offset,
    return 0;
 }
 
+void
+dri_bo_wait_rendering(dri_bo *bo)
+{
+   bo->bufmgr->bo_wait_rendering(bo);
+}
+
 void
 dri_bufmgr_destroy(dri_bufmgr *bufmgr)
 {
index 29f9aea2b152a2977b7935f557b16cc321624841..1abca08cc8a8051a5d2518cf3ad3785b7fabb143 100644 (file)
@@ -127,6 +127,14 @@ struct _dri_bufmgr {
    int (*bo_get_subdata) (dri_bo *bo, unsigned long offset,
                          unsigned long size, void *data);
 
+   /**
+    * Waits for rendering to an object by the GPU to have completed.
+    *
+    * This is not required for any access to the BO by bo_map, bo_subdata, etc.
+    * It is merely a way for the driver to implement glFinish.
+    */
+   void (*bo_wait_rendering) (dri_bo *bo);
+
    /**
     * Tears down the buffer manager instance.
     */
@@ -192,6 +200,7 @@ int dri_bo_subdata(dri_bo *bo, unsigned long offset,
                   unsigned long size, const void *data);
 int dri_bo_get_subdata(dri_bo *bo, unsigned long offset,
                       unsigned long size, void *data);
+void dri_bo_wait_rendering(dri_bo *bo);
 
 void dri_bufmgr_set_debug(dri_bufmgr *bufmgr, GLboolean enable_debug);
 void dri_bufmgr_destroy(dri_bufmgr *bufmgr);
index 5d01a471c50b8fbc39a47ca9e06fd5d6657b07a6..2aed3d85be87c984ba8c3100b1c79b5d2244b3f7 100644 (file)
@@ -533,10 +533,13 @@ dri_bufmgr_fake_wait_idle(dri_bufmgr_fake *bufmgr_fake)
 }
 
 /**
- * Wait for execution pending on a buffer
+ * Wait for rendering to a buffer to complete.
+ *
+ * It is assumed that the bathcbuffer which performed the rendering included
+ * the necessary flushing.
  */
 static void
-dri_bufmgr_fake_bo_wait_idle(dri_bo *bo)
+dri_fake_bo_wait_rendering(dri_bo *bo)
 {
    dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
    dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
@@ -757,7 +760,7 @@ dri_fake_bo_map(dri_bo *bo, GLboolean write_enable)
 
            if (!(bo_fake->flags & BM_NO_FENCE_SUBDATA) &&
                bo_fake->block->fenced) {
-              dri_bufmgr_fake_bo_wait_idle(bo);
+              dri_fake_bo_wait_rendering(bo);
            }
 
            bo->virtual = bo_fake->block->virtual;
@@ -1157,6 +1160,7 @@ dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual,
    bufmgr_fake->bufmgr.bo_unreference = dri_fake_bo_unreference;
    bufmgr_fake->bufmgr.bo_map = dri_fake_bo_map;
    bufmgr_fake->bufmgr.bo_unmap = dri_fake_bo_unmap;
+   bufmgr_fake->bufmgr.bo_wait_rendering = dri_fake_bo_wait_rendering;
    bufmgr_fake->bufmgr.destroy = dri_fake_destroy;
    bufmgr_fake->bufmgr.emit_reloc = dri_fake_emit_reloc;
    bufmgr_fake->bufmgr.process_relocs = dri_fake_process_relocs;
index b472a8f6e160022ab0012847e1e91a24a3b9c9a3..8638d0af1a5b58ef41249676a666df7961e645b6 100644 (file)
@@ -595,6 +595,26 @@ dri_gem_bo_get_subdata (dri_bo *bo, unsigned long offset,
     return 0;
 }
 
+static void
+dri_gem_bo_wait_rendering(dri_bo *bo)
+{
+    dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
+    dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
+    struct drm_gem_set_domain set_domain;
+    int ret;
+
+    set_domain.handle = bo_gem->gem_handle;
+    set_domain.read_domains = DRM_GEM_DOMAIN_CPU;
+    set_domain.write_domain = 0;
+    ret = ioctl (bufmgr_gem->fd, DRM_IOCTL_GEM_SET_DOMAIN, &set_domain);
+    if (ret != 0) {
+       fprintf (stderr, "%s:%d: Error setting memory domains %d (%08x %08x): %s .\n",
+                __FILE__, __LINE__,
+                bo_gem->gem_handle, set_domain.read_domains, set_domain.write_domain,
+                strerror (errno));
+    }
+}
+
 static void
 dri_bufmgr_gem_destroy(dri_bufmgr *bufmgr)
 {
@@ -827,6 +847,7 @@ intel_bufmgr_gem_init(int fd, int batch_size)
     bufmgr_gem->bufmgr.bo_unmap = dri_gem_bo_unmap;
     bufmgr_gem->bufmgr.bo_subdata = dri_gem_bo_subdata;
     bufmgr_gem->bufmgr.bo_get_subdata = dri_gem_bo_get_subdata;
+    bufmgr_gem->bufmgr.bo_wait_rendering = dri_gem_bo_wait_rendering;
     bufmgr_gem->bufmgr.destroy = dri_bufmgr_gem_destroy;
     bufmgr_gem->bufmgr.emit_reloc = dri_gem_emit_reloc;
     bufmgr_gem->bufmgr.process_relocs = dri_gem_process_reloc;
index ae9e53ce6e3bb4da580dac717822b21f2814bd21..6f187f719b151da579dd6ea2576577577b004571 100644 (file)
@@ -375,7 +375,12 @@ intelFinish(GLcontext * ctx)
    intelFlush(ctx);
 
    for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
-      /* XXX: Wait on buffer idle */
+       struct intel_renderbuffer *irb;
+
+       irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]);
+
+       if (irb->region)
+         dri_bo_wait_rendering(irb->region->buffer);
    }
    if (fb->_DepthBuffer) {
       /* XXX: Wait on buffer idle */