📄 intel_buffers.c
字号:
intel_fb->vbl_waited = dPriv->vblSeq; for (i = 0; i < intel_fb->pf_num_pages; i++) { if (intel_fb->color_rb[i]) intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_waited; } } } else { dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY; } /* Update Mesa's notion of window size */ driUpdateFramebufferSize(ctx, dPriv); intel_fb->Base.Initialized = GL_TRUE; /* XXX remove someday */ /* Update hardware scissor */ if (ctx->Driver.Scissor != NULL) { ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, ctx->Scissor.Width, ctx->Scissor.Height); } /* Re-calculate viewport related state */ if (ctx->Driver.DepthRange != NULL) ctx->Driver.DepthRange( ctx, ctx->Viewport.Near, ctx->Viewport.Far );}/* A true meta version of this would be very simple and additionally * machine independent. Maybe we'll get there one day. */static voidintelClearWithTris(struct intel_context *intel, GLbitfield mask){ GLcontext *ctx = &intel->ctx; struct gl_framebuffer *fb = ctx->DrawBuffer; GLuint buf; intel->vtbl.install_meta_state(intel); /* Back and stencil cliprects are the same. Try and do both * buffers at once: */ if (mask & (BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH)) { struct intel_region *backRegion = intel_get_rb_region(fb, BUFFER_BACK_LEFT); struct intel_region *depthRegion = intel_get_rb_region(fb, BUFFER_DEPTH); intel->vtbl.meta_draw_region(intel, backRegion, depthRegion); if (mask & BUFFER_BIT_BACK_LEFT) intel->vtbl.meta_color_mask(intel, GL_TRUE); else intel->vtbl.meta_color_mask(intel, GL_FALSE); if (mask & BUFFER_BIT_STENCIL) intel->vtbl.meta_stencil_replace(intel, intel->ctx.Stencil.WriteMask[0], intel->ctx.Stencil.Clear); else intel->vtbl.meta_no_stencil_write(intel); if (mask & BUFFER_BIT_DEPTH) intel->vtbl.meta_depth_replace(intel); else intel->vtbl.meta_no_depth_write(intel); intel->vtbl.meta_draw_quad(intel, fb->_Xmin, fb->_Xmax, fb->_Ymin, fb->_Ymax, intel->ctx.Depth.Clear, intel->ClearColor8888, 0, 0, 0, 0); /* texcoords */ mask &= ~(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH); } /* clear the remaining (color) renderbuffers */ for (buf = 0; buf < BUFFER_COUNT && mask; buf++) { const GLuint bufBit = 1 << buf; if (mask & bufBit) { struct intel_renderbuffer *irbColor = intel_renderbuffer(fb->Attachment[buf].Renderbuffer); ASSERT(irbColor); 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, irbColor->region, NULL); intel->vtbl.meta_draw_quad(intel, fb->_Xmin, fb->_Xmax, fb->_Ymin, fb->_Ymax, 0, intel->ClearColor8888, 0, 0, 0, 0); /* texcoords */ mask &= ~bufBit; } } intel->vtbl.leave_meta_state(intel);}static const char *buffer_names[] = { [BUFFER_FRONT_LEFT] = "front", [BUFFER_BACK_LEFT] = "back", [BUFFER_FRONT_RIGHT] = "front right", [BUFFER_BACK_RIGHT] = "back right", [BUFFER_AUX0] = "aux0", [BUFFER_AUX1] = "aux1", [BUFFER_AUX2] = "aux2", [BUFFER_AUX3] = "aux3", [BUFFER_DEPTH] = "depth", [BUFFER_STENCIL] = "stencil", [BUFFER_ACCUM] = "accum", [BUFFER_COLOR0] = "color0", [BUFFER_COLOR1] = "color1", [BUFFER_COLOR2] = "color2", [BUFFER_COLOR3] = "color3", [BUFFER_COLOR4] = "color4", [BUFFER_COLOR5] = "color5", [BUFFER_COLOR6] = "color6", [BUFFER_COLOR7] = "color7",};/** * Called by ctx->Driver.Clear. */static voidintelClear(GLcontext *ctx, GLbitfield mask){ 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; struct gl_framebuffer *fb = ctx->DrawBuffer; 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(fb, BUFFER_STENCIL); if (stencilRegion) { /* have hw stencil */ if (IS_965(intel->intelScreen->deviceID) || (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) { /* We have to use the 3D engine if we're clearing a partial mask * of the stencil buffer, or if we're on a 965 which has a tiled * depth/stencil buffer in a layout we can't blit to. */ 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 (IS_965(intel->intelScreen->deviceID) || 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 (!fb->Attachment[i].Renderbuffer->ClassID) { blit_mask &= ~bufBit; tri_mask &= ~bufBit; swrast_mask |= bufBit; } } } if (blit_mask) { if (INTEL_DEBUG & DEBUG_BLIT) { DBG("blit clear:"); for (i = 0; i < BUFFER_COUNT; i++) { if (blit_mask & (1 << i)) DBG(" %s", buffer_names[i]); } DBG("\n"); } intelClearWithBlit(ctx, blit_mask); } if (tri_mask) { if (INTEL_DEBUG & DEBUG_BLIT) { DBG("tri clear:"); for (i = 0; i < BUFFER_COUNT; i++) { if (tri_mask & (1 << i)) DBG(" %s", buffer_names[i]); } DBG("\n"); } intelClearWithTris(intel, tri_mask); } if (swrast_mask) { if (INTEL_DEBUG & DEBUG_BLIT) { DBG("swrast clear:"); for (i = 0; i < BUFFER_COUNT; i++) { if (swrast_mask & (1 << i)) DBG(" %s", buffer_names[i]); } DBG("\n"); } _swrast_Clear(ctx, swrast_mask); }}/* Emit wait for pending flips */voidintel_wait_flips(struct intel_context *intel){ struct intel_framebuffer *intel_fb = (struct intel_framebuffer *) intel->ctx.DrawBuffer; struct intel_renderbuffer *intel_rb = intel_get_renderbuffer(&intel_fb->Base, intel_fb->Base._ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT ? BUFFER_FRONT_LEFT : BUFFER_BACK_LEFT); if (intel_fb->Base.Name == 0 && intel_rb && intel_rb->pf_pending == intel_fb->pf_seq) { GLint pf_planes = intel_fb->pf_planes; BATCH_LOCALS; /* Wait for pending flips to take effect */ BEGIN_BATCH(2, NO_LOOP_CLIPRECTS); OUT_BATCH(pf_planes & 0x1 ? (MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP) : 0); OUT_BATCH(pf_planes & 0x2 ? (MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_B_FLIP) : 0); ADVANCE_BATCH(); intel_rb->pf_pending--; }}/* Flip the front & back buffers */static GLbooleanintelPageFlip(const __DRIdrawablePrivate * dPriv){ struct intel_context *intel; int ret; struct intel_framebuffer *intel_fb = dPriv->driverPrivate; 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; if (intel->intelScreen->drmMinor < 9) return GL_FALSE; intelFlush(&intel->ctx); ret = 0; LOCK_HARDWARE(intel); if (dPriv->numClipRects && intel_fb->pf_active) { drm_i915_flip_t flip; flip.pipes = intel_fb->pf_planes; ret = drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip)); } UNLOCK_HARDWARE(intel); if (ret || !intel_fb->pf_active) return GL_FALSE; if (!dPriv->numClipRects) { usleep(10000); /* throttle invisible client 10ms */ } intel_fb->pf_current_page = (intel->sarea->pf_current_page >> (intel_fb->pf_planes & 0x2)) & 0x3; if (dPriv->numClipRects != 0) { intel_get_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT)->pf_pending = intel_get_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT)->pf_pending = ++intel_fb->pf_seq; } intel_flip_renderbuffers(intel_fb); intel_draw_buffer(&intel->ctx, &intel_fb->Base); return GL_TRUE;}static GLbooleanintelScheduleSwap(__DRIdrawablePrivate * dPriv, GLboolean *missed_target){ struct intel_framebuffer *intel_fb = dPriv->driverPrivate; unsigned int interval; struct intel_context *intel = intelScreenContext(dPriv->driScreenPriv->private); const intelScreenPrivate *intelScreen = intel->intelScreen; unsigned int target; drm_i915_vblank_swap_t swap; GLboolean ret; if (!dPriv->vblFlags || (dPriv->vblFlags & VBLANK_FLAG_NO_IRQ) || intelScreen->drmMinor < (intel_fb->pf_active ? 9 : 6)) return GL_FALSE; interval = driGetVBlankInterval(dPriv); swap.seqtype = DRM_VBLANK_ABSOLUTE; if (dPriv->vblFlags & VBLANK_FLAG_SYNC) { swap.seqtype |= DRM_VBLANK_NEXTONMISS; } else if (interval == 0) return GL_FALSE; swap.drawable = dPriv->hHWDrawable; target = swap.sequence = dPriv->vblSeq + interval; if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) { swap.seqtype |= DRM_VBLANK_SECONDARY; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -