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 "tu_formats.h"
|
||||||
|
|
||||||
#include "fdl/fd6_format_table.h"
|
#include "fdl/fd6_format_table.h"
|
||||||
|
#include "common/freedreno_ubwc.h"
|
||||||
|
|
||||||
#include "vk_android.h"
|
#include "vk_android.h"
|
||||||
#include "vk_enum_defines.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;
|
return fmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum tu6_ubwc_compat_type {
|
static enum fd6_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
|
|
||||||
tu6_ubwc_compat_mode(const struct fd_dev_info *info, VkFormat format)
|
tu6_ubwc_compat_mode(const struct fd_dev_info *info, VkFormat format)
|
||||||
{
|
{
|
||||||
switch (format) {
|
return fd6_ubwc_compat_mode(info, vk_format_to_pipe_format(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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -213,9 +115,9 @@ tu6_mutable_format_list_ubwc_compatible(const struct fd_dev_info *info,
|
|||||||
if (fmt_list->viewFormatCount == 1)
|
if (fmt_list->viewFormatCount == 1)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
enum tu6_ubwc_compat_type type =
|
enum fd6_ubwc_compat_type type =
|
||||||
tu6_ubwc_compat_mode(info, fmt_list->pViewFormats[0]);
|
tu6_ubwc_compat_mode(info, fmt_list->pViewFormats[0]);
|
||||||
if (type == TU6_UBWC_UNKNOWN_COMPAT)
|
if (type == FD6_UBWC_UNKNOWN_COMPAT)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (uint32_t i = 1; i < fmt_list->viewFormatCount; i++) {
|
for (uint32_t i = 1; i < fmt_list->viewFormatCount; i++) {
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
#include "a6xx/fd6_blitter.h"
|
#include "a6xx/fd6_blitter.h"
|
||||||
#include "fd6_resource.h"
|
#include "fd6_resource.h"
|
||||||
#include "fdl/fd6_format_table.h"
|
#include "fdl/fd6_format_table.h"
|
||||||
|
#include "common/freedreno_ubwc.h"
|
||||||
|
|
||||||
#include "a6xx.xml.h"
|
#include "a6xx.xml.h"
|
||||||
|
|
||||||
@@ -127,14 +128,6 @@ can_do_ubwc(struct pipe_resource *prsc)
|
|||||||
return true;
|
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
|
static bool
|
||||||
is_z24s8(enum pipe_format format)
|
is_z24s8(enum pipe_format format)
|
||||||
{
|
{
|
||||||
@@ -150,8 +143,12 @@ is_z24s8(enum pipe_format format)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
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: */
|
/* Special case "casting" format in hw: */
|
||||||
if (format == PIPE_FORMAT_Z24_UNORM_S8_UINT_AS_R8G8B8A8)
|
if (format == PIPE_FORMAT_Z24_UNORM_S8_UINT_AS_R8G8B8A8)
|
||||||
return true;
|
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))
|
is_z24s8(format) && is_z24s8(rsc->b.b.format))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* For some color values (just "solid white") compression metadata maps to
|
return fd6_ubwc_compat_mode(info, format) ==
|
||||||
* different pixel values for uint/sint vs unorm/snorm, so we can't reliably
|
fd6_ubwc_compat_mode(info, rsc->b.b.format);
|
||||||
* "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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -217,7 +195,8 @@ fd6_check_valid_format(struct fd_resource *rsc, enum pipe_format format)
|
|||||||
if (!rsc->layout.ubwc)
|
if (!rsc->layout.ubwc)
|
||||||
return FORMAT_OK;
|
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 FORMAT_OK;
|
||||||
|
|
||||||
return DEMOTE_TO_TILED;
|
return DEMOTE_TO_TILED;
|
||||||
|
Reference in New Issue
Block a user