diff options
author | Nanley Chery <[email protected]> | 2017-01-05 23:32:07 -0800 |
---|---|---|
committer | Nanley Chery <[email protected]> | 2017-01-12 20:52:20 -0800 |
commit | d16871d9580152c5a041e9d54165f54f366ebb45 (patch) | |
tree | 5aecae22553ce9be2a6157487cdc2bc5977a79b5 /src/intel/vulkan/anv_blorp.c | |
parent | 3b7106c18136a107bd0d396bf061b8c9f914b4b9 (diff) |
anv/blorp: Add a gen8 HiZ op resolve function
Add an entry point for resolving using BLORP's gen8 HiZ op function.
v2: Manually add the aux info
Signed-off-by: Nanley Chery <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
Diffstat (limited to 'src/intel/vulkan/anv_blorp.c')
-rw-r--r-- | src/intel/vulkan/anv_blorp.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c index fdea2d0a23f..f7aaa22554d 100644 --- a/src/intel/vulkan/anv_blorp.c +++ b/src/intel/vulkan/anv_blorp.c @@ -1559,3 +1559,86 @@ anv_cmd_buffer_resolve_subpass(struct anv_cmd_buffer *cmd_buffer) blorp_batch_finish(&batch); } + +void +anv_gen8_hiz_op_resolve(struct anv_cmd_buffer *cmd_buffer, + const struct anv_image *image, + enum blorp_hiz_op op) +{ + assert(image); + + /* Don't resolve depth buffers without an auxiliary HiZ buffer and + * don't perform such a resolve on gens that don't support it. + */ + if (cmd_buffer->device->info.gen < 8 || + image->aux_usage != ISL_AUX_USAGE_HIZ) + return; + + const struct anv_cmd_state *cmd_state = &cmd_buffer->state; + const uint32_t ds = cmd_state->subpass->depth_stencil_attachment; + + /* Section 7.4. of the Vulkan 1.0.27 spec states: + * + * "The render area must be contained within the framebuffer dimensions." + * + * Therefore, the only way the extent of the render area can match that of + * the image view is if the render area offset equals (0, 0). + */ + const bool full_surface_op = + cmd_state->render_area.extent.width == image->extent.width && + cmd_state->render_area.extent.height == image->extent.height; + if (full_surface_op) + assert(cmd_state->render_area.offset.x == 0 && + cmd_state->render_area.offset.y == 0); + + /* Check the subpass index to determine if skipping a resolve is allowed */ + const uint32_t subpass_idx = cmd_state->subpass - cmd_state->pass->subpasses; + switch (op) { + case BLORP_HIZ_OP_DEPTH_RESOLVE: + if (cmd_buffer->state.pass->attachments[ds].store_op != + VK_ATTACHMENT_STORE_OP_STORE && + subpass_idx == cmd_state->pass->subpass_count - 1) + return; + break; + case BLORP_HIZ_OP_HIZ_RESOLVE: + /* If the render area covers the entire surface *and* load_op is either + * CLEAR or DONT_CARE then the previous contents of the depth buffer + * will be entirely discarded. In this case, we can skip the HiZ + * resolve. + * + * If the render area is not the full surface, we need to do + * the resolve because otherwise data outside the render area may get + * garbled by the resolve at the end of the render pass. + */ + if (full_surface_op && + cmd_buffer->state.pass->attachments[ds].load_op != + VK_ATTACHMENT_LOAD_OP_LOAD && subpass_idx == 0) + return; + break; + case BLORP_HIZ_OP_DEPTH_CLEAR: + case BLORP_HIZ_OP_NONE: + unreachable("Invalid HiZ OP"); + } + + + struct blorp_batch batch; + blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0); + + struct blorp_surf surf; + get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_DEPTH_BIT, + ISL_AUX_USAGE_NONE, &surf); + + /* Manually add the aux HiZ surf */ + surf.aux_surf = &image->aux_surface.isl, + surf.aux_addr = (struct blorp_address) { + .buffer = image->bo, + .offset = image->offset + image->aux_surface.offset, + }; + surf.aux_usage = ISL_AUX_USAGE_HIZ; + + surf.clear_color.u32[0] = (uint32_t) + cmd_state->attachments[ds].clear_value.depthStencil.depth; + + blorp_gen6_hiz_op(&batch, &surf, 0, 0, op); + blorp_batch_finish(&batch); +} |