blorp: Implement blitter clears via XY_FAST_COLOR_BLT

Vulkan transfer queues need this functionality.  A lot of the code is
pretty similar to what we have for XY_BLOCK_COPY_BLT.

Reviewed-by: Ivan Briano <ivan.briano@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15183>
This commit is contained in:
Kenneth Graunke
2022-02-01 00:12:46 -08:00
committed by Marge Bot
parent 5f4ad65daf
commit 759d51c367
3 changed files with 126 additions and 6 deletions
+5
View File
@@ -210,6 +210,11 @@ blorp_clear_supports_compute(struct blorp_context *blorp,
uint8_t color_write_disable, bool blend_enabled,
enum isl_aux_usage aux_usage);
bool
blorp_clear_supports_blitter(struct blorp_context *blorp,
const struct blorp_surf *surf,
uint8_t color_write_disable, bool blend_enabled);
bool
blorp_copy_supports_compute(struct blorp_context *blorp,
const struct isl_surf *src_surf,
+35 -1
View File
@@ -489,6 +489,36 @@ blorp_fast_clear(struct blorp_batch *batch,
batch->blorp->exec(batch, &params);
}
bool
blorp_clear_supports_blitter(struct blorp_context *blorp,
const struct blorp_surf *surf,
uint8_t color_write_disable,
bool blend_enabled)
{
const struct intel_device_info *devinfo = blorp->isl_dev->info;
if (devinfo->ver < 12)
return false;
if (surf->surf->samples > 1)
return false;
if (color_write_disable != 0 || blend_enabled)
return false;
if (!blorp_blitter_supports_aux(devinfo, surf->aux_usage))
return false;
const struct isl_format_layout *fmtl =
isl_format_get_layout(surf->surf->format);
/* We can only support linear mode for 96bpp. */
if (fmtl->bpb == 96 && surf->surf->tiling != ISL_TILING_LINEAR)
return false;
return true;
}
bool
blorp_clear_supports_compute(struct blorp_context *blorp,
uint8_t color_write_disable, bool blend_enabled,
@@ -521,9 +551,13 @@ blorp_clear(struct blorp_batch *batch,
params.op = BLORP_OP_SLOW_COLOR_CLEAR;
const bool compute = batch->flags & BLORP_BATCH_USE_COMPUTE;
if (compute)
if (compute) {
assert(blorp_clear_supports_compute(batch->blorp, color_write_disable,
false, surf->aux_usage));
} else if (batch->flags & BLORP_BATCH_USE_BLITTER) {
assert(blorp_clear_supports_blitter(batch->blorp, surf,
color_write_disable, false));
}
/* Manually apply the clear destination swizzle. This way swizzled clears
* will work for swizzles which we can't normally use for rendering and it
+86 -5
View File
@@ -2537,17 +2537,98 @@ blorp_xy_block_copy_blt(struct blorp_batch *batch,
#endif
}
UNUSED static void
blorp_xy_fast_color_blit(struct blorp_batch *batch,
const struct blorp_params *params)
{
#if GFX_VER < 12
unreachable("Blitter is only supported on Gfx12+");
#else
UNUSED const struct isl_device *isl_dev = batch->blorp->isl_dev;
const struct isl_surf *dst_surf = &params->dst.surf;
const struct isl_format_layout *fmtl =
isl_format_get_layout(params->dst.view.format);
assert(batch->flags & BLORP_BATCH_USE_BLITTER);
assert(!(batch->flags & BLORP_BATCH_NO_UPDATE_CLEAR_COLOR));
assert(!(batch->flags & BLORP_BATCH_PREDICATE_ENABLE));
assert(params->hiz_op == ISL_AUX_OP_NONE);
assert(params->num_layers == 1);
assert(params->dst.view.levels == 1);
assert(dst_surf->samples == 1);
assert(fmtl->bpb != 96 || dst_surf->tiling == ISL_TILING_LINEAR);
#if GFX_VERx10 < 125
assert(params->dst.view.base_array_layer == 0);
assert(params->dst.z_offset == 0);
#endif
unsigned dst_pitch_unit = dst_surf->tiling == ISL_TILING_LINEAR ? 1 : 4;
#if GFX_VERx10 >= 125
struct isl_extent3d dst_align = isl_get_image_alignment(dst_surf);
#endif
blorp_emit(batch, GENX(XY_FAST_COLOR_BLT), blt) {
blt.ColorDepth = xy_color_depth(fmtl);
blt.DestinationPitch = (dst_surf->row_pitch_B / dst_pitch_unit) - 1;
blt.DestinationTiling = xy_bcb_tiling(dst_surf);
blt.DestinationX1 = params->x0;
blt.DestinationY1 = params->y0;
blt.DestinationX2 = params->x1;
blt.DestinationY2 = params->y1;
blt.DestinationBaseAddress = params->dst.addr;
blt.DestinationXOffset = params->dst.tile_x_sa;
blt.DestinationYOffset = params->dst.tile_y_sa;
isl_color_value_pack((union isl_color_value *)
params->wm_inputs.clear_color,
params->dst.view.format, blt.FillColor);
#if GFX_VERx10 >= 125
blt.DestinationSurfaceType = xy_bcb_surf_dim(dst_surf);
blt.DestinationSurfaceWidth = dst_surf->logical_level0_px.w - 1;
blt.DestinationSurfaceHeight = dst_surf->logical_level0_px.h - 1;
blt.DestinationSurfaceDepth = xy_bcb_surf_depth(dst_surf) - 1;
blt.DestinationArrayIndex =
params->dst.view.base_array_layer + params->dst.z_offset;
blt.DestinationSurfaceQPitch = isl_get_qpitch(dst_surf) >> 2;
blt.DestinationLOD = params->dst.view.base_level;
blt.DestinationMipTailStartLOD = 15;
blt.DestinationHorizontalAlign = isl_encode_halign(dst_align.width);
blt.DestinationVerticalAlign = isl_encode_valign(dst_align.height);
blt.DestinationDepthStencilResource = false;
blt.DestinationTargetMemory =
params->dst.addr.local_hint ? XY_MEM_LOCAL : XY_MEM_SYSTEM;
if (params->dst.aux_usage != ISL_AUX_USAGE_NONE) {
blt.DestinationAuxiliarySurfaceMode = xy_aux_mode(&params->dst);
blt.DestinationCompressionEnable = true;
blt.DestinationCompressionFormat =
isl_get_render_compression_format(dst_surf->format);
blt.DestinationClearValueEnable = !!params->dst.clear_color_addr.buffer;
blt.DestinationClearAddress = params->dst.clear_color_addr;
}
/* XeHP needs special MOCS values for the blitter */
blt.DestinationMOCS = isl_dev->mocs.blitter_dst;
#endif
}
#endif
}
static void
blorp_exec_blitter(struct blorp_batch *batch,
const struct blorp_params *params)
{
blorp_measure_start(batch, params);
/* Someday, if we implement clears on the blit enginer, we can
* use params->src.enabled to determine which case we're in.
*/
assert(params->src.enabled);
blorp_xy_block_copy_blt(batch, params);
if (params->src.enabled)
blorp_xy_block_copy_blt(batch, params);
else
blorp_xy_fast_color_blit(batch, params);
blorp_measure_end(batch, params);
}