Dear Younes, > > Just one more thing. > > If two commands, (1) simple DMA data copies and (2) fencing, are executed in > > this order, it is possible to have the fence value written before completing DMA > > data copies, since DMA and GPU are independent, isn't is? > > No, the fence value will be written after the DMA completes. There is > no independent DMA controller on the GPU, all memory copies are done > by the GPU and are no different than the drawing commands.
Ahh that is why I was so confused; I thought DMAC is independent ;-) I maybe read somewhare a wrong article saying GPU operations can be overlapped with DMA transactions... > Here is a quick example, I copied them from > src/gallium/drivers/nouveau/nv04_surface_2d.c and edited them slightly > in case you want to look at it yourself: > > /* Set up a 2D blit operation to copy an image with dimensions w,h > from src_bo at sx,sy to dst_bo at dx,dy */ > MARK_RING (chan, 12, 4); > BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); > OUT_RELOCo(chan, src_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); > OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); > BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); > OUT_RING (chan, format); > OUT_RING (chan, (dst_pitch << 16) | src_pitch); > OUT_RELOCl(chan, src_bo, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); > OUT_RELOCl(chan, dst_bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); > BEGIN_RING(chan, blit, 0x0300, 3); > OUT_RING (chan, (sy << 16) | sx); > OUT_RING (chan, (dy << 16) | dx); > OUT_RING (chan, ( h << 16) | w); > > /* Set up a general memory-to-memory operation to copy w*h*blocksize > bytes from src_bo + src_offset to dst_bo + dst_offset */ > MARK_RING (chan, 3 + ((h / 2047) + 1) * 9, 2 + ((h / 2047) + 1) * 2); > BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2); > OUT_RELOCo(chan, src_bo, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); > OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); > BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); > OUT_RELOCl(chan, src_bo, src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART > | NOUVEAU_BO_RD); > OUT_RELOCl(chan, dst_bo, dst_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART > | NOUVEAU_BO_WR); > OUT_RING (chan, src_pitch); > OUT_RING (chan, dst_pitch); > OUT_RING (chan, w * util_format_get_blocksize(src->texture->format)); > OUT_RING (chan, h); > OUT_RING (chan, 0x0101); > OUT_RING (chan, 0); > > /* Set up a fill operation to fill a rectangle in dst_bo with > coordinates dx,dy,w,h with some solid color */ > MARK_RING (chan, 16, 4); > BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); > OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); > OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); > BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); > OUT_RING (chan, cs2d_format); > OUT_RING (chan, (dst_pitch << 16) | dst_pitch); > OUT_RELOCl(chan, dst_bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); > OUT_RELOCl(chan, dst_bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); > BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); > OUT_RING (chan, gdirect_format); > BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1); > OUT_RING (chan, value); > BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), > 2); > OUT_RING (chan, (dx << 16) | dy); > OUT_RING (chan, ( w << 16) | h); > > /* Tell the GPU to execute all of the commands in the pushbuffer */ > /* This will cause the kernel to emit a fence with some value X after > the last command in the pushbuffer */ > FIRE_RING(chan) > > while (nvchan_rd32(chan, 0x48) != X) > { > /* wait... */ > } > > /* At this point we are guaranteed that all 3 operations are complete > because the GPU will only write X into the register after it has seen > the fence command created by FIRE_RING() and it will only see that > command after it has seen and executed all other commands. */ I am well conviced by the example. Coundn't understand this much by myself. Thanks! Shinpei _______________________________________________ Nouveau mailing list Nouveau@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/nouveau