X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fbrw_blorp_blit.cpp;h=ec70217f2c67e275160005b6fd471c06ed81e746;hb=4b2e819e10138dba6961d44f07af6de13750a832;hp=8c0db487a29ee6edd0ccbaa41316de8ac09dc7e6;hpb=aff371b634b574cc56bd91464365a50c8bcb42fe;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 8c0db487a29..ec70217f2c6 100644 --- a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp +++ b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp @@ -133,7 +133,7 @@ brw_blorp_blit_miptrees(struct brw_context *brw, float src_x1, float src_y1, float dst_x0, float dst_y0, float dst_x1, float dst_y1, - bool mirror_x, bool mirror_y) + GLenum filter, bool mirror_x, bool mirror_y) { /* 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 @@ -161,7 +161,7 @@ brw_blorp_blit_miptrees(struct brw_context *brw, src_x1, src_y1, dst_x0, dst_y0, dst_x1, dst_y1, - mirror_x, mirror_y); + filter, mirror_x, mirror_y); brw_blorp_exec(brw, ¶ms); intel_miptree_slice_set_needs_hiz_resolve(dst_mt, dst_level, dst_layer); @@ -173,7 +173,7 @@ do_blorp_blit(struct brw_context *brw, GLbitfield buffer_bit, struct intel_renderbuffer *dst_irb, GLfloat srcX0, GLfloat srcY0, GLfloat srcX1, GLfloat srcY1, GLfloat dstX0, GLfloat dstY0, GLfloat dstX1, GLfloat dstY1, - bool mirror_x, bool mirror_y) + GLenum filter, bool mirror_x, bool mirror_y) { /* Find source/dst miptrees */ struct intel_mipmap_tree *src_mt = find_miptree(buffer_bit, src_irb); @@ -185,7 +185,7 @@ do_blorp_blit(struct brw_context *brw, GLbitfield buffer_bit, dst_mt, dst_irb->mt_level, dst_irb->mt_layer, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, - mirror_x, mirror_y); + filter, mirror_x, mirror_y); intel_renderbuffer_set_needs_downsample(dst_irb); } @@ -245,14 +245,6 @@ try_blorp_blit(struct brw_context *brw, fixup_mirroring(mirror_y, srcY0, srcY1); fixup_mirroring(mirror_y, dstY0, dstY1); - /* Linear filtering is not yet implemented in blorp engine. So, fallback - * to other blit paths. - */ - if ((srcX1 - srcX0 != dstX1 - dstX0 || - srcY1 - srcY0 != dstY1 - dstY0) && - filter == GL_LINEAR) - return false; - /* If the destination rectangle needs to be clipped or scissored, do so. */ if (!(clip_or_scissor(mirror_x, srcX0, srcX1, dstX0, dstX1, @@ -304,7 +296,7 @@ try_blorp_blit(struct brw_context *brw, if (dst_irb) do_blorp_blit(brw, buffer_bit, src_irb, dst_irb, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, - mirror_x, mirror_y); + filter, mirror_x, mirror_y); } break; case GL_DEPTH_BUFFER_BIT: @@ -316,7 +308,7 @@ try_blorp_blit(struct brw_context *brw, return false; do_blorp_blit(brw, buffer_bit, src_irb, dst_irb, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, - mirror_x, mirror_y); + filter, mirror_x, mirror_y); break; case GL_STENCIL_BUFFER_BIT: src_irb = @@ -327,7 +319,7 @@ try_blorp_blit(struct brw_context *brw, return false; do_blorp_blit(brw, buffer_bit, src_irb, dst_irb, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, - mirror_x, mirror_y); + filter, mirror_x, mirror_y); break; default: assert(false); @@ -396,7 +388,7 @@ brw_blorp_copytexsubimage(struct brw_context *brw, dst_mt, dst_image->Level, dst_image->Face + slice, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, - false, mirror_y); + GL_NEAREST, false, mirror_y); /* If we're copying to a packed depth stencil texture and the source * framebuffer has separate stencil, we need to also copy the stencil data @@ -420,7 +412,7 @@ brw_blorp_copytexsubimage(struct brw_context *brw, dst_image->Face + slice, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, - false, mirror_y); + GL_NEAREST, false, mirror_y); } } @@ -863,9 +855,10 @@ brw_blorp_blit_program::compile(struct brw_context *brw, * the same as the configuration of the texture, then we need to adjust * the coordinates to compensate for the difference. */ - if (tex_tiled_w != key->src_tiled_w || - key->tex_samples != key->src_samples || - key->tex_layout != key->src_layout) { + if ((tex_tiled_w != key->src_tiled_w || + key->tex_samples != key->src_samples || + key->tex_layout != key->src_layout) && + !key->bilinear_filter) { encode_msaa(key->src_samples, key->src_layout); /* Now (X, Y, S) = detile(src_tiling, offset) */ translate_tiling(key->src_tiled_w, tex_tiled_w); @@ -873,15 +866,20 @@ brw_blorp_blit_program::compile(struct brw_context *brw, decode_msaa(key->tex_samples, key->tex_layout); } - /* Now (X, Y, S) = decode_msaa(tex_samples, detile(tex_tiling, offset)). - * - * In other words: X, Y, and S now contain values which, when passed to - * the texturing unit, will cause data to be read from the correct - * memory location. So we can fetch the texel now. - */ - if (key->tex_layout == INTEL_MSAA_LAYOUT_CMS) - mcs_fetch(); - texel_fetch(texture_data[0]); + if (key->bilinear_filter) { + sample(texture_data[0]); + } + else { + /* Now (X, Y, S) = decode_msaa(tex_samples, detile(tex_tiling, offset)). + * + * In other words: X, Y, and S now contain values which, when passed to + * the texturing unit, will cause data to be read from the correct + * memory location. So we can fetch the texel now. + */ + if (key->tex_layout == INTEL_MSAA_LAYOUT_CMS) + mcs_fetch(); + texel_fetch(texture_data[0]); + } } /* Finally, write the fetched (or blended) value to the render target and @@ -901,22 +899,22 @@ void brw_blorp_blit_program::alloc_push_const_regs(int base_reg) { #define CONST_LOC(name) offsetof(brw_blorp_wm_push_constants, name) -#define ALLOC_REG(name) \ - this->name = \ - brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, \ - base_reg + CONST_LOC(name) / 32, \ - (CONST_LOC(name) % 32) / 4) - - ALLOC_REG(dst_x0); - ALLOC_REG(dst_x1); - ALLOC_REG(dst_y0); - ALLOC_REG(dst_y1); - ALLOC_REG(rect_grid_x1); - ALLOC_REG(rect_grid_y1); - ALLOC_REG(x_transform.multiplier); - ALLOC_REG(x_transform.offset); - ALLOC_REG(y_transform.multiplier); - ALLOC_REG(y_transform.offset); +#define ALLOC_REG(name, type) \ + this->name = \ + retype(brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, \ + base_reg + CONST_LOC(name) / 32, \ + (CONST_LOC(name) % 32) / 4), type) + + ALLOC_REG(dst_x0, BRW_REGISTER_TYPE_UD); + ALLOC_REG(dst_x1, BRW_REGISTER_TYPE_UD); + ALLOC_REG(dst_y0, BRW_REGISTER_TYPE_UD); + ALLOC_REG(dst_y1, BRW_REGISTER_TYPE_UD); + ALLOC_REG(rect_grid_x1, BRW_REGISTER_TYPE_F); + ALLOC_REG(rect_grid_y1, BRW_REGISTER_TYPE_F); + ALLOC_REG(x_transform.multiplier, BRW_REGISTER_TYPE_F); + ALLOC_REG(x_transform.offset, BRW_REGISTER_TYPE_F); + ALLOC_REG(y_transform.multiplier, BRW_REGISTER_TYPE_F); + ALLOC_REG(y_transform.offset, BRW_REGISTER_TYPE_F); #undef CONST_LOC #undef ALLOC_REG } @@ -1442,14 +1440,15 @@ brw_blorp_blit_program::translate_dst_to_src() 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)); - } else { + SWAP_XY_AND_XPYP(); + } else if (!key->bilinear_filter) { /* Round the float coordinates down to nearest integer by moving to * UD registers. */ brw_MOV(&func, Xp, X_f); brw_MOV(&func, Yp, Y_f); + SWAP_XY_AND_XPYP(); } - SWAP_XY_AND_XPYP(); brw_set_compression_control(&func, BRW_COMPRESSION_NONE); } @@ -1873,10 +1872,18 @@ brw_blorp_blit_program::texture_lookup(struct brw_reg dst, for (int arg = 0; arg < num_args; ++arg) { switch (args[arg]) { case SAMPLER_MESSAGE_ARG_U_FLOAT: - brw_MOV(&func, retype(mrf, BRW_REGISTER_TYPE_F), X); + if (key->bilinear_filter) + brw_MOV(&func, retype(mrf, BRW_REGISTER_TYPE_F), + retype(X, BRW_REGISTER_TYPE_F)); + else + brw_MOV(&func, retype(mrf, BRW_REGISTER_TYPE_F), X); break; case SAMPLER_MESSAGE_ARG_V_FLOAT: - brw_MOV(&func, retype(mrf, BRW_REGISTER_TYPE_F), Y); + if (key->bilinear_filter) + brw_MOV(&func, retype(mrf, BRW_REGISTER_TYPE_F), + retype(Y, BRW_REGISTER_TYPE_F)); + else + brw_MOV(&func, retype(mrf, BRW_REGISTER_TYPE_F), Y); break; case SAMPLER_MESSAGE_ARG_U_INT: brw_MOV(&func, mrf, X); @@ -1921,7 +1928,7 @@ brw_blorp_blit_program::texture_lookup(struct brw_reg dst, } brw_SAMPLE(&func, - retype(dst, BRW_REGISTER_TYPE_F) /* dest */, + retype(dst, BRW_REGISTER_TYPE_UW) /* dest */, base_mrf /* msg_reg_nr */, brw_message_reg(base_mrf) /* src0 */, BRW_BLORP_TEXTURE_BINDING_TABLE_INDEX, @@ -2050,15 +2057,33 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw, 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) { struct gl_context *ctx = &brw->ctx; const struct gl_framebuffer *read_fb = ctx->ReadBuffer; - src.set(brw, src_mt, src_level, src_layer); - dst.set(brw, dst_mt, dst_level, dst_layer); + src.set(brw, src_mt, src_level, src_layer, false); + dst.set(brw, dst_mt, dst_level, dst_layer, true); - src.brw_surfaceformat = dst.brw_surfaceformat; + /* 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, + * which means that the type of averaging we do during the resolve should + * only depend on the source format; the destination format should be + * ignored. But, specification doesn't seem to be strict about it. + * + * It has been observed that mulitisample resolves produce slightly better + * looking images when averaging is done using destination format. NVIDIA's + * proprietary OpenGL driver also follow this approach. So, we choose to + * follow it in our driver. + * + * Following if-else block takes care of this exception made for + * multisampled resolves. + */ + if (src.num_samples > 1) + src.brw_surfaceformat = dst.brw_surfaceformat; + else + dst.brw_surfaceformat = src.brw_surfaceformat; use_wm_prog = true; memset(&wm_prog_key, 0, sizeof(wm_prog_key)); @@ -2129,6 +2154,9 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw, wm_prog_key.x_scale = 2.0; wm_prog_key.y_scale = src_mt->num_samples / 2.0; + if (filter == GL_LINEAR) + wm_prog_key.bilinear_filter = true; + /* The render path must be configured to use the same number of samples as * the destination buffer. */