ac,radv,radeonsi: add function to determine if alpha should be on MSB
The only difference for RADV is that the helper now converts SRGB formats to non-SRGB but that shouldn't change anything in practice. Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29308>
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "ac_formats.h"
|
||||
#include "ac_gpu_info.h"
|
||||
|
||||
#include "sid.h"
|
||||
|
||||
@@ -487,3 +488,31 @@ ac_border_color_swizzle(const struct util_format_description *desc)
|
||||
|
||||
return bc_swizzle;
|
||||
}
|
||||
|
||||
/** Linearize and convert luminance/intensity to red. */
|
||||
enum pipe_format
|
||||
ac_simplify_cb_format(enum pipe_format format)
|
||||
{
|
||||
format = util_format_linear(format);
|
||||
format = util_format_luminance_to_red(format);
|
||||
return util_format_intensity_to_red(format);
|
||||
}
|
||||
|
||||
bool
|
||||
ac_alpha_is_on_msb(const struct radeon_info *info, enum pipe_format format)
|
||||
{
|
||||
if (info->gfx_level >= GFX11)
|
||||
return false;
|
||||
|
||||
format = ac_simplify_cb_format(format);
|
||||
const struct util_format_description *desc = util_format_description(format);
|
||||
unsigned comp_swap = ac_translate_colorswap(info->gfx_level, format, false);
|
||||
|
||||
/* The following code matches the hw behavior. */
|
||||
if (desc->nr_channels == 1) {
|
||||
return (comp_swap == V_028C70_SWAP_ALT_REV) != (info->family == CHIP_RAVEN2 ||
|
||||
info->family == CHIP_RENOIR);
|
||||
}
|
||||
|
||||
return comp_swap != V_028C70_SWAP_STD_REV && comp_swap != V_028C70_SWAP_ALT_REV;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,12 @@ ac_is_zs_format_supported(enum pipe_format format);
|
||||
uint32_t
|
||||
ac_border_color_swizzle(const struct util_format_description *desc);
|
||||
|
||||
enum pipe_format
|
||||
ac_simplify_cb_format(enum pipe_format format);
|
||||
|
||||
bool
|
||||
ac_alpha_is_on_msb(const struct radeon_info *info, enum pipe_format format);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include "vk_format.h"
|
||||
#include "vk_shader_module.h"
|
||||
|
||||
#include "ac_formats.h"
|
||||
|
||||
enum { DEPTH_CLEAR_SLOW, DEPTH_CLEAR_FAST };
|
||||
|
||||
static void
|
||||
@@ -1401,6 +1403,7 @@ gfx8_get_fast_clear_parameters(struct radv_device *device, const struct radv_ima
|
||||
const VkClearColorValue *clear_value, uint32_t *reset_value,
|
||||
bool *can_avoid_fast_clear_elim)
|
||||
{
|
||||
const struct radv_physical_device *pdev = radv_device_physical(device);
|
||||
bool values[4] = {0};
|
||||
int extra_channel;
|
||||
bool main_value = false;
|
||||
@@ -1422,7 +1425,7 @@ gfx8_get_fast_clear_parameters(struct radv_device *device, const struct radv_ima
|
||||
iview->vk.format == VK_FORMAT_B5G6R5_UNORM_PACK16)
|
||||
extra_channel = -1;
|
||||
else if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN) {
|
||||
if (vi_alpha_is_on_msb(device, iview->vk.format))
|
||||
if (ac_alpha_is_on_msb(&pdev->info, vk_format_to_pipe_format(iview->vk.format)))
|
||||
extra_channel = desc->nr_channels - 1;
|
||||
else
|
||||
extra_channel = 0;
|
||||
|
||||
@@ -763,26 +763,6 @@ radv_compose_swizzle(const struct util_format_description *desc, const VkCompone
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
vi_alpha_is_on_msb(const struct radv_device *device, const VkFormat format)
|
||||
{
|
||||
const struct radv_physical_device *pdev = radv_device_physical(device);
|
||||
|
||||
if (pdev->info.gfx_level >= GFX11)
|
||||
return false;
|
||||
|
||||
const struct util_format_description *desc = vk_format_description(format);
|
||||
const uint32_t comp_swap = ac_translate_colorswap(pdev->info.gfx_level, desc->format, false);
|
||||
|
||||
/* The following code matches the hw behavior. */
|
||||
if (desc->nr_channels == 1) {
|
||||
return (comp_swap == V_028C70_SWAP_ALT_REV) !=
|
||||
(pdev->info.family == CHIP_RAVEN2 || pdev->info.family == CHIP_RENOIR);
|
||||
}
|
||||
|
||||
return comp_swap != V_028C70_SWAP_STD_REV && comp_swap != V_028C70_SWAP_ALT_REV;
|
||||
}
|
||||
|
||||
static void
|
||||
radv_query_opaque_metadata(struct radv_device *device, struct radv_image *image, unsigned plane_id,
|
||||
struct radeon_bo_metadata *md)
|
||||
|
||||
@@ -316,8 +316,6 @@ unsigned radv_map_swizzle(unsigned swizzle);
|
||||
void radv_compose_swizzle(const struct util_format_description *desc, const VkComponentMapping *mapping,
|
||||
enum pipe_swizzle swizzle[4]);
|
||||
|
||||
bool vi_alpha_is_on_msb(const struct radv_device *device, const VkFormat format);
|
||||
|
||||
void radv_init_metadata(struct radv_device *device, struct radv_image *image, struct radeon_bo_metadata *metadata);
|
||||
|
||||
void radv_image_override_offset_stride(struct radv_device *device, struct radv_image *image, uint64_t offset,
|
||||
|
||||
@@ -197,7 +197,7 @@ gfx10_make_texture_descriptor(struct radv_device *device, struct radv_image *ima
|
||||
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(vi_alpha_is_on_msb(device, vk_format));
|
||||
S_00A018_ALPHA_IS_ON_MSB(ac_alpha_is_on_msb(&pdev->info, vk_format_to_pipe_format(vk_format)));
|
||||
}
|
||||
|
||||
/* Initialize the sampler view for FMASK. */
|
||||
@@ -327,7 +327,7 @@ gfx6_make_texture_descriptor(struct radv_device *device, struct radv_image *imag
|
||||
}
|
||||
|
||||
if (radv_dcc_enabled(image, first_level)) {
|
||||
state[6] = S_008F28_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(device, vk_format));
|
||||
state[6] = S_008F28_ALPHA_IS_ON_MSB(ac_alpha_is_on_msb(&pdev->info, vk_format_to_pipe_format(vk_format)));
|
||||
} else {
|
||||
if (instance->drirc.disable_aniso_single_level) {
|
||||
/* The last dword is unused by hw. The shader uses it to clear
|
||||
|
||||
@@ -195,7 +195,7 @@ radv_sdma_get_metadata_config(const struct radv_device *const device, const stru
|
||||
const struct util_format_description *desc = vk_format_description(format);
|
||||
|
||||
const uint32_t data_format = ac_get_cb_format(pdev->info.gfx_level, vk_format_to_pipe_format(format));
|
||||
const uint32_t alpha_is_on_msb = vi_alpha_is_on_msb(device, format);
|
||||
const uint32_t alpha_is_on_msb = ac_alpha_is_on_msb(&pdev->info, vk_format_to_pipe_format(format));
|
||||
const uint32_t number_type = radv_translate_buffer_numformat(desc, vk_format_get_first_non_void_channel(format));
|
||||
const uint32_t surface_type = radv_sdma_surface_type_from_aspect_mask(aspect_mask);
|
||||
const uint32_t max_comp_block_size = surf->u.gfx9.color.dcc.max_compressed_block_size;
|
||||
|
||||
@@ -175,32 +175,6 @@ static bool si_set_clear_color(struct si_texture *tex, enum pipe_format surface_
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Linearize and convert luminance/intensity to red. */
|
||||
enum pipe_format si_simplify_cb_format(enum pipe_format format)
|
||||
{
|
||||
format = util_format_linear(format);
|
||||
format = util_format_luminance_to_red(format);
|
||||
return util_format_intensity_to_red(format);
|
||||
}
|
||||
|
||||
bool vi_alpha_is_on_msb(struct si_screen *sscreen, enum pipe_format format)
|
||||
{
|
||||
if (sscreen->info.gfx_level >= GFX11)
|
||||
return false;
|
||||
|
||||
format = si_simplify_cb_format(format);
|
||||
const struct util_format_description *desc = util_format_description(format);
|
||||
unsigned comp_swap = ac_translate_colorswap(sscreen->info.gfx_level, format, false);
|
||||
|
||||
/* The following code matches the hw behavior. */
|
||||
if (desc->nr_channels == 1) {
|
||||
return (comp_swap == V_028C70_SWAP_ALT_REV) != (sscreen->info.family == CHIP_RAVEN2 ||
|
||||
sscreen->info.family == CHIP_RENOIR);
|
||||
}
|
||||
|
||||
return comp_swap != V_028C70_SWAP_STD_REV && comp_swap != V_028C70_SWAP_ALT_REV;
|
||||
}
|
||||
|
||||
static bool gfx8_get_dcc_clear_parameters(struct si_screen *sscreen, enum pipe_format base_format,
|
||||
enum pipe_format surface_format,
|
||||
const union pipe_color_union *color, uint32_t *clear_value,
|
||||
@@ -218,7 +192,7 @@ static bool gfx8_get_dcc_clear_parameters(struct si_screen *sscreen, enum pipe_f
|
||||
bool has_alpha = false;
|
||||
|
||||
const struct util_format_description *desc =
|
||||
util_format_description(si_simplify_cb_format(surface_format));
|
||||
util_format_description(ac_simplify_cb_format(surface_format));
|
||||
|
||||
/* 128-bit fast clear with different R,G,B values is unsupported. */
|
||||
if (desc->block.bits == 128 && (color->ui[0] != color->ui[1] || color->ui[0] != color->ui[2]))
|
||||
@@ -230,8 +204,8 @@ static bool gfx8_get_dcc_clear_parameters(struct si_screen *sscreen, enum pipe_f
|
||||
if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
|
||||
return true; /* need ELIMINATE_FAST_CLEAR */
|
||||
|
||||
bool base_alpha_is_on_msb = vi_alpha_is_on_msb(sscreen, base_format);
|
||||
bool surf_alpha_is_on_msb = vi_alpha_is_on_msb(sscreen, surface_format);
|
||||
bool base_alpha_is_on_msb = ac_alpha_is_on_msb(&sscreen->info, base_format);
|
||||
bool surf_alpha_is_on_msb = ac_alpha_is_on_msb(&sscreen->info, surface_format);
|
||||
|
||||
/* Formats with 3 channels can't have alpha. */
|
||||
if (desc->nr_channels == 3)
|
||||
@@ -317,7 +291,7 @@ static bool gfx11_get_dcc_clear_parameters(struct si_screen *sscreen, struct si_
|
||||
bool fail_if_slow)
|
||||
{
|
||||
const struct util_format_description *desc =
|
||||
util_format_description(si_simplify_cb_format(surface_format));
|
||||
util_format_description(ac_simplify_cb_format(surface_format));
|
||||
unsigned start_bit = UINT_MAX;
|
||||
unsigned end_bit = 0;
|
||||
|
||||
|
||||
@@ -1491,8 +1491,6 @@ struct si_clear_info {
|
||||
union pipe_color_union color;
|
||||
};
|
||||
|
||||
enum pipe_format si_simplify_cb_format(enum pipe_format format);
|
||||
bool vi_alpha_is_on_msb(struct si_screen *sscreen, enum pipe_format format);
|
||||
bool vi_dcc_get_clear_info(struct si_context *sctx, struct si_texture *tex, unsigned level,
|
||||
unsigned clear_value, struct si_clear_info *out);
|
||||
void si_init_buffer_clear(struct si_clear_info *info,
|
||||
|
||||
@@ -168,7 +168,7 @@ static bool si_sdma_v4_v5_copy_texture(struct si_context *sctx, struct si_textur
|
||||
radeon_emit((uint32_t)md_address);
|
||||
radeon_emit((uint32_t)(md_address >> 32));
|
||||
radeon_emit(hw_fmt |
|
||||
vi_alpha_is_on_msb(sctx->screen, tiled->buffer.b.b.format) << 8 |
|
||||
ac_alpha_is_on_msb(&sctx->screen->info, tiled->buffer.b.b.format) << 8 |
|
||||
hw_type << 9 |
|
||||
tiled->surface.u.gfx9.color.dcc.max_compressed_block_size << 24 |
|
||||
V_028C78_MAX_BLOCK_SIZE_256B << 26 |
|
||||
|
||||
@@ -4736,7 +4736,7 @@ static void gfx10_make_texture_descriptor(
|
||||
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(vi_alpha_is_on_msb(screen, pipe_format));
|
||||
S_00A018_ALPHA_IS_ON_MSB(ac_alpha_is_on_msb(&screen->info, pipe_format));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4890,7 +4890,7 @@ static void si_make_texture_descriptor(struct si_screen *screen, struct si_textu
|
||||
}
|
||||
|
||||
if (vi_dcc_enabled(tex, first_level)) {
|
||||
state[6] = S_008F28_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(screen, pipe_format));
|
||||
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.
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "amd/addrlib/inc/addrinterface.h"
|
||||
#include "ac_formats.h"
|
||||
|
||||
static enum radeon_surf_mode si_choose_tiling(struct si_screen *sscreen,
|
||||
const struct pipe_resource *templ,
|
||||
@@ -2111,8 +2112,8 @@ bool vi_dcc_formats_compatible(struct si_screen *sscreen, enum pipe_format forma
|
||||
if (format1 == format2)
|
||||
return true;
|
||||
|
||||
format1 = si_simplify_cb_format(format1);
|
||||
format2 = si_simplify_cb_format(format2);
|
||||
format1 = ac_simplify_cb_format(format1);
|
||||
format2 = ac_simplify_cb_format(format2);
|
||||
|
||||
/* Check again after format adjustments. */
|
||||
if (format1 == format2)
|
||||
@@ -2142,7 +2143,7 @@ bool vi_dcc_formats_compatible(struct si_screen *sscreen, enum pipe_format forma
|
||||
|
||||
/* If the clear values are all 1 or all 0, this constraint can be
|
||||
* ignored. */
|
||||
if (vi_alpha_is_on_msb(sscreen, format1) != vi_alpha_is_on_msb(sscreen, format2))
|
||||
if (ac_alpha_is_on_msb(&sscreen->info, format1) != ac_alpha_is_on_msb(&sscreen->info, format2))
|
||||
return false;
|
||||
|
||||
/* Channel types must match if the clear value of 1 is used.
|
||||
|
||||
Reference in New Issue
Block a user