Example #1
0
static int amdgpu_surface_init(struct radeon_winsys *rws,
                               const struct pipe_resource *tex,
                               unsigned flags, unsigned bpe,
                               enum radeon_surf_mode mode,
                               struct radeon_surf *surf)
{
   struct amdgpu_winsys *ws = (struct amdgpu_winsys*)rws;
   int r;

   r = amdgpu_surface_sanity(tex);
   if (r)
      return r;

   surf->blk_w = util_format_get_blockwidth(tex->format);
   surf->blk_h = util_format_get_blockheight(tex->format);
   surf->bpe = bpe;
   surf->flags = flags;

   struct ac_surf_config config;

   config.info.width = tex->width0;
   config.info.height = tex->height0;
   config.info.depth = tex->depth0;
   config.info.array_size = tex->array_size;
   config.info.samples = tex->nr_samples;
   config.info.levels = tex->last_level + 1;
   config.is_3d = !!(tex->target == PIPE_TEXTURE_3D);
   config.is_cube = !!(tex->target == PIPE_TEXTURE_CUBE);

   return ac_compute_surface(ws->addrlib, &ws->info, &config, mode, surf);
}
Example #2
0
static int amdgpu_surface_init(struct radeon_winsys *rws,
                               struct radeon_surf *surf)
{
   struct amdgpu_winsys *ws = (struct amdgpu_winsys*)rws;
   unsigned level, mode, type;
   bool compressed;
   ADDR_COMPUTE_SURFACE_INFO_INPUT AddrSurfInfoIn = {0};
   ADDR_COMPUTE_SURFACE_INFO_OUTPUT AddrSurfInfoOut = {0};
   ADDR_COMPUTE_DCCINFO_INPUT AddrDccIn = {0};
   ADDR_COMPUTE_DCCINFO_OUTPUT AddrDccOut = {0};
   ADDR_TILEINFO AddrTileInfoIn = {0};
   ADDR_TILEINFO AddrTileInfoOut = {0};
   int r;

   r = amdgpu_surface_sanity(surf);
   if (r)
      return r;

   AddrSurfInfoIn.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT);
   AddrSurfInfoOut.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT);
   AddrDccIn.size = sizeof(ADDR_COMPUTE_DCCINFO_INPUT);
   AddrDccOut.size = sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT);
   AddrSurfInfoOut.pTileInfo = &AddrTileInfoOut;

   type = RADEON_SURF_GET(surf->flags, TYPE);
   mode = RADEON_SURF_GET(surf->flags, MODE);
   compressed = surf->blk_w == 4 && surf->blk_h == 4;

   /* MSAA and FMASK require 2D tiling. */
   if (surf->nsamples > 1 ||
       (surf->flags & RADEON_SURF_FMASK))
      mode = RADEON_SURF_MODE_2D;

   /* DB doesn't support linear layouts. */
   if (surf->flags & (RADEON_SURF_Z_OR_SBUFFER) &&
       mode < RADEON_SURF_MODE_1D)
      mode = RADEON_SURF_MODE_1D;

   /* Set the requested tiling mode. */
   switch (mode) {
   case RADEON_SURF_MODE_LINEAR_ALIGNED:
      AddrSurfInfoIn.tileMode = ADDR_TM_LINEAR_ALIGNED;
      break;
   case RADEON_SURF_MODE_1D:
      AddrSurfInfoIn.tileMode = ADDR_TM_1D_TILED_THIN1;
      break;
   case RADEON_SURF_MODE_2D:
      AddrSurfInfoIn.tileMode = ADDR_TM_2D_TILED_THIN1;
      break;
   default:
      assert(0);
   }

   /* The format must be set correctly for the allocation of compressed
    * textures to work. In other cases, setting the bpp is sufficient. */
   if (compressed) {
      switch (surf->bpe) {
      case 8:
         AddrSurfInfoIn.format = ADDR_FMT_BC1;
         break;
      case 16:
         AddrSurfInfoIn.format = ADDR_FMT_BC3;
         break;
      default:
         assert(0);
      }
   }
   else {
      AddrDccIn.bpp = AddrSurfInfoIn.bpp = surf->bpe * 8;
   }

   AddrDccIn.numSamples = AddrSurfInfoIn.numSamples = surf->nsamples;
   AddrSurfInfoIn.tileIndex = -1;

   /* Set the micro tile type. */
   if (surf->flags & RADEON_SURF_SCANOUT)
      AddrSurfInfoIn.tileType = ADDR_DISPLAYABLE;
   else if (surf->flags & RADEON_SURF_Z_OR_SBUFFER)
      AddrSurfInfoIn.tileType = ADDR_DEPTH_SAMPLE_ORDER;
   else
      AddrSurfInfoIn.tileType = ADDR_NON_DISPLAYABLE;

   AddrSurfInfoIn.flags.color = !(surf->flags & RADEON_SURF_Z_OR_SBUFFER);
   AddrSurfInfoIn.flags.depth = (surf->flags & RADEON_SURF_ZBUFFER) != 0;
   AddrSurfInfoIn.flags.cube = type == RADEON_SURF_TYPE_CUBEMAP;
   AddrSurfInfoIn.flags.display = (surf->flags & RADEON_SURF_SCANOUT) != 0;
   AddrSurfInfoIn.flags.pow2Pad = surf->last_level > 0;
   AddrSurfInfoIn.flags.degrade4Space = 1;

   /* DCC notes:
    * - If we add MSAA support, keep in mind that CB can't decompress 8bpp
    *   with samples >= 4.
    * - Mipmapped array textures have low performance (discovered by a closed
    *   driver team).
    */
   AddrSurfInfoIn.flags.dccCompatible = ws->info.chip_class >= VI &&
                                        !(surf->flags & RADEON_SURF_Z_OR_SBUFFER) &&
                                        !(surf->flags & RADEON_SURF_DISABLE_DCC) &&
                                        !compressed && AddrDccIn.numSamples <= 1 &&
                                        ((surf->array_size == 1 && surf->npix_z == 1) ||
                                         surf->last_level == 0);

   AddrSurfInfoIn.flags.noStencil = (surf->flags & RADEON_SURF_SBUFFER) == 0;
   AddrSurfInfoIn.flags.compressZ = AddrSurfInfoIn.flags.depth;

   /* noStencil = 0 can result in a depth part that is incompatible with
    * mipmapped texturing. So set noStencil = 1 when mipmaps are requested (in
    * this case, we may end up setting stencil_adjusted).
    *
    * TODO: update addrlib to a newer version, remove this, and
    * use flags.matchStencilTileCfg = 1 as an alternative fix.
    */
  if (surf->last_level > 0)
      AddrSurfInfoIn.flags.noStencil = 1;

   /* Set preferred macrotile parameters. This is usually required
    * for shared resources. This is for 2D tiling only. */
   if (AddrSurfInfoIn.tileMode >= ADDR_TM_2D_TILED_THIN1 &&
       surf->bankw && surf->bankh && surf->mtilea && surf->tile_split) {
      /* If any of these parameters are incorrect, the calculation
       * will fail. */
      AddrTileInfoIn.banks = surf->num_banks;
      AddrTileInfoIn.bankWidth = surf->bankw;
      AddrTileInfoIn.bankHeight = surf->bankh;
      AddrTileInfoIn.macroAspectRatio = surf->mtilea;
      AddrTileInfoIn.tileSplitBytes = surf->tile_split;
      AddrTileInfoIn.pipeConfig = surf->pipe_config + 1; /* +1 compared to GB_TILE_MODE */
      AddrSurfInfoIn.flags.degrade4Space = 0;
      AddrSurfInfoIn.pTileInfo = &AddrTileInfoIn;

      /* If AddrSurfInfoIn.pTileInfo is set, Addrlib doesn't set
       * the tile index, because we are expected to know it if
       * we know the other parameters.
       *
       * This is something that can easily be fixed in Addrlib.
       * For now, just figure it out here.
       * Note that only 2D_TILE_THIN1 is handled here.
       */
      assert(!(surf->flags & RADEON_SURF_Z_OR_SBUFFER));
      assert(AddrSurfInfoIn.tileMode == ADDR_TM_2D_TILED_THIN1);

      if (ws->info.chip_class == SI) {
         if (AddrSurfInfoIn.tileType == ADDR_DISPLAYABLE) {
            if (surf->bpe == 2)
               AddrSurfInfoIn.tileIndex = 11; /* 16bpp */
            else
               AddrSurfInfoIn.tileIndex = 12; /* 32bpp */
         } else {
            if (surf->bpe == 1)
               AddrSurfInfoIn.tileIndex = 14; /* 8bpp */
            else if (surf->bpe == 2)
               AddrSurfInfoIn.tileIndex = 15; /* 16bpp */
            else if (surf->bpe == 4)
               AddrSurfInfoIn.tileIndex = 16; /* 32bpp */
            else
               AddrSurfInfoIn.tileIndex = 17; /* 64bpp (and 128bpp) */
         }
      } else {
         /* CIK - VI */
         if (AddrSurfInfoIn.tileType == ADDR_DISPLAYABLE)
            AddrSurfInfoIn.tileIndex = 10; /* 2D displayable */
         else
            AddrSurfInfoIn.tileIndex = 14; /* 2D non-displayable */
      }
   }

   surf->bo_size = 0;
   surf->dcc_size = 0;
   surf->dcc_alignment = 1;

   /* Calculate texture layout information. */
   for (level = 0; level <= surf->last_level; level++) {
      r = compute_level(ws, surf, false, level, type, compressed,
                        &AddrSurfInfoIn, &AddrSurfInfoOut, &AddrDccIn, &AddrDccOut);
      if (r)
         return r;

      if (level == 0) {
         surf->bo_alignment = AddrSurfInfoOut.baseAlign;
         surf->pipe_config = AddrSurfInfoOut.pTileInfo->pipeConfig - 1;
         set_micro_tile_mode(surf, &ws->info);

         /* For 2D modes only. */
         if (AddrSurfInfoOut.tileMode >= ADDR_TM_2D_TILED_THIN1) {
            surf->bankw = AddrSurfInfoOut.pTileInfo->bankWidth;
            surf->bankh = AddrSurfInfoOut.pTileInfo->bankHeight;
            surf->mtilea = AddrSurfInfoOut.pTileInfo->macroAspectRatio;
            surf->tile_split = AddrSurfInfoOut.pTileInfo->tileSplitBytes;
            surf->num_banks = AddrSurfInfoOut.pTileInfo->banks;
            surf->macro_tile_index = AddrSurfInfoOut.macroModeIndex;
         } else {
            surf->macro_tile_index = 0;
         }
      }
   }

   /* Calculate texture layout information for stencil. */
   if (surf->flags & RADEON_SURF_SBUFFER) {
      AddrSurfInfoIn.bpp = 8;
      AddrSurfInfoIn.flags.depth = 0;
      AddrSurfInfoIn.flags.stencil = 1;
      /* This will be ignored if AddrSurfInfoIn.pTileInfo is NULL. */
      AddrTileInfoIn.tileSplitBytes = surf->stencil_tile_split;

      for (level = 0; level <= surf->last_level; level++) {
         r = compute_level(ws, surf, true, level, type, compressed,
                           &AddrSurfInfoIn, &AddrSurfInfoOut, &AddrDccIn, &AddrDccOut);
         if (r)
            return r;

         /* DB uses the depth pitch for both stencil and depth. */
         if (surf->stencil_level[level].nblk_x != surf->level[level].nblk_x)
            surf->stencil_adjusted = true;

         if (level == 0) {
            /* For 2D modes only. */
            if (AddrSurfInfoOut.tileMode >= ADDR_TM_2D_TILED_THIN1) {
               surf->stencil_tile_split =
                     AddrSurfInfoOut.pTileInfo->tileSplitBytes;
            }
         }
      }
   }

   /* Recalculate the whole DCC miptree size including disabled levels.
    * This is what addrlib does, but calling addrlib would be a lot more
    * complicated.
    */
   if (surf->dcc_size && surf->last_level > 0) {
      surf->dcc_size = align64(surf->bo_size >> 8,
                               ws->info.pipe_interleave_bytes *
                               ws->info.num_tile_pipes);
   }