radeonsi: merge SI and CI dma_clear_buffer and remove the callback
[mesa.git] / src / gallium / drivers / radeonsi / si_dma_cs.c
index 7db9570af3c4437f22026423333531b9219d4763..ffa2f5ae69be7311b38924b68f2a217a2da0cb11 100644 (file)
@@ -64,6 +64,65 @@ void si_dma_emit_timestamp(struct si_context *sctx, struct r600_resource *dst,
        radeon_emit(cs, va >> 32);
 }
 
+void si_sdma_clear_buffer(struct si_context *sctx, struct pipe_resource *dst,
+                         uint64_t offset, uint64_t size, unsigned clear_value)
+{
+       struct radeon_cmdbuf *cs = sctx->dma_cs;
+       unsigned i, ncopy, csize;
+       struct r600_resource *rdst = r600_resource(dst);
+
+       assert(offset % 4 == 0);
+       assert(size);
+       assert(size % 4 == 0);
+
+       if (!cs || dst->flags & PIPE_RESOURCE_FLAG_SPARSE) {
+               sctx->b.clear_buffer(&sctx->b, dst, offset, size, &clear_value, 4);
+               return;
+       }
+
+       /* Mark the buffer range of destination as valid (initialized),
+        * so that transfer_map knows it should wait for the GPU when mapping
+        * that range. */
+       util_range_add(&rdst->valid_buffer_range, offset, offset + size);
+
+       offset += rdst->gpu_address;
+
+       if (sctx->chip_class == SI) {
+               /* the same maximum size as for copying */
+               ncopy = DIV_ROUND_UP(size, SI_DMA_COPY_MAX_DWORD_ALIGNED_SIZE);
+               si_need_dma_space(sctx, ncopy * 4, rdst, NULL);
+
+               for (i = 0; i < ncopy; i++) {
+                       csize = MIN2(size, SI_DMA_COPY_MAX_DWORD_ALIGNED_SIZE);
+                       radeon_emit(cs, SI_DMA_PACKET(SI_DMA_PACKET_CONSTANT_FILL, 0,
+                                                     csize / 4));
+                       radeon_emit(cs, offset);
+                       radeon_emit(cs, clear_value);
+                       radeon_emit(cs, (offset >> 32) << 16);
+                       offset += csize;
+                       size -= csize;
+               }
+               return;
+       }
+
+       /* The following code is for CI, VI, Vega/Raven, etc. */
+       /* the same maximum size as for copying */
+       ncopy = DIV_ROUND_UP(size, CIK_SDMA_COPY_MAX_SIZE);
+       si_need_dma_space(sctx, ncopy * 5, rdst, NULL);
+
+       for (i = 0; i < ncopy; i++) {
+               csize = MIN2(size, CIK_SDMA_COPY_MAX_SIZE);
+               radeon_emit(cs, CIK_SDMA_PACKET(CIK_SDMA_PACKET_CONSTANT_FILL, 0,
+                                               0x8000 /* dword copy */));
+               radeon_emit(cs, offset);
+               radeon_emit(cs, offset >> 32);
+               radeon_emit(cs, clear_value);
+               radeon_emit(cs, sctx->chip_class >= GFX9 ? csize - 1 : csize);
+               offset += csize;
+               size -= csize;
+       }
+}
+
 void si_need_dma_space(struct si_context *ctx, unsigned num_dw,
                       struct r600_resource *dst, struct r600_resource *src)
 {
@@ -170,7 +229,7 @@ void si_screen_clear_buffer(struct si_screen *sscreen, struct pipe_resource *dst
        struct si_context *ctx = (struct si_context*)sscreen->aux_context;
 
        mtx_lock(&sscreen->aux_context_lock);
-       ctx->dma_clear_buffer(ctx, dst, offset, size, value);
+       si_sdma_clear_buffer(ctx, dst, offset, size, value);
        sscreen->aux_context->flush(sscreen->aux_context, NULL, 0);
        mtx_unlock(&sscreen->aux_context_lock);
 }