/* Flush the indirect buffer to the kernel for submission to the card */
void R600CPFlushIndirect(ScrnInfoPtr pScrn, drmBufPtr ib)
{
    drmBufPtr          buffer = ib;
    int                start  = 0;
    drm_radeon_indirect_t  indirect;
    int drmFD = RHDDRMFDGet(pScrn->scrnIndex);

    if (!buffer) return;

    while (buffer->used & 0x3c){
        E32(buffer, CP_PACKET2()); /* fill up to multiple of 16 dwords */
    }

    indirect.idx     = buffer->idx;
    indirect.start   = start;
    indirect.end     = buffer->used;
    indirect.discard = 1;

    drmCommandWriteRead(drmFD, DRM_RADEON_INDIRECT,
			&indirect, sizeof(drm_radeon_indirect_t));

}
Exemple #2
0
void
radeondrm_commit_ring(struct drm_radeon_private *dev_priv)
{
	int		 i, tail_aligned, num_p2;
	u_int32_t	*ring;

	/* check if the ring is padded out to 16-dword alignment */

	tail_aligned = dev_priv->ring.tail & (RADEON_RING_ALIGN - 1);
	if (tail_aligned) {
		num_p2 = RADEON_RING_ALIGN - tail_aligned;

		ring = dev_priv->ring.start;
		/* pad with some CP_PACKET2 */
		for (i = 0; i < num_p2; i++)
			ring[dev_priv->ring.tail + i] = CP_PACKET2();

		dev_priv->ring.tail += i;
		dev_priv->ring.space -= num_p2;
		
	}
	dev_priv->ring.tail &= dev_priv->ring.tail_mask;
	/* XXX 128byte aligned stuff */
	/* flush write combining buffer and writes to ring */
	DRM_MEMORYBARRIER();
	radeondrm_get_ring_head(dev_priv);
	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
		RADEON_WRITE(R600_CP_RB_WPTR, dev_priv->ring.tail);
		/* read from PCI bus to ensure correct posting */
		RADEON_READ(R600_CP_RB_RPTR);
	} else {
		RADEON_WRITE(RADEON_CP_RB_WPTR, dev_priv->ring.tail);
		/* read from PCI bus to ensure correct posting */
		RADEON_READ(RADEON_CP_RB_RPTR);
	}
}