diff options
Diffstat (limited to 'src/glamo-dri2.c')
-rw-r--r-- | src/glamo-dri2.c | 356 |
1 files changed, 356 insertions, 0 deletions
diff --git a/src/glamo-dri2.c b/src/glamo-dri2.c new file mode 100644 index 0000000..6b743f4 --- /dev/null +++ b/src/glamo-dri2.c @@ -0,0 +1,356 @@ +/* + * DRI for the SMedia Glamo3362 X.org Driver + * + * Modified: 2009 by Thomas White <taw@bitwiz.org.uk> + * + * Based on dri2.c from xf86-video-modesetting, to which the following + * notice applies: + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * + * + * Also based partially on xf86-video-ati, to which the following + * notice applies: + * + * Copyright 2008 Kristian Høgsberg + * Copyright 2008 Jérôme Glisse + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation on the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR + * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <xf86.h> +#include <xf86_OSproc.h> +#include <xf86drm.h> +#include <dri2.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <glamo_bo_gem.h> + +#include "glamo.h" +#include "glamo-dri2.h" +#include "glamo-kms-exa.h" + + +struct glamo_dri2_buffer_priv { + PixmapPtr pixmap; + unsigned int attachment; +}; + + +#if DRI2INFOREC_VERSION >= 3 + +static DRI2BufferPtr glamoCreateBuffer(DrawablePtr drawable, + unsigned int attachment, + unsigned int format) +{ + ScreenPtr pScreen = drawable->pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + DRI2BufferPtr buffer; + struct glamo_dri2_buffer_priv *private; + PixmapPtr pixmap; + struct glamo_exa_pixmap_priv *driver_priv; + int r; + + buffer = xcalloc(1, sizeof(*buffer)); + if (buffer == NULL) { + return NULL; + } + private = xcalloc(1, sizeof(*private)); + if (private == NULL) { + xfree(buffer); + return NULL; + } + + if ( attachment == DRI2BufferFrontLeft ) { + if ( drawable->type == DRAWABLE_PIXMAP ) { + pixmap = (PixmapPtr)drawable; + } else { + pixmap = pScreen->GetWindowPixmap((WindowPtr)drawable); + } + pixmap->refcnt++; + } else { + pixmap = pScreen->CreatePixmap(pScreen, + drawable->width, + drawable->height, + (format != 0)?format:drawable->depth, + 0); + } + exaMoveInPixmap(pixmap); + driver_priv = exaGetPixmapDriverPrivate(pixmap); + if ( !driver_priv ) { + xfree(buffer); + xfree(private); + return NULL; + } + r = glamo_gem_name_buffer(driver_priv->bo, &buffer->name); + if (r) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Couldn't name buffer: %d %s\n", + r, strerror(r)); + xfree(buffer); + xfree(private); + return NULL; + } + buffer->attachment = attachment; + buffer->pitch = pixmap->devKind; + buffer->cpp = pixmap->drawable.bitsPerPixel / 8; + buffer->driverPrivate = private; + buffer->format = format; + buffer->flags = 0; + private->pixmap = pixmap; + private->attachment = attachment; + + return buffer; +} + +#else + +static DRI2BufferPtr glamoCreateBuffers(DrawablePtr drawable, + unsigned int *attachments, int count) +{ + ScreenPtr pScreen = drawable->pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + int i; + DRI2BufferPtr buffers; + struct glamo_dri2_buffer_priv *privates; + + buffers = xcalloc(count, sizeof *buffers); + if ( buffers == NULL ) return NULL; + privates = xcalloc(count, sizeof *privates); + if ( privates == NULL ) { + xfree(buffers); + return NULL; + } + + /* For each attachment */ + for ( i=0; i<count; i++ ) { + + PixmapPtr pixmap; + struct glamo_exa_pixmap_priv *driver_priv; + int r; + + if ( attachments[i] == DRI2BufferFrontLeft ) { + if ( drawable->type == DRAWABLE_PIXMAP ) { + pixmap = (PixmapPtr)drawable; + } else { + pixmap = pScreen->GetWindowPixmap( + (WindowPtr)drawable); + } + pixmap->refcnt++; + } else { + pixmap = pScreen->CreatePixmap(pScreen, + drawable->width, + drawable->height, + drawable->depth, + 0); + } + exaMoveInPixmap(pixmap); + driver_priv = exaGetPixmapDriverPrivate(pixmap); + if ( !driver_priv ) { + xfree(buffers); + xfree(privates); + return NULL; + } + r = glamo_gem_name_buffer(driver_priv->bo, &buffers[i].name); + if (r) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Couldn't name buffer: %d %s\n", + r, strerror(r)); + xfree(buffers); + xfree(privates); + return NULL; + } + buffers[i].attachment = attachments[i]; + buffers[i].pitch = pixmap->devKind; + buffers[i].cpp = pixmap->drawable.bitsPerPixel / 8; + buffers[i].driverPrivate = &privates[i]; + buffers[i].format = drawable->depth; + buffers[i].flags = 0; + privates[i].pixmap = pixmap; + privates[i].attachment = attachments[i]; + + } + + return buffers; +} + +#endif + +#if DRI2INFOREC_VERSION >= 3 + +static void glamoDestroyBuffer(DrawablePtr pDraw, + DRI2BufferPtr buffer) +{ + ScreenPtr pScreen = pDraw->pScreen; + struct glamo_dri2_buffer_priv *private; + + private = buffer->driverPrivate; + pScreen->DestroyPixmap(private->pixmap); + + if ( buffer ) { + xfree(buffer->driverPrivate); + } +} + +#else + +static void glamoDestroyBuffers(DrawablePtr pDraw, + DRI2BufferPtr buffers, int count) +{ + ScreenPtr pScreen = pDraw->pScreen; + int i; + + for ( i=0; i<count; i++ ) { + GlamoDRI2BufferPrivatePtr private; + private = buffers[i].driverPrivate; + pScreen->DestroyPixmap(private->pixmap); + } + + if ( buffers ) { + xfree(buffers[0].driverPrivate); + xfree(buffers); + } +} + +#endif + + +static void glamoCopyRegion(DrawablePtr drawable, RegionPtr region, + DRI2BufferPtr dst_buffer, DRI2BufferPtr src_buffer) +{ + struct glamo_dri2_buffer_priv *src_private; + struct glamo_dri2_buffer_priv *dst_private; + ScreenPtr pScreen = drawable->pScreen; + PixmapPtr src_pixmap; + PixmapPtr dst_pixmap; + RegionPtr copy_clip; + GCPtr gc; + + src_private = src_buffer->driverPrivate; + dst_private = dst_buffer->driverPrivate; + src_pixmap = src_private->pixmap; + dst_pixmap = dst_private->pixmap; + + if (src_private->attachment == DRI2BufferFrontLeft) { + src_pixmap = (PixmapPtr)drawable; + } + if (dst_private->attachment == DRI2BufferFrontLeft) { + dst_pixmap = (PixmapPtr)drawable; + } + + gc = GetScratchGC(drawable->depth, pScreen); + copy_clip = REGION_CREATE(pScreen, NULL, 0); + REGION_COPY(pScreen, copy_clip, region); + gc->funcs->ChangeClip(gc, CT_REGION, copy_clip, 0); + ValidateGC(&dst_pixmap->drawable, gc); + gc->ops->CopyArea(&src_pixmap->drawable, &dst_pixmap->drawable, gc, + 0, 0, drawable->width, drawable->height, 0, 0); + FreeScratchGC(gc); +} + + +void driScreenInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + GlamoPtr pGlamo = GlamoPTR(pScrn); + DRI2InfoRec dri2info; + char *p; + struct stat sbuf; + dev_t d; + int i; + + fstat(pGlamo->drm_fd, &sbuf); + d = sbuf.st_rdev; + p = pGlamo->drm_devname; + for ( i=0; i<DRM_MAX_MINOR; i++ ) { + sprintf(p, DRM_DEV_NAME, DRM_DIR_NAME, i); + if ( stat(p, &sbuf) == 0 && sbuf.st_rdev == d ) break; + } + if ( i == DRM_MAX_MINOR ) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "[glamo-dri] Failed to find name of DRM device\n"); + return; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[glamo-dri] Name of DRM device is '%s'\n", p); + + dri2info.version = DRI2INFOREC_VERSION; + dri2info.fd = pGlamo->drm_fd; + dri2info.deviceName = p; + dri2info.driverName = "glamo"; + +#if DRI2INFOREC_VERSION >= 3 + dri2info.CreateBuffer = glamoCreateBuffer; + dri2info.DestroyBuffer = glamoDestroyBuffer; +#else + dri2info.CreateBuffers = glamoCreateBuffers; + dri2info.DestroyBuffers = glamoDestroyBuffers; +#endif + dri2info.CopyRegion = glamoCopyRegion; + + if ( !DRI2ScreenInit(pScreen, &dri2info) ) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[glamo-dri] DRI2 initialisation failed\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[glamo-dri] DRI2 initialisation succeeded\n"); + } +} + + +void driCloseScreen(ScreenPtr pScreen) +{ + DRI2CloseScreen(pScreen); +} |