diff --git a/src/mesa/drivers/dri/i915/i830_state.c b/src/mesa/drivers/dri/i915/i830_state.c index 66b9fd4bae5..806a4c4c72e 100644 --- a/src/mesa/drivers/dri/i915/i830_state.c +++ b/src/mesa/drivers/dri/i915/i830_state.c @@ -1010,7 +1010,7 @@ static void i830_init_packets( struct i830_context *i830 ) i830->state.Buffer[I830_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; i830->state.Buffer[I830_DESTREG_DBUFADDR1] = (BUF_3D_ID_DEPTH | - BUF_3D_PITCH(screen->depth.pitch * screen->cpp) | + BUF_3D_PITCH(screen->depth.pitch * screen->cpp) | /* XXX FBO fix */ BUF_3D_USE_FENCE); /* i830->state.Buffer[I830_DESTREG_DBUFADDR2] = screen->depth.offset; */ diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c index 4afc4ec2af2..05d8af9737c 100644 --- a/src/mesa/drivers/dri/i915/i915_state.c +++ b/src/mesa/drivers/dri/i915/i915_state.c @@ -699,7 +699,7 @@ static void i915Enable(GLcontext *ctx, GLenum cap, GLboolean state) /* Logicop doesn't seem to work at 16bpp: */ - if (i915->intel.intelScreen->cpp == 2) + if (i915->intel.intelScreen->cpp == 2) /* XXX FBO fix */ FALLBACK( &i915->intel, I915_FALLBACK_LOGICOP, state ); break; @@ -808,7 +808,7 @@ static void i915_init_packets( struct i915_context *i915 ) i915->state.Ctx[I915_CTXREG_LIS4] = 0; i915->state.Ctx[I915_CTXREG_LIS5] = 0; - if (screen->cpp == 2) + if (screen->cpp == 2) /* XXX FBO fix */ i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; @@ -858,13 +858,13 @@ static void i915_init_packets( struct i915_context *i915 ) i915->state.Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; i915->state.Buffer[I915_DESTREG_CBUFADDR1] = (BUF_3D_ID_COLOR_BACK | - BUF_3D_PITCH(screen->front.pitch * screen->cpp) | + BUF_3D_PITCH(screen->front.pitch * screen->cpp) | /* XXX FBO fix */ BUF_3D_USE_FENCE); i915->state.Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; i915->state.Buffer[I915_DESTREG_DBUFADDR1] = (BUF_3D_ID_DEPTH | - BUF_3D_PITCH(screen->depth.pitch * screen->cpp) | + BUF_3D_PITCH(screen->depth.pitch * screen->cpp) | /* XXX FBO fix */ BUF_3D_USE_FENCE); i915->state.Buffer[I915_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD; diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index fb39e03fcd7..018b33b1098 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -250,9 +250,11 @@ static void i915_emit_state( struct intel_context *intel ) OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]); OUT_RELOC(state->draw_region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0); - OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]); - OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]); - OUT_RELOC(state->depth_region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0); + if (state->depth_region) { + OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]); + OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]); + OUT_RELOC(state->depth_region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0); + } OUT_BATCH(state->Buffer[I915_DESTREG_DV0]); OUT_BATCH(state->Buffer[I915_DESTREG_DV1]); diff --git a/src/mesa/drivers/dri/i915/intel_blit.c b/src/mesa/drivers/dri/i915/intel_blit.c index 2ed4a88d9de..998b7ad5e74 100644 --- a/src/mesa/drivers/dri/i915/intel_blit.c +++ b/src/mesa/drivers/dri/i915/intel_blit.c @@ -33,10 +33,11 @@ #include "context.h" #include "enums.h" -#include "intel_reg.h" #include "intel_batchbuffer.h" -#include "intel_context.h" #include "intel_blit.h" +#include "intel_context.h" +#include "intel_fbo.h" +#include "intel_reg.h" #include "intel_regions.h" #include "intel_bufmgr.h" @@ -66,6 +67,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv ) */ LOCK_HARDWARE( intel ); + /* XXX FBO: change this to if intel->numClipRects */ if (intel->driDrawable && intel->driDrawable->numClipRects) { @@ -73,8 +75,8 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv ) __DRIdrawablePrivate *dPriv = intel->driDrawable; int nbox = dPriv->numClipRects; drm_clip_rect_t *pbox = dPriv->pClipRects; - int pitch = intelScreen->front.pitch; - int cpp = intelScreen->cpp; + int pitch = intelScreen->front.pitch; /* XXX FBO change */ + int cpp = intelScreen->cpp; /* XXX FBO change */ int BR13, CMD; int i; @@ -255,15 +257,12 @@ void intelEmitCopyBlit( struct intel_context *intel, void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch) + GLint cx, GLint cy, GLint cw, GLint ch) { struct intel_context *intel = intel_context( ctx ); intelScreenPrivate *intelScreen = intel->intelScreen; GLuint clear_depth, clear_color; - GLint pitch = intelScreen->front.pitch; - GLint cpp = intelScreen->cpp; - GLint i; - GLuint BR13, CMD, D_CMD; + GLbitfield skipBuffer = 0; BATCH_LOCALS; if (INTEL_DEBUG & DEBUG_DRI) @@ -280,52 +279,55 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, clear_depth |= (ctx->Stencil.Clear & 0xff) << 24; } - switch(cpp) { - case 2: - BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24); - D_CMD = CMD = XY_COLOR_BLT_CMD; - break; - case 4: - BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24) | (1<<25); - CMD = (XY_COLOR_BLT_CMD | - XY_COLOR_BLT_WRITE_ALPHA | - XY_COLOR_BLT_WRITE_RGB); - D_CMD = XY_COLOR_BLT_CMD; - if (flags & BUFFER_BIT_DEPTH) D_CMD |= XY_COLOR_BLT_WRITE_RGB; - if (flags & BUFFER_BIT_STENCIL) D_CMD |= XY_COLOR_BLT_WRITE_ALPHA; - break; - default: - BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24); - D_CMD = CMD = XY_COLOR_BLT_CMD; - break; + /* If clearing both depth and stencil, skip BUFFER_BIT_STENCIL in + * the loop below. + */ + if ((flags & BUFFER_BIT_DEPTH) && (flags & BUFFER_BIT_STENCIL)) { + skipBuffer = BUFFER_BIT_STENCIL; } intelFlush( &intel->ctx ); LOCK_HARDWARE( intel ); - if (intel->driDrawable->numClipRects) + if (intel->numClipRects) { drm_clip_rect_t clear; + int i; - /* flip top to bottom */ - clear.x1 = cx + intel->drawX; - clear.y1 = intel->driDrawable->y + intel->driDrawable->h - cy - ch; - clear.x2 = clear.x1 + cw; - clear.y2 = clear.y1 + ch; + if (intel->ctx.DrawBuffer->Name == 0) { + /* clearing a window */ - /* adjust for page flipping */ - if ( intel->sarea->pf_current_page == 1 ) { - GLuint tmp = flags; + /* flip top to bottom */ + clear.x1 = cx + intel->drawX; + clear.y1 = intel->driDrawable->y + intel->driDrawable->h - cy - ch; + clear.x2 = clear.x1 + cw; + clear.y2 = clear.y1 + ch; - flags &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT); - if ( tmp & BUFFER_BIT_FRONT_LEFT ) flags |= BUFFER_BIT_BACK_LEFT; - if ( tmp & BUFFER_BIT_BACK_LEFT ) flags |= BUFFER_BIT_FRONT_LEFT; + /* adjust for page flipping */ + if ( intel->sarea->pf_current_page == 1 ) { + GLuint tmp = flags; + + flags &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT); + if ( tmp & BUFFER_BIT_FRONT_LEFT ) flags |= BUFFER_BIT_BACK_LEFT; + if ( tmp & BUFFER_BIT_BACK_LEFT ) flags |= BUFFER_BIT_FRONT_LEFT; + } + } + else { + /* clearing FBO */ + ASSERT(intel->numClipRects == 1); + ASSERT(intel->pClipRects == &intel->fboRect); + clear.x1 = cx; + clear.y1 = intel->ctx.DrawBuffer->Height - cy - ch; + clear.x2 = clear.y1 + cw; + clear.y2 = clear.y1 + ch; + /* no change to flags */ } for (i = 0 ; i < intel->numClipRects ; i++) { - drm_clip_rect_t *box = &intel->pClipRects[i]; + const drm_clip_rect_t *box = &intel->pClipRects[i]; drm_clip_rect_t b; + GLuint buf; if (!all) { intel_intersect_cliprects(&b, &clear, box); @@ -339,38 +341,67 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, b.x2, b.y2, flags); - if ( flags & BUFFER_BIT_FRONT_LEFT ) { - BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); - OUT_BATCH( CMD ); - OUT_BATCH( BR13 ); - OUT_BATCH( (b.y1 << 16) | b.x1 ); - OUT_BATCH( (b.y2 << 16) | b.x2 ); - OUT_RELOC( intel->front_region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0 ); - OUT_BATCH( clear_color ); - ADVANCE_BATCH(); - } + /* Loop over all renderbuffers */ + for (buf = 0; buf < BUFFER_COUNT && flags; buf++) { + const GLbitfield bufBit = 1 << buf; + if ((flags & bufBit) && !(bufBit & skipBuffer)) { + /* OK, clear this renderbuffer */ + const struct intel_renderbuffer *irb + = intel_renderbuffer(ctx->DrawBuffer-> + Attachment[buf].Renderbuffer); + GLuint clearVal; + GLint pitch, cpp; + GLuint BR13, CMD; - if ( flags & BUFFER_BIT_BACK_LEFT ) { - BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); - OUT_BATCH( CMD ); - OUT_BATCH( BR13 ); - OUT_BATCH( (b.y1 << 16) | b.x1 ); - OUT_BATCH( (b.y2 << 16) | b.x2 ); - OUT_RELOC( intel->back_region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0 ); - OUT_BATCH( clear_color ); - ADVANCE_BATCH(); - } + ASSERT(irb); + ASSERT(irb->region); - if ( flags & (BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH) ) { - BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); - OUT_BATCH( D_CMD ); - OUT_BATCH( BR13 ); - OUT_BATCH( (b.y1 << 16) | b.x1 ); - OUT_BATCH( (b.y2 << 16) | b.x2 ); - OUT_RELOC( intel->depth_region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0 ); - OUT_BATCH( clear_depth ); - ADVANCE_BATCH(); - } + pitch = irb->region->pitch; + cpp = irb->region->cpp; + + if (cpp == 4) { + BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24) | (1<<25); + if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { + CMD = XY_COLOR_BLT_CMD; + if (flags & BUFFER_BIT_DEPTH) + CMD |= XY_COLOR_BLT_WRITE_RGB; + if (flags & BUFFER_BIT_STENCIL) + CMD |= XY_COLOR_BLT_WRITE_ALPHA; + } + else { + /* clearing RGBA */ + CMD = (XY_COLOR_BLT_CMD | + XY_COLOR_BLT_WRITE_ALPHA | + XY_COLOR_BLT_WRITE_RGB); + } + } + else { + ASSERT(cpp == 2 || cpp == 0); + BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24); + CMD = XY_COLOR_BLT_CMD; + } + + if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { + clearVal = clear_depth; + } + else { + clearVal = clear_color; + } + /* + _mesa_debug(ctx, "hardware blit clear buf %d rb id %d\n", + buf, irb->Base.Name); + */ + BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH( CMD ); + OUT_BATCH( BR13 ); + OUT_BATCH( (b.y1 << 16) | b.x1 ); + OUT_BATCH( (b.y2 << 16) | b.x2 ); + OUT_RELOC( irb->region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0 ); + OUT_BATCH( clearVal ); + ADVANCE_BATCH(); + flags &= ~(1 << buf); /* turn off bit, for faster loop exit */ + } + } } intel_batchbuffer_flush( intel->batch ); } diff --git a/src/mesa/drivers/dri/i915/intel_buffers.c b/src/mesa/drivers/dri/i915/intel_buffers.c index 77346ce26e0..6bd336594de 100644 --- a/src/mesa/drivers/dri/i915/intel_buffers.c +++ b/src/mesa/drivers/dri/i915/intel_buffers.c @@ -82,6 +82,7 @@ struct intel_region *intel_readbuf_region( struct intel_context *intel ) /* This will have to change to support EXT_fbo's, but is correct * for now: */ +#if 0 /* XXX FBO */ switch (ctx->ReadBuffer->_ColorReadBufferIndex) { case BUFFER_FRONT_LEFT: return intel->front_region; @@ -91,6 +92,10 @@ struct intel_region *intel_readbuf_region( struct intel_context *intel ) assert(0); return NULL; } +#else + struct intel_renderbuffer *irb = intel_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); + return irb->region; +#endif } @@ -213,8 +218,7 @@ static void intelSetBackClipRects( struct intel_context *intel ) /** * This will be called whenever the currently bound window is moved/resized. - * Actually, it seems that only window moves which expose new regions - * cause this function to be called. (BP) + * XXX: actually, it seems to NOT be called when the window is only moved (BP). */ void intelWindowMoved( struct intel_context *intel ) { @@ -246,14 +250,9 @@ void intelWindowMoved( struct intel_context *intel ) intel->driDrawable->w, intel->driDrawable->h); } - /* Set state we know depends on drawable parameters: - */ - { - GLcontext *ctx = &intel->ctx; - ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y, - ctx->Scissor.Width, ctx->Scissor.Height ); - - } + /* Update hardware scissor */ + ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height ); } @@ -267,32 +266,28 @@ static void intelClearWithTris(struct intel_context *intel, GLint cx, GLint cy, GLint cw, GLint ch) { - __DRIdrawablePrivate *dPriv = intel->driDrawable; + GLcontext *ctx = &intel->ctx; drm_clip_rect_t clear; - if (INTEL_DEBUG & DEBUG_DRI) - _mesa_printf("%s %x\n", __FUNCTION__, mask); + if (1/*INTEL_DEBUG & DEBUG_DRI*/) + _mesa_printf("%s 0x%x\n", __FUNCTION__, mask); LOCK_HARDWARE(intel); - if (intel->driDrawable->numClipRects) { + /* XXX FBO: was: intel->driDrawable->numClipRects */ + if (intel->numClipRects) { intel->vtbl.install_meta_state(intel); - if(!all) { - clear.x1 = cx; - clear.y1 = cy; - clear.x2 = cx + cw; - clear.y2 = cy + ch; - } else { - clear.x1 = 0; - clear.y1 = 0; - clear.x2 = dPriv->w; - clear.y2 = dPriv->h; - } + /* note: regardless of 'all', cx, cy, cw, ch are correct */ + clear.x1 = cx; + clear.y1 = cy; + clear.x2 = cx + cw; + clear.y2 = cy + ch; /* Back and stencil cliprects are the same. Try and do both * buffers at once: + * XXX FBO: This is broken for FBO depth/stencil buffers! */ if (mask & (BUFFER_BIT_BACK_LEFT|BUFFER_BIT_STENCIL|BUFFER_BIT_DEPTH)) { intel->vtbl.meta_draw_region(intel, @@ -348,6 +343,46 @@ static void intelClearWithTris(struct intel_context *intel, 0, 0, 0, 0); } + /* + * User-created RGBA renderbuffers + */ + if (mask & (BUFFER_BIT_COLOR0 | + BUFFER_BIT_COLOR1 | + BUFFER_BIT_COLOR2 | + BUFFER_BIT_COLOR3)) { + struct intel_region *depth_region = NULL; + GLuint buf; + + ASSERT(ctx->Const.MaxColorAttachments == 4); /* XXX FBO fix */ + + for (buf = BUFFER_COLOR0; buf <= BUFFER_COLOR3; buf++) { + const GLbitfield bufBit = 1 << buf; + if (mask & bufBit) { + struct intel_renderbuffer *irb = + intel_renderbuffer(ctx->DrawBuffer-> + Attachment[buf].Renderbuffer); + ASSERT(irb); + ASSERT(irb->region); + + /* XXX move these three calls outside loop? */ + intel->vtbl.meta_no_depth_write(intel); + intel->vtbl.meta_no_stencil_write(intel); + intel->vtbl.meta_color_mask(intel, GL_TRUE ); + intel->vtbl.meta_draw_region(intel, irb->region, depth_region); + + /* XXX: Using INTEL_BATCH_NO_CLIPRECTS here is dangerous as the + * drawing origin may not be correctly emitted. + */ + intel_meta_draw_quad(intel, + clear.x1, clear.x2, + clear.y1, clear.y2, + 0, + intel->ClearColor, + 0, 0, 0, 0); + } + } + } + intel->vtbl.leave_meta_state( intel ); intel_batchbuffer_flush( intel->batch ); } @@ -357,13 +392,21 @@ static void intelClearWithTris(struct intel_context *intel, - +/** + * Called by ctx->Driver.Clear. + */ static void intelClear(GLcontext *ctx, GLbitfield mask, GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch) { + const GLbitfield colorBufferBits = (BUFFER_BIT_FRONT_LEFT | + BUFFER_BIT_BACK_LEFT | + BUFFER_BIT_COLOR0 | + BUFFER_BIT_COLOR1 | + BUFFER_BIT_COLOR2 | + BUFFER_BIT_COLOR3); struct intel_context *intel = intel_context( ctx ); const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); GLbitfield tri_mask = 0; @@ -374,30 +417,19 @@ static void intelClear(GLcontext *ctx, fprintf(stderr, "%s\n", __FUNCTION__); - if (mask & BUFFER_BIT_FRONT_LEFT) { - if (colorMask == ~0) { - blit_mask |= BUFFER_BIT_FRONT_LEFT; - } - else { - tri_mask |= BUFFER_BIT_FRONT_LEFT; - } + /* HW color buffers (front, back, aux, generic FBO, etc) */ + if (colorMask == ~0) { + /* clear all R,G,B,A */ + blit_mask |= (mask & colorBufferBits); + } + else { + /* glColorMask in effect */ + tri_mask |= (mask & colorBufferBits); } - if (mask & BUFFER_BIT_BACK_LEFT) { - if (colorMask == ~0) { - blit_mask |= BUFFER_BIT_BACK_LEFT; - } - else { - tri_mask |= BUFFER_BIT_BACK_LEFT; - } - } - - - if (mask & BUFFER_BIT_STENCIL) { - if (!intel->hw_stencil) { - swrast_mask |= BUFFER_BIT_STENCIL; - } - else if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff) { + /* HW stencil */ + if (intel->hw_stencil && (mask & BUFFER_BIT_STENCIL)) { + if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff) { tri_mask |= BUFFER_BIT_STENCIL; } else { @@ -409,13 +441,20 @@ static void intelClear(GLcontext *ctx, * same buffer. */ if (mask & BUFFER_BIT_DEPTH) { + /* XXX is this logic correct? It looks like the blit routine + * can only clear both buffers while the triangle routine can do + * one or the other. (BP) + */ if (tri_mask & BUFFER_BIT_STENCIL) tri_mask |= BUFFER_BIT_DEPTH; else blit_mask |= BUFFER_BIT_DEPTH; } - swrast_mask |= (mask & BUFFER_BIT_ACCUM); + /* + * Clear in software whatever can't be done w/ hardware. + */ + swrast_mask = mask & ~tri_mask & ~blit_mask; intelFlush( ctx ); @@ -498,62 +537,109 @@ void intelSwapBuffers( __DRIdrawablePrivate *dPriv ) } } -static void intelDrawBuffer(GLcontext *ctx, GLenum mode ) + +/** + * Called via glDrawBuffer, glBindFramebufferEXT, and from various places + * within the driver. + * Note: mode parameter is not used. + */ +static void +intelDrawBuffer(GLcontext *ctx, GLenum mode ) { struct intel_context *intel = intel_context(ctx); - int front = 0; + struct intel_renderbuffer *irb; + struct intel_region *colorRegion, *depthRegion; + int front = 0; /* drawing to front color buffer? */ if (!ctx->DrawBuffer) { /* XXX I don't think this should ever happen. -BP */ return; } - switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) { - case BUFFER_BIT_FRONT_LEFT: - front = 1; - FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE ); - break; - case BUFFER_BIT_BACK_LEFT: - front = 0; - FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE ); - break; - default: - /* GL_FRONT_AND_BACK, GL_NONE, etc */ - FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE ); - return; + if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { + _mesa_update_framebuffer(ctx); } - if ( intel->sarea->pf_current_page == 1 ) - front ^= 1; - + /* + * How many color buffers are we drawing into? + */ + if (ctx->DrawBuffer->_NumColorDrawBuffers[0] != 1 +#if 1 + /* XXX FBO temporary - always use software rendering */ + || ctx->DrawBuffer->Name != 0 +#endif + ) { + /* writing to 0 or 2 or 4 color buffers */ + /*_mesa_debug(ctx, "Software rendering\n");*/ + FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE ); + front = 1; /* might not have back color buffer */ + } + else { + /* draw to exactly one color buffer */ + /*_mesa_debug(ctx, "Hardware rendering\n");*/ + FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE ); + if (ctx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) { + front = 1; + } + } + + /* + * Get the intel_renderbuffer we're drawing into. + * And set up cliprects. + */ if (ctx->DrawBuffer->Name == 0) { /* drawing to window system buffer */ - intelSetFrontClipRects( intel ); + if (intel->sarea->pf_current_page == 1 ) { + /* page flipped back/front */ + front ^= 1; + } + if (front) { + intelSetFrontClipRects( intel ); + irb = intel_renderbuffer(ctx->DrawBuffer-> + Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + } + else { + intelSetBackClipRects( intel ); + irb = intel_renderbuffer(ctx->DrawBuffer-> + Attachment[BUFFER_BACK_LEFT].Renderbuffer); + } } else { /* drawing to user-created FBO */ intelSetRenderbufferClipRects(intel); + irb = intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]); + ASSERT(irb); } - if (front) { - if (intel->draw_region != intel->front_region) { - intel_region_release(intel, &intel->draw_region); - intel_region_reference(&intel->draw_region, intel->front_region); - } - } else { - if (intel->draw_region != intel->back_region) { - intel_region_release(intel, &intel->draw_region); - intel_region_reference(&intel->draw_region, intel->back_region); - } + /* + * Get color buffer region. + */ + if (irb && irb->region) + colorRegion = irb->region; + else + colorRegion = NULL; + + /* + * Unbind old region, bind new region + */ + if (intel->draw_region != colorRegion) { + intel_region_release(intel, &intel->draw_region); + intel_region_reference(&intel->draw_region, colorRegion); } - intel->vtbl.set_draw_region( intel, - intel->draw_region, - intel->depth_region); + /* + * Get depth buffer region + */ + irb = intel_renderbuffer(ctx->DrawBuffer->_DepthBuffer); + if (irb && irb->region) + depthRegion = irb->region; + else + depthRegion = NULL; + + intel->vtbl.set_draw_region( intel, colorRegion, depthRegion ); } - static void intelReadBuffer( GLcontext *ctx, GLenum mode ) { /* Nothing. diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index 24fccb132ce..17d88ba3b7b 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -79,6 +79,7 @@ int INTEL_DEBUG = (0); #define need_GL_EXT_blend_minmax #define need_GL_EXT_cull_vertex #define need_GL_EXT_fog_coord +#define need_GL_EXT_framebuffer_object #define need_GL_EXT_multi_draw_arrays #define need_GL_EXT_secondary_color #define need_GL_NV_vertex_program @@ -166,6 +167,7 @@ const struct dri_extension card_extensions[] = { "GL_EXT_blend_subtract", NULL }, { "GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions }, { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, + { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, { "GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions }, { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions }, { "GL_EXT_stencil_wrap", NULL }, @@ -322,6 +324,8 @@ GLboolean intelInitContext( struct intel_context *intel, ctx->Const.MaxPointSizeAA = 3.0; ctx->Const.PointSizeGranularity = 1.0; + ctx->Const.MaxColorAttachments = 4; /* XXX FBO: review this */ + /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); _ac_CreateContext( ctx ); @@ -394,6 +398,10 @@ GLboolean intelInitContext( struct intel_context *intel, intel->intelScreen->tex.size, DRM_MM_TT); #endif + + /* XXX FBO: these have to go away! + * FBO regions should be setup when creating the drawable. */ + /* These are still static, but create regions for them. */ intel->front_region = @@ -481,7 +489,7 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv) /* This share group is about to go away, free our private * texture object data. */ - fprintf(stderr, "do somethign to free texture heaps\n"); + fprintf(stderr, "do something to free texture heaps\n"); } /* free the Mesa context */ @@ -501,6 +509,8 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv, if (driContextPriv) { struct intel_context *intel = (struct intel_context *) driContextPriv->driverPrivate; + GLframebuffer *drawFb = (GLframebuffer *) driDrawPriv->driverPrivate; + GLframebuffer *readFb = (GLframebuffer *) driReadPriv->driverPrivate; if ( intel->driDrawable != driDrawPriv ) { /* Shouldn't the readbuffer be stored also? */ @@ -508,9 +518,25 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv, intelWindowMoved( intel ); } - _mesa_make_current(&intel->ctx, - (GLframebuffer *) driDrawPriv->driverPrivate, - (GLframebuffer *) driReadPriv->driverPrivate); + /* XXX temporary fix-ups! */ + /* if the renderbuffers don't have regions, init them from the context */ + { + struct intel_renderbuffer *irbFront = intel_renderbuffer(drawFb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + struct intel_renderbuffer *irbBack = intel_renderbuffer(drawFb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); + struct intel_renderbuffer *irbDepth = intel_renderbuffer(drawFb->Attachment[BUFFER_DEPTH].Renderbuffer); + struct intel_renderbuffer *irbStencil = intel_renderbuffer(drawFb->Attachment[BUFFER_STENCIL].Renderbuffer); + + if (irbFront && !irbFront->region) + irbFront->region = intel->front_region; + if (irbBack && !irbBack->region) + irbBack->region = intel->back_region; + if (irbDepth && !irbDepth->region) + irbDepth->region = intel->depth_region; + if (irbStencil && !irbStencil->region) + irbStencil->region = intel->depth_region; /* YES */ + } + + _mesa_make_current(&intel->ctx, drawFb, readFb); intel->ctx.Driver.DrawBuffer( &intel->ctx, intel->ctx.Color.DrawBuffer[0] ); } else { diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h index 91f31ee73e1..0ff5c097f23 100644 --- a/src/mesa/drivers/dri/i915/intel_context.h +++ b/src/mesa/drivers/dri/i915/intel_context.h @@ -559,6 +559,8 @@ static inline struct intel_texture_image *intel_texture_image( struct gl_texture return (struct intel_texture_image *)img; } +extern struct intel_renderbuffer *intel_renderbuffer( struct gl_renderbuffer *rb ); + #endif diff --git a/src/mesa/drivers/dri/i915/intel_fbo.c b/src/mesa/drivers/dri/i915/intel_fbo.c index 610ee4e9a0e..eb5f710b2dd 100644 --- a/src/mesa/drivers/dri/i915/intel_fbo.c +++ b/src/mesa/drivers/dri/i915/intel_fbo.c @@ -40,6 +40,18 @@ #include "intel_span.h" +#define MAGIC 0x12345678 + + +struct intel_renderbuffer *intel_renderbuffer( struct gl_renderbuffer *rb ) +{ + struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb; + if (irb) { + assert(irb->Magic == 0x12345678); + } + return irb; +} + /** * Create a new framebuffer object. */ @@ -56,9 +68,9 @@ intel_delete_renderbuffer(struct gl_renderbuffer *rb) { GET_CURRENT_CONTEXT(ctx); struct intel_context *intel = intel_context(ctx); - struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb; + struct intel_renderbuffer *irb = intel_renderbuffer(rb); - if (irb->region) { + if (intel && irb->region) { intel_region_release(intel, &irb->region); } @@ -76,7 +88,7 @@ static void * intel_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb, GLint x, GLint y) { - struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb; + struct intel_renderbuffer *irb = intel_renderbuffer(rb); /* Actually, we could _always_ return NULL from this function and * be OK. The swrast code would just use the Get/Put routines as needed. @@ -106,7 +118,7 @@ intel_alloc_storage(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint width, GLuint height) { struct intel_context *intel = intel_context(ctx); - struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb; + struct intel_renderbuffer *irb = intel_renderbuffer(rb); const GLenum format = _mesa_base_fbo_format(ctx, internalFormat); GLboolean softwareBuffer = GL_FALSE; int cpp; @@ -126,25 +138,33 @@ intel_alloc_storage(GLcontext *ctx, struct gl_renderbuffer *rb, switch (format) { case GL_RGB: case GL_RGBA: + internalFormat = GL_RGBA8; rb->RedBits = 8; rb->GreenBits = 8; rb->BlueBits = 8; rb->AlphaBits = 8; + rb->DataType = GL_UNSIGNED_BYTE; cpp = 4; break; case GL_DEPTH_COMPONENT: + internalFormat = GL_DEPTH24_STENCIL8_EXT; rb->DepthBits = 24; + rb->DataType = GL_UNSIGNED_BYTE; cpp = 4; break; case GL_STENCIL_INDEX: + internalFormat = GL_STENCIL_INDEX8_EXT; rb->StencilBits = 8; + rb->DataType = GL_UNSIGNED_BYTE; cpp = 1; softwareBuffer = GL_TRUE; /* XXX software buffer? */ break; case GL_DEPTH_STENCIL_EXT: + internalFormat = GL_DEPTH24_STENCIL8_EXT; rb->DepthBits = 24; rb->StencilBits = 8; + rb->DataType = GL_UNSIGNED_INT; cpp = 4; break; default: @@ -164,26 +184,40 @@ intel_alloc_storage(GLcontext *ctx, struct gl_renderbuffer *rb, else { /* hardware renderbuffer */ /* alloc new region */ + assert(width > 1); + assert(height > 1); + _mesa_debug(ctx, "Allocating %d x %d Intel RBO\n", width, height); irb->region = intel_region_alloc(intel, cpp, width, height); if (!irb->region) return GL_FALSE; /* out of memory? */ } + rb->InternalFormat = internalFormat; + rb->Width = width; + rb->Height = height; + + /* This sets the Get/PutRow/Value functions */ + intel_set_span_functions(&irb->Base); + return GL_TRUE; } /** - * Just an error catcher. + * Called for each hardware renderbuffer when a _window_ is resized. + * Just update fields. + * Not use for user-created renderbuffers! */ static GLboolean -intel_alloc_storage_nop(GLcontext *ctx, struct gl_renderbuffer *rb, - GLenum internalFormat, - GLuint width, GLuint height) +intel_alloc_storage_window(GLcontext *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) { - _mesa_problem(ctx, "RenderBuffer storage called for intel window system renderbuffer!"); - return GL_FALSE; + rb->Width = width; + rb->Height = height; + rb->InternalFormat = internalFormat; + return GL_TRUE; } @@ -196,16 +230,20 @@ intel_alloc_storage_nop(GLcontext *ctx, struct gl_renderbuffer *rb, */ struct intel_renderbuffer * intel_create_renderbuffer(GLenum intFormat, GLsizei width, GLsizei height, - int offset, void *map) + int offset, int pitch, int cpp, void *map) { + GET_CURRENT_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); + struct intel_renderbuffer *irb; const GLuint name = 0; - int cpp; irb = CALLOC_STRUCT(intel_renderbuffer); if (!irb) return NULL; + irb->Magic = MAGIC; + _mesa_init_renderbuffer(&irb->Base, name); switch (intFormat) { @@ -214,6 +252,7 @@ intel_create_renderbuffer(GLenum intFormat, GLsizei width, GLsizei height, irb->Base.RedBits = 5; irb->Base.GreenBits = 6; irb->Base.BlueBits = 5; + irb->Base.DataType = GL_UNSIGNED_BYTE; cpp = 2; break; case GL_RGBA8: @@ -222,27 +261,32 @@ intel_create_renderbuffer(GLenum intFormat, GLsizei width, GLsizei height, irb->Base.GreenBits = 8; irb->Base.BlueBits = 8; irb->Base.AlphaBits = 8; + irb->Base.DataType = GL_UNSIGNED_BYTE; cpp = 4; break; case GL_STENCIL_INDEX8_EXT: irb->Base._BaseFormat = GL_STENCIL_INDEX; irb->Base.StencilBits = 8; + irb->Base.DataType = GL_UNSIGNED_BYTE; cpp = 1; break; case GL_DEPTH_COMPONENT16: irb->Base._BaseFormat = GL_DEPTH_COMPONENT; irb->Base.DepthBits = 16; + irb->Base.DataType = GL_UNSIGNED_SHORT; cpp = 2; break; case GL_DEPTH_COMPONENT24: irb->Base._BaseFormat = GL_DEPTH_COMPONENT; irb->Base.DepthBits = 24; + irb->Base.DataType = GL_UNSIGNED_INT; cpp = 4; break; case GL_DEPTH24_STENCIL8_EXT: irb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT; irb->Base.DepthBits = 24; irb->Base.StencilBits = 8; + irb->Base.DataType = GL_UNSIGNED_INT; cpp = 4; break; default: @@ -250,14 +294,19 @@ intel_create_renderbuffer(GLenum intFormat, GLsizei width, GLsizei height, return NULL; } + irb->Base.InternalFormat = intFormat; + /* intel-specific methods */ irb->Base.Delete = intel_delete_renderbuffer; - irb->Base.AllocStorage = intel_alloc_storage_nop; + irb->Base.AllocStorage = intel_alloc_storage_window; irb->Base.GetPointer = intel_get_pointer; /* This sets the Get/PutRow/Value functions */ intel_set_span_functions(&irb->Base); -#if 0 + irb->pfMap = map; + irb->pfPitch = pitch; + +#if 00 irb->region = intel_region_create_static(intel, DRM_MM_TT, offset, @@ -286,6 +335,8 @@ intel_new_renderbuffer(GLcontext *ctx, GLuint name) if (!irb) return NULL; + irb->Magic = MAGIC; + _mesa_init_renderbuffer(&irb->Base, name); /* intel-specific methods */ @@ -304,7 +355,10 @@ static void intel_bind_framebuffer(GLcontext *ctx, GLenum target, struct gl_framebuffer *fb) { + _mesa_debug(ctx, "%s %d\n", __FUNCTION__, fb->Name); + if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { +#if 00 struct intel_context *intel = intel_context(ctx); struct gl_renderbuffer *rbColor, *rbDepth; struct intel_renderbuffer *irbColor, *irbDepth; @@ -314,8 +368,8 @@ intel_bind_framebuffer(GLcontext *ctx, GLenum target, rbColor = intel->ctx.DrawBuffer->_ColorDrawBuffers[0][0]; rbDepth = intel->ctx.DrawBuffer->_DepthBuffer; - irbColor = (struct intel_renderbuffer *) rbColor; - irbDepth = (struct intel_renderbuffer *) rbDepth; + irbColor = intel_renderbuffer(rbColor); + irbDepth = intel_renderbuffer(rbDepth); if (irbColor && irbColor->region) colorRegion = irbColor->region; @@ -327,7 +381,11 @@ intel_bind_framebuffer(GLcontext *ctx, GLenum target, else depthRegion = NULL; + /* XXX FBO */ intel->vtbl.set_draw_region(intel, colorRegion, depthRegion); +#else + ctx->Driver.DrawBuffer(ctx, 0); /* second param is ignored */ +#endif } else { /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */ @@ -344,7 +402,10 @@ intel_framebuffer_renderbuffer(GLcontext *ctx, GLenum attachment, struct gl_renderbuffer *rb) { - /* no-op */ + _mesa_debug(ctx, "Intel FramebufferRenderbuffer %u %u\n", + fb->Name, rb->Name); + + _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); } diff --git a/src/mesa/drivers/dri/i915/intel_fbo.h b/src/mesa/drivers/dri/i915/intel_fbo.h index 7a1c3f8a556..46565d9af14 100644 --- a/src/mesa/drivers/dri/i915/intel_fbo.h +++ b/src/mesa/drivers/dri/i915/intel_fbo.h @@ -28,10 +28,9 @@ #ifndef INTEL_FBO_H #define INTEL_FBO_H -#include "drirenderbuffer.h" - struct intel_context; +struct intel_region; /** @@ -40,12 +39,15 @@ struct intel_context; struct intel_renderbuffer { struct gl_renderbuffer Base; struct intel_region *region; + void *pfMap; /* possibly paged flipped map pointer */ + GLuint pfPitch; /* possibly paged flipped pitch */ + GLuint Magic; /* for debug/sanity */ }; extern struct intel_renderbuffer * intel_create_renderbuffer(GLenum intFormat, GLsizei width, GLsizei height, - int offset, void *map); + int offset, int pitch, int cpp, void *map); extern void diff --git a/src/mesa/drivers/dri/i915/intel_regions.c b/src/mesa/drivers/dri/i915/intel_regions.c index f55a002fdaa..1fe93e0546e 100644 --- a/src/mesa/drivers/dri/i915/intel_regions.c +++ b/src/mesa/drivers/dri/i915/intel_regions.c @@ -89,9 +89,11 @@ struct intel_region *intel_region_alloc( struct intel_context *intel, void intel_region_reference( struct intel_region **dst, struct intel_region *src) { - src->refcount++; assert(*dst == NULL); - *dst = src; + if (src) { + src->refcount++; + *dst = src; + } } void intel_region_release( struct intel_context *intel, @@ -111,7 +113,7 @@ void intel_region_release( struct intel_context *intel, } -struct intel_region *intel_region_create_static( struct intel_context *intel, +struct intel_region *intel_region_create_static( struct intel_context *intel, GLuint mem_type, GLuint offset, void *virtual, diff --git a/src/mesa/drivers/dri/i915/intel_regions.h b/src/mesa/drivers/dri/i915/intel_regions.h index 327c3c1f675..3b33bca7750 100644 --- a/src/mesa/drivers/dri/i915/intel_regions.h +++ b/src/mesa/drivers/dri/i915/intel_regions.h @@ -41,7 +41,7 @@ struct intel_context; * - Blitter commands for copying 2D regions between buffers. (really???) */ struct intel_region { - GLuint buffer; + GLuint buffer; /* buffer manager's buffer ID */ GLuint refcount; GLuint cpp; /* bytes per pixel */ GLuint pitch; /* in pixels */ diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c index cc2b1ba5103..715d05e844b 100644 --- a/src/mesa/drivers/dri/i915/intel_screen.c +++ b/src/mesa/drivers/dri/i915/intel_screen.c @@ -222,6 +222,9 @@ static void intelDestroyScreen(__DRIscreenPrivate *sPriv) } +/** + * This is called when we need to set up GL rendering to a new X window. + */ static GLboolean intelCreateBuffer( __DRIscreenPrivate *driScrnPriv, __DRIdrawablePrivate *driDrawPriv, const __GLcontextModes *mesaVis, @@ -238,62 +241,82 @@ static GLboolean intelCreateBuffer( __DRIscreenPrivate *driScrnPriv, struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis); + printf("** front addr = %p\n", (void*) driScrnPriv->pFB); + printf("** back addr = %p\n", (void*) screen->back.map); + printf("** depth addr = %p\n", (void*) screen->depth.map); + /* setup the hardware-based renderbuffers */ { - driRenderbuffer *frontRb - = driNewRenderbuffer(rgbFormat, - driScrnPriv->pFB, - screen->cpp, - screen->front.offset, screen->front.pitch, - driDrawPriv); + struct intel_renderbuffer *frontRb + = intel_create_renderbuffer(rgbFormat, + screen->width, screen->height, + screen->front.offset, + screen->front.pitch, + screen->cpp, + driScrnPriv->pFB); intel_set_span_functions(&frontRb->Base); _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base); } if (mesaVis->doubleBufferMode) { - driRenderbuffer *backRb - = driNewRenderbuffer(rgbFormat, - screen->back.map, - screen->cpp, - screen->back.offset, screen->back.pitch, - driDrawPriv); + struct intel_renderbuffer *backRb + = intel_create_renderbuffer(rgbFormat, + screen->width, screen->height, + screen->back.offset, + screen->back.pitch, + screen->cpp, + screen->back.map); intel_set_span_functions(&backRb->Base); _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base); } - if (mesaVis->depthBits > 0) { - /* XXX if 32bpp, this should probably be a GL_DEPTH_STENCIL buffer */ - GLenum depthFormat = (mesaVis->depthBits == 16) - ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT24; - driRenderbuffer *depthRb - = driNewRenderbuffer(depthFormat, - screen->depth.map, - screen->cpp, - screen->depth.offset, screen->depth.pitch, - driDrawPriv); - intel_set_span_functions(&depthRb->Base); - _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); + if (mesaVis->depthBits == 24 && mesaVis->stencilBits == 8) { + /* combined depth/stencil buffer */ + struct intel_renderbuffer *depthStencilRb + = intel_create_renderbuffer(/**GL_DEPTH24_STENCIL8_EXT,**/ + GL_DEPTH_COMPONENT24, + screen->width, screen->height, + screen->depth.offset, + screen->depth.pitch, + screen->cpp, /* 4! */ + screen->depth.map); + intel_set_span_functions(&depthStencilRb->Base); + /* note: bind RB to two attachment points */ + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthStencilRb->Base); +#if 1 + /* XXX TEMP: separate stencil */ + depthStencilRb + = intel_create_renderbuffer(GL_STENCIL_INDEX8_EXT, + screen->width, screen->height, + screen->depth.offset, + screen->depth.pitch, + screen->cpp, /* 4! */ + screen->depth.map); + intel_set_span_functions(&depthStencilRb->Base); +#endif + _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &depthStencilRb->Base); } - - if (mesaVis->stencilBits > 0 && !swStencil) { - driRenderbuffer *stencilRb - = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT, - screen->depth.map, - screen->cpp, - screen->depth.offset, screen->depth.pitch, - driDrawPriv); - intel_set_span_functions(&stencilRb->Base); - _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base); + else if (mesaVis->depthBits == 16) { + /* just 16-bit depth buffer, no hw stencil */ + struct intel_renderbuffer *depthRb + = intel_create_renderbuffer(GL_DEPTH_COMPONENT16, + screen->width, screen->height, + screen->depth.offset, + screen->depth.pitch, + screen->cpp, /* 2! */ + screen->depth.map); + intel_set_span_functions(&depthRb->Base); + _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &depthRb->Base); } /* now add any/all software-based renderbuffers we may need */ _mesa_add_soft_renderbuffers(fb, - GL_FALSE, /* color */ - GL_FALSE, /* depth */ + GL_FALSE, /* never sw color */ + GL_FALSE, /* never sw depth */ swStencil, mesaVis->accumRedBits > 0, - GL_FALSE, /* alpha */ - GL_FALSE /* aux */); + GL_FALSE, /* never sw alpha */ + GL_FALSE /* never sw aux */); driDrawPriv->driverPrivate = (void *) fb; return (driDrawPriv->driverPrivate != NULL); diff --git a/src/mesa/drivers/dri/i915/intel_span.c b/src/mesa/drivers/dri/i915/intel_span.c index 4d1ee093151..15eafabd09b 100644 --- a/src/mesa/drivers/dri/i915/intel_span.c +++ b/src/mesa/drivers/dri/i915/intel_span.c @@ -39,21 +39,39 @@ #include "swrast/swrast.h" +/* + break intelWriteRGBASpan_ARGB8888 +*/ + #undef DBG #define DBG 0 -#define LOCAL_VARS \ - struct intel_context *intel = intel_context(ctx); \ - driRenderbuffer *drb = (driRenderbuffer *) rb; \ - const __DRIdrawablePrivate *dPriv = drb->dPriv; \ - const GLuint bottom = dPriv->h - 1; \ - GLubyte *buf = (GLubyte *) drb->flippedData \ - + (dPriv->y * drb->flippedPitch + dPriv->x) * drb->cpp; \ - GLuint p; \ - assert(dPriv->x == intel->drawX); \ - assert(dPriv->y == intel->drawY); \ +#define LOCAL_VARS \ + struct intel_context *intel = intel_context(ctx); \ + struct intel_renderbuffer *irb = intel_renderbuffer(rb); \ + const GLuint bottom = irb->Base.Height - 1; \ + GLubyte *buf = (GLubyte *) irb->pfMap \ + + (intel->drawY * irb->pfPitch + intel->drawX) * irb->region->cpp;\ + GLuint p; \ + assert(irb->pfMap);\ (void) p; +/* XXX FBO: this is identical to the macro in spantmp2.h except we get + * the cliprect info from the context, not the driDrawable. + * Move this into spantmp2.h someday. + */ +#define HW_CLIPLOOP() \ + do { \ + int _nc = intel->numClipRects; \ + while ( _nc-- ) { \ + int minx = intel->pClipRects[_nc].x1 - intel->drawX; \ + int miny = intel->pClipRects[_nc].y1 - intel->drawY; \ + int maxx = intel->pClipRects[_nc].x2 - intel->drawX; \ + int maxy = intel->pClipRects[_nc].y2 - intel->drawY; + + + + #define Y_FLIP(_y) (bottom - _y) #define HW_LOCK() @@ -67,7 +85,7 @@ #define TAG(x) intel##x##_RGB565 #define TAG2(x,y) intel##x##_RGB565##y -#define GET_PTR(X,Y) (buf + ((Y) * drb->flippedPitch + (X)) * 2) +#define GET_PTR(X,Y) (buf + ((Y) * irb->pfPitch + (X)) * 2) #include "spantmp2.h" /* 32 bit, ARGB8888 color spanline and pixel functions @@ -77,29 +95,28 @@ #define TAG(x) intel##x##_ARGB8888 #define TAG2(x,y) intel##x##_ARGB8888##y -#define GET_PTR(X,Y) (buf + ((Y) * drb->flippedPitch + (X)) * 4) +#define GET_PTR(X,Y) (buf + ((Y) * irb->pfPitch + (X)) * 4) #include "spantmp2.h" -#define LOCAL_DEPTH_VARS \ - struct intel_context *intel = intel_context(ctx); \ - __DRIdrawablePrivate *dPriv = intel->driDrawable; \ - driRenderbuffer *drb = (driRenderbuffer *) rb; \ - const GLuint pitch = drb->pitch * drb->cpp; \ - const GLuint bottom = dPriv->h - 1; \ - char *buf = (char *) drb->Base.Data + \ - dPriv->x * drb->cpp + \ - dPriv->y * pitch +#define LOCAL_DEPTH_VARS \ + struct intel_context *intel = intel_context(ctx); \ + struct intel_renderbuffer *irb = intel_renderbuffer(rb); \ + const GLuint pitch = irb->pfPitch/***XXX region->pitch*/; /* in pixels */ \ + const GLuint bottom = rb->Height - 1; \ + char *buf = (char *) irb->pfMap/*XXX use region->map*/ + \ + (intel->drawY * pitch + intel->drawX) * irb->region->cpp; + #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS /* 16 bit depthbuffer functions. */ #define WRITE_DEPTH( _x, _y, d ) \ - *(GLushort *)(buf + (_x)*2 + (_y)*pitch) = d; + ((GLushort *)buf)[(_x) + (_y) * pitch] = d; #define READ_DEPTH( d, _x, _y ) \ - d = *(GLushort *)(buf + (_x)*2 + (_y)*pitch); + d = ((GLushort *)buf)[(_x) + (_y) * pitch]; #define TAG(x) intel##x##_z16 @@ -108,29 +125,29 @@ /* 24/8 bit interleaved depth/stencil functions */ -#define WRITE_DEPTH( _x, _y, d ) { \ - GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \ - tmp &= 0xff000000; \ - tmp |= (d) & 0xffffff; \ - *(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \ +#define WRITE_DEPTH( _x, _y, d ) { \ + GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch]; \ + tmp &= 0xff000000; \ + tmp |= (d) & 0xffffff; \ + ((GLuint *)buf)[(_x) + (_y) * pitch] = tmp; \ } -#define READ_DEPTH( d, _x, _y ) \ - d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch) & 0xffffff; +#define READ_DEPTH( d, _x, _y ) \ + d = ((GLuint *)buf)[(_x) + (_y) * pitch] & 0xffffff; #define TAG(x) intel##x##_z24_s8 #include "depthtmp.h" -#define WRITE_STENCIL( _x, _y, d ) { \ - GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \ - tmp &= 0xffffff; \ - tmp |= ((d)<<24); \ - *(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \ +#define WRITE_STENCIL( _x, _y, d ) { \ + GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch]; \ + tmp &= 0xffffff; \ + tmp |= ((d) << 24); \ + ((GLuint *) buf)[(_x) + (_y) * pitch] = tmp; \ } -#define READ_STENCIL( d, _x, _y ) \ - d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch) >> 24; +#define READ_STENCIL( d, _x, _y ) \ + d = ((GLuint *)buf)[(_x) + (_y) * pitch] >> 24; #define TAG(x) intel##x##_z24_s8 #include "stenciltmp.h" @@ -150,49 +167,82 @@ intel_map_unmap_buffers(struct intel_context *intel, GLboolean map) GLcontext *ctx = &intel->ctx; GLuint i, j; struct intel_renderbuffer *irb; - /* color draw buffers */ for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers[i]; j++) { struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i][j]; - irb = (struct intel_renderbuffer *) rb; + irb = intel_renderbuffer(rb); ASSERT(irb); - if (irb->region) { - if (map) - intel_region_map(intel, irb->region); - else - intel_region_unmap(intel, irb->region); + if (irb->Base.Name != 0) { /* XXX FBO temporary test */ + if (irb->region) { + if (map) + intel_region_map(intel, irb->region); + else + intel_region_unmap(intel, irb->region); + } + irb->pfMap = irb->region->map; + irb->pfPitch = irb->region->pitch; } } } /* color read buffers */ - irb = (struct intel_renderbuffer *) ctx->ReadBuffer->_ColorReadBuffer; - if (irb && irb->region) { + irb = intel_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); + if (irb && irb->region && irb->Base.Name != 0) { if (map) intel_region_map(intel, irb->region); else intel_region_unmap(intel, irb->region); } - /* depth buffer */ - /* XXX wrappers? */ - irb = (struct intel_renderbuffer *) ctx->ReadBuffer->_DepthBuffer; - if (irb && irb->region) { - if (map) - intel_region_map(intel, irb->region); - else - intel_region_unmap(intel, irb->region); + /* Account for front/back color page flipping. + * The span routines use the pfMap and pfPitch fields which will + * swap the front/back region map/pitch if we're page flipped. + * Do this after mapping, above, so the map field is valid. + */ +#if 0 + if (map && ctx->DrawBuffer->Name == 0) { + struct intel_renderbuffer *irbFront = intel_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + struct intel_renderbuffer *irbBack = intel_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer); + if (irbBack) { + /* double buffered */ + if (intel->sarea->pf_current_page == 0) { + irbFront->pfMap = irbFront->region->map; + irbFront->pfPitch = irbFront->region->pitch; + irbBack->pfMap = irbBack->region->map; + irbBack->pfPitch = irbBack->region->pitch; + } + else { + irbFront->pfMap = irbBack->region->map; + irbFront->pfPitch = irbBack->region->pitch; + irbBack->pfMap = irbFront->region->map; + irbBack->pfPitch = irbFront->region->pitch; + } + } + } +#endif + + /* depth buffer (Note wrapper!) */ + if (ctx->DrawBuffer->_DepthBuffer) { + irb = intel_renderbuffer(ctx->DrawBuffer->_DepthBuffer->Wrapped); + if (irb && irb->region && irb->Base.Name != 0) { + if (map) + intel_region_map(intel, irb->region); + else + intel_region_unmap(intel, irb->region); + } } - /* stencil buffer */ - irb = (struct intel_renderbuffer *) ctx->ReadBuffer->_StencilBuffer; - if (irb && irb->region) { - if (map) - intel_region_map(intel, irb->region); - else - intel_region_unmap(intel, irb->region); + /* stencil buffer (Note wrapper!) */ + if (ctx->DrawBuffer->_StencilBuffer) { + irb = intel_renderbuffer(ctx->DrawBuffer->_StencilBuffer->Wrapped); + if (irb && irb->region && irb->Base.Name != 0) { + if (map) + intel_region_map(intel, irb->region); + else + intel_region_unmap(intel, irb->region); + } } } @@ -212,12 +262,14 @@ void intelSpanRenderStart( GLcontext *ctx ) intelFlush(&intel->ctx); LOCK_HARDWARE(intel); +#if 0 /* Just map the framebuffer and all textures. Bufmgr code will * take care of waiting on the necessary fences: */ intel_region_map(intel, intel->front_region); intel_region_map(intel, intel->back_region); intel_region_map(intel, intel->depth_region); +#endif for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { if (ctx->Texture.Unit[i]._ReallyEnabled) { @@ -225,6 +277,11 @@ void intelSpanRenderStart( GLcontext *ctx ) intel_tex_map_images(intel, intel_texture_object(texObj)); } } + +#if 1 + /* XXX FBO: enable this code when old DRI screen mappings go away */ + intel_map_unmap_buffers(intel, GL_TRUE); +#endif } /** @@ -240,9 +297,11 @@ void intelSpanRenderFinish( GLcontext *ctx ) /* Now unmap the framebuffer: */ +#if 0 intel_region_unmap(intel, intel->front_region); intel_region_unmap(intel, intel->back_region); intel_region_unmap(intel, intel->depth_region); +#endif for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { if (ctx->Texture.Unit[i]._ReallyEnabled) { @@ -251,6 +310,11 @@ void intelSpanRenderFinish( GLcontext *ctx ) } } +#if 1 + /* XXX FBO: enable this code when old DRI screen mappings go away */ + intel_map_unmap_buffers(intel, GL_FALSE); +#endif + UNLOCK_HARDWARE( intel ); } @@ -276,10 +340,11 @@ intel_set_span_functions(struct gl_renderbuffer *rb) else if (rb->InternalFormat == GL_DEPTH_COMPONENT16) { intelInitDepthPointers_z16(rb); } - else if (rb->InternalFormat == GL_DEPTH_COMPONENT24) { + else if (rb->InternalFormat == GL_DEPTH_COMPONENT24 || /* XXX FBO remove */ + rb->InternalFormat == GL_DEPTH24_STENCIL8_EXT) { intelInitDepthPointers_z24_s8(rb); } - else if (rb->InternalFormat == GL_STENCIL_INDEX8_EXT) { + else if (rb->InternalFormat == GL_STENCIL_INDEX8_EXT) { /* XXX FBO remove */ intelInitStencilPointers_z24_s8(rb); } else { diff --git a/src/mesa/drivers/dri/i915/intel_span.h b/src/mesa/drivers/dri/i915/intel_span.h index 254be5a1ba6..98dd57b06a8 100644 --- a/src/mesa/drivers/dri/i915/intel_span.h +++ b/src/mesa/drivers/dri/i915/intel_span.h @@ -28,8 +28,6 @@ #ifndef _INTEL_SPAN_H #define _INTEL_SPAN_H -#include "drirenderbuffer.h" - extern void intelInitSpanFuncs( GLcontext *ctx ); extern void intelSpanRenderFinish( GLcontext *ctx );