<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Wed, Jun 27, 2018 at 6:08 PM Chad Versace <<a href="mailto:chadversary@chromium.org">chadversary@chromium.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Tue 26 Jun 2018, Jason Ekstrand wrote:<br>
> This lets us move the glBlitFramebuffer nonsense into the GL driver and<br>
> make the usage of BLORP mutch more explicit and obvious as to what it's<br>
> doing.<br>
> ---<br>
>  src/intel/blorp/blorp.h               |  3 +-<br>
>  src/intel/blorp/blorp_blit.c          | 44 ++-----------------<br>
>  src/intel/vulkan/anv_blorp.c          | 34 +++++++++++----<br>
>  src/mesa/drivers/dri/i965/brw_blorp.c | 63 ++++++++++++++++++++++++++-<br>
>  4 files changed, 93 insertions(+), 51 deletions(-)<br>
<br>
> @@ -2253,39 +2250,6 @@ blorp_blit(struct blorp_batch *batch,<br>
>        wm_prog_key.x_scale = 2.0f;<br>
>     wm_prog_key.y_scale = params.src.surf.samples / wm_prog_key.x_scale;<br>
>  <br>
> -   const bool bilinear_filter = filter == GL_LINEAR &&<br>
> -                                params.src.surf.samples <= 1 &&<br>
> -                                params.dst.surf.samples <= 1;<br>
> -<br>
> -   /* We are downsampling a non-integer color buffer, so blend.<br>
> -    *<br>
> -    * Regarding integer color buffers, the OpenGL ES 3.2 spec says:<br>
> -    *<br>
> -    *    "If the source formats are integer types or stencil values, a<br>
> -    *    single sample's value is selected for each pixel."<br>
> -    *<br>
> -    * This implies we should not blend in that case.<br>
> -    */<br>
> -   const bool blend =<br>
> -      (params.src.surf.usage & ISL_SURF_USAGE_DEPTH_BIT) == 0 &&<br>
> -      (params.src.surf.usage & ISL_SURF_USAGE_STENCIL_BIT) == 0 &&<br>
> -      !isl_format_has_int_channel(params.src.surf.format) &&<br>
> -      params.src.surf.samples > 1 &&<br>
> -      params.dst.surf.samples <= 1;<br>
> -<br>
> -   if (blend && !blit_scaled) {<br>
> -      wm_prog_key.filter = BLORP_FILTER_AVERAGE;<br>
> -   } else if (blend && blit_scaled) {<br>
> -      wm_prog_key.filter = BLORP_FILTER_BILINEAR;<br>
> -   } else if (bilinear_filter) {<br>
> -      wm_prog_key.filter = BLORP_FILTER_BILINEAR;<br>
> -   } else {<br>
> -      if (params.src.surf.samples > 1)<br>
> -         wm_prog_key.filter = BLORP_FILTER_SAMPLE_0;<br>
> -      else<br>
> -         wm_prog_key.filter = BLORP_FILTER_NEAREST;<br>
> -   }<br>
> -<br>
>     params.wm_inputs.rect_grid.x1 =<br>
>        minify(params.src.surf.logical_level0_px.width, src_level) *<br>
>        wm_prog_key.x_scale - 1.0f;<br>
<br>
Crazy GL silliness, be gone! You are not welcome here, in this clean,<br>
pure, do-what-i-say-not-what-i-mean Vulkan driver! Be banished to GL<br>
silly-land forever!<br>
<br>
[snip]<br>
<br>
The following two hunks, combined, are large improvements.  It's crazy<br>
that blorp correctly applied average filtering for multisampled<br>
non-integer color attachments here *despite* the hardcoded GL_NEAREST in<br>
hunk #1.<br>
<br>
> @@ -1181,7 +1182,7 @@ resolve_surface(struct blorp_batch *batch,<br>
>                ISL_FORMAT_UNSUPPORTED, ISL_SWIZZLE_IDENTITY,<br>
>                src_x, src_y, src_x + width, src_y + height,<br>
>                dst_x, dst_y, dst_x + width, dst_y + height,<br>
> -              0x2600 /* GL_NEAREST */, false, false);<br>
> +              filter, false, false);<br>
>  }<br>
>  <br>
>  static void<br>
> @@ -1220,13 +1221,22 @@ resolve_image(struct anv_device *device,<br>
>                                          dst_surf.aux_usage,<br>
>                                          dst_level, dst_layer, 1);<br>
>  <br>
> +      enum blorp_filter filter;<br>
> +      if ((src_surf.surf->usage & ISL_SURF_USAGE_DEPTH_BIT) ||<br>
> +          (src_surf.surf->usage & ISL_SURF_USAGE_STENCIL_BIT) ||<br>
> +          isl_format_has_int_channel(src_surf.surf->format)) {<br>
> +         filter = BLORP_FILTER_SAMPLE_0;<br>
> +      } else {<br>
> +         filter = BLORP_FILTER_AVERAGE;<br>
> +      }<br>
> +<br>
>        assert(!src_image->format->can_ycbcr);<br>
>        assert(!dst_image->format->can_ycbcr);<br>
>  <br>
>        resolve_surface(batch,<br>
>                        &src_surf, src_level, src_layer,<br>
>                        &dst_surf, dst_level, dst_layer,<br>
> -                      src_x, src_y, dst_x, dst_y, width, height);<br>
> +                      src_x, src_y, dst_x, dst_y, width, height, filter);<br>
>     }<br>
>  }<br>
>  <br>
> @@ -1341,6 +1351,13 @@ anv_cmd_buffer_resolve_subpass(struct anv_cmd_buffer *cmd_buffer)<br>
>           assert(src_iview->aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT &&<br>
>                  dst_iview->aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT);<br>
>  <br>
> +         enum blorp_filter filter;<br>
> +         if (isl_format_has_int_channel(src_iview->planes[0].isl.format)) {<br>
> +            filter = BLORP_FILTER_SAMPLE_0;<br>
> +         } else {<br>
> +            filter = BLORP_FILTER_AVERAGE;<br>
> +         }<br>
> +<br>
>           struct blorp_surf src_surf, dst_surf;<br>
>           get_blorp_surf_for_anv_image(cmd_buffer->device, src_iview->image,<br>
>                                        VK_IMAGE_ASPECT_COLOR_BIT,<br>
<br>
[snip]<br>
<br>
> @@ -324,6 +324,65 @@ brw_blorp_blit_miptrees(struct brw_context *brw,<br>
>        src_format = dst_format = MESA_FORMAT_R_FLOAT32;<br>
>     }<br>
>  <br>
> +   enum blorp_filter blorp_filter;<br>
> +   if (fabs(dst_x1 - dst_x0) == fabs(src_x1 - src_x0) &&<br>
> +       fabs(dst_y1 - dst_y0) == fabs(src_y1 - src_y0)) {<br>
<br>
You should use fabsf() here because all params are floats.<br></blockquote><div><br></div><div>Done.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
> +      if (src_mt->surf.samples > 1 && dst_mt->surf.samples <= 1) {<br>
> +         /* From the OpenGL ES 3.2 specification, section 16.2.1:<br>
> +          *<br>
> +          *    "If the read framebuffer is multisampled (its effective value<br>
> +          *    of SAMPLE_BUFFERS is one) and the draw framebuffer is not (its<br>
> +          *    value of SAMPLE_BUFFERS is zero), the samples corresponding to<br>
> +          *    each pixel location in the source are converted to a single<br>
> +          *    sample before being written to the destination.  The filter<br>
> +          *    parameter is ignored. If the source formats are integer types<br>
> +          *    or stencil values, a single sample’s value is selected for each<br>
> +          *    pixel.  If the source formats are floating-point or normalized<br>
> +          *    types, the sample values for each pixel are resolved in an<br>
> +          *    implementation-dependent manner.  If the source formats are<br>
> +          *    depth values, sample values are resolved in an implementation-<br>
> +          *    dependent manner where the result will be between the minimum<br>
> +          *    and maximum depth values in the pixel."<br>
> +          *<br>
> +          * For depth and stencil resolves, we choose to always use the value<br>
> +          * at sample 0.<br>
> +          */<br>
> +         GLenum base_format = _mesa_get_format_base_format(src_mt->format);<br>
> +         if (base_format == GL_DEPTH_COMPONENT ||<br>
> +             base_format == GL_STENCIL_INDEX ||<br>
> +             base_format == GL_DEPTH_STENCIL ||<br>
> +             _mesa_is_format_integer(src_mt->format)) {<br>
> +            /* The OpenGL ES 3.2 spec says:<br>
> +             *<br>
> +             *    "If the source formats are integer types or stencil values,<br>
> +             *    a single sample's value is selected for each pixel."<br>
> +             *<br>
> +             * Just take sample 0 in this case.<br>
> +             */<br>
> +            blorp_filter = BLORP_FILTER_SAMPLE_0;<br>
> +         } else {<br>
> +            blorp_filter = BLORP_FILTER_AVERAGE;<br>
> +         }<br>
> +      } else {<br>
> +         /* From the OpenGL 4.6 specification, section 18.3.1:<br>
> +          *<br>
> +          *    "If the source and destination dimensions are identical, no<br>
> +          *    filtering is applied."<br>
> +          *<br>
> +          * Using BLORP_FILTER_NONE will also handle the upsample case by<br>
> +          * replicating the one value in the source to all values in the<br>
> +          * destination.<br>
> +          */<br>
> +         blorp_filter = BLORP_FILTER_NONE;<br>
> +      }<br>
> +   } else if (gl_filter == GL_LINEAR ||<br>
> +              gl_filter == GL_SCALED_RESOLVE_FASTEST_EXT ||<br>
> +              gl_filter == GL_SCALED_RESOLVE_NICEST_EXT) {<br>
> +      blorp_filter = BLORP_FILTER_BILINEAR;<br>
> +   } else {<br>
> +      blorp_filter = BLORP_FILTER_NEAREST;<br>
> +   }<br>
<br>
This hunk is great. Blorp no longer needs to reverse-engineer what GL<br>
was poorly trying to tell it.<br></blockquote><div><br></div><div>\o/<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
With s/fabs/fabsf/, this patch is<br>
Reviewed-by: Chad Versace <<a href="mailto:chadversary@chromium.org" target="_blank">chadversary@chromium.org</a>><br></blockquote><div><br></div><div>Thanks.  I eagerly await your review on patch 1. <br></div></div></div>