return 0;
}
+void
+dri_bo_wait_rendering(dri_bo *bo)
+{
+ bo->bufmgr->bo_wait_rendering(bo);
+}
+
void
dri_bufmgr_destroy(dri_bufmgr *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.
*/
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);
}
/**
- * 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;
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;
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;
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)
{
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;
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 */