From 842b8c8965327615f4692384a905dd63f1fba63d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 1 Aug 2021 19:59:31 -0400 Subject: [PATCH] crocus: add support for set alpha to one with blt. This is ported from 965 and fixes dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.*rebind_tex2d_rgb* Fixes: f3630548f1da9 ("crocus: initial gallium driver for Intel gfx 4-7") Part-of: --- src/gallium/drivers/crocus/crocus_blt.c | 89 +++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 11 deletions(-) diff --git a/src/gallium/drivers/crocus/crocus_blt.c b/src/gallium/drivers/crocus/crocus_blt.c index b6b8368..fd318a8 100644 --- a/src/gallium/drivers/crocus/crocus_blt.c +++ b/src/gallium/drivers/crocus/crocus_blt.c @@ -31,6 +31,69 @@ #if GFX_VER <= 5 +static uint32_t +color_depth_for_cpp(int cpp) +{ + switch (cpp) { + case 4: return COLOR_DEPTH__32bit; + case 2: return COLOR_DEPTH__565; + case 1: return COLOR_DEPTH__8bit; + default: + unreachable("not reached"); + } +} + +static void +blt_set_alpha_to_one(struct crocus_batch *batch, + struct crocus_resource *dst, + int x, int y, int width, int height) +{ + const struct isl_format_layout *fmtl = isl_format_get_layout(dst->surf.format); + unsigned cpp = fmtl->bpb / 8; + uint32_t pitch = dst->surf.row_pitch_B; + + if (dst->surf.tiling != ISL_TILING_LINEAR) + pitch /= 4; + /* We need to split the blit into chunks that each fit within the blitter's + * restrictions. We can't use a chunk size of 32768 because we need to + * ensure that src_tile_x + chunk_size fits. We choose 16384 because it's + * a nice round power of two, big enough that performance won't suffer, and + * small enough to guarantee everything fits. + */ + const uint32_t max_chunk_size = 16384; + + for (uint32_t chunk_x = 0; chunk_x < width; chunk_x += max_chunk_size) { + for (uint32_t chunk_y = 0; chunk_y < height; chunk_y += max_chunk_size) { + const uint32_t chunk_w = MIN2(max_chunk_size, width - chunk_x); + const uint32_t chunk_h = MIN2(max_chunk_size, height - chunk_y); + uint32_t tile_x, tile_y, offset; + ASSERTED uint32_t z_offset_el, array_offset; + isl_tiling_get_intratile_offset_el(dst->surf.tiling, + cpp * 8, dst->surf.row_pitch_B, + dst->surf.array_pitch_el_rows, + chunk_x, chunk_y, 0, 0, + &offset, + &tile_x, &tile_y, + &z_offset_el, &array_offset); + assert(z_offset_el == 0); + assert(array_offset == 0); + crocus_emit_cmd(batch, GENX(XY_COLOR_BLT), xyblt) { + xyblt.TilingEnable = dst->surf.tiling != ISL_TILING_LINEAR; + xyblt.ColorDepth = color_depth_for_cpp(cpp); + xyblt.RasterOperation = 0xF0; + xyblt.DestinationPitch = pitch; + xyblt._32bppByteMask = 2; + xyblt.DestinationBaseAddress = rw_bo(dst->bo, offset); + xyblt.DestinationX1Coordinate = tile_x; + xyblt.DestinationY1Coordinate = tile_y; + xyblt.DestinationX2Coordinate = tile_x + chunk_w; + xyblt.DestinationY2Coordinate = tile_y + chunk_h; + xyblt.SolidPatternColor = 0xffffffff; + } + } + } +} + static bool validate_blit_for_blt(struct crocus_batch *batch, const struct pipe_blit_info *info) { @@ -51,6 +114,17 @@ static bool validate_blit_for_blt(struct crocus_batch *batch, if (info->dst.box.depth > 1 || info->src.box.depth > 1) return false; + const struct util_format_description *desc = + util_format_description(info->src.format); + int i = util_format_get_first_non_void_channel(info->src.format); + if (i == -1) + return false; + + /* can't do the alpha to 1 setting for these. */ + if ((util_format_has_alpha1(info->src.format) && + util_format_has_alpha(info->dst.format) && + desc->channel[i].size > 8)) + return false; return true; } @@ -62,17 +136,6 @@ static inline int crocus_resource_blt_pitch(struct crocus_resource *res) return pitch; } -static uint32_t -color_depth_for_cpp(int cpp) -{ - switch (cpp) { - case 4: return COLOR_DEPTH__32bit; - case 2: return COLOR_DEPTH__565; - case 1: return COLOR_DEPTH__8bit; - default: - unreachable("not reached"); - } -} static bool emit_copy_blt(struct crocus_batch *batch, struct crocus_resource *src, @@ -283,6 +346,10 @@ static bool crocus_emit_blt(struct crocus_batch *batch, } } } + + if (util_format_has_alpha1(src->base.b.format) && + util_format_has_alpha(dst->base.b.format)) + blt_set_alpha_to_one(batch, dst, 0, 0, src_width, src_height); return true; } -- 2.7.4