diff options
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/state_trackers/dri/dri_drawable.c | 73 | ||||
-rw-r--r-- | src/gallium/state_trackers/dri/dri_drawable.h | 2 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_dri2.c | 46 | ||||
-rw-r--r-- | src/gallium/winsys/drm/intel/gem/intel_be_context.c | 3 |
4 files changed, 100 insertions, 24 deletions
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c index 0a952f7b28..acec719037 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -44,14 +44,6 @@ #include "util/u_memory.h" -static void -dri_copy_to_front(__DRIdrawablePrivate * dPriv, - struct pipe_surface *from, - int x, int y, unsigned w, unsigned h) -{ - /* TODO send a message to the Xserver to copy to the real front buffer */ -} - static struct pipe_surface * dri_surface_from_handle(struct drm_api *api, struct pipe_screen *screen, @@ -96,6 +88,35 @@ dri_surface_from_handle(struct drm_api *api, } /** + * Pixmaps have will have the same name of fake front and front. + */ +static boolean +dri2_check_if_pixmap(__DRIbuffer *buffers, int count) +{ + boolean found = FALSE; + boolean is_pixmap = FALSE; + unsigned name; + int i; + + for (i = 0; i < count; i++) { + switch (buffers[i].attachment) { + case __DRI_BUFFER_FRONT_LEFT: + case __DRI_BUFFER_FAKE_FRONT_LEFT: + if (found) { + is_pixmap = buffers[i].name == name; + } else { + name = buffers[i].name; + found = TRUE; + } + default: + continue; + } + } + + return is_pixmap; +} + +/** * This will be called a drawable is known to have been resized. */ void @@ -153,15 +174,15 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv) memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * count); } + drawable->is_pixmap = dri2_check_if_pixmap(buffers, count); + for (i = 0; i < count; i++) { enum pipe_format format = 0; int index = 0; switch (buffers[i].attachment) { case __DRI_BUFFER_FRONT_LEFT: - index = ST_SURFACE_FRONT_LEFT; - format = drawable->color_format; - break; + continue; case __DRI_BUFFER_FAKE_FRONT_LEFT: index = ST_SURFACE_FRONT_LEFT; format = drawable->color_format; @@ -233,8 +254,25 @@ dri_flush_frontbuffer(struct pipe_screen *screen, struct pipe_surface *surf, void *context_private) { struct dri_context *ctx = (struct dri_context *)context_private; + struct dri_drawable *drawable = dri_drawable(ctx->dPriv); + __DRIdrawable *dri_drawable = ctx->dPriv; + __DRIscreen *dri_screen = ctx->sPriv; + + /* XXX Does this function get called with DRI1? */ + + if (ctx->dPriv == NULL) { + debug_printf("%s: no drawable bound to context\n", __func__); + return; + } + +#if 0 + /* TODO if rendering to pixmaps is slow enable this code. */ + if (drawable->is_pixmap) + return; +#endif - dri_copy_to_front(ctx->dPriv, surf, 0, 0, surf->width, surf->height); + (*dri_screen->dri2.loader->flushFrontBuffer)(dri_drawable, + dri_drawable->loaderPrivate); } /** @@ -259,26 +297,20 @@ dri_create_buffer(__DRIscreenPrivate * sPriv, drawable->color_format = (visual->redBits == 8) ? PIPE_FORMAT_A8R8G8B8_UNORM : PIPE_FORMAT_R5G6B5_UNORM; - debug_printf("Red bits is %d\n", visual->redBits); - switch(visual->depthBits) { default: case 0: - debug_printf("Depth buffer 0.\n"); drawable->depth_format = PIPE_FORMAT_NONE; break; case 16: - debug_printf("Depth buffer 16.\n"); drawable->depth_format = PIPE_FORMAT_Z16_UNORM; break; case 24: if (visual->stencilBits == 0) { - debug_printf("Depth buffer 24. Stencil 0.\n"); drawable->depth_format = (screen->d_depth_bits_last) ? PIPE_FORMAT_X8Z24_UNORM: PIPE_FORMAT_Z24X8_UNORM; } else { - debug_printf("Combined depth stencil 24 / 8.\n"); drawable->depth_format = (screen->sd_depth_bits_last) ? PIPE_FORMAT_S8Z24_UNORM: PIPE_FORMAT_Z24S8_UNORM; @@ -312,12 +344,11 @@ dri_create_buffer(__DRIscreenPrivate * sPriv, dPriv->driverPrivate = (void *)drawable; /* setup dri2 buffers information */ + /* TODO incase of double buffer visual, delay fake creation */ i = 0; drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT; -#if 0 - /* TODO incase of double buffer visual, delay fake creation */ drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT; -#endif + if (visual->doubleBufferMode) drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT; if (visual->depthBits) diff --git a/src/gallium/state_trackers/dri/dri_drawable.h b/src/gallium/state_trackers/dri/dri_drawable.h index dfd0b8766d..eaf0b954bd 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.h +++ b/src/gallium/state_trackers/dri/dri_drawable.h @@ -46,6 +46,8 @@ struct dri_drawable unsigned attachments[8]; unsigned num_attachments; + boolean is_pixmap; + __DRIbuffer old[8]; unsigned old_num; unsigned old_w; diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index 3fbab4dc51..f089965b03 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -97,6 +97,11 @@ driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count) template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL; 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, @@ -171,12 +176,53 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion, GCPtr gc; RegionPtr copy_clip; + /* + * 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_pixmap = src_priv->pPixmap; dst_pixmap = dst_priv->pPixmap; if (pSrcBuffer->attachment == DRI2BufferFrontLeft) src_pixmap = (PixmapPtr)pDraw; if (pDestBuffer->attachment == DRI2BufferFrontLeft) dst_pixmap = (PixmapPtr)pDraw; + + /* + * 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_pixmap == src_pixmap) { + /* pixmap glXWaitX */ + if (pSrcBuffer->attachment == DRI2BufferFrontLeft && + pDestBuffer->attachment == DRI2BufferFakeFrontLeft) { + ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS, NULL); + 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); diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_context.c b/src/gallium/winsys/drm/intel/gem/intel_be_context.c index 629987c6f9..ff4518f868 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_context.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_context.c @@ -57,9 +57,6 @@ intel_be_batch_flush(struct i915_winsys *sws, struct intel_be_context *intel = intel_be_context(sws); struct intel_be_fence **f = (struct intel_be_fence **)fence; - if (fence && *fence) - assert(0); - intel_be_batchbuffer_flush(intel->batch, f); } |