static void r600_clear_buffer(struct pipe_context *ctx, struct pipe_resource *dst, unsigned offset, unsigned size, unsigned value) { struct r600_context *rctx = (struct r600_context*)ctx; if (rctx->screen->b.has_cp_dma && rctx->b.chip_class >= EVERGREEN && offset % 4 == 0 && size % 4 == 0) { evergreen_cp_dma_clear_buffer(rctx, dst, offset, size, value); } else if (rctx->screen->b.has_streamout && offset % 4 == 0 && size % 4 == 0) { union pipe_color_union clear_value; clear_value.ui[0] = value; r600_blitter_begin(ctx, R600_DISABLE_RENDER_COND); util_blitter_clear_buffer(rctx->blitter, dst, offset, size, 1, &clear_value); r600_blitter_end(ctx); } else { uint32_t *map = r600_buffer_map_sync_with_rings(&rctx->b, r600_resource(dst), PIPE_TRANSFER_WRITE); size /= 4; for (unsigned i = 0; i < size; i++) *map++ = value; } }
static void r600_clear_buffer(struct pipe_context *ctx, struct pipe_resource *dst, unsigned offset, unsigned size, unsigned char value) { struct r600_context *rctx = (struct r600_context*)ctx; uint32_t v = value; if (rctx->screen->has_cp_dma && rctx->b.chip_class >= EVERGREEN && offset % 4 == 0 && size % 4 == 0) { uint32_t clear_value = v | (v << 8) | (v << 16) | (v << 24); evergreen_cp_dma_clear_buffer(rctx, dst, offset, size, clear_value); } else if (rctx->screen->has_streamout && offset % 4 == 0 && size % 4 == 0) { union pipe_color_union clear_value; clear_value.ui[0] = v | (v << 8) | (v << 16) | (v << 24); r600_flag_resource_cache_flush(rctx, dst); r600_blitter_begin(ctx, R600_DISABLE_RENDER_COND); util_blitter_clear_buffer(rctx->blitter, dst, offset, size, 1, &clear_value); r600_blitter_end(ctx); /* Flush again in case the 3D engine has been prefetching the resource. */ r600_flag_resource_cache_flush(rctx, dst); } else { char *map = r600_buffer_mmap_sync_with_rings(rctx, r600_resource(dst), PIPE_TRANSFER_WRITE); memset(map + offset, value, size); } }
static void si_pipe_clear_buffer(struct pipe_context *ctx, struct pipe_resource *dst, unsigned offset, unsigned size, const void *clear_value_ptr, int clear_value_size) { struct si_context *sctx = (struct si_context*)ctx; uint32_t dword_value; unsigned i; assert(offset % clear_value_size == 0); assert(size % clear_value_size == 0); if (clear_value_size > 4) { const uint32_t *u32 = clear_value_ptr; bool clear_dword_duplicated = true; /* See if we can lower large fills to dword fills. */ for (i = 1; i < clear_value_size / 4; i++) if (u32[0] != u32[i]) { clear_dword_duplicated = false; break; } if (!clear_dword_duplicated) { /* Use transform feedback for 64-bit, 96-bit, and * 128-bit fills. */ union pipe_color_union clear_value; memcpy(&clear_value, clear_value_ptr, clear_value_size); si_blitter_begin(ctx, SI_DISABLE_RENDER_COND); util_blitter_clear_buffer(sctx->blitter, dst, offset, size, clear_value_size / 4, &clear_value); si_blitter_end(ctx); return; } } /* Expand the clear value to a dword. */ switch (clear_value_size) { case 1: dword_value = *(uint8_t*)clear_value_ptr; dword_value |= (dword_value << 8) | (dword_value << 16) | (dword_value << 24); break; case 2: dword_value = *(uint16_t*)clear_value_ptr; dword_value |= dword_value << 16; break; default: dword_value = *(uint32_t*)clear_value_ptr; } sctx->b.clear_buffer(ctx, dst, offset, size, dword_value, R600_COHERENCY_SHADER); }