summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeonsi
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/radeonsi')
-rw-r--r--src/gallium/drivers/radeonsi/cik_sdma.c217
1 files changed, 2 insertions, 215 deletions
diff --git a/src/gallium/drivers/radeonsi/cik_sdma.c b/src/gallium/drivers/radeonsi/cik_sdma.c
index a8caf04909f..ec3446a5b5f 100644
--- a/src/gallium/drivers/radeonsi/cik_sdma.c
+++ b/src/gallium/drivers/radeonsi/cik_sdma.c
@@ -89,110 +89,6 @@ static void cik_sdma_copy_buffer(struct si_context *ctx,
cik_sdma_do_copy_buffer(ctx, dst, src, dst_offset, src_offset, size);
}
-static void cik_sdma_copy_tile(struct si_context *ctx,
- struct pipe_resource *dst,
- unsigned dst_level,
- struct pipe_resource *src,
- unsigned src_level,
- unsigned y,
- unsigned copy_height,
- unsigned y_align,
- unsigned pitch,
- unsigned bpe)
-{
- struct radeon_winsys_cs *cs = ctx->b.dma.cs;
- struct r600_texture *rsrc = (struct r600_texture*)src;
- struct r600_texture *rdst = (struct r600_texture*)dst;
- unsigned dst_mode = rdst->surface.level[dst_level].mode;
- unsigned src_mode = rsrc->surface.level[src_level].mode;
- bool detile = dst_mode == RADEON_SURF_MODE_LINEAR_ALIGNED;
- struct r600_texture *rlinear = detile ? rdst : rsrc;
- struct r600_texture *rtiled = detile ? rsrc : rdst;
- unsigned linear_lvl = detile ? dst_level : src_level;
- unsigned tiled_lvl = detile ? src_level : dst_level;
- struct radeon_info *info = &ctx->screen->b.info;
- unsigned index = rtiled->surface.tiling_index[tiled_lvl];
- unsigned macro_index = rtiled->surface.macro_tile_index;
- unsigned tile_mode = info->si_tile_mode_array[index];
- unsigned macro_mode = info->cik_macrotile_mode_array[macro_index];
- unsigned array_mode, lbpe, pitch_tile_max, slice_tile_max, size;
- unsigned ncopy, height, cheight, i;
- unsigned sub_op, bank_h, bank_w, mt_aspect, nbanks, tile_split, mt;
- uint64_t base, addr;
- unsigned pipe_config;
-
- assert(dst_mode != src_mode);
- assert(src_mode == RADEON_SURF_MODE_LINEAR_ALIGNED || dst_mode == RADEON_SURF_MODE_LINEAR_ALIGNED);
-
- sub_op = CIK_SDMA_COPY_SUB_OPCODE_TILED;
- lbpe = util_logbase2(bpe);
- pitch_tile_max = ((pitch / bpe) / 8) - 1;
-
- assert(!util_format_is_depth_and_stencil(rtiled->resource.b.b.format));
-
- array_mode = G_009910_ARRAY_MODE(tile_mode);
- slice_tile_max = (rtiled->surface.level[tiled_lvl].nblk_x *
- rtiled->surface.level[tiled_lvl].nblk_y) / (8*8) - 1;
- height = rlinear->surface.level[linear_lvl].nblk_y;
- base = rtiled->surface.level[tiled_lvl].offset;
- addr = rlinear->surface.level[linear_lvl].offset;
- bank_h = G_009990_BANK_HEIGHT(macro_mode);
- bank_w = G_009990_BANK_WIDTH(macro_mode);
- mt_aspect = G_009990_MACRO_TILE_ASPECT(macro_mode);
- /* Non-depth modes don't have TILE_SPLIT set. */
- tile_split = util_logbase2(rtiled->surface.tile_split >> 6);
- nbanks = G_009990_NUM_BANKS(macro_mode);
- base += rtiled->resource.gpu_address;
- addr += rlinear->resource.gpu_address;
-
- pipe_config = G_009910_PIPE_CONFIG(tile_mode);
- mt = G_009910_MICRO_TILE_MODE_NEW(tile_mode);
-
- size = (copy_height * pitch) / 4;
- cheight = copy_height;
- if (((cheight * pitch) / 4) > CIK_SDMA_COPY_MAX_SIZE) {
- cheight = (CIK_SDMA_COPY_MAX_SIZE * 4) / pitch;
- cheight &= ~(y_align - 1);
- }
- ncopy = (copy_height + cheight - 1) / cheight;
- r600_need_dma_space(&ctx->b, ncopy * 12);
-
- radeon_add_to_buffer_list(&ctx->b, &ctx->b.dma, &rsrc->resource,
- RADEON_USAGE_READ, RADEON_PRIO_SDMA_TEXTURE);
- radeon_add_to_buffer_list(&ctx->b, &ctx->b.dma, &rdst->resource,
- RADEON_USAGE_WRITE, RADEON_PRIO_SDMA_TEXTURE);
-
- copy_height = size * 4 / pitch;
- for (i = 0; i < ncopy; i++) {
- cheight = copy_height;
- if (((cheight * pitch) / 4) > CIK_SDMA_COPY_MAX_SIZE) {
- cheight = (CIK_SDMA_COPY_MAX_SIZE * 4) / pitch;
- cheight &= ~(y_align - 1);
- }
- size = (cheight * pitch) / 4;
-
- cs->buf[cs->cdw++] = CIK_SDMA_PACKET(CIK_SDMA_OPCODE_COPY,
- sub_op, detile << 15);
- cs->buf[cs->cdw++] = base;
- cs->buf[cs->cdw++] = base >> 32;
- cs->buf[cs->cdw++] = ((height - 1) << 16) | pitch_tile_max;
- cs->buf[cs->cdw++] = slice_tile_max;
- cs->buf[cs->cdw++] = (pipe_config << 26) | (mt_aspect << 24) |
- (nbanks << 21) | (bank_h << 18) | (bank_w << 15) |
- (tile_split << 11) | (mt << 8) | (array_mode << 3) |
- lbpe;
- cs->buf[cs->cdw++] = y << 16; /* | x */
- cs->buf[cs->cdw++] = 0; /* z */
- cs->buf[cs->cdw++] = addr & 0xfffffffc;
- cs->buf[cs->cdw++] = addr >> 32;
- cs->buf[cs->cdw++] = (pitch / bpe) - 1;
- cs->buf[cs->cdw++] = size;
-
- copy_height -= cheight;
- y += cheight;
- }
-}
-
static void cik_sdma_copy(struct pipe_context *ctx,
struct pipe_resource *dst,
unsigned dst_level,
@@ -202,124 +98,15 @@ static void cik_sdma_copy(struct pipe_context *ctx,
const struct pipe_box *src_box)
{
struct si_context *sctx = (struct si_context *)ctx;
- struct r600_texture *rsrc = (struct r600_texture*)src;
- struct r600_texture *rdst = (struct r600_texture*)dst;
- unsigned dst_pitch, src_pitch, bpe, dst_mode, src_mode;
- unsigned src_w, dst_w;
- unsigned src_x, src_y;
- unsigned copy_height, y_align;
- unsigned dst_x = dstx, dst_y = dsty, dst_z = dstz;
- if (sctx->b.dma.cs == NULL) {
+ if (!sctx->b.dma.cs)
goto fallback;
- }
if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
- cik_sdma_copy_buffer(sctx, dst, src, dst_x, src_box->x, src_box->width);
+ cik_sdma_copy_buffer(sctx, dst, src, dstx, src_box->x, src_box->width);
return;
}
- /* Before re-enabling this, please make sure you can hit all newly
- * enabled paths in your testing, preferably with both piglit (in
- * particular the streaming-texture-leak test) and real world apps
- * (e.g. the UE4 Elemental demo).
- */
- goto fallback;
-
- if (!r600_prepare_for_dma_blit(&sctx->b, rdst, dst_level, dstx, dsty,
- dstz, rsrc, src_level, src_box))
- goto fallback;
-
- src_x = util_format_get_nblocksx(src->format, src_box->x);
- dst_x = util_format_get_nblocksx(src->format, dst_x);
- src_y = util_format_get_nblocksy(src->format, src_box->y);
- dst_y = util_format_get_nblocksy(src->format, dst_y);
-
- dst_pitch = rdst->surface.level[dst_level].pitch_bytes;
- src_pitch = rsrc->surface.level[src_level].pitch_bytes;
- src_w = rsrc->surface.level[src_level].npix_x;
- dst_w = rdst->surface.level[dst_level].npix_x;
-
- if (src_pitch != dst_pitch || src_box->x || dst_x || src_w != dst_w ||
- src_box->width != src_w ||
- rsrc->surface.level[src_level].nblk_y !=
- rdst->surface.level[dst_level].nblk_y) {
- /* FIXME CIK can do partial blit */
- goto fallback;
- }
-
- bpe = rdst->surface.bpe;
- copy_height = src_box->height / rsrc->surface.blk_h;
- dst_mode = rdst->surface.level[dst_level].mode;
- src_mode = rsrc->surface.level[src_level].mode;
-
- /* Dimensions must be aligned to (macro)tiles */
- switch (src_mode == RADEON_SURF_MODE_LINEAR_ALIGNED ? dst_mode : src_mode) {
- case RADEON_SURF_MODE_1D:
- if ((src_x % 8) || (src_y % 8) || (dst_x % 8) || (dst_y % 8) ||
- (copy_height % 8))
- goto fallback;
- y_align = 8;
- break;
- case RADEON_SURF_MODE_2D: {
- unsigned mtilew, mtileh;
- struct radeon_info *info = &sctx->screen->b.info;
- unsigned macro_index = rsrc->surface.macro_tile_index;
- unsigned macro_mode = info->cik_macrotile_mode_array[macro_index];
- unsigned num_banks = 2 << G_009990_NUM_BANKS(macro_mode);
-
- mtilew = (8 * rsrc->surface.bankw *
- sctx->screen->b.info.num_tile_pipes) *
- rsrc->surface.mtilea;
- assert(!(mtilew & (mtilew - 1)));
- mtileh = (8 * rsrc->surface.bankh * num_banks) /
- rsrc->surface.mtilea;
- assert(!(mtileh & (mtileh - 1)));
-
- if ((src_x & (mtilew - 1)) || (src_y & (mtileh - 1)) ||
- (dst_x & (mtilew - 1)) || (dst_y & (mtileh - 1)) ||
- (copy_height & (mtileh - 1)))
- goto fallback;
-
- y_align = mtileh;
- break;
- }
- default:
- y_align = 1;
- }
-
- if (src_mode == dst_mode) {
- uint64_t dst_offset, src_offset;
- unsigned src_h, dst_h;
-
- src_h = rsrc->surface.level[src_level].npix_y;
- dst_h = rdst->surface.level[dst_level].npix_y;
-
- if (src_box->depth > 1 &&
- (src_y || dst_y || src_h != dst_h || src_box->height != src_h))
- goto fallback;
-
- /* simple dma blit would do NOTE code here assume :
- * dst_pitch == src_pitch
- */
- src_offset= rsrc->surface.level[src_level].offset;
- src_offset += rsrc->surface.level[src_level].slice_size * src_box->z;
- src_offset += src_y * src_pitch + src_x * bpe;
- dst_offset = rdst->surface.level[dst_level].offset;
- dst_offset += rdst->surface.level[dst_level].slice_size * dst_z;
- dst_offset += dst_y * dst_pitch + dst_x * bpe;
- cik_sdma_do_copy_buffer(sctx, dst, src, dst_offset, src_offset,
- src_box->depth *
- rsrc->surface.level[src_level].slice_size);
- } else {
- if (dst_y != src_y || src_box->depth > 1 || src_box->z || dst_z)
- goto fallback;
-
- cik_sdma_copy_tile(sctx, dst, dst_level, src, src_level,
- src_y, copy_height, y_align, dst_pitch, bpe);
- }
- return;
-
fallback:
si_resource_copy_region(ctx, dst, dst_level, dstx, dsty, dstz,
src, src_level, src_box);