ac,radv,radeonsi: add a function to build texture descriptors

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29321>
This commit is contained in:
Samuel Pitoiset 2024-05-17 11:25:21 +02:00 committed by Marge Bot
parent 4bb308d403
commit 8cb2cad434
4 changed files with 376 additions and 262 deletions

View file

@ -6,6 +6,7 @@
*/
#include "ac_descriptors.h"
#include "ac_gpu_info.h"
#include "ac_formats.h"
#include "ac_surface.h"
@ -324,6 +325,222 @@ ac_build_fmask_descriptor(const enum amd_gfx_level gfx_level, const struct ac_fm
}
}
static void
ac_build_gfx6_texture_descriptor(const struct radeon_info *info, const struct ac_texture_state *state, uint32_t desc[8])
{
const struct util_format_description *fmt_desc = util_format_description(state->format);
uint32_t num_format, data_format, num_samples;
int first_non_void;
num_samples = fmt_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS ? MAX2(1, state->num_samples)
: MAX2(1, state->num_storage_samples);
first_non_void = util_format_get_first_non_void_channel(state->format);
num_format = ac_translate_tex_numformat(fmt_desc, first_non_void);
data_format = ac_translate_tex_dataformat(info, fmt_desc, first_non_void);
if (data_format == ~0) {
data_format = 0;
}
/* S8 with either Z16 or Z32 HTILE need a special format. */
if (info->gfx_level == GFX9 && state->format == PIPE_FORMAT_S8_UINT && state->tc_compat_htile_enabled) {
if (state->img_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ||
state->img_format == PIPE_FORMAT_Z24_UNORM_S8_UINT ||
state->img_format == PIPE_FORMAT_S8_UINT_Z24_UNORM) {
data_format = V_008F14_IMG_DATA_FORMAT_S8_32;
} else if (state->img_format == PIPE_FORMAT_Z16_UNORM_S8_UINT) {
data_format = V_008F14_IMG_DATA_FORMAT_S8_16;
}
}
desc[0] = 0;
desc[1] = S_008F14_MIN_LOD(util_unsigned_fixed(CLAMP(state->min_lod, 0, 15), 8)) |
S_008F14_DATA_FORMAT(data_format) |
S_008F14_NUM_FORMAT(num_format);
desc[2] = S_008F18_WIDTH(state->width - 1) |
S_008F18_HEIGHT(state->height - 1) |
S_008F18_PERF_MOD(4);
desc[3] = S_008F1C_DST_SEL_X(ac_map_swizzle(state->swizzle[0])) |
S_008F1C_DST_SEL_Y(ac_map_swizzle(state->swizzle[1])) |
S_008F1C_DST_SEL_Z(ac_map_swizzle(state->swizzle[2])) |
S_008F1C_DST_SEL_W(ac_map_swizzle(state->swizzle[3])) |
S_008F1C_BASE_LEVEL(num_samples > 1 ? 0 : state->first_level) |
S_008F1C_LAST_LEVEL(num_samples > 1 ? util_logbase2(num_samples) : state->last_level) |
S_008F1C_TYPE(state->type);
desc[4] = 0;
desc[5] = S_008F24_BASE_ARRAY(state->first_layer);
desc[6] = 0;
desc[7] = 0;
if (info->gfx_level == GFX9) {
const uint32_t bc_swizzle = ac_border_color_swizzle(fmt_desc);
/* Depth is the last accessible layer on Gfx9.
* The hw doesn't need to know the total number of layers.
*/
if (state->type == V_008F1C_SQ_RSRC_IMG_3D)
desc[4] |= S_008F20_DEPTH(state->depth - 1);
else
desc[4] |= S_008F20_DEPTH(state->last_layer);
desc[4] |= S_008F20_BC_SWIZZLE(bc_swizzle);
desc[5] |= S_008F24_MAX_MIP(num_samples > 1 ? util_logbase2(num_samples) : state->num_levels - 1);
} else {
desc[3] |= S_008F1C_POW2_PAD(state->num_levels > 1);
desc[4] |= S_008F20_DEPTH(state->depth - 1);
desc[5] |= S_008F24_LAST_ARRAY(state->last_layer);
}
if (state->dcc_enabled) {
desc[6] = S_008F28_ALPHA_IS_ON_MSB(ac_alpha_is_on_msb(info, state->format));
} else {
if (!state->aniso_single_level) {
/* The last dword is unused by hw. The shader uses it to clear
* bits in the first dword of sampler state.
*/
if (info->gfx_level <= GFX7 && state->num_samples <= 1) {
if (state->first_level == state->last_level)
desc[7] = C_008F30_MAX_ANISO_RATIO;
else
desc[7] = 0xffffffff;
}
}
}
}
static uint32_t
ac_get_gfx10_img_format(const enum amd_gfx_level gfx_level, const struct ac_texture_state *state)
{
const struct gfx10_format *fmt = &ac_get_gfx10_format_table(gfx_level)[state->format];
const struct util_format_description *desc = util_format_description(state->format);
uint32_t img_format = fmt->img_format;
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
state->gfx10.upgraded_depth && !util_format_has_stencil(desc)) {
if (gfx_level >= GFX11) {
assert(img_format == V_008F0C_GFX11_FORMAT_32_FLOAT);
img_format = V_008F0C_GFX11_FORMAT_32_FLOAT_CLAMP;
} else {
assert(img_format == V_008F0C_GFX10_FORMAT_32_FLOAT);
img_format = V_008F0C_GFX10_FORMAT_32_FLOAT_CLAMP;
}
}
return img_format;
}
static void
ac_build_gfx10_texture_descriptor(const struct radeon_info *info, const struct ac_texture_state *state, uint32_t desc[8])
{
const struct radeon_surf *surf = state->surf;
const struct util_format_description *fmt_desc = util_format_description(state->format);
const uint32_t img_format = ac_get_gfx10_img_format(info->gfx_level, state);
const struct ac_surf_nbc_view *nbc_view = state->gfx9.nbc_view;
const uint32_t field_last_level = state->num_samples > 1 ? util_logbase2(state->num_samples) : state->last_level;
desc[0] = 0;
desc[1] = S_00A004_FORMAT_GFX10(img_format) |
S_00A004_WIDTH_LO(state->width - 1);
desc[2] = S_00A008_WIDTH_HI((state->width - 1) >> 2) |
S_00A008_HEIGHT(state->height - 1) |
S_00A008_RESOURCE_LEVEL(info->gfx_level < GFX11);
desc[3] = S_00A00C_DST_SEL_X(ac_map_swizzle(state->swizzle[0])) |
S_00A00C_DST_SEL_Y(ac_map_swizzle(state->swizzle[1])) |
S_00A00C_DST_SEL_Z(ac_map_swizzle(state->swizzle[2])) |
S_00A00C_DST_SEL_W(ac_map_swizzle(state->swizzle[3])) |
S_00A00C_BASE_LEVEL(state->num_samples > 1 ? 0 : state->first_level) |
S_00A00C_LAST_LEVEL_GFX10(field_last_level) |
S_00A00C_BC_SWIZZLE(ac_border_color_swizzle(fmt_desc)) |
S_00A00C_TYPE(state->type);
/* Depth is the the last accessible layer on gfx9+. The hw doesn't need
* to know the total number of layers.
*/
desc[4] = S_00A010_DEPTH_GFX10(state->depth) |
S_00A010_BASE_ARRAY(state->first_layer);
/* ARRAY_PITCH is only meaningful for 3D images, 0 means SRV, 1 means UAV.
* In SRV mode, BASE_ARRAY is ignored and DEPTH is the last slice of mipmap level 0.
* In UAV mode, BASE_ARRAY is the first slice and DEPTH is the last slice of the bound level.
*/
desc[5] = S_00A014_ARRAY_PITCH(state->gfx10.uav3d) | S_00A014_PERF_MOD(4);
desc[6] = 0;
desc[7] = 0;
uint32_t max_mip = state->num_samples > 1 ? util_logbase2(state->num_samples) : state->num_levels - 1;
if (nbc_view && nbc_view->valid)
max_mip = nbc_view->num_levels - 1;
const uint32_t min_lod_clamped = util_unsigned_fixed(CLAMP(state->min_lod, 0, 15), 8);
if (info->gfx_level >= GFX11) {
desc[1] |= S_00A004_MAX_MIP_GFX11(max_mip);
desc[5] |= S_00A014_MIN_LOD_LO_GFX11(min_lod_clamped);
desc[6] |= S_00A018_MIN_LOD_HI(min_lod_clamped >> 5);
} else {
desc[1] |= S_00A004_MIN_LOD(min_lod_clamped);
desc[5] |= S_00A014_MAX_MIP(max_mip);
}
if (state->dcc_enabled) {
desc[6] |= S_00A018_MAX_UNCOMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_256B) |
S_00A018_MAX_COMPRESSED_BLOCK_SIZE(surf->u.gfx9.color.dcc.max_compressed_block_size) |
S_00A018_ALPHA_IS_ON_MSB(ac_alpha_is_on_msb(info, state->format));
}
}
static void
ac_build_gfx12_texture_descriptor(const struct radeon_info *info, const struct ac_texture_state *state, uint32_t desc[8])
{
const struct radeon_surf *surf = state->surf;
const struct util_format_description *fmt_desc = util_format_description(state->format);
const uint32_t img_format = ac_get_gfx10_img_format(info->gfx_level, state);
const uint32_t max_mip = state->num_samples > 1 ? util_logbase2(state->num_samples) : state->num_levels - 1;
const uint32_t field_last_level = state->num_samples > 1 ? util_logbase2(state->num_samples) : state->last_level;
const bool no_edge_clamp = state->num_levels > 1 && util_format_is_compressed(state->img_format) &&
!util_format_is_compressed(state->format);
desc[0] = 0;
desc[1] = S_00A004_MAX_MIP_GFX12(max_mip) |
S_00A004_FORMAT_GFX12(img_format) |
S_00A004_BASE_LEVEL(state->num_samples > 1 ? 0 : state->first_level) |
S_00A004_WIDTH_LO(state->width - 1);
desc[2] = S_00A008_WIDTH_HI((state->width - 1) >> 2) |
S_00A008_HEIGHT(state->height - 1);
desc[3] = S_00A00C_DST_SEL_X(ac_map_swizzle(state->swizzle[0])) |
S_00A00C_DST_SEL_Y(ac_map_swizzle(state->swizzle[1])) |
S_00A00C_DST_SEL_Z(ac_map_swizzle(state->swizzle[2])) |
S_00A00C_DST_SEL_W(ac_map_swizzle(state->swizzle[3])) |
S_00A00C_NO_EDGE_CLAMP(no_edge_clamp) |
S_00A00C_LAST_LEVEL_GFX12(field_last_level) |
S_00A00C_BC_SWIZZLE(ac_border_color_swizzle(fmt_desc)) |
S_00A00C_TYPE(state->type);
/* Depth is the the last accessible layer on gfx9+. The hw doesn't need
* to know the total number of layers.
*/
desc[4] = S_00A010_DEPTH_GFX12(state->depth) |
S_00A010_BASE_ARRAY(state->first_layer);
desc[5] = S_00A014_UAV3D(state->gfx10.uav3d) |
S_00A014_PERF_MOD(4);
desc[6] = S_00A018_MAX_UNCOMPRESSED_BLOCK_SIZE(1 /*256B*/) |
S_00A018_MAX_COMPRESSED_BLOCK_SIZE(surf->u.gfx9.color.dcc.max_compressed_block_size);
desc[7] = 0;
}
void
ac_build_texture_descriptor(const struct radeon_info *info, const struct ac_texture_state *state, uint32_t desc[8])
{
if (info->gfx_level >= GFX12) {
ac_build_gfx12_texture_descriptor(info, state, desc);
} else if (info->gfx_level >= GFX10) {
ac_build_gfx10_texture_descriptor(info, state, desc);
} else {
ac_build_gfx6_texture_descriptor(info, state, desc);
}
}
uint32_t
ac_tile_mode_index(const struct radeon_surf *surf, unsigned level, bool stencil)
{

View file

@ -66,6 +66,43 @@ ac_build_fmask_descriptor(const enum amd_gfx_level gfx_level,
const struct ac_fmask_state *state,
uint32_t desc[8]);
struct ac_texture_state {
struct radeon_surf *surf;
enum pipe_format format;
enum pipe_format img_format;
uint32_t width : 17;
uint32_t height : 17;
uint32_t depth : 15;
uint32_t type : 4;
enum pipe_swizzle swizzle[4];
uint32_t num_samples : 5;
uint32_t num_storage_samples : 5;
uint32_t first_level : 4;
uint32_t last_level : 5;
uint32_t num_levels : 6;
uint32_t first_layer : 14;
uint32_t last_layer : 13;
float min_lod;
struct {
uint32_t uav3d : 1;
uint32_t upgraded_depth : 1;
} gfx10;
struct {
const struct ac_surf_nbc_view *nbc_view;
} gfx9;
uint32_t dcc_enabled : 1;
uint32_t tc_compat_htile_enabled : 1;
uint32_t aniso_single_level : 1;
};
void
ac_build_texture_descriptor(const struct radeon_info *info,
const struct ac_texture_state *state,
uint32_t desc[8]);
uint32_t
ac_tile_mode_index(const struct radeon_surf *surf,
unsigned level,

View file

@ -105,7 +105,6 @@ gfx10_make_texture_descriptor(struct radv_device *device, struct radv_image *ima
const struct util_format_description *desc;
enum pipe_swizzle swizzle[4];
unsigned array_pitch = 0;
unsigned img_format;
unsigned type;
/* For emulated ETC2 without alpha we need to override the format to a 3-componenent format, so
@ -119,8 +118,6 @@ gfx10_make_texture_descriptor(struct radv_device *device, struct radv_image *ima
desc = util_format_description(format);
img_format = ac_get_gfx10_format_table(pdev->info.gfx_level)[format].img_format;
radv_compose_swizzle(desc, mapping, swizzle);
if (create_2d_view_of_3d) {
@ -158,48 +155,42 @@ gfx10_make_texture_descriptor(struct radv_device *device, struct radv_image *ima
array_pitch = 1;
}
state[0] = 0;
state[1] = S_00A004_FORMAT_GFX10(img_format) | S_00A004_WIDTH_LO(width - 1);
state[2] = S_00A008_WIDTH_HI((width - 1) >> 2) | S_00A008_HEIGHT(height - 1) |
S_00A008_RESOURCE_LEVEL(pdev->info.gfx_level < GFX11);
state[3] = S_00A00C_DST_SEL_X(ac_map_swizzle(swizzle[0])) | S_00A00C_DST_SEL_Y(ac_map_swizzle(swizzle[1])) |
S_00A00C_DST_SEL_Z(ac_map_swizzle(swizzle[2])) | S_00A00C_DST_SEL_W(ac_map_swizzle(swizzle[3])) |
S_00A00C_BASE_LEVEL(image->vk.samples > 1 ? 0 : first_level) |
S_00A00C_LAST_LEVEL_GFX10(image->vk.samples > 1 ? util_logbase2(image->vk.samples) : last_level) |
S_00A00C_BC_SWIZZLE(ac_border_color_swizzle(desc)) | S_00A00C_TYPE(type);
/* Depth is the the last accessible layer on gfx9+. The hw doesn't need
* to know the total number of layers.
*/
state[4] =
S_00A010_DEPTH_GFX10(type == V_008F1C_SQ_RSRC_IMG_3D ? depth - 1 : last_layer) | S_00A010_BASE_ARRAY(first_layer);
/* ARRAY_PITCH is only meaningful for 3D images, 0 means SRV, 1 means UAV.
* In SRV mode, BASE_ARRAY is ignored and DEPTH is the last slice of mipmap level 0.
* In UAV mode, BASE_ARRAY is the first slice and DEPTH is the last slice of the bound level.
*/
state[5] = S_00A014_ARRAY_PITCH(array_pitch) | S_00A014_PERF_MOD(4);
state[6] = 0;
state[7] = 0;
const struct ac_texture_state tex_state = {
.surf = &image->planes[0].surface,
.format = format,
.img_format = vk_format_to_pipe_format(image->vk.format),
.width = width,
.height = height,
.depth = type == V_008F1C_SQ_RSRC_IMG_3D ? depth - 1 : last_layer,
.type = type,
.swizzle =
{
swizzle[0],
swizzle[1],
swizzle[2],
swizzle[3],
},
.num_samples = image->vk.samples,
.num_storage_samples = image->vk.samples,
.first_level = first_level,
.last_level = last_level,
.num_levels = image->vk.mip_levels,
.first_layer = first_layer,
.last_layer = last_layer,
.min_lod = min_lod,
.gfx10 =
{
.uav3d = array_pitch,
},
.gfx9 =
{
.nbc_view = nbc_view,
},
.dcc_enabled = radv_dcc_enabled(image, first_level),
.tc_compat_htile_enabled = radv_image_is_tc_compat_htile(image),
};
unsigned max_mip = image->vk.samples > 1 ? util_logbase2(image->vk.samples) : image->vk.mip_levels - 1;
if (nbc_view && nbc_view->valid)
max_mip = nbc_view->num_levels - 1;
unsigned min_lod_clamped = util_unsigned_fixed(CLAMP(min_lod, 0, 15), 8);
if (pdev->info.gfx_level >= GFX11) {
state[1] |= S_00A004_MAX_MIP_GFX11(max_mip);
state[5] |= S_00A014_MIN_LOD_LO_GFX11(min_lod_clamped);
state[6] |= S_00A018_MIN_LOD_HI(min_lod_clamped >> 5);
} else {
state[1] |= S_00A004_MIN_LOD(min_lod_clamped);
state[5] |= S_00A014_MAX_MIP(max_mip);
}
if (radv_dcc_enabled(image, first_level)) {
state[6] |=
S_00A018_MAX_UNCOMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_256B) |
S_00A018_MAX_COMPRESSED_BLOCK_SIZE(image->planes[0].surface.u.gfx9.color.dcc.max_compressed_block_size) |
S_00A018_ALPHA_IS_ON_MSB(ac_alpha_is_on_msb(&pdev->info, format));
}
ac_build_texture_descriptor(&pdev->info, &tex_state, &state[0]);
/* Initialize the sampler view for FMASK. */
if (fmask_state) {
@ -245,8 +236,7 @@ gfx6_make_texture_descriptor(struct radv_device *device, struct radv_image *imag
enum pipe_format format = vk_format_to_pipe_format(vk_format);
const struct util_format_description *desc;
enum pipe_swizzle swizzle[4];
int first_non_void;
unsigned num_format, data_format, type;
unsigned type;
/* For emulated ETC2 without alpha we need to override the format to a 3-componenent format, so
* that border colors work correctly (alpha forced to 1). Since Vulkan has no such format,
@ -261,23 +251,6 @@ gfx6_make_texture_descriptor(struct radv_device *device, struct radv_image *imag
radv_compose_swizzle(desc, mapping, swizzle);
first_non_void = util_format_get_first_non_void_channel(format);
num_format = radv_translate_tex_numformat(desc, first_non_void);
data_format = radv_translate_tex_dataformat(pdev, desc, first_non_void);
if (data_format == ~0) {
data_format = 0;
}
/* S8 with either Z16 or Z32 HTILE need a special format. */
if (pdev->info.gfx_level == GFX9 && format == PIPE_FORMAT_S8_UINT && radv_image_is_tc_compat_htile(image)) {
if (image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT)
data_format = V_008F14_IMG_DATA_FORMAT_S8_32;
else if (image->vk.format == VK_FORMAT_D16_UNORM_S8_UINT)
data_format = V_008F14_IMG_DATA_FORMAT_S8_16;
}
if (pdev->info.gfx_level == GFX9 && create_2d_view_of_3d) {
assert(image->vk.image_type == VK_IMAGE_TYPE_3D);
type = V_008F1C_SQ_RSRC_IMG_3D;
@ -295,54 +268,35 @@ gfx6_make_texture_descriptor(struct radv_device *device, struct radv_image *imag
} else if (type == V_008F1C_SQ_RSRC_IMG_CUBE)
depth = image->vk.array_layers / 6;
state[0] = 0;
state[1] = (S_008F14_MIN_LOD(util_unsigned_fixed(CLAMP(min_lod, 0, 15), 8)) | S_008F14_DATA_FORMAT(data_format) |
S_008F14_NUM_FORMAT(num_format));
state[2] = (S_008F18_WIDTH(width - 1) | S_008F18_HEIGHT(height - 1) | S_008F18_PERF_MOD(4));
state[3] = (S_008F1C_DST_SEL_X(ac_map_swizzle(swizzle[0])) | S_008F1C_DST_SEL_Y(ac_map_swizzle(swizzle[1])) |
S_008F1C_DST_SEL_Z(ac_map_swizzle(swizzle[2])) | S_008F1C_DST_SEL_W(ac_map_swizzle(swizzle[3])) |
S_008F1C_BASE_LEVEL(image->vk.samples > 1 ? 0 : first_level) |
S_008F1C_LAST_LEVEL(image->vk.samples > 1 ? util_logbase2(image->vk.samples) : last_level) |
S_008F1C_TYPE(type));
state[4] = 0;
state[5] = S_008F24_BASE_ARRAY(first_layer);
state[6] = 0;
state[7] = 0;
const struct ac_texture_state tex_state = {
.surf = &image->planes[0].surface,
.format = format,
.img_format = vk_format_to_pipe_format(image->vk.format),
.width = width,
.height = height,
.depth = depth,
.type = type,
.swizzle =
{
swizzle[0],
swizzle[1],
swizzle[2],
swizzle[3],
},
.num_samples = image->vk.samples,
.num_storage_samples = image->vk.samples,
.first_level = first_level,
.last_level = last_level,
.num_levels = image->vk.mip_levels,
.first_layer = first_layer,
.last_layer = last_layer,
.min_lod = min_lod,
.dcc_enabled = radv_dcc_enabled(image, first_level),
.tc_compat_htile_enabled = radv_image_is_tc_compat_htile(image),
.aniso_single_level = !instance->drirc.disable_aniso_single_level,
};
if (pdev->info.gfx_level == GFX9) {
unsigned bc_swizzle = ac_border_color_swizzle(desc);
/* Depth is 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->vk.samples > 1 ? util_logbase2(image->vk.samples) : image->vk.mip_levels - 1);
} else {
state[3] |= S_008F1C_POW2_PAD(image->vk.mip_levels > 1);
state[4] |= S_008F20_DEPTH(depth - 1);
state[5] |= S_008F24_LAST_ARRAY(last_layer);
}
if (radv_dcc_enabled(image, first_level)) {
state[6] = S_008F28_ALPHA_IS_ON_MSB(ac_alpha_is_on_msb(&pdev->info, format));
} else {
if (instance->drirc.disable_aniso_single_level) {
/* The last dword is unused by hw. The shader uses it to clear
* bits in the first dword of sampler state.
*/
if (pdev->info.gfx_level <= GFX7 && image->vk.samples <= 1) {
if (first_level == last_level)
state[7] = C_008F30_MAX_ANISO_RATIO;
else
state[7] = 0xffffffff;
}
}
}
ac_build_texture_descriptor(&pdev->info, &tex_state, &state[0]);
/* Initialize the sampler view for FMASK. */
if (fmask_state) {
@ -351,7 +305,7 @@ gfx6_make_texture_descriptor(struct radv_device *device, struct radv_image *imag
assert(image->plane_count == 1);
const struct ac_fmask_state ac_state = {
const struct ac_fmask_state ac_fmask_state = {
.surf = &image->planes[0].surface,
.va = gpu_address + image->bindings[0].offset,
.width = width,
@ -365,7 +319,7 @@ gfx6_make_texture_descriptor(struct radv_device *device, struct radv_image *imag
.tc_compat_cmask = radv_image_is_tc_compat_cmask(image),
};
ac_build_fmask_descriptor(pdev->info.gfx_level, &ac_state, &fmask_state[0]);
ac_build_fmask_descriptor(pdev->info.gfx_level, &ac_fmask_state, &fmask_state[0]);
} else
memset(fmask_state, 0, 8 * 4);
}

View file

@ -3865,25 +3865,21 @@ static void gfx10_make_texture_descriptor(
struct pipe_resource *res = &tex->buffer.b.b;
const struct util_format_description *desc;
unsigned img_format;
unsigned char swizzle[4];
unsigned type;
desc = util_format_description(pipe_format);
img_format = ac_get_gfx10_format_table(screen->info.gfx_level)[pipe_format].img_format;
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
const unsigned char swizzle_xxxx[4] = {0, 0, 0, 0};
const unsigned char swizzle_yyyy[4] = {1, 1, 1, 1};
const unsigned char swizzle_wwww[4] = {3, 3, 3, 3};
bool is_stencil = false;
switch (pipe_format) {
case PIPE_FORMAT_S8_UINT_Z24_UNORM:
case PIPE_FORMAT_X32_S8X24_UINT:
case PIPE_FORMAT_X8Z24_UNORM:
util_format_compose_swizzles(swizzle_yyyy, state_swizzle, swizzle);
is_stencil = true;
break;
case PIPE_FORMAT_X24S8_UINT:
/*
@ -3892,21 +3888,9 @@ static void gfx10_make_texture_descriptor(
* GL45-CTS.texture_cube_map_array.sampling on GFX8.
*/
util_format_compose_swizzles(swizzle_wwww, state_swizzle, swizzle);
is_stencil = true;
break;
default:
util_format_compose_swizzles(swizzle_xxxx, state_swizzle, swizzle);
is_stencil = pipe_format == PIPE_FORMAT_S8_UINT;
}
if (tex->upgraded_depth && !is_stencil) {
if (screen->info.gfx_level >= GFX11) {
assert(img_format == V_008F0C_GFX11_FORMAT_32_FLOAT);
img_format = V_008F0C_GFX11_FORMAT_32_FLOAT_CLAMP;
} else {
assert(img_format == V_008F0C_GFX10_FORMAT_32_FLOAT);
img_format = V_008F0C_GFX10_FORMAT_32_FLOAT_CLAMP;
}
}
} else {
util_format_compose_swizzles(desc->swizzle, state_swizzle, swizzle);
@ -3930,79 +3914,36 @@ static void gfx10_make_texture_descriptor(
} else if (type == V_008F1C_SQ_RSRC_IMG_CUBE)
depth = res->array_size / 6;
if (screen->info.gfx_level >= GFX12) {
unsigned max_mip = res->nr_samples > 1 ? util_logbase2(res->nr_samples) :
tex->buffer.b.b.last_level;
unsigned field_last_level = res->nr_samples > 1 ? util_logbase2(res->nr_samples) : last_level;
unsigned field_depth = (type == V_008F1C_SQ_RSRC_IMG_3D && sampler) ? depth - 1 : last_layer;
const struct ac_texture_state tex_state = {
.surf = &tex->surface,
.format = pipe_format,
.img_format = res->format,
.width = width,
.height = height,
.depth = (type == V_008F1C_SQ_RSRC_IMG_3D && sampler) ? depth - 1 : last_layer,
.type = type,
.swizzle =
{
swizzle[0],
swizzle[1],
swizzle[2],
swizzle[3],
},
.num_samples = res->nr_samples,
.num_storage_samples = res->nr_storage_samples,
.first_level = first_level,
.last_level = last_level,
.num_levels = res->last_level + 1,
.first_layer = first_layer,
.last_layer = last_layer,
.gfx10 = {
.uav3d = !!(type == V_008F1C_SQ_RSRC_IMG_3D && !sampler),
.upgraded_depth = tex->upgraded_depth,
},
.dcc_enabled = vi_dcc_enabled(tex, first_level),
};
state[0] = 0;
state[1] = S_00A004_MAX_MIP_GFX12(max_mip) |
S_00A004_FORMAT_GFX12(img_format) |
S_00A004_BASE_LEVEL(res->nr_samples > 1 ? 0 : first_level) |
S_00A004_WIDTH_LO(width - 1);
state[2] = S_00A008_WIDTH_HI((width - 1) >> 2) |
S_00A008_HEIGHT(height - 1);
state[3] = S_00A00C_DST_SEL_X(ac_map_swizzle(swizzle[0])) |
S_00A00C_DST_SEL_Y(ac_map_swizzle(swizzle[1])) |
S_00A00C_DST_SEL_Z(ac_map_swizzle(swizzle[2])) |
S_00A00C_DST_SEL_W(ac_map_swizzle(swizzle[3])) |
S_00A00C_NO_EDGE_CLAMP(res->last_level > 0 &&
util_format_is_compressed(res->format) &&
!util_format_is_compressed(pipe_format)) |
S_00A00C_LAST_LEVEL_GFX12(field_last_level) |
S_00A00C_BC_SWIZZLE(ac_border_color_swizzle(desc)) |
S_00A00C_TYPE(type);
/* Depth is the the last accessible layer on gfx9+. The hw doesn't need
* to know the total number of layers.
*/
state[4] = S_00A010_DEPTH_GFX12(field_depth) |
S_00A010_BASE_ARRAY(first_layer);
state[5] = S_00A014_UAV3D(type == V_008F1C_SQ_RSRC_IMG_3D && !sampler) |
S_00A014_PERF_MOD(4);
state[6] = S_00A018_MAX_UNCOMPRESSED_BLOCK_SIZE(1 /*256B*/) |
S_00A018_MAX_COMPRESSED_BLOCK_SIZE(tex->surface.u.gfx9.color.dcc.max_compressed_block_size);
state[7] = 0;
} else {
state[0] = 0;
state[1] = S_00A004_FORMAT_GFX10(img_format) | S_00A004_WIDTH_LO(width - 1);
state[2] = S_00A008_WIDTH_HI((width - 1) >> 2) | S_00A008_HEIGHT(height - 1) |
S_00A008_RESOURCE_LEVEL(screen->info.gfx_level < GFX11);
state[3] =
S_00A00C_DST_SEL_X(ac_map_swizzle(swizzle[0])) |
S_00A00C_DST_SEL_Y(ac_map_swizzle(swizzle[1])) |
S_00A00C_DST_SEL_Z(ac_map_swizzle(swizzle[2])) |
S_00A00C_DST_SEL_W(ac_map_swizzle(swizzle[3])) |
S_00A00C_BASE_LEVEL(res->nr_samples > 1 ? 0 : first_level) |
S_00A00C_LAST_LEVEL_GFX10(res->nr_samples > 1 ? util_logbase2(res->nr_samples) : last_level) |
S_00A00C_BC_SWIZZLE(ac_border_color_swizzle(desc)) | S_00A00C_TYPE(type);
/* Depth is the the last accessible layer on gfx9+. The hw doesn't need
* to know the total number of layers.
*/
state[4] =
S_00A010_DEPTH_GFX10((type == V_008F1C_SQ_RSRC_IMG_3D && sampler) ? depth - 1 : last_layer) |
S_00A010_BASE_ARRAY(first_layer);
state[5] = S_00A014_ARRAY_PITCH(!!(type == V_008F1C_SQ_RSRC_IMG_3D && !sampler)) |
S_00A014_PERF_MOD(4);
unsigned max_mip = res->nr_samples > 1 ? util_logbase2(res->nr_samples) :
tex->buffer.b.b.last_level;
if (screen->info.gfx_level >= GFX11) {
state[1] |= S_00A004_MAX_MIP_GFX11(max_mip);
} else {
state[5] |= S_00A014_MAX_MIP(max_mip);
}
state[6] = 0;
state[7] = 0;
if (vi_dcc_enabled(tex, first_level)) {
state[6] |= S_00A018_MAX_UNCOMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_256B) |
S_00A018_MAX_COMPRESSED_BLOCK_SIZE(tex->surface.u.gfx9.color.dcc.max_compressed_block_size) |
S_00A018_ALPHA_IS_ON_MSB(ac_alpha_is_on_msb(&screen->info, pipe_format));
}
}
ac_build_texture_descriptor(&screen->info, &tex_state, &state[0]);
/* Initialize the sampler view for FMASK. */
if (tex->surface.fmask_offset) {
@ -4045,8 +3986,7 @@ static void si_make_texture_descriptor(struct si_screen *screen, struct si_textu
struct pipe_resource *res = &tex->buffer.b.b;
const struct util_format_description *desc;
unsigned char swizzle[4];
int first_non_void;
unsigned num_format, data_format, type, num_samples;
unsigned type, num_samples;
desc = util_format_description(pipe_format);
@ -4082,19 +4022,6 @@ static void si_make_texture_descriptor(struct si_screen *screen, struct si_textu
util_format_compose_swizzles(desc->swizzle, state_swizzle, swizzle);
}
first_non_void = util_format_get_first_non_void_channel(pipe_format);
num_format = ac_translate_tex_numformat(desc, first_non_void);
data_format = si_translate_texformat(&screen->b, pipe_format, desc, first_non_void);
if (data_format == ~0) {
data_format = 0;
}
/* S8 with Z32 HTILE needs a special format. */
if (screen->info.gfx_level == GFX9 && pipe_format == PIPE_FORMAT_S8_UINT)
data_format = V_008F14_IMG_DATA_FORMAT_S8_32;
if (!sampler && (res->target == PIPE_TEXTURE_CUBE || res->target == PIPE_TEXTURE_CUBE_ARRAY ||
(screen->info.gfx_level <= GFX8 && res->target == PIPE_TEXTURE_3D))) {
/* For the purpose of shader images, treat cube maps and 3D
@ -4118,54 +4045,33 @@ static void si_make_texture_descriptor(struct si_screen *screen, struct si_textu
} else if (type == V_008F1C_SQ_RSRC_IMG_CUBE)
depth = res->array_size / 6;
state[0] = 0;
state[1] = (S_008F14_DATA_FORMAT(data_format) | S_008F14_NUM_FORMAT(num_format));
state[2] = (S_008F18_WIDTH(width - 1) | S_008F18_HEIGHT(height - 1) | S_008F18_PERF_MOD(4));
state[3] = (S_008F1C_DST_SEL_X(ac_map_swizzle(swizzle[0])) |
S_008F1C_DST_SEL_Y(ac_map_swizzle(swizzle[1])) |
S_008F1C_DST_SEL_Z(ac_map_swizzle(swizzle[2])) |
S_008F1C_DST_SEL_W(ac_map_swizzle(swizzle[3])) |
S_008F1C_BASE_LEVEL(num_samples > 1 ? 0 : first_level) |
S_008F1C_LAST_LEVEL(num_samples > 1 ? util_logbase2(num_samples) : last_level) |
S_008F1C_TYPE(type));
state[4] = 0;
state[5] = S_008F24_BASE_ARRAY(first_layer);
state[6] = 0;
state[7] = 0;
const struct ac_texture_state tex_state = {
.surf = &tex->surface,
.format = pipe_format,
.img_format = res->format,
.width = width,
.height = height,
.depth = depth,
.type = type,
.swizzle =
{
swizzle[0],
swizzle[1],
swizzle[2],
swizzle[3],
},
.num_samples = res->nr_samples,
.num_storage_samples = res->nr_storage_samples,
.first_level = first_level,
.last_level = last_level,
.num_levels = res->last_level + 1,
.first_layer = first_layer,
.last_layer = last_layer,
.dcc_enabled = vi_dcc_enabled(tex, first_level),
.tc_compat_htile_enabled = true,
};
if (screen->info.gfx_level == GFX9) {
unsigned bc_swizzle = ac_border_color_swizzle(desc);
/* 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(num_samples > 1 ? util_logbase2(num_samples)
: tex->buffer.b.b.last_level);
} else {
state[3] |= S_008F1C_POW2_PAD(res->last_level > 0);
state[4] |= S_008F20_DEPTH(depth - 1);
state[5] |= S_008F24_LAST_ARRAY(last_layer);
}
if (vi_dcc_enabled(tex, first_level)) {
state[6] = S_008F28_ALPHA_IS_ON_MSB(ac_alpha_is_on_msb(&screen->info, pipe_format));
} else {
/* The last dword is unused by hw. The shader uses it to clear
* bits in the first dword of sampler state.
*/
if (screen->info.gfx_level <= GFX7 && res->nr_samples <= 1) {
if (first_level == last_level)
state[7] = C_008F30_MAX_ANISO_RATIO;
else
state[7] = 0xffffffff;
}
}
ac_build_texture_descriptor(&screen->info, &tex_state, &state[0]);
/* Initialize the sampler view for FMASK. */
if (tex->surface.fmask_offset) {