Exemplo n.º 1
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)
{
    __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;
}
Exemplo n.º 2
0
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 {
Exemplo n.º 3
0
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 {
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
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);
}
Exemplo n.º 6
0
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);
}
Exemplo n.º 7
0
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;
	}
}
Exemplo n.º 8
0
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;
	}
}
Exemplo n.º 9
0
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;
	}
}
Exemplo n.º 10
0
/**
 * 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);
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
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);
	}
Exemplo n.º 13
0
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 {
Exemplo n.º 14
0
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 );
}
Exemplo n.º 15
0
/*
 * 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
}