freedreno: Extract out common UBWC helper
And re-use in gallium driver. Signed-off-by: Rob Clark <robdclark@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30304>
This commit is contained in:
115
src/freedreno/common/freedreno_ubwc.h
Normal file
115
src/freedreno/common/freedreno_ubwc.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright © Google, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef __FREEDRENO_UBWC_H__
|
||||
#define __FREEDRENO_UBWC_H__
|
||||
|
||||
#include "util/format/u_format.h"
|
||||
|
||||
#include "freedreno_dev_info.h"
|
||||
|
||||
enum fd6_ubwc_compat_type {
|
||||
FD6_UBWC_UNKNOWN_COMPAT,
|
||||
FD6_UBWC_R8G8_UNORM,
|
||||
FD6_UBWC_R8G8_INT,
|
||||
FD6_UBWC_R8G8B8A8_UNORM,
|
||||
FD6_UBWC_R8G8B8A8_INT,
|
||||
FD6_UBWC_B8G8R8A8_UNORM,
|
||||
FD6_UBWC_R16G16_UNORM,
|
||||
FD6_UBWC_R16G16_INT,
|
||||
FD6_UBWC_R16G16B16A16_UNORM,
|
||||
FD6_UBWC_R16G16B16A16_INT,
|
||||
FD6_UBWC_R32_INT,
|
||||
FD6_UBWC_R32G32_INT,
|
||||
FD6_UBWC_R32G32B32A32_INT,
|
||||
FD6_UBWC_R32_FLOAT,
|
||||
};
|
||||
|
||||
static inline enum fd6_ubwc_compat_type
|
||||
fd6_ubwc_compat_mode(const struct fd_dev_info *info, enum pipe_format format)
|
||||
{
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_R8G8_UNORM:
|
||||
case PIPE_FORMAT_R8G8_SRGB:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
FD6_UBWC_R8G8_INT : FD6_UBWC_R8G8_UNORM;
|
||||
|
||||
case PIPE_FORMAT_R8G8_SNORM:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
FD6_UBWC_R8G8_INT : FD6_UBWC_UNKNOWN_COMPAT;
|
||||
|
||||
case PIPE_FORMAT_R8G8_UINT:
|
||||
case PIPE_FORMAT_R8G8_SINT:
|
||||
return FD6_UBWC_R8G8_INT;
|
||||
|
||||
case PIPE_FORMAT_R8G8B8A8_UNORM:
|
||||
case PIPE_FORMAT_R8G8B8A8_SRGB:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
FD6_UBWC_R8G8B8A8_INT : FD6_UBWC_R8G8B8A8_UNORM;
|
||||
|
||||
case PIPE_FORMAT_R8G8B8A8_SNORM:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
FD6_UBWC_R8G8B8A8_INT : FD6_UBWC_UNKNOWN_COMPAT;
|
||||
|
||||
case PIPE_FORMAT_R8G8B8A8_UINT:
|
||||
case PIPE_FORMAT_R8G8B8A8_SINT:
|
||||
return FD6_UBWC_R8G8B8A8_INT;
|
||||
|
||||
case PIPE_FORMAT_R16G16_UNORM:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
FD6_UBWC_R16G16_INT : FD6_UBWC_R16G16_UNORM;
|
||||
|
||||
case PIPE_FORMAT_R16G16_SNORM:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
FD6_UBWC_R16G16_INT : FD6_UBWC_UNKNOWN_COMPAT;
|
||||
|
||||
case PIPE_FORMAT_R16G16_UINT:
|
||||
case PIPE_FORMAT_R16G16_SINT:
|
||||
return FD6_UBWC_R16G16_INT;
|
||||
|
||||
case PIPE_FORMAT_R16G16B16A16_UNORM:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
FD6_UBWC_R16G16B16A16_INT : FD6_UBWC_R16G16B16A16_UNORM;
|
||||
|
||||
case PIPE_FORMAT_R16G16B16A16_SNORM:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
FD6_UBWC_R16G16B16A16_INT : FD6_UBWC_UNKNOWN_COMPAT;
|
||||
|
||||
case PIPE_FORMAT_R16G16B16A16_UINT:
|
||||
case PIPE_FORMAT_R16G16B16A16_SINT:
|
||||
return FD6_UBWC_R16G16B16A16_INT;
|
||||
|
||||
case PIPE_FORMAT_R32_UINT:
|
||||
case PIPE_FORMAT_R32_SINT:
|
||||
return FD6_UBWC_R32_INT;
|
||||
|
||||
case PIPE_FORMAT_R32G32_UINT:
|
||||
case PIPE_FORMAT_R32G32_SINT:
|
||||
return FD6_UBWC_R32G32_INT;
|
||||
|
||||
case PIPE_FORMAT_R32G32B32A32_UINT:
|
||||
case PIPE_FORMAT_R32G32B32A32_SINT:
|
||||
return FD6_UBWC_R32G32B32A32_INT;
|
||||
|
||||
case PIPE_FORMAT_Z32_FLOAT:
|
||||
case PIPE_FORMAT_R32_FLOAT:
|
||||
/* TODO: a630 blob allows these, but not a660. When is it legal? */
|
||||
return FD6_UBWC_UNKNOWN_COMPAT;
|
||||
|
||||
case PIPE_FORMAT_B8G8R8A8_UNORM:
|
||||
case PIPE_FORMAT_B8G8R8A8_SRGB:
|
||||
/* The blob doesn't list these as compatible, but they surely are.
|
||||
* freedreno's happy to cast between them, and zink would really like
|
||||
* to.
|
||||
*/
|
||||
return FD6_UBWC_B8G8R8A8_UNORM;
|
||||
|
||||
default:
|
||||
return FD6_UBWC_UNKNOWN_COMPAT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
@@ -7,6 +7,7 @@
|
||||
#include "tu_formats.h"
|
||||
|
||||
#include "fdl/fd6_format_table.h"
|
||||
#include "common/freedreno_ubwc.h"
|
||||
|
||||
#include "vk_android.h"
|
||||
#include "vk_enum_defines.h"
|
||||
@@ -95,109 +96,10 @@ tu6_format_texture(enum pipe_format format, enum a6xx_tile_mode tile_mode)
|
||||
return fmt;
|
||||
}
|
||||
|
||||
enum tu6_ubwc_compat_type {
|
||||
TU6_UBWC_UNKNOWN_COMPAT,
|
||||
TU6_UBWC_R8G8_UNORM,
|
||||
TU6_UBWC_R8G8_INT,
|
||||
TU6_UBWC_R8G8B8A8_UNORM,
|
||||
TU6_UBWC_R8G8B8A8_INT,
|
||||
TU6_UBWC_B8G8R8A8_UNORM,
|
||||
TU6_UBWC_R16G16_UNORM,
|
||||
TU6_UBWC_R16G16_INT,
|
||||
TU6_UBWC_R16G16B16A16_UNORM,
|
||||
TU6_UBWC_R16G16B16A16_INT,
|
||||
TU6_UBWC_R32_INT,
|
||||
TU6_UBWC_R32G32_INT,
|
||||
TU6_UBWC_R32G32B32A32_INT,
|
||||
TU6_UBWC_R32_FLOAT,
|
||||
};
|
||||
|
||||
static enum tu6_ubwc_compat_type
|
||||
static enum fd6_ubwc_compat_type
|
||||
tu6_ubwc_compat_mode(const struct fd_dev_info *info, VkFormat format)
|
||||
{
|
||||
switch (format) {
|
||||
case VK_FORMAT_R8G8_UNORM:
|
||||
case VK_FORMAT_R8G8_SRGB:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
TU6_UBWC_R8G8_INT : TU6_UBWC_R8G8_UNORM;
|
||||
|
||||
case VK_FORMAT_R8G8_SNORM:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
TU6_UBWC_R8G8_INT : TU6_UBWC_UNKNOWN_COMPAT;
|
||||
|
||||
case VK_FORMAT_R8G8_UINT:
|
||||
case VK_FORMAT_R8G8_SINT:
|
||||
return TU6_UBWC_R8G8_INT;
|
||||
|
||||
case VK_FORMAT_R8G8B8A8_UNORM:
|
||||
case VK_FORMAT_R8G8B8A8_SRGB:
|
||||
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
|
||||
case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
TU6_UBWC_R8G8B8A8_INT : TU6_UBWC_R8G8B8A8_UNORM;
|
||||
|
||||
case VK_FORMAT_R8G8B8A8_SNORM:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
TU6_UBWC_R8G8B8A8_INT : TU6_UBWC_UNKNOWN_COMPAT;
|
||||
|
||||
case VK_FORMAT_R8G8B8A8_UINT:
|
||||
case VK_FORMAT_R8G8B8A8_SINT:
|
||||
case VK_FORMAT_A8B8G8R8_UINT_PACK32:
|
||||
case VK_FORMAT_A8B8G8R8_SINT_PACK32:
|
||||
return TU6_UBWC_R8G8B8A8_INT;
|
||||
|
||||
case VK_FORMAT_R16G16_UNORM:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
TU6_UBWC_R16G16_INT : TU6_UBWC_R16G16_UNORM;
|
||||
|
||||
case VK_FORMAT_R16G16_SNORM:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
TU6_UBWC_R16G16_INT : TU6_UBWC_UNKNOWN_COMPAT;
|
||||
|
||||
case VK_FORMAT_R16G16_UINT:
|
||||
case VK_FORMAT_R16G16_SINT:
|
||||
return TU6_UBWC_R16G16_INT;
|
||||
|
||||
case VK_FORMAT_R16G16B16A16_UNORM:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
TU6_UBWC_R16G16B16A16_INT : TU6_UBWC_R16G16B16A16_UNORM;
|
||||
|
||||
case VK_FORMAT_R16G16B16A16_SNORM:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
TU6_UBWC_R16G16B16A16_INT : TU6_UBWC_UNKNOWN_COMPAT;
|
||||
|
||||
case VK_FORMAT_R16G16B16A16_UINT:
|
||||
case VK_FORMAT_R16G16B16A16_SINT:
|
||||
return TU6_UBWC_R16G16B16A16_INT;
|
||||
|
||||
case VK_FORMAT_R32_UINT:
|
||||
case VK_FORMAT_R32_SINT:
|
||||
return TU6_UBWC_R32_INT;
|
||||
|
||||
case VK_FORMAT_R32G32_UINT:
|
||||
case VK_FORMAT_R32G32_SINT:
|
||||
return TU6_UBWC_R32G32_INT;
|
||||
|
||||
case VK_FORMAT_R32G32B32A32_UINT:
|
||||
case VK_FORMAT_R32G32B32A32_SINT:
|
||||
return TU6_UBWC_R32G32B32A32_INT;
|
||||
|
||||
case VK_FORMAT_D32_SFLOAT:
|
||||
case VK_FORMAT_R32_SFLOAT:
|
||||
/* TODO: a630 blob allows these, but not a660. When is it legal? */
|
||||
return TU6_UBWC_UNKNOWN_COMPAT;
|
||||
|
||||
case VK_FORMAT_B8G8R8A8_UNORM:
|
||||
case VK_FORMAT_B8G8R8A8_SRGB:
|
||||
/* The blob doesn't list these as compatible, but they surely are.
|
||||
* freedreno's happy to cast between them, and zink would really like
|
||||
* to.
|
||||
*/
|
||||
return TU6_UBWC_B8G8R8A8_UNORM;
|
||||
|
||||
default:
|
||||
return TU6_UBWC_UNKNOWN_COMPAT;
|
||||
}
|
||||
return fd6_ubwc_compat_mode(info, vk_format_to_pipe_format(format));
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -213,9 +115,9 @@ tu6_mutable_format_list_ubwc_compatible(const struct fd_dev_info *info,
|
||||
if (fmt_list->viewFormatCount == 1)
|
||||
return true;
|
||||
|
||||
enum tu6_ubwc_compat_type type =
|
||||
enum fd6_ubwc_compat_type type =
|
||||
tu6_ubwc_compat_mode(info, fmt_list->pViewFormats[0]);
|
||||
if (type == TU6_UBWC_UNKNOWN_COMPAT)
|
||||
if (type == FD6_UBWC_UNKNOWN_COMPAT)
|
||||
return false;
|
||||
|
||||
for (uint32_t i = 1; i < fmt_list->viewFormatCount; i++) {
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include "a6xx/fd6_blitter.h"
|
||||
#include "fd6_resource.h"
|
||||
#include "fdl/fd6_format_table.h"
|
||||
#include "common/freedreno_ubwc.h"
|
||||
|
||||
#include "a6xx.xml.h"
|
||||
|
||||
@@ -127,14 +128,6 @@ can_do_ubwc(struct pipe_resource *prsc)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
is_norm(enum pipe_format format)
|
||||
{
|
||||
const struct util_format_description *desc = util_format_description(format);
|
||||
|
||||
return desc->is_snorm || desc->is_unorm;
|
||||
}
|
||||
|
||||
static bool
|
||||
is_z24s8(enum pipe_format format)
|
||||
{
|
||||
@@ -150,8 +143,12 @@ is_z24s8(enum pipe_format format)
|
||||
}
|
||||
|
||||
static bool
|
||||
valid_format_cast(struct fd_resource *rsc, enum pipe_format format)
|
||||
valid_ubwc_format_cast(struct fd_resource *rsc, enum pipe_format format)
|
||||
{
|
||||
const struct fd_dev_info *info = fd_screen(rsc->b.b.screen)->info;
|
||||
|
||||
assert(rsc->layout.ubwc);
|
||||
|
||||
/* Special case "casting" format in hw: */
|
||||
if (format == PIPE_FORMAT_Z24_UNORM_S8_UINT_AS_R8G8B8A8)
|
||||
return true;
|
||||
@@ -163,27 +160,8 @@ valid_format_cast(struct fd_resource *rsc, enum pipe_format format)
|
||||
is_z24s8(format) && is_z24s8(rsc->b.b.format))
|
||||
return true;
|
||||
|
||||
/* For some color values (just "solid white") compression metadata maps to
|
||||
* different pixel values for uint/sint vs unorm/snorm, so we can't reliably
|
||||
* "cast" u/snorm to u/sint and visa versa:
|
||||
*/
|
||||
if (is_norm(format) != is_norm(rsc->b.b.format))
|
||||
return false;
|
||||
|
||||
/* The UBWC formats can be re-interpreted so long as the components
|
||||
* have the same # of bits
|
||||
*/
|
||||
for (unsigned i = 0; i < 4; i++) {
|
||||
unsigned sb, db;
|
||||
|
||||
sb = util_format_get_component_bits(rsc->b.b.format, UTIL_FORMAT_COLORSPACE_RGB, i);
|
||||
db = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, i);
|
||||
|
||||
if (sb != db)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return fd6_ubwc_compat_mode(info, format) ==
|
||||
fd6_ubwc_compat_mode(info, rsc->b.b.format);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -217,7 +195,8 @@ fd6_check_valid_format(struct fd_resource *rsc, enum pipe_format format)
|
||||
if (!rsc->layout.ubwc)
|
||||
return FORMAT_OK;
|
||||
|
||||
if (ok_ubwc_format(rsc->b.b.screen, format) && valid_format_cast(rsc, format))
|
||||
if (ok_ubwc_format(rsc->b.b.screen, format) &&
|
||||
valid_ubwc_format_cast(rsc, format))
|
||||
return FORMAT_OK;
|
||||
|
||||
return DEMOTE_TO_TILED;
|
||||
|
Reference in New Issue
Block a user