AddrSurfInfoIn->bpp) {
unsigned alignment = 256 / (AddrSurfInfoIn->bpp / 8);
- assert(util_is_power_of_two(AddrSurfInfoIn->bpp));
+ assert(util_is_power_of_two_or_zero(AddrSurfInfoIn->bpp));
AddrSurfInfoIn->width = align(AddrSurfInfoIn->width, alignment);
}
return index;
}
+static bool get_display_flag(const struct ac_surf_config *config,
+ const struct radeon_surf *surf)
+{
+ unsigned num_channels = config->info.num_channels;
+ unsigned bpe = surf->bpe;
+
+ if (surf->flags & RADEON_SURF_SCANOUT &&
+ !(surf->flags & RADEON_SURF_FMASK) &&
+ config->info.samples <= 1 &&
+ surf->blk_w <= 2 && surf->blk_h == 1) {
+ /* subsampled */
+ if (surf->blk_w == 2 && surf->blk_h == 1)
+ return true;
+
+ if (/* RGBA8 or RGBA16F */
+ (bpe >= 4 && bpe <= 8 && num_channels == 4) ||
+ /* R5G6B5 or R5G5B5A1 */
+ (bpe == 2 && num_channels >= 3) ||
+ /* C8 palette */
+ (bpe == 1 && num_channels == 1))
+ return true;
+ }
+ return false;
+}
+
/**
* This must be called after the first level is computed.
*
config->info.surf_index &&
surf->u.legacy.level[0].mode == RADEON_SURF_MODE_2D &&
!(surf->flags & (RADEON_SURF_Z_OR_SBUFFER | RADEON_SURF_SHAREABLE)) &&
- (config->info.samples > 1 || !(surf->flags & RADEON_SURF_SCANOUT))) {
+ !get_display_flag(config, surf)) {
ADDR_COMPUTE_BASE_SWIZZLE_INPUT AddrBaseSwizzleIn = {0};
ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT AddrBaseSwizzleOut = {0};
AddrSurfInfoIn.flags.depth = (surf->flags & RADEON_SURF_ZBUFFER) != 0;
AddrSurfInfoIn.flags.cube = config->is_cube;
AddrSurfInfoIn.flags.fmask = (surf->flags & RADEON_SURF_FMASK) != 0;
- AddrSurfInfoIn.flags.display = (surf->flags & RADEON_SURF_SCANOUT) != 0;
+ AddrSurfInfoIn.flags.display = get_display_flag(config, surf);
AddrSurfInfoIn.flags.pow2Pad = config->info.levels > 1;
AddrSurfInfoIn.flags.tcCompatible = (surf->flags & RADEON_SURF_TC_COMPATIBLE_HTILE) != 0;
static int
gfx9_get_preferred_swizzle_mode(ADDR_HANDLE addrlib,
ADDR2_COMPUTE_SURFACE_INFO_INPUT *in,
- bool is_fmask, AddrSwizzleMode *swizzle_mode)
+ bool is_fmask, unsigned flags,
+ AddrSwizzleMode *swizzle_mode)
{
ADDR_E_RETURNCODE ret;
ADDR2_GET_PREFERRED_SURF_SETTING_INPUT sin = {0};
sin.numSamples = in->numSamples;
sin.numFrags = in->numFrags;
+ if (flags & RADEON_SURF_SCANOUT)
+ sin.preferredSwSet.sw_D = 1;
+ else if (in->flags.depth || in->flags.stencil || is_fmask)
+ sin.preferredSwSet.sw_Z = 1;
+ else
+ sin.preferredSwSet.sw_S = 1;
+
if (is_fmask) {
+ sin.flags.display = 0;
sin.flags.color = 0;
sin.flags.fmask = 1;
}
in->swizzleMode >= ADDR_SW_64KB_Z_T &&
!out.mipChainInTail &&
!(surf->flags & RADEON_SURF_SHAREABLE) &&
- (in->numSamples > 1 || !(surf->flags & RADEON_SURF_SCANOUT))) {
+ !in->flags.display) {
ADDR2_COMPUTE_PIPEBANKXOR_INPUT xin = {0};
ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT xout = {0};
fin.size = sizeof(ADDR2_COMPUTE_FMASK_INFO_INPUT);
fout.size = sizeof(ADDR2_COMPUTE_FMASK_INFO_OUTPUT);
- ret = gfx9_get_preferred_swizzle_mode(addrlib, in, true, &fin.swizzleMode);
+ ret = gfx9_get_preferred_swizzle_mode(addrlib, in,
+ true, surf->flags,
+ &fin.swizzleMode);
if (ret != ADDR_OK)
return ret;
AddrSurfInfoIn.flags.color = !(surf->flags & RADEON_SURF_Z_OR_SBUFFER);
AddrSurfInfoIn.flags.depth = (surf->flags & RADEON_SURF_ZBUFFER) != 0;
- AddrSurfInfoIn.flags.display = (surf->flags & RADEON_SURF_SCANOUT) != 0;
+ AddrSurfInfoIn.flags.display = get_display_flag(config, surf);
/* flags.texture currently refers to TC-compatible HTILE */
AddrSurfInfoIn.flags.texture = AddrSurfInfoIn.flags.color ||
surf->flags & RADEON_SURF_TC_COMPATIBLE_HTILE;
break;
}
- r = gfx9_get_preferred_swizzle_mode(addrlib, &AddrSurfInfoIn, false,
+ r = gfx9_get_preferred_swizzle_mode(addrlib, &AddrSurfInfoIn,
+ false, surf->flags,
&AddrSurfInfoIn.swizzleMode);
if (r)
return r;
AddrSurfInfoIn.format = ADDR_FMT_8;
if (!AddrSurfInfoIn.flags.depth) {
- r = gfx9_get_preferred_swizzle_mode(addrlib, &AddrSurfInfoIn, false,
+ r = gfx9_get_preferred_swizzle_mode(addrlib, &AddrSurfInfoIn,
+ false, surf->flags,
&AddrSurfInfoIn.swizzleMode);
if (r)
return r;