}
static void
-add_image_relocs(struct anv_cmd_buffer * const cmd_buffer,
- const struct anv_image * const image,
- const VkImageAspectFlags aspect_mask,
- const enum isl_aux_usage aux_usage,
- const struct anv_state state)
+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;
- const uint32_t surf_offset = image->offset +
- anv_image_get_surface_for_aspect_mask(image, aspect_mask)->offset;
- add_surface_state_reloc(cmd_buffer, state, image->bo, surf_offset);
+ add_surface_state_reloc(cmd_buffer, state.state,
+ image->planes[plane].bo, state.address);
- if (aux_usage != ISL_AUX_USAGE_NONE) {
- uint32_t aux_offset = image->offset + image->aux_surface.offset;
+ 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[plane].bo,
+ state.aux_address);
+ if (result != VK_SUCCESS)
+ anv_batch_set_error(&cmd_buffer->batch, result);
+ }
+}
- /* On gen7 and prior, the bottom 12 bits of the MCS base address are
- * used to store other information. This should be ok, however, because
- * surface buffer addresses are always 4K page alinged.
- */
- assert((aux_offset & 0xfff) == 0);
- uint32_t *aux_addr_dw = state.map + isl_dev->ss.aux_addr_offset;
- aux_offset += *aux_addr_dw & 0xfff;
+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.offset + isl_dev->ss.aux_addr_offset,
- image->bo, aux_offset);
+ 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);
}
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.
*/
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 {
* 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
}
}
- 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 &&
* 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,
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;
}
* 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 ==
- anv_layout_to_aux_usage(&cmd_buffer->device->info, image, image->aspects,
- initial_layout);
+ anv_layout_to_aux_usage(&cmd_buffer->device->info, image,
+ VK_IMAGE_ASPECT_DEPTH_BIT, initial_layout);
const bool enable_hiz = ISL_AUX_USAGE_HIZ ==
- anv_layout_to_aux_usage(&cmd_buffer->device->info, image, image->aspects,
- final_layout);
+ anv_layout_to_aux_usage(&cmd_buffer->device->info, image,
+ VK_IMAGE_ASPECT_DEPTH_BIT, final_layout);
enum blorp_hiz_op hiz_op;
if (hiz_enabled && !enable_hiz) {
FAST_CLEAR_STATE_FIELD_NEEDS_RESOLVE,
};
-static inline uint32_t
-get_fast_clear_state_offset(const struct anv_device *device,
- const struct anv_image *image,
- unsigned level, enum fast_clear_state_field field)
+static inline struct anv_address
+get_fast_clear_state_address(const struct anv_device *device,
+ const struct anv_image *image,
+ 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:
break;
}
- assert(offset < image->offset + image->size);
- return offset;
+ assert(offset < image->planes[plane].surface.offset + image->planes[plane].size);
+
+ return (struct anv_address) {
+ .bo = image->planes[plane].bo,
+ .offset = offset,
+ };
}
#define MI_PREDICATE_SRC0 0x2400
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 uint32_t resolve_flag_offset =
- get_fast_clear_state_offset(cmd_buffer->device, image, level,
- FAST_CLEAR_STATE_FIELD_NEEDS_RESOLVE);
+ const struct anv_address resolve_flag_addr =
+ 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
* the following command. We use it nevertheless because it shows no
* issues in testing is currently being used in the GL driver.
*/
anv_batch_emit(&cmd_buffer->batch, GENX(MI_STORE_DATA_IMM), sdi) {
- sdi.Address = (struct anv_address) { image->bo, resolve_flag_offset };
+ sdi.Address = resolve_flag_addr;
sdi.ImmediateData = needs_resolve;
}
}
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 uint32_t resolve_flag_offset =
- get_fast_clear_state_offset(cmd_buffer->device, image, level,
- FAST_CLEAR_STATE_FIELD_NEEDS_RESOLVE);
+ const struct anv_address resolve_flag_addr =
+ 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.
* predicate = do_resolve = resolve_flag != 0;
emit_lri(&cmd_buffer->batch, MI_PREDICATE_SRC1 + 4, 0);
emit_lri(&cmd_buffer->batch, MI_PREDICATE_SRC0 , 0);
emit_lrm(&cmd_buffer->batch, MI_PREDICATE_SRC0 + 4,
- image->bo, resolve_flag_offset);
+ resolve_flag_addr.bo, resolve_flag_addr.offset);
anv_batch_emit(&cmd_buffer->batch, GENX(MI_PREDICATE), mip) {
mip.LoadOperation = LOAD_LOADINV;
mip.CombineOperation = COMBINE_SET;
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
* 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.
unsigned i = 0;
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) {
- const uint32_t entry_offset =
- get_fast_clear_state_offset(cmd_buffer->device, image, level,
- FAST_CLEAR_STATE_FIELD_CLEAR_COLOR);
- sdi.Address = (struct anv_address) { image->bo, entry_offset + i };
+ sdi.Address =
+ 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
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;
- uint32_t entry_offset =
- get_fast_clear_state_offset(cmd_buffer->device, image, level,
- FAST_CLEAR_STATE_FIELD_CLEAR_COLOR);
+ const struct anv_address entry_addr =
+ 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;
if (copy_from_surface_state) {
- genX(cmd_buffer_mi_memcpy)(cmd_buffer, image->bo, entry_offset,
+ genX(cmd_buffer_mi_memcpy)(cmd_buffer, entry_addr.bo, entry_addr.offset,
ss_bo, ss_clear_offset, copy_size);
} else {
genX(cmd_buffer_mi_memcpy)(cmd_buffer, ss_bo, ss_clear_offset,
- image->bo, entry_offset, copy_size);
+ entry_addr.bo, entry_addr.offset, copy_size);
/* Updating a surface state object may require that the state cache be
* invalidated. From the SKL PRM, Shared Functions -> State -> State
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,
{
/* 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);
/* No work is necessary if the layout stays the same or if this subresource
* range lacks auxiliary data.
*/
- if (initial_layout == final_layout ||
- base_layer >= anv_image_aux_layers(image, base_level))
+ if (initial_layout == final_layout)
+ return;
+
+ 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->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, aspect, base_level))
return;
/* A transition of a 3D subresource works on all slices at a time. */
}
/* 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
* 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
"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
* 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.
/* 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->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.
*/
- struct anv_state surface_state =
- anv_cmd_buffer_alloc_surface_state(cmd_buffer);
- isl_surf_fill_state(&cmd_buffer->device->isl_dev, surface_state.map,
- .surf = &image->color_surface.isl,
- .view = &(struct isl_view) {
- .usage = ISL_SURF_USAGE_RENDER_TARGET_BIT,
- .format = image->color_surface.isl.format,
- .swizzle = ISL_SWIZZLE_IDENTITY,
- .base_level = level,
- .levels = 1,
- .base_array_layer = base_layer,
- .array_len = layer_count,
- },
- .aux_surf = &image->aux_surface.isl,
- .aux_usage = image->aux_usage == ISL_AUX_USAGE_NONE ?
- ISL_AUX_USAGE_CCS_D : image->aux_usage,
- .mocs = cmd_buffer->device->default_mocs);
- add_image_relocs(cmd_buffer, image, VK_IMAGE_ASPECT_COLOR_BIT,
- image->aux_usage == ISL_AUX_USAGE_CCS_E ?
- ISL_AUX_USAGE_CCS_E : ISL_AUX_USAGE_CCS_D,
- surface_state);
- anv_state_flush(cmd_buffer->device, surface_state);
- genX(copy_fast_clear_dwords)(cmd_buffer, surface_state, image, level,
- false /* copy to ss */);
- anv_ccs_resolve(cmd_buffer, surface_state, image, level, layer_count,
- image->aux_usage == ISL_AUX_USAGE_CCS_E ?
+ struct anv_surface_state surface_state;
+ surface_state.state = anv_cmd_buffer_alloc_surface_state(cmd_buffer);
+ anv_image_fill_surface_state(cmd_buffer->device,
+ image, VK_IMAGE_ASPECT_COLOR_BIT,
+ &(struct isl_view) {
+ .format = image->planes[plane].surface.isl.format,
+ .swizzle = ISL_SWIZZLE_IDENTITY,
+ .base_level = level,
+ .levels = 1,
+ .base_array_layer = base_layer,
+ .array_len = layer_count,
+ },
+ ISL_SURF_USAGE_RENDER_TARGET_BIT,
+ aux_usage, NULL, 0,
+ &surface_state, NULL);
+ add_image_relocs(cmd_buffer, image, 0, surface_state);
+ genX(copy_fast_clear_dwords)(cmd_buffer, surface_state.state, image,
+ aspect, level, false /* copy to ss */);
+ anv_ccs_resolve(cmd_buffer, surface_state.state, image,
+ 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 |=
for (uint32_t i = 0; i < pass->attachment_count; ++i) {
if (vk_format_is_color(pass->attachments[i].format)) {
- state->attachments[i].color_rt_state = next_state;
+ state->attachments[i].color.state = next_state;
next_state.offset += ss_stride;
next_state.map += ss_stride;
}
if (need_input_attachment_state(&pass->attachments[i])) {
- state->attachments[i].input_att_state = next_state;
+ state->attachments[i].input.state = next_state;
next_state.offset += ss_stride;
next_state.map += ss_stride;
}
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;
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);
- struct isl_view view = iview->isl;
- view.usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
- view.swizzle = anv_swizzle_for_render(view.swizzle);
- isl_surf_fill_state(isl_dev,
- state->attachments[i].color_rt_state.map,
- .surf = &iview->image->color_surface.isl,
- .view = &view,
- .aux_surf = &iview->image->aux_surface.isl,
- .aux_usage = state->attachments[i].aux_usage,
- .clear_color = clear_color,
- .mocs = cmd_buffer->device->default_mocs);
-
- add_image_relocs(cmd_buffer, iview->image, iview->aspect_mask,
- state->attachments[i].aux_usage,
- state->attachments[i].color_rt_state);
+ anv_image_fill_surface_state(cmd_buffer->device,
+ iview->image,
+ VK_IMAGE_ASPECT_COLOR_BIT,
+ &iview->planes[0].isl,
+ ISL_SURF_USAGE_RENDER_TARGET_BIT,
+ state->attachments[i].aux_usage,
+ &clear_color,
+ 0,
+ &state->attachments[i].color,
+ NULL);
+
+ add_image_view_relocs(cmd_buffer, iview, 0,
+ state->attachments[i].color);
} else {
/* This field will be initialized after the first subpass
* transition.
}
if (need_input_attachment_state(&pass->attachments[i])) {
- struct isl_view view = iview->isl;
- view.usage |= ISL_SURF_USAGE_TEXTURE_BIT;
- isl_surf_fill_state(isl_dev,
- state->attachments[i].input_att_state.map,
- .surf = &iview->image->color_surface.isl,
- .view = &view,
- .aux_surf = &iview->image->aux_surface.isl,
- .aux_usage = state->attachments[i].input_aux_usage,
- .clear_color = clear_color,
- .mocs = cmd_buffer->device->default_mocs);
-
- add_image_relocs(cmd_buffer, iview->image, iview->aspect_mask,
- state->attachments[i].input_aux_usage,
- state->attachments[i].input_att_state);
+ anv_image_fill_surface_state(cmd_buffer->device,
+ iview->image,
+ VK_IMAGE_ASPECT_COLOR_BIT,
+ &iview->planes[0].isl,
+ ISL_SURF_USAGE_TEXTURE_BIT,
+ state->attachments[i].input_aux_usage,
+ &clear_color,
+ 0,
+ &state->attachments[i].input,
+ NULL);
+
+ add_image_view_relocs(cmd_buffer, iview, 0,
+ state->attachments[i].input);
}
}
-
- anv_state_flush(cmd_buffer->device, state->render_pass_states);
}
return VK_SUCCESS;
VkResult result = VK_SUCCESS;
if (cmd_buffer->usage_flags &
VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) {
+ assert(pBeginInfo->pInheritanceInfo);
cmd_buffer->state.pass =
anv_render_pass_from_handle(pBeginInfo->pInheritanceInfo->renderPass);
cmd_buffer->state.subpass =
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);
+ }
}
}
if (att == VK_ATTACHMENT_UNUSED) {
surface_state = cmd_buffer->state.null_surface_state;
} else {
- surface_state = cmd_buffer->state.attachments[att].color_rt_state;
+ surface_state = cmd_buffer->state.attachments[att].color.state;
}
} else {
surface_state = cmd_buffer->state.null_surface_state;
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: {
- enum isl_aux_usage aux_usage;
- if (desc->layout == VK_IMAGE_LAYOUT_GENERAL) {
- surface_state = desc->image_view->general_sampler_surface_state;
- aux_usage = desc->image_view->general_sampler_aux_usage;
- } else {
- surface_state = desc->image_view->optimal_sampler_surface_state;
- aux_usage = desc->image_view->optimal_sampler_aux_usage;
- }
+ struct anv_surface_state sstate =
+ (desc->layout == VK_IMAGE_LAYOUT_GENERAL) ?
+ 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,
- desc->image_view->aspect_mask,
- aux_usage, surface_state);
+ 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.
*/
- enum isl_aux_usage aux_usage;
- if (desc->layout == VK_IMAGE_LAYOUT_GENERAL) {
- surface_state = desc->image_view->general_sampler_surface_state;
- aux_usage = desc->image_view->general_sampler_aux_usage;
- } else {
- surface_state = desc->image_view->optimal_sampler_surface_state;
- aux_usage = desc->image_view->optimal_sampler_aux_usage;
- }
+ struct anv_surface_state sstate =
+ (desc->layout == VK_IMAGE_LAYOUT_GENERAL) ?
+ 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,
- desc->image_view->aspect_mask,
- aux_usage, surface_state);
+ 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
assert(binding->input_attachment_index < subpass->input_count);
const unsigned subpass_att = binding->input_attachment_index;
const unsigned att = subpass->input_attachments[subpass_att].attachment;
- surface_state = cmd_buffer->state.attachments[att].input_att_state;
+ surface_state = cmd_buffer->state.attachments[att].input.state;
}
break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
- surface_state = (binding->write_only)
- ? desc->image_view->writeonly_storage_surface_state
- : desc->image_view->storage_surface_state;
+ struct anv_surface_state sstate = (binding->write_only)
+ ? 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,
- desc->image_view->aspect_mask,
- desc->image_view->image->aux_usage, surface_state);
+ 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;
}
continue;
memcpy(state->map + (s * 16),
- sampler->state, sizeof(sampler->state));
+ sampler->state[binding->plane], sizeof(sampler->state[0]));
}
anv_state_flush(cmd_buffer->device, *state);
const char *function)
{
if (device->instance->physicalDevice.cmd_parser_version < required_version) {
- return vk_errorf(VK_ERROR_FEATURE_NOT_PRESENT,
+ return vk_errorf(device->instance, device->instance,
+ VK_ERROR_FEATURE_NOT_PRESENT,
"cmd parser version %d is required for %s",
required_version, function);
} else {
};
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);
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
att_state->current_layout, target_layout);
att_state->aux_usage =
anv_layout_to_aux_usage(&cmd_buffer->device->info, image,
- image->aspects, 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,
+ VK_IMAGE_ASPECT_DEPTH_BIT, target_layout);
+ } 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);
}
* render pass and used in the subpass.
*/
const uint32_t a = state->subpass->color_attachments[i].attachment;
- assert(a < state->pass->attachment_count);
if (a == VK_ATTACHMENT_UNUSED)
continue;
+ assert(a < state->pass->attachment_count);
+
/* Store some information regarding this attachment. */
const struct anv_attachment_state *att_state = &state->attachments[a];
const struct anv_image_view *iview = state->framebuffer->attachments[a];
*/
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_rt_state,
- iview->image, iview->isl.base_level,
+ genX(copy_fast_clear_dwords)(cmd_buffer, att_state->color.state,
+ 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
* 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
*
* TODO: Do this only once per render pass instead of every subpass.
*/
- genX(copy_fast_clear_dwords)(cmd_buffer, att_state->color_rt_state,
- iview->image, iview->isl.base_level,
+ genX(copy_fast_clear_dwords)(cmd_buffer, att_state->color.state,
+ 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_att_state,
- iview->image, iview->isl.base_level,
+ genX(copy_fast_clear_dwords)(cmd_buffer, att_state->input.state,
+ iview->image,
+ VK_IMAGE_ASPECT_COLOR_BIT,
+ iview->planes[0].isl.base_level,
false /* copy to ss */);
}
}