void blorp_ccs_resolve(struct blorp_batch *batch, struct blorp_surf *surf, enum isl_format format) { struct blorp_params params; blorp_params_init(¶ms); brw_blorp_surface_info_init(batch->blorp, ¶ms.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, ¶ms, true); batch->blorp->exec(batch, ¶ms); }
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; }
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; }
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, ¶m->offset[0], ¶m->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); }