diff options
-rw-r--r-- | src/amd/common/ac_surface.c | 85 | ||||
-rw-r--r-- | src/amd/common/ac_surface.h | 6 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/r600_texture.c | 1 | ||||
-rw-r--r-- | src/gallium/winsys/amdgpu/drm/amdgpu_surface.c | 2 |
4 files changed, 91 insertions, 3 deletions
diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c index 590920ee2b6..92bdf1dedec 100644 --- a/src/amd/common/ac_surface.c +++ b/src/amd/common/ac_surface.c @@ -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; } diff --git a/src/amd/common/ac_surface.h b/src/amd/common/ac_surface.h index f18548f73e4..71f320af8ee 100644 --- a/src/amd/common/ac_surface.h +++ b/src/amd/common/ac_surface.h @@ -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 { diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index 125e7ef4089..3a0a79187b8 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -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; } diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c index fabc6ccd93b..fc5c9d5a127 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_surface.c @@ -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); } |