From: Dave Airlie Date: Mon, 2 Mar 2009 17:27:59 +0000 (+1000) Subject: radeon: refactor framebuffer code like intel X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2b85fccae5ba33748846f74f90fe0f72c673a4b1;p=mesa.git radeon: refactor framebuffer code like intel this is a step towards fbos and should fix pageflipping, but I think the first flip seems broken. --- diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index a744469b31c..10a6362afd2 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -261,9 +261,9 @@ static void r200_init_vtbl(radeonContextPtr radeon) { radeon->vtbl.get_lock = r200_get_lock; radeon->vtbl.update_viewport_offset = r200UpdateViewportOffset; - radeon->vtbl.update_draw_buffer = r200UpdateDrawBuffer; radeon->vtbl.emit_cs_header = r200_vtbl_emit_cs_header; radeon->vtbl.swtcl_flush = r200_swtcl_flush; + radeon->vtbl.fallback = r200Fallback; } diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c index c08968f7f86..6076b6d7ea4 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.c +++ b/src/mesa/drivers/dri/r200/r200_ioctl.c @@ -203,7 +203,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask ) GLint ret; if ( R200_DEBUG & DEBUG_IOCTL ) { - fprintf( stderr, "r200Clear\n"); + fprintf( stderr, "r200Clear %x %d\n", mask, rmesa->radeon.sarea->pfCurrentPage); } { diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index 126f78b39ca..46baad33f5c 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -1639,6 +1639,8 @@ static void r200Viewport( GLcontext *ctx, GLint x, GLint y, * values, or keep the originals hanging around. */ r200UpdateWindow( ctx ); + + radeon_viewport(ctx, x, y, width, height); } static void r200DepthRange( GLcontext *ctx, GLclampd nearval, @@ -1754,47 +1756,6 @@ static void r200LogicOpCode( GLcontext *ctx, GLenum opcode ) rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = r200_rop_tab[rop]; } - -static void r200DrawBuffer( GLcontext *ctx, GLenum mode ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s %s\n", __FUNCTION__, - _mesa_lookup_enum_by_nr( mode )); - - radeon_firevertices(&rmesa->radeon); /* don't pipeline cliprect changes */ - - if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) { - /* 0 (GL_NONE) buffers or multiple color drawing buffers */ - FALLBACK( rmesa, R200_FALLBACK_DRAW_BUFFER, GL_TRUE ); - return; - } - - switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) { - case BUFFER_FRONT_LEFT: - case BUFFER_BACK_LEFT: - FALLBACK( rmesa, R200_FALLBACK_DRAW_BUFFER, GL_FALSE ); - break; - default: - FALLBACK( rmesa, R200_FALLBACK_DRAW_BUFFER, GL_TRUE ); - return; - } - - radeonSetCliprects( &rmesa->radeon ); - radeonUpdatePageFlipping(&rmesa->radeon); - - /* We'll set the drawing engine's offset/pitch parameters later - * when we update other state. - */ -} - - -static void r200ReadBuffer( GLcontext *ctx, GLenum mode ) -{ - /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ -} - /* ============================================================= * State enable/disable */ @@ -2289,47 +2250,6 @@ static void update_texturematrix( GLcontext *ctx ) } } - - -/** - * Tell the card where to render (offset, pitch). - * Effected by glDrawBuffer, etc - */ -void -r200UpdateDrawBuffer(GLcontext *ctx) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - struct gl_framebuffer *fb = ctx->DrawBuffer; - struct radeon_renderbuffer *rrb; - - if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { - /* draw to front */ - rrb = (void *) fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - } else if (fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { - /* draw to back */ - rrb = (void *) fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - } else { - /* drawing to multiple buffers, or none */ - return; - } - - assert(rrb); - assert(rrb->pitch); - - R200_STATECHANGE( rmesa, ctx ); - -#if 0 - /* Note: we used the (possibly) page-flipped values */ - rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] - = ((rrb->flippedOffset + rmesa->radeon.radeonScreen->fbLocation) - & R200_COLOROFFSET_MASK); - rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = drb->flippedPitch; - if (rmesa->radeon.sarea->tiling_enabled) { - rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE; - } -#endif -} - static GLboolean r200ValidateBuffers(GLcontext *ctx) { r200ContextPtr rmesa = R200_CONTEXT(ctx); @@ -2395,7 +2315,11 @@ GLboolean r200ValidateState( GLcontext *ctx ) GLuint new_state = rmesa->radeon.NewGLState; if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { - r200UpdateDrawBuffer(ctx); + _mesa_update_framebuffer(ctx); + /* this updates the DrawBuffer's Width/Height if it's a FBO */ + _mesa_update_draw_buffer_bounds(ctx); + + R200_STATECHANGE(rmesa, ctx); } if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM)) { @@ -2523,8 +2447,8 @@ void r200InitStateFuncs( struct dd_function_table *functions ) functions->UpdateState = r200InvalidateState; functions->LightingSpaceChange = r200LightingSpaceChange; - functions->DrawBuffer = r200DrawBuffer; - functions->ReadBuffer = r200ReadBuffer; + functions->DrawBuffer = radeonDrawBuffer; + functions->ReadBuffer = radeonReadBuffer; functions->AlphaFunc = r200AlphaFunc; functions->BlendColor = r200BlendColor; diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 5d497efc9c4..488fd44740c 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -235,26 +235,35 @@ static void r300_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmes static void r300_vtbl_pre_emit_atoms(radeonContextPtr radeon) { - r300ContextPtr r300 = (r300ContextPtr)radeon; - BATCH_LOCALS(radeon); - - r300->vap_flush_needed = GL_TRUE; + r300ContextPtr r300 = (r300ContextPtr)radeon; + BATCH_LOCALS(radeon); + + r300->vap_flush_needed = GL_TRUE; + + cp_wait(radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN); + BEGIN_BATCH_NO_AUTOSTATE(2); + OUT_BATCH_REGVAL(R300_TX_INVALTAGS, R300_TX_FLUSH); + END_BATCH(); + end_3d(radeon); +} - cp_wait(radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN); - BEGIN_BATCH_NO_AUTOSTATE(2); - OUT_BATCH_REGVAL(R300_TX_INVALTAGS, R300_TX_FLUSH); - END_BATCH(); - end_3d(radeon); +static void r300_fallback(GLcontext *ctx, GLuint bit, GLboolean mode) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + if (mode) + r300->radeon.Fallback |= bit; + else + r300->radeon.Fallback &= ~bit; } static void r300_init_vtbl(radeonContextPtr radeon) { - radeon->vtbl.get_lock = r300_get_lock; - radeon->vtbl.update_viewport_offset = r300UpdateViewportOffset; - radeon->vtbl.update_draw_buffer = r300UpdateDrawBuffer; - radeon->vtbl.emit_cs_header = r300_vtbl_emit_cs_header; - radeon->vtbl.swtcl_flush = r300_swtcl_flush; - radeon->vtbl.pre_emit_atoms = r300_vtbl_pre_emit_atoms; + radeon->vtbl.get_lock = r300_get_lock; + radeon->vtbl.update_viewport_offset = r300UpdateViewportOffset; + radeon->vtbl.emit_cs_header = r300_vtbl_emit_cs_header; + radeon->vtbl.swtcl_flush = r300_swtcl_flush; + radeon->vtbl.pre_emit_atoms = r300_vtbl_pre_emit_atoms; + radeon->vtbl.fallback = r300_fallback; } diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index 619d268f387..d1cf57959fa 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -541,7 +541,7 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) { r300ContextPtr r300 = R300_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable; - GLframebuffer *fb = dPriv->driverPrivate; + struct radeon_framebuffer *rfb = dPriv->driverPrivate; struct radeon_renderbuffer *rrb; struct radeon_renderbuffer *rrbd; int flags = 0; @@ -594,16 +594,16 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask) rcommonEnsureCmdBufSpace(&r300->radeon, 421 * 3, __FUNCTION__); if (flags || bits) r300EmitClearState(ctx); - rrbd = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; + rrbd = (void *)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; if (flags & BUFFER_BIT_FRONT_LEFT) { - rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + rrb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer; r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd); bits = 0; } if (flags & BUFFER_BIT_BACK_LEFT) { - rrb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + rrb = (void *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd); bits = 0; } diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index f46477f0f67..402d2d76388 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -427,7 +427,8 @@ static int r300Fallback(GLcontext * ctx) { r300ContextPtr r300 = R300_CONTEXT(ctx); const unsigned back = ctx->Stencil._BackFace; - + + FALLBACK_IF(r300->radeon.Fallback); /* Do we need to use new-style shaders? * Also is there a better way to do this? */ if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 59728a07e5c..6bb0063bc19 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1083,20 +1083,13 @@ static void r300UpdateWindow(GLcontext * ctx) static void r300Viewport(GLcontext * ctx, GLint x, GLint y, GLsizei width, GLsizei height) { - r300ContextPtr rmesa = R300_CONTEXT(ctx); - __DRIcontext *driContext = rmesa->radeon.dri.context; /* Don't pipeline viewport changes, conflict with window offset * setting below. Could apply deltas to rescue pipelined viewport * values, or keep the originals hanging around. */ - if (rmesa->radeon.radeonScreen->driScreen->dri2.enabled) { - radeon_update_renderbuffers(driContext, driContext->driDrawablePriv); - if (driContext->driDrawablePriv != driContext->driReadablePriv) { - radeon_update_renderbuffers(driContext, - driContext->driReadablePriv); - } - } r300UpdateWindow(ctx); + + radeon_viewport(ctx, x, y, width, height); } static void r300DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval) @@ -1129,34 +1122,6 @@ void r300UpdateViewportOffset(GLcontext * ctx) radeonUpdateScissor(ctx); } -/** - * Tell the card where to render (offset, pitch). - * Effected by glDrawBuffer, etc - */ -void r300UpdateDrawBuffer(GLcontext * ctx) -{ - r300ContextPtr rmesa = R300_CONTEXT(ctx); - struct gl_framebuffer *fb = ctx->DrawBuffer; - struct radeon_renderbuffer *rrb; - - if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { - /* draw to front */ - rrb = - (void *) fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - } else if (fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { - /* draw to back */ - rrb = (void *) fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - } else { - /* drawing to multiple buffers, or none */ - return; - } - - assert(rrb); - assert(rrb->pitch); - - R300_STATECHANGE(rmesa, cb); -} - static void r300FetchStateParameter(GLcontext * ctx, const gl_state_index state[STATE_LENGTH], @@ -2653,7 +2618,11 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state) _ae_invalidate_state(ctx, new_state); if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { - r300UpdateDrawBuffer(ctx); + _mesa_update_framebuffer(ctx); + /* this updates the DrawBuffer's Width/Height if it's a FBO */ + _mesa_update_draw_buffer_bounds(ctx); + + R300_STATECHANGE(r300, cb); } r300UpdateStateParameters(ctx, new_state); @@ -2705,28 +2674,6 @@ void r300UpdateClipPlanes( GLcontext *ctx ) } } -static void r300DrawBuffer( GLcontext *ctx, GLenum mode ) -{ - r300ContextPtr rmesa = R300_CONTEXT(ctx); - if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s %s\n", __FUNCTION__, - _mesa_lookup_enum_by_nr( mode )); - - radeon_firevertices(&rmesa->radeon); /* don't pipeline cliprect changes */ - - radeonSetCliprects( &rmesa->radeon ); - if (!rmesa->radeon.radeonScreen->driScreen->dri2.enabled) - radeonUpdatePageFlipping(&rmesa->radeon); -} - -static void r300ReadBuffer( GLcontext *ctx, GLenum mode ) -{ - if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s %s\n", __FUNCTION__, - _mesa_lookup_enum_by_nr( mode )); - -}; - /** * Initialize driver's state callback functions */ @@ -2770,6 +2717,6 @@ void r300InitStateFuncs(struct dd_function_table *functions) functions->ClipPlane = r300ClipPlane; functions->Scissor = radeonScissor; - functions->DrawBuffer = r300DrawBuffer; - functions->ReadBuffer = r300ReadBuffer; + functions->DrawBuffer = radeonDrawBuffer; + functions->ReadBuffer = radeonReadBuffer; } diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index 8a90069a6d0..2d7f392e7c8 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -393,7 +393,7 @@ void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) radeon_texture_image *rImage; radeonContextPtr radeon; r300ContextPtr rmesa; - GLframebuffer *fb; + struct radeon_framebuffer *rfb; radeonTexObjPtr t; uint32_t pitch_val; @@ -402,7 +402,7 @@ void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) radeon = pDRICtx->driverPrivate; rmesa = pDRICtx->driverPrivate; - fb = dPriv->driverPrivate; + rfb = dPriv->driverPrivate; texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target); texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0); @@ -415,17 +415,17 @@ void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) radeon_update_renderbuffers(pDRICtx, dPriv); /* back & depth buffer are useless free them right away */ - rb = (void*)fb->Attachment[BUFFER_DEPTH].Renderbuffer; + rb = (void*)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } - rb = (void*)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + rb = (void*)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } - rb = (void*)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + rb = (void*)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer; if (rb->bo == NULL) { /* Failed to BO for the buffer */ return; diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index f7c0d7d64f5..1021f9beec6 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -51,7 +51,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/light.h" #include "main/framebuffer.h" #include "main/simple_list.h" - +#include "main/renderbuffer.h" #include "swrast/swrast.h" #include "vbo/vbo.h" #include "tnl/tnl.h" @@ -132,6 +132,38 @@ void radeonRecalcScissorRects(radeonContextPtr radeon) } } +static void radeon_get_cliprects(radeonContextPtr radeon, + struct drm_clip_rect **cliprects, + unsigned int *num_cliprects, + int *x_off, int *y_off) +{ + __DRIdrawablePrivate *dPriv = radeon->dri.drawable; + struct radeon_framebuffer *rfb = dPriv->driverPrivate; + + if (radeon->constant_cliprect) { + radeon->fboRect.x1 = 0; + radeon->fboRect.y1 = 0; + radeon->fboRect.x2 = radeon->glCtx->DrawBuffer->Width; + radeon->fboRect.y2 = radeon->glCtx->DrawBuffer->Height; + + *cliprects = &radeon->fboRect; + *num_cliprects = 1; + *x_off = 0; + *y_off = 0; + } else if (radeon->front_cliprects || + rfb->pf_active || dPriv->numBackClipRects == 0) { + *cliprects = dPriv->pClipRects; + *num_cliprects = dPriv->numClipRects; + *x_off = dPriv->x; + *y_off = dPriv->y; + } else { + *num_cliprects = dPriv->numBackClipRects; + *cliprects = dPriv->pBackClipRects; + *x_off = dPriv->backX; + *y_off = dPriv->backY; + } +} + /** * Update cliprects and scissors. */ @@ -139,49 +171,37 @@ void radeonSetCliprects(radeonContextPtr radeon) { __DRIdrawablePrivate *const drawable = radeon->dri.drawable; __DRIdrawablePrivate *const readable = radeon->dri.readable; - GLframebuffer *const draw_fb = (GLframebuffer*)drawable->driverPrivate; - GLframebuffer *const read_fb = (GLframebuffer*)readable->driverPrivate; + struct radeon_framebuffer *const draw_rfb = drawable->driverPrivate; + struct radeon_framebuffer *const read_rfb = readable->driverPrivate; + int x_off, y_off; - if (!radeon->radeonScreen->driScreen->dri2.enabled) { - if (draw_fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { - /* Can't ignore 2d windows if we are page flipping. */ - if (drawable->numBackClipRects == 0 || radeon->doPageFlip || - radeon->sarea->pfCurrentPage == 1) { - radeon->numClipRects = drawable->numClipRects; - radeon->pClipRects = drawable->pClipRects; - } else { - radeon->numClipRects = drawable->numBackClipRects; - radeon->pClipRects = drawable->pBackClipRects; - } - } else { - /* front buffer (or none, or multiple buffers */ - radeon->numClipRects = drawable->numClipRects; - radeon->pClipRects = drawable->pClipRects; - } - } + fprintf(stderr,"cliprects %d %d\n", radeon->front_cliprects, radeon->constant_cliprect); + radeon_get_cliprects(radeon, &radeon->pClipRects, + &radeon->numClipRects, &x_off, &y_off); - if ((draw_fb->Width != drawable->w) || - (draw_fb->Height != drawable->h)) { - _mesa_resize_framebuffer(radeon->glCtx, draw_fb, + if ((draw_rfb->base.Width != drawable->w) || + (draw_rfb->base.Height != drawable->h)) { + _mesa_resize_framebuffer(radeon->glCtx, &draw_rfb->base, drawable->w, drawable->h); - draw_fb->Initialized = GL_TRUE; + draw_rfb->base.Initialized = GL_TRUE; } if (drawable != readable) { - if ((read_fb->Width != readable->w) || - (read_fb->Height != readable->h)) { - _mesa_resize_framebuffer(radeon->glCtx, read_fb, + if ((read_rfb->base.Width != readable->w) || + (read_rfb->base.Height != readable->h)) { + _mesa_resize_framebuffer(radeon->glCtx, &read_rfb->base, readable->w, readable->h); - read_fb->Initialized = GL_TRUE; + read_rfb->base.Initialized = GL_TRUE; } } if (radeon->state.scissor.enabled) radeonRecalcScissorRects(radeon); - radeon->lastStamp = drawable->lastStamp; } + + void radeonUpdateScissor( GLcontext *ctx ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); @@ -348,6 +368,37 @@ static void radeonWaitForIdle(radeonContextPtr radeon) UNLOCK_HARDWARE(radeon); } +static void radeon_flip_renderbuffers(struct radeon_framebuffer *rfb) +{ + int current_page = rfb->pf_current_page; + int next_page = (current_page + 1) % rfb->pf_num_pages; + struct gl_renderbuffer *tmp_rb; + + /* Exchange renderbuffers if necessary but make sure their + * reference counts are preserved. + */ + if (rfb->color_rb[current_page] && + rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer != + &rfb->color_rb[current_page]->base) { + tmp_rb = NULL; + _mesa_reference_renderbuffer(&tmp_rb, + rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + tmp_rb = &rfb->color_rb[current_page]->base; + _mesa_reference_renderbuffer(&rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer, tmp_rb); + _mesa_reference_renderbuffer(&tmp_rb, NULL); + } + + if (rfb->color_rb[next_page] && + rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer != + &rfb->color_rb[next_page]->base) { + tmp_rb = NULL; + _mesa_reference_renderbuffer(&tmp_rb, + rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer); + tmp_rb = &rfb->color_rb[next_page]->base; + _mesa_reference_renderbuffer(&rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer, tmp_rb); + _mesa_reference_renderbuffer(&tmp_rb, NULL); + } +} /* Copy the back color buffer to the front color buffer. */ @@ -355,10 +406,8 @@ void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, const drm_clip_rect_t *rect) { radeonContextPtr rmesa; + struct radeon_framebuffer *rfb; GLint nbox, i, ret; - GLboolean missed_target; - int64_t ust; - __DRIscreenPrivate *psp; assert(dPriv); assert(dPriv->driContextPriv); @@ -366,24 +415,12 @@ void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; + rfb = dPriv->driverPrivate; + if ( RADEON_DEBUG & DEBUG_IOCTL ) { fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *) rmesa->glCtx ); } - radeon_firevertices(rmesa); - LOCK_HARDWARE( rmesa ); - - /* Throttle the frame rate -- only allow one pending swap buffers - * request at a time. - */ - radeonWaitForFrameCompletion( rmesa ); - if (!rect) - { - UNLOCK_HARDWARE( rmesa ); - driWaitForVBlank( dPriv, & missed_target ); - LOCK_HARDWARE( rmesa ); - } - nbox = dPriv->numClipRects; /* must be in locked region */ for ( i = 0 ; i < nbox ; ) { @@ -429,94 +466,76 @@ void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, } UNLOCK_HARDWARE( rmesa ); - if (!rect) - { - psp = dPriv->driScreenPriv; - rmesa->swap_count++; - (*psp->systemTime->getUST)( & ust ); - if ( missed_target ) { - rmesa->swap_missed_count++; - rmesa->swap_missed_ust = ust - rmesa->swap_ust; - } +} - rmesa->swap_ust = ust; - rmesa->hw.all_dirty = GL_TRUE; +static int radeonScheduleSwap(__DRIdrawablePrivate *dPriv, GLboolean *missed_target) +{ + radeonContextPtr rmesa; + + rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; + radeon_firevertices(rmesa); + LOCK_HARDWARE( rmesa ); + + if (!dPriv->numClipRects) { + UNLOCK_HARDWARE(rmesa); + usleep(10000); /* throttle invisible client 10ms */ + return 0; } + + radeonWaitForFrameCompletion(rmesa); + + UNLOCK_HARDWARE(rmesa); + driWaitForVBlank(dPriv, missed_target); + LOCK_HARDWARE(rmesa); + + return 0; } -void radeonPageFlip( __DRIdrawablePrivate *dPriv ) +static GLboolean radeonPageFlip( __DRIdrawablePrivate *dPriv ) { - radeonContextPtr rmesa; + radeonContextPtr radeon; GLint ret; - GLboolean missed_target; __DRIscreenPrivate *psp; struct radeon_renderbuffer *rrb; - GLframebuffer *fb = dPriv->driverPrivate; - + struct radeon_framebuffer *rfb; + assert(dPriv); assert(dPriv->driContextPriv); assert(dPriv->driContextPriv->driverPrivate); - rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; - rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + radeon = (radeonContextPtr) dPriv->driContextPriv->driverPrivate; + rfb = dPriv->driverPrivate; + rrb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer; psp = dPriv->driScreenPriv; if ( RADEON_DEBUG & DEBUG_IOCTL ) { - fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__, - rmesa->sarea->pfCurrentPage); + fprintf(stderr, "%s: pfCurrentPage: %d %d\n", __FUNCTION__, + radeon->sarea->pfCurrentPage, radeon->sarea->pfState); } - - radeon_firevertices(rmesa); - - LOCK_HARDWARE( rmesa ); - - if (!dPriv->numClipRects) { - UNLOCK_HARDWARE(rmesa); - usleep(10000); /* throttle invisible client 10ms */ - return; - } - drm_clip_rect_t *box = dPriv->pClipRects; - drm_clip_rect_t *b = rmesa->sarea->boxes; + drm_clip_rect_t *b = radeon->sarea->boxes; b[0] = box[0]; - rmesa->sarea->nbox = 1; - - /* Throttle the frame rate -- only allow a few pending swap buffers - * request at a time. - */ - radeonWaitForFrameCompletion( rmesa ); - UNLOCK_HARDWARE( rmesa ); - driWaitForVBlank( dPriv, & missed_target ); - if ( missed_target ) { - rmesa->swap_missed_count++; - (void) (*psp->systemTime->getUST)( & rmesa->swap_missed_ust ); - } - LOCK_HARDWARE( rmesa ); + radeon->sarea->nbox = 1; - ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP ); + ret = drmCommandNone( radeon->dri.fd, DRM_RADEON_FLIP ); - UNLOCK_HARDWARE( rmesa ); + UNLOCK_HARDWARE( radeon ); if ( ret ) { fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret ); - exit( 1 ); + return GL_FALSE; } - rmesa->swap_count++; - (void) (*psp->systemTime->getUST)( & rmesa->swap_ust ); - - /* Get ready for drawing next frame. Update the renderbuffers' - * flippedOffset/Pitch fields so we draw into the right place. - */ - // driFlipRenderbuffers(rmesa->glCtx->WinSysDrawBuffer, - // rmesa->sarea->pfCurrentPage); - - rmesa->state.color.rrb = rrb; + if (!rfb->pf_active) + return GL_FALSE; + + rfb->pf_current_page = radeon->sarea->pfCurrentPage; + radeon_flip_renderbuffers(rfb); + radeon_draw_buffer(radeon->glCtx, &rfb->base); - if (rmesa->vtbl.update_draw_buffer) - rmesa->vtbl.update_draw_buffer(rmesa->glCtx); + return GL_TRUE; } @@ -525,6 +544,9 @@ void radeonPageFlip( __DRIdrawablePrivate *dPriv ) */ void radeonSwapBuffers(__DRIdrawablePrivate * dPriv) { + int64_t ust; + __DRIscreenPrivate *psp; + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { radeonContextPtr radeon; GLcontext *ctx; @@ -533,12 +555,29 @@ void radeonSwapBuffers(__DRIdrawablePrivate * dPriv) ctx = radeon->glCtx; if (ctx->Visual.doubleBufferMode) { + GLboolean missed_target; + struct radeon_framebuffer *rfb = dPriv->driverPrivate; _mesa_notifySwapBuffers(ctx);/* flush pending rendering comands */ - if (radeon->doPageFlip) { + + radeonScheduleSwap(dPriv, &missed_target); + + if (rfb->pf_active) { radeonPageFlip(dPriv); } else { radeonCopyBuffer(dPriv, NULL); } + + psp = dPriv->driScreenPriv; + + rfb->swap_count++; + (*psp->systemTime->getUST)( & ust ); + if ( missed_target ) { + rfb->swap_missed_count++; + rfb->swap_missed_ust = ust - rfb->swap_ust; + } + + rfb->swap_ust = ust; + radeon->hw.all_dirty = GL_TRUE; } } else { /* XXX this shouldn't be an error but we can't handle it for now */ @@ -573,7 +612,224 @@ void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, } } +void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + struct radeon_renderbuffer *rrbDepth = NULL, *rrbStencil = NULL, + *rrbColor = NULL; + + + if (!fb) { + /* this can happen during the initial context initialization */ + return; + } + + /* radeons only handle 1 color draw so far */ + if (fb->_NumColorDrawBuffers != 1) { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE); + return; + } + + /* Do this here, note core Mesa, since this function is called from + * many places within the driver. + */ + if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { + /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */ + _mesa_update_framebuffer(ctx); + /* this updates the DrawBuffer's Width/Height if it's a FBO */ + _mesa_update_draw_buffer_bounds(ctx); + } + + if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { + /* this may occur when we're called by glBindFrameBuffer() during + * the process of someone setting up renderbuffers, etc. + */ + /*_mesa_debug(ctx, "DrawBuffer: incomplete user FBO\n");*/ + return; + } + + if (fb->Name) + ;/* do something depthy/stencily TODO */ + + + /* none */ + if (fb->Name == 0) { + if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { + rrbColor = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + radeon->front_cliprects = GL_TRUE; + } else { + rrbColor = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + radeon->front_cliprects = GL_FALSE; + } + } else { + /* user FBO in theory */ + struct radeon_renderbuffer *rrb; + rrb = (void *)fb->_ColorDrawBuffers[0]; + rrbColor = rrb; + radeon->constant_cliprect = GL_TRUE; + } + + if (rrbColor == NULL) + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE); + else + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE); + + + + if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) { + rrbDepth = (struct radeon_renderbuffer *)fb->_DepthBuffer->Wrapped; + if (rrbDepth && rrbDepth->bo) { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE); + } else { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_TRUE); + } + } else { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE); + rrbDepth = NULL; + } + + /* TODO stencil things */ + if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) { + rrbStencil = (struct radeon_renderbuffer *)fb->_DepthBuffer->Wrapped; + if (rrbStencil && rrbStencil->bo) { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE); + /* need to re-compute stencil hw state */ + if (ctx->Driver.Enable != NULL) + ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); + else + ctx->NewState |= _NEW_STENCIL; + if (!rrbDepth) + rrbDepth = rrbStencil; + } else { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_TRUE); + } + } else { + radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE); + if (ctx->Driver.Enable != NULL) + ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); + else + ctx->NewState |= _NEW_STENCIL; + } + + /* Update culling direction which changes depending on the + * orientation of the buffer: + */ + if (ctx->Driver.FrontFace) + ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); + else + ctx->NewState |= _NEW_POLYGON; + + /* + * Update depth test state + */ + if (ctx->Driver.Enable) { + if (ctx->Depth.Test && fb->Visual.depthBits > 0) { + ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_TRUE); + } else { + ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_FALSE); + } + } else { + ctx->NewState |= _NEW_DEPTH; + } + + radeon->state.depth.rrb = rrbDepth; + + radeon->state.color.rrb = rrbColor; + + /* update viewport since it depends on window size */ + if (ctx->Driver.Viewport) { + ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, + ctx->Viewport.Width, ctx->Viewport.Height); + } else { + ctx->NewState |= _NEW_VIEWPORT; + } + + /* Set state we know depends on drawable parameters: + */ + if (ctx->Driver.Scissor) + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); + radeon->NewGLState |= _NEW_SCISSOR; +} + +/** + * Called via glDrawBuffer. + */ +void radeonDrawBuffer( GLcontext *ctx, GLenum mode ) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + + if (RADEON_DEBUG & DEBUG_DRI) + fprintf(stderr, "%s %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr( mode )); + + radeon_firevertices(radeon); /* don't pipeline cliprect changes */ + + radeon_draw_buffer(ctx, ctx->DrawBuffer); +} + +void radeonReadBuffer( GLcontext *ctx, GLenum mode ) +{ + /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ + if (ctx->ReadBuffer == ctx->DrawBuffer) { + /* This will update FBO completeness status. + * A framebuffer will be incomplete if the GL_READ_BUFFER setting + * refers to a missing renderbuffer. Calling glReadBuffer can set + * that straight and can make the drawing buffer complete. + */ + radeon_draw_buffer(ctx, ctx->DrawBuffer); + } +} + +/* Turn on/off page flipping according to the flags in the sarea: + */ +void radeonUpdatePageFlipping(radeonContextPtr radeon) +{ + struct radeon_framebuffer *rfb = radeon->dri.drawable->driverPrivate; + + rfb->pf_active = radeon->sarea->pfState; + rfb->pf_current_page = radeon->sarea->pfCurrentPage; + rfb->pf_num_pages = 2; + radeon_flip_renderbuffers(rfb); + radeon_draw_buffer(radeon->glCtx, radeon->glCtx->DrawBuffer); +} + +void radeon_window_moved(radeonContextPtr radeon) +{ + GLcontext *ctx = radeon->glCtx; + __DRIdrawablePrivate *dPriv = radeon->dri.drawable; + struct radeon_framebuffer *rfb = dPriv->driverPrivate; + + if (!radeon->radeonScreen->driScreen->dri2.enabled) { + radeonUpdatePageFlipping(radeon); + } + radeonSetCliprects(radeon); +} + +void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + __DRIcontext *driContext = radeon->dri.context; + void (*old_viewport)(GLcontext *ctx, GLint x, GLint y, + GLsizei w, GLsizei h); + + if (!driContext->driScreenPriv->dri2.enabled) + return; + + radeon_update_renderbuffers(driContext, driContext->driDrawablePriv); + if (driContext->driDrawablePriv != driContext->driReadablePriv) + radeon_update_renderbuffers(driContext, driContext->driReadablePriv); + + old_viewport = ctx->Driver.Viewport; + ctx->Driver.Viewport = NULL; + radeon->dri.drawable = driContext->driDrawablePriv; + radeon_window_moved(radeon); + radeon_draw_buffer(ctx, radeon->glCtx->DrawBuffer); + ctx->Driver.Viewport = old_viewport; + + +} static void radeon_print_state_atom(radeonContextPtr radeon, struct radeon_state_atom *state ) { int i; diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h index ead0f5551b3..95b718184b7 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.h +++ b/src/mesa/drivers/dri/radeon/radeon_common.h @@ -14,7 +14,6 @@ void radeonWaitForIdleLocked(radeonContextPtr radeon); extern uint32_t radeonGetAge(radeonContextPtr radeon); void radeonCopyBuffer( __DRIdrawablePrivate *dPriv, const drm_clip_rect_t *rect); -void radeonPageFlip( __DRIdrawablePrivate *dPriv ); void radeonSwapBuffers(__DRIdrawablePrivate * dPriv); void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h ); @@ -25,6 +24,12 @@ void radeonFlush(GLcontext *ctx); void radeonFinish(GLcontext * ctx); void radeonEmitState(radeonContextPtr radeon); +void radeon_window_moved(radeonContextPtr radeon); +void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb); +void radeonDrawBuffer( GLcontext *ctx, GLenum mode ); +void radeonReadBuffer( GLcontext *ctx, GLenum mode ); +void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height); + static inline struct radeon_renderbuffer *radeon_get_depthbuffer(radeonContextPtr rmesa) { struct radeon_renderbuffer *rrb; @@ -38,11 +43,11 @@ static inline struct radeon_renderbuffer *radeon_get_depthbuffer(radeonContextPt static inline struct radeon_renderbuffer *radeon_get_colorbuffer(radeonContextPtr rmesa) { struct radeon_renderbuffer *rrb; - GLframebuffer *fb = rmesa->dri.drawable->driverPrivate; + struct radeon_framebuffer *rfb = rmesa->dri.drawable->driverPrivate; rrb = rmesa->state.color.rrb; if (rmesa->radeonScreen->driScreen->dri2.enabled) { - rrb = (struct radeon_renderbuffer *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + rrb = (struct radeon_renderbuffer *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; } if (!rrb) return NULL; diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c index 1b8a05d045b..4da2055c13d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c @@ -35,7 +35,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_common.h" #include "xmlpool.h" /* for symbolic values of enum-type options */ #include "utils.h" -#include "drirenderbuffer.h" #include "vblank.h" #include "main/state.h" @@ -165,8 +164,6 @@ GLboolean radeonInitContext(radeonContextPtr radeon, radeon->do_usleeps ? "usleeps" : "busy waits", fthrottle_mode, radeon->radeonScreen->irq); - (*sPriv->systemTime->getUST) (&radeon->swap_ust); - return GL_TRUE; } @@ -180,39 +177,39 @@ void radeonCleanupContext(radeonContextPtr radeon) FILE *track; #endif struct radeon_renderbuffer *rb; - GLframebuffer *fb; + struct radeon_framebuffer *rfb; /* free the Mesa context */ _mesa_destroy_context(radeon->glCtx); - fb = (void*)radeon->dri.drawable->driverPrivate; - rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + rfb = (void*)radeon->dri.drawable->driverPrivate; + rb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } - rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + rb = (void *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } - rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; + rb = (void *)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } - fb = (void*)radeon->dri.readable->driverPrivate; - rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + rfb = (void*)radeon->dri.readable->driverPrivate; + rb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } - rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + rb = (void *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } - rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; + rb = (void *)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; @@ -260,12 +257,12 @@ GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv) static void radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon, - GLframebuffer *draw) + struct radeon_framebuffer *draw) { /* if radeon->fake */ struct radeon_renderbuffer *rb; - if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { if (!rb->bo) { rb->bo = radeon_bo_open(radeon->radeonScreen->bom, radeon->radeonScreen->frontOffset, @@ -277,7 +274,7 @@ radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon, rb->cpp = radeon->radeonScreen->cpp; rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; } - if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { if (!rb->bo) { rb->bo = radeon_bo_open(radeon->radeonScreen->bom, radeon->radeonScreen->backOffset, @@ -289,7 +286,7 @@ radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon, rb->cpp = radeon->radeonScreen->cpp; rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; } - if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) { if (!rb->bo) { rb->bo = radeon_bo_open(radeon->radeonScreen->bom, radeon->radeonScreen->depthOffset, @@ -301,7 +298,7 @@ radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon, rb->cpp = radeon->radeonScreen->cpp; rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; } - if ((rb = (void *)draw->Attachment[BUFFER_STENCIL].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) { if (!rb->bo) { rb->bo = radeon_bo_open(radeon->radeonScreen->bom, radeon->radeonScreen->depthOffset, @@ -317,7 +314,7 @@ radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon, static void radeon_make_renderbuffer_current(radeonContextPtr radeon, - GLframebuffer *draw) + struct radeon_framebuffer *draw) { int size = 4096*4096*4; /* if radeon->fake */ @@ -329,7 +326,7 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon, } - if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { if (!rb->bo) { rb->bo = radeon_bo_open(radeon->radeonScreen->bom, radeon->radeonScreen->frontOffset + @@ -342,7 +339,7 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon, rb->cpp = radeon->radeonScreen->cpp; rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp; } - if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { if (!rb->bo) { rb->bo = radeon_bo_open(radeon->radeonScreen->bom, radeon->radeonScreen->backOffset + @@ -355,7 +352,7 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon, rb->cpp = radeon->radeonScreen->cpp; rb->pitch = radeon->radeonScreen->backPitch * rb->cpp; } - if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) { if (!rb->bo) { rb->bo = radeon_bo_open(radeon->radeonScreen->bom, radeon->radeonScreen->depthOffset + @@ -368,7 +365,7 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon, rb->cpp = radeon->radeonScreen->cpp; rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp; } - if ((rb = (void *)draw->Attachment[BUFFER_STENCIL].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) { if (!rb->bo) { rb->bo = radeon_bo_open(radeon->radeonScreen->bom, radeon->radeonScreen->depthOffset + @@ -392,7 +389,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) __DRIscreen *screen; struct radeon_renderbuffer *rb; int i, count; - GLframebuffer *draw; + struct radeon_framebuffer *draw; radeonContextPtr radeon; if (RADEON_DEBUG & DEBUG_DRI) @@ -402,13 +399,13 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) screen = context->driScreenPriv; radeon = (radeonContextPtr) context->driverPrivate; i = 0; - if ((rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) { attachments[i++] = __DRI_BUFFER_FRONT_LEFT; } - if ((rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) { attachments[i++] = __DRI_BUFFER_BACK_LEFT; } - if ((rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer)) { + if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) { attachments[i++] = __DRI_BUFFER_DEPTH; } @@ -439,7 +436,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) for (i = 0; i < count; i++) { switch (buffers[i].attachment) { case __DRI_BUFFER_FRONT_LEFT: - rb = (void *)draw->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer; if (rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; @@ -461,7 +458,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) } break; case __DRI_BUFFER_BACK_LEFT: - rb = (void *)draw->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; if (rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; @@ -479,7 +476,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) buffers[i].flags); break; case __DRI_BUFFER_DEPTH: - rb = (void *)draw->Attachment[BUFFER_DEPTH].Renderbuffer; + rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer; if (rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; @@ -518,7 +515,8 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, __DRIdrawablePrivate * driReadPriv) { radeonContextPtr radeon; - GLframebuffer *dfb, *rfb; + struct radeon_framebuffer *drfb; + struct gl_framebuffer *readfb; if (!driContextPriv) { if (RADEON_DEBUG & DEBUG_DRI) @@ -526,61 +524,65 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, _mesa_make_current(NULL, NULL, NULL); return GL_TRUE; } + radeon = (radeonContextPtr) driContextPriv->driverPrivate; - dfb = driDrawPriv->driverPrivate; - rfb = driReadPriv->driverPrivate; + drfb = driDrawPriv->driverPrivate; + readfb = driReadPriv->driverPrivate; if (driContextPriv->driScreenPriv->dri2.enabled) { radeon_update_renderbuffers(driContextPriv, driDrawPriv); if (driDrawPriv != driReadPriv) radeon_update_renderbuffers(driContextPriv, driReadPriv); radeon->state.color.rrb = - (void *)dfb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + (void *)drfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; radeon->state.depth.rrb = - (void *)dfb->Attachment[BUFFER_DEPTH].Renderbuffer; + (void *)drfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; } else { - radeon_make_renderbuffer_current(radeon, dfb); + radeon_make_renderbuffer_current(radeon, drfb); } if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, dfb, rfb); + fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, drfb, readfb); driUpdateFramebufferSize(radeon->glCtx, driDrawPriv); if (driReadPriv != driDrawPriv) driUpdateFramebufferSize(radeon->glCtx, driReadPriv); + _mesa_make_current(radeon->glCtx, &drfb->base, readfb); - - _mesa_make_current(radeon->glCtx, dfb, rfb); - - if (radeon->dri.drawable != driDrawPriv) { - if (driDrawPriv->swap_interval == (unsigned)-1) { - driDrawPriv->vblFlags = - (radeon->radeonScreen->irq != 0) - ? driGetDefaultVBlankFlags(&radeon-> - optionCache) - : VBLANK_FLAG_NO_IRQ; - - driDrawableInitVBlank(driDrawPriv); - } - } + _mesa_update_state(radeon->glCtx); - radeon->dri.readable = driReadPriv; + if (radeon->glCtx->DrawBuffer == &drfb->base) { - if (radeon->dri.drawable != driDrawPriv || - radeon->lastStamp != driDrawPriv->lastStamp) { - radeon->dri.drawable = driDrawPriv; + if (radeon->dri.readable != driReadPriv) + radeon->dri.readable = driReadPriv; - radeonSetCliprects(radeon); - radeon->vtbl.update_viewport_offset(radeon->glCtx); + if (radeon->dri.drawable != driDrawPriv) { + if (driDrawPriv->swap_interval == (unsigned)-1) { + int i; + driDrawPriv->vblFlags = + (radeon->radeonScreen->irq != 0) + ? driGetDefaultVBlankFlags(&radeon-> + optionCache) + : VBLANK_FLAG_NO_IRQ; + + driDrawableInitVBlank(driDrawPriv); + drfb->vbl_waited = driDrawPriv->vblSeq; + + for (i = 0; i < 2; i++) { + if (drfb->color_rb[i]) + drfb->color_rb[i]->vbl_pending = driDrawPriv->vblSeq; + } + + } + radeon->dri.drawable = driDrawPriv; + +// radeonWindowMoved(radeon); + } + radeon_draw_buffer(radeon->glCtx, &drfb->base); } - _mesa_update_state(radeon->glCtx); - - if (!driContextPriv->driScreenPriv->dri2.enabled) { - radeonUpdatePageFlipping(radeon); - } if (RADEON_DEBUG & DEBUG_DRI) fprintf(stderr, "End %s\n", __FUNCTION__); diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index a200e902210..4aeb50fe68e 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -39,6 +39,8 @@ typedef struct radeon_context *radeonContextPtr; #define RADEON_FALLBACK_BLEND_FUNC 0x0020 #define RADEON_FALLBACK_DISABLE 0x0040 #define RADEON_FALLBACK_BORDER_MODE 0x0080 +#define RADEON_FALLBACK_DEPTH_BUFFER 0x0100 +#define RADEON_FALLBACK_STENCIL_BUFFER 0x0200 #define R200_FALLBACK_TEXTURE 0x01 #define R200_FALLBACK_DRAW_BUFFER 0x02 @@ -81,9 +83,34 @@ struct radeon_renderbuffer /* boo Xorg 6.8.2 compat */ int has_surface; + GLuint pf_pending; /**< sequence number of pending flip */ + GLuint vbl_pending; /**< vblank sequence number of pending flip */ __DRIdrawablePrivate *dPriv; }; +struct radeon_framebuffer +{ + struct gl_framebuffer base; + + struct radeon_renderbuffer *color_rb[2]; + + GLuint vbl_waited; + + /* buffer swap */ + int64_t swap_ust; + int64_t swap_missed_ust; + + GLuint swap_count; + GLuint swap_missed_count; + + /* Drawable page flipping state */ + GLboolean pf_active; + GLint pf_current_page; + GLint pf_num_pages; + +}; + + struct radeon_colorbuffer_state { GLuint clear; int roundEnable; @@ -387,9 +414,6 @@ struct radeon_context { GLuint NewGLState; DECLARE_RENDERINPUTS(tnl_index_bitset); /* index of bits for last tnl_install_attrs */ - /* Page flipping */ - GLuint doPageFlip; - /* Drawable, cliprect and scissor information */ GLuint numClipRects; /* Cliprects for the draw buffer */ drm_clip_rect_t *pClipRects; @@ -406,13 +430,6 @@ struct radeon_context { GLuint irqsEmitted; drm_radeon_irq_wait_t iw; - /* buffer swap */ - int64_t swap_ust; - int64_t swap_missed_ust; - - GLuint swap_count; - GLuint swap_missed_count; - /* Derived state - for r300 only */ struct radeon_state state; @@ -422,15 +439,19 @@ struct radeon_context { driOptionCache optionCache; struct radeon_cmdbuf cmdbuf; + + drm_clip_rect_t fboRect; + GLboolean constant_cliprect; /* use for FBO or DRI2 rendering */ + GLboolean front_cliprects; struct { void (*get_lock)(radeonContextPtr radeon); void (*update_viewport_offset)(GLcontext *ctx); - void (*update_draw_buffer)(GLcontext *ctx); void (*emit_cs_header)(struct radeon_cs *cs, radeonContextPtr rmesa); void (*swtcl_flush)(GLcontext *ctx, uint32_t offset); void (*pre_emit_atoms)(radeonContextPtr rmesa); void (*pre_emit_state)(radeonContextPtr rmesa); + void (*fallback)(GLcontext *ctx, GLuint bit, GLboolean mode); } vtbl; }; diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index e4202c71fc5..47ebe41c6d5 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -186,10 +186,10 @@ static void r100_init_vtbl(radeonContextPtr radeon) { radeon->vtbl.get_lock = r100_get_lock; radeon->vtbl.update_viewport_offset = radeonUpdateViewportOffset; - radeon->vtbl.update_draw_buffer = radeonUpdateDrawBuffer; radeon->vtbl.emit_cs_header = r100_vtbl_emit_cs_header; radeon->vtbl.swtcl_flush = r100_swtcl_flush; radeon->vtbl.pre_emit_state = r100_vtbl_pre_emit_state; + radeon->vtbl.fallback = radeonFallback; } /* Create the device specific context. @@ -369,8 +369,6 @@ radeonCreateContext( const __GLcontextModes *glVisual, rmesa->radeon.do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); - (*sPriv->systemTime->getUST)( & rmesa->radeon.swap_ust ); - #if DO_DEBUG RADEON_DEBUG = driParseDebugString( getenv( "RADEON_DEBUG" ), diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.c b/src/mesa/drivers/dri/radeon/radeon_lock.c index 9a7e76b245e..fb9e5e025ea 100644 --- a/src/mesa/drivers/dri/radeon/radeon_lock.c +++ b/src/mesa/drivers/dri/radeon/radeon_lock.c @@ -48,37 +48,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_lock.h" #include "drirenderbuffer.h" -#if DEBUG_LOCKING -char *prevLockFile = NULL; -int prevLockLine = 0; -#endif - -/* Turn on/off page flipping according to the flags in the sarea: - */ -void radeonUpdatePageFlipping(radeonContextPtr rmesa) -{ - int use_back; - __DRIdrawablePrivate *const drawable = rmesa->dri.drawable; - GLframebuffer *fb = drawable->driverPrivate; - - rmesa->doPageFlip = rmesa->sarea->pfState; - if (rmesa->glCtx->WinSysDrawBuffer) { - rmesa->vtbl.update_draw_buffer(rmesa->glCtx); - } - - use_back = rmesa->glCtx->DrawBuffer ? - (rmesa->glCtx->DrawBuffer->_ColorDrawBufferIndexes[0] == - BUFFER_BACK_LEFT) : 1; - use_back ^= (rmesa->sarea->pfCurrentPage == 1); - - if (use_back) - rmesa->state.color.rrb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - else - rmesa->state.color.rrb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - - rmesa->state.depth.rrb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; -} - /* Update the hardware state. This is called if another context has * grabbed the hardware lock, which includes the X server. This * function also updates the driver's window state after the X server @@ -112,13 +81,52 @@ void radeonGetLock(radeonContextPtr rmesa, GLuint flags) } if (rmesa->lastStamp != drawable->lastStamp) { - radeonUpdatePageFlipping(rmesa); - radeonSetCliprects(rmesa); - rmesa->vtbl.update_viewport_offset(rmesa->glCtx); - driUpdateFramebufferSize(rmesa->glCtx, drawable); + radeon_window_moved(rmesa); + rmesa->lastStamp = drawable->lastStamp; } rmesa->vtbl.get_lock(rmesa); rmesa->lost_context = GL_TRUE; } + +static INLINE struct radeon_renderbuffer * +radeon_get_renderbuffer(struct gl_framebuffer *fb, int attIndex) +{ + if (attIndex >= 0) + return (struct radeon_renderbuffer *)fb->Attachment[attIndex].Renderbuffer; + else + return NULL; +} + +void radeon_lock_hardware(radeonContextPtr radeon) +{ + __DRIdrawable *dPriv = radeon->dri.drawable; + char ret = 0; + struct radeon_framebuffer *rfb = NULL; + struct radeon_renderbuffer *rrb = NULL; + + if (radeon->dri.drawable) { + rfb = radeon->dri.drawable->driverPrivate; + + if (rfb) + rrb = radeon_get_renderbuffer(&rfb->base, + rfb->base._ColorDrawBufferIndexes[0]); + } + + if (!radeon->radeonScreen->driScreen->dri2.enabled) { + DRM_CAS(radeon->dri.hwLock, radeon->dri.hwContext, + (DRM_LOCK_HELD | radeon->dri.hwContext), ret ); + if (ret) + radeonGetLock(radeon, 0); + } +} + +void radeon_unlock_hardware(radeonContextPtr radeon) +{ + if (!radeon->radeonScreen->driScreen->dri2.enabled) { + DRM_UNLOCK( radeon->dri.fd, + radeon->dri.hwLock, + radeon->dri.hwContext ); + } +} diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.h b/src/mesa/drivers/dri/radeon/radeon_lock.h index f5ebb8dd54c..2817709eed6 100644 --- a/src/mesa/drivers/dri/radeon/radeon_lock.h +++ b/src/mesa/drivers/dri/radeon/radeon_lock.h @@ -48,73 +48,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. extern void radeonGetLock(radeonContextPtr rmesa, GLuint flags); -/* Turn DEBUG_LOCKING on to find locking conflicts. - */ -#define DEBUG_LOCKING 0 - -#if DEBUG_LOCKING -extern char *prevLockFile; -extern int prevLockLine; - -#define DEBUG_LOCK() \ - do { \ - prevLockFile = (__FILE__); \ - prevLockLine = (__LINE__); \ - } while (0) - -#define DEBUG_RESET() \ - do { \ - prevLockFile = 0; \ - prevLockLine = 0; \ - } while (0) - -#define DEBUG_CHECK_LOCK() \ - do { \ - if ( prevLockFile ) { \ - fprintf( stderr, \ - "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ - prevLockFile, prevLockLine, __FILE__, __LINE__ ); \ - exit( 1 ); \ - } \ - } while (0) - -#else - -#define DEBUG_LOCK() -#define DEBUG_RESET() -#define DEBUG_CHECK_LOCK() - -#endif - -/* - * !!! We may want to separate locks from locks with validation. This - * could be used to improve performance for those things commands that - * do not do any drawing !!! - */ +void radeon_lock_hardware(radeonContextPtr rmesa); +void radeon_unlock_hardware(radeonContextPtr rmesa); /* Lock the hardware and validate our state. */ -#define LOCK_HARDWARE( rmesa ) \ - do { \ - char __ret = 0; \ - DEBUG_CHECK_LOCK(); \ - if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ - DRM_CAS( (rmesa)->dri.hwLock, (rmesa)->dri.hwContext, \ - (DRM_LOCK_HELD | (rmesa)->dri.hwContext), __ret ); \ - if ( __ret ) \ - radeonGetLock( (rmesa), 0 ); \ - } \ - DEBUG_LOCK(); \ - } while (0) - -#define UNLOCK_HARDWARE( rmesa ) \ - do { \ - if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \ - DRM_UNLOCK( (rmesa)->dri.fd, \ - (rmesa)->dri.hwLock, \ - (rmesa)->dri.hwContext ); \ - DEBUG_RESET(); \ - } \ - } while (0) +#define LOCK_HARDWARE( rmesa ) radeon_lock_hardware(rmesa) +#define UNLOCK_HARDWARE( rmesa ) radeon_unlock_hardware(rmesa) #endif diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 78f0bc25147..bf5f5c98bda 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -1262,7 +1262,7 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, const __GLcontextModes *mesaVis, GLboolean isPixmap ) { - radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->private; + radeonScreenPtr screen = (radeonScreenPtr) driScrnPriv->private; const GLboolean swDepth = GL_FALSE; const GLboolean swAlpha = GL_FALSE; @@ -1271,7 +1271,16 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, mesaVis->depthBits != 24; GLenum rgbFormat = (mesaVis->redBits == 5 ? GL_RGB5 : GL_RGBA8); GLenum depthFormat = GL_NONE; - struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis); + struct radeon_framebuffer *rfb; + + if (isPixmap) + return GL_FALSE; /* not implemented */ + + rfb = CALLOC_STRUCT(radeon_framebuffer); + if (!rfb) + return GL_FALSE; + + _mesa_initialize_framebuffer(&rfb->base, mesaVis); if (mesaVis->depthBits == 16) depthFormat = GL_DEPTH_COMPONENT16; @@ -1279,26 +1288,22 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, depthFormat = GL_DEPTH_COMPONENT24; /* front color renderbuffer */ - { - struct radeon_renderbuffer *front = - radeon_create_renderbuffer(rgbFormat, driDrawPriv); - _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &front->base); - front->has_surface = 1; - } + rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv); + _mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base); + rfb->color_rb[0]->has_surface = 1; /* back color renderbuffer */ if (mesaVis->doubleBufferMode) { - struct radeon_renderbuffer *back = - radeon_create_renderbuffer(rgbFormat, driDrawPriv); - _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &back->base); - back->has_surface = 1; + rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv); + _mesa_add_renderbuffer(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base); + rfb->color_rb[1]->has_surface = 1; } /* depth renderbuffer */ if (depthFormat != GL_NONE) { struct radeon_renderbuffer *depth = radeon_create_renderbuffer(depthFormat, driDrawPriv); - _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depth->base); + _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base); depth->has_surface = screen->depthHasSurface; } @@ -1306,18 +1311,18 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, if (mesaVis->stencilBits > 0 && !swStencil) { struct radeon_renderbuffer *stencil = radeon_create_renderbuffer(GL_STENCIL_INDEX8_EXT, driDrawPriv); - _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencil->base); + _mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &stencil->base); stencil->has_surface = screen->depthHasSurface; } - _mesa_add_soft_renderbuffers(fb, + _mesa_add_soft_renderbuffers(&rfb->base, GL_FALSE, /* color */ swDepth, swStencil, swAccum, swAlpha, GL_FALSE /* aux */); - driDrawPriv->driverPrivate = (void *) fb; + driDrawPriv->driverPrivate = (void *) rfb; return (driDrawPriv->driverPrivate != NULL); } @@ -1325,21 +1330,21 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv, static void radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) { - struct radeon_renderbuffer *rb; - GLframebuffer *fb; + struct radeon_renderbuffer *rb; + struct radeon_framebuffer *rfb; - fb = (void*)driDrawPriv->driverPrivate; - rb = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + rfb = (void*)driDrawPriv->driverPrivate; + rb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } - rb = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + rb = (void *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; } - rb = (void *)fb->Attachment[BUFFER_DEPTH].Renderbuffer; + rb = (void *)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; if (rb && rb->bo) { radeon_bo_unref(rb->bo); rb->bo = NULL; @@ -1541,21 +1546,21 @@ __DRIconfig **radeonInitScreen2(__DRIscreenPrivate *psp) static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo ) { - radeonContextPtr rmesa; + struct radeon_framebuffer *rfb; - if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL) - || (dPriv->driContextPriv->driverPrivate == NULL) - || (sInfo == NULL) ) { - return -1; + if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL) + || (dPriv->driContextPriv->driverPrivate == NULL) + || (sInfo == NULL) ) { + return -1; } - rmesa = dPriv->driContextPriv->driverPrivate; - sInfo->swap_count = rmesa->swap_count; - sInfo->swap_ust = rmesa->swap_ust; - sInfo->swap_missed_count = rmesa->swap_missed_count; + rfb = dPriv->driverPrivate; + sInfo->swap_count = rfb->swap_count; + sInfo->swap_ust = rfb->swap_ust; + sInfo->swap_missed_count = rfb->swap_missed_count; sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0) - ? driCalculateSwapUsage( dPriv, 0, rmesa->swap_missed_ust ) + ? driCalculateSwapUsage( dPriv, 0, rfb->swap_missed_ust ) : 0.0; return 0; diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index 5fffa286fe2..0c92a6ff086 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -1418,6 +1418,8 @@ static void radeonViewport( GLcontext *ctx, GLint x, GLint y, * values, or keep the originals hanging around. */ radeonUpdateWindow( ctx ); + + radeon_viewport(ctx, x, y, width, height); } static void radeonDepthRange( GLcontext *ctx, GLclampd nearval, @@ -1532,50 +1534,6 @@ static void radeonLogicOpCode( GLcontext *ctx, GLenum opcode ) rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop]; } - -/** - * Called via glDrawBuffer. - */ -static void radeonDrawBuffer( GLcontext *ctx, GLenum mode ) -{ - r100ContextPtr rmesa = R100_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s %s\n", __FUNCTION__, - _mesa_lookup_enum_by_nr( mode )); - - radeon_firevertices(&rmesa->radeon); /* don't pipeline cliprect changes */ - - if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) { - /* 0 (GL_NONE) buffers or multiple color drawing buffers */ - FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE ); - return; - } - - switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) { - case BUFFER_FRONT_LEFT: - case BUFFER_BACK_LEFT: - FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE ); - break; - default: - FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE ); - return; - } - - radeonSetCliprects( &rmesa->radeon ); - if (!rmesa->radeon.radeonScreen->driScreen->dri2.enabled) - radeonUpdatePageFlipping(&rmesa->radeon); - /* We'll set the drawing engine's offset/pitch parameters later - * when we update other state. - */ -} - -static void radeonReadBuffer( GLcontext *ctx, GLenum mode ) -{ - /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ -} - - /* ============================================================= * State enable/disable */ @@ -2066,42 +2024,16 @@ static void update_texturematrix( GLcontext *ctx ) } -/** - * Tell the card where to render (offset, pitch). - * Effected by glDrawBuffer, etc - */ -void -radeonUpdateDrawBuffer(GLcontext *ctx) -{ - r100ContextPtr rmesa = R100_CONTEXT(ctx); - struct gl_framebuffer *fb = ctx->DrawBuffer; - struct radeon_renderbuffer *rrb; - - if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { - /* draw to front */ - rrb = (void *) fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - } else if (fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { - /* draw to back */ - rrb = (void *) fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - } else { - /* drawing to multiple buffers, or none */ - return; - } - - assert(rrb); - assert(rrb->pitch); - - RADEON_STATECHANGE( rmesa, ctx ); -} - - void radeonValidateState( GLcontext *ctx ) { r100ContextPtr rmesa = R100_CONTEXT(ctx); GLuint new_state = rmesa->radeon.NewGLState; if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { - radeonUpdateDrawBuffer(ctx); + _mesa_update_framebuffer(ctx); + /* this updates the DrawBuffer's Width/Height if it's a FBO */ + _mesa_update_draw_buffer_bounds(ctx); + RADEON_STATECHANGE(rmesa, ctx); } if (new_state & _NEW_TEXTURE) {