[Mesa-dev] [PATCH 14/15] anv: enable multiple planes per image/imageView
Lionel Landwerlin
lionel.g.landwerlin at intel.com
Fri Sep 15 14:11:06 UTC 2017
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).
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
---
src/intel/vulkan/anv_blorp.c | 324 ++++++++++++-----
src/intel/vulkan/anv_dump.c | 17 +-
src/intel/vulkan/anv_formats.c | 3 +-
src/intel/vulkan/anv_image.c | 708 ++++++++++++++++++++++++-------------
src/intel/vulkan/anv_intel.c | 4 +-
src/intel/vulkan/anv_private.h | 228 +++++++++---
src/intel/vulkan/anv_wsi.c | 8 +-
src/intel/vulkan/gen8_cmd_buffer.c | 2 +-
src/intel/vulkan/genX_cmd_buffer.c | 312 +++++++++-------
9 files changed, 1049 insertions(+), 557 deletions(-)
diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c
index c1f6eb69ca8..5f11944c092 100644
--- a/src/intel/vulkan/anv_blorp.c
+++ b/src/intel/vulkan/anv_blorp.c
@@ -177,30 +177,58 @@ get_blorp_surf_for_anv_buffer(struct anv_device *device,
static void
get_blorp_surf_for_anv_image(const struct anv_image *image,
+ uint32_t plane,
VkImageAspectFlags aspect,
enum isl_aux_usage aux_usage,
struct blorp_surf *blorp_surf)
{
+ /* For the stencil surface aux_usage is always NONE. */
if (aspect == VK_IMAGE_ASPECT_STENCIL_BIT ||
aux_usage == ISL_AUX_USAGE_HIZ)
aux_usage = ISL_AUX_USAGE_NONE;
- const struct anv_surface *surface =
- anv_image_get_surface_for_aspect_mask(image, aspect);
+ const struct anv_surface *surface = &image->planes[plane].surface;
*blorp_surf = (struct blorp_surf) {
.surf = &surface->isl,
.addr = {
- .buffer = image->bo,
- .offset = image->offset + surface->offset,
+ .buffer = surface->bo,
+ .offset = surface->offset + surface->bo_offset,
},
};
if (aux_usage != ISL_AUX_USAGE_NONE) {
- blorp_surf->aux_surf = &image->aux_surface.isl,
+ const struct anv_surface *aux_surface =
+ &image->planes[plane].aux_surface;
+
+ blorp_surf->aux_surf = &aux_surface->isl,
blorp_surf->aux_addr = (struct blorp_address) {
- .buffer = image->bo,
- .offset = image->offset + image->aux_surface.offset,
+ .buffer = surface->bo,
+ .offset = surface->offset + aux_surface->offset,
+ };
+ blorp_surf->aux_usage = aux_usage;
+ }
+}
+
+static void
+get_blorp_surf_for_anv_surface(const struct anv_surface *surface,
+ const struct anv_surface *aux_surface,
+ enum isl_aux_usage aux_usage,
+ struct blorp_surf *blorp_surf)
+{
+ *blorp_surf = (struct blorp_surf) {
+ .surf = &surface->isl,
+ .addr = {
+ .buffer = surface->bo,
+ .offset = surface->offset + surface->bo_offset,
+ },
+ };
+
+ if (aux_usage != ISL_AUX_USAGE_NONE) {
+ blorp_surf->aux_surf = &aux_surface->isl,
+ blorp_surf->aux_addr = (struct blorp_address) {
+ .buffer = surface->bo,
+ .offset = surface->offset + aux_surface->offset,
};
blorp_surf->aux_usage = aux_usage;
}
@@ -249,17 +277,44 @@ void anv_CmdCopyImage(
anv_get_layerCount(src_image, &pRegions[r].srcSubresource));
}
- assert(pRegions[r].srcSubresource.aspectMask ==
- pRegions[r].dstSubresource.aspectMask);
-
- uint32_t a;
- for_each_bit(a, pRegions[r].dstSubresource.aspectMask) {
- VkImageAspectFlagBits aspect = (1 << a);
-
+ VkImageAspectFlags src_mask = pRegions[r].srcSubresource.aspectMask,
+ dst_mask = pRegions[r].dstSubresource.aspectMask;
+
+ assert(anv_image_aspects_compatible(src_mask, dst_mask));
+
+ if (_mesa_bitcount(src_mask) > 1) {
+ uint32_t plane, bit_aspect;
+ anv_foreach_plane_aspect_bit(plane, bit_aspect, src_mask,
+ src_image->aspects) {
+ struct blorp_surf src_surf, dst_surf;
+ get_blorp_surf_for_anv_image(src_image, plane, 1UL << bit_aspect,
+ src_image->planes[plane].aux_usage,
+ &src_surf);
+ get_blorp_surf_for_anv_image(dst_image, plane, 1UL << bit_aspect,
+ dst_image->planes[plane].aux_usage,
+ &dst_surf);
+
+ for (unsigned i = 0; i < layer_count; i++) {
+ blorp_copy(&batch, &src_surf, pRegions[r].srcSubresource.mipLevel,
+ src_base_layer + i,
+ &dst_surf, pRegions[r].dstSubresource.mipLevel,
+ dst_base_layer + i,
+ srcOffset.x, srcOffset.y,
+ dstOffset.x, dstOffset.y,
+ extent.width, extent.height);
+ }
+ }
+ } else {
+ uint32_t src_plane = anv_image_aspect_to_plane(src_image->aspects,
+ src_mask),
+ dst_plane = anv_image_aspect_to_plane(dst_image->aspects,
+ dst_mask);
struct blorp_surf src_surf, dst_surf;
- get_blorp_surf_for_anv_image(src_image, aspect, src_image->aux_usage,
+ get_blorp_surf_for_anv_image(src_image, src_plane, src_mask,
+ src_image->planes[src_plane].aux_usage,
&src_surf);
- get_blorp_surf_for_anv_image(dst_image, aspect, dst_image->aux_usage,
+ get_blorp_surf_for_anv_image(dst_image, dst_plane, dst_mask,
+ dst_image->planes[dst_plane].aux_usage,
&dst_surf);
for (unsigned i = 0; i < layer_count; i++) {
@@ -270,7 +325,7 @@ void anv_CmdCopyImage(
srcOffset.x, srcOffset.y,
dstOffset.x, dstOffset.y,
extent.width, extent.height);
- }
+ }
}
}
@@ -307,8 +362,10 @@ copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,
for (unsigned r = 0; r < regionCount; r++) {
const VkImageAspectFlags aspect = pRegions[r].imageSubresource.aspectMask;
+ uint32_t plane = anv_image_aspect_to_plane(anv_image->aspects, aspect);
- get_blorp_surf_for_anv_image(anv_image, aspect, anv_image->aux_usage,
+ get_blorp_surf_for_anv_image(anv_image, plane, aspect,
+ anv_image->planes[plane].aux_usage,
&image.surf);
image.offset =
anv_sanitize_image_offset(anv_image->type, pRegions[r].imageOffset);
@@ -455,10 +512,15 @@ void anv_CmdBlitImage(
const VkImageSubresourceLayers *src_res = &pRegions[r].srcSubresource;
const VkImageSubresourceLayers *dst_res = &pRegions[r].dstSubresource;
- get_blorp_surf_for_anv_image(src_image, src_res->aspectMask,
- src_image->aux_usage, &src);
- get_blorp_surf_for_anv_image(dst_image, dst_res->aspectMask,
- dst_image->aux_usage, &dst);
+ const uint32_t src_plane = anv_image_aspect_to_plane(src_image->aspects,
+ src_res->aspectMask),
+ dst_plane = anv_image_aspect_to_plane(dst_image->aspects,
+ dst_res->aspectMask);
+
+ get_blorp_surf_for_anv_image(src_image, src_plane, src_res->aspectMask,
+ src_image->planes[src_plane].aux_usage, &src);
+ get_blorp_surf_for_anv_image(dst_image, dst_plane, dst_res->aspectMask,
+ dst_image->planes[dst_plane].aux_usage, &dst);
struct anv_format_plane src_format =
anv_get_plane_format(&cmd_buffer->device->info, src_image->vk_format,
@@ -751,15 +813,19 @@ void anv_CmdClearColorImage(
struct blorp_batch batch;
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
- struct blorp_surf surf;
- get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_COLOR_BIT,
- image->aux_usage, &surf);
for (unsigned r = 0; r < rangeCount; r++) {
if (pRanges[r].aspectMask == 0)
continue;
- assert(pRanges[r].aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
+ assert(pRanges[r].aspectMask & VK_IMAGE_ASPECT_ANY_COLOR_BIT);
+
+ const uint32_t plane = anv_image_aspect_to_plane(image->aspects,
+ pRanges[r].aspectMask);
+
+ struct blorp_surf surf;
+ get_blorp_surf_for_anv_image(image, plane, pRanges[r].aspectMask,
+ image->planes[plane].aux_usage, &surf);
struct anv_format_plane src_format =
anv_get_plane_format(&cmd_buffer->device->info, image->vk_format,
@@ -805,14 +871,20 @@ void anv_CmdClearDepthStencilImage(
struct blorp_surf depth, stencil;
if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
- get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_DEPTH_BIT,
+ uint32_t depth_plane =
+ anv_image_aspect_to_plane(image->aspects, VK_IMAGE_ASPECT_DEPTH_BIT);
+ get_blorp_surf_for_anv_image(image, depth_plane,
+ VK_IMAGE_ASPECT_DEPTH_BIT,
ISL_AUX_USAGE_NONE, &depth);
} else {
memset(&depth, 0, sizeof(depth));
}
if (image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
- get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_STENCIL_BIT,
+ uint32_t stencil_plane =
+ anv_image_aspect_to_plane(image->aspects, VK_IMAGE_ASPECT_STENCIL_BIT);
+ get_blorp_surf_for_anv_image(image, stencil_plane,
+ VK_IMAGE_ASPECT_STENCIL_BIT,
ISL_AUX_USAGE_NONE, &stencil);
} else {
memset(&stencil, 0, sizeof(stencil));
@@ -1046,7 +1118,7 @@ void anv_CmdClearAttachments(
BLORP_BATCH_NO_EMIT_DEPTH_STENCIL);
for (uint32_t a = 0; a < attachmentCount; ++a) {
- if (pAttachments[a].aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {
+ if (pAttachments[a].aspectMask & VK_IMAGE_ASPECT_ANY_COLOR_BIT) {
clear_color_attachment(cmd_buffer, &batch,
&pAttachments[a],
rectCount, pRects);
@@ -1132,7 +1204,7 @@ anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer)
struct anv_image_view *iview = fb->attachments[a];
const struct anv_image *image = iview->image;
struct blorp_surf surf;
- get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_COLOR_BIT,
+ get_blorp_surf_for_anv_image(image, 0, VK_IMAGE_ASPECT_COLOR_BIT,
att_state->aux_usage, &surf);
if (att_state->fast_clear) {
@@ -1157,24 +1229,26 @@ anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer)
cmd_buffer->state.pending_pipe_bits |=
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;
- blorp_fast_clear(&batch, &surf, iview->isl.format,
- iview->isl.base_level,
- iview->isl.base_array_layer, fb->layers,
- render_area.offset.x, render_area.offset.y,
- render_area.offset.x + render_area.extent.width,
- render_area.offset.y + render_area.extent.height);
+ for (unsigned p = 0; p < iview->n_planes; p++)
+ blorp_fast_clear(&batch, &surf, iview->planes[p].isl.format,
+ iview->planes[p].isl.base_level,
+ iview->planes[p].isl.base_array_layer, fb->layers,
+ render_area.offset.x, render_area.offset.y,
+ render_area.offset.x + render_area.extent.width,
+ render_area.offset.y + render_area.extent.height);
cmd_buffer->state.pending_pipe_bits |=
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;
} else {
- blorp_clear(&batch, &surf, iview->isl.format,
- anv_swizzle_for_render(iview->isl.swizzle),
- iview->isl.base_level,
- iview->isl.base_array_layer, fb->layers,
- render_area.offset.x, render_area.offset.y,
- render_area.offset.x + render_area.extent.width,
- render_area.offset.y + render_area.extent.height,
- vk_to_isl_color(att_state->clear_value.color), NULL);
+ for (unsigned p = 0; p < iview->n_planes; p++)
+ blorp_clear(&batch, &surf, iview->planes[p].isl.format,
+ anv_swizzle_for_render(iview->planes[p].isl.swizzle),
+ iview->planes[p].isl.base_level,
+ iview->planes[p].isl.base_array_layer, fb->layers,
+ render_area.offset.x, render_area.offset.y,
+ render_area.offset.x + render_area.extent.width,
+ render_area.offset.y + render_area.extent.height,
+ vk_to_isl_color(att_state->clear_value.color), NULL);
}
att_state->pending_clear_aspects = 0;
@@ -1209,7 +1283,7 @@ anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer)
* a stencil clear in addition to using the BLORP-fallback for depth.
*/
if (clear_depth) {
- if (!blorp_can_hiz_clear_depth(gen, iview->isl.format,
+ if (!blorp_can_hiz_clear_depth(gen, iview->planes[0].isl.format,
iview->image->samples,
render_area.offset.x,
render_area.offset.y,
@@ -1226,8 +1300,7 @@ anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer)
clear_with_hiz = false;
} else if (gen == 8 &&
anv_can_sample_with_hiz(&cmd_buffer->device->info,
- iview->aspect_mask,
- iview->image->samples)) {
+ iview->image)) {
/* Only gen9+ supports returning ANV_HZ_FC_VAL when sampling a
* fast-cleared portion of a HiZ buffer. Testing has revealed
* that Gen8 only supports returning 0.0f. Gens prior to gen8 do
@@ -1278,13 +1351,41 @@ anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer)
blorp_batch_finish(&batch);
}
+static void
+resolve_surface(struct blorp_batch *batch,
+ const struct anv_surface *src_surface,
+ const struct anv_surface *src_aux_surface,
+ enum isl_aux_usage src_aux_usage,
+ uint32_t src_level, uint32_t src_layer,
+ const struct anv_surface *dst_surface,
+ const struct anv_surface *dst_aux_surface,
+ enum isl_aux_usage dst_aux_usage,
+ uint32_t dst_level, uint32_t dst_layer,
+ uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
+ uint32_t width, uint32_t height)
+{
+ struct blorp_surf src_surf, dst_surf;
+
+ get_blorp_surf_for_anv_surface(src_surface, src_aux_surface,
+ src_aux_usage, &src_surf);
+ get_blorp_surf_for_anv_surface(dst_surface, dst_aux_surface,
+ dst_aux_usage, &dst_surf);
+
+ blorp_blit(batch,
+ &src_surf, src_level, src_layer,
+ ISL_FORMAT_UNSUPPORTED, ISL_SWIZZLE_IDENTITY,
+ &dst_surf, dst_level, dst_layer,
+ ISL_FORMAT_UNSUPPORTED, ISL_SWIZZLE_IDENTITY,
+ src_x, src_y, src_x + width, src_y + height,
+ dst_x, dst_y, dst_x + width, dst_y + height,
+ 0x2600 /* GL_NEAREST */, false, false);
+}
+
static void
resolve_image(struct blorp_batch *batch,
const struct anv_image *src_image,
- enum isl_aux_usage src_aux_usage,
uint32_t src_level, uint32_t src_layer,
const struct anv_image *dst_image,
- enum isl_aux_usage dst_aux_usage,
uint32_t dst_level, uint32_t dst_layer,
VkImageAspectFlags aspect_mask,
uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
@@ -1294,25 +1395,29 @@ resolve_image(struct blorp_batch *batch,
assert(src_image->samples > 1);
assert(dst_image->type == VK_IMAGE_TYPE_2D);
assert(dst_image->samples == 1);
-
- uint32_t a;
- for_each_bit(a, aspect_mask) {
- VkImageAspectFlagBits aspect = 1 << a;
-
- struct blorp_surf src_surf, dst_surf;
- get_blorp_surf_for_anv_image(src_image, aspect,
- src_aux_usage, &src_surf);
- get_blorp_surf_for_anv_image(dst_image, aspect,
- dst_aux_usage, &dst_surf);
-
- blorp_blit(batch,
- &src_surf, src_level, src_layer,
- ISL_FORMAT_UNSUPPORTED, ISL_SWIZZLE_IDENTITY,
- &dst_surf, dst_level, dst_layer,
- ISL_FORMAT_UNSUPPORTED, ISL_SWIZZLE_IDENTITY,
- src_x, src_y, src_x + width, src_y + height,
- dst_x, dst_y, dst_x + width, dst_y + height,
- 0x2600 /* GL_NEAREST */, false, false);
+ assert(src_image->n_planes == dst_image->n_planes);
+
+ uint32_t plane, aspect_bit;
+ anv_foreach_plane_aspect_bit(plane, aspect_bit, aspect_mask,
+ src_image->aspects) {
+ uint32_t width_div = src_image->format->planes[plane].denominator_scales[0],
+ height_div = src_image->format->planes[plane].denominator_scales[1];
+
+ resolve_surface(batch,
+ &src_image->planes[plane].surface,
+ &src_image->planes[plane].aux_surface,
+ src_image->planes[plane].aux_usage,
+ src_level, src_layer,
+ &dst_image->planes[plane].surface,
+ &dst_image->planes[plane].aux_surface,
+ dst_image->planes[plane].aux_usage,
+ dst_level, dst_layer,
+ src_x / width_div,
+ src_y / height_div,
+ dst_x / width_div,
+ dst_y / height_div,
+ width / width_div,
+ height / height_div);
}
}
@@ -1343,10 +1448,10 @@ void anv_CmdResolveImage(
for (uint32_t layer = 0; layer < layer_count; layer++) {
resolve_image(&batch,
- src_image, src_image->aux_usage,
+ src_image,
pRegions[r].srcSubresource.mipLevel,
pRegions[r].srcSubresource.baseArrayLayer + layer,
- dst_image, dst_image->aux_usage,
+ dst_image,
pRegions[r].dstSubresource.mipLevel,
pRegions[r].dstSubresource.baseArrayLayer + layer,
pRegions[r].dstSubresource.aspectMask,
@@ -1362,6 +1467,7 @@ void anv_CmdResolveImage(
void
anv_image_fast_clear(struct anv_cmd_buffer *cmd_buffer,
const struct anv_image *image,
+ const uint32_t plane,
const uint32_t base_level, const uint32_t level_count,
const uint32_t base_layer, uint32_t layer_count)
{
@@ -1376,9 +1482,9 @@ anv_image_fast_clear(struct anv_cmd_buffer *cmd_buffer,
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
struct blorp_surf surf;
- get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_COLOR_BIT,
- image->aux_usage == ISL_AUX_USAGE_NONE ?
- ISL_AUX_USAGE_CCS_D : image->aux_usage,
+ get_blorp_surf_for_anv_image(image, plane, VK_IMAGE_ASPECT_COLOR_BIT,
+ image->planes[plane].aux_usage == ISL_AUX_USAGE_NONE ?
+ ISL_AUX_USAGE_CCS_D : image->planes[plane].aux_usage,
&surf);
/* From the Sky Lake PRM Vol. 7, "Render Target Fast Clear":
@@ -1399,6 +1505,9 @@ anv_image_fast_clear(struct anv_cmd_buffer *cmd_buffer,
cmd_buffer->state.pending_pipe_bits |=
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;
+ uint32_t width_div = image->format->planes[plane].denominator_scales[0],
+ height_div = image->format->planes[plane].denominator_scales[1];
+
for (uint32_t l = 0; l < level_count; l++) {
const uint32_t level = base_level + l;
@@ -1411,11 +1520,13 @@ anv_image_fast_clear(struct anv_cmd_buffer *cmd_buffer,
if (image->type == VK_IMAGE_TYPE_3D)
layer_count = extent.depth;
- assert(level < anv_image_aux_levels(image));
- assert(base_layer + layer_count <= anv_image_aux_layers(image, level));
+ assert(level < anv_image_aux_levels(image, plane));
+ assert(base_layer + layer_count <= anv_image_aux_layers(image, plane, level));
blorp_fast_clear(&batch, &surf, surf.surf->format,
level, base_layer, layer_count,
- 0, 0, extent.width, extent.height);
+ 0, 0,
+ extent.width / width_div,
+ extent.height / height_div);
}
cmd_buffer->state.pending_pipe_bits |=
@@ -1472,17 +1583,31 @@ anv_cmd_buffer_resolve_subpass(struct anv_cmd_buffer *cmd_buffer)
const VkRect2D render_area = cmd_buffer->state.render_area;
assert(src_iview->aspect_mask == dst_iview->aspect_mask);
-
- resolve_image(&batch, src_iview->image, src_aux_usage,
- src_iview->isl.base_level,
- src_iview->isl.base_array_layer,
- dst_iview->image, dst_aux_usage,
- dst_iview->isl.base_level,
- dst_iview->isl.base_array_layer,
- src_iview->aspect_mask,
- render_area.offset.x, render_area.offset.y,
- render_area.offset.x, render_area.offset.y,
- render_area.extent.width, render_area.extent.height);
+ assert(src_iview->n_planes == 1);
+ assert(dst_iview->n_planes == 1);
+
+ const struct anv_format *format = src_iview->image->format;
+
+ uint32_t width_div = format->planes[0].denominator_scales[0],
+ height_div = format->planes[0].denominator_scales[1];
+
+ resolve_surface(&batch,
+ &src_iview->image->planes[0].surface,
+ &src_iview->image->planes[0].aux_surface,
+ src_aux_usage,
+ src_iview->planes[0].isl.base_level,
+ src_iview->planes[0].isl.base_array_layer,
+ &dst_iview->image->planes[0].surface,
+ &dst_iview->image->planes[0].aux_surface,
+ dst_aux_usage,
+ dst_iview->planes[0].isl.base_level,
+ dst_iview->planes[0].isl.base_array_layer,
+ render_area.offset.x / width_div,
+ render_area.offset.y / height_div,
+ render_area.offset.x / width_div,
+ render_area.offset.y / height_div,
+ render_area.extent.width / width_div,
+ render_area.extent.height / height_div);
}
blorp_batch_finish(&batch);
@@ -1500,7 +1625,7 @@ anv_gen8_hiz_op_resolve(struct anv_cmd_buffer *cmd_buffer,
* don't perform such a resolve on gens that don't support it.
*/
if (cmd_buffer->device->info.gen < 8 ||
- image->aux_usage != ISL_AUX_USAGE_HIZ)
+ image->planes[0].aux_usage != ISL_AUX_USAGE_HIZ)
return;
assert(op == BLORP_HIZ_OP_HIZ_RESOLVE ||
@@ -1510,14 +1635,15 @@ anv_gen8_hiz_op_resolve(struct anv_cmd_buffer *cmd_buffer,
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
struct blorp_surf surf;
- get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_DEPTH_BIT,
+ get_blorp_surf_for_anv_image(image, 0, VK_IMAGE_ASPECT_DEPTH_BIT,
ISL_AUX_USAGE_NONE, &surf);
/* Manually add the aux HiZ surf */
- surf.aux_surf = &image->aux_surface.isl,
+ surf.aux_surf = &image->planes[0].aux_surface.isl,
surf.aux_addr = (struct blorp_address) {
- .buffer = image->bo,
- .offset = image->offset + image->aux_surface.offset,
+ .buffer = image->planes[0].surface.bo,
+ .offset = image->planes[0].surface.bo_offset +
+ image->planes[0].aux_surface.offset,
};
surf.aux_usage = ISL_AUX_USAGE_HIZ;
@@ -1531,15 +1657,16 @@ void
anv_ccs_resolve(struct anv_cmd_buffer * const cmd_buffer,
const struct anv_state surface_state,
const struct anv_image * const image,
+ const uint32_t plane,
const uint8_t level, const uint32_t layer_count,
const enum blorp_fast_clear_op op)
{
assert(cmd_buffer && image);
/* The resolved subresource range must have a CCS buffer. */
- assert(level < anv_image_aux_levels(image));
- assert(layer_count <= anv_image_aux_layers(image, level));
- assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT && image->samples == 1);
+ assert(level < anv_image_aux_levels(image, plane));
+ assert(layer_count <= anv_image_aux_layers(image, plane, level));
+ assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT && image->samples == 1);
/* Create a binding table for this surface state. */
uint32_t binding_table;
@@ -1554,13 +1681,14 @@ anv_ccs_resolve(struct anv_cmd_buffer * const cmd_buffer,
BLORP_BATCH_PREDICATE_ENABLE);
struct blorp_surf surf;
- get_blorp_surf_for_anv_image(image, VK_IMAGE_ASPECT_COLOR_BIT,
- image->aux_usage == ISL_AUX_USAGE_CCS_E ?
+ get_blorp_surf_for_anv_image(image, plane, VK_IMAGE_ASPECT_COLOR_BIT,
+ image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E ?
ISL_AUX_USAGE_CCS_E : ISL_AUX_USAGE_CCS_D,
&surf);
blorp_ccs_resolve_attachment(&batch, binding_table, &surf, level,
- layer_count, image->color_surface.isl.format,
+ layer_count,
+ image->planes[plane].surface.isl.format,
op);
blorp_batch_finish(&batch);
diff --git a/src/intel/vulkan/anv_dump.c b/src/intel/vulkan/anv_dump.c
index 0608904219e..160c18c4f17 100644
--- a/src/intel/vulkan/anv_dump.c
+++ b/src/intel/vulkan/anv_dump.c
@@ -424,20 +424,25 @@ anv_dump_add_framebuffer(struct anv_cmd_buffer *cmd_buffer,
uint32_t b;
for_each_bit(b, iview->image->aspects) {
VkImageAspectFlagBits aspect = (1 << b);
- char suffix;
+ const char *suffix;
switch (aspect) {
- case VK_IMAGE_ASPECT_COLOR_BIT: suffix = 'c'; break;
- case VK_IMAGE_ASPECT_DEPTH_BIT: suffix = 'd'; break;
- case VK_IMAGE_ASPECT_STENCIL_BIT: suffix = 's'; break;
+ case VK_IMAGE_ASPECT_COLOR_BIT: suffix = "c"; break;
+ case VK_IMAGE_ASPECT_DEPTH_BIT: suffix = "d"; break;
+ case VK_IMAGE_ASPECT_STENCIL_BIT: suffix = "s"; break;
+ case VK_IMAGE_ASPECT_PLANE_0_BIT_KHR: suffix = "c0"; break;
+ case VK_IMAGE_ASPECT_PLANE_1_BIT_KHR: suffix = "c1"; break;
+ case VK_IMAGE_ASPECT_PLANE_2_BIT_KHR: suffix = "c2"; break;
default:
unreachable("Invalid aspect");
}
- char *filename = ralloc_asprintf(dump_ctx, "framebuffer%04d-%d%c.ppm",
+ char *filename = ralloc_asprintf(dump_ctx, "framebuffer%04d-%d%s.ppm",
dump_idx, i, suffix);
+ unsigned plane = anv_image_aspect_to_plane(iview->image->aspects, aspect);
dump_add_image(cmd_buffer, (struct anv_image *)iview->image, aspect,
- iview->isl.base_level, iview->isl.base_array_layer,
+ iview->planes[plane].isl.base_level,
+ iview->planes[plane].isl.base_array_layer,
filename);
}
}
diff --git a/src/intel/vulkan/anv_formats.c b/src/intel/vulkan/anv_formats.c
index d828294c5e8..a8e9298a058 100644
--- a/src/intel/vulkan/anv_formats.c
+++ b/src/intel/vulkan/anv_formats.c
@@ -419,8 +419,7 @@ anv_get_plane_format(const struct gen_device_info *devinfo, VkFormat vk_format,
return plane_format;
}
- assert(aspect == VK_IMAGE_ASPECT_COLOR_BIT);
- assert(vk_format_aspects(vk_format) == VK_IMAGE_ASPECT_COLOR_BIT);
+ assert((aspect & ~VK_IMAGE_ASPECT_ANY_COLOR_BIT) == 0);
const struct isl_format_layout *isl_layout =
isl_format_get_layout(plane_format.isl_format);
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index 905d7d087cc..26cb7273eef 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -68,6 +68,9 @@ choose_isl_surf_usage(VkImageCreateFlags vk_create_flags,
isl_usage |= ISL_SURF_USAGE_STENCIL_BIT;
break;
case VK_IMAGE_ASPECT_COLOR_BIT:
+ case VK_IMAGE_ASPECT_PLANE_0_BIT_KHR:
+ case VK_IMAGE_ASPECT_PLANE_1_BIT_KHR:
+ case VK_IMAGE_ASPECT_PLANE_2_BIT_KHR:
break;
default:
unreachable("bad VkImageAspect");
@@ -95,26 +98,31 @@ choose_isl_surf_usage(VkImageCreateFlags vk_create_flags,
static struct anv_surface *
get_surface(struct anv_image *image, VkImageAspectFlags aspect)
{
- switch (aspect) {
- default:
- unreachable("bad VkImageAspect");
- case VK_IMAGE_ASPECT_COLOR_BIT:
- return &image->color_surface;
- case VK_IMAGE_ASPECT_DEPTH_BIT:
- return &image->depth_surface;
- case VK_IMAGE_ASPECT_STENCIL_BIT:
- return &image->stencil_surface;
- }
+ uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);
+ return &image->planes[plane].surface;
}
static void
-add_surface(struct anv_image *image, struct anv_surface *surf)
+add_surface(struct anv_image *image, struct anv_surface *surf, uint32_t plane)
{
assert(surf->isl.size > 0); /* isl surface must be initialized */
- surf->offset = align_u32(image->size, surf->isl.alignment);
+ if (image->disjoint) {
+ surf->offset = align_u32(image->planes[plane].size, surf->isl.alignment);
+ /* Plane offset is always 0 when it's disjoint. */
+ } else {
+ surf->offset = align_u32(image->size, surf->isl.alignment);
+ /* Determine plane's offset only once when the first surface is added. */
+ if (image->planes[plane].size == 0)
+ image->planes[plane].offset = image->size;
+ }
+
image->size = surf->offset + surf->isl.size;
+ image->planes[plane].size = (surf->offset + surf->isl.size) - image->planes[plane].offset;
+
image->alignment = MAX2(image->alignment, surf->isl.alignment);
+ image->planes[plane].alignment = MAX2(image->planes[plane].alignment,
+ surf->isl.alignment);
}
/**
@@ -161,11 +169,12 @@ add_surface(struct anv_image *image, struct anv_surface *surf)
*/
static void
add_fast_clear_state_buffer(struct anv_image *image,
+ uint32_t plane,
const struct anv_device *device)
{
assert(image && device);
- assert(image->aux_surface.isl.size > 0 &&
- image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
+ assert(image->planes[plane].aux_surface.isl.size > 0 &&
+ image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT);
/* The offset to the buffer of clear values must be dword-aligned for GPU
* memcpy operations. It is located immediately after the auxiliary surface.
@@ -179,18 +188,31 @@ add_fast_clear_state_buffer(struct anv_image *image,
/* Auxiliary buffers should be a multiple of 4K, so the start of the clear
* values buffer should already be dword-aligned.
*/
- assert(image->aux_surface.isl.size % 4 == 0);
+ assert((image->planes[plane].offset + image->planes[plane].size) % 4 == 0);
- /* This buffer should be at the very end of the image. */
- assert(image->size ==
- image->aux_surface.offset + image->aux_surface.isl.size);
+ /* This buffer should be at the very end of the plane. */
+ if (image->disjoint) {
+ assert(image->planes[plane].size ==
+ (image->planes[plane].offset + image->planes[plane].size));
+ } else {
+ assert(image->size ==
+ (image->planes[plane].offset + image->planes[plane].size));
+ }
const unsigned entry_size = anv_fast_clear_state_entry_size(device);
/* There's no padding between entries, so ensure that they're always a
* multiple of 32 bits in order to enable GPU memcpy operations.
*/
assert(entry_size % 4 == 0);
- image->size += entry_size * anv_image_aux_levels(image);
+
+ const unsigned plane_state_size =
+ entry_size * anv_image_aux_levels(image, plane);
+
+ image->planes[plane].fast_clear_state_offset =
+ image->planes[plane].offset + image->planes[plane].size;
+
+ image->planes[plane].size += plane_state_size;
+ image->size += plane_state_size;
}
/**
@@ -226,21 +248,19 @@ make_surface(const struct anv_device *dev,
assert(tiling_flags);
- struct anv_surface *anv_surf = get_surface(image, aspect);
-
image->extent = anv_sanitize_image_extent(vk_info->imageType,
vk_info->extent);
- enum isl_format format =
- anv_get_isl_plane_format(&dev->info, vk_info->format,
- aspect, vk_info->tiling);
- assert(format != ISL_FORMAT_UNSUPPORTED);
+ const unsigned plane = anv_image_aspect_to_plane(image->aspects, aspect);
+ const struct anv_format_plane plane_format =
+ anv_get_plane_format(&dev->info, image->vk_format, aspect, image->tiling);
+ struct anv_surface *anv_surf = &image->planes[plane].surface;
ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl,
.dim = vk_to_isl_surf_dim[vk_info->imageType],
- .format = format,
- .width = image->extent.width,
- .height = image->extent.height,
+ .format = plane_format.isl_format,
+ .width = image->extent.width / plane_format.denominator_scales[0],
+ .height = image->extent.height / plane_format.denominator_scales[1],
.depth = image->extent.depth,
.levels = vk_info->mipLevels,
.array_len = vk_info->arrayLayers,
@@ -255,7 +275,18 @@ make_surface(const struct anv_device *dev,
*/
assert(ok);
- add_surface(image, anv_surf);
+ image->planes[plane].aux_usage = ISL_AUX_USAGE_NONE;
+
+ if (!image->disjoint) {
+ /* With non disjoint planes, align the plane to its surface alignment.
+ */
+ uint32_t previous_plane_size = plane == 0 ? 0 :
+ (image->planes[plane - 1].offset + image->planes[plane - 1].size);
+ image->planes[plane].offset = align_u32(previous_plane_size,
+ anv_surf->isl.alignment);
+ }
+
+ add_surface(image, anv_surf, plane);
/* Add a HiZ surface to a depth buffer that will be used for rendering.
*/
@@ -280,24 +311,43 @@ make_surface(const struct anv_device *dev,
} else if (dev->info.gen == 8 && vk_info->samples > 1) {
anv_perf_warn(dev->instance, image, "Enable gen8 multisampled HiZ");
} else if (!unlikely(INTEL_DEBUG & DEBUG_NO_HIZ)) {
- assert(image->aux_surface.isl.size == 0);
- ok = isl_surf_get_hiz_surf(&dev->isl_dev, &image->depth_surface.isl,
- &image->aux_surface.isl);
+ assert(image->planes[plane].aux_surface.isl.size == 0);
+ ok = isl_surf_get_hiz_surf(&dev->isl_dev,
+ &image->planes[plane].surface.isl,
+ &image->planes[plane].aux_surface.isl);
assert(ok);
- add_surface(image, &image->aux_surface);
- image->aux_usage = ISL_AUX_USAGE_HIZ;
+ add_surface(image, &image->planes[plane].aux_surface, plane);
+ image->planes[plane].aux_usage = ISL_AUX_USAGE_HIZ;
}
- } else if (aspect == VK_IMAGE_ASPECT_COLOR_BIT && vk_info->samples == 1) {
- if (!unlikely(INTEL_DEBUG & DEBUG_NO_RBC)) {
- assert(image->aux_surface.isl.size == 0);
- ok = isl_surf_get_ccs_surf(&dev->isl_dev, &anv_surf->isl,
- &image->aux_surface.isl, 0);
+ } else if ((aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT) && vk_info->samples == 1) {
+ /* TODO: Allow compression on :
+ *
+ * 1) non multiplanar images (We appear to hit a sampler bug with CCS &
+ * R16G16 format. Putting the clear state a page (4096 bytes)
+ * further fixes the issue.
+ *
+ * 2) alias images, because they might be aliases of images described
+ * in 1)
+ *
+ * 3) if compression is disabled by debug
+ */
+ const bool allow_compression =
+ image->n_planes == 1 &&
+ (vk_info->flags & VK_IMAGE_CREATE_ALIAS_BIT_KHR) == 0 &&
+ likely((INTEL_DEBUG & DEBUG_NO_RBC) == 0);
+
+ if (allow_compression) {
+ assert(image->planes[plane].aux_surface.isl.size == 0);
+ ok = isl_surf_get_ccs_surf(&dev->isl_dev,
+ &image->planes[plane].surface.isl,
+ &image->planes[plane].aux_surface.isl, 0);
if (ok) {
/* Disable CCS when it is not useful (i.e., when you can't render
* to the image with CCS enabled).
*/
- if (!isl_format_supports_rendering(&dev->info, format)) {
+ if (!isl_format_supports_rendering(&dev->info,
+ plane_format.isl_format)) {
/* While it may be technically possible to enable CCS for this
* image, we currently don't have things hooked up to get it
* working.
@@ -305,12 +355,12 @@ make_surface(const struct anv_device *dev,
anv_perf_warn(dev->instance, image,
"This image format doesn't support rendering. "
"Not allocating an CCS buffer.");
- image->aux_surface.isl.size = 0;
+ image->planes[plane].aux_surface.isl.size = 0;
return VK_SUCCESS;
}
- add_surface(image, &image->aux_surface);
- add_fast_clear_state_buffer(image, dev);
+ add_surface(image, &image->planes[plane].aux_surface, plane);
+ add_fast_clear_state_buffer(image, plane, dev);
/* For images created without MUTABLE_FORMAT_BIT set, we know that
* they will always be used with the original format. In
@@ -322,26 +372,58 @@ make_surface(const struct anv_device *dev,
*/
if (!(vk_info->usage & VK_IMAGE_USAGE_STORAGE_BIT) &&
!(vk_info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) &&
- isl_format_supports_ccs_e(&dev->info, format)) {
- image->aux_usage = ISL_AUX_USAGE_CCS_E;
+ isl_format_supports_ccs_e(&dev->info, plane_format.isl_format)) {
+ image->planes[plane].aux_usage = ISL_AUX_USAGE_CCS_E;
}
}
}
- } else if (aspect == VK_IMAGE_ASPECT_COLOR_BIT && vk_info->samples > 1) {
- assert(image->aux_surface.isl.size == 0);
+ } else if ((aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT) && vk_info->samples > 1) {
assert(!(vk_info->usage & VK_IMAGE_USAGE_STORAGE_BIT));
- ok = isl_surf_get_mcs_surf(&dev->isl_dev, &anv_surf->isl,
- &image->aux_surface.isl);
+ assert(image->planes[plane].aux_surface.isl.size == 0);
+ ok = isl_surf_get_mcs_surf(&dev->isl_dev,
+ &image->planes[plane].surface.isl,
+ &image->planes[plane].aux_surface.isl);
if (ok) {
- add_surface(image, &image->aux_surface);
- add_fast_clear_state_buffer(image, dev);
- image->aux_usage = ISL_AUX_USAGE_MCS;
+ add_surface(image, &image->planes[plane].aux_surface, plane);
+ add_fast_clear_state_buffer(image, plane, dev);
+ image->planes[plane].aux_usage = ISL_AUX_USAGE_MCS;
}
}
+ assert((image->planes[plane].offset + image->planes[plane].size) == image->size);
+
+ /* Upper bound of the last surface should be smaller than the plane's
+ * size.
+ */
+ assert((MAX2(image->planes[plane].surface.offset,
+ image->planes[plane].aux_surface.offset) +
+ (image->planes[plane].aux_surface.isl.size > 0 ?
+ image->planes[plane].aux_surface.isl.size :
+ image->planes[plane].surface.isl.size)) <=
+ (image->planes[plane].offset + image->planes[plane].size));
+
+ if (image->planes[plane].aux_surface.isl.size) {
+ /* assert(image->planes[plane].fast_clear_state_offset == */
+ /* (image->planes[plane].aux_surface.offset + image->planes[plane].aux_surface.isl.size)); */
+ assert(image->planes[plane].fast_clear_state_offset <
+ (image->planes[plane].offset + image->planes[plane].size));
+ }
+
return VK_SUCCESS;
}
+static uint32_t
+get_surface_offset(struct anv_surface *surf)
+{
+ return surf->bo_offset + surf->offset;
+}
+
+static uint32_t
+get_surface_range(struct anv_surface *surf)
+{
+ return surf->bo->size - get_surface_offset(surf);
+}
+
VkResult
anv_image_create(VkDevice _device,
const struct anv_image_create_info *create_info,
@@ -370,13 +452,18 @@ anv_image_create(VkDevice _device,
image->type = pCreateInfo->imageType;
image->extent = pCreateInfo->extent;
image->vk_format = pCreateInfo->format;
+ image->format = anv_get_format(pCreateInfo->format);
image->aspects = vk_format_aspects(image->vk_format);
image->levels = pCreateInfo->mipLevels;
image->array_size = pCreateInfo->arrayLayers;
image->samples = pCreateInfo->samples;
image->usage = pCreateInfo->usage;
image->tiling = pCreateInfo->tiling;
- image->aux_usage = ISL_AUX_USAGE_NONE;
+
+ const struct anv_format *format = anv_get_format(image->vk_format);
+ assert(format != NULL);
+
+ image->n_planes = format->n_planes;
uint32_t b;
for_each_bit(b, image->aspects) {
@@ -423,24 +510,75 @@ anv_DestroyImage(VkDevice _device, VkImage _image,
vk_free2(&device->alloc, pAllocator, image);
}
+static VkResult anv_image_bind_memory_plane(struct anv_device *device,
+ struct anv_image *image,
+ uint32_t plane,
+ struct anv_device_memory *memory,
+ uint32_t memory_offset)
+{
+ struct anv_surface *anv_surf = &image->planes[plane].surface;
+
+ if (memory) {
+ anv_surf->bo = memory->bo;
+ anv_surf->bo_offset = memory_offset;
+ } else {
+ anv_surf->bo = NULL;
+ anv_surf->bo_offset = 0;
+ }
+
+ if (image->planes[plane].aux_surface.isl.size > 0) {
+ struct anv_surface *anv_aux_surf = &image->planes[plane].aux_surface;
+ uint32_t aux_offset = anv_surf->bo_offset + anv_aux_surf->offset;
+
+ /* The offset and size must be a multiple of 4K or else the anv_gem_mmap
+ * call below will return NULL.
+ */
+ assert(aux_offset % 4096 == 0);
+ assert(anv_aux_surf->isl.size % 4096 == 0);
+
+ /* Auxiliary surfaces need to have their memory cleared to 0 before they
+ * can be used. For CCS surfaces, this puts them in the "resolved" state
+ * so they can be used with CCS enabled before we ever touch it from the
+ * GPU. For HiZ, we need something valid or else we may get GPU hangs on
+ * some hardware and 0 works fine.
+ */
+ void *map = anv_gem_mmap(device, anv_surf->bo->gem_handle,
+ aux_offset, anv_aux_surf->isl.size,
+ device->info.has_llc ? 0 : I915_MMAP_WC);
+
+ /* If anv_gem_mmap returns NULL, it's likely that the kernel was not
+ * able to find space on the host to create a proper mapping.
+ */
+ if (map == NULL)
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+
+ memset(map, 0, anv_aux_surf->isl.size);
+
+ anv_gem_munmap(map, anv_aux_surf->isl.size);
+ }
+
+ return VK_SUCCESS;
+}
+
VkResult anv_BindImageMemory(
VkDevice _device,
VkImage _image,
VkDeviceMemory _memory,
VkDeviceSize memoryOffset)
{
+ ANV_FROM_HANDLE(anv_device, device, _device);
ANV_FROM_HANDLE(anv_device_memory, mem, _memory);
ANV_FROM_HANDLE(anv_image, image, _image);
- if (mem == NULL) {
- image->bo = NULL;
- image->offset = 0;
- return VK_SUCCESS;
+ uint32_t plane, aspect_bit;
+ anv_foreach_plane_aspect_bit(plane, aspect_bit,
+ image->aspects, image->aspects) {
+ VkResult result = anv_image_bind_memory_plane(device, image, plane,
+ mem, memoryOffset);
+ if (result != VK_SUCCESS)
+ return vk_error(result);
}
- image->bo = mem->bo;
- image->offset = memoryOffset;
-
return VK_SUCCESS;
}
@@ -467,10 +605,6 @@ VkResult anv_BindImageMemory2KHR(
}
}
}
-
- /* Stop at the first error. */
- if (result != VK_SUCCESS)
- break;
}
return result;
@@ -505,22 +639,10 @@ void anv_GetImageSubresourceLayout(
assert(__builtin_popcount(pSubresource->aspectMask) == 1);
- switch (pSubresource->aspectMask) {
- case VK_IMAGE_ASPECT_COLOR_BIT:
- anv_surface_get_subresource_layout(image, &image->color_surface,
- pSubresource, pLayout);
- break;
- case VK_IMAGE_ASPECT_DEPTH_BIT:
- anv_surface_get_subresource_layout(image, &image->depth_surface,
- pSubresource, pLayout);
- break;
- case VK_IMAGE_ASPECT_STENCIL_BIT:
- anv_surface_get_subresource_layout(image, &image->stencil_surface,
- pSubresource, pLayout);
- break;
- default:
- assert(!"Invalid image aspect");
- }
+ anv_surface_get_subresource_layout(image,
+ get_surface(image,
+ pSubresource->aspectMask),
+ pSubresource, pLayout);
}
/**
@@ -531,7 +653,7 @@ void anv_GetImageSubresourceLayout(
*
* @param devinfo The device information of the Intel GPU.
* @param image The image that may contain a collection of buffers.
- * @param aspects The aspect(s) of the image to be accessed.
+ * @param plane The plane of the image to be accessed.
* @param layout The current layout of the image aspect(s).
*
* @return The primary buffer that should be used for the given layout.
@@ -539,7 +661,7 @@ void anv_GetImageSubresourceLayout(
enum isl_aux_usage
anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
const struct anv_image * const image,
- const VkImageAspectFlags aspects,
+ const uint32_t plane,
const VkImageLayout layout)
{
/* Validate the inputs. */
@@ -550,35 +672,41 @@ anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
/* The layout of a NULL image is not properly defined. */
assert(image != NULL);
- /* The aspects must be a subset of the image aspects. */
- assert(aspects & image->aspects && aspects <= image->aspects);
-
/* Determine the optimal buffer. */
- /* If there is no auxiliary surface allocated, we must use the one and only
- * main buffer.
+ /* Depth & stencil buffers share the same auxilliary buffer, we need to
+ * process them differently from color buffers.
*/
- if (image->aux_surface.isl.size == 0)
- return ISL_AUX_USAGE_NONE;
+ if (image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT) {
+ /* If there is no auxiliary surface allocated, we must use the one and
+ * only main buffer.
+ */
+ if (image->planes[plane].aux_surface.isl.size == 0)
+ return ISL_AUX_USAGE_NONE;
+ } else {
+ /* If there is no auxiliary surface allocated, we must use the one and
+ * only main buffer.
+ */
+ if (image->planes[plane].aux_surface.isl.size == 0)
+ return ISL_AUX_USAGE_NONE;
+
+ /* On BDW+, when clearing the stencil aspect of a depth stencil image,
+ * the HiZ buffer allows us to record the clear with a relatively small
+ * number of packets. Prior to BDW, the HiZ buffer provides no known
+ * benefit to the stencil aspect.
+ */
+ if (devinfo->gen < 8 && plane != 0 /* aka stencil */)
+ return ISL_AUX_USAGE_NONE;
+ }
/* All images that use an auxiliary surface are required to be tiled. */
assert(image->tiling == VK_IMAGE_TILING_OPTIMAL);
- /* On BDW+, when clearing the stencil aspect of a depth stencil image,
- * the HiZ buffer allows us to record the clear with a relatively small
- * number of packets. Prior to BDW, the HiZ buffer provides no known benefit
- * to the stencil aspect.
- */
- if (devinfo->gen < 8 && aspects == VK_IMAGE_ASPECT_STENCIL_BIT)
- return ISL_AUX_USAGE_NONE;
-
- const bool color_aspect = aspects == VK_IMAGE_ASPECT_COLOR_BIT;
-
/* The following switch currently only handles depth stencil aspects.
* TODO: Handle the color aspect.
*/
- if (color_aspect)
- return image->aux_usage;
+ if (image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT)
+ return image->planes[plane].aux_usage;
switch (layout) {
@@ -612,16 +740,16 @@ anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
/* Sampling Layouts */
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
- assert(!color_aspect);
+ assert((image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT) == 0);
/* Fall-through */
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
- if (anv_can_sample_with_hiz(devinfo, aspects, image->samples))
+ if (anv_can_sample_with_hiz(devinfo, image))
return ISL_AUX_USAGE_HIZ;
else
return ISL_AUX_USAGE_NONE;
case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
- assert(color_aspect);
+ assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT);
/* On SKL+, the render buffer can be decompressed by the presentation
* engine. Support for this feature has not yet landed in the wider
@@ -643,11 +771,11 @@ anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
/* Rendering Layouts */
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
- assert(color_aspect);
+ assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT);
unreachable("Color images are not yet supported.");
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
- assert(!color_aspect);
+ assert((image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT) == 0);
return ISL_AUX_USAGE_HIZ;
case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR:
@@ -686,6 +814,21 @@ remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component,
}
}
+static VkImageAspectFlags
+remap_aspect_flags(VkImageAspectFlags view_aspects)
+{
+ if (view_aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT) {
+ if (_mesa_bitcount(view_aspects) == 1)
+ return VK_IMAGE_ASPECT_COLOR_BIT;
+
+ VkImageAspectFlags color_aspects = 0;
+ for (uint32_t i = 0; i < _mesa_bitcount(view_aspects); i++)
+ color_aspects |= VK_IMAGE_ASPECT_PLANE_0_BIT_KHR << i;
+ return color_aspects;
+ }
+ /* No special remapping needed for depth & stencil aspects. */
+ return view_aspects;
+}
VkResult
anv_CreateImageView(VkDevice _device,
@@ -725,156 +868,190 @@ anv_CreateImageView(VkDevice _device,
break;
}
- const struct anv_surface *surface =
- anv_image_get_surface_for_aspect_mask(image, range->aspectMask);
+ /* First expand aspects to the image's ones (for example
+ * VK_IMAGE_ASPECT_COLOR_BIT will be converted to
+ * VK_IMAGE_ASPECT_PLANE_0_BIT_KHR | VK_IMAGE_ASPECT_PLANE_1_BIT_KHR |
+ * VK_IMAGE_ASPECT_PLANE_2_BIT_KHR for an image of format
+ * VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR.
+ */
+ VkImageAspectFlags expanded_aspects =
+ anv_image_color_aspects(image, range->aspectMask);
iview->image = image;
- iview->bo = image->bo;
- iview->offset = image->offset + surface->offset;
- iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
+ /* Remap the expanded aspects for the image view. For example if only
+ * VK_IMAGE_ASPECT_PLANE_1_BIT_KHR was given in range->aspectMask, we will
+ * convert it to VK_IMAGE_ASPECT_COLOR_BIT since from the point of view of
+ * the image view, it only has a single plane.
+ */
+ iview->aspect_mask = remap_aspect_flags(expanded_aspects);
+ iview->n_planes = anv_image_aspect_get_planes(iview->aspect_mask);
iview->vk_format = pCreateInfo->format;
- struct anv_format_plane format =
- anv_get_plane_format(&device->info, pCreateInfo->format,
- range->aspectMask, image->tiling);
-
- iview->isl = (struct isl_view) {
- .format = format.isl_format,
- .base_level = range->baseMipLevel,
- .levels = anv_get_levelCount(image, range),
- .base_array_layer = range->baseArrayLayer,
- .array_len = anv_get_layerCount(image, range),
- .swizzle = {
- .r = remap_swizzle(pCreateInfo->components.r,
- VK_COMPONENT_SWIZZLE_R, format.swizzle),
- .g = remap_swizzle(pCreateInfo->components.g,
- VK_COMPONENT_SWIZZLE_G, format.swizzle),
- .b = remap_swizzle(pCreateInfo->components.b,
- VK_COMPONENT_SWIZZLE_B, format.swizzle),
- .a = remap_swizzle(pCreateInfo->components.a,
- VK_COMPONENT_SWIZZLE_A, format.swizzle),
- },
- };
-
iview->extent = (VkExtent3D) {
.width = anv_minify(image->extent.width , range->baseMipLevel),
.height = anv_minify(image->extent.height, range->baseMipLevel),
.depth = anv_minify(image->extent.depth , range->baseMipLevel),
};
- if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_3D) {
- iview->isl.base_array_layer = 0;
- iview->isl.array_len = iview->extent.depth;
- }
-
- if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
- pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {
- iview->isl.usage = ISL_SURF_USAGE_CUBE_BIT;
- } else {
- iview->isl.usage = 0;
- }
-
- /* Input attachment surfaces for color are allocated and filled
- * out at BeginRenderPass time because they need compression information.
- * Compression is not yet enabled for depth textures and stencil doesn't
- * allow compression so we can just use the texture surface state from the
- * view.
+ /* Now go through the underlying image selected planes (computed in
+ * expanded_aspects) and map them to planes in the image view.
*/
- if (image->usage & VK_IMAGE_USAGE_SAMPLED_BIT ||
- (image->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT &&
- !(iview->aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT))) {
- iview->optimal_sampler_surface_state = alloc_surface_state(device);
- iview->general_sampler_surface_state = alloc_surface_state(device);
-
- iview->general_sampler_aux_usage =
- anv_layout_to_aux_usage(&device->info, image, iview->aspect_mask,
- VK_IMAGE_LAYOUT_GENERAL);
- iview->optimal_sampler_aux_usage =
- anv_layout_to_aux_usage(&device->info, image, iview->aspect_mask,
- VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
-
- /* If this is a HiZ buffer we can sample from with a programmable clear
- * value (SKL+), define the clear value to the optimal constant.
- */
- union isl_color_value clear_color = { .u32 = { 0, } };
- if ((iview->aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) &&
- device->info.gen >= 9)
- clear_color.f32[0] = ANV_HZ_FC_VAL;
-
- struct isl_view view = iview->isl;
- view.usage |= ISL_SURF_USAGE_TEXTURE_BIT;
-
- isl_surf_fill_state(&device->isl_dev,
- iview->optimal_sampler_surface_state.map,
- .surf = &surface->isl,
- .view = &view,
- .clear_color = clear_color,
- .aux_surf = &image->aux_surface.isl,
- .aux_usage = iview->optimal_sampler_aux_usage,
- .mocs = device->default_mocs);
-
- isl_surf_fill_state(&device->isl_dev,
- iview->general_sampler_surface_state.map,
- .surf = &surface->isl,
- .view = &view,
- .clear_color = clear_color,
- .aux_surf = &image->aux_surface.isl,
- .aux_usage = iview->general_sampler_aux_usage,
- .mocs = device->default_mocs);
-
- anv_state_flush(device, iview->optimal_sampler_surface_state);
- anv_state_flush(device, iview->general_sampler_surface_state);
- }
-
- /* NOTE: This one needs to go last since it may stomp isl_view.format */
- if (image->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
- iview->storage_surface_state = alloc_surface_state(device);
- iview->writeonly_storage_surface_state = alloc_surface_state(device);
+ uint32_t iaspect_bit, vplane = 0, iplane;
+ anv_foreach_plane_aspect_bit(iplane, iaspect_bit,
+ expanded_aspects, image->aspects) {
+ VkImageAspectFlags vplane_aspect =
+ anv_plane_to_aspect(iview->aspect_mask, vplane);
+
+ iview->planes[vplane].surface = &image->planes[iplane].surface;
+ iview->planes[vplane].aux_surface = &image->planes[iplane].aux_surface;
+ iview->planes[vplane].aux_usage = image->planes[iplane].aux_usage;
+
+ struct anv_format_plane format =
+ anv_get_plane_format(&device->info, iview->vk_format,
+ vplane_aspect, image->tiling);
+
+ iview->planes[vplane].isl = (struct isl_view) {
+ .format = format.isl_format,
+ .base_level = range->baseMipLevel,
+ .levels = anv_get_levelCount(image, range),
+ .base_array_layer = range->baseArrayLayer,
+ .array_len = anv_get_layerCount(image, range),
+ .swizzle = {
+ .r = remap_swizzle(pCreateInfo->components.r,
+ VK_COMPONENT_SWIZZLE_R, format.swizzle),
+ .g = remap_swizzle(pCreateInfo->components.g,
+ VK_COMPONENT_SWIZZLE_G, format.swizzle),
+ .b = remap_swizzle(pCreateInfo->components.b,
+ VK_COMPONENT_SWIZZLE_B, format.swizzle),
+ .a = remap_swizzle(pCreateInfo->components.a,
+ VK_COMPONENT_SWIZZLE_A, format.swizzle),
+ },
+ };
+
+ if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_3D) {
+ iview->planes[vplane].isl.base_array_layer = 0;
+ iview->planes[vplane].isl.array_len = iview->extent.depth;
+ }
- struct isl_view view = iview->isl;
- view.usage |= ISL_SURF_USAGE_STORAGE_BIT;
+ if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
+ pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {
+ iview->planes[vplane].isl.usage = ISL_SURF_USAGE_CUBE_BIT;
+ } else {
+ iview->planes[vplane].isl.usage = 0;
+ }
- /* Write-only accesses always used a typed write instruction and should
- * therefore use the real format.
+ /* Input attachment surfaces for color are allocated and filled
+ * out at BeginRenderPass time because they need compression information.
+ * Compression is not yet enabled for depth textures and stencil doesn't
+ * allow compression so we can just use the texture surface state from the
+ * view.
*/
- isl_surf_fill_state(&device->isl_dev,
- iview->writeonly_storage_surface_state.map,
- .surf = &surface->isl,
- .view = &view,
- .aux_surf = &image->aux_surface.isl,
- .aux_usage = image->aux_usage,
- .mocs = device->default_mocs);
-
- if (isl_has_matching_typed_storage_image_format(&device->info,
- format.isl_format)) {
- /* Typed surface reads support a very limited subset of the shader
- * image formats. Translate it into the closest format the hardware
- * supports.
+ if (image->usage & VK_IMAGE_USAGE_SAMPLED_BIT ||
+ (image->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT &&
+ !(iview->aspect_mask & VK_IMAGE_ASPECT_ANY_COLOR_BIT))) {
+ iview->planes[vplane].optimal_sampler_surface_state =
+ alloc_surface_state(device);
+ iview->planes[vplane].general_sampler_surface_state =
+ alloc_surface_state(device);
+
+ iview->planes[vplane].general_sampler_aux_usage =
+ anv_layout_to_aux_usage(&device->info, image, iplane,
+ VK_IMAGE_LAYOUT_GENERAL);
+ iview->planes[vplane].optimal_sampler_aux_usage =
+ anv_layout_to_aux_usage(&device->info, image, iplane,
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
+
+ /* If this is a HiZ buffer we can sample from with a programmable clear
+ * value (SKL+), define the clear value to the optimal constant.
*/
- view.format = isl_lower_storage_image_format(&device->info,
- format.isl_format);
+ union isl_color_value clear_color = { .u32 = { 0, } };
+ if ((iview->aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) &&
+ device->info.gen >= 9)
+ clear_color.f32[0] = ANV_HZ_FC_VAL;
+
+ struct isl_view view = iview->planes[vplane].isl;
+ view.usage |= ISL_SURF_USAGE_TEXTURE_BIT;
isl_surf_fill_state(&device->isl_dev,
- iview->storage_surface_state.map,
- .surf = &surface->isl,
+ iview->planes[vplane].optimal_sampler_surface_state.map,
+ .surf = &image->planes[iplane].surface.isl,
.view = &view,
- .aux_surf = &image->aux_surface.isl,
- .aux_usage = image->aux_usage,
+ .clear_color = clear_color,
+ .aux_surf = &image->planes[iplane].aux_surface.isl,
+ .aux_usage = iview->planes[vplane].optimal_sampler_aux_usage,
.mocs = device->default_mocs);
- } else {
- anv_fill_buffer_surface_state(device, iview->storage_surface_state,
- ISL_FORMAT_RAW,
- iview->offset,
- iview->bo->size - iview->offset, 1);
+
+ isl_surf_fill_state(&device->isl_dev,
+ iview->planes[vplane].general_sampler_surface_state.map,
+ .surf = &image->planes[iplane].surface.isl,
+ .view = &view,
+ .clear_color = clear_color,
+ .aux_surf = &image->planes[iplane].aux_surface.isl,
+ .aux_usage = iview->planes[vplane].general_sampler_aux_usage,
+ .mocs = device->default_mocs);
+
+ anv_state_flush(device, iview->planes[vplane].optimal_sampler_surface_state);
+ anv_state_flush(device, iview->planes[vplane].general_sampler_surface_state);
}
- isl_surf_fill_image_param(&device->isl_dev,
- &iview->storage_image_param,
- &surface->isl, &iview->isl);
+ /* NOTE: This one needs to go last since it may stomp isl_view.format */
+ if (image->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
+ iview->planes[vplane].storage_surface_state =
+ alloc_surface_state(device);
+ iview->planes[vplane].writeonly_storage_surface_state =
+ alloc_surface_state(device);
+
+ struct isl_view view = iview->planes[vplane].isl;
+ view.usage |= ISL_SURF_USAGE_STORAGE_BIT;
+
+ /* Write-only accesses always used a typed write instruction and should
+ * therefore use the real format.
+ */
+ isl_surf_fill_state(&device->isl_dev,
+ iview->planes[vplane].writeonly_storage_surface_state.map,
+ .surf = &image->planes[iplane].surface.isl,
+ .view = &view,
+ .aux_surf = &image->planes[iplane].aux_surface.isl,
+ .aux_usage = image->planes[iplane].aux_usage,
+ .mocs = device->default_mocs);
+
+ enum isl_format isl_format = format.isl_format;
+
+ if (isl_has_matching_typed_storage_image_format(&device->info,
+ isl_format)) {
+ /* Typed surface reads support a very limited subset of the shader
+ * image formats. Translate it into the closest format the hardware
+ * supports.
+ */
+ view.format = isl_lower_storage_image_format(&device->info,
+ isl_format);
+
+ isl_surf_fill_state(&device->isl_dev,
+ iview->planes[vplane].storage_surface_state.map,
+ .surf = &image->planes[iplane].surface.isl,
+ .view = &view,
+ .aux_surf = &image->planes[iplane].aux_surface.isl,
+ .aux_usage = image->planes[iplane].aux_usage,
+ .mocs = device->default_mocs);
+ } else {
+ anv_fill_buffer_surface_state(device,
+ iview->planes[vplane].storage_surface_state,
+ ISL_FORMAT_RAW,
+ get_surface_offset(iview->planes[vplane].surface),
+ get_surface_range(iview->planes[vplane].surface), 1);
+ }
+
+ isl_surf_fill_image_param(&device->isl_dev,
+ &iview->planes[vplane].storage_image_param,
+ &image->planes[iplane].surface.isl,
+ &iview->planes[vplane].isl);
+
+ anv_state_flush(device, iview->planes[vplane].storage_surface_state);
+ anv_state_flush(device, iview->planes[vplane].writeonly_storage_surface_state);
+ }
- anv_state_flush(device, iview->storage_surface_state);
- anv_state_flush(device, iview->writeonly_storage_surface_state);
+ vplane++;
}
*pView = anv_image_view_to_handle(iview);
@@ -892,24 +1069,26 @@ anv_DestroyImageView(VkDevice _device, VkImageView _iview,
if (!iview)
return;
- if (iview->optimal_sampler_surface_state.alloc_size > 0) {
- anv_state_pool_free(&device->surface_state_pool,
- iview->optimal_sampler_surface_state);
- }
+ for (uint32_t plane = 0; plane < iview->n_planes; plane++) {
+ if (iview->planes[plane].optimal_sampler_surface_state.alloc_size > 0) {
+ anv_state_pool_free(&device->surface_state_pool,
+ iview->planes[plane].optimal_sampler_surface_state);
+ }
- if (iview->general_sampler_surface_state.alloc_size > 0) {
- anv_state_pool_free(&device->surface_state_pool,
- iview->general_sampler_surface_state);
- }
+ if (iview->planes[plane].general_sampler_surface_state.alloc_size > 0) {
+ anv_state_pool_free(&device->surface_state_pool,
+ iview->planes[plane].general_sampler_surface_state);
+ }
- if (iview->storage_surface_state.alloc_size > 0) {
- anv_state_pool_free(&device->surface_state_pool,
- iview->storage_surface_state);
- }
+ if (iview->planes[plane].storage_surface_state.alloc_size > 0) {
+ anv_state_pool_free(&device->surface_state_pool,
+ iview->planes[plane].storage_surface_state);
+ }
- if (iview->writeonly_storage_surface_state.alloc_size > 0) {
- anv_state_pool_free(&device->surface_state_pool,
- iview->writeonly_storage_surface_state);
+ if (iview->planes[plane].writeonly_storage_surface_state.alloc_size > 0) {
+ anv_state_pool_free(&device->surface_state_pool,
+ iview->planes[plane].writeonly_storage_surface_state);
+ }
}
vk_free2(&device->alloc, pAllocator, iview);
@@ -1017,16 +1196,21 @@ const struct anv_surface *
anv_image_get_surface_for_aspect_mask(const struct anv_image *image,
VkImageAspectFlags aspect_mask)
{
+ VkImageAspectFlags sanitized_mask;
+
switch (aspect_mask) {
case VK_IMAGE_ASPECT_COLOR_BIT:
assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
- return &image->color_surface;
+ sanitized_mask = VK_IMAGE_ASPECT_COLOR_BIT;
+ break;
case VK_IMAGE_ASPECT_DEPTH_BIT:
assert(image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT);
- return &image->depth_surface;
+ sanitized_mask = VK_IMAGE_ASPECT_DEPTH_BIT;
+ break;
case VK_IMAGE_ASPECT_STENCIL_BIT:
assert(image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT);
- return &image->stencil_surface;
+ sanitized_mask = VK_IMAGE_ASPECT_STENCIL_BIT;
+ break;
case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
/* FINISHME: The Vulkan spec (git a511ba2) requires support for
* combined depth stencil formats. Specifically, it states:
@@ -1040,13 +1224,29 @@ anv_image_get_surface_for_aspect_mask(const struct anv_image *image,
* stencil surfaces from the underlying surface.
*/
if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
- return &image->depth_surface;
+ sanitized_mask = VK_IMAGE_ASPECT_DEPTH_BIT;
} else {
assert(image->aspects == VK_IMAGE_ASPECT_STENCIL_BIT);
- return &image->stencil_surface;
+ sanitized_mask = VK_IMAGE_ASPECT_STENCIL_BIT;
}
- default:
+ break;
+ case VK_IMAGE_ASPECT_PLANE_0_BIT_KHR:
+ assert((image->aspects & ~VK_IMAGE_ASPECT_ANY_COLOR_BIT) == 0);
+ sanitized_mask = VK_IMAGE_ASPECT_PLANE_0_BIT_KHR;
+ break;
+ case VK_IMAGE_ASPECT_PLANE_1_BIT_KHR:
+ assert((image->aspects & ~VK_IMAGE_ASPECT_ANY_COLOR_BIT) == 0);
+ sanitized_mask = VK_IMAGE_ASPECT_PLANE_1_BIT_KHR;
+ break;
+ case VK_IMAGE_ASPECT_PLANE_2_BIT_KHR:
+ assert((image->aspects & ~VK_IMAGE_ASPECT_ANY_COLOR_BIT) == 0);
+ sanitized_mask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
+ break;
+ default:
unreachable("image does not have aspect");
return NULL;
}
+
+ uint32_t plane = anv_image_aspect_to_plane(image->aspects, sanitized_mask);
+ return &image->planes[plane].surface;
}
diff --git a/src/intel/vulkan/anv_intel.c b/src/intel/vulkan/anv_intel.c
index 991a93542d2..a8eea5e24d2 100644
--- a/src/intel/vulkan/anv_intel.c
+++ b/src/intel/vulkan/anv_intel.c
@@ -80,8 +80,8 @@ VkResult anv_CreateDmaBufImageINTEL(
pAllocator, &image_h);
image = anv_image_from_handle(image_h);
- image->bo = mem->bo;
- image->offset = 0;
+ image->planes[0].surface.bo = mem->bo;
+ image->planes[0].surface.offset = 0;
assert(image->extent.width > 0);
assert(image->extent.height > 0);
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 131b87d6d3b..19e4e1c0916 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -1564,6 +1564,16 @@ anv_pipe_invalidate_bits_for_access_flags(VkAccessFlags flags)
return pipe_bits;
}
+#define VK_IMAGE_ASPECT_ANY_COLOR_BIT ( \
+ VK_IMAGE_ASPECT_COLOR_BIT | \
+ VK_IMAGE_ASPECT_PLANE_0_BIT_KHR | \
+ VK_IMAGE_ASPECT_PLANE_1_BIT_KHR | \
+ VK_IMAGE_ASPECT_PLANE_2_BIT_KHR)
+#define VK_IMAGE_ASPECT_PLANES_BITS ( \
+ VK_IMAGE_ASPECT_PLANE_0_BIT_KHR | \
+ VK_IMAGE_ASPECT_PLANE_1_BIT_KHR | \
+ VK_IMAGE_ASPECT_PLANE_2_BIT_KHR)
+
struct anv_vertex_binding {
struct anv_buffer * buffer;
VkDeviceSize offset;
@@ -2217,10 +2227,48 @@ anv_image_aspect_to_plane(VkImageAspectFlags image_aspects,
case VK_IMAGE_ASPECT_PLANE_2_BIT_KHR:
return 2;
default:
+ /* Purposefully assert with depth/stencil aspects. */
unreachable("invalid image aspect");
}
}
+static inline uint32_t
+anv_image_aspect_get_planes(VkImageAspectFlags aspect_mask)
+{
+ uint32_t planes = 0;
+
+ if (aspect_mask & (VK_IMAGE_ASPECT_COLOR_BIT |
+ VK_IMAGE_ASPECT_DEPTH_BIT |
+ VK_IMAGE_ASPECT_STENCIL_BIT |
+ VK_IMAGE_ASPECT_PLANE_0_BIT_KHR))
+ planes++;
+ if (aspect_mask & VK_IMAGE_ASPECT_PLANE_1_BIT_KHR)
+ planes++;
+ if (aspect_mask & VK_IMAGE_ASPECT_PLANE_2_BIT_KHR)
+ planes++;
+
+ return planes;
+}
+
+static inline VkImageAspectFlags
+anv_plane_to_aspect(VkImageAspectFlags image_aspects,
+ uint32_t plane)
+{
+ if (image_aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT) {
+ //if (_mesa_bitcount(image_aspects) > 1)
+ return VK_IMAGE_ASPECT_PLANE_0_BIT_KHR << plane;
+ //return VK_IMAGE_ASPECT_COLOR_BIT;
+ }
+ if (image_aspects & VK_IMAGE_ASPECT_DEPTH_BIT)
+ return VK_IMAGE_ASPECT_DEPTH_BIT << plane;
+ assert(image_aspects == VK_IMAGE_ASPECT_STENCIL_BIT);
+ return VK_IMAGE_ASPECT_STENCIL_BIT;
+}
+
+#define anv_foreach_plane_aspect_bit(p, b, aspects, image_aspects) \
+ for_each_bit(b, aspects) \
+ for (p = anv_image_aspect_to_plane(image_aspects, 1 << b); p != ~0; p = ~0)
+
const struct anv_format *
anv_get_format(VkFormat format);
@@ -2273,6 +2321,10 @@ struct anv_surface {
* Offset from VkImage's base address, as bound by vkBindImageMemory().
*/
uint32_t offset;
+
+ /* Set when bound */
+ struct anv_bo *bo;
+ VkDeviceSize bo_offset;
};
struct anv_image {
@@ -2281,65 +2333,95 @@ struct anv_image {
* of the actual surface formats.
*/
VkFormat vk_format;
+ const struct anv_format *format;
+
VkImageAspectFlags aspects;
VkExtent3D extent;
uint32_t levels;
uint32_t array_size;
uint32_t samples; /**< VkImageCreateInfo::samples */
+ uint32_t n_planes;
VkImageUsageFlags usage; /**< Superset of VkImageCreateInfo::usage. */
VkImageTiling tiling; /** VkImageCreateInfo::tiling */
VkDeviceSize size;
uint32_t alignment;
- /* Set when bound */
- struct anv_bo *bo;
- VkDeviceSize offset;
+ bool disjoint;
/**
* Image subsurfaces
*
- * For each foo, anv_image::foo_surface is valid if and only if
- * anv_image::aspects has a foo aspect.
+ * For each foo, anv_image::planes[x].surface is valid if and only if
+ * anv_image::aspects has a x aspect. Refer to anv_image_aspect_to_plane()
+ * to figure the number associated with a given aspect.
*
* The hardware requires that the depth buffer and stencil buffer be
* separate surfaces. From Vulkan's perspective, though, depth and stencil
* reside in the same VkImage. To satisfy both the hardware and Vulkan, we
* allocate the depth and stencil buffers as separate surfaces in the same
* bo.
+ *
+ * Memory layout :
+ *
+ * -----------------------
+ * | surface0 | /|\
+ * ----------------------- |
+ * | aux surface0 | | Plane 0
+ * ----------------------- |
+ * | fast clear colors0 | \|/
+ * -----------------------
+ * | surface1 | /|\
+ * ----------------------- |
+ * | aux surface1 | | Plane 1
+ * ----------------------- |
+ * | fast clear colors1 | \|/
+ * -----------------------
+ * | ... |
+ * | |
+ * -----------------------
*/
- union {
- struct anv_surface color_surface;
+ struct {
+ uint32_t offset;
- struct {
- struct anv_surface depth_surface;
- struct anv_surface stencil_surface;
- };
- };
+ VkDeviceSize size;
+ uint32_t alignment;
- /**
- * For color images, this is the aux usage for this image when not used as a
- * color attachment.
- *
- * For depth/stencil images, this is set to ISL_AUX_USAGE_HIZ if the image
- * has a HiZ buffer.
- */
- enum isl_aux_usage aux_usage;
+ /**
+ * Offset of the fast clear state (used to compute the
+ * fast_clear_state_offset of the following planes).
+ */
+ uint32_t fast_clear_state_offset;
- struct anv_surface aux_surface;
+ struct anv_surface surface;
+
+ /**
+ * For color images, this is the aux usage for this image when not used as a
+ * color attachment.
+ *
+ * For depth/stencil images, this is set to ISL_AUX_USAGE_HIZ if the
+ * image has a HiZ buffer (note that stencil surfaces this will always
+ * be NONE and the depth surface will have its aux_usage set
+ * appropriately as they share the same buffer).
+ */
+ enum isl_aux_usage aux_usage;
+ struct anv_surface aux_surface;
+ } planes[3];
};
/* Returns the number of auxiliary buffer levels attached to an image. */
static inline uint8_t
-anv_image_aux_levels(const struct anv_image * const image)
+anv_image_aux_levels(const struct anv_image * const image, uint8_t plane)
{
assert(image);
- return image->aux_surface.isl.size > 0 ? image->aux_surface.isl.levels : 0;
+ return image->planes[plane].aux_surface.isl.size > 0 ?
+ image->planes[plane].aux_surface.isl.levels : 0;
}
/* Returns the number of auxiliary buffer layers attached to an image. */
static inline uint32_t
anv_image_aux_layers(const struct anv_image * const image,
+ const uint32_t plane,
const uint8_t miplevel)
{
assert(image);
@@ -2347,14 +2429,14 @@ anv_image_aux_layers(const struct anv_image * const image,
/* The miplevel must exist in the main buffer. */
assert(miplevel < image->levels);
- if (miplevel >= anv_image_aux_levels(image)) {
+ if (miplevel >= anv_image_aux_levels(image, plane)) {
/* There are no layers with auxiliary data because the miplevel has no
* auxiliary data.
*/
return 0;
} else {
- return MAX2(image->aux_surface.isl.logical_level0_px.array_len,
- image->aux_surface.isl.logical_level0_px.depth >> miplevel);
+ return MAX2(image->planes[plane].aux_surface.isl.logical_level0_px.array_len,
+ image->planes[plane].aux_surface.isl.logical_level0_px.depth >> miplevel);
}
}
@@ -2378,13 +2460,12 @@ anv_fast_clear_state_entry_size(const struct anv_device *device)
/* Returns true if a HiZ-enabled depth buffer can be sampled from. */
static inline bool
anv_can_sample_with_hiz(const struct gen_device_info * const devinfo,
- const VkImageAspectFlags aspect_mask,
- const uint32_t samples)
+ const struct anv_image *image)
{
/* Validate the inputs. */
- assert(devinfo && aspect_mask && samples);
- return devinfo->gen >= 8 && (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) &&
- samples == 1;
+ assert(devinfo && image && image->samples);
+ return devinfo->gen >= 8 && (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) &&
+ image->samples == 1;
}
void
@@ -2395,12 +2476,14 @@ void
anv_ccs_resolve(struct anv_cmd_buffer * const cmd_buffer,
const struct anv_state surface_state,
const struct anv_image * const image,
+ const uint32_t plane,
const uint8_t level, const uint32_t layer_count,
const enum blorp_fast_clear_op op);
void
anv_image_fast_clear(struct anv_cmd_buffer *cmd_buffer,
const struct anv_image *image,
+ const uint32_t plane,
const uint32_t base_level, const uint32_t level_count,
const uint32_t base_layer, uint32_t layer_count);
@@ -2425,41 +2508,74 @@ anv_get_levelCount(const struct anv_image *image,
image->levels - range->baseMipLevel : range->levelCount;
}
+static inline VkImageAspectFlags
+anv_image_color_aspects(struct anv_image *image, VkImageAspectFlags aspects)
+{
+ /* If the underlying image has color plane aspects and
+ * VK_IMAGE_ASPECT_COLOR_BIT has been requested, then return the aspects of
+ * the underlying image. */
+ if ((image->aspects & VK_IMAGE_ASPECT_PLANES_BITS) != 0 &&
+ aspects == VK_IMAGE_ASPECT_COLOR_BIT)
+ return image->aspects;
+
+ return aspects;
+}
+
+static inline bool
+anv_image_aspects_compatible(VkImageAspectFlags aspects1,
+ VkImageAspectFlags aspects2)
+{
+ if (aspects1 == aspects2)
+ return true;
+
+ /* Only 1 color aspects are compatibles. */
+ if ((aspects1 & VK_IMAGE_ASPECT_ANY_COLOR_BIT) != 0 &&
+ (aspects2 & VK_IMAGE_ASPECT_ANY_COLOR_BIT) != 0 &&
+ _mesa_bitcount(aspects1) == _mesa_bitcount(aspects2))
+ return true;
+
+ return false;
+}
struct anv_image_view {
const struct anv_image *image; /**< VkImageViewCreateInfo::image */
- struct anv_bo *bo;
- uint32_t offset; /**< Offset into bo. */
-
- struct isl_view isl;
VkImageAspectFlags aspect_mask;
- VkFormat vk_format;
VkExtent3D extent; /**< Extent of VkImageViewCreateInfo::baseMipLevel. */
+ VkFormat vk_format;
- /**
- * RENDER_SURFACE_STATE when using image as a sampler surface with an image
- * layout of SHADER_READ_ONLY_OPTIMAL or DEPTH_STENCIL_READ_ONLY_OPTIMAL.
- */
- enum isl_aux_usage optimal_sampler_aux_usage;
- struct anv_state optimal_sampler_surface_state;
+ unsigned n_planes;
+ struct {
+ struct anv_surface *surface;
+ struct anv_surface *aux_surface;
+ enum isl_aux_usage aux_usage;
- /**
- * RENDER_SURFACE_STATE when using image as a sampler surface with an image
- * layout of GENERAL.
- */
- enum isl_aux_usage general_sampler_aux_usage;
- struct anv_state general_sampler_surface_state;
+ struct isl_view isl;
- /**
- * RENDER_SURFACE_STATE when using image as a storage image. Separate states
- * for write-only and readable, using the real format for write-only and the
- * lowered format for readable.
- */
- struct anv_state storage_surface_state;
- struct anv_state writeonly_storage_surface_state;
+ /**
+ * RENDER_SURFACE_STATE when using image as a sampler surface with an image
+ * layout of SHADER_READ_ONLY_OPTIMAL or DEPTH_STENCIL_READ_ONLY_OPTIMAL.
+ */
+ enum isl_aux_usage optimal_sampler_aux_usage;
+ struct anv_state optimal_sampler_surface_state;
- struct brw_image_param storage_image_param;
+ /**
+ * RENDER_SURFACE_STATE when using image as a sampler surface with an image
+ * layout of GENERAL.
+ */
+ enum isl_aux_usage general_sampler_aux_usage;
+ struct anv_state general_sampler_surface_state;
+
+ /**
+ * RENDER_SURFACE_STATE when using image as a storage image. Separate states
+ * for write-only and readable, using the real format for write-only and the
+ * lowered format for readable.
+ */
+ struct anv_state storage_surface_state;
+ struct anv_state writeonly_storage_surface_state;
+
+ struct brw_image_param storage_image_param;
+ } planes[3];
};
struct anv_image_create_info {
diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c
index c3e5dc1870b..3fca076894c 100644
--- a/src/intel/vulkan/anv_wsi.c
+++ b/src/intel/vulkan/anv_wsi.c
@@ -221,7 +221,7 @@ anv_wsi_image_create(VkDevice device_h,
result = anv_AllocateMemory(anv_device_to_handle(device),
&(VkMemoryAllocateInfo) {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
- .allocationSize = image->size,
+ .allocationSize = image->planes[0].surface.isl.size,
.memoryTypeIndex = 0,
},
NULL /* XXX: pAllocator */,
@@ -240,7 +240,7 @@ anv_wsi_image_create(VkDevice device_h,
anv_BindImageMemory(device_h, image_h, memory_h, 0);
- struct anv_surface *surface = &image->color_surface;
+ struct anv_surface *surface = &image->planes[0].surface;
assert(surface->isl.tiling == ISL_TILING_X);
*row_pitch = surface->isl.row_pitch;
@@ -266,8 +266,8 @@ anv_wsi_image_create(VkDevice device_h,
*image_p = image_h;
*memory_p = memory_h;
*fd_p = fd;
- *size = image->size;
- *offset = image->offset;
+ *size = image->planes[0].surface.isl.size;
+ *offset = image->planes[0].surface.offset;
return VK_SUCCESS;
fail_alloc_memory:
anv_FreeMemory(device_h, memory_h, pAllocator);
diff --git a/src/intel/vulkan/gen8_cmd_buffer.c b/src/intel/vulkan/gen8_cmd_buffer.c
index 064b8e930e9..5c08e6ccbea 100644
--- a/src/intel/vulkan/gen8_cmd_buffer.c
+++ b/src/intel/vulkan/gen8_cmd_buffer.c
@@ -323,7 +323,7 @@ want_stencil_pma_fix(struct anv_cmd_buffer *cmd_buffer)
/* HiZ is enabled so we had better have a depth buffer with HiZ */
const struct anv_image_view *ds_iview =
anv_cmd_buffer_get_depth_stencil_view(cmd_buffer);
- assert(ds_iview && ds_iview->image->aux_usage == ISL_AUX_USAGE_HIZ);
+ assert(ds_iview && ds_iview->image->planes[0].aux_usage == ISL_AUX_USAGE_HIZ);
/* 3DSTATE_PS_EXTRA::PixelShaderValid */
struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c
index bea73dfb504..afe0db1b3cd 100644
--- a/src/intel/vulkan/genX_cmd_buffer.c
+++ b/src/intel/vulkan/genX_cmd_buffer.c
@@ -180,19 +180,18 @@ add_surface_state_reloc(struct anv_cmd_buffer *cmd_buffer,
static void
add_image_relocs(struct anv_cmd_buffer * const cmd_buffer,
- const struct anv_image * const image,
- const VkImageAspectFlags aspect_mask,
+ const struct anv_surface * const surface,
+ const struct anv_surface * const aux_surface,
const enum isl_aux_usage aux_usage,
const struct anv_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;
+ const uint32_t surf_offset = surface->offset + surface->bo_offset;
- add_surface_state_reloc(cmd_buffer, state, image->bo, surf_offset);
+ add_surface_state_reloc(cmd_buffer, state, surface->bo, surf_offset);
if (aux_usage != ISL_AUX_USAGE_NONE) {
- uint32_t aux_offset = image->offset + image->aux_surface.offset;
+ uint32_t aux_offset = surface->offset + aux_surface->offset;
/* 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
@@ -206,7 +205,7 @@ add_image_relocs(struct anv_cmd_buffer * const cmd_buffer,
anv_reloc_list_add(&cmd_buffer->surface_relocs,
&cmd_buffer->pool->alloc,
state.offset + isl_dev->ss.aux_addr_offset,
- image->bo, aux_offset);
+ surface->bo, aux_offset);
if (result != VK_SUCCESS)
anv_batch_set_error(&cmd_buffer->batch, result);
}
@@ -239,8 +238,10 @@ 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, 0, iview->planes[0].isl.base_level)) {
/* There is no aux buffer which corresponds to the level and layer(s)
* being accessed.
*/
@@ -248,12 +249,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->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->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 {
@@ -269,7 +270,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
@@ -288,10 +289,10 @@ color_attachment_compute_aux_usage(struct anv_device * device,
}
}
- assert(iview->image->aux_surface.isl.usage & ISL_SURF_USAGE_CCS_BIT);
+ assert(iview->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 &&
@@ -323,7 +324,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, 0,
+ iview->planes[0].isl.base_level)) {
att_state->fast_clear = false;
if (GEN_GEN == 7) {
anv_perf_warn(device->instance, iview->image,
@@ -339,7 +341,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->planes[0].aux_usage == ISL_AUX_USAGE_NONE)) {
att_state->fast_clear = false;
}
@@ -384,14 +386,14 @@ 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 ==
- anv_layout_to_aux_usage(&cmd_buffer->device->info, image, image->aspects,
+ anv_layout_to_aux_usage(&cmd_buffer->device->info, image, 0,
initial_layout);
const bool enable_hiz = ISL_AUX_USAGE_HIZ ==
- anv_layout_to_aux_usage(&cmd_buffer->device->info, image, image->aspects,
+ anv_layout_to_aux_usage(&cmd_buffer->device->info, image, 0,
final_layout);
enum blorp_hiz_op hiz_op;
@@ -417,14 +419,16 @@ enum fast_clear_state_field {
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)
+ unsigned plane, 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, plane));
+ /* 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:
@@ -434,7 +438,8 @@ get_fast_clear_state_offset(const struct anv_device *device,
break;
}
- assert(offset < image->offset + image->size);
+ assert(offset < image->planes[plane].surface.offset + image->planes[plane].size);
+
return offset;
}
@@ -447,14 +452,14 @@ get_fast_clear_state_offset(const struct anv_device *device,
static void
genX(set_image_needs_resolve)(struct anv_cmd_buffer *cmd_buffer,
const struct anv_image *image,
- unsigned level, bool needs_resolve)
+ unsigned plane, 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, plane));
const uint32_t resolve_flag_offset =
- get_fast_clear_state_offset(cmd_buffer->device, image, level,
+ get_fast_clear_state_offset(cmd_buffer->device, image, plane, level,
FAST_CLEAR_STATE_FIELD_NEEDS_RESOLVE);
/* The HW docs say that there is no way to guarantee the completion of
@@ -462,7 +467,8 @@ genX(set_image_needs_resolve)(struct anv_cmd_buffer *cmd_buffer,
* 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 = (struct anv_address) { image->planes[plane].surface.bo,
+ resolve_flag_offset };
sdi.ImmediateData = needs_resolve;
}
}
@@ -470,14 +476,14 @@ 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,
- unsigned level)
+ unsigned plane, 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, plane));
const uint32_t resolve_flag_offset =
- get_fast_clear_state_offset(cmd_buffer->device, image, level,
+ get_fast_clear_state_offset(cmd_buffer->device, image, plane, level,
FAST_CLEAR_STATE_FIELD_NEEDS_RESOLVE);
/* Make the pending predicated resolve a no-op if one is not needed.
@@ -487,7 +493,7 @@ genX(load_needs_resolve_predicate)(struct anv_cmd_buffer *cmd_buffer,
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);
+ image->planes[plane].surface.bo, resolve_flag_offset);
anv_batch_emit(&cmd_buffer->batch, GENX(MI_PREDICATE), mip) {
mip.LoadOperation = LOAD_LOADINV;
mip.CombineOperation = COMBINE_SET;
@@ -498,11 +504,11 @@ 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,
- unsigned level)
+ unsigned plane, 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, plane));
/* The resolve flag should updated to signify that fast-clear/compression
* data needs to be removed when leaving the undefined layout. Such data
@@ -510,8 +516,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, plane, level,
+ image->planes[plane].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.
@@ -528,13 +534,14 @@ 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) {
const uint32_t entry_offset =
- get_fast_clear_state_offset(cmd_buffer->device, image, level,
+ get_fast_clear_state_offset(cmd_buffer->device, image, plane, level,
FAST_CLEAR_STATE_FIELD_CLEAR_COLOR);
- sdi.Address = (struct anv_address) { image->bo, entry_offset + i };
+ sdi.Address = (struct anv_address) { image->planes[plane].surface.bo,
+ entry_offset + i };
if (GEN_GEN >= 9) {
/* MCS buffers on SKL+ can only have 1/0 clear colors. */
- assert(image->aux_usage == ISL_AUX_USAGE_MCS);
+ assert(image->planes[plane].aux_usage == ISL_AUX_USAGE_MCS);
sdi.ImmediateData = 0;
} else if (GEN_VERSIONx10 >= 75) {
/* Pre-SKL, the dword containing the clear values also contains
@@ -564,28 +571,31 @@ static void
genX(copy_fast_clear_dwords)(struct anv_cmd_buffer *cmd_buffer,
struct anv_state surface_state,
const struct anv_image *image,
- unsigned level,
+ unsigned plane, 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, plane));
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,
+ get_fast_clear_state_offset(cmd_buffer->device, image, plane, 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,
+ image->planes[plane].surface.bo,
+ entry_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);
+ image->planes[plane].surface.bo,
+ entry_offset, copy_size);
/* Updating a surface state object may require that the state cache be
* invalidated. From the SKL PRM, Shared Functions -> State -> State
@@ -617,6 +627,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,
+ const uint32_t plane,
const uint32_t base_level, uint32_t level_count,
uint32_t base_layer, uint32_t layer_count,
VkImageLayout initial_layout,
@@ -624,7 +635,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);
@@ -642,7 +653,7 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,
* range lacks auxiliary data.
*/
if (initial_layout == final_layout ||
- base_layer >= anv_image_aux_layers(image, base_level))
+ base_layer >= anv_image_aux_layers(image, plane, base_level))
return;
/* A transition of a 3D subresource works on all slices at a time. */
@@ -652,9 +663,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, plane) - base_level);
layer_count = MIN2(layer_count,
- anv_image_aux_layers(image, base_level) - base_layer);
+ anv_image_aux_layers(image, plane, base_level) - base_layer);
last_level_num = base_level + level_count;
/* Record whether or not the layout is undefined. Pre-initialized images
@@ -675,7 +686,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, plane, 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
@@ -699,7 +710,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, plane,
+ base_level, level_count,
base_layer, layer_count);
}
/* At this point, some elements of the CCS buffer may have the fast-clear
@@ -711,7 +723,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.
@@ -763,10 +776,10 @@ 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, plane, level));
}
- genX(load_needs_resolve_predicate)(cmd_buffer, image, level);
+ genX(load_needs_resolve_predicate)(cmd_buffer, image, plane, level);
/* Create a surface state with the right clear color and perform the
* resolve.
@@ -774,33 +787,35 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,
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,
+ .surf = &image->planes[plane].surface.isl,
.view = &(struct isl_view) {
.usage = ISL_SURF_USAGE_RENDER_TARGET_BIT,
- .format = image->color_surface.isl.format,
+ .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,
},
- .aux_surf = &image->aux_surface.isl,
- .aux_usage = image->aux_usage == ISL_AUX_USAGE_NONE ?
- ISL_AUX_USAGE_CCS_D : image->aux_usage,
+ .aux_surf = &image->planes[plane].aux_surface.isl,
+ .aux_usage = image->planes[plane].aux_usage == ISL_AUX_USAGE_NONE ?
+ ISL_AUX_USAGE_CCS_D : image->planes[0].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 ?
+ add_image_relocs(cmd_buffer,
+ &image->planes[plane].surface,
+ &image->planes[plane].aux_surface,
+ image->planes[plane].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 ?
+ genX(copy_fast_clear_dwords)(cmd_buffer, surface_state, image,
+ plane, level, false /* copy to ss */);
+ anv_ccs_resolve(cmd_buffer, surface_state, image, 0, 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, plane, level, false);
}
cmd_buffer->state.pending_pipe_bits |=
@@ -886,7 +901,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;
@@ -910,26 +925,29 @@ 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) {
color_attachment_compute_aux_usage(cmd_buffer->device,
state, i, begin->renderArea,
&clear_color);
- struct isl_view view = iview->isl;
+ struct isl_view view = iview->planes[0].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,
+ .surf = &iview->planes[0].surface->isl,
.view = &view,
- .aux_surf = &iview->image->aux_surface.isl,
+ .aux_surf = &iview->planes[0].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,
+ add_image_relocs(cmd_buffer,
+ iview->planes[0].surface,
+ iview->planes[0].aux_surface,
state->attachments[i].aux_usage,
state->attachments[i].color_rt_state);
} else {
@@ -942,18 +960,20 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer,
}
if (need_input_attachment_state(&pass->attachments[i])) {
- struct isl_view view = iview->isl;
+ struct isl_view view = iview->planes[0].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,
+ .surf = &iview->planes[0].surface->isl,
.view = &view,
- .aux_surf = &iview->image->aux_surface.isl,
+ .aux_surf = &iview->planes[0].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,
+ add_image_relocs(cmd_buffer,
+ iview->planes[0].surface,
+ iview->planes[0].aux_surface,
state->attachments[i].input_aux_usage,
state->attachments[i].input_att_state);
}
@@ -1381,14 +1401,21 @@ 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_color_aspects(image, range->aspectMask);
+ uint32_t aspect_bit, plane;
+
+ anv_foreach_plane_aspect_bit(plane, aspect_bit, color_aspects,
+ image->aspects) {
+ transition_color_buffer(cmd_buffer, image, plane,
+ range->baseMipLevel,
+ anv_get_levelCount(image, range),
+ range->baseArrayLayer,
+ anv_get_layerCount(image, range),
+ pImageMemoryBarriers[i].oldLayout,
+ pImageMemoryBarriers[i].newLayout);
+ }
}
}
@@ -1579,35 +1606,37 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
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;
+ surface_state = desc->image_view->planes[desc->plane].general_sampler_surface_state;
+ aux_usage = desc->image_view->planes[desc->plane].general_sampler_aux_usage;
} else {
- surface_state = desc->image_view->optimal_sampler_surface_state;
- aux_usage = desc->image_view->optimal_sampler_aux_usage;
+ surface_state = desc->image_view->planes[desc->plane].optimal_sampler_surface_state;
+ aux_usage = desc->image_view->planes[desc->plane].optimal_sampler_aux_usage;
}
assert(surface_state.alloc_size);
- add_image_relocs(cmd_buffer, desc->image_view->image,
- desc->image_view->aspect_mask,
+ add_image_relocs(cmd_buffer,
+ desc->image_view->planes[desc->plane].surface,
+ desc->image_view->planes[desc->plane].aux_surface,
aux_usage, surface_state);
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;
+ surface_state = desc->image_view->planes[desc->plane].general_sampler_surface_state;
+ aux_usage = desc->image_view->planes[desc->plane].general_sampler_aux_usage;
} else {
- surface_state = desc->image_view->optimal_sampler_surface_state;
- aux_usage = desc->image_view->optimal_sampler_aux_usage;
+ surface_state = desc->image_view->planes[desc->plane].optimal_sampler_surface_state;
+ aux_usage = desc->image_view->planes[desc->plane].optimal_sampler_aux_usage;
}
assert(surface_state.alloc_size);
- add_image_relocs(cmd_buffer, desc->image_view->image,
- desc->image_view->aspect_mask,
+ add_image_relocs(cmd_buffer,
+ desc->image_view->planes[desc->plane].surface,
+ desc->image_view->planes[desc->plane].aux_surface,
aux_usage, surface_state);
} else {
/* For color input attachments, we create the surface state at
@@ -1623,17 +1652,18 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
surface_state = (binding->write_only)
- ? desc->image_view->writeonly_storage_surface_state
- : desc->image_view->storage_surface_state;
+ ? desc->image_view->planes[0].writeonly_storage_surface_state
+ : desc->image_view->planes[0].storage_surface_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_relocs(cmd_buffer,
+ desc->image_view->planes[desc->plane].surface,
+ desc->image_view->planes[desc->plane].aux_surface,
+ desc->image_view->planes[desc->plane].aux_usage, surface_state);
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[0].storage_image_param;
image_param->surface_idx = bias + s;
break;
}
@@ -2768,41 +2798,49 @@ 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);
+ surface->bo,
+ surface->offset + surface->bo_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[0].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);
+ surface->bo,
+ surface->offset + image->planes[0].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);
+ surface->bo,
+ surface->offset + surface->bo_offset);
}
isl_emit_depth_stencil_hiz_s(&device->isl_dev, dw, &info);
@@ -2892,7 +2930,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
@@ -2910,12 +2948,12 @@ cmd_buffer_subpass_transition_layouts(struct anv_cmd_buffer * const cmd_buffer,
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,
+ 0, target_layout);
+ } else if (image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT) {
+ transition_color_buffer(cmd_buffer, image, 0,
+ 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);
}
@@ -2960,22 +2998,25 @@ 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_rt_state,
- iview->image, iview->isl.base_level,
+ iview->image, 0,
+ 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
* will match what's in every RENDER_SURFACE_STATE object when it's
* being used for sampling.
*/
- genX(set_image_needs_resolve)(cmd_buffer, iview->image,
- iview->isl.base_level, false);
+ genX(set_image_needs_resolve)(cmd_buffer, iview->image, 0,
+ iview->planes[0].isl.base_level,
+ false);
} else {
- genX(set_image_needs_resolve)(cmd_buffer, iview->image,
- iview->isl.base_level, true);
+ genX(set_image_needs_resolve)(cmd_buffer, iview->image, 0,
+ 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
@@ -2984,13 +3025,16 @@ 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_rt_state,
- iview->image, iview->isl.base_level,
+ iview->image, 0,
+ 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_att_state,
+ iview->image, 0,
+ iview->planes[0].isl.base_level,
false /* copy to ss */);
}
}
--
2.14.1
More information about the mesa-dev
mailing list