Esempio n. 1
0
void
blorp_ccs_resolve(struct blorp_batch *batch,
                  struct blorp_surf *surf, enum isl_format format)
{
   struct blorp_params params;
   blorp_params_init(&params);

   brw_blorp_surface_info_init(batch->blorp, &params.dst, surf,
                               0 /* level */, 0 /* layer */, format, true);

   /* From the Ivy Bridge PRM, Vol2 Part1 11.9 "Render Target Resolve":
    *
    *     A rectangle primitive must be scaled down by the following factors
    *     with respect to render target being resolved.
    *
    * The scaledown factors in the table that follows are related to the block
    * size of the CCS format.  For IVB and HSW, we divide by two, for BDW we
    * multiply by 8 and 16. On Sky Lake, we multiply by 8.
    */
   const struct isl_format_layout *aux_fmtl =
      isl_format_get_layout(params.dst.aux_surf.format);
   assert(aux_fmtl->txc == ISL_TXC_CCS);

   unsigned x_scaledown, y_scaledown;
   if (ISL_DEV_GEN(batch->blorp->isl_dev) >= 9) {
      x_scaledown = aux_fmtl->bw * 8;
      y_scaledown = aux_fmtl->bh * 8;
   } else if (ISL_DEV_GEN(batch->blorp->isl_dev) >= 8) {
      x_scaledown = aux_fmtl->bw * 8;
      y_scaledown = aux_fmtl->bh * 16;
   } else {
      x_scaledown = aux_fmtl->bw / 2;
      y_scaledown = aux_fmtl->bh / 2;
   }
   params.x0 = params.y0 = 0;
   params.x1 = params.dst.aux_surf.logical_level0_px.width;
   params.y1 = params.dst.aux_surf.logical_level0_px.height;
   params.x1 = ALIGN(params.x1, x_scaledown) / x_scaledown;
   params.y1 = ALIGN(params.y1, y_scaledown) / y_scaledown;

   if (batch->blorp->isl_dev->info->gen >= 9) {
      if (params.dst.aux_usage == ISL_AUX_USAGE_CCS_E)
         params.fast_clear_op = BLORP_FAST_CLEAR_OP_RESOLVE_FULL;
      else
         params.fast_clear_op = BLORP_FAST_CLEAR_OP_RESOLVE_PARTIAL;
   } else {
      /* Broadwell and earlier do not have a partial resolve */
      params.fast_clear_op = BLORP_FAST_CLEAR_OP_RESOLVE_FULL;
   }

   /* Note: there is no need to initialize push constants because it doesn't
    * matter what data gets dispatched to the render target.  However, we must
    * ensure that the fragment shader delivers the data using the "replicated
    * color" message.
    */

   blorp_params_get_clear_kernel(batch->blorp, &params, true);

   batch->blorp->exec(batch, &params);
}
Esempio n. 2
0
static bool
gen7_format_needs_valign2(const struct isl_device *dev,
                          enum isl_format format)
{
    assert(ISL_DEV_GEN(dev) == 7);

    /* From the Ivybridge PRM (2012-05-31), Volume 4, Part 1, Section 2.12.1,
     * RENDER_SURFACE_STATE Surface Vertical Alignment:
     *
     *    - Value of 1 [VALIGN_4] is not supported for format YCRCB_NORMAL
     *      (0x182), YCRCB_SWAPUVY (0x183), YCRCB_SWAPUV (0x18f), YCRCB_SWAPY
     *      (0x190)
     *
     *    - VALIGN_4 is not supported for surface format R32G32B32_FLOAT.
     */
    return isl_format_is_yuv(format) ||
           format == ISL_FORMAT_R32G32B32_FLOAT;
}
Esempio n. 3
0
bool
isl_gen7_choose_msaa_layout(const struct isl_device *dev,
                            const struct isl_surf_init_info *info,
                            enum isl_tiling tiling,
                            enum isl_msaa_layout *msaa_layout)
{
    bool require_array = false;
    bool require_interleaved = false;

    assert(ISL_DEV_GEN(dev) == 7);
    assert(info->samples >= 1);

    if (info->samples == 1) {
        *msaa_layout = ISL_MSAA_LAYOUT_NONE;
        return true;
    }

    if (!isl_format_supports_multisampling(dev->info, info->format))
        return false;

    /* From the Ivybridge PRM, Volume 4 Part 1 p73, SURFACE_STATE, Number of
     * Multisamples:
     *
     *    - If this field is any value other than MULTISAMPLECOUNT_1, the
     *      Surface Type must be SURFTYPE_2D.
     *
     *    - If this field is any value other than MULTISAMPLECOUNT_1, Surface
     *      Min LOD, Mip Count / LOD, and Resource Min LOD must be set to zero
     */
    if (info->dim != ISL_SURF_DIM_2D)
        return false;
    if (info->levels > 1)
        return false;

    /* The Ivyrbridge PRM insists twice that signed integer formats cannot be
     * multisampled.
     *
     * From the Ivybridge PRM, Volume 4 Part 1 p73, SURFACE_STATE, Number of
     * Multisamples:
     *
     *    - This field must be set to MULTISAMPLECOUNT_1 for SINT MSRTs when
     *      all RT channels are not written.
     *
     * And errata from the Ivybridge PRM, Volume 4 Part 1 p77,
     * RENDER_SURFACE_STATE, MCS Enable:
     *
     *   This field must be set to 0 [MULTISAMPLECOUNT_1] for all SINT MSRTs
     *   when all RT channels are not written.
     *
     * Note that the above SINT restrictions apply only to *MSRTs* (that is,
     * *multisampled* render targets). The restrictions seem to permit an MCS
     * if the render target is singlesampled.
     */
    if (isl_format_has_sint_channel(info->format))
        return false;

    /* More obvious restrictions */
    if (isl_surf_usage_is_display(info->usage))
        return false;
    if (tiling == ISL_TILING_LINEAR)
        return false;

    /* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
     * Suface Storage Format:
     *
     *    +---------------------+----------------------------------------------------------------+
     *    | MSFMT_MSS           | Multsampled surface was/is rendered as a render target         |
     *    | MSFMT_DEPTH_STENCIL | Multisampled surface was rendered as a depth or stencil buffer |
     *    +---------------------+----------------------------------------------------------------+
     *
     * In the table above, MSFMT_MSS refers to ISL_MSAA_LAYOUT_ARRAY, and
     * MSFMT_DEPTH_STENCIL refers to ISL_MSAA_LAYOUT_INTERLEAVED.
     */
    if (isl_surf_usage_is_depth_or_stencil(info->usage) ||
            (info->usage & ISL_SURF_USAGE_HIZ_BIT))
        require_interleaved = true;

    /* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
     * Suface Storage Format:
     *
     *    If the surface’s Number of Multisamples is MULTISAMPLECOUNT_8, Width
     *    is >= 8192 (meaning the actual surface width is >= 8193 pixels), this
     *    field must be set to MSFMT_MSS.
     */
    if (info->samples == 8 && info->width == 8192)
        require_array = true;

    /* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
     * Suface Storage Format:
     *
     *    If the surface’s Number of Multisamples is MULTISAMPLECOUNT_8,
     *    ((Depth+1) * (Height+1)) is > 4,194,304, OR if the surface’s Number
     *    of Multisamples is MULTISAMPLECOUNT_4, ((Depth+1) * (Height+1)) is
     *    > 8,388,608, this field must be set to MSFMT_DEPTH_STENCIL.
     */
    if ((info->samples == 8 && info->height > 4194304u) ||
            (info->samples == 4 && info->height > 8388608u))
        require_interleaved = true;

    /* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
     * Suface Storage Format:
     *
     *    This field must be set to MSFMT_DEPTH_STENCIL if Surface Format is
     *    one of the following: I24X8_UNORM, L24X8_UNORM, A24X8_UNORM, or
     *    R24_UNORM_X8_TYPELESS.
     */
    if (info->format == ISL_FORMAT_I24X8_UNORM ||
            info->format == ISL_FORMAT_L24X8_UNORM ||
            info->format == ISL_FORMAT_A24X8_UNORM ||
            info->format == ISL_FORMAT_R24_UNORM_X8_TYPELESS)
        require_interleaved = true;

    if (require_array && require_interleaved)
        return false;

    if (require_interleaved) {
        *msaa_layout = ISL_MSAA_LAYOUT_INTERLEAVED;
        return true;
    }

    /* Default to the array layout because it permits multisample
     * compression.
     */
    *msaa_layout = ISL_MSAA_LAYOUT_ARRAY;
    return true;
}
Esempio n. 4
0
void
isl_surf_fill_image_param(const struct isl_device *dev,
                          struct brw_image_param *param,
                          const struct isl_surf *surf,
                          const struct isl_view *view)
{
   *param = image_param_defaults;

   param->size[0] = isl_minify(surf->logical_level0_px.w, view->base_level);
   param->size[1] = isl_minify(surf->logical_level0_px.h, view->base_level);
   if (surf->dim == ISL_SURF_DIM_3D) {
      param->size[2] = isl_minify(surf->logical_level0_px.d, view->base_level);
   } else {
      param->size[2] = surf->logical_level0_px.array_len -
                       view->base_array_layer;
   }

   isl_surf_get_image_offset_el(surf, view->base_level,
                                surf->dim == ISL_SURF_DIM_3D ?
                                   0 : view->base_array_layer,
                                surf->dim == ISL_SURF_DIM_3D ?
                                   view->base_array_layer : 0,
                                &param->offset[0],  &param->offset[1]);

   const int cpp = isl_format_get_layout(surf->format)->bpb / 8;
   param->stride[0] = cpp;
   param->stride[1] = surf->row_pitch / cpp;

   const struct isl_extent3d image_align_sa =
      isl_surf_get_image_alignment_sa(surf);
   if (ISL_DEV_GEN(dev) < 9 && surf->dim == ISL_SURF_DIM_3D) {
      param->stride[2] = isl_align_npot(param->size[0], image_align_sa.w);
      param->stride[3] = isl_align_npot(param->size[1], image_align_sa.h);
   } else {
      param->stride[2] = 0;
      param->stride[3] = isl_surf_get_array_pitch_el_rows(surf);
   }

   switch (surf->tiling) {
   case ISL_TILING_LINEAR:
      /* image_param_defaults is good enough */
      break;

   case ISL_TILING_X:
      /* An X tile is a rectangular block of 512x8 bytes. */
      param->tiling[0] = isl_log2u(512 / cpp);
      param->tiling[1] = isl_log2u(8);

      if (dev->has_bit6_swizzling) {
         /* Right shifts required to swizzle bits 9 and 10 of the memory
          * address with bit 6.
          */
         param->swizzling[0] = 3;
         param->swizzling[1] = 4;
      }
      break;

   case ISL_TILING_Y0:
      /* The layout of a Y-tiled surface in memory isn't really fundamentally
       * different to the layout of an X-tiled surface, we simply pretend that
       * the surface is broken up in a number of smaller 16Bx32 tiles, each
       * one arranged in X-major order just like is the case for X-tiling.
       */
      param->tiling[0] = isl_log2u(16 / cpp);
      param->tiling[1] = isl_log2u(32);

      if (dev->has_bit6_swizzling) {
         /* Right shift required to swizzle bit 9 of the memory address with
          * bit 6.
          */
         param->swizzling[0] = 3;
         param->swizzling[1] = 0xff;
      }
      break;

   default:
      assert(!"Unhandled storage image tiling");
   }

   /* 3D textures are arranged in 2D in memory with 2^lod slices per row.  The
    * address calculation algorithm (emit_address_calculation() in
    * brw_fs_surface_builder.cpp) handles this as a sort of tiling with
    * modulus equal to the LOD.
    */
   param->tiling[2] = (ISL_DEV_GEN(dev) < 9 && surf->dim == ISL_SURF_DIM_3D ?
                       view->base_level : 0);
}