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:
committed by
Marge Bot
parent
5f4ad65daf
commit
759d51c367
@@ -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,
|
||||
|
||||
@@ -489,6 +489,36 @@ blorp_fast_clear(struct blorp_batch *batch,
|
||||
batch->blorp->exec(batch, ¶ms);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -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 = ¶ms->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(¶ms->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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user