📄 ffb_xmesa.c
字号:
if (mesaVis->depthBits == 16) { driRenderbuffer *depthRb = driNewRenderbuffer(GL_DEPTH_COMPONENT16, NULL, bpp, offset, bogusPitch, driDrawPriv); ffbSetDepthFunctions(depthRb, mesaVis); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); } if (mesaVis->stencilBits > 0 && !swStencil) { driRenderbuffer *stencilRb = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT, NULL, bpp, offset, bogusPitch, driDrawPriv); ffbSetStencilFunctions(stencilRb, mesaVis); _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base); } _mesa_add_soft_renderbuffers(fb, GL_FALSE, /* color */ GL_FALSE, /* depth */ swStencil, mesaVis->accumRedBits > 0, GL_FALSE, /* alpha */ GL_FALSE /* aux */); driDrawPriv->driverPrivate = (void *) fb; return (driDrawPriv->driverPrivate != NULL); }}static voidffbDestroyBuffer(__DRIdrawablePrivate *driDrawPriv){ _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));}#define USE_FAST_SWAPstatic voidffbSwapBuffers( __DRIdrawablePrivate *dPriv ){ ffbContextPtr fmesa = (ffbContextPtr) dPriv->driContextPriv->driverPrivate; unsigned int fbc, wid, wid_reg_val, dac_db_bit; unsigned int shadow_dac_addr, active_dac_addr; ffb_fbcPtr ffb; ffb_dacPtr dac; if (fmesa == NULL || fmesa->glCtx->Visual.doubleBufferMode == 0) return; /* Flush pending rendering commands */ _mesa_notifySwapBuffers(fmesa->glCtx); ffb = fmesa->regs; dac = fmesa->ffbScreen->dac; fbc = fmesa->fbc; wid = fmesa->wid; /* Swap the buffer we render into and read pixels from. */ fmesa->back_buffer ^= 1; /* If we are writing into both buffers, don't mess with * the WB setting. */ if ((fbc & FFB_FBC_WB_AB) != FFB_FBC_WB_AB) { if ((fbc & FFB_FBC_WB_A) != 0) fbc = (fbc & ~FFB_FBC_WB_A) | FFB_FBC_WB_B; else fbc = (fbc & ~FFB_FBC_WB_B) | FFB_FBC_WB_A; } /* But either way, we must flip the read buffer setting. */ if ((fbc & FFB_FBC_RB_A) != 0) fbc = (fbc & ~FFB_FBC_RB_A) | FFB_FBC_RB_B; else fbc = (fbc & ~FFB_FBC_RB_B) | FFB_FBC_RB_A; LOCK_HARDWARE(fmesa); if (fmesa->fbc != fbc) { FFBFifo(fmesa, 1); ffb->fbc = fmesa->fbc = fbc; fmesa->ffbScreen->rp_active = 1; } /* And swap the buffer displayed in the WID. */ if (fmesa->ffb_sarea->flags & FFB_DRI_PAC1) { shadow_dac_addr = FFBDAC_PAC1_SPWLUT(wid); active_dac_addr = FFBDAC_PAC1_APWLUT(wid); dac_db_bit = FFBDAC_PAC1_WLUT_DB; } else { shadow_dac_addr = FFBDAC_PAC2_SPWLUT(wid); active_dac_addr = FFBDAC_PAC2_APWLUT(wid); dac_db_bit = FFBDAC_PAC2_WLUT_DB; } FFBWait(fmesa, ffb); wid_reg_val = DACCFG_READ(dac, active_dac_addr); if (fmesa->back_buffer == 0) wid_reg_val |= dac_db_bit; else wid_reg_val &= ~dac_db_bit;#ifdef USE_FAST_SWAP DACCFG_WRITE(dac, active_dac_addr, wid_reg_val);#else DACCFG_WRITE(dac, shadow_dac_addr, wid_reg_val); /* Schedule the window transfer. */ DACCFG_WRITE(dac, FFBDAC_CFG_WTCTRL, (FFBDAC_CFG_WTCTRL_TCMD | FFBDAC_CFG_WTCTRL_TE)); { int limit = 1000000; while (limit--) { unsigned int wtctrl = DACCFG_READ(dac, FFBDAC_CFG_WTCTRL); if ((wtctrl & FFBDAC_CFG_WTCTRL_DS) == 0) break; } }#endif UNLOCK_HARDWARE(fmesa);}static void ffb_init_wid(ffbContextPtr fmesa, unsigned int wid){ ffb_dacPtr dac = fmesa->ffbScreen->dac; unsigned int wid_reg_val, dac_db_bit, active_dac_addr; unsigned int shadow_dac_addr; if (fmesa->ffb_sarea->flags & FFB_DRI_PAC1) { shadow_dac_addr = FFBDAC_PAC1_SPWLUT(wid); active_dac_addr = FFBDAC_PAC1_APWLUT(wid); dac_db_bit = FFBDAC_PAC1_WLUT_DB; } else { shadow_dac_addr = FFBDAC_PAC2_SPWLUT(wid); active_dac_addr = FFBDAC_PAC2_APWLUT(wid); dac_db_bit = FFBDAC_PAC2_WLUT_DB; } wid_reg_val = DACCFG_READ(dac, active_dac_addr); wid_reg_val &= ~dac_db_bit;#ifdef USE_FAST_SWAP DACCFG_WRITE(dac, active_dac_addr, wid_reg_val);#else DACCFG_WRITE(dac, shadow_dac_addr, wid_reg_val); /* Schedule the window transfer. */ DACCFG_WRITE(dac, FFBDAC_CFG_WTCTRL, (FFBDAC_CFG_WTCTRL_TCMD | FFBDAC_CFG_WTCTRL_TE)); { int limit = 1000000; while (limit--) { unsigned int wtctrl = DACCFG_READ(dac, FFBDAC_CFG_WTCTRL); if ((wtctrl & FFBDAC_CFG_WTCTRL_DS) == 0) break; } }#endif}/* Force the context `c' to be the current context and associate with it buffer `b' */static GLbooleanffbMakeCurrent(__DRIcontextPrivate *driContextPriv, __DRIdrawablePrivate *driDrawPriv, __DRIdrawablePrivate *driReadPriv){ if (driContextPriv) { ffbContextPtr fmesa = (ffbContextPtr) driContextPriv->driverPrivate; int first_time; fmesa->driDrawable = driDrawPriv; _mesa_make_current(fmesa->glCtx, (GLframebuffer *) driDrawPriv->driverPrivate, (GLframebuffer *) driReadPriv->driverPrivate); first_time = 0; if (fmesa->wid == ~0) { first_time = 1; if (getenv("LIBGL_SOFTWARE_RENDERING")) FALLBACK( fmesa->glCtx, FFB_BADATTR_SWONLY, GL_TRUE ); } LOCK_HARDWARE(fmesa); if (first_time) { fmesa->wid = fmesa->ffb_sarea->wid_table[driDrawPriv->index]; ffb_init_wid(fmesa, fmesa->wid); } fmesa->state_dirty |= FFB_STATE_ALL; fmesa->state_fifo_ents = fmesa->state_all_fifo_ents; ffbSyncHardware(fmesa); UNLOCK_HARDWARE(fmesa); if (first_time) { /* Also, at the first switch to a new context, * we need to clear all the hw buffers. */ ffbDDClear(fmesa->glCtx, (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT | BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); } } else { _mesa_make_current(NULL, NULL, NULL); } return GL_TRUE;}/* Force the context `c' to be unbound from its buffer */static GLbooleanffbUnbindContext(__DRIcontextPrivate *driContextPriv){ return GL_TRUE;}void ffbXMesaUpdateState(ffbContextPtr fmesa){ __DRIdrawablePrivate *dPriv = fmesa->driDrawable; __DRIscreenPrivate *sPriv = fmesa->driScreen; int stamp = dPriv->lastStamp; DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); if (dPriv->lastStamp != stamp) { GLcontext *ctx = fmesa->glCtx; ffbCalcViewport(ctx); driUpdateFramebufferSize(ctx, dPriv); if (ctx->Polygon.StippleFlag) { ffbXformAreaPattern(fmesa, (const GLubyte *)ctx->PolygonStipple); } }}static const __DRIconfig **ffbFillInModes( __DRIscreenPrivate *psp, unsigned pixel_bits, unsigned depth_bits, unsigned stencil_bits, GLboolean have_back_buffer ){ __DRIconfig **configs; __GLcontextModes *m; unsigned depth_buffer_factor; unsigned back_buffer_factor; GLenum fb_format; GLenum fb_type; int i; /* GLX_SWAP_COPY_OML is only supported because the FFB driver doesn't * support pageflipping at all. */ static const GLenum back_buffer_modes[] = { GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML }; u_int8_t depth_bits_array[3]; u_int8_t stencil_bits_array[3]; depth_bits_array[0] = 0; depth_bits_array[1] = depth_bits; depth_bits_array[2] = depth_bits; /* Just like with the accumulation buffer, always provide some modes * with a stencil buffer. It will be a sw fallback, but some apps won't * care about that. */ stencil_bits_array[0] = 0; stencil_bits_array[1] = 0; stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; back_buffer_factor = (have_back_buffer) ? 3 : 1; if ( pixel_bits == 16 ) { fb_format = GL_RGB; fb_type = GL_UNSIGNED_SHORT_5_6_5; } else { fb_format = GL_BGRA; fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; } configs = driCreateConfigs(fb_format, fb_type, depth_bits_array, stencil_bits_array, depth_buffer_factor, back_buffer_modes, back_buffer_factor); if (configs == NULL) { fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); return NULL; } /* Mark the visual as slow if there are "fake" stencil bits. */ for (i = 0; configs[i]; i++) { m = &configs[i]->modes; if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { m->visualRating = GLX_SLOW_CONFIG; } } return (const __DRIconfig **) configs;}/** * This is the driver specific part of the createNewScreen entry point. * * \todo maybe fold this into intelInitDriver * * \return the __GLcontextModes supported by this driver */static const __DRIconfig **ffbInitScreen(__DRIscreen *psp){ static const __DRIversion ddx_expected = { 0, 1, 1 }; static const __DRIversion dri_expected = { 4, 0, 0 }; static const __DRIversion drm_expected = { 0, 0, 1 }; if ( ! driCheckDriDdxDrmVersions2( "ffb", &psp->dri_version, & dri_expected, &psp->ddx_version, & ddx_expected, &psp->drm_version, & drm_expected ) ) return NULL; if (!ffbInitDriver(psp)) return NULL; return ffbFillInModes( psp, 32, 16, 0, GL_TRUE );}const struct __DriverAPIRec driDriverAPI = { .InitScreen = ffbInitScreen, .DestroyScreen = ffbDestroyScreen, .CreateContext = ffbCreateContext, .DestroyContext = ffbDestroyContext, .CreateBuffer = ffbCreateBuffer, .DestroyBuffer = ffbDestroyBuffer, .SwapBuffers = ffbSwapBuffers, .MakeCurrent = ffbMakeCurrent, .UnbindContext = ffbUnbindContext, .GetSwapInfo = NULL, .GetDrawableMSC = NULL, .WaitForMSC = NULL, .WaitForSBC = NULL, .SwapBuffersMSC = NULL};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -