[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.
This commit is contained in:
Eric Anholt
2007-12-12 10:25:19 -08:00
parent 00e10a1385
commit 7c71ef3a3d
32 changed files with 503 additions and 654 deletions

View File

@@ -46,12 +46,9 @@
#include "intel_fbo.h"
#include "i830_dri.h"
#include "dri_bufmgr.h"
#include "intel_regions.h"
#include "intel_batchbuffer.h"
#include "intel_bufmgr_ttm.h"
PUBLIC const char __driConfigOptions[] =
DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE
DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
@@ -143,105 +140,6 @@ intelMapScreenRegions(__DRIscreenPrivate * sPriv)
return GL_TRUE;
}
/** 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 struct intel_region *
intel_recreate_static(intelScreenPrivate *intelScreen,
const char *name,
struct intel_region *region,
intelRegion *region_desc,
GLuint mem_type)
{
if (region) {
intel_region_update_static(intelScreen, region, name, mem_type,
region_desc->bo_handle, region_desc->offset,
region_desc->map, intelScreen->cpp,
region_desc->pitch / intelScreen->cpp,
intelScreen->height, region_desc->tiled);
} else {
region = intel_region_create_static(intelScreen, name, mem_type,
region_desc->bo_handle,
region_desc->offset,
region_desc->map, intelScreen->cpp,
region_desc->pitch / intelScreen->cpp,
intelScreen->height,
region_desc->tiled);
}
assert(region->buffer != NULL);
return region;
}
/* Create intel_region structs to describe the static front,back,depth
* buffers created by the xserver.
*
* Although FBO's mean we now no longer use these as render targets in
* all circumstances, they won't go away until the back and depth
* buffers become private, and the front buffer will remain even then.
*
* Note that these don't allocate video memory, just describe
* allocations alread made by the X server.
*/
static void
intel_recreate_static_regions(intelScreenPrivate *intelScreen)
{
intelScreen->front_region =
intel_recreate_static(intelScreen, "front",
intelScreen->front_region,
&intelScreen->front,
DRM_BO_FLAG_MEM_TT);
intelScreen->back_region =
intel_recreate_static(intelScreen, "back",
intelScreen->back_region,
&intelScreen->back,
DRM_BO_FLAG_MEM_TT);
if (intelScreen->third.handle) {
intelScreen->third_region =
intel_recreate_static(intelScreen, "third",
intelScreen->third_region,
&intelScreen->third,
DRM_BO_FLAG_MEM_TT);
}
/* Still assumes front.cpp == depth.cpp. We can kill this when we move to
* private buffers.
*/
intelScreen->depth_region =
intel_recreate_static(intelScreen, "depth",
intelScreen->depth_region,
&intelScreen->depth,
DRM_BO_FLAG_MEM_TT);
}
void
intelUnmapScreenRegions(intelScreenPrivate * intelScreen)
{
@@ -426,10 +324,6 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
(((GLubyte *) sPriv->pSAREA) + intelScreen->sarea_priv_offset);
intelScreen->deviceID = gDRIPriv->deviceID;
if (intelScreen->deviceID == PCI_CHIP_I865_G)
intelScreen->maxBatchSize = 4096;
else
intelScreen->maxBatchSize = BATCH_SZ;
intelScreen->mem = gDRIPriv->mem;
intelScreen->cpp = gDRIPriv->cpp;
@@ -496,41 +390,6 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
sPriv->extensions = intelExtensions;
/* If we've got a new enough DDX that's initializing TTM and giving us
* object handles for the shared buffers, use that.
*/
intelScreen->ttm = GL_FALSE;
if (getenv("INTEL_NO_TTM") == NULL &&
intelScreen->driScrnPriv->ddx_version.minor >= 9 &&
intelScreen->drmMinor >= 11 &&
intelScreen->front.bo_handle != -1) {
intelScreen->bufmgr = intel_bufmgr_ttm_init(sPriv->fd,
DRM_FENCE_TYPE_EXE,
DRM_FENCE_TYPE_EXE |
DRM_I915_FENCE_TYPE_RW,
BATCH_SZ);
if (intelScreen->bufmgr != NULL)
intelScreen->ttm = GL_TRUE;
}
/* Otherwise, use the classic buffer manager. */
if (intelScreen->bufmgr == NULL) {
if (intelScreen->tex.size == 0) {
fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
__func__, __LINE__);
return GL_FALSE;
}
fprintf(stderr, "[%s:%u] Failed to init TTM buffer manager, falling back"
" to classic.\n", __func__, __LINE__);
intelScreen->bufmgr = dri_bufmgr_fake_init(intelScreen->tex.offset,
intelScreen->tex.map,
intelScreen->tex.size,
intel_fence_emit,
intel_fence_wait,
intelScreen);
}
intel_recreate_static_regions(intelScreen);
return GL_TRUE;
}
@@ -542,7 +401,6 @@ intelDestroyScreen(__DRIscreenPrivate * sPriv)
intelUnmapScreenRegions(intelScreen);
dri_bufmgr_destroy(intelScreen->bufmgr);
FREE(intelScreen);
sPriv->private = NULL;
}