X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fstate_trackers%2Fxorg%2Fxorg_dri2.c;h=adc9531dbd3e38fdc005998e56e2ae2386841b54;hb=e73553bff74a41f08cba9d52b5fec19f15ab3d48;hp=7d6954016fe70053c919dad6ce9aba12d39d01c0;hpb=476290946e7bd3b7fe5688622127d8c6a9c7f367;p=mesa.git diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index 7d6954016fe..adc9531dbd3 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -33,6 +33,7 @@ #include "xf86_OSproc.h" #include "xorg_tracker.h" +#include "xorg_exa.h" #include "dri2.h" @@ -44,107 +45,192 @@ typedef struct { PixmapPtr pPixmap; struct pipe_texture *tex; - struct pipe_buffer *buf; struct pipe_fence_handle *fence; } *BufferPrivatePtr; -static DRI2BufferPtr -driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count) +static Bool +driDoCreateBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format) { - struct pipe_texture *depth, *tex; - struct pipe_buffer *buf; + struct pipe_texture *tex = NULL; ScreenPtr pScreen = pDraw->pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; modesettingPtr ms = modesettingPTR(pScrn); - BufferPrivatePtr privates; - DRI2BufferPtr buffers; + struct exa_pixmap_priv *exa_priv; + BufferPrivatePtr private = buffer->driverPrivate; PixmapPtr pPixmap; unsigned stride, handle; - boolean have_depth = FALSE, have_stencil = FALSE; - int i; - - buffers = xcalloc(count, sizeof *buffers); - if (!buffers) - goto fail_buffers; - - privates = xcalloc(count, sizeof *privates); - if (!privates) - goto fail_privates; - - for (i = 0; i < count; i++) { - if (attachments[i] == DRI2BufferDepth) - have_depth = TRUE; - else if (attachments[i] == DRI2BufferStencil) - have_stencil = TRUE; - } - - if (have_stencil && !have_depth) - FatalError("Doesn't support only stencil yet\n"); - depth = NULL; - for (i = 0; i < count; i++) { - pPixmap = NULL; - tex = NULL; - buf = NULL; - if (attachments[i] == DRI2BufferFrontLeft) { - if (pDraw->type == DRAWABLE_PIXMAP) - pPixmap = (PixmapPtr) pDraw; - else - pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw); - pPixmap->refcnt++; - tex = xorg_exa_get_texture(pPixmap); - } else if (attachments[i] == DRI2BufferStencil) { - pipe_texture_reference(&tex, depth); - } else if (attachments[i] == DRI2BufferDepth) { + 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 defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2 + case DRI2BufferDepthStencil: +#else + /* Works on old X servers because sanity checking is for the weak */ + case 9: +#endif + if (exa_priv->depth_stencil_tex && + !pf_is_depth_stencil(exa_priv->depth_stencil_tex->format)) + exa_priv->depth_stencil_tex = NULL; + /* Fall through */ + case DRI2BufferDepth: + if (exa_priv->depth_stencil_tex) + pipe_texture_reference(&tex, exa_priv->depth_stencil_tex); + else { struct pipe_texture template; memset(&template, 0, sizeof(template)); template.target = PIPE_TEXTURE_2D; - if (have_stencil) + if (buffer->attachment == DRI2BufferDepth) template.format = ms->ds_depth_bits_last ? - PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM; - else - template.format = ms->d_depth_bits_last ? PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM; + else + template.format = ms->ds_depth_bits_last ? + PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM; pf_get_block(template.format, &template.block); template.width[0] = pDraw->width; template.height[0] = pDraw->height; template.depth[0] = 1; template.last_level = 0; - template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL; + template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL | + PIPE_TEXTURE_USAGE_DISPLAY_TARGET; tex = ms->screen->texture_create(ms->screen, &template); - depth = tex; - } else if (attachments[i] == DRI2BufferFakeFrontLeft && - pDraw->type == DRAWABLE_PIXMAP) { - pPixmap = (PixmapPtr) pDraw; - pPixmap->refcnt++; - tex = xorg_exa_get_texture(pPixmap); - } else { - pPixmap = (*pScreen->CreatePixmap)(pScreen, pDraw->width, - pDraw->height, - pDraw->depth, - 0); - tex = xorg_exa_get_texture(pPixmap); + pipe_texture_reference(&exa_priv->depth_stencil_tex, tex); } + break; + } + + if (!private->pPixmap) { + private->pPixmap = pPixmap; + pPixmap->refcnt++; + } + + if (!tex) { + exaMoveInPixmap(private->pPixmap); + xorg_exa_set_shared_usage(private->pPixmap); + pScreen->ModifyPixmapHeader(private->pPixmap, 0, 0, 0, 0, 0, NULL); + tex = xorg_exa_get_texture(private->pPixmap); + } + + if (!tex) + FatalError("NO TEXTURE IN DRI2\n"); + + ms->api->shared_handle_from_texture(ms->api, ms->screen, tex, &stride, &handle); + + buffer->name = handle; + buffer->pitch = stride; + buffer->cpp = 4; + buffer->driverPrivate = private; + buffer->flags = 0; /* not tiled */ +#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION == 2 + ((DRI2Buffer2Ptr)buffer)->format = 0; +#elif defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION >= 3 + buffer->format = 0; +#endif + private->tex = tex; + + return TRUE; +} + +static void +driDoDestroyBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer) +{ + ScreenPtr pScreen = pDraw->pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + BufferPrivatePtr private = buffer->driverPrivate; + struct exa_pixmap_priv *exa_priv = exaGetPixmapDriverPrivate(private->pPixmap); + + pipe_texture_reference(&private->tex, NULL); + ms->screen->fence_reference(ms->screen, &private->fence, NULL); + pipe_texture_reference(&exa_priv->depth_stencil_tex, NULL); + (*pScreen->DestroyPixmap)(private->pPixmap); +} - if (!tex) - FatalError("NO TEXTURE IN DRI2\n"); +#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION >= 2 - ms->api->buffer_from_texture(ms->api, tex, &buf, &stride); - ms->api->global_handle_from_buffer(ms->api, ms->screen, buf, &handle); +static DRI2Buffer2Ptr +driCreateBuffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format) +{ + DRI2Buffer2Ptr buffer; + BufferPrivatePtr private; + + buffer = xcalloc(1, sizeof *buffer); + if (!buffer) + return NULL; + + private = xcalloc(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 (driDoCreateBuffer(pDraw, (DRI2BufferPtr)buffer, format)) + return buffer; + + xfree(private); +fail: + xfree(buffer); + return NULL; +} + +static void +driDestroyBuffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer) +{ + /* So far it is safe to downcast a DRI2Buffer2Ptr to DRI2BufferPtr */ + driDoDestroyBuffer(pDraw, (DRI2BufferPtr)buffer); + + xfree(buffer->driverPrivate); + xfree(buffer); +} + +#else /* !defined(DRI2INFOREC_VERSION) || DRI2INFOREC_VERSION < 2 */ + +static DRI2BufferPtr +driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count) +{ + BufferPrivatePtr privates; + DRI2BufferPtr buffers; + int i; - buffers[i].name = handle; + buffers = xcalloc(count, sizeof *buffers); + if (!buffers) + goto fail_buffers; + + privates = xcalloc(count, sizeof *privates); + if (!privates) + goto fail_privates; + + for (i = 0; i < count; i++) { buffers[i].attachment = attachments[i]; - buffers[i].pitch = stride; - buffers[i].cpp = 4; buffers[i].driverPrivate = &privates[i]; - buffers[i].flags = 0; /* not tiled */ - privates[i].pPixmap = pPixmap; - privates[i].buf = buf; - privates[i].tex = tex; + + if (!driDoCreateBuffer(pDraw, &buffers[i], 0)) + goto fail; } return buffers; +fail: + xfree(privates); fail_privates: xfree(buffers); fail_buffers: @@ -154,22 +240,10 @@ fail_buffers: static void driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count) { - ScreenPtr pScreen = pDraw->pScreen; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - modesettingPtr ms = modesettingPTR(pScrn); - BufferPrivatePtr private; int i; - (void)ms; for (i = 0; i < count; i++) { - private = buffers[i].driverPrivate; - - pipe_texture_reference(&private->tex, NULL); - pipe_buffer_reference(&private->buf, NULL); - ms->screen->fence_reference(ms->screen, &private->fence, NULL); - - if (private->pPixmap) - (*pScreen->DestroyPixmap)(private->pPixmap); + driDoDestroyBuffer(pDraw, &buffers[i]); } if (buffers) { @@ -178,6 +252,8 @@ driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count) } } +#endif /* defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION >= 2 */ + static void driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion, DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer) @@ -273,18 +349,25 @@ driScreenInit(ScreenPtr pScreen) modesettingPtr ms = modesettingPTR(pScrn); DRI2InfoRec dri2info; - dri2info.version = 1; - dri2info.fd = ms->fd; -#if 0 - dri2info.driverName = pScrn->name; +#if defined(DRI2INFOREC_VERSION) + dri2info.version = DRI2INFOREC_VERSION; #else - dri2info.driverName = "i915"; /* FIXME */ + dri2info.version = 1; #endif + dri2info.fd = ms->fd; + + dri2info.driverName = pScrn->driverName; dri2info.deviceName = "/dev/dri/card0"; /* FIXME */ +#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION >= 2 + dri2info.CreateBuffer = driCreateBuffer; + dri2info.DestroyBuffer = driDestroyBuffer; +#else dri2info.CreateBuffers = driCreateBuffers; dri2info.DestroyBuffers = driDestroyBuffers; +#endif dri2info.CopyRegion = driCopyRegion; + dri2info.Wait = NULL; ms->d_depth_bits_last = ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_X8Z24_UNORM,