diff options
author | Jason Ekstrand <[email protected]> | 2016-11-17 22:55:30 -0800 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2016-11-22 14:24:29 -0800 |
commit | 5e8069a5726ec62ce21d1d708cb6e82ae628de14 (patch) | |
tree | c0b8c245bf660f23cf3f1940237e9643d07f317e /src/intel/vulkan/anv_blorp.c | |
parent | dae8e52030dc289562f5079a4049de7ff6261e8e (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.c | 102 |
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 |