summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/i965/intel_screen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/i965/intel_screen.c')
-rw-r--r--src/mesa/drivers/dri/i965/intel_screen.c150
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;
}