ac/surface: compute tile swizzle for GFX9

Tested-by: Dieter Nützel <Dieter@nuetzel-hh.de>
This commit is contained in:
Marek Olšák 2017-07-29 01:40:48 +02:00
parent 9f0c9c6d18
commit f7ffa504a0
4 changed files with 91 additions and 3 deletions

View file

@ -849,6 +849,7 @@ gfx9_get_preferred_swizzle_mode(ADDR_HANDLE addrlib,
}
static int gfx9_compute_miptree(ADDR_HANDLE addrlib,
const struct ac_surf_config *config,
struct radeon_surf *surf, bool compressed,
ADDR2_COMPUTE_SURFACE_INFO_INPUT *in)
{
@ -923,6 +924,37 @@ static int gfx9_compute_miptree(ADDR_HANDLE addrlib,
surf->htile_slice_size = hout.sliceSize;
surf->htile_alignment = hout.baseAlign;
} else {
/* Compute tile swizzle for the color surface.
* All *_X and *_T modes can use the swizzle.
*/
if (config->info.surf_index &&
in->swizzleMode >= ADDR_SW_64KB_Z_T &&
!out.mipChainInTail &&
!(surf->flags & RADEON_SURF_SHAREABLE) &&
(in->numSamples > 1 || !(surf->flags & RADEON_SURF_SCANOUT))) {
ADDR2_COMPUTE_PIPEBANKXOR_INPUT xin = {0};
ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT xout = {0};
xin.size = sizeof(ADDR2_COMPUTE_PIPEBANKXOR_INPUT);
xout.size = sizeof(ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT);
xin.surfIndex = p_atomic_inc_return(config->info.surf_index) - 1;
xin.flags = in->flags;
xin.swizzleMode = in->swizzleMode;
xin.resourceType = in->resourceType;
xin.format = in->format;
xin.numSamples = in->numSamples;
xin.numFrags = in->numFrags;
ret = Addr2ComputePipeBankXor(addrlib, &xin, &xout);
if (ret != ADDR_OK)
return ret;
assert(xout.pipeBankXor <=
u_bit_consecutive(0, sizeof(surf->tile_swizzle) * 8));
surf->tile_swizzle = xout.pipeBankXor;
}
/* DCC */
if (!(surf->flags & RADEON_SURF_DISABLE_DCC) &&
!compressed &&
@ -1018,6 +1050,34 @@ static int gfx9_compute_miptree(ADDR_HANDLE addrlib,
surf->u.gfx9.fmask.epitch = fout.pitch - 1;
surf->u.gfx9.fmask_size = fout.fmaskBytes;
surf->u.gfx9.fmask_alignment = fout.baseAlign;
/* Compute tile swizzle for the FMASK surface. */
if (config->info.fmask_surf_index &&
fin.swizzleMode >= ADDR_SW_64KB_Z_T &&
!(surf->flags & RADEON_SURF_SHAREABLE)) {
ADDR2_COMPUTE_PIPEBANKXOR_INPUT xin = {0};
ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT xout = {0};
xin.size = sizeof(ADDR2_COMPUTE_PIPEBANKXOR_INPUT);
xout.size = sizeof(ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT);
/* This counter starts from 1 instead of 0. */
xin.surfIndex = p_atomic_inc_return(config->info.fmask_surf_index);
xin.flags = in->flags;
xin.swizzleMode = in->swizzleMode;
xin.resourceType = in->resourceType;
xin.format = in->format;
xin.numSamples = in->numSamples;
xin.numFrags = in->numFrags;
ret = Addr2ComputePipeBankXor(addrlib, &xin, &xout);
if (ret != ADDR_OK)
return ret;
assert(xout.pipeBankXor <=
u_bit_consecutive(0, sizeof(surf->u.gfx9.fmask_tile_swizzle) * 8));
surf->u.gfx9.fmask_tile_swizzle = xout.pipeBankXor;
}
}
/* CMASK */
@ -1084,6 +1144,25 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
assert(0);
}
} else {
switch (surf->bpe) {
case 1:
AddrSurfInfoIn.format = ADDR_FMT_8;
break;
case 2:
AddrSurfInfoIn.format = ADDR_FMT_16;
break;
case 4:
AddrSurfInfoIn.format = ADDR_FMT_32;
break;
case 8:
AddrSurfInfoIn.format = ADDR_FMT_32_32;
break;
case 16:
AddrSurfInfoIn.format = ADDR_FMT_32_32_32_32;
break;
default:
assert(0);
}
AddrSurfInfoIn.bpp = surf->bpe * 8;
}
@ -1155,7 +1234,8 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
surf->u.gfx9.cmask_size = 0;
/* Calculate texture layout information. */
r = gfx9_compute_miptree(addrlib, surf, compressed, &AddrSurfInfoIn);
r = gfx9_compute_miptree(addrlib, config, surf, compressed,
&AddrSurfInfoIn);
if (r)
return r;
@ -1172,7 +1252,8 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
} else
AddrSurfInfoIn.flags.depth = 0;
r = gfx9_compute_miptree(addrlib, surf, compressed, &AddrSurfInfoIn);
r = gfx9_compute_miptree(addrlib, config, surf, compressed,
&AddrSurfInfoIn);
if (r)
return r;
}

View file

@ -147,6 +147,8 @@ struct gfx9_surf_layout {
uint32_t fmask_alignment;
uint32_t cmask_alignment;
uint8_t fmask_tile_swizzle;
};
struct radeon_surf {
@ -175,7 +177,8 @@ struct radeon_surf {
/* Tile swizzle can be OR'd with low bits of the BASE_256B address.
* The value is the same for all mipmap levels. Supported tile modes:
* - GFX6: Only macro tiling.
* - GFX9: Only *_X swizzle modes. Level 0 must not be in the mip tail.
* - GFX9: Only *_X and *_T swizzle modes. Level 0 must not be in the mip
* tail.
*
* Only these surfaces are allowed to set it:
* - color (if it doesn't have to be displayable)
@ -218,6 +221,7 @@ struct ac_surf_info {
uint8_t levels;
uint16_t array_size;
uint32_t *surf_index; /* Set a monotonic counter for tile swizzling. */
uint32_t *fmask_surf_index; /* GFX9+ */
};
struct ac_surf_config {

View file

@ -848,6 +848,7 @@ void si_texture_get_fmask_info(struct si_screen *sscreen,
if (sscreen->info.chip_class >= GFX9) {
out->alignment = rtex->surface.u.gfx9.fmask_alignment;
out->size = rtex->surface.u.gfx9.fmask_size;
out->tile_swizzle = rtex->surface.u.gfx9.fmask_tile_swizzle;
return;
}

View file

@ -100,6 +100,8 @@ static int amdgpu_surface_init(struct radeon_winsys *rws,
else
config.info.surf_index = NULL;
config.info.fmask_surf_index = &ws->surf_index_fmask;
return ac_compute_surface(ws->addrlib, &ws->info, &config, mode, surf);
}