diff options
author | Lionel Landwerlin <[email protected]> | 2017-07-19 12:14:19 +0100 |
---|---|---|
committer | Lionel Landwerlin <[email protected]> | 2017-10-06 16:32:20 +0100 |
commit | a62a97933578a813beb0d27cc8e404850f7fd302 (patch) | |
tree | 4c2848c345858b68ca48b9d7f203a8797f5ceb6b /src/intel/vulkan/genX_cmd_buffer.c | |
parent | 185e719090c8d8a4056a041f3884d86ca224a400 (diff) |
anv: enable multiple planes per image/imageView
This change introduce the concept of planes for image & views. It
matches the planes available in new formats.
We also refactor depth & stencil support through the usage of planes
for the sake of uniformity. In the backend (genX_cmd_buffer.c) we have
to take some care though with regard to auxilliary surfaces.
Multiplanar color buffers can have multiple auxilliary surfaces but
depth & stencil share the same HiZ one (only store in the depth
plane).
v2: by Jason
Remove unused aspect parameters from anv_blorp.c
Assert when attempting to resolve YUV images
Drop redundant logic for plane offset in make_surface()
Rework anv_foreach_plane_aspect_bit()
Signed-off-by: Lionel Landwerlin <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
Diffstat (limited to 'src/intel/vulkan/genX_cmd_buffer.c')
-rw-r--r-- | src/intel/vulkan/genX_cmd_buffer.c | 296 |
1 files changed, 190 insertions, 106 deletions
diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index dcebf1d3c42..93d360a1bbe 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -181,18 +181,45 @@ add_surface_state_reloc(struct anv_cmd_buffer *cmd_buffer, static void add_image_relocs(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *image, + const uint32_t plane, struct anv_surface_state state) { const struct isl_device *isl_dev = &cmd_buffer->device->isl_dev; - add_surface_state_reloc(cmd_buffer, state.state, image->bo, state.address); + add_surface_state_reloc(cmd_buffer, state.state, + image->planes[plane].bo, state.address); if (state.aux_address) { VkResult result = anv_reloc_list_add(&cmd_buffer->surface_relocs, &cmd_buffer->pool->alloc, state.state.offset + isl_dev->ss.aux_addr_offset, - image->bo, state.aux_address); + image->planes[plane].bo, + state.aux_address); + if (result != VK_SUCCESS) + anv_batch_set_error(&cmd_buffer->batch, result); + } +} + +static void +add_image_view_relocs(struct anv_cmd_buffer *cmd_buffer, + const struct anv_image_view *image_view, + const uint32_t plane, + struct anv_surface_state state) +{ + const struct isl_device *isl_dev = &cmd_buffer->device->isl_dev; + const struct anv_image *image = image_view->image; + uint32_t image_plane = image_view->planes[plane].image_plane; + + add_surface_state_reloc(cmd_buffer, state.state, + image->planes[image_plane].bo, state.address); + + if (state.aux_address) { + VkResult result = + anv_reloc_list_add(&cmd_buffer->surface_relocs, + &cmd_buffer->pool->alloc, + state.state.offset + isl_dev->ss.aux_addr_offset, + image->planes[image_plane].bo, state.aux_address); if (result != VK_SUCCESS) anv_batch_set_error(&cmd_buffer->batch, result); } @@ -225,8 +252,11 @@ color_attachment_compute_aux_usage(struct anv_device * device, struct anv_attachment_state *att_state = &cmd_state->attachments[att]; struct anv_image_view *iview = cmd_state->framebuffer->attachments[att]; - if (iview->isl.base_array_layer >= - anv_image_aux_layers(iview->image, iview->isl.base_level)) { + assert(iview->n_planes == 1); + + if (iview->planes[0].isl.base_array_layer >= + anv_image_aux_layers(iview->image, VK_IMAGE_ASPECT_COLOR_BIT, + iview->planes[0].isl.base_level)) { /* There is no aux buffer which corresponds to the level and layer(s) * being accessed. */ @@ -234,12 +264,12 @@ color_attachment_compute_aux_usage(struct anv_device * device, att_state->input_aux_usage = ISL_AUX_USAGE_NONE; att_state->fast_clear = false; return; - } else if (iview->image->aux_usage == ISL_AUX_USAGE_MCS) { + } else if (iview->image->planes[0].aux_usage == ISL_AUX_USAGE_MCS) { att_state->aux_usage = ISL_AUX_USAGE_MCS; att_state->input_aux_usage = ISL_AUX_USAGE_MCS; att_state->fast_clear = false; return; - } else if (iview->image->aux_usage == ISL_AUX_USAGE_CCS_E) { + } else if (iview->image->planes[0].aux_usage == ISL_AUX_USAGE_CCS_E) { att_state->aux_usage = ISL_AUX_USAGE_CCS_E; att_state->input_aux_usage = ISL_AUX_USAGE_CCS_E; } else { @@ -255,7 +285,7 @@ color_attachment_compute_aux_usage(struct anv_device * device, * In other words, we can only sample from a fast-cleared image if it * also supports color compression. */ - if (isl_format_supports_ccs_e(&device->info, iview->isl.format)) { + if (isl_format_supports_ccs_e(&device->info, iview->planes[0].isl.format)) { att_state->input_aux_usage = ISL_AUX_USAGE_CCS_D; /* While fast-clear resolves and partial resolves are fairly cheap in the @@ -274,10 +304,10 @@ color_attachment_compute_aux_usage(struct anv_device * device, } } - assert(iview->image->aux_surface.isl.usage & ISL_SURF_USAGE_CCS_BIT); + assert(iview->image->planes[0].aux_surface.isl.usage & ISL_SURF_USAGE_CCS_BIT); att_state->clear_color_is_zero_one = - color_is_zero_one(att_state->clear_value.color, iview->isl.format); + color_is_zero_one(att_state->clear_value.color, iview->planes[0].isl.format); att_state->clear_color_is_zero = att_state->clear_value.color.uint32[0] == 0 && att_state->clear_value.color.uint32[1] == 0 && @@ -309,7 +339,8 @@ color_attachment_compute_aux_usage(struct anv_device * device, * layers. */ if (cmd_state->framebuffer->layers != - anv_image_aux_layers(iview->image, iview->isl.base_level)) { + anv_image_aux_layers(iview->image, VK_IMAGE_ASPECT_COLOR_BIT, + iview->planes[0].isl.base_level)) { att_state->fast_clear = false; if (GEN_GEN == 7) { anv_perf_warn(device->instance, iview->image, @@ -325,7 +356,7 @@ color_attachment_compute_aux_usage(struct anv_device * device, if (cmd_state->pass->attachments[att].first_subpass_layout == VK_IMAGE_LAYOUT_GENERAL && (!att_state->clear_color_is_zero || - iview->image->aux_usage == ISL_AUX_USAGE_NONE)) { + iview->image->planes[0].aux_usage == ISL_AUX_USAGE_NONE)) { att_state->fast_clear = false; } @@ -370,7 +401,7 @@ transition_depth_buffer(struct anv_cmd_buffer *cmd_buffer, * that's currently in the buffer. Therefore, a data-preserving resolve * operation is not needed. */ - if (image->aux_usage != ISL_AUX_USAGE_HIZ || initial_layout == final_layout) + if (image->planes[0].aux_usage != ISL_AUX_USAGE_HIZ || initial_layout == final_layout) return; const bool hiz_enabled = ISL_AUX_USAGE_HIZ == @@ -403,14 +434,20 @@ enum fast_clear_state_field { static inline struct anv_address get_fast_clear_state_address(const struct anv_device *device, const struct anv_image *image, - unsigned level, enum fast_clear_state_field field) + VkImageAspectFlagBits aspect, + unsigned level, + enum fast_clear_state_field field) { assert(device && image); - assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT); - assert(level < anv_image_aux_levels(image)); - uint32_t offset = image->offset + image->aux_surface.offset + - image->aux_surface.isl.size + - anv_fast_clear_state_entry_size(device) * level; + assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT); + assert(level < anv_image_aux_levels(image, aspect)); + + uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect); + + /* Refer to the definition of anv_image for the memory layout. */ + uint32_t offset = image->planes[plane].fast_clear_state_offset; + + offset += anv_fast_clear_state_entry_size(device) * level; switch (field) { case FAST_CLEAR_STATE_FIELD_NEEDS_RESOLVE: @@ -420,9 +457,10 @@ get_fast_clear_state_address(const struct anv_device *device, break; } - assert(offset < image->offset + image->size); + assert(offset < image->planes[plane].surface.offset + image->planes[plane].size); + return (struct anv_address) { - .bo = image->bo, + .bo = image->planes[plane].bo, .offset = offset, }; } @@ -436,14 +474,15 @@ get_fast_clear_state_address(const struct anv_device *device, static void genX(set_image_needs_resolve)(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *image, + VkImageAspectFlagBits aspect, unsigned level, bool needs_resolve) { assert(cmd_buffer && image); - assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT); - assert(level < anv_image_aux_levels(image)); + assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT); + assert(level < anv_image_aux_levels(image, aspect)); const struct anv_address resolve_flag_addr = - get_fast_clear_state_address(cmd_buffer->device, image, level, + get_fast_clear_state_address(cmd_buffer->device, image, aspect, level, FAST_CLEAR_STATE_FIELD_NEEDS_RESOLVE); /* The HW docs say that there is no way to guarantee the completion of @@ -459,14 +498,15 @@ genX(set_image_needs_resolve)(struct anv_cmd_buffer *cmd_buffer, static void genX(load_needs_resolve_predicate)(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *image, + VkImageAspectFlagBits aspect, unsigned level) { assert(cmd_buffer && image); - assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT); - assert(level < anv_image_aux_levels(image)); + assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT); + assert(level < anv_image_aux_levels(image, aspect)); const struct anv_address resolve_flag_addr = - get_fast_clear_state_address(cmd_buffer->device, image, level, + get_fast_clear_state_address(cmd_buffer->device, image, aspect, level, FAST_CLEAR_STATE_FIELD_NEEDS_RESOLVE); /* Make the pending predicated resolve a no-op if one is not needed. @@ -487,11 +527,15 @@ genX(load_needs_resolve_predicate)(struct anv_cmd_buffer *cmd_buffer, static void init_fast_clear_state_entry(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *image, + VkImageAspectFlagBits aspect, unsigned level) { assert(cmd_buffer && image); - assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT); - assert(level < anv_image_aux_levels(image)); + assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT); + assert(level < anv_image_aux_levels(image, aspect)); + + uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect); + enum isl_aux_usage aux_usage = image->planes[plane].aux_usage; /* The resolve flag should updated to signify that fast-clear/compression * data needs to be removed when leaving the undefined layout. Such data @@ -499,8 +543,8 @@ init_fast_clear_state_entry(struct anv_cmd_buffer *cmd_buffer, * to return incorrect data. The fast clear data in CCS_D buffers should * be removed because CCS_D isn't enabled all the time. */ - genX(set_image_needs_resolve)(cmd_buffer, image, level, - image->aux_usage == ISL_AUX_USAGE_NONE); + genX(set_image_needs_resolve)(cmd_buffer, image, aspect, level, + aux_usage == ISL_AUX_USAGE_NONE); /* The fast clear value dword(s) will be copied into a surface state object. * Ensure that the restrictions of the fields in the dword(s) are followed. @@ -517,12 +561,12 @@ init_fast_clear_state_entry(struct anv_cmd_buffer *cmd_buffer, for (; i < cmd_buffer->device->isl_dev.ss.clear_value_size; i += 4) { anv_batch_emit(&cmd_buffer->batch, GENX(MI_STORE_DATA_IMM), sdi) { sdi.Address = - get_fast_clear_state_address(cmd_buffer->device, image, level, + get_fast_clear_state_address(cmd_buffer->device, image, aspect, level, FAST_CLEAR_STATE_FIELD_CLEAR_COLOR); if (GEN_GEN >= 9) { /* MCS buffers on SKL+ can only have 1/0 clear colors. */ - assert(image->aux_usage == ISL_AUX_USAGE_MCS); + assert(aux_usage == ISL_AUX_USAGE_MCS); sdi.ImmediateData = 0; } else if (GEN_VERSIONx10 >= 75) { /* Pre-SKL, the dword containing the clear values also contains @@ -552,19 +596,20 @@ static void genX(copy_fast_clear_dwords)(struct anv_cmd_buffer *cmd_buffer, struct anv_state surface_state, const struct anv_image *image, + VkImageAspectFlagBits aspect, unsigned level, bool copy_from_surface_state) { assert(cmd_buffer && image); - assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT); - assert(level < anv_image_aux_levels(image)); + assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT); + assert(level < anv_image_aux_levels(image, aspect)); struct anv_bo *ss_bo = &cmd_buffer->device->surface_state_pool.block_pool.bo; uint32_t ss_clear_offset = surface_state.offset + cmd_buffer->device->isl_dev.ss.clear_value_offset; const struct anv_address entry_addr = - get_fast_clear_state_address(cmd_buffer->device, image, level, + get_fast_clear_state_address(cmd_buffer->device, image, aspect, level, FAST_CLEAR_STATE_FIELD_CLEAR_COLOR); unsigned copy_size = cmd_buffer->device->isl_dev.ss.clear_value_size; @@ -605,6 +650,7 @@ genX(copy_fast_clear_dwords)(struct anv_cmd_buffer *cmd_buffer, static void transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *image, + VkImageAspectFlagBits aspect, const uint32_t base_level, uint32_t level_count, uint32_t base_layer, uint32_t layer_count, VkImageLayout initial_layout, @@ -612,7 +658,7 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, { /* Validate the inputs. */ assert(cmd_buffer); - assert(image && image->aspects == VK_IMAGE_ASPECT_COLOR_BIT); + assert(image && image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT); /* These values aren't supported for simplicity's sake. */ assert(level_count != VK_REMAINING_MIP_LEVELS && layer_count != VK_REMAINING_ARRAY_LAYERS); @@ -632,22 +678,25 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, if (initial_layout == final_layout) return; - if (image->shadow_surface.isl.size > 0 && + uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect); + + if (image->planes[plane].shadow_surface.isl.size > 0 && final_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { /* This surface is a linear compressed image with a tiled shadow surface * for texturing. The client is about to use it in READ_ONLY_OPTIMAL so * we need to ensure the shadow copy is up-to-date. */ assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT); - assert(image->color_surface.isl.tiling == ISL_TILING_LINEAR); - assert(image->shadow_surface.isl.tiling != ISL_TILING_LINEAR); - assert(isl_format_is_compressed(image->color_surface.isl.format)); - anv_image_copy_to_shadow(cmd_buffer, image, VK_IMAGE_ASPECT_COLOR_BIT, + assert(image->planes[plane].surface.isl.tiling == ISL_TILING_LINEAR); + assert(image->planes[plane].shadow_surface.isl.tiling != ISL_TILING_LINEAR); + assert(isl_format_is_compressed(image->planes[plane].surface.isl.format)); + assert(plane == 0); + anv_image_copy_to_shadow(cmd_buffer, image, base_level, level_count, base_layer, layer_count); } - if (base_layer >= anv_image_aux_layers(image, base_level)) + if (base_layer >= anv_image_aux_layers(image, aspect, base_level)) return; /* A transition of a 3D subresource works on all slices at a time. */ @@ -657,9 +706,9 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, } /* We're interested in the subresource range subset that has aux data. */ - level_count = MIN2(level_count, anv_image_aux_levels(image) - base_level); + level_count = MIN2(level_count, anv_image_aux_levels(image, aspect) - base_level); layer_count = MIN2(layer_count, - anv_image_aux_layers(image, base_level) - base_layer); + anv_image_aux_layers(image, aspect, base_level) - base_layer); last_level_num = base_level + level_count; /* Record whether or not the layout is undefined. Pre-initialized images @@ -680,7 +729,7 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, * Initialize the relevant clear buffer entries. */ for (unsigned level = base_level; level < last_level_num; level++) - init_fast_clear_state_entry(cmd_buffer, image, level); + init_fast_clear_state_entry(cmd_buffer, image, aspect, level); /* Initialize the aux buffers to enable correct rendering. This operation * requires up to two steps: one to rid the aux buffer of data that may @@ -704,7 +753,8 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, "define an MCS buffer."); } - anv_image_fast_clear(cmd_buffer, image, base_level, level_count, + anv_image_fast_clear(cmd_buffer, image, aspect, + base_level, level_count, base_layer, layer_count); } /* At this point, some elements of the CCS buffer may have the fast-clear @@ -716,7 +766,8 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, * enabled. In this case, we must force the associated CCS buffers of the * specified range to enter the ambiguated state in advance. */ - if (image->samples == 1 && image->aux_usage != ISL_AUX_USAGE_CCS_E && + if (image->samples == 1 && + image->planes[plane].aux_usage != ISL_AUX_USAGE_CCS_E && final_layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { /* The CCS_D buffer may not be enabled in the final layout. Continue * executing this function to perform a resolve. @@ -768,13 +819,14 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, /* The number of layers changes at each 3D miplevel. */ if (image->type == VK_IMAGE_TYPE_3D) { - layer_count = MIN2(layer_count, anv_image_aux_layers(image, level)); + layer_count = MIN2(layer_count, anv_image_aux_layers(image, aspect, level)); } - genX(load_needs_resolve_predicate)(cmd_buffer, image, level); + genX(load_needs_resolve_predicate)(cmd_buffer, image, aspect, level); - enum isl_aux_usage aux_usage = image->aux_usage == ISL_AUX_USAGE_NONE ? - ISL_AUX_USAGE_CCS_D : image->aux_usage; + enum isl_aux_usage aux_usage = + image->planes[plane].aux_usage == ISL_AUX_USAGE_NONE ? + ISL_AUX_USAGE_CCS_D : image->planes[plane].aux_usage; /* Create a surface state with the right clear color and perform the * resolve. @@ -784,7 +836,7 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, anv_image_fill_surface_state(cmd_buffer->device, image, VK_IMAGE_ASPECT_COLOR_BIT, &(struct isl_view) { - .format = image->color_surface.isl.format, + .format = image->planes[plane].surface.isl.format, .swizzle = ISL_SWIZZLE_IDENTITY, .base_level = level, .levels = 1, @@ -794,16 +846,16 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer, ISL_SURF_USAGE_RENDER_TARGET_BIT, aux_usage, NULL, 0, &surface_state, NULL); - add_image_relocs(cmd_buffer, image, surface_state); + add_image_relocs(cmd_buffer, image, 0, surface_state); genX(copy_fast_clear_dwords)(cmd_buffer, surface_state.state, image, - level, false /* copy to ss */); + aspect, level, false /* copy to ss */); anv_ccs_resolve(cmd_buffer, surface_state.state, image, - level, layer_count, - image->aux_usage == ISL_AUX_USAGE_CCS_E ? + aspect, level, layer_count, + image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E ? BLORP_FAST_CLEAR_OP_RESOLVE_PARTIAL : BLORP_FAST_CLEAR_OP_RESOLVE_FULL); - genX(set_image_needs_resolve)(cmd_buffer, image, level, false); + genX(set_image_needs_resolve)(cmd_buffer, image, aspect, level, false); } cmd_buffer->state.pending_pipe_bits |= @@ -889,7 +941,7 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer, VkImageAspectFlags att_aspects = vk_format_aspects(att->format); VkImageAspectFlags clear_aspects = 0; - if (att_aspects == VK_IMAGE_ASPECT_COLOR_BIT) { + if (att_aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT) { /* color attachment */ if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) { clear_aspects |= VK_IMAGE_ASPECT_COLOR_BIT; @@ -913,9 +965,11 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer, struct anv_image_view *iview = framebuffer->attachments[i]; anv_assert(iview->vk_format == att->format); + anv_assert(iview->n_planes == 1); union isl_color_value clear_color = { .u32 = { 0, } }; - if (att_aspects == VK_IMAGE_ASPECT_COLOR_BIT) { + if (att_aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT) { + assert(att_aspects == VK_IMAGE_ASPECT_COLOR_BIT); color_attachment_compute_aux_usage(cmd_buffer->device, state, i, begin->renderArea, &clear_color); @@ -923,7 +977,7 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer, anv_image_fill_surface_state(cmd_buffer->device, iview->image, VK_IMAGE_ASPECT_COLOR_BIT, - &iview->isl, + &iview->planes[0].isl, ISL_SURF_USAGE_RENDER_TARGET_BIT, state->attachments[i].aux_usage, &clear_color, @@ -931,8 +985,8 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer, &state->attachments[i].color, NULL); - add_image_relocs(cmd_buffer, iview->image, - state->attachments[i].color); + add_image_view_relocs(cmd_buffer, iview, 0, + state->attachments[i].color); } else { /* This field will be initialized after the first subpass * transition. @@ -946,7 +1000,7 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer, anv_image_fill_surface_state(cmd_buffer->device, iview->image, VK_IMAGE_ASPECT_COLOR_BIT, - &iview->isl, + &iview->planes[0].isl, ISL_SURF_USAGE_TEXTURE_BIT, state->attachments[i].input_aux_usage, &clear_color, @@ -954,8 +1008,8 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer, &state->attachments[i].input, NULL); - add_image_relocs(cmd_buffer, iview->image, - state->attachments[i].input); + add_image_view_relocs(cmd_buffer, iview, 0, + state->attachments[i].input); } } } @@ -1380,14 +1434,20 @@ void genX(CmdPipelineBarrier)( transition_depth_buffer(cmd_buffer, image, pImageMemoryBarriers[i].oldLayout, pImageMemoryBarriers[i].newLayout); - } else if (range->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) { - transition_color_buffer(cmd_buffer, image, - range->baseMipLevel, - anv_get_levelCount(image, range), - range->baseArrayLayer, - anv_get_layerCount(image, range), - pImageMemoryBarriers[i].oldLayout, - pImageMemoryBarriers[i].newLayout); + } else if (range->aspectMask & VK_IMAGE_ASPECT_ANY_COLOR_BIT) { + VkImageAspectFlags color_aspects = + anv_image_expand_aspects(image, range->aspectMask); + uint32_t aspect_bit; + + anv_foreach_image_aspect_bit(aspect_bit, image, color_aspects) { + transition_color_buffer(cmd_buffer, image, 1UL << aspect_bit, + range->baseMipLevel, + anv_get_levelCount(image, range), + range->baseArrayLayer, + anv_get_layerCount(image, range), + pImageMemoryBarriers[i].oldLayout, + pImageMemoryBarriers[i].newLayout); + } } } @@ -1578,26 +1638,28 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer, case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: { struct anv_surface_state sstate = (desc->layout == VK_IMAGE_LAYOUT_GENERAL) ? - desc->image_view->general_sampler_surface_state : - desc->image_view->optimal_sampler_surface_state; + desc->image_view->planes[binding->plane].general_sampler_surface_state : + desc->image_view->planes[binding->plane].optimal_sampler_surface_state; surface_state = sstate.state; assert(surface_state.alloc_size); - add_image_relocs(cmd_buffer, desc->image_view->image, sstate); + add_image_view_relocs(cmd_buffer, desc->image_view, + binding->plane, sstate); break; } case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: assert(stage == MESA_SHADER_FRAGMENT); - if (desc->image_view->aspect_mask != VK_IMAGE_ASPECT_COLOR_BIT) { + if ((desc->image_view->aspect_mask & VK_IMAGE_ASPECT_ANY_COLOR_BIT) == 0) { /* For depth and stencil input attachments, we treat it like any * old texture that a user may have bound. */ struct anv_surface_state sstate = (desc->layout == VK_IMAGE_LAYOUT_GENERAL) ? - desc->image_view->general_sampler_surface_state : - desc->image_view->optimal_sampler_surface_state; + desc->image_view->planes[binding->plane].general_sampler_surface_state : + desc->image_view->planes[binding->plane].optimal_sampler_surface_state; surface_state = sstate.state; assert(surface_state.alloc_size); - add_image_relocs(cmd_buffer, desc->image_view->image, sstate); + add_image_view_relocs(cmd_buffer, desc->image_view, + binding->plane, sstate); } else { /* For color input attachments, we create the surface state at * vkBeginRenderPass time so that we can include aux and clear @@ -1612,16 +1674,17 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer, case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: { struct anv_surface_state sstate = (binding->write_only) - ? desc->image_view->writeonly_storage_surface_state - : desc->image_view->storage_surface_state; + ? desc->image_view->planes[binding->plane].writeonly_storage_surface_state + : desc->image_view->planes[binding->plane].storage_surface_state; surface_state = sstate.state; assert(surface_state.alloc_size); - add_image_relocs(cmd_buffer, desc->image_view->image, sstate); + add_image_view_relocs(cmd_buffer, desc->image_view, + binding->plane, sstate); struct brw_image_param *image_param = &cmd_buffer->state.push_constants[stage]->images[image++]; - *image_param = desc->image_view->storage_image_param; + *image_param = desc->image_view->planes[binding->plane].storage_image_param; image_param->surface_idx = bias + s; break; } @@ -2750,41 +2813,51 @@ cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer) }; if (iview) - info.view = &iview->isl; + info.view = &iview->planes[0].isl; if (image && (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) { - info.depth_surf = &image->depth_surface.isl; + uint32_t depth_plane = + anv_image_aspect_to_plane(image->aspects, VK_IMAGE_ASPECT_DEPTH_BIT); + const struct anv_surface *surface = &image->planes[depth_plane].surface; + + info.depth_surf = &surface->isl; info.depth_address = anv_batch_emit_reloc(&cmd_buffer->batch, dw + device->isl_dev.ds.depth_offset / 4, - image->bo, - image->offset + image->depth_surface.offset); + image->planes[depth_plane].bo, + image->planes[depth_plane].bo_offset + + surface->offset); const uint32_t ds = cmd_buffer->state.subpass->depth_stencil_attachment.attachment; info.hiz_usage = cmd_buffer->state.attachments[ds].aux_usage; if (info.hiz_usage == ISL_AUX_USAGE_HIZ) { - info.hiz_surf = &image->aux_surface.isl; + info.hiz_surf = &image->planes[depth_plane].aux_surface.isl; info.hiz_address = anv_batch_emit_reloc(&cmd_buffer->batch, dw + device->isl_dev.ds.hiz_offset / 4, - image->bo, - image->offset + image->aux_surface.offset); + image->planes[depth_plane].bo, + image->planes[depth_plane].bo_offset + + image->planes[depth_plane].aux_surface.offset); info.depth_clear_value = ANV_HZ_FC_VAL; } } if (image && (image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT)) { - info.stencil_surf = &image->stencil_surface.isl; + uint32_t stencil_plane = + anv_image_aspect_to_plane(image->aspects, VK_IMAGE_ASPECT_STENCIL_BIT); + const struct anv_surface *surface = &image->planes[stencil_plane].surface; + + info.stencil_surf = &surface->isl; info.stencil_address = anv_batch_emit_reloc(&cmd_buffer->batch, dw + device->isl_dev.ds.stencil_offset / 4, - image->bo, - image->offset + image->stencil_surface.offset); + image->planes[stencil_plane].bo, + image->planes[stencil_plane].bo_offset + surface->offset); } isl_emit_depth_stencil_hiz_s(&device->isl_dev, dw, &info); @@ -2874,7 +2947,7 @@ cmd_buffer_subpass_transition_layouts(struct anv_cmd_buffer * const cmd_buffer, att_state->input_aux_usage != att_state->aux_usage; if (subpass_end) { target_layout = att_desc->final_layout; - } else if (iview->aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT && + } else if (iview->aspect_mask & VK_IMAGE_ASPECT_ANY_COLOR_BIT && !input_needs_resolve) { /* Layout transitions before the final only help to enable sampling as * an input attachment. If the input attachment supports sampling @@ -2893,11 +2966,12 @@ cmd_buffer_subpass_transition_layouts(struct anv_cmd_buffer * const cmd_buffer, att_state->aux_usage = anv_layout_to_aux_usage(&cmd_buffer->device->info, image, VK_IMAGE_ASPECT_DEPTH_BIT, target_layout); - } else if (image->aspects == VK_IMAGE_ASPECT_COLOR_BIT) { - transition_color_buffer(cmd_buffer, image, - iview->isl.base_level, 1, - iview->isl.base_array_layer, - iview->isl.array_len, + } else if (image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT) { + assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT); + transition_color_buffer(cmd_buffer, image, VK_IMAGE_ASPECT_COLOR_BIT, + iview->planes[0].isl.base_level, 1, + iview->planes[0].isl.base_array_layer, + iview->planes[0].isl.array_len, att_state->current_layout, target_layout); } @@ -2942,11 +3016,13 @@ cmd_buffer_subpass_sync_fast_clear_values(struct anv_cmd_buffer *cmd_buffer) if (att_state->pending_clear_aspects && att_state->fast_clear) { /* Update the fast clear state entry. */ genX(copy_fast_clear_dwords)(cmd_buffer, att_state->color.state, - iview->image, iview->isl.base_level, + iview->image, + VK_IMAGE_ASPECT_COLOR_BIT, + iview->planes[0].isl.base_level, true /* copy from ss */); /* Fast-clears impact whether or not a resolve will be necessary. */ - if (iview->image->aux_usage == ISL_AUX_USAGE_CCS_E && + if (iview->image->planes[0].aux_usage == ISL_AUX_USAGE_CCS_E && att_state->clear_color_is_zero) { /* This image always has the auxiliary buffer enabled. We can mark * the subresource as not needing a resolve because the clear color @@ -2954,10 +3030,14 @@ cmd_buffer_subpass_sync_fast_clear_values(struct anv_cmd_buffer *cmd_buffer) * being used for sampling. */ genX(set_image_needs_resolve)(cmd_buffer, iview->image, - iview->isl.base_level, false); + VK_IMAGE_ASPECT_COLOR_BIT, + iview->planes[0].isl.base_level, + false); } else { genX(set_image_needs_resolve)(cmd_buffer, iview->image, - iview->isl.base_level, true); + VK_IMAGE_ASPECT_COLOR_BIT, + iview->planes[0].isl.base_level, + true); } } else if (rp_att->load_op == VK_ATTACHMENT_LOAD_OP_LOAD) { /* The attachment may have been fast-cleared in a previous render @@ -2966,13 +3046,17 @@ cmd_buffer_subpass_sync_fast_clear_values(struct anv_cmd_buffer *cmd_buffer) * TODO: Do this only once per render pass instead of every subpass. */ genX(copy_fast_clear_dwords)(cmd_buffer, att_state->color.state, - iview->image, iview->isl.base_level, + iview->image, + VK_IMAGE_ASPECT_COLOR_BIT, + iview->planes[0].isl.base_level, false /* copy to ss */); if (need_input_attachment_state(rp_att) && att_state->input_aux_usage != ISL_AUX_USAGE_NONE) { genX(copy_fast_clear_dwords)(cmd_buffer, att_state->input.state, - iview->image, iview->isl.base_level, + iview->image, + VK_IMAGE_ASPECT_COLOR_BIT, + iview->planes[0].isl.base_level, false /* copy to ss */); } } |