diff options
author | Eric Anholt <eric@anholt.net> | 2007-12-12 10:25:19 -0800 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2007-12-12 11:52:10 -0800 |
commit | 7c71ef3a3d0cf2620525f468960cdc76a0fb0d33 (patch) | |
tree | 7b7e071b5c854bc5b737401990b54e488febf650 /src/mesa/drivers/dri/i915 | |
parent | 00e10a1385bfd376f5f45ad94e3543ac87f15de8 (diff) |
[intel] Move bufmgr back to context instead of screen, fixing glthreads.
Putting the bufmgr in the screen is not thread-safe since the emit_reloc
changes. It also led to a significant performance hit from pthread usage
for the attempted thread-safety (up to 12% of a cpu spent on refcounting
protection in single-threaded 965). The motivation had been to allow
multi-context bufmgr sharing in classic mode, but it wasn't worth the cost.
Diffstat (limited to 'src/mesa/drivers/dri/i915')
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_context.c | 118 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_context.h | 16 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_ioctl.c | 12 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_ioctl.h | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_pixel_copy.c | 9 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_pixel_draw.c | 2 |
6 files changed, 129 insertions, 32 deletions
diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index 326be9c76f..c67d906db0 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -60,6 +60,7 @@ #include "intel_buffer_objects.h" #include "intel_fbo.h" #include "intel_decode.h" +#include "intel_bufmgr_ttm.h" #include "drirenderbuffer.h" #include "vblank.h" @@ -291,6 +292,81 @@ intelFinish(GLcontext * ctx) } } +/** 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 ttm_disable = getenv("INTEL_NO_TTM") != NULL; + + /* If we've got a new enough DDX that's initializing TTM and giving us + * object handles for the shared buffers, use that. + */ + intel->ttm = GL_FALSE; + if (!ttm_disable && + intel->intelScreen->driScrnPriv->ddx_version.minor >= 9 && + intel->intelScreen->drmMinor >= 11 && + intel->intelScreen->front.bo_handle != -1) + { + intel->bufmgr = intel_bufmgr_ttm_init(intel->driFd, + DRM_FENCE_TYPE_EXE, + DRM_FENCE_TYPE_EXE | + DRM_I915_FENCE_TYPE_RW, + BATCH_SZ); + if (intel->bufmgr != NULL) + intel->ttm = GL_TRUE; + } + /* Otherwise, use the classic buffer manager. */ + if (intel->bufmgr == NULL) { + if (ttm_disable) { + fprintf(stderr, "TTM buffer manager disabled. Using classic.\n"); + } else { + fprintf(stderr, "Failed to initialize TTM buffer manager. " + "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 = dri_bufmgr_fake_init(intelScreen->tex.offset, + intelScreen->tex.map, + intelScreen->tex.size, + intel_fence_emit, + intel_fence_wait, + intel); + } + + return GL_TRUE; +} void intelInitDriverFunctions(struct dd_function_table *functions) @@ -338,9 +414,22 @@ intelInitContext(struct intel_context *intel, intel->driScreen = sPriv; intel->sarea = saPriv; + /* Dri stuff */ + intel->hHWContext = driContextPriv->hHWContext; + intel->driFd = sPriv->fd; + intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; + intel->width = intelScreen->width; intel->height = intelScreen->height; + if (intelScreen->deviceID == PCI_CHIP_I865_G) + intel->maxBatchSize = 4096; + else + intel->maxBatchSize = BATCH_SZ; + + if (!intel_init_bufmgr(intel)) + return GL_FALSE; + if (!lockMutexInit) { lockMutexInit = GL_TRUE; _glthread_INIT_MUTEX(lockMutex); @@ -391,11 +480,6 @@ intelInitContext(struct intel_context *intel, _swrast_allow_pixel_fog(ctx, GL_FALSE); _swrast_allow_vertex_fog(ctx, GL_TRUE); - /* Dri stuff */ - intel->hHWContext = driContextPriv->hHWContext; - intel->driFd = sPriv->fd; - intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; - intel->hw_stipple = 1; /* XXX FBO: this doesn't seem to be used anywhere */ @@ -436,9 +520,10 @@ intelInitContext(struct intel_context *intel, /* GL_TRUE, */ GL_FALSE); - if (intelScreen->ttm) + if (intel->ttm) driInitExtensions(ctx, ttm_extensions, GL_FALSE); + intel_recreate_static_regions(intel); intel->batch = intel_batchbuffer_alloc(intel); intel->last_swap_fence = NULL; @@ -457,11 +542,10 @@ intelInitContext(struct intel_context *intel, intel->prim.primitive = ~0; - #if DO_DEBUG INTEL_DEBUG = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); - if (!intel->intelScreen->ttm && (INTEL_DEBUG & DEBUG_BUFMGR)) - dri_bufmgr_fake_set_debug(intel->intelScreen->bufmgr, GL_TRUE); + if (!intel->ttm && (INTEL_DEBUG & DEBUG_BUFMGR)) + dri_bufmgr_fake_set_debug(intel->bufmgr, GL_TRUE); #endif if (getenv("INTEL_NO_RAST")) { @@ -507,6 +591,7 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) intel->first_swap_fence = NULL; } + dri_bufmgr_destroy(intel->bufmgr); if (release_texture_heaps) { /* This share group is about to go away, free our private @@ -551,21 +636,21 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv, if (intel_fb->color_rb[0] && !intel_fb->color_rb[0]->region) { intel_region_reference(&intel_fb->color_rb[0]->region, - intel->intelScreen->front_region); + intel->front_region); } if (intel_fb->color_rb[1] && !intel_fb->color_rb[1]->region) { intel_region_reference(&intel_fb->color_rb[1]->region, - intel->intelScreen->back_region); + intel->back_region); } if (intel_fb->color_rb[2] && !intel_fb->color_rb[2]->region) { intel_region_reference(&intel_fb->color_rb[2]->region, - intel->intelScreen->third_region); + intel->third_region); } if (irbDepth && !irbDepth->region) { - intel_region_reference(&irbDepth->region, intel->intelScreen->depth_region); + intel_region_reference(&irbDepth->region, intel->depth_region); } if (irbStencil && !irbStencil->region) { - intel_region_reference(&irbStencil->region, intel->intelScreen->depth_region); + intel_region_reference(&irbStencil->region, intel->depth_region); } } @@ -618,7 +703,6 @@ intelContendedLock(struct intel_context *intel, GLuint flags) { __DRIdrawablePrivate *dPriv = intel->driDrawable; __DRIscreenPrivate *sPriv = intel->driScreen; - intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; drmI830Sarea *sarea = intel->sarea; drmGetLock(intel->driFd, intel->hHWContext, flags); @@ -639,9 +723,9 @@ intelContendedLock(struct intel_context *intel, GLuint flags) * between contexts of a single fake bufmgr, but this will at least make * things correct for now. */ - if (!intel->intelScreen->ttm && sarea->texAge != intel->hHWContext) { + if (!intel->ttm && sarea->texAge != intel->hHWContext) { sarea->texAge = intel->hHWContext; - dri_bufmgr_fake_contended_lock_take(intel->intelScreen->bufmgr); + dri_bufmgr_fake_contended_lock_take(intel->bufmgr); if (INTEL_DEBUG & DEBUG_BATCH) intel_decode_context_reset(); } diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h index 993a08ef95..6f0051ed8b 100644 --- a/src/mesa/drivers/dri/i915/intel_context.h +++ b/src/mesa/drivers/dri/i915/intel_context.h @@ -34,6 +34,7 @@ #include "drm.h" #include "mm.h" #include "texmem.h" +#include "dri_bufmgr.h" #include "intel_screen.h" #include "intel_tex_obj.h" @@ -142,10 +143,25 @@ struct intel_context GLuint Fallback; GLuint NewGLState; + dri_bufmgr *bufmgr; + unsigned int maxBatchSize; + + struct intel_region *front_region; + struct intel_region *back_region; + struct intel_region *third_region; + struct intel_region *depth_region; + + /** + * This value indicates that the kernel memory manager is being used + * instead of the fake client-side memory manager. + */ + GLboolean ttm; + dri_fence *last_swap_fence; dri_fence *first_swap_fence; struct intel_batchbuffer *batch; + unsigned batch_id; GLuint last_state_batch_id; struct diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.c b/src/mesa/drivers/dri/i915/intel_ioctl.c index 94f7e73ecf..37704d66ec 100644 --- a/src/mesa/drivers/dri/i915/intel_ioctl.c +++ b/src/mesa/drivers/dri/i915/intel_ioctl.c @@ -47,15 +47,14 @@ #define FILE_DEBUG_FLAG DEBUG_IOCTL int -intelEmitIrqLocked(intelScreenPrivate *intelScreen) +intelEmitIrqLocked(struct intel_context *intel) { drmI830IrqEmit ie; int ret, seq; ie.irq_seq = &seq; - ret = drmCommandWriteRead(intelScreen->driScrnPriv->fd, - DRM_I830_IRQ_EMIT, &ie, sizeof(ie)); + ret = drmCommandWriteRead(intel->driFd, DRM_I830_IRQ_EMIT, &ie, sizeof(ie)); if (ret) { fprintf(stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret); exit(1); @@ -67,7 +66,7 @@ intelEmitIrqLocked(intelScreenPrivate *intelScreen) } void -intelWaitIrq(intelScreenPrivate *intelScreen, int seq) +intelWaitIrq(struct intel_context *intel, int seq) { drm_i915_irq_wait_t iw; int ret; @@ -77,8 +76,7 @@ intelWaitIrq(intelScreenPrivate *intelScreen, int seq) iw.irq_seq = seq; do { - ret = drmCommandWrite(intelScreen->driScrnPriv->fd, - DRM_I830_IRQ_WAIT, &iw, sizeof(iw)); + ret = drmCommandWrite(intel->driFd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw)); } while (ret == -EAGAIN || ret == -EINTR); if (ret) { @@ -170,7 +168,7 @@ intel_exec_ioctl(struct intel_context *intel, } - fo = intel_ttm_fence_create_from_arg(intel->intelScreen->bufmgr, "fence buffers", + fo = intel_ttm_fence_create_from_arg(intel->bufmgr, "fence buffers", &execbuf.fence_arg); if (!fo) { fprintf(stderr, "failed to fence handle: %08x\n", execbuf.fence_arg.handle); diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.h b/src/mesa/drivers/dri/i915/intel_ioctl.h index 953fee9240..60bc4a3fb9 100644 --- a/src/mesa/drivers/dri/i915/intel_ioctl.h +++ b/src/mesa/drivers/dri/i915/intel_ioctl.h @@ -30,8 +30,8 @@ #include "intel_context.h" -void intelWaitIrq(intelScreenPrivate *intelScreen, int seq); -int intelEmitIrqLocked(intelScreenPrivate *intelScreen); +void intelWaitIrq(struct intel_context *intel, int seq); +int intelEmitIrqLocked(struct intel_context *intel); void intel_batch_ioctl(struct intel_context *intel, GLuint start_offset, diff --git a/src/mesa/drivers/dri/i915/intel_pixel_copy.c b/src/mesa/drivers/dri/i915/intel_pixel_copy.c index 629cdb979d..0bda2d863f 100644 --- a/src/mesa/drivers/dri/i915/intel_pixel_copy.c +++ b/src/mesa/drivers/dri/i915/intel_pixel_copy.c @@ -54,9 +54,8 @@ copypix_src_region(struct intel_context *intel, GLenum type) case GL_DEPTH: /* Don't think this is really possible execpt at 16bpp, when we have no stencil. */ - if (intel->intelScreen->depth_region && - intel->intelScreen->depth_region->cpp == 2) - return intel->intelScreen->depth_region; + if (intel->depth_region && intel->depth_region->cpp == 2) + return intel->depth_region; case GL_STENCIL: /* Don't think this is really possible. */ @@ -64,7 +63,7 @@ copypix_src_region(struct intel_context *intel, GLenum type) case GL_DEPTH_STENCIL_EXT: /* Does it matter whether it is stencil/depth or depth/stencil? */ - return intel->intelScreen->depth_region; + return intel->depth_region; default: break; } @@ -164,7 +163,7 @@ do_texture_copypixels(GLcontext * ctx, /* Set the 3d engine to draw into the destination region: */ - intel->vtbl.meta_draw_region(intel, dst, intel->intelScreen->depth_region); + intel->vtbl.meta_draw_region(intel, dst, intel->depth_region); intel->vtbl.meta_import_pixel_state(intel); diff --git a/src/mesa/drivers/dri/i915/intel_pixel_draw.c b/src/mesa/drivers/dri/i915/intel_pixel_draw.c index 8349f4c748..0fea9a1d01 100644 --- a/src/mesa/drivers/dri/i915/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/i915/intel_pixel_draw.c @@ -112,7 +112,7 @@ do_texture_drawpixels(GLcontext * ctx, /* Set the 3d engine to draw into the destination region: */ - intel->vtbl.meta_draw_region(intel, dst, intel->intelScreen->depth_region); + intel->vtbl.meta_draw_region(intel, dst, intel->depth_region); intel->vtbl.meta_import_pixel_state(intel); |