/** * This function takes both a read buffer and a draw buffer. This is needed * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent * function. */ static int driBindContext(__DRIcontext *pcp, __DRIdrawable *pdp, __DRIdrawable *prp) { __DRIscreenPrivate *psp; /* ** Assume error checking is done properly in glXMakeCurrent before ** calling driBindContext. */ if (pcp == NULL || pdp == None || prp == None) return GL_FALSE; /* Bind the drawable to the context */ pcp->driDrawablePriv = pdp; pcp->driReadablePriv = prp; pdp->driContextPriv = pcp; pdp->refcount++; if ( pdp != prp ) { prp->refcount++; } /* ** Now that we have a context associated with this drawable, we can ** initialize the drawable information if has not been done before. */ psp = pcp->driScreenPriv; if (psp->dri2.enabled) { __driParseEvents(pcp, pdp); __driParseEvents(pcp, prp); } else { if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) { DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); __driUtilUpdateDrawableInfo(pdp); DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); } if ((pdp != prp) && (!prp->pStamp || *prp->pStamp != prp->lastStamp)) { DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); __driUtilUpdateDrawableInfo(prp); DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); } } /* Call device-specific MakeCurrent */ (*psp->DriverAPI.MakeCurrent)(pcp, pdp, prp); return GL_TRUE; }
paddr_t drmmmap(dev_t kdev, off_t offset, int prot) { struct drm_device *dev = drm_get_device_from_kdev(kdev); drm_local_map_t *map; struct drm_file *priv; drm_map_type_t type; paddr_t phys; DRM_LOCK(); priv = drm_find_file_by_minor(dev, minor(kdev)); DRM_UNLOCK(); if (priv == NULL) { DRM_ERROR("can't find authenticator\n"); return (EINVAL); } if (!priv->authenticated) return (EACCES); if (dev->dma && offset >= 0 && offset < ptoa(dev->dma->page_count)) { drm_device_dma_t *dma = dev->dma; DRM_SPINLOCK(&dev->dma_lock); if (dma->pagelist != NULL) { unsigned long page = offset >> PAGE_SHIFT; unsigned long phys = dma->pagelist[page]; DRM_SPINUNLOCK(&dev->dma_lock); return (atop(phys)); } else {
int drm_mmap(struct dev_mmap_args *ap) { struct cdev *kdev = ap->a_head.a_dev; vm_offset_t offset = ap->a_offset; struct drm_device *dev = drm_get_device_from_kdev(kdev); struct drm_file *file_priv = NULL; drm_local_map_t *map; enum drm_map_type type; vm_paddr_t phys; DRM_LOCK(); file_priv = drm_find_file_by_proc(dev, DRM_CURPROC); DRM_UNLOCK(); if (file_priv == NULL) { DRM_ERROR("can't find authenticator\n"); return EINVAL; } if (!file_priv->authenticated) return EACCES; if (dev->dma && offset < ptoa(dev->dma->page_count)) { drm_device_dma_t *dma = dev->dma; DRM_SPINLOCK(&dev->dma_lock); if (dma->pagelist != NULL) { unsigned long page = offset >> PAGE_SHIFT; unsigned long phys = dma->pagelist[page]; ap->a_result = atop(phys); DRM_SPINUNLOCK(&dev->dma_lock); return 0; } else {
int drm_adddraw(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_draw_t *draw = data; struct bsd_drm_drawable_info *info; info = drm_calloc(1, sizeof(struct bsd_drm_drawable_info), DRM_MEM_DRAWABLE); if (info == NULL) return ENOMEM; #ifdef __FreeBSD__ info->handle = alloc_unr(dev->drw_unrhdr); #else /* XXXJDM */ info->handle = ++dev->drw_no; #endif DRM_SPINLOCK(&dev->drw_lock); RB_INSERT(drawable_tree, &dev->drw_head, info); draw->handle = info->handle; DRM_SPINUNLOCK(&dev->drw_lock); DRM_DEBUG("%d\n", draw->handle); return 0; }
/** * This function takes both a read buffer and a draw buffer. This is needed * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent * function. */ static int driBindContext(__DRIcontext *pcp, __DRIdrawable *pdp, __DRIdrawable *prp) { __DRIscreen *psp = NULL; /* ** Assume error checking is done properly in glXMakeCurrent before ** calling driUnbindContext. */ if (!pcp) return GL_FALSE; /* Bind the drawable to the context */ psp = pcp->driScreenPriv; pcp->driDrawablePriv = pdp; pcp->driReadablePriv = prp; if (pdp) { pdp->driContextPriv = pcp; dri_get_drawable(pdp); } if (prp && pdp != prp) { dri_get_drawable(prp); } /* ** Now that we have a context associated with this drawable, we can ** initialize the drawable information if has not been done before. */ if (!psp->dri2.enabled) { if (pdp && !pdp->pStamp) { DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); __driUtilUpdateDrawableInfo(pdp); DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); } if (prp && pdp != prp && !prp->pStamp) { DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); __driUtilUpdateDrawableInfo(prp); DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); } } /* Call device-specific MakeCurrent */ return (*psp->DriverAPI.MakeCurrent)(pcp, pdp, prp); }
void drm_drawable_free_all(struct drm_device *dev) { struct bsd_drm_drawable_info *info, *next; DRM_SPINLOCK(&dev->drw_lock); for (info = RB_MIN(drawable_tree, &dev->drw_head); info != NULL ; info = next) { next = RB_NEXT(drawable_tree, &dev->drw_head, info); RB_REMOVE(drawable_tree, &dev->drw_head, (struct bsd_drm_drawable_info *)info); DRM_SPINUNLOCK(&dev->drw_lock); free_unr(dev->drw_unrhdr, info->handle); free(info->info.rects, DRM_MEM_DRAWABLE); free(info, DRM_MEM_DRAWABLE); DRM_SPINLOCK(&dev->drw_lock); } DRM_SPINUNLOCK(&dev->drw_lock); }
int drm_update_draw(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_drawable_info *info; struct drm_update_draw *update = (struct drm_update_draw *)data; int ret; info = drm_get_drawable_info(dev, update->handle); if (info == NULL) return EINVAL; switch (update->type) { case DRM_DRAWABLE_CLIPRECTS: DRM_SPINLOCK(&dev->drw_lock); if (update->num != info->num_rects) { drm_free(info->rects, sizeof(*info->rects) * info->num_rects, DRM_MEM_DRAWABLE); info->rects = NULL; info->num_rects = 0; } if (update->num == 0) { DRM_SPINUNLOCK(&dev->drw_lock); return 0; } if (info->rects == NULL) { info->rects = drm_alloc(sizeof(*info->rects) * update->num, DRM_MEM_DRAWABLE); if (info->rects == NULL) { DRM_SPINUNLOCK(&dev->drw_lock); return ENOMEM; } info->num_rects = update->num; } /* For some reason the pointer arg is unsigned long long. */ ret = copyin((void *)(intptr_t)update->data, info->rects, sizeof(*info->rects) * info->num_rects); DRM_SPINUNLOCK(&dev->drw_lock); return ret; default: return EINVAL; } }
int drm_rmdraw(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_draw *draw = (struct drm_draw *)data; struct drm_drawable_info *info; DRM_SPINLOCK(&dev->drw_lock); info = drm_get_drawable_info(dev, draw->handle); if (info != NULL) { RB_REMOVE(drawable_tree, &dev->drw_head, (struct bsd_drm_drawable_info *)info); DRM_SPINUNLOCK(&dev->drw_lock); free_unr(dev->drw_unrhdr, draw->handle); free(info->rects, DRM_MEM_DRAWABLE); free(info, DRM_MEM_DRAWABLE); return 0; } else { DRM_SPINUNLOCK(&dev->drw_lock); return EINVAL; } }
int drm_rmdraw(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_draw_t *draw = (drm_draw_t *)data; struct drm_drawable_info *info; DRM_SPINLOCK(&dev->drw_lock); info = drm_get_drawable_info(dev, draw->handle); if (info != NULL) { RB_REMOVE(drawable_tree, &dev->drw_head, (struct bsd_drm_drawable_info *)info); DRM_SPINUNLOCK(&dev->drw_lock); #ifdef __FreeBSD__ free_unr(dev->drw_unrhdr, draw->handle); #endif drm_free(info, sizeof(struct bsd_drm_drawable_info), DRM_MEM_DRAWABLE); return 0; } else { DRM_SPINUNLOCK(&dev->drw_lock); return EINVAL; } }
/** * Update private drawable information. * * \param pdp pointer to the private drawable information to update. * * This function basically updates the __DRIdrawablePrivate struct's * cliprect information by calling \c __DRIinterfaceMethods::getDrawableInfo. * This is usually called by the DRI_VALIDATE_DRAWABLE_INFO macro which * compares the __DRIdrwablePrivate pStamp and lastStamp values. If * the values are different that means we have to update the clipping * info. */ void __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) { __DRIscreenPrivate *psp = pdp->driScreenPriv; __DRIcontextPrivate *pcp = pdp->driContextPriv; if (!pcp || ((pdp != pcp->driDrawablePriv) && (pdp != pcp->driReadablePriv))) { /* ERROR!!! * ...but we must ignore it. There can be many contexts bound to a * drawable. */ } if (pdp->pClipRects) { _mesa_free(pdp->pClipRects); pdp->pClipRects = NULL; } if (pdp->pBackClipRects) { _mesa_free(pdp->pBackClipRects); pdp->pBackClipRects = NULL; } DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); if (! (*psp->getDrawableInfo->getDrawableInfo)(pdp, &pdp->index, &pdp->lastStamp, &pdp->x, &pdp->y, &pdp->w, &pdp->h, &pdp->numClipRects, &pdp->pClipRects, &pdp->backX, &pdp->backY, &pdp->numBackClipRects, &pdp->pBackClipRects, pdp->loaderPrivate)) { /* Error -- eg the window may have been destroyed. Keep going * with no cliprects. */ pdp->pStamp = &pdp->lastStamp; /* prevent endless loop */ pdp->numClipRects = 0; pdp->pClipRects = NULL; pdp->numBackClipRects = 0; pdp->pBackClipRects = NULL; } else pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp); DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); }
int drm_adddraw(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_draw *draw = data; struct bsd_drm_drawable_info *info; info = malloc(sizeof(struct bsd_drm_drawable_info), DRM_MEM_DRAWABLE, M_NOWAIT | M_ZERO); if (info == NULL) return ENOMEM; info->handle = alloc_unr(dev->drw_unrhdr); DRM_SPINLOCK(&dev->drw_lock); RB_INSERT(drawable_tree, &dev->drw_head, info); draw->handle = info->handle; DRM_SPINUNLOCK(&dev->drw_lock); DRM_DEBUG("%d\n", draw->handle); return 0; }
static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) { struct drm_mm_node *child; if (atomic) child = malloc(sizeof(*child), DRM_MEM_MM, M_NOWAIT); else child = malloc(sizeof(*child), DRM_MEM_MM, M_WAITOK); if (unlikely(child == NULL)) { DRM_SPINLOCK(&mm->unused_lock); if (list_empty(&mm->unused_nodes)) child = NULL; else { child = list_entry(mm->unused_nodes.next, struct drm_mm_node, fl_entry); list_del(&child->fl_entry); --mm->num_unused; } DRM_SPINUNLOCK(&mm->unused_lock); }
int drm_mmap(struct cdev *kdev, vm_ooffset_t offset, vm_paddr_t *paddr, int prot, vm_memattr_t *memattr) { struct drm_device *dev = drm_get_device_from_kdev(kdev); struct drm_file *file_priv = NULL; drm_local_map_t *map; enum drm_map_type type; vm_paddr_t phys; int error; /* d_mmap gets called twice, we can only reference file_priv during * the first call. We need to assume that if error is EBADF the * call was succesful and the client is authenticated. */ error = devfs_get_cdevpriv((void **)&file_priv); if (error == ENOENT) { DRM_ERROR("Could not find authenticator!\n"); return EINVAL; } if (file_priv && !file_priv->authenticated) return EACCES; DRM_DEBUG("called with offset %016jx\n", offset); if (dev->dma && offset < ptoa(dev->dma->page_count)) { drm_device_dma_t *dma = dev->dma; DRM_SPINLOCK(&dev->dma_lock); if (dma->pagelist != NULL) { unsigned long page = offset >> PAGE_SHIFT; unsigned long phys = dma->pagelist[page]; DRM_SPINUNLOCK(&dev->dma_lock); *paddr = phys; return 0; } else {
static void gammaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch ) { gammaContextPtr gmesa = GAMMA_CONTEXT(ctx); GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)gmesa->driScreen->pDevPriv; GLuint temp = 0; FLUSH_BATCH( gmesa ); /* Update and emit any new state. We need to do this here to catch * changes to the masks. * FIXME: Just update the masks? */ if ( gmesa->new_state ) gammaDDUpdateHWState( ctx ); #ifdef DO_VALIDATE /* Flush any partially filled buffers */ FLUSH_DMA_BUFFER(gmesa); DRM_SPINLOCK(&gmesa->driScreen->pSAREA->drawable_lock, gmesa->driScreen->drawLockID); VALIDATE_DRAWABLE_INFO_NO_LOCK(gmesa); #endif if (mask & BUFFER_BIT_DEPTH) { /* Turn off writes the FB */ CHECK_DMA_BUFFER(gmesa, 1); WRITE(gmesa->buf, FBWriteMode, FBWriteModeDisable); mask &= ~BUFFER_BIT_DEPTH; /* * Turn Rectangle2DControl off when the window is not clipped * (i.e., the GID tests are not necessary). This dramatically * increases the performance of the depth clears. */ if (!gmesa->NotClipped) { CHECK_DMA_BUFFER(gmesa, 1); WRITE(gmesa->buf, Rectangle2DControl, 1); } temp = (gmesa->LBReadMode & LBPartialProdMask) | LBWindowOriginBot; if (gDRIPriv->numMultiDevices == 2) temp |= LBScanLineInt2; CHECK_DMA_BUFFER(gmesa, 5); WRITE(gmesa->buf, LBReadMode, temp); WRITE(gmesa->buf, DeltaMode, DM_DepthEnable); WRITE(gmesa->buf, DepthMode, (DepthModeEnable | DM_Always | DM_SourceDepthRegister | DM_WriteMask)); WRITE(gmesa->buf, GLINTDepth, gmesa->ClearDepth); /* Increment the frame count */ gmesa->FrameCount++; #ifdef FAST_CLEAR_4 gmesa->FrameCount &= 0x0f; #else gmesa->FrameCount &= 0xff; #endif /* Force FCP to be written */ WRITE(gmesa->buf, GLINTWindow, (WindowEnable | W_PassIfEqual | (gmesa->Window & W_GIDMask) | W_DepthFCP | W_LBUpdateFromRegisters | W_OverrideWriteFiltering | (gmesa->FrameCount << 9))); /* Clear part of the depth and FCP buffers */ { int y = gmesa->driScreen->fbHeight - gmesa->driDrawable->y - gmesa->driDrawable->h; int x = gmesa->driDrawable->x; int w = gmesa->driDrawable->w; int h = gmesa->driDrawable->h; #ifndef TURN_OFF_FCP float hsub = h; if (gmesa->WindowChanged) { gmesa->WindowChanged = GL_FALSE; } else { #ifdef FAST_CLEAR_4 hsub /= 16; #else hsub /= 256; #endif /* Handle the case where the height < # of FCPs */ if (hsub < 1.0) { if (gmesa->FrameCount > h) gmesa->FrameCount = 0; h = 1; y += gmesa->FrameCount; } else { h = (gmesa->FrameCount+1)*hsub; h -= (int)(gmesa->FrameCount*hsub); y += gmesa->FrameCount*hsub; } } #endif if (h && w) { #if 0 CHECK_DMA_BUFFER(gmesa, 2); WRITE(gmesa->buf, Rectangle2DMode, ((h & 0xfff)<<12) | (w & 0xfff) ); WRITE(gmesa->buf, DrawRectangle2D, ((y & 0xffff)<<16) | (x & 0xffff) ); #else CHECK_DMA_BUFFER(gmesa, 8); WRITE(gmesa->buf, StartXDom, x<<16); WRITE(gmesa->buf, StartY, y<<16); WRITE(gmesa->buf, StartXSub, (x+w)<<16); WRITE(gmesa->buf, GLINTCount, h); WRITE(gmesa->buf, dY, 1<<16); WRITE(gmesa->buf, dXDom, 0<<16); WRITE(gmesa->buf, dXSub, 0<<16); WRITE(gmesa->buf, Render, 0x00000040); /* NOT_DONE */ #endif } } CHECK_DMA_BUFFER(gmesa, 6); WRITE(gmesa->buf, DepthMode, gmesa->DepthMode); WRITE(gmesa->buf, DeltaMode, gmesa->DeltaMode); WRITE(gmesa->buf, LBReadMode, gmesa->LBReadMode); WRITE(gmesa->buf, GLINTWindow, gmesa->Window); WRITE(gmesa->buf, FastClearDepth, gmesa->ClearDepth); WRITE(gmesa->buf, FBWriteMode, FBWriteModeEnable); /* Turn on Depth FCP */ if (gmesa->Window & W_DepthFCP) { CHECK_DMA_BUFFER(gmesa, 1); WRITE(gmesa->buf, WindowOr, (gmesa->FrameCount << 9)); } /* Turn off GID clipping if window is not clipped */ if (gmesa->NotClipped) { CHECK_DMA_BUFFER(gmesa, 1); WRITE(gmesa->buf, Rectangle2DControl, 0); } } if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)) { int y = gmesa->driScreen->fbHeight - gmesa->driDrawable->y - gmesa->driDrawable->h; int x = gmesa->driDrawable->x; int w = gmesa->driDrawable->w; int h = gmesa->driDrawable->h; mask &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT); if (x < 0) { w -= -x; x = 0; } /* Turn on GID clipping if window is clipped */ if (!gmesa->NotClipped) { CHECK_DMA_BUFFER(gmesa, 1); WRITE(gmesa->buf, Rectangle2DControl, 1); } CHECK_DMA_BUFFER(gmesa, 18); WRITE(gmesa->buf, FBBlockColor, gmesa->ClearColor); WRITE(gmesa->buf, ColorDDAMode, ColorDDADisable); WRITE(gmesa->buf, FBWriteMode, FBWriteModeEnable); WRITE(gmesa->buf, DepthMode, 0); WRITE(gmesa->buf, DeltaMode, 0); WRITE(gmesa->buf, AlphaBlendMode, 0); #if 1 WRITE(gmesa->buf, dY, 1<<16); WRITE(gmesa->buf, dXDom, 0<<16); WRITE(gmesa->buf, dXSub, 0<<16); WRITE(gmesa->buf, StartXSub, (x+w)<<16); WRITE(gmesa->buf, GLINTCount, h); WRITE(gmesa->buf, StartXDom, x<<16); WRITE(gmesa->buf, StartY, y<<16); WRITE(gmesa->buf, Render, 0x00000048); /* NOT_DONE */ #else WRITE(gmesa->buf, Rectangle2DMode, (((h & 0xfff)<<12) | (w & 0xfff))); WRITE(gmesa->buf, DrawRectangle2D, (((y & 0xffff)<<16) | (x & 0xffff))); #endif WRITE(gmesa->buf, DepthMode, gmesa->DepthMode); WRITE(gmesa->buf, DeltaMode, gmesa->DeltaMode); WRITE(gmesa->buf, AlphaBlendMode, gmesa->AlphaBlendMode); WRITE(gmesa->buf, ColorDDAMode, gmesa->ColorDDAMode); /* Turn off GID clipping if window is clipped */ if (gmesa->NotClipped) { CHECK_DMA_BUFFER(gmesa, 1); WRITE(gmesa->buf, Rectangle2DControl, 0); } } #ifdef DO_VALIDATE PROCESS_DMA_BUFFER_TOP_HALF(gmesa); DRM_SPINUNLOCK(&gmesa->driScreen->pSAREA->drawable_lock, gmesa->driScreen->drawLockID); VALIDATE_DRAWABLE_INFO_NO_LOCK_POST(gmesa); PROCESS_DMA_BUFFER_BOTTOM_HALF(gmesa); #endif if ( mask ) _swrast_Clear( ctx, mask, all, cx, cy, cw, ch ); }
/* * Load the current context's state into the hardware. * * NOTE: Be VERY careful about ensuring the context state is marked for * upload, the only place it shouldn't be uploaded is when the setup * state has changed in ReducedPrimitiveChange as this comes right after * a state update. * * Blits of any type should always upload the context and masks after * they are done. */ void gammaEmitHwState( gammaContextPtr gmesa ) { if (!gmesa->driDrawable) return; if (!gmesa->dirty) return; #ifdef DO_VALIDATE /* Flush any partially filled buffers */ FLUSH_DMA_BUFFER(gmesa); DRM_SPINLOCK(&gmesa->driScreen->pSAREA->drawable_lock, gmesa->driScreen->drawLockID); VALIDATE_DRAWABLE_INFO_NO_LOCK(gmesa); #endif if (gmesa->dirty & GAMMA_UPLOAD_VIEWPORT) { gmesa->dirty &= ~GAMMA_UPLOAD_VIEWPORT; CHECK_DMA_BUFFER(gmesa, 6); WRITEF(gmesa->buf, ViewPortOffsetX, gmesa->ViewportOffsetX); WRITEF(gmesa->buf, ViewPortOffsetY, gmesa->ViewportOffsetY); WRITEF(gmesa->buf, ViewPortOffsetZ, gmesa->ViewportOffsetZ); WRITEF(gmesa->buf, ViewPortScaleX, gmesa->ViewportScaleX); WRITEF(gmesa->buf, ViewPortScaleY, gmesa->ViewportScaleY); WRITEF(gmesa->buf, ViewPortScaleZ, gmesa->ViewportScaleZ); } if ( (gmesa->dirty & GAMMA_UPLOAD_POINTMODE) || (gmesa->dirty & GAMMA_UPLOAD_LINEMODE) || (gmesa->dirty & GAMMA_UPLOAD_TRIMODE) ) { CHECK_DMA_BUFFER(gmesa, 1); WRITE(gmesa->buf, AntialiasMode, gmesa->AntialiasMode); } if (gmesa->dirty & GAMMA_UPLOAD_POINTMODE) { gmesa->dirty &= ~GAMMA_UPLOAD_POINTMODE; CHECK_DMA_BUFFER(gmesa, 1); WRITE(gmesa->buf, PointMode, gmesa->PointMode); } if (gmesa->dirty & GAMMA_UPLOAD_LINEMODE) { gmesa->dirty &= ~GAMMA_UPLOAD_LINEMODE; CHECK_DMA_BUFFER(gmesa, 2); WRITE(gmesa->buf, LineMode, gmesa->LineMode); WRITE(gmesa->buf, LineStippleMode, gmesa->LineMode); } if (gmesa->dirty & GAMMA_UPLOAD_TRIMODE) { gmesa->dirty &= ~GAMMA_UPLOAD_TRIMODE; CHECK_DMA_BUFFER(gmesa, 1); WRITE(gmesa->buf, TriangleMode, gmesa->TriangleMode); } if (gmesa->dirty & GAMMA_UPLOAD_FOG) { GLchan c[3], col; UNCLAMPED_FLOAT_TO_RGB_CHAN( c, gmesa->glCtx->Fog.Color ); col = gammaPackColor(4, c[0], c[1], c[2], 0); gmesa->dirty &= ~GAMMA_UPLOAD_FOG; CHECK_DMA_BUFFER(gmesa, 5); #if 0 WRITE(gmesa->buf, FogMode, gmesa->FogMode); WRITE(gmesa->buf, FogColor, col); WRITEF(gmesa->buf, FStart, gmesa->glCtx->Fog.Start); #endif WRITEF(gmesa->buf, FogEnd, gmesa->glCtx->Fog.End); WRITEF(gmesa->buf, FogDensity, gmesa->glCtx->Fog.Density); WRITEF(gmesa->buf, FogScale, 1.0f/(gmesa->glCtx->Fog.End - gmesa->glCtx->Fog.Start)); } if (gmesa->dirty & GAMMA_UPLOAD_DITHER) { gmesa->dirty &= ~GAMMA_UPLOAD_DITHER; CHECK_DMA_BUFFER(gmesa, 1); WRITE(gmesa->buf, DitherMode, gmesa->DitherMode); } if (gmesa->dirty & GAMMA_UPLOAD_LOGICOP) { gmesa->dirty &= ~GAMMA_UPLOAD_LOGICOP; CHECK_DMA_BUFFER(gmesa, 1); WRITE(gmesa->buf, LogicalOpMode, gmesa->LogicalOpMode); } if (gmesa->dirty & GAMMA_UPLOAD_CLIP) { gmesa->dirty &= ~GAMMA_UPLOAD_CLIP; CHECK_DMA_BUFFER(gmesa, 3); WRITE(gmesa->buf, ScissorMinXY, gmesa->ScissorMinXY); WRITE(gmesa->buf, ScissorMaxXY, gmesa->ScissorMaxXY); WRITE(gmesa->buf, ScissorMode, gmesa->ScissorMode); } if (gmesa->dirty & GAMMA_UPLOAD_MASKS) { gmesa->dirty &= ~GAMMA_UPLOAD_MASKS; CHECK_DMA_BUFFER(gmesa, 1); WRITE(gmesa->buf, FBHardwareWriteMask, gmesa->FBHardwareWriteMask); } if (gmesa->dirty & GAMMA_UPLOAD_ALPHA) { gmesa->dirty &= ~GAMMA_UPLOAD_ALPHA; CHECK_DMA_BUFFER(gmesa, 1); WRITE(gmesa->buf, AlphaTestMode, gmesa->AlphaTestMode); } if (gmesa->dirty & GAMMA_UPLOAD_BLEND) { gmesa->dirty &= ~GAMMA_UPLOAD_BLEND; CHECK_DMA_BUFFER(gmesa, 1); WRITE(gmesa->buf, AlphaBlendMode, gmesa->AlphaBlendMode); } CHECK_DMA_BUFFER(gmesa, 1); if (gmesa->glCtx->Color.BlendEnabled || gmesa->glCtx->Color.AlphaEnabled) { WRITE(gmesa->buf, FBReadMode, gmesa->FBReadMode | gmesa->AB_FBReadMode_Save); } else { WRITE(gmesa->buf, FBReadMode, gmesa->FBReadMode); } if (gmesa->dirty & GAMMA_UPLOAD_LIGHT) { gmesa->dirty &= ~GAMMA_UPLOAD_LIGHT; CHECK_DMA_BUFFER(gmesa, 2); WRITE(gmesa->buf, LightingMode, gmesa->LightingMode); WRITE(gmesa->buf, MaterialMode, gmesa->MaterialMode); } if (gmesa->dirty & GAMMA_UPLOAD_SHADE) { gmesa->dirty &= ~GAMMA_UPLOAD_SHADE; CHECK_DMA_BUFFER(gmesa, 1); WRITE(gmesa->buf, ColorDDAMode, gmesa->ColorDDAMode); } if (gmesa->dirty & GAMMA_UPLOAD_POLYGON) { gmesa->dirty &= ~GAMMA_UPLOAD_POLYGON; CHECK_DMA_BUFFER(gmesa, 2); WRITEF(gmesa->buf, PolygonOffsetBias, gmesa->glCtx->Polygon.OffsetUnits); WRITEF(gmesa->buf, PolygonOffsetFactor, gmesa->glCtx->Polygon.OffsetFactor); } if (gmesa->dirty & GAMMA_UPLOAD_STIPPLE) { gmesa->dirty &= ~GAMMA_UPLOAD_STIPPLE; CHECK_DMA_BUFFER(gmesa, 33); WRITE(gmesa->buf, AreaStippleMode, gmesa->AreaStippleMode); WRITE(gmesa->buf, AreaStipplePattern0, gmesa->glCtx->PolygonStipple[0]); WRITE(gmesa->buf, AreaStipplePattern1, gmesa->glCtx->PolygonStipple[1]); WRITE(gmesa->buf, AreaStipplePattern2, gmesa->glCtx->PolygonStipple[2]); WRITE(gmesa->buf, AreaStipplePattern3, gmesa->glCtx->PolygonStipple[3]); WRITE(gmesa->buf, AreaStipplePattern4, gmesa->glCtx->PolygonStipple[4]); WRITE(gmesa->buf, AreaStipplePattern5, gmesa->glCtx->PolygonStipple[5]); WRITE(gmesa->buf, AreaStipplePattern6, gmesa->glCtx->PolygonStipple[6]); WRITE(gmesa->buf, AreaStipplePattern7, gmesa->glCtx->PolygonStipple[7]); WRITE(gmesa->buf, AreaStipplePattern8, gmesa->glCtx->PolygonStipple[8]); WRITE(gmesa->buf, AreaStipplePattern9, gmesa->glCtx->PolygonStipple[9]); WRITE(gmesa->buf, AreaStipplePattern10, gmesa->glCtx->PolygonStipple[10]); WRITE(gmesa->buf, AreaStipplePattern11, gmesa->glCtx->PolygonStipple[11]); WRITE(gmesa->buf, AreaStipplePattern12, gmesa->glCtx->PolygonStipple[12]); WRITE(gmesa->buf, AreaStipplePattern13, gmesa->glCtx->PolygonStipple[13]); WRITE(gmesa->buf, AreaStipplePattern14, gmesa->glCtx->PolygonStipple[14]); WRITE(gmesa->buf, AreaStipplePattern15, gmesa->glCtx->PolygonStipple[15]); WRITE(gmesa->buf, AreaStipplePattern16, gmesa->glCtx->PolygonStipple[16]); WRITE(gmesa->buf, AreaStipplePattern17, gmesa->glCtx->PolygonStipple[17]); WRITE(gmesa->buf, AreaStipplePattern18, gmesa->glCtx->PolygonStipple[18]); WRITE(gmesa->buf, AreaStipplePattern19, gmesa->glCtx->PolygonStipple[19]); WRITE(gmesa->buf, AreaStipplePattern20, gmesa->glCtx->PolygonStipple[20]); WRITE(gmesa->buf, AreaStipplePattern21, gmesa->glCtx->PolygonStipple[21]); WRITE(gmesa->buf, AreaStipplePattern22, gmesa->glCtx->PolygonStipple[22]); WRITE(gmesa->buf, AreaStipplePattern23, gmesa->glCtx->PolygonStipple[23]); WRITE(gmesa->buf, AreaStipplePattern24, gmesa->glCtx->PolygonStipple[24]); WRITE(gmesa->buf, AreaStipplePattern25, gmesa->glCtx->PolygonStipple[25]); WRITE(gmesa->buf, AreaStipplePattern26, gmesa->glCtx->PolygonStipple[26]); WRITE(gmesa->buf, AreaStipplePattern27, gmesa->glCtx->PolygonStipple[27]); WRITE(gmesa->buf, AreaStipplePattern28, gmesa->glCtx->PolygonStipple[28]); WRITE(gmesa->buf, AreaStipplePattern29, gmesa->glCtx->PolygonStipple[29]); WRITE(gmesa->buf, AreaStipplePattern30, gmesa->glCtx->PolygonStipple[30]); WRITE(gmesa->buf, AreaStipplePattern31, gmesa->glCtx->PolygonStipple[31]); } if (gmesa->dirty & GAMMA_UPLOAD_DEPTH) { gmesa->dirty &= ~GAMMA_UPLOAD_DEPTH; CHECK_DMA_BUFFER(gmesa, 4); WRITE(gmesa->buf, DepthMode, gmesa->DepthMode); WRITE(gmesa->buf, DeltaMode, gmesa->DeltaMode); WRITE(gmesa->buf, GLINTWindow,gmesa->Window | (gmesa->FrameCount << 9)); WRITE(gmesa->buf, LBReadMode, gmesa->LBReadMode); } if (gmesa->dirty & GAMMA_UPLOAD_GEOMETRY) { gmesa->dirty &= ~GAMMA_UPLOAD_GEOMETRY; CHECK_DMA_BUFFER(gmesa, 1); WRITE(gmesa->buf, GeometryMode, gmesa->GeometryMode); } if (gmesa->dirty & GAMMA_UPLOAD_TRANSFORM) { gmesa->dirty &= ~GAMMA_UPLOAD_TRANSFORM; CHECK_DMA_BUFFER(gmesa, 1); WRITE(gmesa->buf, TransformMode, gmesa->TransformMode); } if (gmesa->dirty & GAMMA_UPLOAD_TEX0) { gammaTextureObjectPtr curTex = gmesa->CurrentTexObj[0]; gmesa->dirty &= ~GAMMA_UPLOAD_TEX0; if (curTex) { CHECK_DMA_BUFFER(gmesa, 21); WRITE(gmesa->buf, GeometryMode, gmesa->GeometryMode | GM_TextureEnable); WRITE(gmesa->buf, DeltaMode, gmesa->DeltaMode | DM_TextureEnable); WRITE(gmesa->buf, TextureAddressMode, curTex->TextureAddressMode); WRITE(gmesa->buf, TextureReadMode, curTex->TextureReadMode); WRITE(gmesa->buf, TextureColorMode, curTex->TextureColorMode); WRITE(gmesa->buf, TextureFilterMode, curTex->TextureFilterMode); WRITE(gmesa->buf, TextureFormat, curTex->TextureFormat); WRITE(gmesa->buf, GLINTBorderColor, curTex->TextureBorderColor); WRITE(gmesa->buf, TxBaseAddr0, curTex->TextureBaseAddr[0]); WRITE(gmesa->buf, TxBaseAddr1, curTex->TextureBaseAddr[1]); WRITE(gmesa->buf, TxBaseAddr2, curTex->TextureBaseAddr[2]); WRITE(gmesa->buf, TxBaseAddr3, curTex->TextureBaseAddr[3]); WRITE(gmesa->buf, TxBaseAddr4, curTex->TextureBaseAddr[4]); WRITE(gmesa->buf, TxBaseAddr5, curTex->TextureBaseAddr[5]); WRITE(gmesa->buf, TxBaseAddr6, curTex->TextureBaseAddr[6]); WRITE(gmesa->buf, TxBaseAddr7, curTex->TextureBaseAddr[7]); WRITE(gmesa->buf, TxBaseAddr8, curTex->TextureBaseAddr[8]); WRITE(gmesa->buf, TxBaseAddr9, curTex->TextureBaseAddr[9]); WRITE(gmesa->buf, TxBaseAddr10, curTex->TextureBaseAddr[10]); WRITE(gmesa->buf, TxBaseAddr11, curTex->TextureBaseAddr[11]); WRITE(gmesa->buf, TextureCacheControl, (TCC_Enable | TCC_Invalidate)); } else { CHECK_DMA_BUFFER(gmesa, 6); WRITE(gmesa->buf, GeometryMode, gmesa->GeometryMode); WRITE(gmesa->buf, DeltaMode, gmesa->DeltaMode); WRITE(gmesa->buf, TextureAddressMode, TextureAddressModeDisable); WRITE(gmesa->buf, TextureReadMode, TextureReadModeDisable); WRITE(gmesa->buf, TextureFilterMode, TextureFilterModeDisable); WRITE(gmesa->buf, TextureColorMode, TextureColorModeDisable); } } #ifdef DO_VALIDATE PROCESS_DMA_BUFFER_TOP_HALF(gmesa); DRM_SPINUNLOCK(&gmesa->driScreen->pSAREA->drawable_lock, gmesa->driScreen->drawLockID); VALIDATE_DRAWABLE_INFO_NO_LOCK_POST(gmesa); PROCESS_DMA_BUFFER_BOTTOM_HALF(gmesa); #endif }