ac/surface: move CB format translation helpers here

Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23216>
This commit is contained in:
Marek Olšák 2023-04-27 15:25:46 -04:00
parent 8642740aef
commit 78d5626d17
10 changed files with 130 additions and 252 deletions

View file

@ -3493,3 +3493,118 @@ nir_ssa_def *ac_nir_htile_addr_from_coord(nir_builder *b, const struct radeon_in
htile_pitch, htile_slice_size,
x, y, z, pipe_xor, NULL);
}
unsigned ac_get_cb_number_type(enum pipe_format format)
{
const struct util_format_description *desc = util_format_description(format);
int chan = util_format_get_first_non_void_channel(format);
if (chan == -1 || desc->channel[chan].type == UTIL_FORMAT_TYPE_FLOAT) {
return V_028C70_NUMBER_FLOAT;
} else {
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
return V_028C70_NUMBER_SRGB;
} else if (desc->channel[chan].type == UTIL_FORMAT_TYPE_SIGNED) {
return desc->channel[chan].pure_integer ? V_028C70_NUMBER_SINT : V_028C70_NUMBER_SNORM;
} else if (desc->channel[chan].type == UTIL_FORMAT_TYPE_UNSIGNED) {
return desc->channel[chan].pure_integer ? V_028C70_NUMBER_UINT : V_028C70_NUMBER_UNORM;
} else {
return V_028C70_NUMBER_UNORM;
}
}
}
unsigned ac_get_cb_format(enum amd_gfx_level gfx_level, enum pipe_format format)
{
const struct util_format_description *desc = util_format_description(format);
#define HAS_SIZE(x, y, z, w) \
(desc->channel[0].size == (x) && desc->channel[1].size == (y) && \
desc->channel[2].size == (z) && desc->channel[3].size == (w))
if (format == PIPE_FORMAT_R11G11B10_FLOAT) /* isn't plain */
return V_028C70_COLOR_10_11_11;
if (gfx_level >= GFX10_3 &&
format == PIPE_FORMAT_R9G9B9E5_FLOAT) /* isn't plain */
return V_028C70_COLOR_5_9_9_9;
if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
return V_028C70_COLOR_INVALID;
/* hw cannot support mixed formats (except depth/stencil, since
* stencil is not written to). */
if (desc->is_mixed && desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
return V_028C70_COLOR_INVALID;
int first_non_void = util_format_get_first_non_void_channel(format);
/* Reject SCALED formats because we don't implement them for CB. */
if (first_non_void >= 0 && first_non_void <= 3 &&
(desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_UNSIGNED ||
desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_SIGNED) &&
!desc->channel[first_non_void].normalized &&
!desc->channel[first_non_void].pure_integer)
return V_028C70_COLOR_INVALID;
switch (desc->nr_channels) {
case 1:
switch (desc->channel[0].size) {
case 8:
return V_028C70_COLOR_8;
case 16:
return V_028C70_COLOR_16;
case 32:
return V_028C70_COLOR_32;
}
break;
case 2:
if (desc->channel[0].size == desc->channel[1].size) {
switch (desc->channel[0].size) {
case 8:
return V_028C70_COLOR_8_8;
case 16:
return V_028C70_COLOR_16_16;
case 32:
return V_028C70_COLOR_32_32;
}
} else if (HAS_SIZE(8, 24, 0, 0)) {
return V_028C70_COLOR_24_8;
} else if (HAS_SIZE(24, 8, 0, 0)) {
return V_028C70_COLOR_8_24;
}
break;
case 3:
if (HAS_SIZE(5, 6, 5, 0)) {
return V_028C70_COLOR_5_6_5;
} else if (HAS_SIZE(32, 8, 24, 0)) {
return V_028C70_COLOR_X24_8_32_FLOAT;
}
break;
case 4:
if (desc->channel[0].size == desc->channel[1].size &&
desc->channel[0].size == desc->channel[2].size &&
desc->channel[0].size == desc->channel[3].size) {
switch (desc->channel[0].size) {
case 4:
return V_028C70_COLOR_4_4_4_4;
case 8:
return V_028C70_COLOR_8_8_8_8;
case 16:
return V_028C70_COLOR_16_16_16_16;
case 32:
return V_028C70_COLOR_32_32_32_32;
}
} else if (HAS_SIZE(5, 5, 5, 1)) {
return V_028C70_COLOR_1_5_5_5;
} else if (HAS_SIZE(1, 5, 5, 5)) {
return V_028C70_COLOR_5_5_5_1;
} else if (HAS_SIZE(10, 10, 10, 2)) {
return V_028C70_COLOR_2_10_10_10;
} else if (HAS_SIZE(2, 10, 10, 10)) {
return V_028C70_COLOR_10_10_10_2;
}
break;
}
return V_028C70_COLOR_INVALID;
}

View file

@ -485,6 +485,8 @@ void ac_surface_print_info(FILE *out, const struct radeon_info *info,
bool ac_surface_supports_dcc_image_stores(enum amd_gfx_level gfx_level,
const struct radeon_surf *surf);
unsigned ac_get_cb_number_type(enum pipe_format format);
unsigned ac_get_cb_format(enum amd_gfx_level gfx_level, enum pipe_format format);
#ifdef AC_SURFACE_INCLUDE_NIR
nir_ssa_def *ac_nir_dcc_addr_from_coord(nir_builder *b, const struct radeon_info *info,

View file

@ -1565,9 +1565,8 @@ radv_initialise_color_surface(struct radv_device *device, struct radv_color_buff
cb->cb_color_fmask = cb->cb_color_base;
}
ntype = radv_translate_color_numformat(iview->vk.format, desc,
vk_format_get_first_non_void_channel(iview->vk.format));
format = radv_translate_colorformat(iview->vk.format);
ntype = ac_get_cb_number_type(desc->format);
format = ac_get_cb_format(device->physical_device->rad_info.gfx_level, desc->format);
assert(format != V_028C70_COLOR_INVALID);
swap = radv_translate_colorswap(iview->vk.format, false);

View file

@ -463,39 +463,6 @@ radv_translate_tex_numformat(VkFormat format, const struct util_format_descripti
}
}
uint32_t
radv_translate_color_numformat(VkFormat format, const struct util_format_description *desc,
int first_non_void)
{
unsigned ntype;
assert(vk_format_get_plane_count(format) == 1);
if (first_non_void == -1 || desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_FLOAT)
ntype = V_028C70_NUMBER_FLOAT;
else {
ntype = V_028C70_NUMBER_UNORM;
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
ntype = V_028C70_NUMBER_SRGB;
else if (desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_SIGNED) {
if (desc->channel[first_non_void].pure_integer) {
ntype = V_028C70_NUMBER_SINT;
} else if (desc->channel[first_non_void].normalized) {
ntype = V_028C70_NUMBER_SNORM;
} else
ntype = ~0u;
} else if (desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_UNSIGNED) {
if (desc->channel[first_non_void].pure_integer) {
ntype = V_028C70_NUMBER_UINT;
} else if (desc->channel[first_non_void].normalized) {
ntype = V_028C70_NUMBER_UNORM;
} else
ntype = ~0u;
}
}
return ntype;
}
static bool
radv_is_sampler_format_supported(VkFormat format, bool *linear_sampling)
{
@ -610,10 +577,9 @@ radv_is_colorbuffer_format_supported(const struct radv_physical_device *pdevice,
bool *blendable)
{
const struct util_format_description *desc = vk_format_description(format);
uint32_t color_format = radv_translate_colorformat(format);
uint32_t color_format = ac_get_cb_format(pdevice->rad_info.gfx_level, desc->format);
uint32_t color_swap = radv_translate_colorswap(format, false);
uint32_t color_num_format =
radv_translate_color_numformat(format, desc, vk_format_get_first_non_void_channel(format));
uint32_t color_num_format = ac_get_cb_number_type(desc->format);
if (color_num_format == V_028C70_NUMBER_UINT || color_num_format == V_028C70_NUMBER_SINT ||
color_format == V_028C70_COLOR_8_24 || color_format == V_028C70_COLOR_24_8 ||
@ -882,89 +848,6 @@ radv_physical_device_get_format_properties(struct radv_physical_device *physical
out_properties->bufferFeatures = buffer;
}
uint32_t
radv_translate_colorformat(VkFormat format)
{
const struct util_format_description *desc = vk_format_description(format);
#define HAS_SIZE(x, y, z, w) \
(desc->channel[0].size == (x) && desc->channel[1].size == (y) && \
desc->channel[2].size == (z) && desc->channel[3].size == (w))
if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) /* isn't plain */
return V_028C70_COLOR_10_11_11;
if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)
return V_028C70_COLOR_5_9_9_9;
if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
return V_028C70_COLOR_INVALID;
/* hw cannot support mixed formats (except depth/stencil, since
* stencil is not written to). */
if (desc->is_mixed && desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
return V_028C70_COLOR_INVALID;
switch (desc->nr_channels) {
case 1:
switch (desc->channel[0].size) {
case 8:
return V_028C70_COLOR_8;
case 16:
return V_028C70_COLOR_16;
case 32:
return V_028C70_COLOR_32;
}
break;
case 2:
if (desc->channel[0].size == desc->channel[1].size) {
switch (desc->channel[0].size) {
case 8:
return V_028C70_COLOR_8_8;
case 16:
return V_028C70_COLOR_16_16;
case 32:
return V_028C70_COLOR_32_32;
}
} else if (HAS_SIZE(8, 24, 0, 0)) {
return V_028C70_COLOR_24_8;
} else if (HAS_SIZE(24, 8, 0, 0)) {
return V_028C70_COLOR_8_24;
}
break;
case 3:
if (HAS_SIZE(5, 6, 5, 0)) {
return V_028C70_COLOR_5_6_5;
} else if (HAS_SIZE(32, 8, 24, 0)) {
return V_028C70_COLOR_X24_8_32_FLOAT;
}
break;
case 4:
if (desc->channel[0].size == desc->channel[1].size &&
desc->channel[0].size == desc->channel[2].size &&
desc->channel[0].size == desc->channel[3].size) {
switch (desc->channel[0].size) {
case 4:
return V_028C70_COLOR_4_4_4_4;
case 8:
return V_028C70_COLOR_8_8_8_8;
case 16:
return V_028C70_COLOR_16_16_16_16;
case 32:
return V_028C70_COLOR_32_32_32_32;
}
} else if (HAS_SIZE(5, 5, 5, 1)) {
return V_028C70_COLOR_1_5_5_5;
} else if (HAS_SIZE(1, 5, 5, 5)) {
return V_028C70_COLOR_5_5_5_1;
} else if (HAS_SIZE(10, 10, 10, 2)) {
return V_028C70_COLOR_2_10_10_10;
}
break;
}
return V_028C70_COLOR_INVALID;
}
uint32_t
radv_colorformat_endian_swap(uint32_t colorformat)
{

View file

@ -149,9 +149,8 @@ radv_choose_spi_color_format(const struct radv_device *device, VkFormat vk_forma
struct ac_spi_color_formats formats = {0};
unsigned format, ntype, swap;
format = radv_translate_colorformat(vk_format);
ntype = radv_translate_color_numformat(vk_format, desc,
vk_format_get_first_non_void_channel(vk_format));
format = ac_get_cb_format(device->physical_device->rad_info.gfx_level, desc->format);
ntype = ac_get_cb_number_type(desc->format);
swap = radv_translate_colorswap(vk_format, false);
ac_choose_spi_color_formats(format, swap, ntype, false, use_rbplus, &formats);

View file

@ -2463,9 +2463,6 @@ uint32_t radv_translate_buffer_dataformat(const struct util_format_description *
uint32_t radv_translate_buffer_numformat(const struct util_format_description *desc,
int first_non_void);
bool radv_is_buffer_format_supported(VkFormat format, bool *scaled);
uint32_t radv_translate_colorformat(VkFormat format);
uint32_t radv_translate_color_numformat(VkFormat format, const struct util_format_description *desc,
int first_non_void);
uint32_t radv_colorformat_endian_swap(uint32_t colorformat);
unsigned radv_translate_colorswap(VkFormat format, bool do_endian_swap);
uint32_t radv_translate_dbformat(VkFormat format);

View file

@ -114,7 +114,8 @@ radv_sdma_v4_v5_copy_image_to_buffer(struct radv_device *device, struct radeon_c
unsigned hw_fmt, hw_type;
desc = vk_format_description(image->vk.format);
hw_fmt = radv_translate_colorformat(format);
hw_fmt = ac_get_cb_format(device->physical_device->rad_info.gfx_level,
vk_format_to_pipe_format(format));
hw_type = radv_translate_buffer_numformat(desc, vk_format_get_first_non_void_channel(format));
/* Add metadata */

View file

@ -56,7 +56,7 @@ static
bool si_translate_format_to_hw(struct si_context *sctx, enum pipe_format format, unsigned *hw_fmt, unsigned *hw_type)
{
const struct util_format_description *desc = util_format_description(format);
*hw_fmt = si_translate_colorformat(sctx->gfx_level, format);
*hw_fmt = ac_get_cb_format(sctx->gfx_level, format);
int firstchan = util_format_get_first_non_void_channel(format);
if (firstchan == -1 || desc->channel[firstchan].type == UTIL_FORMAT_TYPE_FLOAT) {

View file

@ -1634,101 +1634,6 @@ static void si_emit_db_render_state(struct si_context *sctx)
/*
* format translation
*/
uint32_t si_translate_colorformat(enum amd_gfx_level gfx_level,
enum pipe_format format)
{
const struct util_format_description *desc = util_format_description(format);
#define HAS_SIZE(x, y, z, w) \
(desc->channel[0].size == (x) && desc->channel[1].size == (y) && \
desc->channel[2].size == (z) && desc->channel[3].size == (w))
if (format == PIPE_FORMAT_R11G11B10_FLOAT) /* isn't plain */
return V_028C70_COLOR_10_11_11;
if (gfx_level >= GFX10_3 &&
format == PIPE_FORMAT_R9G9B9E5_FLOAT) /* isn't plain */
return V_028C70_COLOR_5_9_9_9;
if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
return V_028C70_COLOR_INVALID;
/* hw cannot support mixed formats (except depth/stencil, since
* stencil is not written to). */
if (desc->is_mixed && desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
return V_028C70_COLOR_INVALID;
int first_non_void = util_format_get_first_non_void_channel(format);
/* Reject SCALED formats because we don't implement them for CB. */
if (first_non_void >= 0 && first_non_void <= 3 &&
(desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_UNSIGNED ||
desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_SIGNED) &&
!desc->channel[first_non_void].normalized &&
!desc->channel[first_non_void].pure_integer)
return V_028C70_COLOR_INVALID;
switch (desc->nr_channels) {
case 1:
switch (desc->channel[0].size) {
case 8:
return V_028C70_COLOR_8;
case 16:
return V_028C70_COLOR_16;
case 32:
return V_028C70_COLOR_32;
}
break;
case 2:
if (desc->channel[0].size == desc->channel[1].size) {
switch (desc->channel[0].size) {
case 8:
return V_028C70_COLOR_8_8;
case 16:
return V_028C70_COLOR_16_16;
case 32:
return V_028C70_COLOR_32_32;
}
} else if (HAS_SIZE(8, 24, 0, 0)) {
return V_028C70_COLOR_24_8;
} else if (HAS_SIZE(24, 8, 0, 0)) {
return V_028C70_COLOR_8_24;
}
break;
case 3:
if (HAS_SIZE(5, 6, 5, 0)) {
return V_028C70_COLOR_5_6_5;
} else if (HAS_SIZE(32, 8, 24, 0)) {
return V_028C70_COLOR_X24_8_32_FLOAT;
}
break;
case 4:
if (desc->channel[0].size == desc->channel[1].size &&
desc->channel[0].size == desc->channel[2].size &&
desc->channel[0].size == desc->channel[3].size) {
switch (desc->channel[0].size) {
case 4:
return V_028C70_COLOR_4_4_4_4;
case 8:
return V_028C70_COLOR_8_8_8_8;
case 16:
return V_028C70_COLOR_16_16_16_16;
case 32:
return V_028C70_COLOR_32_32_32_32;
}
} else if (HAS_SIZE(5, 5, 5, 1)) {
return V_028C70_COLOR_1_5_5_5;
} else if (HAS_SIZE(1, 5, 5, 5)) {
return V_028C70_COLOR_5_5_5_1;
} else if (HAS_SIZE(10, 10, 10, 2)) {
return V_028C70_COLOR_2_10_10_10;
} else if (HAS_SIZE(2, 10, 10, 10)) {
return V_028C70_COLOR_10_10_10_2;
}
break;
}
return V_028C70_COLOR_INVALID;
}
static uint32_t si_colorformat_endian_swap(uint32_t colorformat)
{
@ -2368,7 +2273,7 @@ static unsigned si_is_vertex_format_supported(struct pipe_screen *screen, enum p
static bool si_is_colorbuffer_format_supported(enum amd_gfx_level gfx_level,
enum pipe_format format)
{
return si_translate_colorformat(gfx_level, format) != V_028C70_COLOR_INVALID &&
return ac_get_cb_format(gfx_level, format) != V_028C70_COLOR_INVALID &&
si_translate_colorswap(gfx_level, format, false) != ~0U;
}
@ -2500,35 +2405,13 @@ static void si_initialize_color_surface(struct si_context *sctx, struct si_surfa
struct si_texture *tex = (struct si_texture *)surf->base.texture;
unsigned format, swap, ntype, endian;
const struct util_format_description *desc;
int firstchan;
unsigned blend_clamp = 0, blend_bypass = 0;
desc = util_format_description(surf->base.format);
firstchan = util_format_get_first_non_void_channel(surf->base.format);
if (firstchan == -1 || desc->channel[firstchan].type == UTIL_FORMAT_TYPE_FLOAT) {
ntype = V_028C70_NUMBER_FLOAT;
} else {
ntype = V_028C70_NUMBER_UNORM;
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
ntype = V_028C70_NUMBER_SRGB;
else if (desc->channel[firstchan].type == UTIL_FORMAT_TYPE_SIGNED) {
if (desc->channel[firstchan].pure_integer) {
ntype = V_028C70_NUMBER_SINT;
} else {
assert(desc->channel[firstchan].normalized);
ntype = V_028C70_NUMBER_SNORM;
}
} else if (desc->channel[firstchan].type == UTIL_FORMAT_TYPE_UNSIGNED) {
if (desc->channel[firstchan].pure_integer) {
ntype = V_028C70_NUMBER_UINT;
} else {
assert(desc->channel[firstchan].normalized);
ntype = V_028C70_NUMBER_UNORM;
}
}
}
format = si_translate_colorformat(sctx->gfx_level, surf->base.format);
ntype = ac_get_cb_number_type(surf->base.format);
format = ac_get_cb_format(sctx->gfx_level, surf->base.format);
if (format == V_028C70_COLOR_INVALID) {
PRINT_ERR("Invalid CB format: %d, disabling CB.\n", surf->base.format);
}

View file

@ -513,7 +513,6 @@ struct pb_slab *si_bindless_descriptor_slab_alloc(void *priv, unsigned heap, uns
void si_bindless_descriptor_slab_free(void *priv, struct pb_slab *pslab);
void si_rebind_buffer(struct si_context *sctx, struct pipe_resource *buf);
/* si_state.c */
uint32_t si_translate_colorformat(enum amd_gfx_level gfx_level, enum pipe_format format);
void si_init_state_compute_functions(struct si_context *sctx);
void si_init_state_functions(struct si_context *sctx);
void si_init_screen_state_functions(struct si_screen *sscreen);