Exemple #1
0
static void surf_drm_to_winsys(struct radeon_drm_winsys *ws,
                               struct radeon_surf *surf_ws,
                               const struct radeon_surface *surf_drm)
{
    int i;

    memset(surf_ws, 0, sizeof(*surf_ws));

    surf_ws->blk_w = surf_drm->blk_w;
    surf_ws->blk_h = surf_drm->blk_h;
    surf_ws->bpe = surf_drm->bpe;
    surf_ws->is_linear = surf_drm->level[0].mode <= RADEON_SURF_MODE_LINEAR_ALIGNED;
    surf_ws->has_stencil = !!(surf_drm->flags & RADEON_SURF_SBUFFER);
    surf_ws->flags = surf_drm->flags;

    surf_ws->surf_size = surf_drm->bo_size;
    surf_ws->surf_alignment = surf_drm->bo_alignment;

    surf_ws->u.legacy.bankw = surf_drm->bankw;
    surf_ws->u.legacy.bankh = surf_drm->bankh;
    surf_ws->u.legacy.mtilea = surf_drm->mtilea;
    surf_ws->u.legacy.tile_split = surf_drm->tile_split;

    surf_ws->u.legacy.macro_tile_index = cik_get_macro_tile_index(surf_ws);

    for (i = 0; i <= surf_drm->last_level; i++) {
        surf_level_drm_to_winsys(&surf_ws->u.legacy.level[i], &surf_drm->level[i],
                                 surf_drm->bpe * surf_drm->nsamples);
        surf_ws->u.legacy.tiling_index[i] = surf_drm->tiling_index[i];
    }

    if (surf_ws->flags & RADEON_SURF_SBUFFER) {
        surf_ws->u.legacy.stencil_tile_split = surf_drm->stencil_tile_split;

        for (i = 0; i <= surf_drm->last_level; i++) {
            surf_level_drm_to_winsys(&surf_ws->u.legacy.stencil_level[i],
                                     &surf_drm->stencil_level[i],
                                     surf_drm->nsamples);
            surf_ws->u.legacy.stencil_tiling_index[i] = surf_drm->stencil_tiling_index[i];
        }
    }

    set_micro_tile_mode(surf_ws, &ws->info);
    surf_ws->is_displayable = surf_ws->is_linear ||
			      surf_ws->micro_tile_mode == RADEON_MICRO_MODE_DISPLAY ||
			      surf_ws->micro_tile_mode == RADEON_MICRO_MODE_ROTATED;
}
Exemple #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);
   }