diff --git a/src/amd/common/ac_cmdbuf_sdma.c b/src/amd/common/ac_cmdbuf_sdma.c index 5a74076f530..99cb4fe115c 100644 --- a/src/amd/common/ac_cmdbuf_sdma.c +++ b/src/amd/common/ac_cmdbuf_sdma.c @@ -7,6 +7,8 @@ #include "ac_cmdbuf.h" #include "ac_cmdbuf_sdma.h" +#include "ac_formats.h" +#include "ac_surface.h" #include "sid.h" #include "util/u_math.h" @@ -182,3 +184,170 @@ ac_emit_sdma_copy_linear_sub_window(struct ac_cmdbuf *cs, enum sdma_version sdma } ac_cmdbuf_end(); } + +static uint32_t +ac_sdma_get_tiled_header_dword(enum sdma_version sdma_ip_version, + const struct ac_sdma_surf_tiled *tiled) +{ + if (sdma_ip_version >= SDMA_5_0) { + return 0; + } else if (sdma_ip_version >= SDMA_4_0) { + const uint32_t mip_max = MAX2(tiled->num_levels, 1); + const uint32_t mip_id = tiled->first_level; + + return (mip_max - 1) << 20 | mip_id << 24; + } else { + UNREACHABLE("unsupported SDMA version"); + } +} + +static enum gfx9_resource_type +ac_sdma_get_tiled_resource_dim(enum sdma_version sdma_ip_version, + const struct ac_sdma_surf_tiled *tiled) +{ + if (sdma_ip_version >= SDMA_5_0) { + /* Use the 2D resource type for rotated or Z swizzles. */ + if ((tiled->surf->u.gfx9.resource_type == RADEON_RESOURCE_1D || + tiled->surf->u.gfx9.resource_type == RADEON_RESOURCE_3D) && + (tiled->surf->micro_tile_mode == RADEON_MICRO_MODE_RENDER || + tiled->surf->micro_tile_mode == RADEON_MICRO_MODE_DEPTH)) + return RADEON_RESOURCE_2D; + } + + return tiled->surf->u.gfx9.resource_type; +} + +static uint32_t +ac_sdma_get_tiled_info_dword(const struct radeon_info *info, + const struct ac_sdma_surf_tiled *tiled) +{ + const uint32_t swizzle_mode = tiled->surf->has_stencil ? tiled->surf->u.gfx9.zs.stencil_swizzle_mode + : tiled->surf->u.gfx9.swizzle_mode; + const enum gfx9_resource_type dimension = + ac_sdma_get_tiled_resource_dim(info->sdma_ip_version, tiled); + const uint32_t mip_max = MAX2(tiled->num_levels, 1); + const uint32_t mip_id = tiled->first_level; + const uint32_t element_size = util_logbase2(tiled->bpp); + uint32_t info_dword = 0; + + if (info->sdma_ip_version >= SDMA_4_0) { + info_dword |= element_size; + info_dword |= swizzle_mode << 3; + + if (info->sdma_ip_version >= SDMA_7_0) { + return info_dword | (mip_max - 1) << 16 | mip_id << 24; + } else if (info->sdma_ip_version >= SDMA_5_0) { + return info_dword | dimension << 9 | (mip_max - 1) << 16 | mip_id << 20; + } else { + return info_dword | dimension << 9 | tiled->surf->u.gfx9.epitch << 16; + } + } else { + const uint32_t tile_index = tiled->surf->u.legacy.tiling_index[0]; + const uint32_t macro_tile_index = tiled->surf->u.legacy.macro_tile_index; + const uint32_t tile_mode = info->si_tile_mode_array[tile_index]; + const uint32_t macro_tile_mode = info->cik_macrotile_mode_array[macro_tile_index]; + + return element_size | + (G_009910_ARRAY_MODE(tile_mode) << 3) | + (G_009910_MICRO_TILE_MODE_NEW(tile_mode) << 8) | + /* Non-depth modes don't have TILE_SPLIT set. */ + ((util_logbase2(tiled->surf->u.legacy.tile_split >> 6)) << 11) | + (G_009990_BANK_WIDTH(macro_tile_mode) << 15) | + (G_009990_BANK_HEIGHT(macro_tile_mode) << 18) | + (G_009990_NUM_BANKS(macro_tile_mode) << 21) | + (G_009990_MACRO_TILE_ASPECT(macro_tile_mode) << 24) | + (G_009910_PIPE_CONFIG(tile_mode) << 26); + } +} + +static uint32_t +ac_sdma_get_tiled_metadata_config(const struct radeon_info *info, + const struct ac_sdma_surf_tiled *tiled, + bool detile, bool tmz) +{ + const uint32_t data_format = ac_get_cb_format(info->gfx_level, tiled->format); + const uint32_t number_type = ac_get_cb_number_type(tiled->format); + const bool alpha_is_on_msb = ac_alpha_is_on_msb(info, tiled->format); + const uint32_t dcc_max_compressed_block_size = + tiled->surf->u.gfx9.color.dcc.max_compressed_block_size; + + if (info->sdma_ip_version >= SDMA_7_0) { + return SDMA7_DCC_DATA_FORMAT(data_format) | + SDMA7_DCC_NUM_TYPE(number_type) | + SDMA7_DCC_MAX_COM(dcc_max_compressed_block_size) | + SDMA7_DCC_READ_CM(2) | + SDMA7_DCC_MAX_UCOM(1) | + SDMA7_DCC_WRITE_CM(!detile); + } else { + const bool dcc_pipe_aligned = tiled->htile_enabled || + tiled->surf->u.gfx9.color.dcc.pipe_aligned; + + return SDMA5_DCC_DATA_FORMAT(data_format) | + SDMA5_DCC_ALPHA_IS_ON_MSB(alpha_is_on_msb) | + SDMA5_DCC_NUM_TYPE(number_type) | + SDMA5_DCC_SURF_TYPE(tiled->surf_type) | + SDMA5_DCC_MAX_COM(dcc_max_compressed_block_size) | + SDMA5_DCC_PIPE_ALIGNED(dcc_pipe_aligned) | + SDMA5_DCC_MAX_UCOM(V_028C78_MAX_BLOCK_SIZE_256B) | + SDMA5_DCC_WRITE_COMPRESS(!detile) | + SDMA5_DCC_TMZ(tmz); + } +} + +void +ac_emit_sdma_copy_tiled_sub_window(struct ac_cmdbuf *cs, const struct radeon_info *info, + const struct ac_sdma_surf_linear *linear, + const struct ac_sdma_surf_tiled *tiled, + bool detile, uint32_t width, uint32_t height, + uint32_t depth, bool tmz) +{ + const uint32_t header_dword = + ac_sdma_get_tiled_header_dword(info->sdma_ip_version, tiled); + const uint32_t info_dword = + ac_sdma_get_tiled_info_dword(info, tiled); + const bool dcc = tiled->is_compressed; + + /* Sanity checks. */ + const bool uses_depth = linear->offset.z != 0 || tiled->offset.z != 0 || depth != 1; + assert(util_is_power_of_two_nonzero(tiled->bpp)); + ac_sdma_check_pitches(linear->pitch, linear->slice_pitch, tiled->bpp, uses_depth); + if (!info->sdma_supports_compression) + assert(!tiled->is_compressed); + + ac_cmdbuf_begin(cs); + ac_cmdbuf_emit(SDMA_PACKET(SDMA_OPCODE_COPY, SDMA_COPY_SUB_OPCODE_TILED_SUB_WINDOW, (tmz ? 4 : 0)) | + dcc << 19 | detile << 31 | header_dword); + ac_cmdbuf_emit(tiled->va); + ac_cmdbuf_emit(tiled->va >> 32); + ac_cmdbuf_emit(tiled->offset.x | tiled->offset.y << 16); + ac_cmdbuf_emit(tiled->offset.z | (tiled->extent.width - 1) << 16); + ac_cmdbuf_emit((tiled->extent.height - 1) | (tiled->extent.depth - 1) << 16); + ac_cmdbuf_emit(info_dword); + ac_cmdbuf_emit(linear->va); + ac_cmdbuf_emit(linear->va >> 32); + ac_cmdbuf_emit(linear->offset.x | linear->offset.y << 16); + ac_cmdbuf_emit(linear->offset.z | (linear->pitch - 1) << 16); + ac_cmdbuf_emit(linear->slice_pitch - 1); + if (info->sdma_ip_version == SDMA_2_0) { + ac_cmdbuf_emit(width | (height << 16)); + ac_cmdbuf_emit(depth); + } else { + ac_cmdbuf_emit((width - 1) | (height - 1) << 16); + ac_cmdbuf_emit((depth - 1)); + } + + if (tiled->is_compressed) { + const uint32_t meta_config = + ac_sdma_get_tiled_metadata_config(info, tiled, detile, tmz); + + if (info->sdma_ip_version >= SDMA_7_0) { + ac_cmdbuf_emit(meta_config); + } else { + ac_cmdbuf_emit(tiled->meta_va); + ac_cmdbuf_emit(tiled->meta_va >> 32); + ac_cmdbuf_emit(meta_config); + } + } + + ac_cmdbuf_end(); +} diff --git a/src/amd/common/ac_cmdbuf_sdma.h b/src/amd/common/ac_cmdbuf_sdma.h index ffd8e695c93..dc4132db1eb 100644 --- a/src/amd/common/ac_cmdbuf_sdma.h +++ b/src/amd/common/ac_cmdbuf_sdma.h @@ -8,6 +8,9 @@ #ifndef AC_CMDBUF_SDMA_H #define AC_CMDBUF_SDMA_H +#include "util/format/u_format.h" + +struct radeon_info; struct ac_cmdbuf; #ifdef __cplusplus @@ -52,6 +55,41 @@ ac_emit_sdma_copy_linear_sub_window(struct ac_cmdbuf *cs, enum sdma_version sdma const struct ac_sdma_surf_linear *src, const struct ac_sdma_surf_linear *dst, uint32_t width, uint32_t height, uint32_t depth); + +struct ac_sdma_surf_tiled { + const struct radeon_surf *surf; + uint64_t va; + enum pipe_format format; + uint32_t bpp; + + struct { + uint32_t x; + uint32_t y; + uint32_t z; + } offset; + + struct { + uint32_t width; + uint32_t height; + uint32_t depth; + } extent; + + uint32_t first_level; + uint32_t num_levels; + + bool is_compressed; + uint64_t meta_va; + uint32_t surf_type; + bool htile_enabled; +}; + +void +ac_emit_sdma_copy_tiled_sub_window(struct ac_cmdbuf *cs, const struct radeon_info *info, + const struct ac_sdma_surf_linear *linear, + const struct ac_sdma_surf_tiled *tiled, + bool detile, uint32_t width, uint32_t height, + uint32_t depth, bool tmz); + #ifdef __cplusplus } #endif diff --git a/src/amd/vulkan/radv_sdma.c b/src/amd/vulkan/radv_sdma.c index 8a47ea55b52..9dac59804ec 100644 --- a/src/amd/vulkan/radv_sdma.c +++ b/src/amd/vulkan/radv_sdma.c @@ -50,22 +50,6 @@ radv_sdma_pitch_alignment(const struct radv_device *device, const unsigned bpp) return 4; } -ALWAYS_INLINE static void -radv_sdma_check_pitches(const unsigned pitch, const unsigned slice_pitch, const unsigned bpp, const bool uses_depth) -{ - ASSERTED const unsigned pitch_alignment = MAX2(1, 4 / bpp); - assert(pitch); - assert(pitch <= (1 << 14)); - assert(util_is_aligned(pitch, pitch_alignment)); - - if (uses_depth) { - ASSERTED const unsigned slice_pitch_alignment = 4; - assert(slice_pitch); - assert(slice_pitch <= (1 << 28)); - assert(util_is_aligned(slice_pitch, slice_pitch_alignment)); - } -} - ALWAYS_INLINE static enum gfx9_resource_type radv_sdma_surface_resource_type(const struct radv_device *const device, const struct radeon_surf *const surf) { @@ -292,7 +276,9 @@ radv_sdma_get_surf(const struct radv_device *const device, const struct radv_ima const uint64_t va = binding->addr; const uint32_t bpe = radv_sdma_get_bpe(image, subresource.aspectMask); struct radv_sdma_surf info = { + .surf = surf, .format = image->vk.format, + .aspect_format = vk_format_get_aspect_format(image->vk.format, subresource.aspectMask), .extent = { .width = vk_format_get_plane_width(image->vk.format, plane_idx, image->vk.extent.width), @@ -308,6 +294,7 @@ radv_sdma_get_surf(const struct radv_device *const device, const struct radv_ima .bpp = bpe, .blk_w = surf->blk_w, .blk_h = surf->blk_h, + .first_level = subresource.mipLevel, .mip_levels = image->vk.mip_levels, .micro_tile_mode = surf->micro_tile_mode, .texel_scale = radv_sdma_get_texel_scale(image), @@ -323,6 +310,8 @@ radv_sdma_get_surf(const struct radv_device *const device, const struct radv_ima info.pitch = surf->u.gfx9.pitch[subresource.mipLevel]; info.slice_pitch = surf->blk_w * surf->blk_h * surf->u.gfx9.surf_slice_size / bpe; } else { + const bool htile_enabled = radv_htile_enabled(image, subresource.mipLevel); + /* 1D resources should be linear. */ assert(surf->u.gfx9.resource_type != RADEON_RESOURCE_1D); @@ -334,13 +323,15 @@ radv_sdma_get_surf(const struct radv_device *const device, const struct radv_ima if (pdev->info.gfx_level >= GFX12) { info.is_compressed = binding->bo && binding->bo->gfx12_allow_dcc; } else if (pdev->info.sdma_supports_compression && - (radv_dcc_enabled(image, subresource.mipLevel) || radv_htile_enabled(image, subresource.mipLevel))) { + (radv_dcc_enabled(image, subresource.mipLevel) || htile_enabled)) { info.is_compressed = true; } if (info.is_compressed) { info.meta_va = va + surf->meta_offset; + info.surface_type = radv_sdma_surface_type_from_aspect_mask(subresource.aspectMask); info.meta_config = radv_sdma_get_metadata_config(device, image, surf, subresource); + info.htile_enabled = htile_enabled; } } @@ -444,54 +435,54 @@ radv_sdma_emit_copy_tiled_sub_window(const struct radv_device *device, struct ra const bool detile) { const struct radv_physical_device *pdev = radv_device_physical(device); - - if (!pdev->info.sdma_supports_compression) { - assert(!tiled->is_compressed); - } - const VkOffset3D linear_off = radv_sdma_pixel_offset_to_blocks(linear->offset, linear->blk_w, linear->blk_h); const VkOffset3D tiled_off = radv_sdma_pixel_offset_to_blocks(tiled->offset, tiled->blk_w, tiled->blk_h); const VkExtent3D tiled_ext = radv_sdma_pixel_extent_to_blocks(tiled->extent, tiled->blk_w, tiled->blk_h); const VkExtent3D ext = radv_sdma_pixel_extent_to_blocks(pix_extent, tiled->blk_w, tiled->blk_h); const unsigned linear_pitch = radv_sdma_pixels_to_blocks(linear->pitch, tiled->blk_w); const unsigned linear_slice_pitch = radv_sdma_pixel_area_to_blocks(linear->slice_pitch, tiled->blk_w, tiled->blk_h); - const bool dcc = tiled->is_compressed; - const bool uses_depth = linear_off.z != 0 || tiled_off.z != 0 || ext.depth != 1; - assert(util_is_power_of_two_nonzero(tiled->bpp)); - radv_sdma_check_pitches(linear_pitch, linear_slice_pitch, tiled->bpp, uses_depth); + const struct ac_sdma_surf_linear surf_linear = { + .va = linear->va, + .offset = + { + .x = linear_off.x, + .y = linear_off.y, + .z = linear_off.z, + }, + .pitch = linear_pitch, + .slice_pitch = linear_slice_pitch, + }; - ASSERTED unsigned cdw_end = radeon_check_space(device->ws, cs->b, 14 + (dcc ? 3 : 0)); + const struct ac_sdma_surf_tiled surf_tiled = { + .surf = tiled->surf, + .va = tiled->va, + .format = radv_format_to_pipe_format(tiled->aspect_format), + .bpp = tiled->bpp, + .offset = + { + .x = tiled_off.x, + .y = tiled_off.y, + .z = tiled_off.z, + }, + .extent = + { + .width = tiled_ext.width, + .height = tiled_ext.height, + .depth = tiled_ext.depth, + }, + .first_level = tiled->first_level, + .num_levels = tiled->mip_levels, + .is_compressed = tiled->is_compressed, + .surf_type = tiled->surface_type, + .meta_va = tiled->meta_va, + .htile_enabled = tiled->htile_enabled, - radeon_begin(cs); - radeon_emit(SDMA_PACKET(SDMA_OPCODE_COPY, SDMA_COPY_SUB_OPCODE_TILED_SUB_WINDOW, 0) | dcc << 19 | detile << 31 | - tiled->header_dword); - radeon_emit(tiled->va); - radeon_emit(tiled->va >> 32); - radeon_emit(tiled_off.x | tiled_off.y << 16); - radeon_emit(tiled_off.z | (tiled_ext.width - 1) << 16); - radeon_emit((tiled_ext.height - 1) | (tiled_ext.depth - 1) << 16); - radeon_emit(tiled->info_dword); - radeon_emit(linear->va); - radeon_emit(linear->va >> 32); - radeon_emit(linear_off.x | linear_off.y << 16); - radeon_emit(linear_off.z | (linear_pitch - 1) << 16); - radeon_emit(linear_slice_pitch - 1); - radeon_emit((ext.width - 1) | (ext.height - 1) << 16); - radeon_emit((ext.depth - 1)); + }; - if (tiled->is_compressed) { - if (pdev->info.sdma_ip_version >= SDMA_7_0) { - radeon_emit(tiled->meta_config | SDMA7_DCC_WRITE_CM(!detile)); - } else { - radeon_emit(tiled->meta_va); - radeon_emit(tiled->meta_va >> 32); - radeon_emit(tiled->meta_config | SDMA5_DCC_WRITE_COMPRESS(!detile)); - } - } - - radeon_end(); - assert(cs->b->cdw <= cdw_end); + radeon_check_space(device->ws, cs->b, 17); + ac_emit_sdma_copy_tiled_sub_window(cs->b, &pdev->info, &surf_linear, &surf_tiled, detile, ext.width, ext.height, + ext.depth, false); } static void diff --git a/src/amd/vulkan/radv_sdma.h b/src/amd/vulkan/radv_sdma.h index 098365a8bb4..55267ebef1b 100644 --- a/src/amd/vulkan/radv_sdma.h +++ b/src/amd/vulkan/radv_sdma.h @@ -16,13 +16,16 @@ extern "C" { #endif struct radv_sdma_surf { + const struct radeon_surf *surf; VkFormat format; /* Image format. */ + VkFormat aspect_format; /* Image subresource format. */ VkExtent3D extent; /* Image extent. */ VkOffset3D offset; /* Image offset. */ uint64_t va; /* Virtual address of image data. */ unsigned bpp; /* Bytes per pixel. */ unsigned blk_w; /* Image format block width in pixels. */ unsigned blk_h; /* Image format block height in pixels. */ + unsigned first_level; /* First mip level in the image. */ unsigned mip_levels; /* Mip levels in the image. */ uint8_t micro_tile_mode; /* Micro tile mode of the image. */ uint8_t texel_scale; /* Texel scale for 96-bit formats */ @@ -42,6 +45,8 @@ struct radv_sdma_surf { uint32_t header_dword; /* Extra bits for the copy packet header. */ uint32_t info_dword; /* Image information DWORD. */ bool is_compressed; + uint32_t surface_type; + bool htile_enabled; }; }; }; diff --git a/src/gallium/drivers/radeonsi/si_sdma_copy_image.c b/src/gallium/drivers/radeonsi/si_sdma_copy_image.c index df4653c0587..0042102b65f 100644 --- a/src/gallium/drivers/radeonsi/si_sdma_copy_image.c +++ b/src/gallium/drivers/radeonsi/si_sdma_copy_image.c @@ -33,26 +33,6 @@ static unsigned minify_as_blocks(unsigned width, unsigned level, unsigned blk_w) return DIV_ROUND_UP(width, blk_w); } -static unsigned encode_legacy_tile_info(struct si_context *sctx, struct si_texture *tex) -{ - struct radeon_info *info = &sctx->screen->info; - unsigned tile_index = tex->surface.u.legacy.tiling_index[0]; - unsigned macro_tile_index = tex->surface.u.legacy.macro_tile_index; - unsigned tile_mode = info->si_tile_mode_array[tile_index]; - unsigned macro_tile_mode = info->cik_macrotile_mode_array[macro_tile_index]; - - return util_logbase2(tex->surface.bpe) | - (G_009910_ARRAY_MODE(tile_mode) << 3) | - (G_009910_MICRO_TILE_MODE_NEW(tile_mode) << 8) | - /* Non-depth modes don't have TILE_SPLIT set. */ - ((util_logbase2(tex->surface.u.legacy.tile_split >> 6)) << 11) | - (G_009990_BANK_WIDTH(macro_tile_mode) << 15) | - (G_009990_BANK_HEIGHT(macro_tile_mode) << 18) | - (G_009990_NUM_BANKS(macro_tile_mode) << 21) | - (G_009990_MACRO_TILE_ASPECT(macro_tile_mode) << 24) | - (G_009910_PIPE_CONFIG(tile_mode) << 26); -} - static bool si_sdma_v4_v5_copy_texture(struct si_context *sctx, struct si_texture *sdst, struct si_texture *ssrc) { @@ -130,60 +110,49 @@ static bool si_sdma_v4_v5_copy_texture(struct si_context *sctx, struct si_textur linear_address += linear->surface.u.gfx9.offset[0]; - radeon_begin(cs); - radeon_emit( - SDMA_PACKET(SDMA_OPCODE_COPY, - SDMA_COPY_SUB_OPCODE_TILED_SUB_WINDOW, - (tmz ? 4 : 0)) | - dcc << 19 | - (is_v5 ? 0 : tiled->buffer.b.b.last_level) << 20 | - (linear == sdst ? 1u : 0) << 31); - radeon_emit((uint32_t)tiled_address | (tiled->surface.tile_swizzle << 8)); - radeon_emit((uint32_t)(tiled_address >> 32)); - radeon_emit(0); - radeon_emit(((tiled_width - 1) << 16)); - radeon_emit((tiled_height - 1)); - radeon_emit(util_logbase2(bpp) | - tiled->surface.u.gfx9.swizzle_mode << 3 | - (is_v7 ? 0 : tiled->surface.u.gfx9.resource_type << 9) | - (is_v5 ? tiled->buffer.b.b.last_level : tiled->surface.u.gfx9.epitch) << 16); - radeon_emit((uint32_t)linear_address); - radeon_emit((uint32_t)(linear_address >> 32)); - radeon_emit(0); - radeon_emit(((linear_pitch - 1) << 16)); - radeon_emit(linear_slice_pitch - 1); - radeon_emit((copy_width - 1) | ((copy_height - 1) << 16)); - radeon_emit(0); + const uint64_t md_address = dcc ? tiled_address + tiled->surface.meta_offset : 0; + const bool detile = linear == sdst; - if (dcc) { - unsigned data_format = ac_get_cb_format(sctx->gfx_level, tiled->buffer.b.b.format); - unsigned number_type = ac_get_cb_number_type(tiled->buffer.b.b.format); + const struct ac_sdma_surf_linear surf_linear = { + .va = linear_address, + .offset = + { + .x = 0, + .y = 0, + .z = 0, + }, + .pitch = linear_pitch, + .slice_pitch = linear_slice_pitch, + }; - if (is_v7) { - radeon_emit(SDMA7_DCC_DATA_FORMAT(data_format) | - SDMA7_DCC_NUM_TYPE(number_type) | - SDMA7_DCC_READ_CM(2) | - SDMA7_DCC_WRITE_CM(1) | - SDMA7_DCC_MAX_COM(tiled->surface.u.gfx9.color.dcc.max_compressed_block_size) | - SDMA7_DCC_MAX_UCOM(1)); - } else { - /* Add metadata */ - uint64_t md_address = tiled_address + tiled->surface.meta_offset; + const struct ac_sdma_surf_tiled surf_tiled = { + .surf = &tiled->surface, + .va = tiled_address | (tiled->surface.tile_swizzle << 8), + .format = tiled->buffer.b.b.format, + .bpp = bpp, + .offset = + { + .x = 0, + .y = 0, + .z = 0, + }, + .extent = { + .width = tiled_width, + .height = tiled_height, + .depth = 1, + }, + .first_level = 0, + .num_levels = tiled->buffer.b.b.last_level + 1, + .is_compressed = dcc, + .surf_type = 0, + .meta_va = md_address, + .htile_enabled = false, + }; + + ac_emit_sdma_copy_tiled_sub_window(&cs->current, &sctx->screen->info, + &surf_linear, &surf_tiled, detile, + copy_width, copy_height, 1, tmz); - radeon_emit((uint32_t)md_address); - radeon_emit((uint32_t)(md_address >> 32)); - radeon_emit(SDMA5_DCC_DATA_FORMAT(data_format) | - SDMA5_DCC_ALPHA_IS_ON_MSB(ac_alpha_is_on_msb(&sctx->screen->info, tiled->buffer.b.b.format)) | - SDMA5_DCC_NUM_TYPE(number_type) | - SDMA5_DCC_SURF_TYPE(0) | - SDMA5_DCC_MAX_COM(tiled->surface.u.gfx9.color.dcc.max_compressed_block_size) | - SDMA5_DCC_MAX_UCOM(V_028C78_MAX_BLOCK_SIZE_256B) | - SDMA5_DCC_WRITE_COMPRESS(tiled == sdst) | - SDMA5_DCC_TMZ(tmz) | - SDMA5_DCC_PIPE_ALIGNED(tiled->surface.u.gfx9.color.dcc.pipe_aligned)); - } - } - radeon_end(); return true; } @@ -362,31 +331,45 @@ bool cik_sdma_copy_texture(struct si_context *sctx, struct si_texture *sdst, str linear_slice_pitch <= (1 << 28) && copy_width_aligned <= (1 << 14) && copy_height <= (1 << 14)) { struct radeon_cmdbuf *cs = sctx->sdma_cs; - uint32_t direction = linear == sdst ? 1u << 31 : 0; + const bool detile = linear == sdst; - radeon_begin(cs); - radeon_emit(SDMA_PACKET(SDMA_OPCODE_COPY, - SDMA_COPY_SUB_OPCODE_TILED_SUB_WINDOW, 0) | - direction); - radeon_emit(tiled_address); - radeon_emit(tiled_address >> 32); - radeon_emit(0); - radeon_emit(pitch_tile_max << 16); - radeon_emit(slice_tile_max); - radeon_emit(encode_legacy_tile_info(sctx, tiled)); - radeon_emit(linear_address); - radeon_emit(linear_address >> 32); - radeon_emit(0); - radeon_emit(((linear_pitch - 1) << 16)); - radeon_emit(linear_slice_pitch - 1); - if (sctx->gfx_level == GFX7) { - radeon_emit(copy_width_aligned | (copy_height << 16)); - radeon_emit(1); - } else { - radeon_emit((copy_width_aligned - 1) | ((copy_height - 1) << 16)); - radeon_emit(0); - } - radeon_end(); + const struct ac_sdma_surf_linear surf_linear = { + .va = linear_address, + .offset = + { + .x = 0, + .y = 0, + .z = 0, + }, + .pitch = linear_pitch, + .slice_pitch = linear_slice_pitch, + }; + + const struct ac_sdma_surf_tiled surf_tiled = { + .surf = &tiled->surface, + .va = tiled_address, + .bpp = bpp, + .offset = + { + .x = 0, + .y = 0, + .z = 0, + }, + .extent = + { + .width = pitch_tile_max + 1, + .height = slice_tile_max + 1, + .depth = 1, + }, + .first_level = 0, + .num_levels = 1, + .is_compressed = false, + .htile_enabled = false, + }; + + ac_emit_sdma_copy_tiled_sub_window(&cs->current, info, &surf_linear, + &surf_tiled, detile, copy_width_aligned, + copy_height, 1, false); return true; } }