diff options
Diffstat (limited to 'src/gallium/state_trackers/xorg/xorg_dri2.c')
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_dri2.c | 473 |
1 files changed, 0 insertions, 473 deletions
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c deleted file mode 100644 index fb50ef8ca11..00000000000 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ /dev/null @@ -1,473 +0,0 @@ -/* - * 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> - * Author: Jakob Bornecrantz <wallbraker@gmail.com> - * - */ - -#include "xorg-server.h" -#include "xf86.h" -#include "xf86_OSproc.h" - -#include "xorg_tracker.h" -#include "xorg_exa.h" - -#include "dri2.h" - -#include "pipe/p_state.h" -#include "util/u_inlines.h" - -#include "util/u_format.h" - -#include "state_tracker/drm_driver.h" - -/* Make all the #if cases in the code esier to read */ -#ifndef DRI2INFOREC_VERSION -#define DRI2INFOREC_VERSION 1 -#endif - -#if DRI2INFOREC_VERSION == 2 -static Bool set_format_in_do_create_buffer; -#endif - -typedef struct { - PixmapPtr pPixmap; - struct pipe_resource *tex; - struct pipe_fence_handle *fence; -} *BufferPrivatePtr; - -static Bool -dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format) -{ - struct pipe_resource *tex = NULL; - ScreenPtr pScreen = pDraw->pScreen; - ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); - modesettingPtr ms = modesettingPTR(pScrn); - struct exa_pixmap_priv *exa_priv; - BufferPrivatePtr private = buffer->driverPrivate; - PixmapPtr pPixmap; - struct winsys_handle whandle; - - if (pDraw->type == DRAWABLE_PIXMAP) - pPixmap = (PixmapPtr) pDraw; - else - pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw); - exa_priv = exaGetPixmapDriverPrivate(pPixmap); - - - switch (buffer->attachment) { - default: - if (buffer->attachment != DRI2BufferFakeFrontLeft || - pDraw->type != DRAWABLE_PIXMAP) { - private->pPixmap = (*pScreen->CreatePixmap)(pScreen, pDraw->width, - pDraw->height, - pDraw->depth, - 0); - } - break; - case DRI2BufferFrontLeft: - break; - case DRI2BufferStencil: -#if DRI2INFOREC_VERSION >= 3 - case DRI2BufferDepthStencil: -#else - /* Works on old X servers because sanity checking is for the weak */ - case 9: -#endif - if (exa_priv->depth_stencil_tex && - !util_format_is_depth_or_stencil(exa_priv->depth_stencil_tex->format)) - exa_priv->depth_stencil_tex = NULL; - /* Fall through */ - case DRI2BufferDepth: - if (exa_priv->depth_stencil_tex) - pipe_resource_reference(&tex, exa_priv->depth_stencil_tex); - else { - struct pipe_resource template; - unsigned depthBits = (format != 0) ? format : pDraw->depth; - memset(&template, 0, sizeof(template)); - template.target = PIPE_TEXTURE_2D; - if (buffer->attachment == DRI2BufferDepth) { - switch(depthBits) { - case 16: - template.format = PIPE_FORMAT_Z16_UNORM; - break; - case 32: - template.format = PIPE_FORMAT_Z32_UNORM; - break; - default: - template.format = ms->ds_depth_bits_last ? - PIPE_FORMAT_Z24X8_UNORM : PIPE_FORMAT_X8Z24_UNORM; - break; - } - } else { - template.format = ms->ds_depth_bits_last ? - PIPE_FORMAT_Z24_UNORM_S8_UINT : PIPE_FORMAT_S8_UINT_Z24_UNORM; - } - template.width0 = pDraw->width; - template.height0 = pDraw->height; - template.depth0 = 1; - template.array_size = 1; - template.last_level = 0; - template.bind = PIPE_BIND_DEPTH_STENCIL | - PIPE_BIND_SHARED; - tex = ms->screen->resource_create(ms->screen, &template); - pipe_resource_reference(&exa_priv->depth_stencil_tex, tex); - } - break; - } - - if (!private->pPixmap) { - private->pPixmap = pPixmap; - pPixmap->refcnt++; - } - - if (!tex) { - /* First call to make sure we have a pixmap private */ - exaMoveInPixmap(private->pPixmap); - xorg_exa_set_shared_usage(private->pPixmap); - pScreen->ModifyPixmapHeader(private->pPixmap, 0, 0, 0, 0, 0, NULL); - /* Second call to make sure texture has valid contents */ - exaMoveInPixmap(private->pPixmap); - tex = xorg_exa_get_texture(private->pPixmap); - } - - if (!tex) - FatalError("NO TEXTURE IN DRI2\n"); - - memset(&whandle, 0, sizeof(whandle)); - whandle.type = DRM_API_HANDLE_TYPE_SHARED; - - ms->screen->resource_get_handle(ms->screen, tex, &whandle); - - buffer->name = whandle.handle; - buffer->pitch = whandle.stride; - buffer->cpp = 4; - buffer->driverPrivate = private; - buffer->flags = 0; /* not tiled */ -#if DRI2INFOREC_VERSION == 2 - /* ABI forwards/backwards compatibility */ - if (set_format_in_do_create_buffer) - ((DRI2Buffer2Ptr)buffer)->format = 0; -#elif DRI2INFOREC_VERSION >= 3 - buffer->format = 0; -#endif - private->tex = tex; - - return TRUE; -} - -static void -dri2_do_destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer) -{ - ScreenPtr pScreen = pDraw->pScreen; - ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); - modesettingPtr ms = modesettingPTR(pScrn); - BufferPrivatePtr private = buffer->driverPrivate; - struct exa_pixmap_priv *exa_priv = exaGetPixmapDriverPrivate(private->pPixmap); - - pipe_resource_reference(&private->tex, NULL); - ms->screen->fence_reference(ms->screen, &private->fence, NULL); - pipe_resource_reference(&exa_priv->depth_stencil_tex, NULL); - (*pScreen->DestroyPixmap)(private->pPixmap); -} - -#if DRI2INFOREC_VERSION >= 2 - -static DRI2Buffer2Ptr -dri2_create_buffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format) -{ - DRI2Buffer2Ptr buffer; - BufferPrivatePtr private; - - buffer = calloc(1, sizeof *buffer); - if (!buffer) - return NULL; - - private = calloc(1, sizeof *private); - if (!private) { - goto fail; - } - - buffer->attachment = attachment; - buffer->driverPrivate = private; - - /* So far it is safe to downcast a DRI2Buffer2Ptr to DRI2BufferPtr */ - if (dri2_do_create_buffer(pDraw, (DRI2BufferPtr)buffer, format)) - return buffer; - - free(private); -fail: - free(buffer); - return NULL; -} - -static void -dri2_destroy_buffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer) -{ - /* So far it is safe to downcast a DRI2Buffer2Ptr to DRI2BufferPtr */ - dri2_do_destroy_buffer(pDraw, (DRI2BufferPtr)buffer); - - free(buffer->driverPrivate); - free(buffer); -} - -#endif /* DRI2INFOREC_VERSION >= 2 */ - -#if DRI2INFOREC_VERSION <= 2 - -static DRI2BufferPtr -dri2_create_buffers(DrawablePtr pDraw, unsigned int *attachments, int count) -{ - BufferPrivatePtr privates; - DRI2BufferPtr buffers; - int i; - - buffers = calloc(count, sizeof *buffers); - if (!buffers) - goto fail_buffers; - - privates = calloc(count, sizeof *privates); - if (!privates) - goto fail_privates; - - for (i = 0; i < count; i++) { - buffers[i].attachment = attachments[i]; - buffers[i].driverPrivate = &privates[i]; - - if (!dri2_do_create_buffer(pDraw, &buffers[i], 0)) - goto fail; - } - - return buffers; - -fail: - free(privates); -fail_privates: - free(buffers); -fail_buffers: - return NULL; -} - -static void -dri2_destroy_buffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count) -{ - int i; - - for (i = 0; i < count; i++) { - dri2_do_destroy_buffer(pDraw, &buffers[i]); - } - - if (buffers) { - free(buffers[0].driverPrivate); - free(buffers); - } -} - -#endif /* DRI2INFOREC_VERSION <= 2 */ - -static void -dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, - DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer) -{ - ScreenPtr pScreen = pDraw->pScreen; - ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); - modesettingPtr ms = modesettingPTR(pScrn); - BufferPrivatePtr dst_priv = pDestBuffer->driverPrivate; - BufferPrivatePtr src_priv = pSrcBuffer->driverPrivate; - DrawablePtr src_draw; - DrawablePtr dst_draw; - GCPtr gc; - RegionPtr copy_clip; - Bool save_accel; - CustomizerPtr cust = ms->cust; - - /* - * In driCreateBuffers we dewrap windows into the - * backing pixmaps in order to get to the texture. - * We need to use the real drawable in CopyArea - * so that cliprects and offsets are correct. - */ - src_draw = (pSrcBuffer->attachment == DRI2BufferFrontLeft) ? pDraw : - &src_priv->pPixmap->drawable; - dst_draw = (pDestBuffer->attachment == DRI2BufferFrontLeft) ? pDraw : - &dst_priv->pPixmap->drawable; - - /* - * The clients implements glXWaitX with a copy front to fake and then - * waiting on the server to signal its completion of it. While - * glXWaitGL is a client side flush and a copy from fake to front. - * This is how it is done in the DRI2 protocol, how ever depending - * which type of drawables the server does things a bit differently - * then what the protocol says as the fake and front are the same. - * - * for pixmaps glXWaitX is a server flush. - * for pixmaps glXWaitGL is a client flush. - * for windows glXWaitX is a copy from front to fake then a server flush. - * for windows glXWaitGL is a client flush then a copy from fake to front. - * - * XXX in the windows case this code always flushes but that isn't a - * must in the glXWaitGL case but we don't know if this is a glXWaitGL - * or a glFlush/glFinish call. - */ - if (dst_priv->pPixmap == src_priv->pPixmap) { - /* pixmap glXWaitX */ - if (pSrcBuffer->attachment == DRI2BufferFrontLeft && - pDestBuffer->attachment == DRI2BufferFakeFrontLeft) { - ms->ctx->flush(ms->ctx, NULL, 0); - return; - } - /* pixmap glXWaitGL */ - if (pDestBuffer->attachment == DRI2BufferFrontLeft && - pSrcBuffer->attachment == DRI2BufferFakeFrontLeft) { - return; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "copying between the same pixmap\n"); - } - } - - gc = GetScratchGC(pDraw->depth, pScreen); - copy_clip = REGION_CREATE(pScreen, NULL, 0); - REGION_COPY(pScreen, copy_clip, pRegion); - (*gc->funcs->ChangeClip) (gc, CT_REGION, copy_clip, 0); - ValidateGC(dst_draw, gc); - - /* If this is a full buffer swap, throttle on the previous one */ - if (ms->swapThrottling && - dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) { - BoxPtr extents = REGION_EXTENTS(pScreen, pRegion); - - if (extents->x1 == 0 && extents->y1 == 0 && - extents->x2 == pDraw->width && extents->y2 == pDraw->height) { - ms->screen->fence_finish(ms->screen, dst_priv->fence, - PIPE_TIMEOUT_INFINITE); - ms->screen->fence_reference(ms->screen, &dst_priv->fence, NULL); - } - } - - /* Try to make sure the blit will be accelerated */ - save_accel = ms->exa->accel; - ms->exa->accel = TRUE; - - if (pSrcBuffer->attachment != DRI2BufferFrontLeft) { - /* In case it won't be though, make sure the GPU copy contents of the - * source pixmap will be used for the software fallback - presumably the - * client modified them before calling in here. - */ - exaMoveInPixmap(src_priv->pPixmap); - DamageRegionAppend(src_draw, pRegion); - DamageRegionProcessPending(src_draw); - } - - if (cust && cust->winsys_context_throttle) - cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_SWAP); - - (*gc->ops->CopyArea)(src_draw, dst_draw, gc, - 0, 0, pDraw->width, pDraw->height, 0, 0); - ms->exa->accel = save_accel; - - FreeScratchGC(gc); - - ms->ctx->flush(ms->ctx, - (pDestBuffer->attachment == DRI2BufferFrontLeft - && ms->swapThrottling) ? - &dst_priv->fence : NULL, 0); - - if (cust && cust->winsys_context_throttle) - cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_RENDER); - -} - -Bool -xorg_dri2_init(ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); - modesettingPtr ms = modesettingPTR(pScrn); - DRI2InfoRec dri2info; -#if DRI2INFOREC_VERSION >= 2 - int major, minor; - - if (xf86LoaderCheckSymbol("DRI2Version")) { - DRI2Version(&major, &minor); - } else { - /* Assume version 1.0 */ - major = 1; - minor = 0; - } -#endif - - dri2info.version = min(DRI2INFOREC_VERSION, 3); - dri2info.fd = ms->fd; - - dri2info.driverName = pScrn->driverName; - dri2info.deviceName = "/dev/dri/card0"; /* FIXME */ - -#if DRI2INFOREC_VERSION >= 2 - dri2info.CreateBuffer = dri2_create_buffer; - dri2info.DestroyBuffer = dri2_destroy_buffer; -#endif - - /* For X servers in the 1.6.x series there where two DRI2 version. - * This allows us to build one binary that works on both servers. - */ -#if DRI2INFOREC_VERSION == 2 - if (minor == 0) { - set_format_in_do_create_buffer = FALSE; - dri2info.CreateBuffers = dri2_create_buffers; - dri2info.DestroyBuffers = dri2_destroy_buffers; - } else - set_format_in_do_create_buffer = FALSE; -#endif - - /* For version 1 set these unconditionaly. */ -#if DRI2INFOREC_VERSION == 1 - dri2info.CreateBuffers = dri2_create_buffers; - dri2info.DestroyBuffers = dri2_destroy_buffers; -#endif - dri2info.CopyRegion = dri2_copy_region; - dri2info.Wait = NULL; - - ms->d_depth_bits_last = - ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_Z24X8_UNORM, - PIPE_TEXTURE_2D, - 0, - PIPE_BIND_DEPTH_STENCIL); - ms->ds_depth_bits_last = - ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_Z24_UNORM_S8_UINT, - PIPE_TEXTURE_2D, - 0, - PIPE_BIND_DEPTH_STENCIL); - - return DRI2ScreenInit(pScreen, &dri2info); -} - -void -xorg_dri2_close(ScreenPtr pScreen) -{ - DRI2CloseScreen(pScreen); -} - -/* vim: set sw=4 ts=8 sts=4: */ |