summaryrefslogtreecommitdiffstats
path: root/src/intel/vulkan/anv_blorp.c
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2016-11-17 22:55:30 -0800
committerJason Ekstrand <[email protected]>2016-11-22 14:24:29 -0800
commit5e8069a5726ec62ce21d1d708cb6e82ae628de14 (patch)
treec0b8c245bf660f23cf3f1940237e9643d07f317e /src/intel/vulkan/anv_blorp.c
parentdae8e52030dc289562f5079a4049de7ff6261e8e (diff)
anv: Add support for fast clears on gen9
Reviewed-by: Jordan Justen <[email protected]>
Diffstat (limited to 'src/intel/vulkan/anv_blorp.c')
-rw-r--r--src/intel/vulkan/anv_blorp.c102
1 files changed, 88 insertions, 14 deletions
diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c
index 4b639e4a139..159e4a01d01 100644
--- a/src/intel/vulkan/anv_blorp.c
+++ b/src/intel/vulkan/anv_blorp.c
@@ -1193,16 +1193,35 @@ anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer)
struct blorp_surf surf;
get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_COLOR_BIT,
att_state->aux_usage, &surf);
+ surf.clear_color = vk_to_isl_color(att_state->clear_value.color);
const VkRect2D render_area = cmd_buffer->state.render_area;
- blorp_clear(&batch, &surf, iview->isl.format, iview->isl.swizzle,
- iview->isl.base_level,
- iview->isl.base_array_layer, fb->layers,
- render_area.offset.x, render_area.offset.y,
- render_area.offset.x + render_area.extent.width,
- render_area.offset.y + render_area.extent.height,
- vk_to_isl_color(att_state->clear_value.color), NULL);
+ if (att_state->fast_clear) {
+ blorp_fast_clear(&batch, &surf, iview->isl.format,
+ iview->isl.base_level,
+ iview->isl.base_array_layer, fb->layers,
+ render_area.offset.x, render_area.offset.y,
+ render_area.offset.x + render_area.extent.width,
+ render_area.offset.y + render_area.extent.height);
+
+ /* From the Sky Lake PRM Vol. 7, "Render Target Fast Clear":
+ *
+ * "After Render target fast clear, pipe-control with color cache
+ * write-flush must be issued before sending any DRAW commands on
+ * that render target."
+ */
+ cmd_buffer->state.pending_pipe_bits |=
+ ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;
+ } else {
+ blorp_clear(&batch, &surf, iview->isl.format, iview->isl.swizzle,
+ iview->isl.base_level,
+ iview->isl.base_array_layer, fb->layers,
+ render_area.offset.x, render_area.offset.y,
+ render_area.offset.x + render_area.extent.width,
+ render_area.offset.y + render_area.extent.height,
+ surf.clear_color, NULL);
+ }
att_state->pending_clear_aspects = 0;
}
@@ -1313,10 +1332,12 @@ ccs_resolve_attachment(struct anv_cmd_buffer *cmd_buffer,
struct anv_attachment_state *att_state =
&cmd_buffer->state.attachments[att];
- assert(att_state->aux_usage != ISL_AUX_USAGE_CCS_D);
- if (att_state->aux_usage != ISL_AUX_USAGE_CCS_E)
+ if (att_state->aux_usage == ISL_AUX_USAGE_NONE)
return; /* Nothing to resolve */
+ assert(att_state->aux_usage == ISL_AUX_USAGE_CCS_E ||
+ att_state->aux_usage == ISL_AUX_USAGE_CCS_D);
+
struct anv_render_pass *pass = cmd_buffer->state.pass;
struct anv_subpass *subpass = cmd_buffer->state.subpass;
unsigned subpass_idx = subpass - pass->subpasses;
@@ -1327,14 +1348,17 @@ ccs_resolve_attachment(struct anv_cmd_buffer *cmd_buffer,
* of a particular attachment. That way we only resolve once but it's
* still hot in the cache.
*/
+ bool found_draw = false;
+ enum anv_subpass_usage usage = 0;
for (uint32_t s = subpass_idx + 1; s < pass->subpass_count; s++) {
- enum anv_subpass_usage usage = pass->attachments[att].subpass_usage[s];
+ usage |= pass->attachments[att].subpass_usage[s];
if (usage & (ANV_SUBPASS_USAGE_DRAW | ANV_SUBPASS_USAGE_RESOLVE_DST)) {
/* We found another subpass that draws to this attachment. We'll
* wait to resolve until then.
*/
- return;
+ found_draw = true;
+ break;
}
}
@@ -1342,12 +1366,60 @@ ccs_resolve_attachment(struct anv_cmd_buffer *cmd_buffer,
const struct anv_image *image = iview->image;
assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
- if (image->aux_usage == ISL_AUX_USAGE_CCS_E)
+ enum blorp_fast_clear_op resolve_op = BLORP_FAST_CLEAR_OP_NONE;
+ if (!found_draw) {
+ /* This is the last subpass that writes to this attachment so we need to
+ * resolve here. Ideally, we would like to only resolve if the storeOp
+ * is set to VK_ATTACHMENT_STORE_OP_STORE. However, we need to ensure
+ * that the CCS bits are set to "resolved" because there may be copy or
+ * blit operations (which may ignore CCS) between now and the next time
+ * we render and we need to ensure that anything they write will be
+ * respected in the next render. Unfortunately, the hardware does not
+ * provide us with any sort of "invalidate" pass that sets the CCS to
+ * "resolved" without writing to the render target.
+ */
+ if (iview->image->aux_usage != ISL_AUX_USAGE_CCS_E) {
+ /* The image destination surface doesn't support compression outside
+ * the render pass. We need a full resolve.
+ */
+ resolve_op = BLORP_FAST_CLEAR_OP_RESOLVE_FULL;
+ } else if (att_state->fast_clear) {
+ /* We don't know what to do with clear colors outside the render
+ * pass. We need a partial resolve.
+ */
+ resolve_op = BLORP_FAST_CLEAR_OP_RESOLVE_PARTIAL;
+ } else {
+ /* The image "natively" supports all the compression we care about
+ * and we don't need to resolve at all. If this is the case, we also
+ * don't need to resolve for any of the input attachment cases below.
+ */
+ }
+ } else if (usage & ANV_SUBPASS_USAGE_INPUT) {
+ /* Input attachments are clear-color aware so, at least on Sky Lake, we
+ * can frequently sample from them with no resolves at all.
+ */
+ if (att_state->aux_usage != att_state->input_aux_usage) {
+ assert(att_state->input_aux_usage == ISL_AUX_USAGE_NONE);
+ resolve_op = BLORP_FAST_CLEAR_OP_RESOLVE_FULL;
+ } else if (!att_state->clear_color_is_zero_one) {
+ /* Sky Lake PRM, Vol. 2d, RENDER_SURFACE_STATE::Red Clear Color:
+ *
+ * "If Number of Multisamples is MULTISAMPLECOUNT_1 AND if this RT
+ * is fast cleared with non-0/1 clear value, this RT must be
+ * partially resolved (refer to Partial Resolve operation) before
+ * binding this surface to Sampler."
+ */
+ resolve_op = BLORP_FAST_CLEAR_OP_RESOLVE_PARTIAL;
+ }
+ }
+
+ if (resolve_op == BLORP_FAST_CLEAR_OP_NONE)
return;
struct blorp_surf surf;
get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_COLOR_BIT,
att_state->aux_usage, &surf);
+ surf.clear_color = vk_to_isl_color(att_state->clear_value.color);
/* From the Sky Lake PRM Vol. 7, "Render Target Resolve":
*
@@ -1368,12 +1440,14 @@ ccs_resolve_attachment(struct anv_cmd_buffer *cmd_buffer,
blorp_ccs_resolve(batch, &surf,
iview->isl.base_level,
iview->isl.base_array_layer + layer,
- iview->isl.format,
- BLORP_FAST_CLEAR_OP_RESOLVE_FULL);
+ iview->isl.format, resolve_op);
}
cmd_buffer->state.pending_pipe_bits |=
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;
+
+ /* Once we've done any sort of resolve, we're no longer fast-cleared */
+ att_state->fast_clear = false;
}
void