First half of commit (DRM) for blits using BM_HOSTDATA. This elminates the

need for userspace clients to add HOSTDATA0 commands to blit buffers
    every 16 dwords. However, it requires using BM_HOSTDATA rather than
    BM_ADDR as the target register in the DMA descriptors for the blit
    data. The first descriptor for a blit buffer sets up the state using
    BM_ADDR. Both types of descriptor work with SRC_BM_OP_SYSTEM_TO_REG in
    SRC_CNTL.
This commit is contained in:
Leif Delgass 2002-06-08 21:11:35 +00:00
parent c351b6dd62
commit 75d5b6bb0e
3 changed files with 84 additions and 10 deletions

View file

@ -436,18 +436,18 @@ static int mach64_bm_dma_test( drm_device_t *dev )
/* fill up a buffer with sets of 3 consecutive writes starting with VERTEX_1_S */
count = 0;
data[count++] = cpu_to_le32(0x00020190); /* 1_90 = VERTEX_1_S */
data[count++] = cpu_to_le32(DMAREG(MACH64_VERTEX_1_S) | (2 << 16));
data[count++] = expected[0] = 0x11111111;
data[count++] = expected[1] = 0x22222222;
data[count++] = expected[2] = 0x33333333;
while (count < 1020) {
data[count++] = cpu_to_le32(0x00020190);
data[count++] = cpu_to_le32(DMAREG(MACH64_VERTEX_1_S) | (2 << 16));
data[count++] = 0x11111111;
data[count++] = 0x22222222;
data[count++] = 0x33333333;
}
data[count++] = cpu_to_le32(0x0000006d); /* SRC_CNTL */
data[count++] = cpu_to_le32(DMAREG(MACH64_SRC_CNTL) | (0 << 16));
data[count++] = 0;
DRM_DEBUG( "Preparing table ...\n" );

View file

@ -742,4 +742,76 @@ do { \
mach64_dma_start( dev_priv ); \
} while(0)
#define DMAADVANCEHOSTDATA( dev_priv ) \
do { \
struct list_head *ptr; \
drm_mach64_freelist_t *entry; \
RING_LOCALS; \
\
if ( MACH64_VERBOSE ) { \
DRM_INFO( "DMAADVANCE() in %s\n", __FUNCTION__ ); \
} \
\
if (list_empty(&dev_priv->placeholders)) { \
DRM_ERROR( "%s: empty placeholder list in DMAADVANCE()\n", \
__FUNCTION__ ); \
return -EFAULT; \
} \
\
ptr = dev_priv->placeholders.next; \
list_del(ptr); \
entry = list_entry(ptr, drm_mach64_freelist_t, list); \
entry->buf = buf; \
entry->buf->pending = 1; \
list_add_tail(ptr, &dev_priv->pending); \
\
ADD_HOSTDATA_BUF_TO_RING( dev_priv, entry ); \
} while (0)
#define ADD_HOSTDATA_BUF_TO_RING( dev_priv, entry ) \
do { \
int bytes, pages, remainder; \
drm_buf_t *buf = entry->buf; \
u32 address, page; \
int i; \
\
bytes = buf->used - MACH64_HOSTDATA_BLIT_OFFSET; \
pages = (bytes + DMA_CHUNKSIZE - 1) / DMA_CHUNKSIZE; \
address = GETBUFADDR( buf ); \
\
BEGIN_RING( 4 + pages * 4 ); \
\
OUT_RING( APERTURE_OFFSET + MACH64_BM_ADDR ); \
OUT_RING( address ); \
OUT_RING( MACH64_HOSTDATA_BLIT_OFFSET | DMA_HOLD_OFFSET ); \
OUT_RING( 0 ); \
\
address += MACH64_HOSTDATA_BLIT_OFFSET; \
\
for ( i = 0 ; i < pages-1 ; i++ ) { \
page = address + i * DMA_CHUNKSIZE; \
OUT_RING( APERTURE_OFFSET + MACH64_BM_HOSTDATA ); \
OUT_RING( page ); \
OUT_RING( DMA_CHUNKSIZE | DMA_HOLD_OFFSET ); \
OUT_RING( 0 ); \
} \
\
/* generate the final descriptor for any remaining commands in this buffer */ \
page = address + i * DMA_CHUNKSIZE; \
remainder = bytes - i * DMA_CHUNKSIZE; \
\
/* Save dword offset of last descriptor for this buffer. \
* This is needed to check for completion of the buffer in freelist_get \
*/ \
entry->ring_ofs = RING_WRITE_OFS; \
\
OUT_RING( APERTURE_OFFSET + MACH64_BM_HOSTDATA ); \
OUT_RING( page ); \
OUT_RING( remainder | DMA_HOLD_OFFSET ); \
OUT_RING( 0 ); \
\
ADVANCE_RING(); \
mach64_dma_start( dev_priv ); \
} while(0)
#endif /* __MACH64_DRV_H__ */

View file

@ -467,13 +467,15 @@ static int mach64_dma_dispatch_blit( drm_device_t *dev,
p = GETBUFPTR( buf );
dwords = (blit->width * blit->height) >> dword_shift;
/* Add in a command for every 16 dwords */
dwords += ( ( dwords + 15 ) / 16 );
buf->used = dwords << 2;
/* Blit via the host data registers (gui-master)
* Add state setup at the start of the buffer --
* the client leaves space for this based on MACH64_HOSTDATA_BLIT_OFFSET
/* FIXME: Use a last buffer flag and reduce the state emitted for subsequent,
* continuation buffers?
*/
/* Blit via BM_HOSTDATA (gui-master) - like HOST_DATA[0-15], but doesn't require
* a register command every 16 dwords. State setup is added at the start of the
* buffer -- the client leaves space for this based on MACH64_HOSTDATA_BLIT_OFFSET
*/
DMAOUTREG( MACH64_Z_CNTL, 0 );
DMAOUTREG( MACH64_SCALE_3D_CNTL, 0 );
@ -510,8 +512,8 @@ static int mach64_dma_dispatch_blit( drm_device_t *dev,
DRM_DEBUG( "%s: %d bytes\n", __FUNCTION__, buf->used );
/* Add the buffer to the queue */
DMAADVANCE( dev_priv );
DMAADVANCEHOSTDATA( dev_priv );
dev_priv->sarea_priv->dirty |= (MACH64_UPLOAD_CONTEXT |
MACH64_UPLOAD_MISC);