From d7815f59134b0fb5cb3b56b72b22ba55002265ac Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 10 Nov 2006 00:14:30 +0000 Subject: Implement GLX_SGI_make_current_read Discontinue use of the old GetBuffeSize interface. Track both the current read-drawable and the current draw-drawable. After moving some context state to via_rednerbuffer, GLX_SGI_make_current_read can be enabled. The extension works, but the wincopy test prodcues a black window for the destination window. After messing around with the window and looking at the code, I believe the problem is in the handling of buffer swap requests on a drawable that isn't the current draw-drawable. --- src/mesa/drivers/dri/unichrome/via_context.c | 146 ++++++++++++++++++--------- src/mesa/drivers/dri/unichrome/via_context.h | 33 ++++-- src/mesa/drivers/dri/unichrome/via_ioctl.c | 34 ++++--- src/mesa/drivers/dri/unichrome/via_screen.c | 1 + src/mesa/drivers/dri/unichrome/via_span.c | 10 +- src/mesa/drivers/dri/unichrome/via_state.c | 14 ++- 6 files changed, 153 insertions(+), 85 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c index fa143186c1b..49c24656551 100644 --- a/src/mesa/drivers/dri/unichrome/via_context.c +++ b/src/mesa/drivers/dri/unichrome/via_context.c @@ -147,10 +147,13 @@ viaRenderbufferStorage(GLcontext *ctx, struct gl_renderbuffer *rb, static void -viaInitRenderbuffer(struct gl_renderbuffer *rb, GLenum format) +viaInitRenderbuffer(struct via_renderbuffer *vrb, GLenum format, + __DRIdrawablePrivate *dPriv) { const GLuint name = 0; + struct gl_renderbuffer *rb = & vrb->Base; + vrb->dPriv = dPriv; _mesa_init_renderbuffer(rb, name); /* Make sure we're using a null-valued GetPointer routine */ @@ -198,8 +201,9 @@ viaInitRenderbuffer(struct gl_renderbuffer *rb, GLenum format) * \sa AllocateBuffer */ static GLboolean -calculate_buffer_parameters( struct via_context *vmesa, - struct gl_framebuffer *fb ) +calculate_buffer_parameters(struct via_context *vmesa, + struct gl_framebuffer *fb, + __DRIdrawablePrivate *dPriv) { const unsigned shift = vmesa->viaScreen->bitsPerPixel / 16; const unsigned extra = 32; @@ -215,26 +219,28 @@ calculate_buffer_parameters( struct via_context *vmesa, if (!vmesa->front.Base.InternalFormat) { /* do one-time init for the renderbuffers */ - viaInitRenderbuffer(&vmesa->front.Base, GL_RGBA); + viaInitRenderbuffer(&vmesa->front, GL_RGBA, dPriv); viaSetSpanFunctions(&vmesa->front, &fb->Visual); _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &vmesa->front.Base); if (fb->Visual.doubleBufferMode) { - viaInitRenderbuffer(&vmesa->back.Base, GL_RGBA); + viaInitRenderbuffer(&vmesa->back, GL_RGBA, dPriv); viaSetSpanFunctions(&vmesa->back, &fb->Visual); _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &vmesa->back.Base); } if (vmesa->glCtx->Visual.depthBits > 0) { - viaInitRenderbuffer(&vmesa->depth.Base, + viaInitRenderbuffer(&vmesa->depth, (vmesa->glCtx->Visual.depthBits == 16 - ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT24)); + ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT24), + dPriv); viaSetSpanFunctions(&vmesa->depth, &fb->Visual); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &vmesa->depth.Base); } if (vmesa->glCtx->Visual.stencilBits > 0) { - viaInitRenderbuffer(&vmesa->stencil.Base, GL_STENCIL_INDEX8_EXT); + viaInitRenderbuffer(&vmesa->stencil, GL_STENCIL_INDEX8_EXT, + dPriv); viaSetSpanFunctions(&vmesa->stencil, &fb->Visual); _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &vmesa->stencil.Base); } @@ -243,11 +249,9 @@ calculate_buffer_parameters( struct via_context *vmesa, assert(vmesa->front.Base.InternalFormat); assert(vmesa->front.Base.AllocStorage); if (fb->Visual.doubleBufferMode) { - assert(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); - assert(vmesa->front.Base.AllocStorage); + assert(vmesa->back.Base.AllocStorage); } if (fb->Visual.depthBits) { - assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer); assert(vmesa->depth.Base.AllocStorage); } @@ -352,19 +356,11 @@ void viaReAllocateBuffers(GLcontext *ctx, GLframebuffer *drawbuffer, { struct via_context *vmesa = VIA_CONTEXT(ctx); - calculate_buffer_parameters( vmesa, drawbuffer ); + calculate_buffer_parameters(vmesa, drawbuffer, vmesa->driDrawable); _mesa_resize_framebuffer(ctx, drawbuffer, width, height); } -static void viaBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height) -{ - GET_CURRENT_CONTEXT(ctx); - struct via_context *vmesa = VIA_CONTEXT(ctx); - *width = vmesa->driDrawable->w; - *height = vmesa->driDrawable->h; -} - /* Extension strings exported by the Unichrome driver. */ const struct dri_extension card_extensions[] = @@ -579,7 +575,6 @@ viaCreateContext(const __GLcontextModes *visual, ctx->Const.MaxPointSizeAA = 1.0; ctx->Const.PointSizeGranularity = 1.0; - ctx->Driver.GetBufferSize = viaBufferSize; ctx->Driver.GetString = viaGetString; ctx->DriverCtx = (void *)vmesa; @@ -734,50 +729,72 @@ viaDestroyContext(__DRIcontextPrivate *driContextPriv) void viaXMesaWindowMoved(struct via_context *vmesa) { - __DRIdrawablePrivate *dPriv = vmesa->driDrawable; + __DRIdrawablePrivate *const drawable = vmesa->driDrawable; + __DRIdrawablePrivate *const readable = vmesa->driReadable; + struct via_renderbuffer *const draw_buffer = + (struct via_renderbuffer *) drawable->driverPrivate; + struct via_renderbuffer *const read_buffer = + (struct via_renderbuffer *) readable->driverPrivate; GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; - if (!dPriv) + if (!drawable) return; switch (vmesa->glCtx->DrawBuffer->_ColorDrawBufferMask[0]) { case BUFFER_BIT_BACK_LEFT: - if (dPriv->numBackClipRects == 0) { - vmesa->numClipRects = dPriv->numClipRects; - vmesa->pClipRects = dPriv->pClipRects; + if (drawable->numBackClipRects == 0) { + vmesa->numClipRects = drawable->numClipRects; + vmesa->pClipRects = drawable->pClipRects; } else { - vmesa->numClipRects = dPriv->numBackClipRects; - vmesa->pClipRects = dPriv->pBackClipRects; + vmesa->numClipRects = drawable->numBackClipRects; + vmesa->pClipRects = drawable->pBackClipRects; } break; case BUFFER_BIT_FRONT_LEFT: - vmesa->numClipRects = dPriv->numClipRects; - vmesa->pClipRects = dPriv->pClipRects; + vmesa->numClipRects = drawable->numClipRects; + vmesa->pClipRects = drawable->pClipRects; break; default: vmesa->numClipRects = 0; break; } - if (vmesa->drawW != dPriv->w || - vmesa->drawH != dPriv->h) - calculate_buffer_parameters( vmesa, vmesa->glCtx->DrawBuffer ); + if ((draw_buffer->drawW != drawable->w) + || (draw_buffer->drawH != drawable->h)) { + calculate_buffer_parameters(vmesa, vmesa->glCtx->DrawBuffer, + drawable); + } - vmesa->drawXoff = (GLuint)(((dPriv->x * bytePerPixel) & 0x1f) / + draw_buffer->drawXoff = (GLuint)(((drawable->x * bytePerPixel) & 0x1f) / bytePerPixel); - vmesa->drawX = dPriv->x - vmesa->drawXoff; - vmesa->drawY = dPriv->y; - vmesa->drawW = dPriv->w; - vmesa->drawH = dPriv->h; + draw_buffer->drawX = drawable->x - draw_buffer->drawXoff; + draw_buffer->drawY = drawable->y; + draw_buffer->drawW = drawable->w; + draw_buffer->drawH = drawable->h; + + if (drawable != readable) { + if ((read_buffer->drawW != readable->w) + || (read_buffer->drawH != readable->h)) { + calculate_buffer_parameters(vmesa, vmesa->glCtx->ReadBuffer, + readable); + } + + read_buffer->drawXoff = (GLuint)(((readable->x * bytePerPixel) & 0x1f) / + bytePerPixel); + read_buffer->drawX = readable->x - read_buffer->drawXoff; + read_buffer->drawY = readable->y; + read_buffer->drawW = readable->w; + read_buffer->drawH = readable->h; + } vmesa->front.orig = (vmesa->front.offset + - vmesa->drawY * vmesa->front.pitch + - vmesa->drawX * bytePerPixel); + draw_buffer->drawY * vmesa->front.pitch + + draw_buffer->drawX * bytePerPixel); vmesa->front.origMap = (vmesa->front.map + - vmesa->drawY * vmesa->front.pitch + - vmesa->drawX * bytePerPixel); + draw_buffer->drawY * vmesa->front.pitch + + draw_buffer->drawX * bytePerPixel); vmesa->back.orig = vmesa->back.offset; vmesa->depth.orig = vmesa->depth.offset; @@ -813,15 +830,41 @@ viaMakeCurrent(__DRIcontextPrivate *driContextPriv, drawBuffer = (GLframebuffer *)driDrawPriv->driverPrivate; readBuffer = (GLframebuffer *)driReadPriv->driverPrivate; - if ( vmesa->driDrawable != driDrawPriv ) { - driDrawableInitVBlank( driDrawPriv, vmesa->vblank_flags, - &vmesa->vbl_seq ); - vmesa->driDrawable = driDrawPriv; - if ( ! calculate_buffer_parameters( vmesa, drawBuffer ) ) { - return GL_FALSE; - } + if (vmesa->driDrawable != driDrawPriv) { + driDrawableInitVBlank(driDrawPriv, vmesa->vblank_flags, + &vmesa->vbl_seq); } + if ((vmesa->driDrawable != driDrawPriv) + || (vmesa->driReadable != driReadPriv)) { + vmesa->driDrawable = driDrawPriv; + vmesa->driReadable = driReadPriv; + + if ((drawBuffer->Width != driDrawPriv->w) + || (drawBuffer->Height != driDrawPriv->h)) { + _mesa_resize_framebuffer(ctx, drawBuffer, + driDrawPriv->w, driDrawPriv->h); + drawBuffer->Initialized = GL_TRUE; + } + + if (!calculate_buffer_parameters(vmesa, drawBuffer, driDrawPriv)) { + return GL_FALSE; + } + + if (driDrawPriv != driReadPriv) { + if ((readBuffer->Width != driReadPriv->w) + || (readBuffer->Height != driReadPriv->h)) { + _mesa_resize_framebuffer(ctx, readBuffer, + driReadPriv->w, driReadPriv->h); + readBuffer->Initialized = GL_TRUE; + } + + if (!calculate_buffer_parameters(vmesa, readBuffer, driReadPriv)) { + return GL_FALSE; + } + } + } + _mesa_make_current(vmesa->glCtx, drawBuffer, readBuffer); ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] ); @@ -847,7 +890,10 @@ void viaGetLock(struct via_context *vmesa, GLuint flags) drmGetLock(vmesa->driFd, vmesa->hHWContext, flags); - DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv ); + DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); + if (dPriv != vmesa->driReadable) { + DRI_VALIDATE_DRAWABLE_INFO(sPriv, vmesa->driReadable); + } if (vmesa->sarea->ctxOwner != vmesa->hHWContext) { vmesa->sarea->ctxOwner = vmesa->hHWContext; diff --git a/src/mesa/drivers/dri/unichrome/via_context.h b/src/mesa/drivers/dri/unichrome/via_context.h index 9d7a0e6cb64..77161a8d5df 100644 --- a/src/mesa/drivers/dri/unichrome/via_context.h +++ b/src/mesa/drivers/dri/unichrome/via_context.h @@ -98,6 +98,18 @@ struct via_renderbuffer { * at (drawX,drawY) in screen space. */ char *origMap; + + int drawX; /* origin of drawable in draw buffer */ + int drawY; + int drawW; + int drawH; + + int drawXoff; /* drawX is 32byte aligned - this is + * the delta to the real origin, in + * pixel units. + */ + + __DRIdrawablePrivate *dPriv; }; @@ -272,16 +284,6 @@ struct via_context { struct via_renderbuffer *drawBuffer; - int drawX; /* origin of drawable in draw buffer */ - int drawY; - int drawW; - int drawH; - - int drawXoff; /* drawX is 32byte aligned - this is - * the delta to the real origin, in - * pixel units. - */ - GLuint numClipRects; /* cliprects for that buffer */ drm_clip_rect_t *pClipRects; @@ -294,7 +296,16 @@ struct via_context { int driFd; __DRInativeDisplay *display; - __DRIdrawablePrivate *driDrawable; + /** + * DRI drawable bound to this context for drawing. + */ + __DRIdrawablePrivate *driDrawable; + + /** + * DRI drawable bound to this context for reading. + */ + __DRIdrawablePrivate *driReadable; + __DRIscreenPrivate *driScreen; viaScreenPrivate *viaScreen; drm_via_sarea_t *sarea; diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.c b/src/mesa/drivers/dri/unichrome/via_ioctl.c index dd2e93b286f..5d102de93ed 100644 --- a/src/mesa/drivers/dri/unichrome/via_ioctl.c +++ b/src/mesa/drivers/dri/unichrome/via_ioctl.c @@ -182,8 +182,8 @@ static void viaFillBuffer(struct via_context *vmesa, GLuint i; for (i = 0; i < nboxes ; i++) { - int x = pbox[i].x1 - vmesa->drawX; - int y = pbox[i].y1 - vmesa->drawY; + int x = pbox[i].x1 - buffer->drawX; + int y = pbox[i].y1 - buffer->drawY; int w = pbox[i].x2 - pbox[i].x1; int h = pbox[i].y2 - pbox[i].y1; @@ -206,6 +206,8 @@ static void viaClear(GLcontext *ctx, GLbitfield mask) { struct via_context *vmesa = VIA_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = vmesa->driDrawable; + struct via_renderbuffer *const vrb = + (struct via_renderbuffer *) dPriv->driverPrivate; int flag = 0; GLuint i = 0; GLuint clear_depth_mask = 0xf << 28; @@ -274,8 +276,8 @@ static void viaClear(GLcontext *ctx, GLbitfield mask) /* flip top to bottom */ cy = dPriv->h - cy - ch; - cx += vmesa->drawX + vmesa->drawXoff; - cy += vmesa->drawY; + cx += vrb->drawX + vrb->drawXoff; + cy += vrb->drawY; if (!all) { drm_clip_rect_t *b = vmesa->pClipRects; @@ -352,8 +354,8 @@ static void viaDoSwapBuffers(struct via_context *vmesa, GLuint i; for (i = 0; i < nbox; i++, b++) { - GLint x = b->x1 - vmesa->drawX; - GLint y = b->y1 - vmesa->drawY; + GLint x = b->x1 - back->drawX; + GLint y = b->y1 - back->drawY; GLint w = b->x2 - b->x1; GLint h = b->y2 - b->y1; @@ -766,7 +768,7 @@ static void via_emit_cliprect(struct via_context *vmesa, vb[4] = (HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF); vb[5] = (HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000) >> 24); - vb[6] = (HC_SubA_HSPXYOS << 24) | ((31-vmesa->drawXoff) << HC_HSPXOS_SHIFT); + vb[6] = (HC_SubA_HSPXYOS << 24) | ((31 - buffer->drawXoff) << HC_HSPXOS_SHIFT); vb[7] = (HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch; } @@ -881,21 +883,25 @@ void viaFlushDmaLocked(struct via_context *vmesa, GLuint flags) } else if (vmesa->numClipRects) { drm_clip_rect_t *pbox = vmesa->pClipRects; - + __DRIdrawablePrivate *dPriv = vmesa->driDrawable; + struct via_renderbuffer *const vrb = + (struct via_renderbuffer *) dPriv->driverPrivate; + + for (i = 0; i < vmesa->numClipRects; i++) { drm_clip_rect_t b; - b.x1 = pbox[i].x1 - (vmesa->drawX + vmesa->drawXoff); - b.x2 = pbox[i].x2 - (vmesa->drawX + vmesa->drawXoff); - b.y1 = pbox[i].y1 - vmesa->drawY; - b.y2 = pbox[i].y2 - vmesa->drawY; + b.x1 = pbox[i].x1 - (vrb->drawX + vrb->drawXoff); + b.x2 = pbox[i].x2 - (vrb->drawX + vrb->drawXoff); + b.y1 = pbox[i].y1 - vrb->drawY; + b.y2 = pbox[i].y2 - vrb->drawY; if (vmesa->scissor && !intersect_rect(&b, &b, &vmesa->scissorRect)) continue; - b.x1 += vmesa->drawXoff; - b.x2 += vmesa->drawXoff; + b.x1 += vrb->drawXoff; + b.x2 += vrb->drawXoff; via_emit_cliprect(vmesa, &b); diff --git a/src/mesa/drivers/dri/unichrome/via_screen.c b/src/mesa/drivers/dri/unichrome/via_screen.c index 98a742c720f..28e1f9451e6 100644 --- a/src/mesa/drivers/dri/unichrome/via_screen.c +++ b/src/mesa/drivers/dri/unichrome/via_screen.c @@ -182,6 +182,7 @@ viaInitDriver(__DRIscreenPrivate *sPriv) (*glx_enable_extension)( psc, "GLX_MESA_swap_control" ); } + (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" ); (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" ); } diff --git a/src/mesa/drivers/dri/unichrome/via_span.c b/src/mesa/drivers/dri/unichrome/via_span.c index 6ff95cc444c..f1ed98036bf 100644 --- a/src/mesa/drivers/dri/unichrome/via_span.c +++ b/src/mesa/drivers/dri/unichrome/via_span.c @@ -41,13 +41,12 @@ #undef LOCAL_VARS #define LOCAL_VARS \ - struct via_context *vmesa = VIA_CONTEXT(ctx); \ - __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \ struct via_renderbuffer *vrb = (struct via_renderbuffer *) rb; \ + __DRIdrawablePrivate *dPriv = vrb->dPriv; \ GLuint pitch = vrb->pitch; \ GLuint height = dPriv->h; \ GLint p = 0; \ - char *buf = (char *)(vrb->origMap + vmesa->drawXoff * vrb->bpp); \ + char *buf = (char *)(vrb->origMap + vrb->drawXoff * vrb->bpp); \ (void) p; /* ================================================================ @@ -79,12 +78,11 @@ /* 16 bit depthbuffer functions. */ #define LOCAL_DEPTH_VARS \ - struct via_context *vmesa = VIA_CONTEXT(ctx); \ - __DRIdrawablePrivate *dPriv = vmesa->driDrawable; \ struct via_renderbuffer *vrb = (struct via_renderbuffer *) rb; \ + __DRIdrawablePrivate *dPriv = vrb->dPriv; \ GLuint depth_pitch = vrb->pitch; \ GLuint height = dPriv->h; \ - char *buf = (char *)(vrb->map + (vmesa->drawXoff * vrb->bpp/8)) + char *buf = (char *)(vrb->map + (vrb->drawXoff * vrb->bpp/8)) #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS diff --git a/src/mesa/drivers/dri/unichrome/via_state.c b/src/mesa/drivers/dri/unichrome/via_state.c index c001661d0b6..2c9cfca522e 100644 --- a/src/mesa/drivers/dri/unichrome/via_state.c +++ b/src/mesa/drivers/dri/unichrome/via_state.c @@ -476,6 +476,9 @@ void viaEmitState(struct via_context *vmesa) */ if (ctx->Polygon.StippleFlag) { GLuint *stipple = &ctx->PolygonStipple[0]; + __DRIdrawablePrivate *dPriv = vmesa->driDrawable; + struct via_renderbuffer *const vrb = + (struct via_renderbuffer *) dPriv->driverPrivate; GLint i; BEGIN_RING(38); @@ -498,9 +501,9 @@ void viaEmitState(struct via_context *vmesa) OUT_RING( HC_HEADER2 ); OUT_RING( (HC_ParaType_NotTex << 16) ); OUT_RING( (HC_SubA_HSPXYOS << 24) | - (((32- vmesa->drawXoff) & 0x1f) << HC_HSPXOS_SHIFT)); + (((32- vrb->drawXoff) & 0x1f) << HC_HSPXOS_SHIFT)); OUT_RING( (HC_SubA_HSPXYOS << 24) | - (((32 - vmesa->drawXoff) & 0x1f) << HC_HSPXOS_SHIFT)); + (((32 - vrb->drawXoff) & 0x1f) << HC_HSPXOS_SHIFT)); ADVANCE_RING(); } @@ -720,15 +723,18 @@ static void viaColorMask(GLcontext *ctx, void viaCalcViewport(GLcontext *ctx) { struct via_context *vmesa = VIA_CONTEXT(ctx); + __DRIdrawablePrivate *dPriv = vmesa->driDrawable; + struct via_renderbuffer *const vrb = + (struct via_renderbuffer *) dPriv->driverPrivate; const GLfloat *v = ctx->Viewport._WindowMap.m; GLfloat *m = vmesa->ViewportMatrix.m; /* See also via_translate_vertex. */ m[MAT_SX] = v[MAT_SX]; - m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X + vmesa->drawXoff; + m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X + vrb->drawXoff; m[MAT_SY] = - v[MAT_SY]; - m[MAT_TY] = - v[MAT_TY] + vmesa->driDrawable->h + SUBPIXEL_Y; + m[MAT_TY] = - v[MAT_TY] + dPriv->h + SUBPIXEL_Y; m[MAT_SZ] = v[MAT_SZ] * (1.0 / vmesa->depth_max); m[MAT_TZ] = v[MAT_TZ] * (1.0 / vmesa->depth_max); } -- cgit v1.2.3