From 941b4d063a7b12af773cc4837e6c0fa3b29abdc0 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Tue, 30 Aug 2016 12:49:54 -0700 Subject: [PATCH] intel/blorp: Pull the guts of blorp_blit into a helper Signed-off-by: Jason Ekstrand Reviewed-by: Topi Pohjolainen --- src/intel/blorp/blorp_blit.c | 277 +++++++++++++++++++---------------- 1 file changed, 147 insertions(+), 130 deletions(-) diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c index dba49b9c207..60b6578f214 100644 --- a/src/intel/blorp/blorp_blit.c +++ b/src/intel/blorp/blorp_blit.c @@ -1408,110 +1408,54 @@ surf_retile_w_to_y(const struct isl_device *isl_dev, info->tile_y_sa /= 2; } -void -blorp_blit(struct blorp_batch *batch, - const struct blorp_surf *src_surf, - unsigned src_level, unsigned src_layer, - enum isl_format src_format, struct isl_swizzle src_swizzle, - const struct blorp_surf *dst_surf, - unsigned dst_level, unsigned dst_layer, - enum isl_format dst_format, struct isl_swizzle dst_swizzle, - float src_x0, float src_y0, - float src_x1, float src_y1, - float dst_x0, float dst_y0, - float dst_x1, float dst_y1, - GLenum filter, bool mirror_x, bool mirror_y) +static void +do_blorp_blit(struct blorp_batch *batch, + struct blorp_params *params, + struct brw_blorp_blit_prog_key *wm_prog_key, + float src_x0, float src_y0, + float src_x1, float src_y1, + float dst_x0, float dst_y0, + float dst_x1, float dst_y1, + bool mirror_x, bool mirror_y) { const struct gen_device_info *devinfo = batch->blorp->isl_dev->info; - struct blorp_params params; - blorp_params_init(¶ms); - - brw_blorp_surface_info_init(batch->blorp, ¶ms.src, src_surf, src_level, - src_layer, src_format, false); - brw_blorp_surface_info_init(batch->blorp, ¶ms.dst, dst_surf, dst_level, - dst_layer, dst_format, true); - - struct brw_blorp_blit_prog_key wm_prog_key; - memset(&wm_prog_key, 0, sizeof(wm_prog_key)); - - if (isl_format_has_sint_channel(params.src.view.format)) { - wm_prog_key.texture_data_type = nir_type_int; - } else if (isl_format_has_uint_channel(params.src.view.format)) { - wm_prog_key.texture_data_type = nir_type_uint; + if (isl_format_has_sint_channel(params->src.view.format)) { + wm_prog_key->texture_data_type = nir_type_int; + } else if (isl_format_has_uint_channel(params->src.view.format)) { + wm_prog_key->texture_data_type = nir_type_uint; } else { - wm_prog_key.texture_data_type = nir_type_float; - } - - /* Scaled blitting or not. */ - wm_prog_key.blit_scaled = - ((dst_x1 - dst_x0) == (src_x1 - src_x0) && - (dst_y1 - dst_y0) == (src_y1 - src_y0)) ? false : true; - - /* Scaling factors used for bilinear filtering in multisample scaled - * blits. - */ - if (params.src.surf.samples == 16) - wm_prog_key.x_scale = 4.0f; - else - wm_prog_key.x_scale = 2.0f; - wm_prog_key.y_scale = params.src.surf.samples / wm_prog_key.x_scale; - - if (filter == GL_LINEAR && - params.src.surf.samples <= 1 && params.dst.surf.samples <= 1) - wm_prog_key.bilinear_filter = true; - - if ((params.src.surf.usage & ISL_SURF_USAGE_DEPTH_BIT) == 0 && - (params.src.surf.usage & ISL_SURF_USAGE_STENCIL_BIT) == 0 && - !isl_format_has_int_channel(params.src.surf.format) && - params.src.surf.samples > 1 && params.dst.surf.samples <= 1) { - /* We are downsampling a non-integer color buffer, so blend. - * - * Regarding integer color buffers, the OpenGL ES 3.2 spec says: - * - * "If the source formats are integer types or stencil values, a - * single sample's value is selected for each pixel." - * - * This implies we should not blend in that case. - */ - wm_prog_key.blend = true; + wm_prog_key->texture_data_type = nir_type_float; } /* src_samples and dst_samples are the true sample counts */ - wm_prog_key.src_samples = params.src.surf.samples; - wm_prog_key.dst_samples = params.dst.surf.samples; + wm_prog_key->src_samples = params->src.surf.samples; + wm_prog_key->dst_samples = params->dst.surf.samples; - wm_prog_key.tex_aux_usage = params.src.aux_usage; + wm_prog_key->tex_aux_usage = params->src.aux_usage; /* src_layout and dst_layout indicate the true MSAA layout used by src and * dst. */ - wm_prog_key.src_layout = params.src.surf.msaa_layout; - wm_prog_key.dst_layout = params.dst.surf.msaa_layout; + wm_prog_key->src_layout = params->src.surf.msaa_layout; + wm_prog_key->dst_layout = params->dst.surf.msaa_layout; /* Round floating point values to nearest integer to avoid "off by one texel" * kind of errors when blitting. */ - params.x0 = params.wm_inputs.discard_rect.x0 = roundf(dst_x0); - params.y0 = params.wm_inputs.discard_rect.y0 = roundf(dst_y0); - params.x1 = params.wm_inputs.discard_rect.x1 = roundf(dst_x1); - params.y1 = params.wm_inputs.discard_rect.y1 = roundf(dst_y1); + params->x0 = params->wm_inputs.discard_rect.x0 = roundf(dst_x0); + params->y0 = params->wm_inputs.discard_rect.y0 = roundf(dst_y0); + params->x1 = params->wm_inputs.discard_rect.x1 = roundf(dst_x1); + params->y1 = params->wm_inputs.discard_rect.y1 = roundf(dst_y1); - params.wm_inputs.rect_grid.x1 = - minify(params.src.surf.logical_level0_px.width, src_level) * - wm_prog_key.x_scale - 1.0f; - params.wm_inputs.rect_grid.y1 = - minify(params.src.surf.logical_level0_px.height, src_level) * - wm_prog_key.y_scale - 1.0f; - - brw_blorp_setup_coord_transform(¶ms.wm_inputs.coord_transform[0], + brw_blorp_setup_coord_transform(¶ms->wm_inputs.coord_transform[0], src_x0, src_x1, dst_x0, dst_x1, mirror_x); - brw_blorp_setup_coord_transform(¶ms.wm_inputs.coord_transform[1], + brw_blorp_setup_coord_transform(¶ms->wm_inputs.coord_transform[1], src_y0, src_y1, dst_y0, dst_y1, mirror_y); if (devinfo->gen > 6 && - params.dst.surf.msaa_layout == ISL_MSAA_LAYOUT_INTERLEAVED) { - assert(params.dst.surf.samples > 1); + params->dst.surf.msaa_layout == ISL_MSAA_LAYOUT_INTERLEAVED) { + assert(params->dst.surf.samples > 1); /* We must expand the rectangle we send through the rendering pipeline, * to account for the fact that we are mapping the destination region as @@ -1526,19 +1470,19 @@ blorp_blit(struct blorp_batch *batch, * pipeline as multisampled. */ struct isl_extent2d px_size_sa = - isl_get_interleaved_msaa_px_size_sa(params.dst.surf.samples); - params.x0 = ROUND_DOWN_TO(params.x0, 2) * px_size_sa.width; - params.y0 = ROUND_DOWN_TO(params.y0, 2) * px_size_sa.height; - params.x1 = ALIGN(params.x1, 2) * px_size_sa.width; - params.y1 = ALIGN(params.y1, 2) * px_size_sa.height; + isl_get_interleaved_msaa_px_size_sa(params->dst.surf.samples); + params->x0 = ROUND_DOWN_TO(params->x0, 2) * px_size_sa.width; + params->y0 = ROUND_DOWN_TO(params->y0, 2) * px_size_sa.height; + params->x1 = ALIGN(params->x1, 2) * px_size_sa.width; + params->y1 = ALIGN(params->y1, 2) * px_size_sa.height; - surf_fake_interleaved_msaa(batch->blorp->isl_dev, ¶ms.dst); + surf_fake_interleaved_msaa(batch->blorp->isl_dev, ¶ms->dst); - wm_prog_key.use_kill = true; - wm_prog_key.need_dst_offset = true; + wm_prog_key->use_kill = true; + wm_prog_key->need_dst_offset = true; } - if (params.dst.surf.tiling == ISL_TILING_W) { + if (params->dst.surf.tiling == ISL_TILING_W) { /* We must modify the rectangle we send through the rendering pipeline * (and the size and x/y offset of the destination surface), to account * for the fact that we are mapping it as Y-tiled when it is in fact @@ -1585,31 +1529,32 @@ blorp_blit(struct blorp_batch *batch, * TODO: what if this makes the coordinates (or the texture size) too * large? */ - const unsigned x_align = 8, y_align = params.dst.surf.samples != 0 ? 8 : 4; - params.x0 = ROUND_DOWN_TO(params.x0, x_align) * 2; - params.y0 = ROUND_DOWN_TO(params.y0, y_align) / 2; - params.x1 = ALIGN(params.x1, x_align) * 2; - params.y1 = ALIGN(params.y1, y_align) / 2; + const unsigned x_align = 8; + const unsigned y_align = params->dst.surf.samples != 0 ? 8 : 4; + params->x0 = ROUND_DOWN_TO(params->x0, x_align) * 2; + params->y0 = ROUND_DOWN_TO(params->y0, y_align) / 2; + params->x1 = ALIGN(params->x1, x_align) * 2; + params->y1 = ALIGN(params->y1, y_align) / 2; /* Retile the surface to Y-tiled */ - surf_retile_w_to_y(batch->blorp->isl_dev, ¶ms.dst); + surf_retile_w_to_y(batch->blorp->isl_dev, ¶ms->dst); - wm_prog_key.dst_tiled_w = true; - wm_prog_key.use_kill = true; - wm_prog_key.need_dst_offset = true; + wm_prog_key->dst_tiled_w = true; + wm_prog_key->use_kill = true; + wm_prog_key->need_dst_offset = true; - if (params.dst.surf.samples > 1) { + if (params->dst.surf.samples > 1) { /* If the destination surface is a W-tiled multisampled stencil * buffer that we're mapping as Y tiled, then we need to arrange for * the WM program to run once per sample rather than once per pixel, * because the memory layout of related samples doesn't match between * W and Y tiling. */ - wm_prog_key.persample_msaa_dispatch = true; + wm_prog_key->persample_msaa_dispatch = true; } } - if (devinfo->gen < 8 && params.src.surf.tiling == ISL_TILING_W) { + if (devinfo->gen < 8 && params->src.surf.tiling == ISL_TILING_W) { /* On Haswell and earlier, we have to fake W-tiled sources as Y-tiled. * Broadwell adds support for sampling from stencil. * @@ -1618,58 +1563,130 @@ blorp_blit(struct blorp_batch *batch, * * TODO: what if this makes the texture size too large? */ - surf_retile_w_to_y(batch->blorp->isl_dev, ¶ms.src); + surf_retile_w_to_y(batch->blorp->isl_dev, ¶ms->src); - wm_prog_key.src_tiled_w = true; - wm_prog_key.need_src_offset = true; + wm_prog_key->src_tiled_w = true; + wm_prog_key->need_src_offset = true; } /* tex_samples and rt_samples are the sample counts that are set up in * SURFACE_STATE. */ - wm_prog_key.tex_samples = params.src.surf.samples; - wm_prog_key.rt_samples = params.dst.surf.samples; + wm_prog_key->tex_samples = params->src.surf.samples; + wm_prog_key->rt_samples = params->dst.surf.samples; /* tex_layout and rt_layout indicate the MSAA layout the GPU pipeline will * use to access the source and destination surfaces. */ - wm_prog_key.tex_layout = params.src.surf.msaa_layout; - wm_prog_key.rt_layout = params.dst.surf.msaa_layout; + wm_prog_key->tex_layout = params->src.surf.msaa_layout; + wm_prog_key->rt_layout = params->dst.surf.msaa_layout; - if (params.src.surf.samples > 0 && params.dst.surf.samples > 1) { + if (params->src.surf.samples > 0 && params->dst.surf.samples > 1) { /* We are blitting from a multisample buffer to a multisample buffer, so * we must preserve samples within a pixel. This means we have to * arrange for the WM program to run once per sample rather than once * per pixel. */ - wm_prog_key.persample_msaa_dispatch = true; + wm_prog_key->persample_msaa_dispatch = true; } - if (params.src.tile_x_sa || params.src.tile_y_sa) { - assert(wm_prog_key.need_src_offset); - surf_get_intratile_offset_px(¶ms.src, - ¶ms.wm_inputs.src_offset.x, - ¶ms.wm_inputs.src_offset.y); + if (params->src.tile_x_sa || params->src.tile_y_sa) { + assert(wm_prog_key->need_src_offset); + surf_get_intratile_offset_px(¶ms->src, + ¶ms->wm_inputs.src_offset.x, + ¶ms->wm_inputs.src_offset.y); } - if (params.dst.tile_x_sa || params.dst.tile_y_sa) { - assert(wm_prog_key.need_dst_offset); - surf_get_intratile_offset_px(¶ms.dst, - ¶ms.wm_inputs.dst_offset.x, - ¶ms.wm_inputs.dst_offset.y); - params.x0 += params.wm_inputs.dst_offset.x; - params.y0 += params.wm_inputs.dst_offset.y; - params.x1 += params.wm_inputs.dst_offset.x; - params.y1 += params.wm_inputs.dst_offset.y; + if (params->dst.tile_x_sa || params->dst.tile_y_sa) { + assert(wm_prog_key->need_dst_offset); + surf_get_intratile_offset_px(¶ms->dst, + ¶ms->wm_inputs.dst_offset.x, + ¶ms->wm_inputs.dst_offset.y); + params->x0 += params->wm_inputs.dst_offset.x; + params->y0 += params->wm_inputs.dst_offset.y; + params->x1 += params->wm_inputs.dst_offset.x; + params->y1 += params->wm_inputs.dst_offset.y; } /* For some texture types, we need to pass the layer through the sampler. */ - params.wm_inputs.src_z = params.src.z_offset; + params->wm_inputs.src_z = params->src.z_offset; + + brw_blorp_get_blit_kernel(batch->blorp, params, wm_prog_key); - brw_blorp_get_blit_kernel(batch->blorp, ¶ms, &wm_prog_key); + batch->blorp->exec(batch, params); +} + +void +blorp_blit(struct blorp_batch *batch, + const struct blorp_surf *src_surf, + unsigned src_level, unsigned src_layer, + enum isl_format src_format, struct isl_swizzle src_swizzle, + const struct blorp_surf *dst_surf, + unsigned dst_level, unsigned dst_layer, + enum isl_format dst_format, struct isl_swizzle dst_swizzle, + float src_x0, float src_y0, + float src_x1, float src_y1, + float dst_x0, float dst_y0, + float dst_x1, float dst_y1, + GLenum filter, bool mirror_x, bool mirror_y) +{ + struct blorp_params params; + blorp_params_init(¶ms); + + brw_blorp_surface_info_init(batch->blorp, ¶ms.src, src_surf, src_level, + src_layer, src_format, false); + brw_blorp_surface_info_init(batch->blorp, ¶ms.dst, dst_surf, dst_level, + dst_layer, dst_format, true); params.src.view.swizzle = src_swizzle; params.dst.view.swizzle = dst_swizzle; - batch->blorp->exec(batch, ¶ms); + struct brw_blorp_blit_prog_key wm_prog_key; + memset(&wm_prog_key, 0, sizeof(wm_prog_key)); + + /* Scaled blitting or not. */ + wm_prog_key.blit_scaled = + ((dst_x1 - dst_x0) == (src_x1 - src_x0) && + (dst_y1 - dst_y0) == (src_y1 - src_y0)) ? false : true; + + /* Scaling factors used for bilinear filtering in multisample scaled + * blits. + */ + if (params.src.surf.samples == 16) + wm_prog_key.x_scale = 4.0f; + else + wm_prog_key.x_scale = 2.0f; + wm_prog_key.y_scale = params.src.surf.samples / wm_prog_key.x_scale; + + if (filter == GL_LINEAR && + params.src.surf.samples <= 1 && params.dst.surf.samples <= 1) + wm_prog_key.bilinear_filter = true; + + if ((params.src.surf.usage & ISL_SURF_USAGE_DEPTH_BIT) == 0 && + (params.src.surf.usage & ISL_SURF_USAGE_STENCIL_BIT) == 0 && + !isl_format_has_int_channel(params.src.surf.format) && + params.src.surf.samples > 1 && params.dst.surf.samples <= 1) { + /* We are downsampling a non-integer color buffer, so blend. + * + * Regarding integer color buffers, the OpenGL ES 3.2 spec says: + * + * "If the source formats are integer types or stencil values, a + * single sample's value is selected for each pixel." + * + * This implies we should not blend in that case. + */ + wm_prog_key.blend = true; + } + + params.wm_inputs.rect_grid.x1 = + minify(params.src.surf.logical_level0_px.width, src_level) * + wm_prog_key.x_scale - 1.0f; + params.wm_inputs.rect_grid.y1 = + minify(params.src.surf.logical_level0_px.height, src_level) * + wm_prog_key.y_scale - 1.0f; + + do_blorp_blit(batch, ¶ms, &wm_prog_key, + src_x0, src_y0, src_x1, src_y1, + dst_x0, dst_y0, dst_x1, dst_y1, + mirror_x, mirror_y); } -- 2.30.2