static void si_set_mutable_tex_desc_fields(struct radv_device *device, struct radv_image *image, const struct radeon_surf_level *base_level_info, unsigned base_level, unsigned first_level, unsigned block_width, bool is_stencil, uint32_t *state) { uint64_t gpu_address = device->ws->buffer_get_va(image->bo) + image->offset; uint64_t va = gpu_address + base_level_info->offset; unsigned pitch = base_level_info->nblk_x * block_width; state[1] &= C_008F14_BASE_ADDRESS_HI; state[3] &= C_008F1C_TILING_INDEX; state[4] &= C_008F20_PITCH; state[6] &= C_008F28_COMPRESSION_EN; assert(!(va & 255)); state[0] = va >> 8; state[1] |= S_008F14_BASE_ADDRESS_HI(va >> 40); state[3] |= S_008F1C_TILING_INDEX(si_tile_mode_index(image, base_level, is_stencil)); state[4] |= S_008F20_PITCH(pitch - 1); if (image->surface.dcc_size && image->surface.level[first_level].dcc_enabled) { state[6] |= S_008F28_COMPRESSION_EN(1); state[7] = (gpu_address + image->dcc_offset + base_level_info->dcc_offset) >> 8; }
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 si_screen *sscreen = ctx->screen; struct r600_texture *rsrc = (struct r600_texture*)src; struct r600_texture *rdst = (struct r600_texture*)dst; struct r600_texture *rlinear, *rtiled; unsigned linear_lvl, tiled_lvl; unsigned array_mode, lbpe, pitch_tile_max, slice_tile_max, size; unsigned ncopy, height, cheight, detile, i, src_mode, dst_mode; unsigned sub_op, bank_h, bank_w, mt_aspect, nbanks, tile_split, mt; uint64_t base, addr; unsigned pipe_config, tile_mode_index; dst_mode = rdst->surface.level[dst_level].mode; src_mode = rsrc->surface.level[src_level].mode; 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; detile = dst_mode == RADEON_SURF_MODE_LINEAR_ALIGNED; rlinear = detile ? rdst : rsrc; rtiled = detile ? rsrc : rdst; linear_lvl = detile ? dst_level : src_level; tiled_lvl = detile ? src_level : dst_level; assert(!util_format_is_depth_and_stencil(rtiled->resource.b.b.format)); array_mode = si_array_mode(rtiled->surface.level[tiled_lvl].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 = cik_bank_wh(rtiled->surface.bankh); bank_w = cik_bank_wh(rtiled->surface.bankw); mt_aspect = cik_macro_tile_aspect(rtiled->surface.mtilea); tile_split = cik_tile_split(rtiled->surface.tile_split); tile_mode_index = si_tile_mode_index(rtiled, tiled_lvl, false); nbanks = si_num_banks(sscreen, rtiled); base += rtiled->resource.gpu_address; addr += rlinear->resource.gpu_address; pipe_config = cik_db_pipe_config(sscreen, tile_mode_index); mt = cik_micro_tile_mode(sscreen, tile_mode_index); 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; } }