From ab03e59867ebf078d910063e717498cdf8905fa0 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Sat, 27 Aug 2016 12:07:31 -0700 Subject: [PATCH] intel/blorp: Add support for RGB destinations in copies Signed-off-by: Jason Ekstrand Reviewed-by: Topi Pohjolainen --- src/intel/blorp/blorp_blit.c | 62 ++++++++++++++++++++++++++++++++++++ src/intel/blorp/blorp_priv.h | 7 ++++ 2 files changed, 69 insertions(+) diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c index 49c8648aee7..0898ed45faa 100644 --- a/src/intel/blorp/blorp_blit.c +++ b/src/intel/blorp/blorp_blit.c @@ -1198,6 +1198,27 @@ brw_blorp_build_nir_shader(struct blorp_context *blorp, } } + if (key->dst_rgb) { + /* The destination image is bound as a red texture three times as wide + * as the actual image. Our shader is effectively running one color + * component at a time. We need to pick off the appropriate component + * from the source color and write that to destination red. + */ + assert(dst_pos->num_components == 2); + nir_ssa_def *comp = + nir_umod(&b, nir_channel(&b, dst_pos, 0), nir_imm_int(&b, 3)); + + nir_ssa_def *color_component = + nir_bcsel(&b, nir_ieq(&b, comp, nir_imm_int(&b, 0)), + nir_channel(&b, color, 0), + nir_bcsel(&b, nir_ieq(&b, comp, nir_imm_int(&b, 1)), + nir_channel(&b, color, 1), + nir_channel(&b, color, 2))); + + nir_ssa_def *u = nir_ssa_undef(&b, 1, 32); + color = nir_vec4(&b, color_component, u, u, u); + } + nir_store_var(&b, v.color_out, color, 0xf); return b.shader; @@ -1772,6 +1793,40 @@ surf_convert_to_uncompressed(const struct isl_device *isl_dev, info->surf.format = get_copy_format_for_bpb(fmtl->bpb); } +static void +surf_fake_rgb_with_red(const struct isl_device *isl_dev, + struct brw_blorp_surface_info *info, + uint32_t *x, uint32_t *width) +{ + surf_convert_to_single_slice(isl_dev, info); + + info->surf.logical_level0_px.width *= 3; + info->surf.phys_level0_sa.width *= 3; + *x *= 3; + *width *= 3; + + enum isl_format red_format; + switch (info->view.format) { + case ISL_FORMAT_R8G8B8_UNORM: + red_format = ISL_FORMAT_R8_UNORM; + break; + case ISL_FORMAT_R16G16B16_UNORM: + red_format = ISL_FORMAT_R16_UNORM; + break; + case ISL_FORMAT_R32G32B32_UINT: + red_format = ISL_FORMAT_R32_UINT; + break; + default: + unreachable("Invalid RGB copy destination format"); + } + assert(isl_format_get_layout(red_format)->channels.r.type == + isl_format_get_layout(info->view.format)->channels.r.type); + assert(isl_format_get_layout(red_format)->channels.r.bits == + isl_format_get_layout(info->view.format)->channels.r.bits); + + info->surf.format = info->view.format = red_format; +} + void blorp_copy(struct blorp_batch *batch, const struct blorp_surf *src_surf, @@ -1818,6 +1873,13 @@ blorp_copy(struct blorp_batch *batch, uint32_t dst_width = src_width; uint32_t dst_height = src_height; + if (dst_fmtl->bpb % 3 == 0) { + surf_fake_rgb_with_red(batch->blorp->isl_dev, ¶ms.dst, + &dst_x, &dst_width); + wm_prog_key.dst_rgb = true; + wm_prog_key.need_dst_offset = true; + } + do_blorp_blit(batch, ¶ms, &wm_prog_key, src_x, src_y, src_x + src_width, src_y + src_height, dst_x, dst_y, dst_x + dst_width, dst_y + dst_height, diff --git a/src/intel/blorp/blorp_priv.h b/src/intel/blorp/blorp_priv.h index 46ff272630a..a88d0f87ba1 100644 --- a/src/intel/blorp/blorp_priv.h +++ b/src/intel/blorp/blorp_priv.h @@ -245,6 +245,13 @@ struct brw_blorp_blit_prog_key */ bool dst_tiled_w; + /* True if the destination is an RGB format. If true, the surface state + * for the render target must be configured as red with three times the + * normal width. We need to do this because you cannot render to + * non-power-of-two formats. + */ + bool dst_rgb; + /* True if all source samples should be blended together to produce each * destination pixel. If true, src_tiled_w must be false, tex_samples must * equal src_samples, and tex_samples must be nonzero. -- 2.30.2