Use new drmBOSetPin interface instead of NO_EVICT/NO_MOVE buffers.
To do this, we have to deal with buffer offsets being set at EnterVT time instead of screen init time. We've wanted to move this direction for a long time, but there are repercussions. The EXA offscreen memory manager has to be disabled, because it can't be moved. That will be replaced by BO-backed pixmaps soon. Also unresolved is whether our moving front/back/depth/texture buffers will break the classic-mode DRI driver. This code doesn't actually work yet.
This commit is contained in:
parent
18c707a8c1
commit
1a585d0397
|
|
@ -286,7 +286,13 @@ typedef struct _I830Rec {
|
|||
/* These are set in PreInit and never changed. */
|
||||
long FbMapSize;
|
||||
|
||||
i830_memory *memory_list; /**< Linked list of video memory allocations */
|
||||
/**
|
||||
* Linked list of video memory allocations. The head and tail are
|
||||
* dummy entries that bound the allocation area.
|
||||
*/
|
||||
i830_memory *memory_list;
|
||||
/** Linked list of buffer object memory allocations */
|
||||
i830_memory *bo_list;
|
||||
long stolen_size; /**< bytes of pre-bound stolen memory */
|
||||
int gtt_acquired; /**< whether we currently own the AGP */
|
||||
|
||||
|
|
|
|||
|
|
@ -2403,8 +2403,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
|
|||
|
||||
I830UnmapMMIO(pScrn);
|
||||
|
||||
i830_describe_allocations(pScrn, 1, "");
|
||||
|
||||
if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"Cannot support DRI with frame buffer width > 2048.\n");
|
||||
|
|
@ -2632,6 +2630,14 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
|
|||
} else
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing SW Cursor!\n");
|
||||
|
||||
#ifdef XF86DRI
|
||||
/* Must be called before EnterVT, so we can acquire the DRI lock when
|
||||
* binding our memory.
|
||||
*/
|
||||
if (pI830->directRenderingEnabled)
|
||||
pI830->directRenderingEnabled = I830DRIFinishScreenInit(pScreen);
|
||||
#endif
|
||||
|
||||
if (!I830EnterVT(scrnIndex, 0))
|
||||
return FALSE;
|
||||
|
||||
|
|
@ -2654,11 +2660,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
|
|||
I830InitVideo(pScreen);
|
||||
#endif
|
||||
|
||||
#ifdef XF86DRI
|
||||
if (pI830->directRenderingEnabled)
|
||||
pI830->directRenderingEnabled = I830DRIFinishScreenInit(pScreen);
|
||||
#endif
|
||||
|
||||
/* Setup 3D engine, needed for rotation too */
|
||||
IntelEmitInvarientState(pScrn);
|
||||
|
||||
|
|
@ -2802,6 +2803,7 @@ static Bool
|
|||
I830EnterVT(int scrnIndex, int flags)
|
||||
{
|
||||
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
|
||||
ScreenPtr pScreen = pScrn->pScreen;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
int o;
|
||||
|
|
@ -2823,6 +2825,18 @@ I830EnterVT(int scrnIndex, int flags)
|
|||
if (!i830_bind_all_memory(pScrn))
|
||||
return FALSE;
|
||||
|
||||
i830_describe_allocations(pScrn, 1, "");
|
||||
|
||||
/* Update buffer locations, which may have changed as a result of
|
||||
* i830_bind_all_memory().
|
||||
*/
|
||||
pScrn->fbOffset = pI830->front_buffer->offset;
|
||||
if (!pScreen->ModifyPixmapHeader(pScreen->GetScreenPixmap(pScreen),
|
||||
-1, -1, -1, -1, -1,
|
||||
(pointer)(pI830->FbBase +
|
||||
pScrn->fbOffset)))
|
||||
FatalError("Couldn't adjust screen pixmap\n");
|
||||
|
||||
if (i830_check_error_state(pScrn)) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
|
||||
"Existing errors found in hardware state.\n");
|
||||
|
|
|
|||
|
|
@ -405,9 +405,14 @@ I830EXAInit(ScreenPtr pScreen)
|
|||
pI830->EXADriverPtr->exa_major = 2;
|
||||
pI830->EXADriverPtr->exa_minor = 1;
|
||||
pI830->EXADriverPtr->memoryBase = pI830->FbBase;
|
||||
pI830->EXADriverPtr->offScreenBase = pI830->exa_offscreen->offset;
|
||||
pI830->EXADriverPtr->memorySize = pI830->exa_offscreen->offset +
|
||||
if (pI830->exa_offscreen) {
|
||||
pI830->EXADriverPtr->offScreenBase = pI830->exa_offscreen->offset;
|
||||
pI830->EXADriverPtr->memorySize = pI830->exa_offscreen->offset +
|
||||
pI830->exa_offscreen->size;
|
||||
} else {
|
||||
pI830->EXADriverPtr->offScreenBase = pI830->FbMapSize;
|
||||
pI830->EXADriverPtr->memorySize = pI830->FbMapSize;
|
||||
}
|
||||
pI830->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
|
||||
|
||||
DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, memorySize 0x%x\n",
|
||||
|
|
|
|||
|
|
@ -155,10 +155,25 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem)
|
|||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
||||
if (mem == NULL || mem->key == -1 || mem->bound || !pI830->gtt_acquired)
|
||||
if (mem == NULL || mem->bound || !pI830->gtt_acquired)
|
||||
return TRUE;
|
||||
|
||||
if (xf86BindGARTMemory(pScrn->scrnIndex, mem->key, mem->agp_offset)) {
|
||||
#ifdef XF86DRI_MM
|
||||
if (mem->bo.size != 0) {
|
||||
int ret;
|
||||
|
||||
ret = drmBOSetPin(pI830->drmSubFD, &mem->bo, 1);
|
||||
mem->offset = mem->bo.offset;
|
||||
mem->end = mem->offset + mem->size;
|
||||
if (ret)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mem->key == -1 ||
|
||||
xf86BindGARTMemory(pScrn->scrnIndex, mem->key, mem->agp_offset)) {
|
||||
mem->bound = TRUE;
|
||||
return TRUE;
|
||||
} else {
|
||||
|
|
@ -171,10 +186,23 @@ i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem)
|
|||
static Bool
|
||||
i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem)
|
||||
{
|
||||
if (mem == NULL || mem->key == -1 || !mem->bound)
|
||||
if (mem == NULL || !mem->bound)
|
||||
return TRUE;
|
||||
|
||||
if (xf86UnbindGARTMemory(pScrn->scrnIndex, mem->key)) {
|
||||
#ifdef XF86DRI_MM
|
||||
if (mem->bo.size != 0) {
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
int ret;
|
||||
|
||||
ret = drmBOSetPin(pI830->drmSubFD, &mem->bo, 0);
|
||||
if (ret)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mem->key == -1 || xf86UnbindGARTMemory(pScrn->scrnIndex, mem->key)) {
|
||||
mem->bound = FALSE;
|
||||
return TRUE;
|
||||
} else {
|
||||
|
|
@ -195,6 +223,12 @@ i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem)
|
|||
#ifdef XF86DRI_MM
|
||||
if (mem->bo.size != 0) {
|
||||
drmBOUnReference(pI830->drmSubFD, &mem->bo);
|
||||
if (pI830->bo_list == mem)
|
||||
pI830->bo_list = mem->next;
|
||||
if (mem->next)
|
||||
mem->next->prev = NULL;
|
||||
if (mem->prev)
|
||||
mem->prev->next = NULL;
|
||||
xfree(mem->name);
|
||||
xfree(mem);
|
||||
return;
|
||||
|
|
@ -615,7 +649,7 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name,
|
|||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
i830_memory *mem;
|
||||
unsigned long hint, mask;
|
||||
unsigned long mask;
|
||||
int ret;
|
||||
|
||||
assert((flags & NEED_PHYSICAL_ADDR) == 0);
|
||||
|
|
@ -635,14 +669,10 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name,
|
|||
}
|
||||
|
||||
mask = DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_MAPPABLE |
|
||||
DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE;
|
||||
hint = DRM_BO_HINT_DONT_FENCE | DRM_BO_HINT_DONT_BLOCK |
|
||||
DRM_BO_HINT_ALLOW_UNFENCED_MAP;
|
||||
DRM_BO_FLAG_MEM_TT;
|
||||
|
||||
I830DRILock(pScrn);
|
||||
ret = drmBOCreate(pI830->drmSubFD, 0, size, align / GTT_PAGE_SIZE, NULL,
|
||||
drm_bo_type_dc, mask, hint, &mem->bo);
|
||||
I830DRIUnlock(pScrn);
|
||||
drm_bo_type_dc, mask, 0, &mem->bo);
|
||||
if (ret) {
|
||||
xfree(mem->name);
|
||||
xfree(mem);
|
||||
|
|
@ -653,6 +683,13 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name,
|
|||
mem->end = mem->bo.start + size;
|
||||
mem->size = size;
|
||||
|
||||
/* Insert new allocation into the list */
|
||||
mem->prev = NULL;
|
||||
mem->next = pI830->bo_list;
|
||||
if (pI830->bo_list != NULL)
|
||||
pI830->bo_list->prev = mem;
|
||||
pI830->bo_list = mem;
|
||||
|
||||
return mem;
|
||||
}
|
||||
#endif /* XF86DRI_MM */
|
||||
|
|
@ -711,6 +748,12 @@ i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name,
|
|||
if (tile_format == TILING_NONE)
|
||||
return i830_allocate_memory(pScrn, name, size, alignment, flags);
|
||||
|
||||
/* XXX: for now, refuse to tile with buffer object allocations,
|
||||
* until we can move the set_fence (and failure recovery) into EnterVT.
|
||||
*/
|
||||
if (pI830->memory_manager != NULL)
|
||||
return NULL;
|
||||
|
||||
/* Only allocate page-sized increments. */
|
||||
size = ALIGN(size, GTT_PAGE_SIZE);
|
||||
|
||||
|
|
@ -811,7 +854,7 @@ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix)
|
|||
}
|
||||
|
||||
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
|
||||
"%sMemory allocation layout:\n", prefix);
|
||||
"%sFixed memory allocation layout:\n", prefix);
|
||||
|
||||
for (mem = pI830->memory_list->next; mem->next != NULL; mem = mem->next) {
|
||||
|
||||
|
|
@ -831,7 +874,7 @@ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix)
|
|||
} else {
|
||||
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
|
||||
"%s0x%08lx-0x%08lx: %s "
|
||||
"(%ld kB, 0x%16llx physical)\n",
|
||||
"(%ld kB, 0x%016llx physical)\n",
|
||||
prefix,
|
||||
mem->offset, mem->end - 1, mem->name,
|
||||
mem->size / 1024, mem->bus_addr);
|
||||
|
|
@ -841,6 +884,25 @@ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix)
|
|||
"%s0x%08lx: end of aperture\n",
|
||||
prefix, pI830->FbMapSize);
|
||||
|
||||
#ifdef XF86DRI_MM
|
||||
if (pI830->memory_manager) {
|
||||
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
|
||||
"%sBO memory allocation layout:\n", prefix);
|
||||
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
|
||||
"%s0x%08lx: start of memory manager\n",
|
||||
prefix, pI830->memory_manager->offset);
|
||||
for (mem = pI830->bo_list; mem != NULL; mem = mem->next) {
|
||||
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
|
||||
"%s0x%08lx-0x%08lx: %s (%ld kB)\n", prefix,
|
||||
mem->offset, mem->end - 1, mem->name,
|
||||
mem->size / 1024);
|
||||
}
|
||||
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
|
||||
"%s0x%08lx: end of memory manager\n",
|
||||
prefix, pI830->memory_manager->end);
|
||||
}
|
||||
#endif /* XF86DRI_MM */
|
||||
|
||||
if (pI830->front_buffer != NULL) {
|
||||
i830_describe_tiling(pScrn, verbosity, prefix, pI830->front_buffer,
|
||||
pI830->front_tiled);
|
||||
|
|
@ -1305,7 +1367,12 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn)
|
|||
|
||||
#ifdef I830_USE_EXA
|
||||
if (pI830->useEXA) {
|
||||
if (pI830->exa_offscreen == NULL) {
|
||||
/* With the kernel memory manager, the exa offscreen allocation would
|
||||
* change locations at EnterVT, which EXA is unprepared for. The
|
||||
* performance of EXA offscreen memory management was low enough
|
||||
* that just not using it is reasonable.
|
||||
*/
|
||||
if (pI830->exa_offscreen == NULL && pI830->memory_manager == NULL) {
|
||||
/* Default EXA to having 3 screens worth of offscreen memory space
|
||||
* (for pixmaps), plus a double-buffered, 1920x1088 video's worth.
|
||||
*
|
||||
|
|
@ -1799,6 +1866,10 @@ i830_bind_all_memory(ScrnInfoPtr pScrn)
|
|||
FatalError("Couldn't bind memory for %s\n", mem->name);
|
||||
}
|
||||
}
|
||||
for (mem = pI830->bo_list; mem != NULL; mem = mem->next) {
|
||||
if (!i830_bind_memory(pScrn, mem))
|
||||
FatalError("Couldn't bind memory for BO %s\n", mem->name);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
@ -1821,6 +1892,8 @@ i830_unbind_all_memory(ScrnInfoPtr pScrn)
|
|||
{
|
||||
i830_unbind_memory(pScrn, mem);
|
||||
}
|
||||
for (mem = pI830->bo_list; mem != NULL; mem = mem->next)
|
||||
i830_unbind_memory(pScrn, mem);
|
||||
|
||||
pI830->gtt_acquired = FALSE;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue