X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fbrw_blorp_blit.cpp;h=fe75100d776caf1c30bfbdbdf61e6113139aac6e;hb=81b11bf0934d5387bd3741b6268501df3973a6a7;hp=f9d1079eb5aa356efd4103f48ec15c1ecd9e594a;hpb=bbab8068d2adb2dd9c09882cc8a19e62cf0ea8f0;p=mesa.git diff --git a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp index f9d1079eb5a..fe75100d776 100644 --- a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp +++ b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp @@ -31,87 +31,10 @@ #include "brw_context.h" #include "brw_blorp_blit_eu.h" #include "brw_state.h" +#include "brw_meta_util.h" #define FILE_DEBUG_FLAG DEBUG_BLORP -/** - * Helper function for handling mirror image blits. - * - * If coord0 > coord1, swap them and invert the "mirror" boolean. - */ -static inline void -fixup_mirroring(bool &mirror, GLfloat &coord0, GLfloat &coord1) -{ - if (coord0 > coord1) { - mirror = !mirror; - GLfloat tmp = coord0; - coord0 = coord1; - coord1 = tmp; - } -} - - -/** - * Adjust {src,dst}_x{0,1} to account for clipping and scissoring of - * destination coordinates. - * - * Return true if there is still blitting to do, false if all pixels got - * rejected by the clip and/or scissor. - * - * For clarity, the nomenclature of this function assumes we are clipping and - * scissoring the X coordinate; the exact same logic applies for Y - * coordinates. - * - * Note: this function may also be used to account for clipping of source - * coordinates, by swapping the roles of src and dst. - */ -static inline bool -clip_or_scissor(bool mirror, GLfloat &src_x0, GLfloat &src_x1, GLfloat &dst_x0, - GLfloat &dst_x1, GLfloat fb_xmin, GLfloat fb_xmax) -{ - float scale = (float) (src_x1 - src_x0) / (dst_x1 - dst_x0); - /* If we are going to scissor everything away, stop. */ - if (!(fb_xmin < fb_xmax && - dst_x0 < fb_xmax && - fb_xmin < dst_x1 && - dst_x0 < dst_x1)) { - return false; - } - - /* Clip the destination rectangle, and keep track of how many pixels we - * clipped off of the left and right sides of it. - */ - GLint pixels_clipped_left = 0; - GLint pixels_clipped_right = 0; - if (dst_x0 < fb_xmin) { - pixels_clipped_left = fb_xmin - dst_x0; - dst_x0 = fb_xmin; - } - if (fb_xmax < dst_x1) { - pixels_clipped_right = dst_x1 - fb_xmax; - dst_x1 = fb_xmax; - } - - /* If we are mirrored, then before applying pixels_clipped_{left,right} to - * the source coordinates, we need to flip them to account for the - * mirroring. - */ - if (mirror) { - GLint tmp = pixels_clipped_left; - pixels_clipped_left = pixels_clipped_right; - pixels_clipped_right = tmp; - } - - /* Adjust the source rectangle to remove the pixels corresponding to those - * that were clipped/scissored out of the destination rectangle. - */ - src_x0 += pixels_clipped_left * scale; - src_x1 -= pixels_clipped_right * scale; - - return true; -} - - static struct intel_mipmap_tree * find_miptree(GLbitfield buffer_bit, struct intel_renderbuffer *irb) { @@ -151,12 +74,12 @@ brw_blorp_blit_miptrees(struct brw_context *brw, 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 %s mt %p %d %d (%f,%f) (%f,%f)" - "to %s mt %p %d %d (%f,%f) (%f,%f) (flip %d,%d)\n", + 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", __FUNCTION__, - _mesa_get_format_name(src_mt->format), src_mt, + 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, - _mesa_get_format_name(dst_mt->format), dst_mt, + 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); @@ -193,24 +116,24 @@ do_blorp_blit(struct brw_context *brw, GLbitfield buffer_bit, dstX0, dstY0, dstX1, dstY1, filter, mirror_x, mirror_y); - intel_renderbuffer_set_needs_downsample(dst_irb); + dst_irb->need_downsample = true; } static bool -color_formats_match(gl_format src_format, gl_format dst_format) +color_formats_match(mesa_format src_format, mesa_format dst_format) { - gl_format linear_src_format = _mesa_get_srgb_format_linear(src_format); - gl_format linear_dst_format = _mesa_get_srgb_format_linear(dst_format); + mesa_format linear_src_format = _mesa_get_srgb_format_linear(src_format); + mesa_format linear_dst_format = _mesa_get_srgb_format_linear(dst_format); /* Normally, we require the formats to be equal. However, we also support * blitting from ARGB to XRGB (discarding alpha), and from XRGB to ARGB * (overriding alpha to 1.0 via blending). */ return linear_src_format == linear_dst_format || - (linear_src_format == MESA_FORMAT_XRGB8888 && - linear_dst_format == MESA_FORMAT_ARGB8888) || - (linear_src_format == MESA_FORMAT_ARGB8888 && - linear_dst_format == MESA_FORMAT_XRGB8888); + (linear_src_format == MESA_FORMAT_B8G8R8X8_UNORM && + linear_dst_format == MESA_FORMAT_B8G8R8A8_UNORM) || + (linear_src_format == MESA_FORMAT_B8G8R8A8_UNORM && + linear_dst_format == MESA_FORMAT_B8G8R8X8_UNORM); } static bool @@ -219,11 +142,11 @@ formats_match(GLbitfield buffer_bit, struct intel_renderbuffer *src_irb, { /* Note: don't just check gl_renderbuffer::Format, because in some cases * multiple gl_formats resolve to the same native type in the miptree (for - * example MESA_FORMAT_X8_Z24 and MESA_FORMAT_S8_Z24), and we can blit + * example MESA_FORMAT_Z24_UNORM_X8_UINT and MESA_FORMAT_Z24_UNORM_S8_UINT), and we can blit * between those formats. */ - gl_format src_format = find_miptree(buffer_bit, src_irb)->format; - gl_format dst_format = find_miptree(buffer_bit, dst_irb)->format; + mesa_format src_format = find_miptree(buffer_bit, src_irb)->format; + mesa_format dst_format = find_miptree(buffer_bit, dst_irb)->format; return color_formats_match(src_format, dst_format); } @@ -244,47 +167,12 @@ try_blorp_blit(struct brw_context *brw, const struct gl_framebuffer *read_fb = ctx->ReadBuffer; const struct gl_framebuffer *draw_fb = ctx->DrawBuffer; - /* Detect if the blit needs to be mirrored */ - bool mirror_x = false, mirror_y = false; - fixup_mirroring(mirror_x, srcX0, srcX1); - fixup_mirroring(mirror_x, dstX0, dstX1); - fixup_mirroring(mirror_y, srcY0, srcY1); - fixup_mirroring(mirror_y, dstY0, dstY1); - - /* If the destination rectangle needs to be clipped or scissored, do so. - */ - if (!(clip_or_scissor(mirror_x, srcX0, srcX1, dstX0, dstX1, - draw_fb->_Xmin, draw_fb->_Xmax) && - clip_or_scissor(mirror_y, srcY0, srcY1, dstY0, dstY1, - draw_fb->_Ymin, draw_fb->_Ymax))) { - /* Everything got clipped/scissored away, so the blit was successful. */ + bool mirror_x, mirror_y; + if (brw_meta_mirror_clip_and_scissor(ctx, + &srcX0, &srcY0, &srcX1, &srcY1, + &dstX0, &dstY0, &dstX1, &dstY1, + &mirror_x, &mirror_y)) return true; - } - - /* If the source rectangle needs to be clipped or scissored, do so. */ - if (!(clip_or_scissor(mirror_x, dstX0, dstX1, srcX0, srcX1, - 0, read_fb->Width) && - clip_or_scissor(mirror_y, dstY0, dstY1, srcY0, srcY1, - 0, read_fb->Height))) { - /* Everything got clipped/scissored away, so the blit was successful. */ - return true; - } - - /* Account for the fact that in the system framebuffer, the origin is at - * the lower left. - */ - if (_mesa_is_winsys_fbo(read_fb)) { - GLint tmp = read_fb->Height - srcY0; - srcY0 = read_fb->Height - srcY1; - srcY1 = tmp; - mirror_y = !mirror_y; - } - if (_mesa_is_winsys_fbo(draw_fb)) { - GLint tmp = draw_fb->Height - dstY0; - dstY0 = draw_fb->Height - dstY1; - dstY1 = tmp; - mirror_y = !mirror_y; - } /* Find buffers */ struct intel_renderbuffer *src_irb; @@ -368,8 +256,8 @@ brw_blorp_copytexsubimage(struct brw_context *brw, * we have to lie about the surface format. See the comments in * brw_blorp_surface_info::set(). */ - if ((src_mt->format == MESA_FORMAT_X8_Z24) != - (dst_mt->format == MESA_FORMAT_X8_Z24)) { + if ((src_mt->format == MESA_FORMAT_Z24_UNORM_X8_UINT) != + (dst_mt->format == MESA_FORMAT_Z24_UNORM_X8_UINT)) { return false; } @@ -402,9 +290,13 @@ brw_blorp_copytexsubimage(struct brw_context *brw, mirror_y = true; } + /* Account for face selection and texture view MinLayer */ + int dst_slice = slice + dst_image->TexObject->MinLayer + dst_image->Face; + int dst_level = dst_image->Level + dst_image->TexObject->MinLevel; + brw_blorp_blit_miptrees(brw, src_mt, src_irb->mt_level, src_irb->mt_layer, - dst_mt, dst_image->Level, dst_image->Face + slice, + dst_mt, dst_level, dst_slice, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, GL_NEAREST, false, mirror_y); @@ -427,8 +319,7 @@ brw_blorp_copytexsubimage(struct brw_context *brw, if (src_mt != dst_mt) { brw_blorp_blit_miptrees(brw, src_mt, src_irb->mt_level, src_irb->mt_layer, - dst_mt, dst_image->Level, - dst_image->Face + slice, + dst_mt, dst_level, dst_slice, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, GL_NEAREST, false, mirror_y); @@ -629,7 +520,7 @@ public: const brw_blorp_blit_prog_key *key); const GLuint *compile(struct brw_context *brw, GLuint *program_size, - FILE *dump_file = stdout); + FILE *dump_file = stderr); brw_blorp_prog_data prog_data; @@ -654,11 +545,6 @@ private: const sampler_message_arg *args, int num_args); void render_target_write(); - void emit_lrp(const struct brw_reg &dst, - const struct brw_reg &src1, - const struct brw_reg &src2, - const struct brw_reg &src3); - /** * Base-2 logarithm of the maximum number of samples that can be blended. */ @@ -1387,16 +1273,16 @@ brw_blorp_blit_program::translate_dst_to_src() emit_mov(Xp_f, X); emit_mov(Yp_f, Y); /* Scale and offset */ - brw_MUL(&func, X_f, Xp_f, x_transform.multiplier); - brw_MUL(&func, Y_f, Yp_f, y_transform.multiplier); + emit_mul(X_f, Xp_f, x_transform.multiplier); + emit_mul(Y_f, Yp_f, y_transform.multiplier); emit_add(X_f, X_f, x_transform.offset); emit_add(Y_f, Y_f, y_transform.offset); if (key->blit_scaled && key->blend) { /* Translate coordinates to lay out the samples in a rectangular grid * roughly corresponding to sample locations. */ - brw_MUL(&func, X_f, X_f, brw_imm_f(key->x_scale)); - brw_MUL(&func, Y_f, Y_f, brw_imm_f(key->y_scale)); + emit_mul(X_f, X_f, brw_imm_f(key->x_scale)); + emit_mul(Y_f, Y_f, brw_imm_f(key->y_scale)); /* Adjust coordinates so that integers represent pixel centers rather * than pixel edges. */ @@ -1413,14 +1299,14 @@ brw_blorp_blit_program::translate_dst_to_src() /* Store the fractional parts to be used as bilinear interpolation * coefficients. */ - brw_FRC(&func, x_frac, X_f); - brw_FRC(&func, y_frac, Y_f); + emit_frc(x_frac, X_f); + emit_frc(y_frac, Y_f); /* Round the float coordinates down to nearest integer */ - brw_RNDD(&func, Xp_f, X_f); - brw_RNDD(&func, Yp_f, Y_f); - brw_MUL(&func, X_f, Xp_f, brw_imm_f(1 / key->x_scale)); - brw_MUL(&func, Y_f, Yp_f, brw_imm_f(1 / key->y_scale)); + emit_rndd(Xp_f, X_f); + emit_rndd(Yp_f, Y_f); + emit_mul(X_f, Xp_f, brw_imm_f(1 / key->x_scale)); + emit_mul(Y_f, Yp_f, brw_imm_f(1 / key->y_scale)); SWAP_XY_AND_XPYP(); } else if (!key->bilinear_filter) { /* Round the float coordinates down to nearest integer by moving to @@ -1548,9 +1434,7 @@ brw_blorp_blit_program::manual_blend_average(unsigned num_samples) * Since we have already sampled from sample 0, all we need to do is * skip the remaining fetches and averaging if MCS is zero. */ - brw_CMP(&func, vec16(brw_null_reg()), BRW_CONDITIONAL_NZ, - mcs_data, brw_imm_ud(0)); - brw_IF(&func, BRW_EXECUTE_16); + emit_cmp_if(BRW_CONDITIONAL_NZ, mcs_data, brw_imm_ud(0)); } /* Do count_trailing_one_bits(i) times */ @@ -1576,29 +1460,14 @@ brw_blorp_blit_program::manual_blend_average(unsigned num_samples) /* Scale the result down by a factor of num_samples */ /* TODO: should use a smaller loop bound for non-RGBA formats */ for (int j = 0; j < 4; ++j) { - brw_MUL(&func, offset(texture_data[0], 2*j), + emit_mul(offset(texture_data[0], 2*j), offset(vec8(texture_data[0]), 2*j), brw_imm_f(1.0/num_samples)); } } if (key->tex_layout == INTEL_MSAA_LAYOUT_CMS) - brw_ENDIF(&func); -} - -void -brw_blorp_blit_program::emit_lrp(const struct brw_reg &dst, - const struct brw_reg &src1, - const struct brw_reg &src2, - const struct brw_reg &src3) -{ - brw_set_access_mode(&func, BRW_ALIGN_16); - brw_set_compression_control(&func, BRW_COMPRESSION_NONE); - brw_LRP(&func, dst, src1, src2, src3); - brw_set_compression_control(&func, BRW_COMPRESSION_2NDHALF); - brw_LRP(&func, sechalf(dst), sechalf(src1), sechalf(src2), sechalf(src3)); - brw_set_compression_control(&func, BRW_COMPRESSION_COMPRESSED); - brw_set_access_mode(&func, BRW_ALIGN_1); + emit_endif(); } void @@ -1664,32 +1533,30 @@ brw_blorp_blit_program::manual_blend_bilinear(unsigned num_samples) * | 6 | 7 | | 7 | 1 | * --------- --------- */ - brw_FRC(&func, vec16(t1_f), x_sample_coords); - brw_FRC(&func, vec16(t2_f), y_sample_coords); - brw_MUL(&func, vec16(t1_f), t1_f, brw_imm_f(key->x_scale)); - brw_MUL(&func, vec16(t2_f), t2_f, brw_imm_f(key->x_scale * key->y_scale)); + emit_frc(vec16(t1_f), x_sample_coords); + emit_frc(vec16(t2_f), y_sample_coords); + emit_mul(vec16(t1_f), t1_f, brw_imm_f(key->x_scale)); + emit_mul(vec16(t2_f), t2_f, brw_imm_f(key->x_scale * key->y_scale)); emit_add(vec16(t1_f), t1_f, t2_f); emit_mov(vec16(S), t1_f); if (num_samples == 8) { /* Map the sample index to a sample number */ - brw_CMP(&func, vec16(brw_null_reg()), BRW_CONDITIONAL_L, - S, brw_imm_d(4)); - brw_IF(&func, BRW_EXECUTE_16); + emit_cmp_if(BRW_CONDITIONAL_L, S, brw_imm_d(4)); { emit_mov(vec16(t2), brw_imm_d(5)); emit_if_eq_mov(S, 1, vec16(t2), 2); emit_if_eq_mov(S, 2, vec16(t2), 4); emit_if_eq_mov(S, 3, vec16(t2), 6); } - brw_ELSE(&func); + emit_else(); { emit_mov(vec16(t2), brw_imm_d(0)); emit_if_eq_mov(S, 5, vec16(t2), 3); emit_if_eq_mov(S, 6, vec16(t2), 7); emit_if_eq_mov(S, 7, vec16(t2), 1); } - brw_ENDIF(&func); + emit_endif(); emit_mov(vec16(S), t2); } texel_fetch(texture_data[i]); @@ -1997,9 +1864,6 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw, GLenum filter, bool mirror_x, bool mirror_y) { - struct gl_context *ctx = &brw->ctx; - const struct gl_framebuffer *read_fb = ctx->ReadBuffer; - src.set(brw, src_mt, src_level, src_layer, false); dst.set(brw, dst_mt, dst_level, dst_layer, true); @@ -2054,7 +1918,7 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw, wm_prog_key.texture_data_type = BRW_REGISTER_TYPE_F; break; case GL_UNSIGNED_INT: - if (src_mt->format == MESA_FORMAT_S8) { + if (src_mt->format == MESA_FORMAT_S_UINT8) { /* We process stencil as though it's an unsigned normalized color */ wm_prog_key.texture_data_type = BRW_REGISTER_TYPE_F; } else { @@ -2151,8 +2015,10 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw, y0 = wm_push_consts.dst_y0 = dst_y0; x1 = wm_push_consts.dst_x1 = dst_x1; y1 = wm_push_consts.dst_y1 = dst_y1; - wm_push_consts.rect_grid_x1 = read_fb->Width * wm_prog_key.x_scale - 1.0; - wm_push_consts.rect_grid_y1 = read_fb->Height * wm_prog_key.y_scale - 1.0; + wm_push_consts.rect_grid_x1 = (minify(src_mt->logical_width0, src_level) * + wm_prog_key.x_scale - 1.0); + wm_push_consts.rect_grid_y1 = (minify(src_mt->logical_height0, src_level) * + wm_prog_key.y_scale - 1.0); 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); @@ -2278,7 +2144,7 @@ brw_blorp_blit_params::get_wm_prog(struct brw_context *brw, &prog_offset, prog_data)) { brw_blorp_blit_program prog(brw, &this->wm_prog_key); GLuint program_size; - const GLuint *program = prog.compile(brw, &program_size, stdout); + const GLuint *program = prog.compile(brw, &program_size, stderr); brw_upload_cache(&brw->cache, BRW_BLORP_BLIT_PROG, &this->wm_prog_key, sizeof(this->wm_prog_key), program, program_size,