intel/blorp: Take an explicit filter parameter in blorp_blit
This lets us move the glBlitFramebuffer nonsense into the GL driver and make the usage of BLORP mutch more explicit and obvious as to what it's doing. Reviewed-by: Chad Versace <chadversary@chromium.org>
This commit is contained in:
parent
9fbe2a2007
commit
aaa6fac8f6
|
@ -139,7 +139,8 @@ blorp_blit(struct blorp_batch *batch,
|
|||
float src_x1, float src_y1,
|
||||
float dst_x0, float dst_y0,
|
||||
float dst_x1, float dst_y1,
|
||||
uint32_t filter, bool mirror_x, bool mirror_y);
|
||||
enum blorp_filter filter,
|
||||
bool mirror_x, bool mirror_y);
|
||||
|
||||
void
|
||||
blorp_copy(struct blorp_batch *batch,
|
||||
|
|
|
@ -2211,7 +2211,8 @@ blorp_blit(struct blorp_batch *batch,
|
|||
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)
|
||||
enum blorp_filter filter,
|
||||
bool mirror_x, bool mirror_y)
|
||||
{
|
||||
struct blorp_params params;
|
||||
blorp_params_init(¶ms);
|
||||
|
@ -2240,14 +2241,10 @@ blorp_blit(struct blorp_batch *batch,
|
|||
params.dst.view.swizzle = dst_swizzle;
|
||||
|
||||
struct brw_blorp_blit_prog_key wm_prog_key = {
|
||||
.shader_type = BLORP_SHADER_TYPE_BLIT
|
||||
.shader_type = BLORP_SHADER_TYPE_BLIT,
|
||||
.filter = filter,
|
||||
};
|
||||
|
||||
/* Scaled blitting or not. */
|
||||
const bool 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.
|
||||
*/
|
||||
|
@ -2257,39 +2254,6 @@ blorp_blit(struct blorp_batch *batch,
|
|||
wm_prog_key.x_scale = 2.0f;
|
||||
wm_prog_key.y_scale = params.src.surf.samples / wm_prog_key.x_scale;
|
||||
|
||||
const bool bilinear_filter = filter == GL_LINEAR &&
|
||||
params.src.surf.samples <= 1 &&
|
||||
params.dst.surf.samples <= 1;
|
||||
|
||||
/* If we are downsampling a non-integer color buffer, 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.
|
||||
*/
|
||||
const bool blend =
|
||||
(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;
|
||||
|
||||
if (blend && !blit_scaled) {
|
||||
wm_prog_key.filter = BLORP_FILTER_AVERAGE;
|
||||
} else if (blend && blit_scaled) {
|
||||
wm_prog_key.filter = BLORP_FILTER_BILINEAR;
|
||||
} else if (bilinear_filter) {
|
||||
wm_prog_key.filter = BLORP_FILTER_BILINEAR;
|
||||
} else {
|
||||
if (params.src.surf.samples > 1)
|
||||
wm_prog_key.filter = BLORP_FILTER_SAMPLE_0;
|
||||
else
|
||||
wm_prog_key.filter = BLORP_FILTER_NEAREST;
|
||||
}
|
||||
|
||||
params.wm_inputs.rect_grid.x1 =
|
||||
minify(params.src.surf.logical_level0_px.width, src_level) *
|
||||
wm_prog_key.x_scale - 1.0f;
|
||||
|
|
|
@ -513,13 +513,13 @@ void anv_CmdBlitImage(
|
|||
|
||||
struct blorp_surf src, dst;
|
||||
|
||||
uint32_t gl_filter;
|
||||
enum blorp_filter blorp_filter;
|
||||
switch (filter) {
|
||||
case VK_FILTER_NEAREST:
|
||||
gl_filter = 0x2600; /* GL_NEAREST */
|
||||
blorp_filter = BLORP_FILTER_NEAREST;
|
||||
break;
|
||||
case VK_FILTER_LINEAR:
|
||||
gl_filter = 0x2601; /* GL_LINEAR */
|
||||
blorp_filter = BLORP_FILTER_BILINEAR;
|
||||
break;
|
||||
default:
|
||||
unreachable("Invalid filter");
|
||||
|
@ -604,7 +604,7 @@ void anv_CmdBlitImage(
|
|||
dst_format.isl_format, dst_format.swizzle,
|
||||
src_x0, src_y0, src_x1, src_y1,
|
||||
dst_x0, dst_y0, dst_x1, dst_y1,
|
||||
gl_filter, flip_x, flip_y);
|
||||
blorp_filter, flip_x, flip_y);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1171,7 +1171,8 @@ resolve_surface(struct blorp_batch *batch,
|
|||
struct blorp_surf *dst_surf,
|
||||
uint32_t dst_level, uint32_t dst_layer,
|
||||
uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
|
||||
uint32_t width, uint32_t height)
|
||||
uint32_t width, uint32_t height,
|
||||
enum blorp_filter filter)
|
||||
{
|
||||
blorp_blit(batch,
|
||||
src_surf, src_level, src_layer,
|
||||
|
@ -1180,7 +1181,7 @@ resolve_surface(struct blorp_batch *batch,
|
|||
ISL_FORMAT_UNSUPPORTED, ISL_SWIZZLE_IDENTITY,
|
||||
src_x, src_y, src_x + width, src_y + height,
|
||||
dst_x, dst_y, dst_x + width, dst_y + height,
|
||||
0x2600 /* GL_NEAREST */, false, false);
|
||||
filter, false, false);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1219,13 +1220,22 @@ resolve_image(struct anv_device *device,
|
|||
dst_surf.aux_usage,
|
||||
dst_level, dst_layer, 1);
|
||||
|
||||
enum blorp_filter filter;
|
||||
if ((src_surf.surf->usage & ISL_SURF_USAGE_DEPTH_BIT) ||
|
||||
(src_surf.surf->usage & ISL_SURF_USAGE_STENCIL_BIT) ||
|
||||
isl_format_has_int_channel(src_surf.surf->format)) {
|
||||
filter = BLORP_FILTER_SAMPLE_0;
|
||||
} else {
|
||||
filter = BLORP_FILTER_AVERAGE;
|
||||
}
|
||||
|
||||
assert(!src_image->format->can_ycbcr);
|
||||
assert(!dst_image->format->can_ycbcr);
|
||||
|
||||
resolve_surface(batch,
|
||||
&src_surf, src_level, src_layer,
|
||||
&dst_surf, dst_level, dst_layer,
|
||||
src_x, src_y, dst_x, dst_y, width, height);
|
||||
src_x, src_y, dst_x, dst_y, width, height, filter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1340,6 +1350,13 @@ anv_cmd_buffer_resolve_subpass(struct anv_cmd_buffer *cmd_buffer)
|
|||
assert(src_iview->aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT &&
|
||||
dst_iview->aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
enum blorp_filter filter;
|
||||
if (isl_format_has_int_channel(src_iview->planes[0].isl.format)) {
|
||||
filter = BLORP_FILTER_SAMPLE_0;
|
||||
} else {
|
||||
filter = BLORP_FILTER_AVERAGE;
|
||||
}
|
||||
|
||||
struct blorp_surf src_surf, dst_surf;
|
||||
get_blorp_surf_for_anv_image(cmd_buffer->device, src_iview->image,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
|
@ -1381,7 +1398,8 @@ anv_cmd_buffer_resolve_subpass(struct anv_cmd_buffer *cmd_buffer)
|
|||
base_dst_layer + i,
|
||||
render_area.offset.x, render_area.offset.y,
|
||||
render_area.offset.x, render_area.offset.y,
|
||||
render_area.extent.width, render_area.extent.height);
|
||||
render_area.extent.width, render_area.extent.height,
|
||||
filter);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -283,7 +283,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,
|
||||
GLenum filter, bool mirror_x, bool mirror_y,
|
||||
GLenum gl_filter, bool mirror_x, bool mirror_y,
|
||||
bool decode_srgb, bool encode_srgb)
|
||||
{
|
||||
const struct gen_device_info *devinfo = &brw->screen->devinfo;
|
||||
|
@ -320,6 +320,65 @@ brw_blorp_blit_miptrees(struct brw_context *brw,
|
|||
src_format = dst_format = MESA_FORMAT_R_FLOAT32;
|
||||
}
|
||||
|
||||
enum blorp_filter blorp_filter;
|
||||
if (fabsf(dst_x1 - dst_x0) == fabsf(src_x1 - src_x0) &&
|
||||
fabsf(dst_y1 - dst_y0) == fabsf(src_y1 - src_y0)) {
|
||||
if (src_mt->surf.samples > 1 && dst_mt->surf.samples <= 1) {
|
||||
/* From the OpenGL ES 3.2 specification, section 16.2.1:
|
||||
*
|
||||
* "If the read framebuffer is multisampled (its effective value
|
||||
* of SAMPLE_BUFFERS is one) and the draw framebuffer is not (its
|
||||
* value of SAMPLE_BUFFERS is zero), the samples corresponding to
|
||||
* each pixel location in the source are converted to a single
|
||||
* sample before being written to the destination. The filter
|
||||
* parameter is ignored. If the source formats are integer types
|
||||
* or stencil values, a single sample’s value is selected for each
|
||||
* pixel. If the source formats are floating-point or normalized
|
||||
* types, the sample values for each pixel are resolved in an
|
||||
* implementation-dependent manner. If the source formats are
|
||||
* depth values, sample values are resolved in an implementation-
|
||||
* dependent manner where the result will be between the minimum
|
||||
* and maximum depth values in the pixel."
|
||||
*
|
||||
* For depth and stencil resolves, we choose to always use the value
|
||||
* at sample 0.
|
||||
*/
|
||||
GLenum base_format = _mesa_get_format_base_format(src_mt->format);
|
||||
if (base_format == GL_DEPTH_COMPONENT ||
|
||||
base_format == GL_STENCIL_INDEX ||
|
||||
base_format == GL_DEPTH_STENCIL ||
|
||||
_mesa_is_format_integer(src_mt->format)) {
|
||||
/* 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."
|
||||
*
|
||||
* Just take sample 0 in this case.
|
||||
*/
|
||||
blorp_filter = BLORP_FILTER_SAMPLE_0;
|
||||
} else {
|
||||
blorp_filter = BLORP_FILTER_AVERAGE;
|
||||
}
|
||||
} else {
|
||||
/* From the OpenGL 4.6 specification, section 18.3.1:
|
||||
*
|
||||
* "If the source and destination dimensions are identical, no
|
||||
* filtering is applied."
|
||||
*
|
||||
* Using BLORP_FILTER_NONE will also handle the upsample case by
|
||||
* replicating the one value in the source to all values in the
|
||||
* destination.
|
||||
*/
|
||||
blorp_filter = BLORP_FILTER_NONE;
|
||||
}
|
||||
} else if (gl_filter == GL_LINEAR ||
|
||||
gl_filter == GL_SCALED_RESOLVE_FASTEST_EXT ||
|
||||
gl_filter == GL_SCALED_RESOLVE_NICEST_EXT) {
|
||||
blorp_filter = BLORP_FILTER_BILINEAR;
|
||||
} else {
|
||||
blorp_filter = BLORP_FILTER_NEAREST;
|
||||
}
|
||||
|
||||
enum isl_format src_isl_format =
|
||||
brw_blorp_to_isl_format(brw, src_format, false);
|
||||
enum isl_aux_usage src_aux_usage =
|
||||
|
@ -365,7 +424,7 @@ brw_blorp_blit_miptrees(struct brw_context *brw,
|
|||
dst_isl_format, ISL_SWIZZLE_IDENTITY,
|
||||
src_x0, src_y0, src_x1, src_y1,
|
||||
dst_x0, dst_y0, dst_x1, dst_y1,
|
||||
filter, mirror_x, mirror_y);
|
||||
blorp_filter, mirror_x, mirror_y);
|
||||
blorp_batch_finish(&batch);
|
||||
|
||||
intel_miptree_finish_write(brw, dst_mt, dst_level, dst_layer, 1,
|
||||
|
|
Loading…
Reference in New Issue