/** @file $Id: vboxvideo_dri2.c$
*
* VirtualBox X11 Additions graphics driver, DRI2 support
*/
/*
* Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* you can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include "vboxvideo.h"
#include <xf86drm.h>
#include <drm.h>
#include <dri2.h>
#include <fcntl.h>
#include <unistd.h>
static void VBOXDRICopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
DRI2BufferPtr pDest, DRI2BufferPtr pSrc)
{
}
static DRI2Buffer2Ptr VBOXDRICreateBuffer(DrawablePtr pDraw,
unsigned int cAttachment,
unsigned int cFormat)
{
return calloc(1, sizeof(DRI2Buffer2Rec));
}
static void VBOXDRIDestroyBuffer(DrawablePtr pDraw, DRI2Buffer2Ptr pBuffer)
{
free(pBuffer);
}
/* We need to pass a constant path string to the screen initialisation function.
* The format is hard-coded in "drmOpen" in libdrm, and libdrm contains a
* comment to say that open should be done manually in future and not using
* "drmOpen", so we will do it manually but also hard-coding the format. The
* maximum minor number (15) is also hard-coded. */
#define PATH(minor) "/dev/dri/card" #minor
const char *devicePaths[] =
{
PATH(0), PATH(1), PATH(2), PATH(3), PATH(4), PATH(5), PATH(6), PATH(7),
PATH(8), PATH(9), PATH(10), PATH(11), PATH(12), PATH(13), PATH(14), PATH(15)
};
#undef PATH
/** As long as we are using our fake DRI driver inside of Mesa, we only want
* to implement the minimum here to make Mesa load it. */
Bool VBOXDRIScreenInit(ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox)
{
DRI2InfoRec DRI2Info;
unsigned i;
memset(&DRI2Info, 0, sizeof(DRI2Info));
pVBox->drmFD = -1;
for (i = 0; i < RT_ELEMENTS(devicePaths); ++i)
{
int fd = open(devicePaths[i], O_RDWR);
if (fd >= 0)
{
drmVersionPtr pVersion = drmGetVersion(fd);
if ( pVersion
&& pVersion->name_len
&& !strcmp(pVersion->name, VBOX_DRM_DRIVER_NAME)
&& drmSetMaster(fd) == 0)
{
TRACE_LOG("Opened drm device %s\n", devicePaths[i]);
DRI2Info.deviceName = devicePaths[i];
/* Keep the driver open and hope that the path won't change. */
pVBox->drmFD = fd;
drmFreeVersion(pVersion);
break;
}
close(fd);
drmFreeVersion(pVersion);
}
}
if (!DRI2Info.deviceName)
return FALSE;
DRI2Info.version = 3;
DRI2Info.fd = pVBox->drmFD;
DRI2Info.driverName = VBOX_DRI_DRIVER_NAME;
DRI2Info.CopyRegion = VBOXDRICopyRegion;
DRI2Info.Wait = NULL;
DRI2Info.CreateBuffer = VBOXDRICreateBuffer;
DRI2Info.DestroyBuffer = VBOXDRIDestroyBuffer;
return DRI2ScreenInit(pScreen, &DRI2Info);
}
void VBOXDRICloseScreen(ScreenPtr pScreen, VBOXPtr pVBox)
{
DRI2CloseScreen(pScreen);
if (pVBox->drmFD >= 0)
close(pVBox->drmFD);
}