return mt;
}
-
-/**
- * Note: if the src (or dst) is a 2D multisample array texture on Gen7+ using
- * INTEL_MSAA_LAYOUT_UMS or INTEL_MSAA_LAYOUT_CMS, src_layer (dst_layer) is
- * the physical layer holding sample 0. So, for example, if
- * src_mt->num_samples == 4, then logical layer n corresponds to src_layer ==
- * 4*n.
- */
-void
-brw_blorp_blit_miptrees(struct brw_context *brw,
- struct intel_mipmap_tree *src_mt,
- unsigned src_level, unsigned src_layer,
- mesa_format src_format, int src_swizzle,
- struct intel_mipmap_tree *dst_mt,
- unsigned dst_level, unsigned dst_layer,
- mesa_format dst_format,
- 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,
- bool decode_srgb, bool encode_srgb)
-{
- /* Get ready to blit. This includes depth resolving the src and dst
- * buffers if necessary. Note: it's not necessary to do a color resolve on
- * the destination buffer because we use the standard render path to render
- * to destination color buffers, and the standard render path is
- * fast-color-aware.
- * Lossless compression is only introduced for gen9 onwards whereas
- * blorp is not supported even for gen8. Therefore it should be impossible
- * to end up here with single sampled compressed surfaces.
- */
- assert(!intel_miptree_is_lossless_compressed(brw, src_mt));
- assert(!intel_miptree_is_lossless_compressed(brw, dst_mt));
- intel_miptree_resolve_color(brw, src_mt, 0);
- intel_miptree_slice_resolve_depth(brw, src_mt, src_level, src_layer);
- intel_miptree_slice_resolve_depth(brw, dst_mt, dst_level, dst_layer);
-
- DBG("%s from %dx %s mt %p %d %d (%f,%f) (%f,%f)"
- "to %dx %s mt %p %d %d (%f,%f) (%f,%f) (flip %d,%d)\n",
- __func__,
- src_mt->num_samples, _mesa_get_format_name(src_mt->format), src_mt,
- src_level, src_layer, src_x0, src_y0, src_x1, src_y1,
- dst_mt->num_samples, _mesa_get_format_name(dst_mt->format), dst_mt,
- dst_level, dst_layer, dst_x0, dst_y0, dst_x1, dst_y1,
- mirror_x, mirror_y);
-
- if (!decode_srgb && _mesa_get_format_color_encoding(src_format) == GL_SRGB)
- src_format = _mesa_get_srgb_format_linear(src_format);
-
- if (!encode_srgb && _mesa_get_format_color_encoding(dst_format) == GL_SRGB)
- dst_format = _mesa_get_srgb_format_linear(dst_format);
-
- brw_blorp_blit_params params(brw,
- src_mt, src_level, src_layer, src_format,
- dst_mt, dst_level, dst_layer, dst_format,
- src_x0, src_y0,
- src_x1, src_y1,
- dst_x0, dst_y0,
- dst_x1, dst_y1,
- filter, mirror_x, mirror_y);
- params.src.swizzle = src_swizzle;
-
- brw_blorp_exec(brw, ¶ms);
-
- intel_miptree_slice_set_needs_hiz_resolve(dst_mt, dst_level, dst_layer);
-}
-
static int
blorp_get_texture_swizzle(const struct intel_renderbuffer *irb)
{
}
-brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
- struct intel_mipmap_tree *src_mt,
- unsigned src_level, unsigned src_layer,
- mesa_format src_format,
- struct intel_mipmap_tree *dst_mt,
- unsigned dst_level, unsigned dst_layer,
- mesa_format dst_format,
- GLfloat src_x0, GLfloat src_y0,
- GLfloat src_x1, GLfloat src_y1,
- GLfloat dst_x0, GLfloat dst_y0,
- GLfloat dst_x1, GLfloat dst_y1,
- GLenum filter,
- bool mirror_x, bool mirror_y)
+/**
+ * Note: if the src (or dst) is a 2D multisample array texture on Gen7+ using
+ * INTEL_MSAA_LAYOUT_UMS or INTEL_MSAA_LAYOUT_CMS, src_layer (dst_layer) is
+ * the physical layer holding sample 0. So, for example, if
+ * src_mt->num_samples == 4, then logical layer n corresponds to src_layer ==
+ * 4*n.
+ */
+void
+brw_blorp_blit_miptrees(struct brw_context *brw,
+ struct intel_mipmap_tree *src_mt,
+ unsigned src_level, unsigned src_layer,
+ mesa_format src_format, int src_swizzle,
+ struct intel_mipmap_tree *dst_mt,
+ unsigned dst_level, unsigned dst_layer,
+ mesa_format dst_format,
+ 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,
+ bool decode_srgb, bool encode_srgb)
{
- src.set(brw, src_mt, src_level, src_layer, src_format, false);
- dst.set(brw, dst_mt, dst_level, dst_layer, dst_format, true);
+ /* Get ready to blit. This includes depth resolving the src and dst
+ * buffers if necessary. Note: it's not necessary to do a color resolve on
+ * the destination buffer because we use the standard render path to render
+ * to destination color buffers, and the standard render path is
+ * fast-color-aware.
+ * Lossless compression is only introduced for gen9 onwards whereas
+ * blorp is not supported even for gen8. Therefore it should be impossible
+ * to end up here with single sampled compressed surfaces.
+ */
+ assert(!intel_miptree_is_lossless_compressed(brw, src_mt));
+ assert(!intel_miptree_is_lossless_compressed(brw, dst_mt));
+ intel_miptree_resolve_color(brw, src_mt, 0);
+ intel_miptree_slice_resolve_depth(brw, src_mt, src_level, src_layer);
+ intel_miptree_slice_resolve_depth(brw, dst_mt, dst_level, dst_layer);
+
+ DBG("%s from %dx %s mt %p %d %d (%f,%f) (%f,%f)"
+ "to %dx %s mt %p %d %d (%f,%f) (%f,%f) (flip %d,%d)\n",
+ __func__,
+ src_mt->num_samples, _mesa_get_format_name(src_mt->format), src_mt,
+ src_level, src_layer, src_x0, src_y0, src_x1, src_y1,
+ dst_mt->num_samples, _mesa_get_format_name(dst_mt->format), dst_mt,
+ dst_level, dst_layer, dst_x0, dst_y0, dst_x1, dst_y1,
+ mirror_x, mirror_y);
+
+ if (!decode_srgb && _mesa_get_format_color_encoding(src_format) == GL_SRGB)
+ src_format = _mesa_get_srgb_format_linear(src_format);
+
+ if (!encode_srgb && _mesa_get_format_color_encoding(dst_format) == GL_SRGB)
+ dst_format = _mesa_get_srgb_format_linear(dst_format);
+
+ brw_blorp_params params;
+
+ params.src.set(brw, src_mt, src_level, src_layer, src_format, false);
+ params.dst.set(brw, dst_mt, dst_level, dst_layer, dst_format, true);
/* Even though we do multisample resolves at the time of the blit, OpenGL
* specification defines them as if they happen at the time of rendering,
* (aside from the color space), we choose to blit in sRGB space to get
* this higher quality image.
*/
- if (src.num_samples > 1 &&
+ if (params.src.num_samples > 1 &&
_mesa_get_format_color_encoding(dst_mt->format) == GL_SRGB &&
_mesa_get_srgb_format_linear(src_mt->format) ==
_mesa_get_srgb_format_linear(dst_mt->format)) {
assert(brw->format_supported_as_render_target[dst_mt->format]);
- dst.brw_surfaceformat = brw->render_target_format[dst_mt->format];
- src.brw_surfaceformat = brw_format_for_mesa_format(dst_mt->format);
+ params.dst.brw_surfaceformat = brw->render_target_format[dst_mt->format];
+ params.src.brw_surfaceformat = brw_format_for_mesa_format(dst_mt->format);
}
/* When doing a multisample resolve of a GL_LUMINANCE32F or GL_INTENSITY32F
* shouldn't affect rendering correctness, since the destination format is
* R32_FLOAT, so only the contents of the red channel matters.
*/
- if (brw->gen == 6 && src.num_samples > 1 && dst.num_samples <= 1 &&
+ if (brw->gen == 6 &&
+ params.src.num_samples > 1 && params.dst.num_samples <= 1 &&
src_mt->format == dst_mt->format &&
- dst.brw_surfaceformat == BRW_SURFACEFORMAT_R32_FLOAT) {
- src.brw_surfaceformat = dst.brw_surfaceformat;
+ params.dst.brw_surfaceformat == BRW_SURFACEFORMAT_R32_FLOAT) {
+ params.src.brw_surfaceformat = params.dst.brw_surfaceformat;
}
+ struct brw_blorp_blit_prog_key wm_prog_key;
memset(&wm_prog_key, 0, sizeof(wm_prog_key));
/* texture_data_type indicates the register type that should be used to
* single-sampled texture and interleave the samples ourselves.
*/
if (dst_mt->msaa_layout == INTEL_MSAA_LAYOUT_IMS)
- dst.num_samples = 0;
+ params.dst.num_samples = 0;
}
- if (dst.map_stencil_as_y_tiled && dst.num_samples > 1) {
+ if (params.dst.map_stencil_as_y_tiled && params.dst.num_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
wm_prog_key.persample_msaa_dispatch = true;
}
- if (src.num_samples > 0 && dst.num_samples > 1) {
+ if (params.src.num_samples > 0 && params.dst.num_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
wm_prog_key.x_scale = 2.0f;
wm_prog_key.y_scale = src_mt->num_samples / 2.0f;
- if (filter == GL_LINEAR && src.num_samples <= 1 && dst.num_samples <= 1)
+ if (filter == GL_LINEAR &&
+ params.src.num_samples <= 1 && params.dst.num_samples <= 1)
wm_prog_key.bilinear_filter = true;
GLenum base_format = _mesa_get_format_base_format(src_mt->format);
/* tex_samples and rt_samples are the sample counts that are set up in
* SURFACE_STATE.
*/
- wm_prog_key.tex_samples = src.num_samples;
- wm_prog_key.rt_samples = dst.num_samples;
+ wm_prog_key.tex_samples = params.src.num_samples;
+ wm_prog_key.rt_samples = params.dst.num_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 =
- compute_msaa_layout_for_pipeline(brw, src.num_samples, src.msaa_layout);
+ compute_msaa_layout_for_pipeline(brw, params.src.num_samples,
+ params.src.msaa_layout);
wm_prog_key.rt_layout =
- compute_msaa_layout_for_pipeline(brw, dst.num_samples, dst.msaa_layout);
+ compute_msaa_layout_for_pipeline(brw, params.dst.num_samples,
+ params.dst.msaa_layout);
/* src_layout and dst_layout indicate the true MSAA layout used by src and
* dst.
wm_prog_key.src_layout = src_mt->msaa_layout;
wm_prog_key.dst_layout = dst_mt->msaa_layout;
- wm_prog_key.src_tiled_w = src.map_stencil_as_y_tiled;
- wm_prog_key.dst_tiled_w = dst.map_stencil_as_y_tiled;
+ wm_prog_key.src_tiled_w = params.src.map_stencil_as_y_tiled;
+ wm_prog_key.dst_tiled_w = params.dst.map_stencil_as_y_tiled;
/* Round floating point values to nearest integer to avoid "off by one texel"
* kind of errors when blitting.
*/
- x0 = wm_push_consts.dst_x0 = roundf(dst_x0);
- y0 = wm_push_consts.dst_y0 = roundf(dst_y0);
- x1 = wm_push_consts.dst_x1 = roundf(dst_x1);
- y1 = wm_push_consts.dst_y1 = roundf(dst_y1);
- wm_push_consts.rect_grid_x1 = (minify(src_mt->logical_width0, src_level) *
- wm_prog_key.x_scale - 1.0f);
- wm_push_consts.rect_grid_y1 = (minify(src_mt->logical_height0, src_level) *
- wm_prog_key.y_scale - 1.0f);
-
- wm_push_consts.x_transform.setup(src_x0, src_x1, dst_x0, dst_x1, mirror_x);
- wm_push_consts.y_transform.setup(src_y0, src_y1, dst_y0, dst_y1, mirror_y);
-
- wm_push_consts.src_z = src.mt->target == GL_TEXTURE_3D ? src.layer : 0;
-
- if (dst.num_samples <= 1 && dst_mt->num_samples > 1) {
+ params.x0 = params.wm_push_consts.dst_x0 = roundf(dst_x0);
+ params.y0 = params.wm_push_consts.dst_y0 = roundf(dst_y0);
+ params.x1 = params.wm_push_consts.dst_x1 = roundf(dst_x1);
+ params.y1 = params.wm_push_consts.dst_y1 = roundf(dst_y1);
+ params.wm_push_consts.rect_grid_x1 =
+ minify(src_mt->logical_width0, src_level) * wm_prog_key.x_scale - 1.0f;
+ params.wm_push_consts.rect_grid_y1 =
+ minify(src_mt->logical_height0, src_level) * wm_prog_key.y_scale - 1.0f;
+
+ params.wm_push_consts.x_transform.setup(src_x0, src_x1, dst_x0, dst_x1, mirror_x);
+ params.wm_push_consts.y_transform.setup(src_y0, src_y1, dst_y0, dst_y1, mirror_y);
+
+ params.wm_push_consts.src_z =
+ params.src.mt->target == GL_TEXTURE_3D ? params.src.layer : 0;
+
+ if (params.dst.num_samples <= 1 && dst_mt->num_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
* single-sampled when it is in fact multisampled. We must also align
assert(dst_mt->msaa_layout == INTEL_MSAA_LAYOUT_IMS);
switch (dst_mt->num_samples) {
case 2:
- x0 = ROUND_DOWN_TO(x0 * 2, 4);
- y0 = ROUND_DOWN_TO(y0, 4);
- x1 = ALIGN(x1 * 2, 4);
- y1 = ALIGN(y1, 4);
+ params.x0 = ROUND_DOWN_TO(params.x0 * 2, 4);
+ params.y0 = ROUND_DOWN_TO(params.y0, 4);
+ params.x1 = ALIGN(params.x1 * 2, 4);
+ params.y1 = ALIGN(params.y1, 4);
break;
case 4:
- x0 = ROUND_DOWN_TO(x0 * 2, 4);
- y0 = ROUND_DOWN_TO(y0 * 2, 4);
- x1 = ALIGN(x1 * 2, 4);
- y1 = ALIGN(y1 * 2, 4);
+ params.x0 = ROUND_DOWN_TO(params.x0 * 2, 4);
+ params.y0 = ROUND_DOWN_TO(params.y0 * 2, 4);
+ params.x1 = ALIGN(params.x1 * 2, 4);
+ params.y1 = ALIGN(params.y1 * 2, 4);
break;
case 8:
- x0 = ROUND_DOWN_TO(x0 * 4, 8);
- y0 = ROUND_DOWN_TO(y0 * 2, 4);
- x1 = ALIGN(x1 * 4, 8);
- y1 = ALIGN(y1 * 2, 4);
+ params.x0 = ROUND_DOWN_TO(params.x0 * 4, 8);
+ params.y0 = ROUND_DOWN_TO(params.y0 * 2, 4);
+ params.x1 = ALIGN(params.x1 * 4, 8);
+ params.y1 = ALIGN(params.y1 * 2, 4);
break;
default:
unreachable("Unrecognized sample count in brw_blorp_blit_params ctor");
wm_prog_key.use_kill = true;
}
- if (dst.map_stencil_as_y_tiled) {
+ if (params.dst.map_stencil_as_y_tiled) {
/* 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
* TODO: what if this makes the coordinates (or the texture size) too
* large?
*/
- const unsigned x_align = 8, y_align = dst.num_samples != 0 ? 8 : 4;
- x0 = ROUND_DOWN_TO(x0, x_align) * 2;
- y0 = ROUND_DOWN_TO(y0, y_align) / 2;
- x1 = ALIGN(x1, x_align) * 2;
- y1 = ALIGN(y1, y_align) / 2;
- dst.width = ALIGN(dst.width, x_align) * 2;
- dst.height = ALIGN(dst.height, y_align) / 2;
- dst.x_offset *= 2;
- dst.y_offset /= 2;
+ const unsigned x_align = 8, y_align = params.dst.num_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;
+ params.dst.width = ALIGN(params.dst.width, x_align) * 2;
+ params.dst.height = ALIGN(params.dst.height, y_align) / 2;
+ params.dst.x_offset *= 2;
+ params.dst.y_offset /= 2;
wm_prog_key.use_kill = true;
}
- if (src.map_stencil_as_y_tiled) {
+ if (params.src.map_stencil_as_y_tiled) {
/* We must modify the size and x/y offset of the source surface to
* account for the fact that we are mapping it as Y-tiled when it is in
* fact W tiled.
*
* TODO: what if this makes the texture size too large?
*/
- const unsigned x_align = 8, y_align = src.num_samples != 0 ? 8 : 4;
- src.width = ALIGN(src.width, x_align) * 2;
- src.height = ALIGN(src.height, y_align) / 2;
- src.x_offset *= 2;
- src.y_offset /= 2;
+ const unsigned x_align = 8, y_align = params.src.num_samples != 0 ? 8 : 4;
+ params.src.width = ALIGN(params.src.width, x_align) * 2;
+ params.src.height = ALIGN(params.src.height, y_align) / 2;
+ params.src.x_offset *= 2;
+ params.src.y_offset /= 2;
}
if (!brw_search_cache(&brw->cache, BRW_CACHE_BLORP_PROG,
- &this->wm_prog_key, sizeof(this->wm_prog_key),
- &this->wm_prog_kernel, &this->wm_prog_data)) {
- brw_blorp_blit_program prog(brw, &this->wm_prog_key);
+ &wm_prog_key, sizeof(wm_prog_key),
+ ¶ms.wm_prog_kernel, ¶ms.wm_prog_data)) {
+ brw_blorp_blit_program prog(brw, &wm_prog_key);
GLuint program_size;
const GLuint *program = prog.compile(brw, INTEL_DEBUG & DEBUG_BLORP,
&program_size);
brw_upload_cache(&brw->cache, BRW_CACHE_BLORP_PROG,
- &this->wm_prog_key, sizeof(this->wm_prog_key),
+ &wm_prog_key, sizeof(wm_prog_key),
program, program_size,
&prog.prog_data, sizeof(prog.prog_data),
- &this->wm_prog_kernel, &this->wm_prog_data);
+ ¶ms.wm_prog_kernel, ¶ms.wm_prog_data);
}
+
+ params.src.swizzle = src_swizzle;
+
+ brw_blorp_exec(brw, ¶ms);
+
+ intel_miptree_slice_set_needs_hiz_resolve(dst_mt, dst_level, dst_layer);
}