From 7e0bbdcf033981282978554c2e68ce48b55aa291 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 4 Sep 2008 22:16:31 +0100 Subject: intel: Move the bufmgr back to the screen. Mesa requires that we be able to share objects between contexts, which means that the objects need to be created by the same bufmgr, and the bufmgr internally requires pthread protection for thread safety. Rely on the bufmgr having appropriate locking. --- src/mesa/drivers/dri/intel/intel_batchbuffer.c | 4 +- src/mesa/drivers/dri/intel/intel_context.c | 115 +++---------------------- src/mesa/drivers/dri/intel/intel_ioctl.c | 21 +++-- src/mesa/drivers/dri/intel/intel_ioctl.h | 4 +- src/mesa/drivers/dri/intel/intel_screen.c | 98 +++++++++++++++++++++ src/mesa/drivers/dri/intel/intel_screen.h | 4 + 6 files changed, 132 insertions(+), 114 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c index 5afaad070c..550f467f83 100644 --- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c @@ -265,9 +265,9 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file, fprintf(stderr, "waiting for idle\n"); LOCK_HARDWARE(intel); - irq = intelEmitIrqLocked(intel); + irq = intelEmitIrqLocked(intel->intelScreen); UNLOCK_HARDWARE(intel); - intelWaitIrq(intel, irq); + intelWaitIrq(intel->intelScreen, irq); } /* Reset the buffer: diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index 18e73484ae..15ab9cbf35 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -575,105 +575,6 @@ intelEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) } #endif -/** Driver-specific fence emit implementation for the fake memory manager. */ -static unsigned int -intel_fence_emit(void *private) -{ - struct intel_context *intel = (struct intel_context *)private; - unsigned int fence; - - /* XXX: Need to emit a flush, if we haven't already (at least with the - * current batchbuffer implementation, we have). - */ - - fence = intelEmitIrqLocked(intel); - - return fence; -} - -/** Driver-specific fence wait implementation for the fake memory manager. */ -static int -intel_fence_wait(void *private, unsigned int cookie) -{ - struct intel_context *intel = (struct intel_context *)private; - - intelWaitIrq(intel, cookie); - - return 0; -} - -static GLboolean -intel_init_bufmgr(struct intel_context *intel) -{ - intelScreenPrivate *intelScreen = intel->intelScreen; - GLboolean gem_disable = getenv("INTEL_NO_GEM") != NULL; - int gem_kernel = 0; - GLboolean gem_supported; - struct drm_i915_getparam gp; - - gp.param = I915_PARAM_HAS_GEM; - gp.value = &gem_kernel; - - (void) drmCommandWriteRead(intel->driFd, DRM_I915_GETPARAM, &gp, sizeof(gp)); - - /* If we've got a new enough DDX that's initializing GEM and giving us - * object handles for the shared buffers, use that. - */ - intel->ttm = GL_FALSE; - if (intel->intelScreen->driScrnPriv->dri2.enabled) - gem_supported = GL_TRUE; - else if (intel->intelScreen->driScrnPriv->ddx_version.minor >= 9 && - gem_kernel && - intel->intelScreen->front.bo_handle != -1) - gem_supported = GL_TRUE; - else - gem_supported = GL_FALSE; - - if (!gem_disable && gem_supported) { - int bo_reuse_mode; - intel->bufmgr = intel_bufmgr_gem_init(intel->driFd, - BATCH_SZ); - if (intel->bufmgr != NULL) - intel->ttm = GL_TRUE; - - bo_reuse_mode = driQueryOptioni(&intel->optionCache, "bo_reuse"); - switch (bo_reuse_mode) { - case DRI_CONF_BO_REUSE_DISABLED: - break; - case DRI_CONF_BO_REUSE_ALL: - intel_bufmgr_gem_enable_reuse(intel->bufmgr); - break; - } - } - /* Otherwise, use the classic buffer manager. */ - if (intel->bufmgr == NULL) { - if (gem_disable) { - fprintf(stderr, "GEM disabled. Using classic.\n"); - } else { - fprintf(stderr, "Failed to initialize GEM. " - "Falling back to classic.\n"); - } - - if (intelScreen->tex.size == 0) { - fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n", - __func__, __LINE__); - return GL_FALSE; - } - - intel->bufmgr = intel_bufmgr_fake_init(intelScreen->tex.offset, - intelScreen->tex.map, - intelScreen->tex.size, - intel_fence_emit, - intel_fence_wait, - intel); - } - - /* XXX bufmgr should be per-screen, not per-context */ - intelScreen->ttm = intel->ttm; - - return GL_TRUE; -} - void intelInitDriverFunctions(struct dd_function_table *functions) { @@ -745,8 +646,20 @@ intelInitContext(struct intel_context *intel, else intel->maxBatchSize = BATCH_SZ; - if (!intel_init_bufmgr(intel)) - return GL_FALSE; + intel->bufmgr = intelScreen->bufmgr; + intel->ttm = intelScreen->ttm; + if (intel->ttm) { + int bo_reuse_mode; + + bo_reuse_mode = driQueryOptioni(&intel->optionCache, "bo_reuse"); + switch (bo_reuse_mode) { + case DRI_CONF_BO_REUSE_DISABLED: + break; + case DRI_CONF_BO_REUSE_ALL: + intel_bufmgr_gem_enable_reuse(intel->bufmgr); + break; + } + } ctx->Const.MaxTextureMaxAnisotropy = 2.0; diff --git a/src/mesa/drivers/dri/intel/intel_ioctl.c b/src/mesa/drivers/dri/intel/intel_ioctl.c index 58c81766cd..ac9e9337d6 100644 --- a/src/mesa/drivers/dri/intel/intel_ioctl.c +++ b/src/mesa/drivers/dri/intel/intel_ioctl.c @@ -50,22 +50,23 @@ #define FILE_DEBUG_FLAG DEBUG_IOCTL int -intelEmitIrqLocked(struct intel_context *intel) +intelEmitIrqLocked(intelScreenPrivate *intelScreen) { + __DRIscreenPrivate *spriv = intelScreen->driScrnPriv; struct drm_i915_irq_emit ie; int ret, seq = 1; - if (intel->no_hw) + if (intelScreen->no_hw) return 1; /* - assert(((*(int *)intel->driHwLock) & ~DRM_LOCK_CONT) == - (DRM_LOCK_HELD|intel->hHWContext)); + assert(((*(int *)intelScreen->driHwLock) & ~DRM_LOCK_CONT) == + (DRM_LOCK_HELD|intelScreen->hHWContext)); */ ie.irq_seq = &seq; - ret = drmCommandWriteRead(intel->driFd, DRM_I915_IRQ_EMIT, &ie, sizeof(ie)); + ret = drmCommandWriteRead(spriv->fd, DRM_I915_IRQ_EMIT, &ie, sizeof(ie)); if (ret) { fprintf(stderr, "%s: drm_i915_irq_emit: %d\n", __FUNCTION__, ret); exit(1); @@ -77,13 +78,15 @@ intelEmitIrqLocked(struct intel_context *intel) } void -intelWaitIrq(struct intel_context *intel, int seq) +intelWaitIrq(intelScreenPrivate *intelScreen, int seq) { + __DRIscreenPrivate *spriv = intelScreen->driScrnPriv; struct drm_i915_irq_wait iw; int ret, lastdispatch; - volatile struct drm_i915_sarea *sarea = intel->sarea; + volatile struct drm_i915_sarea *sarea = (struct drm_i915_sarea *) + (((GLubyte *) spriv->pSAREA) + intelScreen->sarea_priv_offset); - if (intel->no_hw) + if (intelScreen->no_hw) return; DBG("%s %d\n", __FUNCTION__, seq); @@ -92,7 +95,7 @@ intelWaitIrq(struct intel_context *intel, int seq) do { lastdispatch = sarea->last_dispatch; - ret = drmCommandWrite(intel->driFd, DRM_I915_IRQ_WAIT, &iw, sizeof(iw)); + ret = drmCommandWrite(spriv->fd, DRM_I915_IRQ_WAIT, &iw, sizeof(iw)); } while (ret == -EAGAIN || ret == -EINTR || (ret == -EBUSY && lastdispatch != sarea->last_dispatch) || diff --git a/src/mesa/drivers/dri/intel/intel_ioctl.h b/src/mesa/drivers/dri/intel/intel_ioctl.h index 526e38358c..2ea40001db 100644 --- a/src/mesa/drivers/dri/intel/intel_ioctl.h +++ b/src/mesa/drivers/dri/intel/intel_ioctl.h @@ -30,8 +30,8 @@ #include "intel_context.h" -void intelWaitIrq( struct intel_context *intel, int seq ); -int intelEmitIrqLocked( struct intel_context *intel ); +void intelWaitIrq(intelScreenPrivate *intelScreen, int seq); +int intelEmitIrqLocked(intelScreenPrivate *intelScreen); int intel_batch_ioctl(struct intel_context *intel, GLuint start_offset, diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index c193830f05..5cfb893305 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -552,6 +552,96 @@ intelFillInModes(__DRIscreenPrivate *psp, } +/** Driver-specific fence emit implementation for the fake memory manager. */ +static unsigned int +intel_fence_emit(void *private) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *)private; + unsigned int fence; + + /* XXX: Need to emit a flush, if we haven't already (at least with the + * current batchbuffer implementation, we have). + */ + + fence = intelEmitIrqLocked(intelScreen); + + return fence; +} + +/** Driver-specific fence wait implementation for the fake memory manager. */ +static int +intel_fence_wait(void *private, unsigned int cookie) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *)private; + + intelWaitIrq(intelScreen, cookie); + + return 0; +} + +static GLboolean +intel_init_bufmgr(intelScreenPrivate *intelScreen) +{ + GLboolean gem_disable = getenv("INTEL_NO_GEM") != NULL; + int gem_kernel = 0; + GLboolean gem_supported; + struct drm_i915_getparam gp; + __DRIscreenPrivate *spriv = intelScreen->driScrnPriv; + + intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL; + + gp.param = I915_PARAM_HAS_GEM; + gp.value = &gem_kernel; + + (void) drmCommandWriteRead(spriv->fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); + + /* If we've got a new enough DDX that's initializing GEM and giving us + * object handles for the shared buffers, use that. + */ + intelScreen->ttm = GL_FALSE; + if (intelScreen->driScrnPriv->dri2.enabled) + gem_supported = GL_TRUE; + else if (intelScreen->driScrnPriv->ddx_version.minor >= 9 && + gem_kernel && + intelScreen->front.bo_handle != -1) + gem_supported = GL_TRUE; + else + gem_supported = GL_FALSE; + + if (!gem_disable && gem_supported) { + intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ); + if (intelScreen->bufmgr != NULL) + intelScreen->ttm = GL_TRUE; + } + /* Otherwise, use the classic buffer manager. */ + if (intelScreen->bufmgr == NULL) { + if (gem_disable) { + fprintf(stderr, "GEM disabled. Using classic.\n"); + } else { + fprintf(stderr, "Failed to initialize GEM. " + "Falling back to classic.\n"); + } + + if (intelScreen->tex.size == 0) { + fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n", + __func__, __LINE__); + return GL_FALSE; + } + + intelScreen->bufmgr = intel_bufmgr_fake_init(intelScreen->tex.offset, + intelScreen->tex.map, + intelScreen->tex.size, + intel_fence_emit, + intel_fence_wait, + intelScreen); + } + + /* XXX bufmgr should be per-screen, not per-context */ + intelScreen->ttm = intelScreen->ttm; + + return GL_TRUE; +} + /** * This is the driver specific part of the createNewScreen entry point. * Called when using legacy DRI. @@ -562,6 +652,7 @@ intelFillInModes(__DRIscreenPrivate *psp, */ static const __DRIconfig **intelInitScreen(__DRIscreenPrivate *psp) { + intelScreenPrivate *intelScreen; #ifdef I915 static const __DRIversion ddx_expected = { 1, 5, 0 }; #else @@ -595,6 +686,10 @@ static const __DRIconfig **intelInitScreen(__DRIscreenPrivate *psp) psp->extensions = intelScreenExtensions; + intelScreen = psp->private; + if (!intel_init_bufmgr(intelScreen)) + return GL_FALSE; + return (const __DRIconfig **) intelFillInModes(psp, dri_priv->cpp * 8, (dri_priv->cpp == 2) ? 16 : 24, @@ -659,6 +754,9 @@ __DRIconfig **intelInitScreen2(__DRIscreenPrivate *psp) &intelScreen->deviceID)) return GL_FALSE; + if (!intel_init_bufmgr(intelScreen)) + return GL_FALSE; + intelScreen->irq_active = 1; psp->extensions = intelScreenExtensions; diff --git a/src/mesa/drivers/dri/intel/intel_screen.h b/src/mesa/drivers/dri/intel/intel_screen.h index 9a73b13951..299da87210 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.h +++ b/src/mesa/drivers/dri/intel/intel_screen.h @@ -30,6 +30,7 @@ #include #include "dri_util.h" +#include "dri_bufmgr.h" #include "i915_drm.h" #include "xmlconfig.h" @@ -74,7 +75,10 @@ typedef struct int irq_active; int allow_batchbuffer; + GLboolean no_hw; + int ttm; + dri_bufmgr *bufmgr; /** * Configuration cache with default values for all contexts -- cgit v1.2.3