From 6cefae5354fb3015c5a14677071871613faa9c3a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 19 May 2008 15:42:00 -0700 Subject: [PATCH] Add back a mostly-correct glFinish for GEM and fake. The right solution would probably be keeping a list of regions which have been rendered to. --- src/mesa/drivers/dri/common/dri_bufmgr.c | 6 ++++++ src/mesa/drivers/dri/common/dri_bufmgr.h | 9 ++++++++ .../drivers/dri/intel/intel_bufmgr_fake.c | 10 ++++++--- src/mesa/drivers/dri/intel/intel_bufmgr_gem.c | 21 +++++++++++++++++++ src/mesa/drivers/dri/intel/intel_context.c | 7 ++++++- 5 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.c b/src/mesa/drivers/dri/common/dri_bufmgr.c index 19ea2a8f86d..be2a7b740c3 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr.c @@ -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) { diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.h b/src/mesa/drivers/dri/common/dri_bufmgr.h index 29f9aea2b15..1abca08cc8a 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.h +++ b/src/mesa/drivers/dri/common/dri_bufmgr.h @@ -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); diff --git a/src/mesa/drivers/dri/intel/intel_bufmgr_fake.c b/src/mesa/drivers/dri/intel/intel_bufmgr_fake.c index 5d01a471c50..2aed3d85be8 100644 --- a/src/mesa/drivers/dri/intel/intel_bufmgr_fake.c +++ b/src/mesa/drivers/dri/intel/intel_bufmgr_fake.c @@ -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; diff --git a/src/mesa/drivers/dri/intel/intel_bufmgr_gem.c b/src/mesa/drivers/dri/intel/intel_bufmgr_gem.c index b472a8f6e16..8638d0af1a5 100644 --- a/src/mesa/drivers/dri/intel/intel_bufmgr_gem.c +++ b/src/mesa/drivers/dri/intel/intel_bufmgr_gem.c @@ -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; diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index ae9e53ce6e3..6f187f719b1 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -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 */ -- 2.30.2