summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2007-08-16 14:32:53 -0700
committerEric Anholt <eric@anholt.net>2007-08-16 14:38:33 -0700
commit3e168a0ec840af65863e197f4a884aae905b213e (patch)
tree5d838ff3e80734ff90de6583809a0f0f66d9d8aa
parentb6ad5e7de8dc84ee42eeeb62d2112f096413b335 (diff)
downloadexternal_mesa3d-3e168a0ec840af65863e197f4a884aae905b213e.zip
external_mesa3d-3e168a0ec840af65863e197f4a884aae905b213e.tar.gz
external_mesa3d-3e168a0ec840af65863e197f4a884aae905b213e.tar.bz2
Convert TTM code to require the server provide buffers for front/back/depth.
This removes the use of fake buffers from the driver, such that it could probably be removed from the interface. It also should assist in proper synchronization of access.
-rw-r--r--src/mesa/drivers/dri/common/dri_bufmgr.h2
-rw-r--r--src/mesa/drivers/dri/common/dri_bufmgr_ttm.c46
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_regions.c32
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_regions.h2
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_screen.c110
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_screen.h1
-rw-r--r--src/mesa/drivers/dri/i915tex/server/i830_common.h9
7 files changed, 121 insertions, 81 deletions
diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.h b/src/mesa/drivers/dri/common/dri_bufmgr.h
index 0f8e279..3be3429 100644
--- a/src/mesa/drivers/dri/common/dri_bufmgr.h
+++ b/src/mesa/drivers/dri/common/dri_bufmgr.h
@@ -192,5 +192,7 @@ dri_bufmgr *dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual,
unsigned int cookie),
void *driver_priv);
void dri_bufmgr_destroy(dri_bufmgr *bufmgr);
+dri_bo *dri_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name,
+ unsigned int handle);
#endif
diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c
index 2d4f518..5128d95 100644
--- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c
+++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c
@@ -131,15 +131,30 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name,
return &ttm_buf->bo;
}
+/* Our TTM backend doesn't allow creation of static buffers, as that requires
+ * privelege for the non-fake case, and the lock in the fake case where we were
+ * working around the X Server not creating buffers and passing handles to us.
+ */
static dri_bo *
dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name,
unsigned long offset, unsigned long size, void *virtual,
unsigned int location_mask)
{
+ return NULL;
+}
+
+/** Returns a dri_bo wrapping the given buffer object handle.
+ *
+ * This can be used when one application needs to pass a buffer object
+ * to another.
+ */
+dri_bo *
+dri_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name,
+ unsigned int handle)
+{
dri_bufmgr_ttm *ttm_bufmgr;
dri_bo_ttm *ttm_buf;
int ret;
- unsigned int flags, hint;
ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr;
@@ -147,25 +162,14 @@ dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name,
if (!ttm_buf)
return NULL;
- /* The mask argument doesn't do anything for us that we want other than
- * determine which pool (TTM or local) the buffer is allocated into, so just
- * pass all of the allocation class flags.
- */
- flags = location_mask | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
- DRM_BO_FLAG_EXE | DRM_BO_FLAG_NO_MOVE;
- /* No hints we want to use. */
- hint = 0;
-
- ret = drmBOCreate(ttm_bufmgr->fd, offset, size, 0,
- NULL, drm_bo_type_fake,
- flags, hint, &ttm_buf->drm_bo);
+ ret = drmBOReference(ttm_bufmgr->fd, handle, &ttm_buf->drm_bo);
if (ret != 0) {
free(ttm_buf);
return NULL;
}
ttm_buf->bo.size = ttm_buf->drm_bo.size;
ttm_buf->bo.offset = ttm_buf->drm_bo.offset;
- ttm_buf->bo.virtual = virtual;
+ ttm_buf->bo.virtual = NULL;
ttm_buf->bo.bufmgr = bufmgr;
ttm_buf->name = name;
ttm_buf->refcount = 1;
@@ -367,7 +371,6 @@ dri_bufmgr_ttm_init(int fd, unsigned int fence_type,
unsigned int fence_type_flush)
{
dri_bufmgr_ttm *bufmgr_ttm;
- dri_bo *test_alloc;
bufmgr_ttm = malloc(sizeof(*bufmgr_ttm));
bufmgr_ttm->fd = fd;
@@ -388,18 +391,5 @@ dri_bufmgr_ttm_init(int fd, unsigned int fence_type,
bufmgr_ttm->bufmgr.fence_wait = dri_ttm_fence_wait;
bufmgr_ttm->bufmgr.destroy = dri_bufmgr_ttm_destroy;
- /* Attempt an allocation to make sure that the DRM was actually set up for
- * TTM.
- */
- test_alloc = dri_bo_alloc((dri_bufmgr *)bufmgr_ttm, "test allocation",
- 4096, 4096, DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_MEM_TT);
- if (test_alloc == NULL) {
- fprintf(stderr, "TTM test allocation failed\n");
- _glthread_DESTROY_MUTEX(bufmgr_ttm->mutex);
- free(bufmgr_ttm);
- return NULL;
- }
- dri_bo_unreference(test_alloc);
-
return &bufmgr_ttm->bufmgr;
}
diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.c b/src/mesa/drivers/dri/i915tex/intel_regions.c
index 4e3cea5..4eac859 100644
--- a/src/mesa/drivers/dri/i915tex/intel_regions.c
+++ b/src/mesa/drivers/dri/i915tex/intel_regions.c
@@ -147,6 +147,7 @@ intel_region_release(struct intel_region **region)
struct intel_region *
intel_region_create_static(intelScreenPrivate *intelScreen,
GLuint mem_type,
+ unsigned int bo_handle,
GLuint offset,
void *virtual,
GLuint cpp, GLuint pitch, GLuint height)
@@ -159,9 +160,18 @@ intel_region_create_static(intelScreenPrivate *intelScreen,
region->height = height; /* needed? */
region->refcount = 1;
- region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, "static region",
- offset, pitch * cpp * height, virtual,
- DRM_BO_FLAG_MEM_TT);
+ if (intelScreen->ttm) {
+ assert(bo_handle != -1);
+ region->buffer = dri_ttm_bo_create_from_handle(intelScreen->bufmgr,
+ "static region",
+ bo_handle);
+ } else {
+ region->buffer = dri_bo_alloc_static(intelScreen->bufmgr,
+ "static region",
+ offset, pitch * cpp * height,
+ virtual,
+ DRM_BO_FLAG_MEM_TT);
+ }
return region;
}
@@ -172,6 +182,7 @@ void
intel_region_update_static(intelScreenPrivate *intelScreen,
struct intel_region *region,
GLuint mem_type,
+ unsigned int bo_handle,
GLuint offset,
void *virtual,
GLuint cpp, GLuint pitch, GLuint height)
@@ -188,9 +199,18 @@ intel_region_update_static(intelScreenPrivate *intelScreen,
*/
dri_bo_unreference(region->buffer);
- region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, "static region",
- offset, pitch * cpp * height, virtual,
- DRM_BO_FLAG_MEM_TT);
+ if (intelScreen->ttm) {
+ assert(bo_handle != -1);
+ region->buffer = dri_ttm_bo_create_from_handle(intelScreen->bufmgr,
+ "static region",
+ bo_handle);
+ } else {
+ region->buffer = dri_bo_alloc_static(intelScreen->bufmgr,
+ "static region",
+ offset, pitch * cpp * height,
+ virtual,
+ DRM_BO_FLAG_MEM_TT);
+ }
}
diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.h b/src/mesa/drivers/dri/i915tex/intel_regions.h
index 9623cf7..42d7b17 100644
--- a/src/mesa/drivers/dri/i915tex/intel_regions.h
+++ b/src/mesa/drivers/dri/i915tex/intel_regions.h
@@ -73,6 +73,7 @@ void intel_region_release(struct intel_region **ib);
extern struct intel_region
*intel_region_create_static(intelScreenPrivate *intelScreen,
GLuint mem_type,
+ unsigned int bo_handle,
GLuint offset,
void *virtual,
GLuint cpp,
@@ -81,6 +82,7 @@ extern void
intel_region_update_static(intelScreenPrivate *intelScreen,
struct intel_region *region,
GLuint mem_type,
+ unsigned int bo_handle,
GLuint offset,
void *virtual,
GLuint cpp, GLuint pitch, GLuint height);
diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c
index a047101..2721a90 100644
--- a/src/mesa/drivers/dri/i915tex/intel_screen.c
+++ b/src/mesa/drivers/dri/i915tex/intel_screen.c
@@ -170,18 +170,26 @@ intel_fence_wait(void *private, unsigned int cookie)
static struct intel_region *
intel_recreate_static(intelScreenPrivate *intelScreen,
struct intel_region *region,
- GLuint mem_type,
- GLuint offset,
- void *virtual,
- GLuint cpp, GLuint pitch, GLuint height)
+ intelRegion *region_desc,
+ GLuint mem_type)
{
if (region) {
- intel_region_update_static(intelScreen, region, mem_type, offset,
- virtual, cpp, pitch, height);
+ 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);
} else {
- region = intel_region_create_static(intelScreen, mem_type, offset,
- virtual, cpp, pitch, height);
+ region = intel_region_create_static(intelScreen, mem_type,
+ region_desc->bo_handle,
+ region_desc->offset,
+ region_desc->map, intelScreen->cpp,
+ region_desc->pitch / intelScreen->cpp,
+ intelScreen->height);
}
+
+ assert(region->buffer != NULL);
+
return region;
}
@@ -203,57 +211,42 @@ intel_recreate_static_regions(intelScreenPrivate *intelScreen)
intelScreen->front_region =
intel_recreate_static(intelScreen,
intelScreen->front_region,
- DRM_BO_FLAG_MEM_TT,
- intelScreen->front.offset,
- intelScreen->front.map,
- intelScreen->cpp,
- intelScreen->front.pitch / intelScreen->cpp,
- intelScreen->height);
-
- intelScreen->rotated_region =
- intel_recreate_static(intelScreen,
- intelScreen->rotated_region,
- DRM_BO_FLAG_MEM_TT,
- intelScreen->rotated.offset,
- intelScreen->rotated.map,
- intelScreen->cpp,
- intelScreen->rotated.pitch /
- intelScreen->cpp, intelScreen->height);
+ &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->ddxMinor < 8) {
+ intelScreen->rotated_region =
+ intel_recreate_static(intelScreen,
+ intelScreen->rotated_region,
+ &intelScreen->rotated,
+ DRM_BO_FLAG_MEM_TT);
+ }
intelScreen->back_region =
intel_recreate_static(intelScreen,
intelScreen->back_region,
- DRM_BO_FLAG_MEM_TT,
- intelScreen->back.offset,
- intelScreen->back.map,
- intelScreen->cpp,
- intelScreen->back.pitch / intelScreen->cpp,
- intelScreen->height);
+ &intelScreen->back,
+ DRM_BO_FLAG_MEM_TT);
if (intelScreen->third.handle) {
intelScreen->third_region =
intel_recreate_static(intelScreen,
intelScreen->third_region,
- DRM_BO_FLAG_MEM_TT,
- intelScreen->third.offset,
- intelScreen->third.map,
- intelScreen->cpp,
- intelScreen->third.pitch / intelScreen->cpp,
- intelScreen->height);
+ &intelScreen->third,
+ DRM_BO_FLAG_MEM_TT);
}
- /* Still assuming front.cpp == depth.cpp
+ /* Still assumes front.cpp == depth.cpp. We can kill this when we move to
+ * private buffers.
*/
intelScreen->depth_region =
intel_recreate_static(intelScreen,
intelScreen->depth_region,
- DRM_BO_FLAG_MEM_TT,
- intelScreen->depth.offset,
- intelScreen->depth.map,
- intelScreen->cpp,
- intelScreen->depth.pitch / intelScreen->cpp,
- intelScreen->height);
+ &intelScreen->depth,
+ DRM_BO_FLAG_MEM_TT);
}
/**
@@ -396,6 +389,18 @@ intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen,
intelScreen->depth.handle = sarea->depth_handle;
intelScreen->depth.size = sarea->depth_size;
+ if (intelScreen->driScrnPriv->ddxMinor >= 9) {
+ intelScreen->front.bo_handle = sarea->front_bo_handle;
+ intelScreen->back.bo_handle = sarea->back_bo_handle;
+ intelScreen->third.bo_handle = sarea->third_bo_handle;
+ intelScreen->depth.bo_handle = sarea->depth_bo_handle;
+ } else {
+ intelScreen->front.bo_handle = -1;
+ intelScreen->back.bo_handle = -1;
+ intelScreen->third.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;
@@ -526,10 +531,21 @@ intelInitDriver(__DRIscreenPrivate * sPriv)
(*glx_enable_extension) (psc, "GLX_SGI_make_current_read");
}
- intelScreen->bufmgr = dri_bufmgr_ttm_init(sPriv->fd,
- DRM_FENCE_TYPE_EXE,
- DRM_FENCE_TYPE_EXE |
- DRM_I915_FENCE_TYPE_RW);
+ /* 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->ddxMinor >= 9 &&
+ intelScreen->front.bo_handle != -1) {
+ intelScreen->bufmgr = dri_bufmgr_ttm_init(sPriv->fd,
+ DRM_FENCE_TYPE_EXE,
+ DRM_FENCE_TYPE_EXE |
+ DRM_I915_FENCE_TYPE_RW);
+ 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",
diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.h b/src/mesa/drivers/dri/i915tex/intel_screen.h
index 168793d..aa0ef2c 100644
--- a/src/mesa/drivers/dri/i915tex/intel_screen.h
+++ b/src/mesa/drivers/dri/i915tex/intel_screen.h
@@ -45,6 +45,7 @@ typedef struct
char *map; /* memory map */
int offset; /* from start of video mem, in bytes */
int pitch; /* row stride, in bytes */
+ unsigned int bo_handle; /* buffer object id if available, or -1 */
} intelRegion;
typedef struct
diff --git a/src/mesa/drivers/dri/i915tex/server/i830_common.h b/src/mesa/drivers/dri/i915tex/server/i830_common.h
index 7a76957..bd2bec3 100644
--- a/src/mesa/drivers/dri/i915tex/server/i830_common.h
+++ b/src/mesa/drivers/dri/i915tex/server/i830_common.h
@@ -136,6 +136,15 @@ typedef struct {
int third_offset;
int third_size;
unsigned int third_tiled;
+
+ /* buffer object handles for the static buffers. May change
+ * over the lifetime of the client, though it doesn't in our current
+ * implementation.
+ */
+ unsigned int front_bo_handle;
+ unsigned int back_bo_handle;
+ unsigned int third_bo_handle;
+ unsigned int depth_bo_handle;
} drmI830Sarea;
/* Flags for perf_boxes