📄 intel_buffers.c
字号:
LOCK_HARDWARE(intel); intel_batchbuffer_flush(intel->batch); if ( intel_fb->pf_active ) { swap.seqtype |= DRM_VBLANK_FLIP; intel_fb->pf_current_page = (((intel->sarea->pf_current_page >> (intel_fb->pf_planes & 0x2)) & 0x3) + 1) % intel_fb->pf_num_pages; } if (!drmCommandWriteRead(intel->driFd, DRM_I915_VBLANK_SWAP, &swap, sizeof(swap))) { dPriv->vblSeq = swap.sequence; swap.sequence -= target; *missed_target = swap.sequence > 0 && swap.sequence <= (1 << 23); intel_get_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT)->vbl_pending = intel_get_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT)->vbl_pending = dPriv->vblSeq; if (swap.seqtype & DRM_VBLANK_FLIP) { intel_flip_renderbuffers(intel_fb); intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer); } ret = GL_TRUE; } else { if (swap.seqtype & DRM_VBLANK_FLIP) { intel_fb->pf_current_page = ((intel->sarea->pf_current_page >> (intel_fb->pf_planes & 0x2)) & 0x3) % intel_fb->pf_num_pages; } ret = GL_FALSE; } UNLOCK_HARDWARE(intel); return ret;} voidintelSwapBuffers(__DRIdrawablePrivate * dPriv){ __DRIscreenPrivate *psp = dPriv->driScreenPriv; if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { GET_CURRENT_CONTEXT(ctx); struct intel_context *intel; if (ctx == NULL) return; intel = intel_context(ctx); if (ctx->Visual.doubleBufferMode) { GLboolean missed_target; struct intel_framebuffer *intel_fb = dPriv->driverPrivate; int64_t ust; _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ if (!intelScheduleSwap(dPriv, &missed_target)) { driWaitForVBlank(dPriv, &missed_target); /* * Update each buffer's vbl_pending so we don't get too out of * sync */ intel_get_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT)->vbl_pending = intel_get_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT)->vbl_pending = dPriv->vblSeq; if (!intelPageFlip(dPriv)) { intelCopyBuffer(dPriv, NULL); } } intel_fb->swap_count++; (*psp->systemTime->getUST) (&ust); if (missed_target) { intel_fb->swap_missed_count++; intel_fb->swap_missed_ust = ust - intel_fb->swap_ust; } intel_fb->swap_ust = ust; } } else { /* XXX this shouldn't be an error but we can't handle it for now */ fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); }}voidintelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h){ if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { struct intel_context *intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate; GLcontext *ctx = &intel->ctx; if (ctx->Visual.doubleBufferMode) { drm_clip_rect_t rect; rect.x1 = x + dPriv->x; rect.y1 = (dPriv->h - y - h) + dPriv->y; rect.x2 = rect.x1 + w; rect.y2 = rect.y1 + h; _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ intelCopyBuffer(dPriv, &rect); } } else { /* XXX this shouldn't be an error but we can't handle it for now */ fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); }}/** * 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 *colorRegions[MAX_DRAW_BUFFERS], *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); /* If the batch contents require looping over cliprects, flush them before * we go changing which cliprects get referenced when that happens. */ if (intel->batch->cliprect_mode == LOOP_CLIPRECTS) intel_batchbuffer_flush(intel->batch); /* * How many color buffers are we drawing into? */ if (fb->_NumColorDrawBuffers == 0) { /* writing to 0 */ FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE); colorRegions[0] = NULL; if (fb->Name != 0) intelSetRenderbufferClipRects(intel); } else if (fb->_NumColorDrawBuffers > 1) { int i; struct intel_renderbuffer *irb; FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE); if (fb->Name != 0) intelSetRenderbufferClipRects(intel); for (i = 0; i < fb->_NumColorDrawBuffers; i++) { irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]); colorRegions[i] = (irb && irb->region) ? irb->region : NULL; } } else { /* draw to exactly one color buffer */ /*_mesa_debug(ctx, "Hardware rendering\n");*/ FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE); if (fb->_ColorDrawBufferIndexes[0] == BUFFER_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 (front) { intelSetFrontClipRects(intel); colorRegions[0] = intel_get_rb_region(fb, BUFFER_FRONT_LEFT); } else { intelSetBackClipRects(intel); colorRegions[0]= 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]); colorRegions[0] = (irb && irb->region) ? irb->region : NULL; } } /* 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; if (!colorRegions[0]) { 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 && 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 */ if (ctx->Driver.Enable != NULL) ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); else ctx->NewState |= _NEW_STENCIL; 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 */ if (ctx->Driver.Enable != NULL) ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); else ctx->NewState |= _NEW_STENCIL; } /* * 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; } intel->vtbl.set_draw_region(intel, colorRegions, depthRegion, fb->_NumColorDrawBuffers); /* 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); intel->NewGLState |= _NEW_SCISSOR; if (ctx->Driver.DepthRange) ctx->Driver.DepthRange(ctx, ctx->Viewport.Near, ctx->Viewport.Far);}static voidintelDrawBuffer(GLcontext * ctx, GLenum mode){ intel_draw_buffer(ctx, ctx->DrawBuffer);}static voidintelReadBuffer(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. */}voidintelInitBufferFuncs(struct dd_function_table *functions){ functions->Clear = intelClear; functions->DrawBuffer = intelDrawBuffer; functions->ReadBuffer = intelReadBuffer;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -