[Mesa-dev] [PATCH 9/9] intel/blorp: Refactor MCS clears
Jason Ekstrand
jason at jlekstrand.net
Tue May 15 22:28:12 UTC 2018
This commit renames blorp_fast_clear to blorp_mcs_clear, pulls in the
fast clear rectangle calculation into the function, and removes the
unneeded level parameter. We could have also removed the x0, y0, x1,
and y1 parameters because all of the callers only do full-slice clears.
However, partial clears are a thing that we can, in theory, do under the
right conditions. We may as well keep them for a rainy day.
---
src/intel/blorp/blorp.h | 13 ++--
src/intel/blorp/blorp_clear.c | 143 ++++++++++++++--------------------
src/intel/vulkan/anv_blorp.c | 6 +-
src/mesa/drivers/dri/i965/brw_blorp.c | 6 +-
4 files changed, 71 insertions(+), 97 deletions(-)
diff --git a/src/intel/blorp/blorp.h b/src/intel/blorp/blorp.h
index e27ea7e..6a4501d 100644
--- a/src/intel/blorp/blorp.h
+++ b/src/intel/blorp/blorp.h
@@ -142,12 +142,6 @@ blorp_buffer_copy(struct blorp_batch *batch,
uint64_t size);
void
-blorp_fast_clear(struct blorp_batch *batch,
- const struct blorp_surf *surf, enum isl_format format,
- uint32_t level, uint32_t start_layer, uint32_t num_layers,
- uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1);
-
-void
blorp_clear(struct blorp_batch *batch,
const struct blorp_surf *surf,
enum isl_format format, struct isl_swizzle swizzle,
@@ -208,6 +202,13 @@ blorp_ccs_op(struct blorp_batch *batch,
enum isl_aux_op ccs_op);
void
+blorp_mcs_clear(struct blorp_batch *batch,
+ const struct blorp_surf *surf,
+ enum isl_format format,
+ uint32_t start_layer, uint32_t num_layers,
+ uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1);
+
+void
blorp_mcs_partial_resolve(struct blorp_batch *batch,
struct blorp_surf *surf,
enum isl_format format,
diff --git a/src/intel/blorp/blorp_clear.c b/src/intel/blorp/blorp_clear.c
index 5625221..ee1a204 100644
--- a/src/intel/blorp/blorp_clear.c
+++ b/src/intel/blorp/blorp_clear.c
@@ -179,107 +179,80 @@ blorp_params_get_layer_offset_vs(struct blorp_context *blorp,
return result;
}
-/* The x0, y0, x1, and y1 parameters must already be populated with the render
- * area of the framebuffer to be cleared.
- */
-static void
-get_fast_clear_rect(const struct isl_device *dev,
- const struct isl_surf *aux_surf,
- unsigned *x0, unsigned *y0,
- unsigned *x1, unsigned *y1)
-{
- unsigned int x_align, y_align;
- unsigned int x_scaledown, y_scaledown;
-
- /* Only single sampled surfaces need to (and actually can) be resolved. */
- if (aux_surf->usage == ISL_SURF_USAGE_CCS_BIT) {
- unreachable("This function only supports MCS fast-clear");
- } else {
- assert(aux_surf->usage == ISL_SURF_USAGE_MCS_BIT);
-
- /* From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render
- * Target(s)", beneath the "MSAA Compression" bullet (p326):
- *
- * Clear pass for this case requires that scaled down primitive
- * is sent down with upper left co-ordinate to coincide with
- * actual rectangle being cleared. For MSAA, clear rectangle’s
- * height and width need to as show in the following table in
- * terms of (width,height) of the RT.
- *
- * MSAA Width of Clear Rect Height of Clear Rect
- * 2X Ceil(1/8*width) Ceil(1/2*height)
- * 4X Ceil(1/8*width) Ceil(1/2*height)
- * 8X Ceil(1/2*width) Ceil(1/2*height)
- * 16X width Ceil(1/2*height)
- *
- * The text "with upper left co-ordinate to coincide with actual
- * rectangle being cleared" is a little confusing--it seems to imply
- * that to clear a rectangle from (x,y) to (x+w,y+h), one needs to
- * feed the pipeline using the rectangle (x,y) to
- * (x+Ceil(w/N),y+Ceil(h/2)), where N is either 2 or 8 depending on
- * the number of samples. Experiments indicate that this is not
- * quite correct; actually, what the hardware appears to do is to
- * align whatever rectangle is sent down the pipeline to the nearest
- * multiple of 2x2 blocks, and then scale it up by a factor of N
- * horizontally and 2 vertically. So the resulting alignment is 4
- * vertically and either 4 or 16 horizontally, and the scaledown
- * factor is 2 vertically and either 2 or 8 horizontally.
- */
- switch (aux_surf->format) {
- case ISL_FORMAT_MCS_2X:
- case ISL_FORMAT_MCS_4X:
- x_scaledown = 8;
- break;
- case ISL_FORMAT_MCS_8X:
- x_scaledown = 2;
- break;
- case ISL_FORMAT_MCS_16X:
- x_scaledown = 1;
- break;
- default:
- unreachable("Unexpected MCS format for fast clear");
- }
- y_scaledown = 2;
- x_align = x_scaledown * 2;
- y_align = y_scaledown * 2;
- }
-
- *x0 = ROUND_DOWN_TO(*x0, x_align) / x_scaledown;
- *y0 = ROUND_DOWN_TO(*y0, y_align) / y_scaledown;
- *x1 = ALIGN(*x1, x_align) / x_scaledown;
- *y1 = ALIGN(*y1, y_align) / y_scaledown;
-}
-
void
-blorp_fast_clear(struct blorp_batch *batch,
- const struct blorp_surf *surf, enum isl_format format,
- uint32_t level, uint32_t start_layer, uint32_t num_layers,
- uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1)
+blorp_mcs_clear(struct blorp_batch *batch,
+ const struct blorp_surf *surf,
+ enum isl_format format,
+ uint32_t start_layer, uint32_t num_layers,
+ uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1)
{
/* Ensure that all layers undergoing the clear have an auxiliary buffer. */
assert(start_layer + num_layers <=
- MAX2(surf->aux_surf->logical_level0_px.depth >> level,
- surf->aux_surf->logical_level0_px.array_len));
+ surf->aux_surf->logical_level0_px.array_len);
struct blorp_params params;
blorp_params_init(¶ms);
params.num_layers = num_layers;
- params.x0 = x0;
- params.y0 = y0;
- params.x1 = x1;
- params.y1 = y1;
+ /* From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render
+ * Target(s)", beneath the "MSAA Compression" bullet (p326):
+ *
+ * Clear pass for this case requires that scaled down primitive
+ * is sent down with upper left co-ordinate to coincide with
+ * actual rectangle being cleared. For MSAA, clear rectangle’s
+ * height and width need to as show in the following table in
+ * terms of (width,height) of the RT.
+ *
+ * MSAA Width of Clear Rect Height of Clear Rect
+ * 2X Ceil(1/8*width) Ceil(1/2*height)
+ * 4X Ceil(1/8*width) Ceil(1/2*height)
+ * 8X Ceil(1/2*width) Ceil(1/2*height)
+ * 16X width Ceil(1/2*height)
+ *
+ * The text "with upper left co-ordinate to coincide with actual
+ * rectangle being cleared" is a little confusing--it seems to imply
+ * that to clear a rectangle from (x,y) to (x+w,y+h), one needs to
+ * feed the pipeline using the rectangle (x,y) to
+ * (x+Ceil(w/N),y+Ceil(h/2)), where N is either 2 or 8 depending on
+ * the number of samples. Experiments indicate that this is not
+ * quite correct; actually, what the hardware appears to do is to
+ * align whatever rectangle is sent down the pipeline to the nearest
+ * multiple of 2x2 blocks, and then scale it up by a factor of N
+ * horizontally and 2 vertically. So the resulting alignment is 4
+ * vertically and either 4 or 16 horizontally, and the scaledown
+ * factor is 2 vertically and either 2 or 8 horizontally.
+ */
+ uint32_t x_scaledown;
+ switch (surf->aux_surf->format) {
+ case ISL_FORMAT_MCS_2X:
+ case ISL_FORMAT_MCS_4X:
+ x_scaledown = 8;
+ break;
+ case ISL_FORMAT_MCS_8X:
+ x_scaledown = 2;
+ break;
+ case ISL_FORMAT_MCS_16X:
+ x_scaledown = 1;
+ break;
+ default:
+ unreachable("Unexpected MCS format for fast clear");
+ }
+ uint32_t y_scaledown = 2;
+ uint32_t x_align = x_scaledown * 2;
+ uint32_t y_align = y_scaledown * 2;
+
+ params.x0 = ROUND_DOWN_TO(x0, x_align) / x_scaledown;
+ params.y0 = ROUND_DOWN_TO(y0, y_align) / y_scaledown;
+ params.x1 = ALIGN(x1, x_align) / x_scaledown;
+ params.y1 = ALIGN(y1, y_align) / y_scaledown;
memset(¶ms.wm_inputs.clear_color, 0xff, 4*sizeof(float));
params.fast_clear_op = ISL_AUX_OP_FAST_CLEAR;
- get_fast_clear_rect(batch->blorp->isl_dev, surf->aux_surf,
- ¶ms.x0, ¶ms.y0, ¶ms.x1, ¶ms.y1);
-
if (!blorp_params_get_clear_kernel(batch->blorp, ¶ms, true))
return;
- brw_blorp_surface_info_init(batch->blorp, ¶ms.dst, surf, level,
+ brw_blorp_surface_info_init(batch->blorp, ¶ms.dst, surf, 0,
start_layer, format, true);
params.num_samples = params.dst.surf.samples;
diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c
index d71a648..9126350 100644
--- a/src/intel/vulkan/anv_blorp.c
+++ b/src/intel/vulkan/anv_blorp.c
@@ -1668,9 +1668,9 @@ anv_image_mcs_op(struct anv_cmd_buffer *cmd_buffer,
switch (mcs_op) {
case ISL_AUX_OP_FAST_CLEAR:
- blorp_fast_clear(&batch, &surf, surf.surf->format,
- 0, base_layer, layer_count,
- 0, 0, image->extent.width, image->extent.height);
+ blorp_mcs_clear(&batch, &surf, surf.surf->format,
+ base_layer, layer_count,
+ 0, 0, image->extent.width, image->extent.height);
break;
case ISL_AUX_OP_PARTIAL_RESOLVE:
blorp_mcs_partial_resolve(&batch, &surf, surf.surf->format,
diff --git a/src/mesa/drivers/dri/i965/brw_blorp.c b/src/mesa/drivers/dri/i965/brw_blorp.c
index b6097f5..d83fafb 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.c
+++ b/src/mesa/drivers/dri/i965/brw_blorp.c
@@ -1265,9 +1265,9 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
blorp_ccs_op(&batch, &surf, level, irb->mt_layer, num_layers,
isl_format, ISL_AUX_OP_FAST_CLEAR);
} else {
- blorp_fast_clear(&batch, &surf, isl_format,
- level, irb->mt_layer, num_layers,
- x0, y0, x1, y1);
+ blorp_mcs_clear(&batch, &surf, isl_format,
+ irb->mt_layer, num_layers,
+ x0, y0, x1, y1);
}
blorp_batch_finish(&batch);
--
2.5.0.400.gff86faf
More information about the mesa-dev
mailing list