mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-30 13:40:23 +01:00
ac,radv,radeonsi: add ac_emit_sdma_copy_tiled_sub_window()
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38448>
This commit is contained in:
parent
5f8fa6ae03
commit
f5ecc5ffd5
5 changed files with 336 additions and 150 deletions
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue