summaryrefslogtreecommitdiffstats
path: root/src/intel/vulkan/genX_cmd_buffer.c
diff options
context:
space:
mode:
authorLionel Landwerlin <[email protected]>2017-07-19 12:14:19 +0100
committerLionel Landwerlin <[email protected]>2017-10-06 16:32:20 +0100
commita62a97933578a813beb0d27cc8e404850f7fd302 (patch)
tree4c2848c345858b68ca48b9d7f203a8797f5ceb6b /src/intel/vulkan/genX_cmd_buffer.c
parent185e719090c8d8a4056a041f3884d86ca224a400 (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.c296
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 */);
}
}