ac,radv,radeonsi: introduce a helper to build a sampler descriptor

This introduces ac_sampler_state which contains all information to
build a sampler descriptor for AMD hardware instead of duplicating
code between RADV and RadeonSI. Both drivers just need to fill this
new struct to get a descriptor.

This allows RADV to get GFX12 support for free. I think we should
introduce helpers for other type of descriptors.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29221>
This commit is contained in:
Samuel Pitoiset 2024-05-15 15:45:21 +02:00 committed by Marge Bot
parent cd05b23a95
commit 7fe169dd4a
5 changed files with 156 additions and 72 deletions

View File

@ -0,0 +1,64 @@
/*
* Copyright 2015 Advanced Micro Devices, Inc.
* Copyright 2024 Valve Corporation
*
* SPDX-License-Identifier: MIT
*/
#include "ac_descriptors.h"
#include "sid.h"
#include "util/u_math.h"
void
ac_build_sampler_descriptor(const enum amd_gfx_level gfx_level, const struct ac_sampler_state *state, uint32_t desc[4])
{
const unsigned perf_mip = state->max_aniso_ratio ? state->max_aniso_ratio + 6 : 0;
const bool compat_mode = gfx_level == GFX8 || gfx_level == GFX9;
desc[0] = S_008F30_CLAMP_X(state->address_mode_u) |
S_008F30_CLAMP_Y(state->address_mode_v) |
S_008F30_CLAMP_Z(state->address_mode_w) |
S_008F30_MAX_ANISO_RATIO(state->max_aniso_ratio) |
S_008F30_DEPTH_COMPARE_FUNC(state->depth_compare_func) |
S_008F30_FORCE_UNNORMALIZED(state->unnormalized_coords) |
S_008F30_ANISO_THRESHOLD(state->max_aniso_ratio >> 1) |
S_008F30_ANISO_BIAS(state->max_aniso_ratio) |
S_008F30_DISABLE_CUBE_WRAP(!state->cube_wrap) |
S_008F30_COMPAT_MODE(compat_mode) |
S_008F30_TRUNC_COORD(state->trunc_coord) |
S_008F30_FILTER_MODE(state->filter_mode);
desc[1] = 0;
desc[2] = S_008F38_XY_MAG_FILTER(state->mag_filter) |
S_008F38_XY_MIN_FILTER(state->min_filter) |
S_008F38_MIP_FILTER(state->mip_filter);
desc[3] = S_008F3C_BORDER_COLOR_TYPE(state->border_color_type);
if (gfx_level >= GFX12) {
desc[1] |= S_008F34_MIN_LOD_GFX12(util_unsigned_fixed(CLAMP(state->min_lod, 0, 17), 8)) |
S_008F34_MAX_LOD_GFX12(util_unsigned_fixed(CLAMP(state->max_lod, 0, 17), 8));
desc[2] |= S_008F38_PERF_MIP_LO(perf_mip);
desc[3] |= S_008F3C_PERF_MIP_HI(perf_mip >> 2);
} else {
desc[1] |= S_008F34_MIN_LOD_GFX6(util_unsigned_fixed(CLAMP(state->min_lod, 0, 15), 8)) |
S_008F34_MAX_LOD_GFX6(util_unsigned_fixed(CLAMP(state->max_lod, 0, 15), 8)) |
S_008F34_PERF_MIP(perf_mip);
}
if (gfx_level >= GFX10) {
desc[2] |= S_008F38_LOD_BIAS(util_signed_fixed(CLAMP(state->lod_bias, -32, 31), 8)) |
S_008F38_ANISO_OVERRIDE_GFX10(!state->aniso_single_level);
} else {
desc[2] |= S_008F38_LOD_BIAS(util_signed_fixed(CLAMP(state->lod_bias, -16, 16), 8)) |
S_008F38_DISABLE_LSB_CEIL(gfx_level <= GFX8) |
S_008F38_FILTER_PREC_FIX(1) |
S_008F38_ANISO_OVERRIDE_GFX8(gfx_level >= GFX8 && !state->aniso_single_level);
}
if (gfx_level >= GFX11) {
desc[3] |= S_008F3C_BORDER_COLOR_PTR_GFX11(state->border_color_ptr);
} else {
desc[3] |= S_008F3C_BORDER_COLOR_PTR_GFX6(state->border_color_ptr);
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2015 Advanced Micro Devices, Inc.
* Copyright 2024 Valve Corporation
*
* SPDX-License-Identifier: MIT
*/
#ifndef AC_DESCRIPTORS_H
#define AC_DESCRIPTORS_H
#include "ac_gpu_info.h"
#ifdef __cplusplus
extern "C" {
#endif
struct ac_sampler_state {
unsigned address_mode_u : 3;
unsigned address_mode_v : 3;
unsigned address_mode_w : 3;
unsigned max_aniso_ratio : 3;
unsigned depth_compare_func : 3;
unsigned unnormalized_coords : 1;
unsigned cube_wrap : 1;
unsigned trunc_coord : 1;
unsigned filter_mode : 2;
unsigned mag_filter : 2;
unsigned min_filter : 2;
unsigned mip_filter : 2;
unsigned aniso_single_level : 1;
unsigned border_color_type : 2;
unsigned border_color_ptr : 12;
float min_lod;
float max_lod;
float lod_bias;
};
void
ac_build_sampler_descriptor(const enum amd_gfx_level gfx_level,
const struct ac_sampler_state *state,
uint32_t desc[4]);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -82,6 +82,8 @@ amd_common_files = files(
'ac_surface.h',
'ac_debug.c',
'ac_debug.h',
'ac_descriptors.c',
'ac_descriptors.h',
'ac_formats.c',
'ac_formats.h',
'ac_shadowed_regs.c',

View File

@ -10,6 +10,8 @@
#include "vk_log.h"
#include "ac_descriptors.h"
#include "radv_sampler.h"
#include "radv_device.h"
#include "radv_entrypoints.h"
@ -186,7 +188,6 @@ radv_init_sampler(struct radv_device *device, struct radv_sampler *sampler, cons
const struct radv_instance *instance = radv_physical_device_instance(pdev);
uint32_t max_aniso = radv_get_max_anisotropy(device, pCreateInfo);
uint32_t max_aniso_ratio = radv_tex_aniso_filter(max_aniso);
bool compat_mode = pdev->info.gfx_level == GFX8 || pdev->info.gfx_level == GFX9;
unsigned filter_mode = radv_tex_filter_mode(sampler->vk.reduction_mode);
unsigned depth_compare_func = V_008F30_SQ_TEX_DEPTH_COMPARE_NEVER;
bool trunc_coord = ((pCreateInfo->minFilter == VK_FILTER_NEAREST && pCreateInfo->magFilter == VK_FILTER_NEAREST) ||
@ -217,37 +218,28 @@ radv_init_sampler(struct radv_device *device, struct radv_sampler *sampler, cons
/* If we don't have a custom color, set the ptr to 0 */
border_color_ptr = sampler->border_color_slot != RADV_BORDER_COLOR_COUNT ? sampler->border_color_slot : 0;
sampler->state[0] = (S_008F30_CLAMP_X(radv_tex_wrap(pCreateInfo->addressModeU)) |
S_008F30_CLAMP_Y(radv_tex_wrap(pCreateInfo->addressModeV)) |
S_008F30_CLAMP_Z(radv_tex_wrap(pCreateInfo->addressModeW)) |
S_008F30_MAX_ANISO_RATIO(max_aniso_ratio) | S_008F30_DEPTH_COMPARE_FUNC(depth_compare_func) |
S_008F30_FORCE_UNNORMALIZED(pCreateInfo->unnormalizedCoordinates ? 1 : 0) |
S_008F30_ANISO_THRESHOLD(max_aniso_ratio >> 1) | S_008F30_ANISO_BIAS(max_aniso_ratio) |
S_008F30_DISABLE_CUBE_WRAP(disable_cube_wrap) | S_008F30_COMPAT_MODE(compat_mode) |
S_008F30_FILTER_MODE(filter_mode) | S_008F30_TRUNC_COORD(trunc_coord));
sampler->state[1] = (S_008F34_MIN_LOD_GFX6(util_unsigned_fixed(CLAMP(pCreateInfo->minLod, 0, 15), 8)) |
S_008F34_MAX_LOD_GFX6(util_unsigned_fixed(CLAMP(pCreateInfo->maxLod, 0, 15), 8)) |
S_008F34_PERF_MIP(max_aniso_ratio ? max_aniso_ratio + 6 : 0));
sampler->state[2] = (S_008F38_XY_MAG_FILTER(radv_tex_filter(pCreateInfo->magFilter, max_aniso)) |
S_008F38_XY_MIN_FILTER(radv_tex_filter(pCreateInfo->minFilter, max_aniso)) |
S_008F38_MIP_FILTER(radv_tex_mipfilter(pCreateInfo->mipmapMode)));
sampler->state[3] = S_008F3C_BORDER_COLOR_TYPE(radv_tex_bordercolor(border_color));
struct ac_sampler_state ac_state = {
.address_mode_u = radv_tex_wrap(pCreateInfo->addressModeU),
.address_mode_v = radv_tex_wrap(pCreateInfo->addressModeV),
.address_mode_w = radv_tex_wrap(pCreateInfo->addressModeW),
.max_aniso_ratio = max_aniso_ratio,
.depth_compare_func = depth_compare_func,
.unnormalized_coords = pCreateInfo->unnormalizedCoordinates ? 1 : 0,
.cube_wrap = !disable_cube_wrap,
.trunc_coord = trunc_coord,
.filter_mode = filter_mode,
.mag_filter = radv_tex_filter(pCreateInfo->magFilter, max_aniso),
.min_filter = radv_tex_filter(pCreateInfo->minFilter, max_aniso),
.mip_filter = radv_tex_mipfilter(pCreateInfo->mipmapMode),
.min_lod = pCreateInfo->minLod,
.max_lod = pCreateInfo->maxLod,
.lod_bias = pCreateInfo->mipLodBias,
.aniso_single_level = !instance->drirc.disable_aniso_single_level,
.border_color_type = radv_tex_bordercolor(border_color),
.border_color_ptr = border_color_ptr,
};
if (pdev->info.gfx_level >= GFX10) {
sampler->state[2] |= S_008F38_LOD_BIAS(util_signed_fixed(CLAMP(pCreateInfo->mipLodBias, -32, 31), 8)) |
S_008F38_ANISO_OVERRIDE_GFX10(instance->drirc.disable_aniso_single_level);
} else {
sampler->state[2] |=
S_008F38_LOD_BIAS(util_signed_fixed(CLAMP(pCreateInfo->mipLodBias, -16, 16), 8)) |
S_008F38_DISABLE_LSB_CEIL(pdev->info.gfx_level <= GFX8) | S_008F38_FILTER_PREC_FIX(1) |
S_008F38_ANISO_OVERRIDE_GFX8(instance->drirc.disable_aniso_single_level && pdev->info.gfx_level >= GFX8);
}
if (pdev->info.gfx_level >= GFX11) {
sampler->state[3] |= S_008F3C_BORDER_COLOR_PTR_GFX11(border_color_ptr);
} else {
sampler->state[3] |= S_008F3C_BORDER_COLOR_PTR_GFX6(border_color_ptr);
}
ac_build_sampler_descriptor(pdev->info.gfx_level, &ac_state, sampler->state);
}
VKAPI_ATTR VkResult VKAPI_CALL

View File

@ -18,6 +18,7 @@
#include "util/u_upload_mgr.h"
#include "util/u_blend.h"
#include "ac_descriptors.h"
#include "ac_formats.h"
#include "gfx10_format_table.h"
@ -5470,7 +5471,6 @@ static void *si_create_sampler_state(struct pipe_context *ctx,
struct si_sampler_state *rstate = CALLOC_STRUCT(si_sampler_state);
unsigned max_aniso = sscreen->force_aniso >= 0 ? sscreen->force_aniso : state->max_anisotropy;
unsigned max_aniso_ratio = si_tex_aniso_filter(max_aniso);
unsigned perf_mip = max_aniso_ratio ? max_aniso_ratio + 6 : 0;
bool trunc_coord = (state->min_img_filter == PIPE_TEX_FILTER_NEAREST &&
state->mag_img_filter == PIPE_TEX_FILTER_NEAREST &&
state->compare_mode == PIPE_TEX_COMPARE_NONE) ||
@ -5502,47 +5502,26 @@ static void *si_create_sampler_state(struct pipe_context *ctx,
state->border_color_is_integer,
&border_color_ptr);
rstate->val[0] =
(S_008F30_CLAMP_X(si_tex_wrap(state->wrap_s)) | S_008F30_CLAMP_Y(si_tex_wrap(state->wrap_t)) |
S_008F30_CLAMP_Z(si_tex_wrap(state->wrap_r)) | S_008F30_MAX_ANISO_RATIO(max_aniso_ratio) |
S_008F30_DEPTH_COMPARE_FUNC(si_tex_compare(state->compare_mode, state->compare_func)) |
S_008F30_FORCE_UNNORMALIZED(state->unnormalized_coords) |
S_008F30_ANISO_THRESHOLD(max_aniso_ratio >> 1) | S_008F30_ANISO_BIAS(max_aniso_ratio) |
S_008F30_DISABLE_CUBE_WRAP(!state->seamless_cube_map) |
S_008F30_TRUNC_COORD(trunc_coord));
rstate->val[1] = 0;
rstate->val[2] = (S_008F38_XY_MAG_FILTER(si_tex_filter(state->mag_img_filter, max_aniso)) |
S_008F38_XY_MIN_FILTER(si_tex_filter(state->min_img_filter, max_aniso)) |
S_008F38_MIP_FILTER(si_tex_mipfilter(state->min_mip_filter)));
rstate->val[3] = S_008F3C_BORDER_COLOR_TYPE(border_color_type);
struct ac_sampler_state ac_state = {
.address_mode_u = si_tex_wrap(state->wrap_s),
.address_mode_v = si_tex_wrap(state->wrap_t),
.address_mode_w = si_tex_wrap(state->wrap_r),
.max_aniso_ratio = max_aniso_ratio,
.depth_compare_func = si_tex_compare(state->compare_mode, state->compare_func),
.unnormalized_coords = state->unnormalized_coords,
.cube_wrap = state->seamless_cube_map,
.trunc_coord = trunc_coord,
.mag_filter = si_tex_filter(state->mag_img_filter, max_aniso),
.min_filter = si_tex_filter(state->min_img_filter, max_aniso),
.mip_filter = si_tex_mipfilter(state->min_mip_filter),
.min_lod = state->min_lod,
.max_lod = state->max_lod,
.lod_bias = state->lod_bias,
.border_color_type = border_color_type,
.border_color_ptr = border_color_ptr,
};
if (sscreen->info.gfx_level >= GFX12) {
rstate->val[1] |= S_008F34_MIN_LOD_GFX12(S_FIXED(CLAMP(state->min_lod, 0, 17), 8)) |
S_008F34_MAX_LOD_GFX12(S_FIXED(CLAMP(state->max_lod, 0, 17), 8));
rstate->val[2] |= S_008F38_PERF_MIP_LO(perf_mip);
rstate->val[3] |= S_008F3C_PERF_MIP_HI(perf_mip >> 2);
} else {
rstate->val[1] |= S_008F34_MIN_LOD_GFX6(S_FIXED(CLAMP(state->min_lod, 0, 15), 8)) |
S_008F34_MAX_LOD_GFX6(S_FIXED(CLAMP(state->max_lod, 0, 15), 8)) |
S_008F34_PERF_MIP(perf_mip);
}
if (sscreen->info.gfx_level >= GFX10) {
rstate->val[2] |= S_008F38_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -32, 31), 8)) |
S_008F38_ANISO_OVERRIDE_GFX10(1);
} else {
rstate->val[0] |= S_008F30_COMPAT_MODE(sctx->gfx_level >= GFX8);
rstate->val[2] |= S_008F38_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 8)) |
S_008F38_DISABLE_LSB_CEIL(sctx->gfx_level <= GFX8) |
S_008F38_FILTER_PREC_FIX(1) |
S_008F38_ANISO_OVERRIDE_GFX8(sctx->gfx_level >= GFX8);
}
if (sscreen->info.gfx_level >= GFX11) {
rstate->val[3] |= S_008F3C_BORDER_COLOR_PTR_GFX11(border_color_ptr);
} else {
rstate->val[3] |= S_008F3C_BORDER_COLOR_PTR_GFX6(border_color_ptr);
}
ac_build_sampler_descriptor(sscreen->info.gfx_level, &ac_state, rstate->val);
/* Create sampler resource for upgraded depth textures. */
memcpy(rstate->upgraded_depth_val, rstate->val, sizeof(rstate->val));