📄 intel_buffers.c
字号:
} UNLOCK_HARDWARE(intel);}/** * Called by ctx->Driver.Clear. */static void intelClear(GLcontext *ctx, GLbitfield mask, GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch){ struct intel_context *intel = intel_context( ctx ); const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); GLbitfield tri_mask = 0; GLbitfield blit_mask = 0; GLbitfield swrast_mask = 0; GLuint i; if (0) fprintf(stderr, "%s\n", __FUNCTION__); /* HW color buffers (front, back, aux, generic FBO, etc) */ if (colorMask == ~0) { /* clear all R,G,B,A */ /* XXX FBO: need to check if colorbuffers are software RBOs! */ blit_mask |= (mask & BUFFER_BITS_COLOR); } else { /* glColorMask in effect */ tri_mask |= (mask & BUFFER_BITS_COLOR); } /* HW stencil */ if (mask & BUFFER_BIT_STENCIL) { const struct intel_region *stencilRegion = intel_get_rb_region(ctx->DrawBuffer, BUFFER_STENCIL); if (stencilRegion) { /* have hw stencil */ if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff) { /* not clearing all stencil bits, so use triangle clearing */ tri_mask |= BUFFER_BIT_STENCIL; } else { /* clearing all stencil bits, use blitting */ blit_mask |= BUFFER_BIT_STENCIL; } } } /* HW depth */ if (mask & BUFFER_BIT_DEPTH) { /* clear depth with whatever method is used for stencil (see above) */ if (tri_mask & BUFFER_BIT_STENCIL) tri_mask |= BUFFER_BIT_DEPTH; else blit_mask |= BUFFER_BIT_DEPTH; } /* SW fallback clearing */ swrast_mask = mask & ~tri_mask & ~blit_mask; for (i = 0; i < BUFFER_COUNT; i++) { GLuint bufBit = 1 << i; if ((blit_mask | tri_mask) & bufBit) { if (!ctx->DrawBuffer->Attachment[i].Renderbuffer->ClassID) { blit_mask &= ~bufBit; tri_mask &= ~bufBit; swrast_mask |= bufBit; } } } intelFlush( ctx ); /* XXX intelClearWithBlit also does this */ if (blit_mask) intelClearWithBlit( ctx, blit_mask, all, cx, cy, cw, ch ); if (tri_mask) intelClearWithTris( intel, tri_mask, all, cx, cy, cw, ch); if (swrast_mask) _swrast_Clear( ctx, swrast_mask, all, cx, cy, cw, ch );}/* Flip the front & back buffers */static void intelPageFlip( const __DRIdrawablePrivate *dPriv ){#if 0 struct intel_context *intel; int tmp, ret; if (INTEL_DEBUG & DEBUG_IOCTL) fprintf(stderr, "%s\n", __FUNCTION__); assert(dPriv); assert(dPriv->driContextPriv); assert(dPriv->driContextPriv->driverPrivate); intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate; intelFlush( &intel->ctx ); LOCK_HARDWARE( intel ); if (dPriv->pClipRects) { *(drm_clip_rect_t *)intel->sarea->boxes = dPriv->pClipRects[0]; intel->sarea->nbox = 1; } ret = drmCommandNone(intel->driFd, DRM_I830_FLIP); if (ret) { fprintf(stderr, "%s: %d\n", __FUNCTION__, ret); UNLOCK_HARDWARE( intel ); exit(1); } tmp = intel->sarea->last_enqueue; intelRefillBatchLocked( intel ); UNLOCK_HARDWARE( intel ); intelSetDrawBuffer( &intel->ctx, intel->ctx.Color.DriverDrawBuffer );#endif}void intelSwapBuffers( __DRIdrawablePrivate *dPriv ){ if (dPriv->driverPrivate) { const struct gl_framebuffer *fb = (struct gl_framebuffer *) dPriv->driverPrivate; if (fb->Visual.doubleBufferMode) { GET_CURRENT_CONTEXT(ctx); if (ctx && ctx->DrawBuffer == fb) { _mesa_notifySwapBuffers( ctx ); /* flush pending rendering */ } if ( 0 /*intel->doPageFlip*/ ) { /* doPageFlip is never set !!! */ intelPageFlip( dPriv ); } else { intelCopyBuffer( dPriv ); } } } else { _mesa_problem(NULL, "dPriv has no gl_framebuffer pointer in intelSwapBuffers"); }}/** * Update the hardware state for drawing into a window or framebuffer object. * * Called by glDrawBuffer, glBindFramebufferEXT, MakeCurrent, and other * places within the driver. * * Basically, this needs to be called any time the current framebuffer * changes, the renderbuffers change, or we need to draw into different * color buffers. */voidintel_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb){ struct intel_context *intel = intel_context(ctx); struct intel_region *colorRegion, *depthRegion = NULL; struct intel_renderbuffer *irbDepth = NULL, *irbStencil = NULL; int front = 0; /* drawing to front color buffer? */ if (!fb) { /* this can happen during the initial context initialization */ 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) intel_validate_paired_depth_stencil(ctx, fb); /* * How many color buffers are we drawing into? */ if (fb->_NumColorDrawBuffers[0] != 1#if 0 /* XXX FBO temporary - always use software rendering */ || 1#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 (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) { front = 1; } } /* * Get the intel_renderbuffer for the colorbuffer we're drawing into. * And set up cliprects. */ if (fb->Name == 0) { /* drawing to window system buffer */ if (intel->sarea->pf_current_page == 1 ) { /* page flipped back/front */ front ^= 1; } if (front) { intelSetFrontClipRects( intel ); colorRegion = intel_get_rb_region(fb, BUFFER_FRONT_LEFT); } else { intelSetBackClipRects( intel ); colorRegion = intel_get_rb_region(fb, BUFFER_BACK_LEFT); } } else { /* drawing to user-created FBO */ struct intel_renderbuffer *irb; intelSetRenderbufferClipRects(intel); irb = intel_renderbuffer(fb->_ColorDrawBuffers[0][0]); colorRegion = (irb && irb->region) ? irb->region : NULL; } if (!colorRegion) { FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE ); } else { FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE ); } /*** *** Get depth buffer region and check if we need a software fallback. *** Note that the depth buffer is usually a DEPTH_STENCIL buffer. ***/ if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) { irbDepth = intel_renderbuffer(fb->_DepthBuffer->Wrapped); if (irbDepth->region) { FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE); depthRegion = irbDepth->region; } else { FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_TRUE); depthRegion = NULL; } } else { /* not using depth buffer */ FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE); depthRegion = NULL; } /*** *** Stencil buffer *** This can only be hardware accelerated if we're using a *** combined DEPTH_STENCIL buffer (for now anyway). ***/ if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) { irbStencil = intel_renderbuffer(fb->_StencilBuffer->Wrapped); if (irbStencil && irbStencil->region) { ASSERT(irbStencil->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE); /* need to re-compute stencil hw state */ ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); if (!depthRegion) depthRegion = irbStencil->region; } else { FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_TRUE); } } else { /* XXX FBO: instead of FALSE, pass ctx->Stencil.Enabled ??? */ FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE); /* need to re-compute stencil hw state */ ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); } /** ** Release old regions, reference new regions **/#if 0 /* XXX FBO: this seems to be redundant with i915_state_draw_region() */ if (intel->draw_region != colorRegion) { intel_region_release(intel, &intel->draw_region); intel_region_reference(&intel->draw_region, colorRegion); } if (intel->depth_region != depthRegion) { intel_region_release(intel, &intel->depth_region); intel_region_reference(&intel->depth_region, depthRegion); }#endif intel->vtbl.set_draw_region( intel, colorRegion, depthRegion ); /* update viewport since it depends on window size */ ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, ctx->Viewport.Width, ctx->Viewport.Height); /* Update hardware scissor */ ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y, ctx->Scissor.Width, ctx->Scissor.Height );}static voidintelDrawBuffer(GLcontext *ctx, GLenum mode){ intel_draw_buffer(ctx, ctx->DrawBuffer);}static void intelReadBuffer( GLcontext *ctx, GLenum mode ){ 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. */ intel_draw_buffer(ctx, ctx->DrawBuffer); } /* Generally, functions which read pixels (glReadPixels, glCopyPixels, etc) * reference ctx->ReadBuffer and do appropriate state checks. */}void intelInitBufferFuncs( struct dd_function_table *functions ){ functions->Clear = intelClear; functions->GetBufferSize = intelBufferSize; functions->ResizeBuffers = _mesa_resize_framebuffer; functions->DrawBuffer = intelDrawBuffer; functions->ReadBuffer = intelReadBuffer;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -