diff options
Diffstat (limited to 'src/mesa/drivers/dri/i965/intel_screen.c')
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_screen.c | 150 |
1 files changed, 149 insertions, 1 deletions
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index 77fd9e386a..975c647e55 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -42,7 +42,10 @@ #include "intel_tex.h" #include "intel_span.h" #include "intel_ioctl.h" +#include "intel_regions.h" +#include "intel_bufmgr_ttm.h" +#include "i915_drm.h" #include "i830_dri.h" PUBLIC const char __driConfigOptions[] = @@ -126,6 +129,107 @@ 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, + char *name, struct intel_region *region, + intelRegion *region_desc, + GLuint mem_type) +{ + if (region) { + intel_region_update_static(intelScreen, region, 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 and rotated buffers 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); + + /* The rotated region is only used for old DDXes that didn't handle rotation + * on their own. + */ + if (intelScreen->driScrnPriv->ddx_version.minor < 8) { + intelScreen->rotated_region = + intel_recreate_static(intelScreen, "rotated", + intelScreen->rotated_region, + &intelScreen->rotated, + DRM_BO_FLAG_MEM_TT); + } + + intelScreen->back_region = + intel_recreate_static(intelScreen, "back", + intelScreen->back_region, + &intelScreen->back, + 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) @@ -243,6 +347,16 @@ intelUpdateScreenFromSAREA(intelScreenPrivate *intelScreen, intelScreen->depth.size = sarea->depth_size; intelScreen->depth.tiled = sarea->depth_tiled; + if (intelScreen->driScrnPriv->ddx_version.minor >= 9) { + intelScreen->front.bo_handle = sarea->front_bo_handle; + intelScreen->back.bo_handle = sarea->back_bo_handle; + intelScreen->depth.bo_handle = sarea->depth_bo_handle; + } else { + intelScreen->front.bo_handle = -1; + intelScreen->back.bo_handle = -1; + intelScreen->depth.bo_handle = -1; + } + intelScreen->tex.offset = sarea->tex_offset; intelScreen->logTextureGranularity = sarea->log_tex_granularity; intelScreen->tex.handle = sarea->tex_handle; @@ -301,6 +415,7 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv) (((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset); intelScreen->deviceID = gDRIPriv->deviceID; + intelScreen->maxBatchSize = 16 * 1024; intelScreen->mem = gDRIPriv->mem; intelScreen->cpp = gDRIPriv->cpp; @@ -357,7 +472,40 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv) } sPriv->extensions = intelExtensions; - + + 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, + intelScreen->maxBatchSize); + 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); + + intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL; + return GL_TRUE; } |