mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 02:20:11 +01:00
radv: add texture descriptor/fmask/cmask support for GFX9
This adds gfx9 support for the texture descriptor along with the fmask/cmask allocation routines. Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
87b3799493
commit
b11c4a5546
1 changed files with 158 additions and 31 deletions
|
|
@ -196,27 +196,74 @@ si_set_mutable_tex_desc_fields(struct radv_device *device,
|
|||
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;
|
||||
uint64_t va = gpu_address;
|
||||
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_GFX6;
|
||||
state[6] &= C_008F28_COMPRESSION_EN;
|
||||
|
||||
assert(!(va & 255));
|
||||
enum chip_class chip_class = device->physical_device->rad_info.chip_class;
|
||||
uint64_t meta_va = 0;
|
||||
if (chip_class >= GFX9) {
|
||||
if (is_stencil)
|
||||
va += image->surface.u.gfx9.stencil_offset;
|
||||
else
|
||||
va += image->surface.u.gfx9.surf_offset;
|
||||
} else
|
||||
va += base_level_info->offset;
|
||||
|
||||
state[0] = va >> 8;
|
||||
state[1] &= C_008F14_BASE_ADDRESS_HI;
|
||||
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_GFX6(pitch - 1);
|
||||
|
||||
if (image->surface.dcc_size && first_level < image->surface.num_dcc_levels) {
|
||||
state[6] |= S_008F28_COMPRESSION_EN(1);
|
||||
state[7] = (gpu_address +
|
||||
image->dcc_offset +
|
||||
base_level_info->dcc_offset) >> 8;
|
||||
if (chip_class >= VI) {
|
||||
state[6] &= C_008F28_COMPRESSION_EN;
|
||||
state[7] = 0;
|
||||
if (image->surface.dcc_size && first_level < image->surface.num_dcc_levels) {
|
||||
uint64_t meta_va = gpu_address + image->dcc_offset;
|
||||
if (chip_class <= VI)
|
||||
meta_va += base_level_info->dcc_offset;
|
||||
state[6] |= S_008F28_COMPRESSION_EN(1);
|
||||
state[7] = meta_va >> 8;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (chip_class >= GFX9) {
|
||||
state[3] &= C_008F1C_SW_MODE;
|
||||
state[4] &= C_008F20_PITCH_GFX9;
|
||||
|
||||
if (is_stencil) {
|
||||
state[3] |= S_008F1C_SW_MODE(image->surface.u.gfx9.stencil.swizzle_mode);
|
||||
state[4] |= S_008F20_PITCH_GFX9(image->surface.u.gfx9.stencil.epitch);
|
||||
} else {
|
||||
state[3] |= S_008F1C_SW_MODE(image->surface.u.gfx9.surf.swizzle_mode);
|
||||
state[4] |= S_008F20_PITCH_GFX9(image->surface.u.gfx9.surf.epitch);
|
||||
}
|
||||
|
||||
state[5] &= C_008F24_META_DATA_ADDRESS &
|
||||
C_008F24_META_PIPE_ALIGNED &
|
||||
C_008F24_META_RB_ALIGNED;
|
||||
if (meta_va) {
|
||||
struct gfx9_surf_meta_flags meta;
|
||||
|
||||
if (image->dcc_offset)
|
||||
meta = image->surface.u.gfx9.dcc;
|
||||
else
|
||||
meta = image->surface.u.gfx9.htile;
|
||||
|
||||
state[5] |= S_008F24_META_DATA_ADDRESS(meta_va >> 40) |
|
||||
S_008F24_META_PIPE_ALIGNED(meta.pipe_aligned) |
|
||||
S_008F24_META_RB_ALIGNED(meta.rb_aligned);
|
||||
}
|
||||
} else {
|
||||
/* SI-CI-VI */
|
||||
unsigned pitch = base_level_info->nblk_x * block_width;
|
||||
unsigned index = si_tile_mode_index(image, base_level, is_stencil);
|
||||
|
||||
state[3] &= C_008F1C_TILING_INDEX;
|
||||
state[3] |= S_008F1C_TILING_INDEX(index);
|
||||
state[4] &= C_008F20_PITCH_GFX6;
|
||||
state[4] |= S_008F20_PITCH_GFX6(pitch - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -242,6 +289,36 @@ static unsigned radv_tex_dim(VkImageType image_type, VkImageViewType view_type,
|
|||
unreachable("illegale image type");
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned gfx9_border_color_swizzle(const unsigned char swizzle[4])
|
||||
{
|
||||
unsigned bc_swizzle = V_008F20_BC_SWIZZLE_XYZW;
|
||||
|
||||
if (swizzle[3] == VK_SWIZZLE_X) {
|
||||
/* For the pre-defined border color values (white, opaque
|
||||
* black, transparent black), the only thing that matters is
|
||||
* that the alpha channel winds up in the correct place
|
||||
* (because the RGB channels are all the same) so either of
|
||||
* these enumerations will work.
|
||||
*/
|
||||
if (swizzle[2] == VK_SWIZZLE_Y)
|
||||
bc_swizzle = V_008F20_BC_SWIZZLE_WZYX;
|
||||
else
|
||||
bc_swizzle = V_008F20_BC_SWIZZLE_WXYZ;
|
||||
} else if (swizzle[0] == VK_SWIZZLE_X) {
|
||||
if (swizzle[1] == VK_SWIZZLE_Y)
|
||||
bc_swizzle = V_008F20_BC_SWIZZLE_XYZW;
|
||||
else
|
||||
bc_swizzle = V_008F20_BC_SWIZZLE_XWYZ;
|
||||
} else if (swizzle[1] == VK_SWIZZLE_X) {
|
||||
bc_swizzle = V_008F20_BC_SWIZZLE_YXWZ;
|
||||
} else if (swizzle[2] == VK_SWIZZLE_X) {
|
||||
bc_swizzle = V_008F20_BC_SWIZZLE_ZYXW;
|
||||
}
|
||||
|
||||
return bc_swizzle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the sampler view descriptor for a texture.
|
||||
*/
|
||||
|
|
@ -314,11 +391,25 @@ si_make_texture_descriptor(struct radv_device *device,
|
|||
S_008F1C_TYPE(type));
|
||||
state[4] = 0;
|
||||
state[5] = S_008F24_BASE_ARRAY(first_layer);
|
||||
|
||||
state[6] = 0;
|
||||
state[7] = 0;
|
||||
|
||||
{
|
||||
if (device->physical_device->rad_info.chip_class >= GFX9) {
|
||||
unsigned bc_swizzle = gfx9_border_color_swizzle(desc->swizzle);
|
||||
|
||||
/* Depth is the the last accessible layer on Gfx9.
|
||||
* The hw doesn't need to know the total number of layers.
|
||||
*/
|
||||
if (type == V_008F1C_SQ_RSRC_IMG_3D)
|
||||
state[4] |= S_008F20_DEPTH(depth - 1);
|
||||
else
|
||||
state[4] |= S_008F20_DEPTH(last_layer);
|
||||
|
||||
state[4] |= S_008F20_BC_SWIZZLE(bc_swizzle);
|
||||
state[5] |= S_008F24_MAX_MIP(image->info.samples > 1 ?
|
||||
util_logbase2(image->info.samples) :
|
||||
last_level);
|
||||
} else {
|
||||
state[3] |= S_008F1C_POW2_PAD(image->info.levels > 1);
|
||||
state[4] |= S_008F20_DEPTH(depth - 1);
|
||||
state[5] |= S_008F24_LAST_ARRAY(last_layer);
|
||||
|
|
@ -341,31 +432,49 @@ si_make_texture_descriptor(struct radv_device *device,
|
|||
|
||||
/* Initialize the sampler view for FMASK. */
|
||||
if (image->fmask.size) {
|
||||
uint32_t fmask_format;
|
||||
uint32_t fmask_format, num_format;
|
||||
uint64_t gpu_address = device->ws->buffer_get_va(image->bo);
|
||||
uint64_t va;
|
||||
|
||||
va = gpu_address + image->offset + image->fmask.offset;
|
||||
|
||||
switch (image->info.samples) {
|
||||
case 2:
|
||||
fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S2_F2;
|
||||
break;
|
||||
case 4:
|
||||
fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S4_F4;
|
||||
break;
|
||||
case 8:
|
||||
fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK32_S8_F8;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
fmask_format = V_008F14_IMG_DATA_FORMAT_INVALID;
|
||||
if (device->physical_device->rad_info.chip_class >= GFX9) {
|
||||
fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK;
|
||||
switch (image->info.samples) {
|
||||
case 2:
|
||||
num_format = V_008F14_IMG_FMASK_8_2_2;
|
||||
break;
|
||||
case 4:
|
||||
num_format = V_008F14_IMG_FMASK_8_4_4;
|
||||
break;
|
||||
case 8:
|
||||
num_format = V_008F14_IMG_FMASK_32_8_8;
|
||||
break;
|
||||
default:
|
||||
unreachable("invalid nr_samples");
|
||||
}
|
||||
} else {
|
||||
switch (image->info.samples) {
|
||||
case 2:
|
||||
fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S2_F2;
|
||||
break;
|
||||
case 4:
|
||||
fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S4_F4;
|
||||
break;
|
||||
case 8:
|
||||
fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK32_S8_F8;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
fmask_format = V_008F14_IMG_DATA_FORMAT_INVALID;
|
||||
}
|
||||
num_format = V_008F14_IMG_NUM_FORMAT_UINT;
|
||||
}
|
||||
|
||||
fmask_state[0] = va >> 8;
|
||||
fmask_state[1] = S_008F14_BASE_ADDRESS_HI(va >> 40) |
|
||||
S_008F14_DATA_FORMAT_GFX6(fmask_format) |
|
||||
S_008F14_NUM_FORMAT_GFX6(V_008F14_IMG_NUM_FORMAT_UINT);
|
||||
S_008F14_NUM_FORMAT_GFX6(num_format);
|
||||
fmask_state[2] = S_008F18_WIDTH(width - 1) |
|
||||
S_008F18_HEIGHT(height - 1);
|
||||
fmask_state[3] = S_008F1C_DST_SEL_X(V_008F1C_SQ_SEL_X) |
|
||||
|
|
@ -378,7 +487,13 @@ si_make_texture_descriptor(struct radv_device *device,
|
|||
fmask_state[6] = 0;
|
||||
fmask_state[7] = 0;
|
||||
|
||||
{
|
||||
if (device->physical_device->rad_info.chip_class >= GFX9) {
|
||||
fmask_state[3] |= S_008F1C_SW_MODE(image->surface.u.gfx9.fmask.swizzle_mode);
|
||||
fmask_state[4] |= S_008F20_DEPTH(last_layer) |
|
||||
S_008F20_PITCH_GFX9(image->surface.u.gfx9.fmask.epitch);
|
||||
fmask_state[5] |= S_008F24_META_PIPE_ALIGNED(image->surface.u.gfx9.cmask.pipe_aligned) |
|
||||
S_008F24_META_RB_ALIGNED(image->surface.u.gfx9.cmask.rb_aligned);
|
||||
} else {
|
||||
fmask_state[3] |= S_008F1C_TILING_INDEX(image->fmask.tile_mode_index);
|
||||
fmask_state[4] |= S_008F20_DEPTH(depth - 1) |
|
||||
S_008F20_PITCH_GFX6(image->fmask.pitch_in_pixels - 1);
|
||||
|
|
@ -476,6 +591,12 @@ radv_image_get_fmask_info(struct radv_device *device,
|
|||
struct ac_surf_info info = image->info;
|
||||
memset(out, 0, sizeof(*out));
|
||||
|
||||
if (device->physical_device->rad_info.chip_class >= GFX9) {
|
||||
out->alignment = image->surface.u.gfx9.fmask_alignment;
|
||||
out->size = image->surface.u.gfx9.fmask_size;
|
||||
return;
|
||||
}
|
||||
|
||||
fmask.blk_w = image->surface.blk_w;
|
||||
fmask.blk_h = image->surface.blk_h;
|
||||
info.samples = 1;
|
||||
|
|
@ -533,6 +654,12 @@ radv_image_get_cmask_info(struct radv_device *device,
|
|||
unsigned num_pipes = device->physical_device->rad_info.num_tile_pipes;
|
||||
unsigned cl_width, cl_height;
|
||||
|
||||
if (device->physical_device->rad_info.chip_class >= GFX9) {
|
||||
out->alignment = image->surface.u.gfx9.cmask_alignment;
|
||||
out->size = image->surface.u.gfx9.cmask_size;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (num_pipes) {
|
||||
case 2:
|
||||
cl_width = 32;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue