ac,radv,radeonsi: add a function to translate colorswap

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29265>
This commit is contained in:
Samuel Pitoiset 2024-05-17 13:12:17 +02:00 committed by Marge Bot
parent 40428bd497
commit 7f0430bb36
11 changed files with 83 additions and 137 deletions

View file

@ -192,3 +192,67 @@ ac_translate_tex_numformat(const struct util_format_description *desc,
return num_format;
}
unsigned
ac_translate_colorswap(enum amd_gfx_level gfx_level, enum pipe_format format, bool do_endian_swap)
{
const struct util_format_description *desc = util_format_description(format);
#define HAS_SWIZZLE(chan, swz) (desc->swizzle[chan] == PIPE_SWIZZLE_##swz)
if (format == PIPE_FORMAT_R11G11B10_FLOAT) /* isn't plain */
return V_028C70_SWAP_STD;
if (gfx_level >= GFX10_3 &&
format == PIPE_FORMAT_R9G9B9E5_FLOAT) /* isn't plain */
return V_028C70_SWAP_STD;
if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
return ~0U;
switch (desc->nr_channels) {
case 1:
if (HAS_SWIZZLE(0, X))
return V_028C70_SWAP_STD; /* X___ */
else if (HAS_SWIZZLE(3, X))
return V_028C70_SWAP_ALT_REV; /* ___X */
break;
case 2:
if ((HAS_SWIZZLE(0, X) && HAS_SWIZZLE(1, Y)) || (HAS_SWIZZLE(0, X) && HAS_SWIZZLE(1, NONE)) ||
(HAS_SWIZZLE(0, NONE) && HAS_SWIZZLE(1, Y)))
return V_028C70_SWAP_STD; /* XY__ */
else if ((HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(1, X)) ||
(HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(1, NONE)) ||
(HAS_SWIZZLE(0, NONE) && HAS_SWIZZLE(1, X)))
/* YX__ */
return (do_endian_swap ? V_028C70_SWAP_STD : V_028C70_SWAP_STD_REV);
else if (HAS_SWIZZLE(0, X) && HAS_SWIZZLE(3, Y))
return V_028C70_SWAP_ALT; /* X__Y */
else if (HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(3, X))
return V_028C70_SWAP_ALT_REV; /* Y__X */
break;
case 3:
if (HAS_SWIZZLE(0, X))
return (do_endian_swap ? V_028C70_SWAP_STD_REV : V_028C70_SWAP_STD);
else if (HAS_SWIZZLE(0, Z))
return V_028C70_SWAP_STD_REV; /* ZYX */
break;
case 4:
/* check the middle channels, the 1st and 4th channel can be NONE */
if (HAS_SWIZZLE(1, Y) && HAS_SWIZZLE(2, Z)) {
return V_028C70_SWAP_STD; /* XYZW */
} else if (HAS_SWIZZLE(1, Z) && HAS_SWIZZLE(2, Y)) {
return V_028C70_SWAP_STD_REV; /* WZYX */
} else if (HAS_SWIZZLE(1, Y) && HAS_SWIZZLE(2, X)) {
return V_028C70_SWAP_ALT; /* ZYXW */
} else if (HAS_SWIZZLE(1, Z) && HAS_SWIZZLE(2, W)) {
/* YZWX */
if (desc->is_array)
return V_028C70_SWAP_ALT_REV;
else
return (do_endian_swap ? V_028C70_SWAP_ALT : V_028C70_SWAP_ALT_REV);
}
break;
}
return ~0U;
}

View file

@ -8,6 +8,8 @@
#ifndef AC_FORMATS_H
#define AC_FORMATS_H
#include "amd_family.h"
#include "util/format/u_format.h"
#ifdef __cplusplus
@ -26,6 +28,11 @@ uint32_t
ac_translate_tex_numformat(const struct util_format_description *desc,
int first_non_void);
unsigned
ac_translate_colorswap(enum amd_gfx_level gfx_level,
enum pipe_format format,
bool do_endian_swap);
#ifdef __cplusplus
}
#endif

View file

@ -74,6 +74,8 @@ typedef void *drmDevicePtr;
#include "ac_llvm_util.h"
#endif
#include "ac_formats.h"
static bool
radv_spm_trace_enabled(struct radv_instance *instance)
{
@ -1683,7 +1685,7 @@ radv_initialise_color_surface(struct radv_device *device, struct radv_color_buff
format = ac_get_cb_format(pdev->info.gfx_level, desc->format);
assert(format != V_028C70_COLOR_INVALID);
swap = radv_translate_colorswap(vk_format_to_pipe_format(iview->vk.format), false);
swap = ac_translate_colorswap(pdev->info.gfx_level, vk_format_to_pipe_format(iview->vk.format), false);
endian = radv_colorformat_endian_swap(format);
/* blend clamp should be set for all NORM/SRGB types */

View file

@ -446,7 +446,7 @@ radv_is_colorbuffer_format_supported(const struct radv_physical_device *pdev, Vk
{
const struct util_format_description *desc = vk_format_description(format);
uint32_t color_format = ac_get_cb_format(pdev->info.gfx_level, desc->format);
uint32_t color_swap = radv_translate_colorswap(desc->format, false);
uint32_t color_swap = ac_translate_colorswap(pdev->info.gfx_level, desc->format, false);
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 ||
@ -858,68 +858,6 @@ radv_translate_dbformat(VkFormat format)
}
}
unsigned
radv_translate_colorswap(enum pipe_format format, bool do_endian_swap)
{
const struct util_format_description *desc = util_format_description(format);
#define HAS_SWIZZLE(chan, swz) (desc->swizzle[chan] == PIPE_SWIZZLE_##swz)
if (format == PIPE_FORMAT_R11G11B10_FLOAT)
return V_028C70_SWAP_STD;
if (format == PIPE_FORMAT_R9G9B9E5_FLOAT)
return V_028C70_SWAP_STD;
if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
return ~0U;
switch (desc->nr_channels) {
case 1:
if (HAS_SWIZZLE(0, X))
return V_028C70_SWAP_STD; /* X___ */
else if (HAS_SWIZZLE(3, X))
return V_028C70_SWAP_ALT_REV; /* ___X */
break;
case 2:
if ((HAS_SWIZZLE(0, X) && HAS_SWIZZLE(1, Y)) || (HAS_SWIZZLE(0, X) && HAS_SWIZZLE(1, NONE)) ||
(HAS_SWIZZLE(0, NONE) && HAS_SWIZZLE(1, Y)))
return V_028C70_SWAP_STD; /* XY__ */
else if ((HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(1, X)) || (HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(1, NONE)) ||
(HAS_SWIZZLE(0, NONE) && HAS_SWIZZLE(1, X)))
/* YX__ */
return (do_endian_swap ? V_028C70_SWAP_STD : V_028C70_SWAP_STD_REV);
else if (HAS_SWIZZLE(0, X) && HAS_SWIZZLE(3, Y))
return V_028C70_SWAP_ALT; /* X__Y */
else if (HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(3, X))
return V_028C70_SWAP_ALT_REV; /* Y__X */
break;
case 3:
if (HAS_SWIZZLE(0, X))
return (do_endian_swap ? V_028C70_SWAP_STD_REV : V_028C70_SWAP_STD);
else if (HAS_SWIZZLE(0, Z))
return V_028C70_SWAP_STD_REV; /* ZYX */
break;
case 4:
/* check the middle channels, the 1st and 4th channel can be NONE */
if (HAS_SWIZZLE(1, Y) && HAS_SWIZZLE(2, Z)) {
return V_028C70_SWAP_STD; /* XYZW */
} else if (HAS_SWIZZLE(1, Z) && HAS_SWIZZLE(2, Y)) {
return V_028C70_SWAP_STD_REV; /* WZYX */
} else if (HAS_SWIZZLE(1, Y) && HAS_SWIZZLE(2, X)) {
return V_028C70_SWAP_ALT; /* ZYXW */
} else if (HAS_SWIZZLE(1, Z) && HAS_SWIZZLE(2, W)) {
/* YZWX */
if (desc->is_array)
return V_028C70_SWAP_ALT_REV;
else
return (do_endian_swap ? V_028C70_SWAP_ALT : V_028C70_SWAP_ALT_REV);
}
break;
}
return ~0U;
}
bool
radv_format_pack_clear_color(VkFormat format, uint32_t clear_vals[2], VkClearColorValue *value)
{

View file

@ -163,8 +163,6 @@ uint32_t radv_colorformat_endian_swap(uint32_t colorformat);
uint32_t radv_translate_dbformat(VkFormat format);
unsigned radv_translate_colorswap(enum pipe_format format, bool do_endian_swap);
bool radv_format_pack_clear_color(VkFormat format, uint32_t clear_vals[2], VkClearColorValue *value);
bool radv_dcc_formats_compatible(enum amd_gfx_level gfx_level, VkFormat format1, VkFormat format2,

View file

@ -12,6 +12,7 @@
#include "util/u_atomic.h"
#include "util/u_debug.h"
#include "ac_drm_fourcc.h"
#include "ac_formats.h"
#include "radv_android.h"
#include "radv_buffer.h"
#include "radv_buffer_view.h"
@ -777,7 +778,7 @@ vi_alpha_is_on_msb(const struct radv_device *device, const VkFormat format)
if (pdev->info.gfx_level >= GFX10 && desc->nr_channels == 1)
return desc->swizzle[3] == PIPE_SWIZZLE_X;
return radv_translate_colorswap(desc->format, false) <= 1;
return ac_translate_colorswap(pdev->info.gfx_level, desc->format, false) <= 1;
}
static void

View file

@ -33,6 +33,7 @@
#include "util/u_debug.h"
#include "ac_binary.h"
#include "ac_formats.h"
#include "ac_nir.h"
#include "ac_shader_util.h"
#include "aco_interface.h"
@ -112,7 +113,7 @@ radv_choose_spi_color_format(const struct radv_device *device, VkFormat vk_forma
format = ac_get_cb_format(pdev->info.gfx_level, desc->format);
ntype = ac_get_cb_number_type(desc->format);
swap = radv_translate_colorswap(desc->format, false);
swap = ac_translate_colorswap(pdev->info.gfx_level, desc->format, false);
ac_choose_spi_color_formats(format, swap, ntype, false, use_rbplus, &formats);

View file

@ -9,6 +9,7 @@
#include "util/format/u_format.h"
#include "util/u_pack_color.h"
#include "util/u_surface.h"
#include "ac_formats.h"
enum {
SI_CLEAR = SI_SAVE_FRAGMENT_STATE | SI_SAVE_FRAGMENT_CONSTANT,
@ -189,7 +190,7 @@ bool vi_alpha_is_on_msb(struct si_screen *sscreen, enum pipe_format format)
format = si_simplify_cb_format(format);
const struct util_format_description *desc = util_format_description(format);
unsigned comp_swap = si_translate_colorswap(sscreen->info.gfx_level, format, false);
unsigned comp_swap = ac_translate_colorswap(sscreen->info.gfx_level, format, false);
/* The following code matches the hw behavior. */
if (desc->nr_channels == 1) {

View file

@ -1767,8 +1767,6 @@ bool vi_dcc_formats_are_incompatible(struct pipe_resource *tex, unsigned level,
enum pipe_format view_format);
void vi_disable_dcc_if_incompatible_format(struct si_context *sctx, struct pipe_resource *tex,
unsigned level, enum pipe_format view_format);
unsigned si_translate_colorswap(enum amd_gfx_level gfx_level, enum pipe_format format,
bool do_endian_swap);
bool si_texture_disable_dcc(struct si_context *sctx, struct si_texture *tex);
void si_init_screen_texture_functions(struct si_screen *sscreen);
void si_init_context_texture_functions(struct si_context *sctx);

View file

@ -2525,7 +2525,7 @@ static bool si_is_colorbuffer_format_supported(enum amd_gfx_level gfx_level,
enum pipe_format format)
{
return ac_get_cb_format(gfx_level, format) != V_028C70_COLOR_INVALID &&
si_translate_colorswap(gfx_level, format, false) != ~0U;
ac_translate_colorswap(gfx_level, format, false) != ~0U;
}
static bool si_is_zs_format_supported(enum pipe_format format)
@ -2667,7 +2667,7 @@ static void si_initialize_color_surface(struct si_context *sctx, struct si_surfa
PRINT_ERR("Invalid CB format: %d, disabling CB.\n", surf->base.format);
}
assert(format != V_028C70_COLOR_INVALID);
swap = si_translate_colorswap(sctx->gfx_level, surf->base.format, false);
swap = ac_translate_colorswap(sctx->gfx_level, surf->base.format, false);
endian = si_colorformat_endian_swap(format);
/* blend clamp should be set for all NORM/SRGB types */

View file

@ -2238,70 +2238,6 @@ static void si_surface_destroy(struct pipe_context *pipe, struct pipe_surface *s
FREE(surface);
}
unsigned si_translate_colorswap(enum amd_gfx_level gfx_level, enum pipe_format format,
bool do_endian_swap)
{
const struct util_format_description *desc = util_format_description(format);
#define HAS_SWIZZLE(chan, swz) (desc->swizzle[chan] == PIPE_SWIZZLE_##swz)
if (format == PIPE_FORMAT_R11G11B10_FLOAT) /* isn't plain */
return V_028C70_SWAP_STD;
if (gfx_level >= GFX10_3 &&
format == PIPE_FORMAT_R9G9B9E5_FLOAT) /* isn't plain */
return V_028C70_SWAP_STD;
if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
return ~0U;
switch (desc->nr_channels) {
case 1:
if (HAS_SWIZZLE(0, X))
return V_028C70_SWAP_STD; /* X___ */
else if (HAS_SWIZZLE(3, X))
return V_028C70_SWAP_ALT_REV; /* ___X */
break;
case 2:
if ((HAS_SWIZZLE(0, X) && HAS_SWIZZLE(1, Y)) || (HAS_SWIZZLE(0, X) && HAS_SWIZZLE(1, NONE)) ||
(HAS_SWIZZLE(0, NONE) && HAS_SWIZZLE(1, Y)))
return V_028C70_SWAP_STD; /* XY__ */
else if ((HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(1, X)) ||
(HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(1, NONE)) ||
(HAS_SWIZZLE(0, NONE) && HAS_SWIZZLE(1, X)))
/* YX__ */
return (do_endian_swap ? V_028C70_SWAP_STD : V_028C70_SWAP_STD_REV);
else if (HAS_SWIZZLE(0, X) && HAS_SWIZZLE(3, Y))
return V_028C70_SWAP_ALT; /* X__Y */
else if (HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(3, X))
return V_028C70_SWAP_ALT_REV; /* Y__X */
break;
case 3:
if (HAS_SWIZZLE(0, X))
return (do_endian_swap ? V_028C70_SWAP_STD_REV : V_028C70_SWAP_STD);
else if (HAS_SWIZZLE(0, Z))
return V_028C70_SWAP_STD_REV; /* ZYX */
break;
case 4:
/* check the middle channels, the 1st and 4th channel can be NONE */
if (HAS_SWIZZLE(1, Y) && HAS_SWIZZLE(2, Z)) {
return V_028C70_SWAP_STD; /* XYZW */
} else if (HAS_SWIZZLE(1, Z) && HAS_SWIZZLE(2, Y)) {
return V_028C70_SWAP_STD_REV; /* WZYX */
} else if (HAS_SWIZZLE(1, Y) && HAS_SWIZZLE(2, X)) {
return V_028C70_SWAP_ALT; /* ZYXW */
} else if (HAS_SWIZZLE(1, Z) && HAS_SWIZZLE(2, W)) {
/* YZWX */
if (desc->is_array)
return V_028C70_SWAP_ALT_REV;
else
return (do_endian_swap ? V_028C70_SWAP_ALT : V_028C70_SWAP_ALT_REV);
}
break;
}
return ~0U;
}
static struct pipe_memory_object *
si_memobj_from_handle(struct pipe_screen *screen, struct winsys_handle *whandle, bool dedicated)
{