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;
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;
unsigned int fence_type_flush)
{
dri_bufmgr_ttm *bufmgr_ttm;
- dri_bo *test_alloc;
bufmgr_ttm = malloc(sizeof(*bufmgr_ttm));
bufmgr_ttm->fd = fd;
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;
}
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)
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;
}
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)
*/
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);
+ }
}
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;
}
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);
}
/**
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;
(*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",