<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Oct 3, 2017 at 9:29 AM, Lionel Landwerlin <span dir="ltr"><<a href="mailto:lionel.g.landwerlin@intel.com" target="_blank">lionel.g.landwerlin@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">This change introduce the concept of planes for image & views. It<br>
matches the planes available in new formats.<br>
<br>
We also refactor depth & stencil support through the usage of planes<br>
for the sake of uniformity. In the backend (genX_cmd_buffer.c) we have<br>
to take some care though with regard to auxilliary surfaces.<br>
Multiplanar color buffers can have multiple auxilliary surfaces but<br>
depth & stencil share the same HiZ one (only store in the depth<br>
plane).<br>
<br>
Signed-off-by: Lionel Landwerlin <<a href="mailto:lionel.g.landwerlin@intel.com">lionel.g.landwerlin@intel.com</a><wbr>><br>
---<br>
src/intel/vulkan/anv_blorp.c | 302 ++++++++++++------<br>
src/intel/vulkan/anv_dump.c | 17 +-<br>
src/intel/vulkan/anv_formats.c | 3 +-<br>
src/intel/vulkan/anv_image.c | 632 +++++++++++++++++++++++-------<wbr>-------<br>
src/intel/vulkan/anv_intel.c | 4 +-<br>
src/intel/vulkan/anv_private.h | 244 ++++++++++----<br>
src/intel/vulkan/anv_wsi.c | 8 +-<br>
src/intel/vulkan/gen8_cmd_<wbr>buffer.c | 2 +-<br>
src/intel/vulkan/genX_cmd_<wbr>buffer.c | 312 ++++++++++--------<br>
9 files changed, 985 insertions(+), 539 deletions(-)<br>
<br>
diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c<br>
index 72f482625aa..a181630a2f9 100644<br>
--- a/src/intel/vulkan/anv_blorp.c<br>
+++ b/src/intel/vulkan/anv_blorp.c<br>
@@ -177,30 +177,34 @@ get_blorp_surf_for_anv_buffer(<wbr>struct anv_device *device,<br>
<br>
static void<br>
get_blorp_surf_for_anv_image(<wbr>const struct anv_image *image,<br>
+ uint32_t plane,<br>
VkImageAspectFlags aspect,<br></blockquote><div><br></div><div>Ok, maybe I'm being a bit dense, but doesn't the aspect imply the plane? Why can't we just use anv_image_aspect_to_plane here? That would reduce the churn by a good bit.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
enum isl_aux_usage aux_usage,<br>
struct blorp_surf *blorp_surf)<br>
{<br>
+ /* For the stencil surface aux_usage is always NONE. */<br>
if (aspect == VK_IMAGE_ASPECT_STENCIL_BIT ||<br>
aux_usage == ISL_AUX_USAGE_HIZ)<br>
aux_usage = ISL_AUX_USAGE_NONE;<br>
<br>
- const struct anv_surface *surface =<br>
- anv_image_get_surface_for_<wbr>aspect_mask(image, aspect);<br>
+ const struct anv_surface *surface = &image->planes[plane].surface;<br>
<br>
*blorp_surf = (struct blorp_surf) {<br>
.surf = &surface->isl,<br>
.addr = {<br>
- .buffer = image->bo,<br>
- .offset = image->offset + surface->offset,<br>
+ .buffer = image->planes[plane].bo,<br>
+ .offset = image->planes[plane].bo_offset + surface->offset,<br>
},<br>
};<br>
<br>
if (aux_usage != ISL_AUX_USAGE_NONE) {<br>
- blorp_surf->aux_surf = &image->aux_surface.isl,<br>
+ const struct anv_surface *aux_surface =<br>
+ &image->planes[plane].aux_<wbr>surface;<br>
+<br>
+ blorp_surf->aux_surf = &aux_surface->isl,<br>
blorp_surf->aux_addr = (struct blorp_address) {<br>
- .buffer = image->bo,<br>
- .offset = image->offset + image->aux_surface.offset,<br>
+ .buffer = image->planes[plane].bo,<br>
+ .offset = image->planes[plane].bo_offset + aux_surface->offset,<br>
};<br>
blorp_surf->aux_usage = aux_usage;<br>
}<br>
@@ -249,17 +253,44 @@ void anv_CmdCopyImage(<br>
anv_get_layerCount(src_image, &pRegions[r].srcSubresource));<br>
}<br>
<br>
- assert(pRegions[r].<wbr>srcSubresource.aspectMask ==<br>
- pRegions[r].dstSubresource.<wbr>aspectMask);<br>
-<br>
- uint32_t a;<br>
- for_each_bit(a, pRegions[r].dstSubresource.<wbr>aspectMask) {<br>
- VkImageAspectFlagBits aspect = (1 << a);<br>
-<br>
+ VkImageAspectFlags src_mask = pRegions[r].srcSubresource.<wbr>aspectMask,<br>
+ dst_mask = pRegions[r].dstSubresource.<wbr>aspectMask;<br>
+<br>
+ assert(anv_image_aspects_<wbr>compatible(src_mask, dst_mask));<br>
+<br>
+ if (_mesa_bitcount(src_mask) > 1) {<br>
+ uint32_t plane, bit_aspect;<br>
+ anv_foreach_plane_aspect_bit(<wbr>plane, bit_aspect, src_mask,<br>
+ src_image->aspects) {<br>
+ struct blorp_surf src_surf, dst_surf;<br>
+ get_blorp_surf_for_anv_image(<wbr>src_image, plane, 1UL << bit_aspect,<br>
+ src_image->planes[plane].aux_<wbr>usage,<br>
+ &src_surf);<br>
+ get_blorp_surf_for_anv_image(<wbr>dst_image, plane, 1UL << bit_aspect,<br>
+ dst_image->planes[plane].aux_<wbr>usage,<br>
+ &dst_surf);<br>
+<br>
+ for (unsigned i = 0; i < layer_count; i++) {<br>
+ blorp_copy(&batch, &src_surf, pRegions[r].srcSubresource.<wbr>mipLevel,<br>
+ src_base_layer + i,<br>
+ &dst_surf, pRegions[r].dstSubresource.<wbr>mipLevel,<br>
+ dst_base_layer + i,<br>
+ srcOffset.x, srcOffset.y,<br>
+ dstOffset.x, dstOffset.y,<br>
+ extent.width, extent.height);<br>
+ }<br>
+ }<br>
+ } else {<br>
+ uint32_t src_plane = anv_image_aspect_to_plane(src_<wbr>image->aspects,<br>
+ src_mask),<br>
+ dst_plane = anv_image_aspect_to_plane(dst_<wbr>image->aspects,<br>
+ dst_mask);<br>
struct blorp_surf src_surf, dst_surf;<br>
- get_blorp_surf_for_anv_image(<wbr>src_image, aspect, src_image->aux_usage,<br>
+ get_blorp_surf_for_anv_image(<wbr>src_image, src_plane, src_mask,<br>
+ src_image->planes[src_plane].<wbr>aux_usage,<br>
&src_surf);<br>
- get_blorp_surf_for_anv_image(<wbr>dst_image, aspect, dst_image->aux_usage,<br>
+ get_blorp_surf_for_anv_image(<wbr>dst_image, dst_plane, dst_mask,<br>
+ dst_image->planes[dst_plane].<wbr>aux_usage,<br>
&dst_surf);<br>
<br>
for (unsigned i = 0; i < layer_count; i++) {<br>
@@ -307,8 +338,10 @@ copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,<br>
<br>
for (unsigned r = 0; r < regionCount; r++) {<br>
const VkImageAspectFlags aspect = pRegions[r].imageSubresource.<wbr>aspectMask;<br>
+ uint32_t plane = anv_image_aspect_to_plane(anv_<wbr>image->aspects, aspect);<br>
<br>
- get_blorp_surf_for_anv_image(<wbr>anv_image, aspect, anv_image->aux_usage,<br>
+ get_blorp_surf_for_anv_image(<wbr>anv_image, plane, aspect,<br>
+ anv_image->planes[plane].aux_<wbr>usage,<br>
&image.surf);<br>
image.offset =<br>
anv_sanitize_image_offset(anv_<wbr>image->type, pRegions[r].imageOffset);<br>
@@ -455,10 +488,15 @@ void anv_CmdBlitImage(<br>
const VkImageSubresourceLayers *src_res = &pRegions[r].srcSubresource;<br>
const VkImageSubresourceLayers *dst_res = &pRegions[r].dstSubresource;<br>
<br>
- get_blorp_surf_for_anv_image(<wbr>src_image, src_res->aspectMask,<br>
- src_image->aux_usage, &src);<br>
- get_blorp_surf_for_anv_image(<wbr>dst_image, dst_res->aspectMask,<br>
- dst_image->aux_usage, &dst);<br>
+ const uint32_t src_plane = anv_image_aspect_to_plane(src_<wbr>image->aspects,<br>
+ src_res->aspectMask),<br>
+ dst_plane = anv_image_aspect_to_plane(dst_<wbr>image->aspects,<br>
+ dst_res->aspectMask);<br>
+<br>
+ get_blorp_surf_for_anv_image(<wbr>src_image, src_plane, src_res->aspectMask,<br>
+ src_image->planes[src_plane].<wbr>aux_usage, &src);<br>
+ get_blorp_surf_for_anv_image(<wbr>dst_image, dst_plane, dst_res->aspectMask,<br>
+ dst_image->planes[dst_plane].<wbr>aux_usage, &dst);<br>
<br>
struct anv_format_plane src_format =<br>
anv_get_plane_format(&cmd_<wbr>buffer->device->info, src_image->vk_format,<br>
@@ -749,15 +787,19 @@ void anv_CmdClearColorImage(<br>
struct blorp_batch batch;<br>
blorp_batch_init(&cmd_buffer-><wbr>device->blorp, &batch, cmd_buffer, 0);<br>
<br>
- struct blorp_surf surf;<br>
- get_blorp_surf_for_anv_image(<wbr>image, VK_IMAGE_ASPECT_COLOR_BIT,<br>
- image->aux_usage, &surf);<br>
<br>
for (unsigned r = 0; r < rangeCount; r++) {<br>
if (pRanges[r].aspectMask == 0)<br>
continue;<br>
<br>
- assert(pRanges[r].aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);<br>
+ assert(pRanges[r].aspectMask & VK_IMAGE_ASPECT_ANY_COLOR_BIT)<wbr>;<br>
+<br>
+ const uint32_t plane = anv_image_aspect_to_plane(<wbr>image->aspects,<br>
+ pRanges[r].aspectMask);<br>
+<br>
+ struct blorp_surf surf;<br>
+ get_blorp_surf_for_anv_image(<wbr>image, plane, pRanges[r].aspectMask,<br>
+ image->planes[plane].aux_<wbr>usage, &surf);<br>
<br>
struct anv_format_plane src_format =<br>
anv_get_plane_format(&cmd_<wbr>buffer->device->info, image->vk_format,<br>
@@ -803,14 +845,20 @@ void anv_CmdClearDepthStencilImage(<br>
<br>
struct blorp_surf depth, stencil;<br>
if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {<br>
- get_blorp_surf_for_anv_image(<wbr>image, VK_IMAGE_ASPECT_DEPTH_BIT,<br>
+ uint32_t depth_plane =<br>
+ anv_image_aspect_to_plane(<wbr>image->aspects, VK_IMAGE_ASPECT_DEPTH_BIT);<br>
+ get_blorp_surf_for_anv_image(<wbr>image, depth_plane,<br>
+ VK_IMAGE_ASPECT_DEPTH_BIT,<br>
ISL_AUX_USAGE_NONE, &depth);<br>
} else {<br>
memset(&depth, 0, sizeof(depth));<br>
}<br>
<br>
if (image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {<br>
- get_blorp_surf_for_anv_image(<wbr>image, VK_IMAGE_ASPECT_STENCIL_BIT,<br>
+ uint32_t stencil_plane =<br>
+ anv_image_aspect_to_plane(<wbr>image->aspects, VK_IMAGE_ASPECT_STENCIL_BIT);<br>
+ get_blorp_surf_for_anv_image(<wbr>image, stencil_plane,<br>
+ VK_IMAGE_ASPECT_STENCIL_BIT,<br>
ISL_AUX_USAGE_NONE, &stencil);<br>
} else {<br>
memset(&stencil, 0, sizeof(stencil));<br>
@@ -1044,7 +1092,7 @@ void anv_CmdClearAttachments(<br>
BLORP_BATCH_NO_EMIT_DEPTH_<wbr>STENCIL);<br>
<br>
for (uint32_t a = 0; a < attachmentCount; ++a) {<br>
- if (pAttachments[a].aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {<br>
+ if (pAttachments[a].aspectMask & VK_IMAGE_ASPECT_ANY_COLOR_BIT) {<br>
clear_color_attachment(cmd_<wbr>buffer, &batch,<br>
&pAttachments[a],<br>
rectCount, pRects);<br>
@@ -1130,7 +1178,7 @@ anv_cmd_buffer_clear_subpass(<wbr>struct anv_cmd_buffer *cmd_buffer)<br>
struct anv_image_view *iview = fb->attachments[a];<br>
const struct anv_image *image = iview->image;<br>
struct blorp_surf surf;<br>
- get_blorp_surf_for_anv_image(<wbr>image, VK_IMAGE_ASPECT_COLOR_BIT,<br>
+ get_blorp_surf_for_anv_image(<wbr>image, 0, VK_IMAGE_ASPECT_COLOR_BIT,<br>
att_state->aux_usage, &surf);<br>
<br>
if (att_state->fast_clear) {<br>
@@ -1155,24 +1203,26 @@ anv_cmd_buffer_clear_subpass(<wbr>struct anv_cmd_buffer *cmd_buffer)<br>
cmd_buffer->state.pending_<wbr>pipe_bits |=<br>
ANV_PIPE_RENDER_TARGET_CACHE_<wbr>FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;<br>
<br>
- blorp_fast_clear(&batch, &surf, iview->isl.format,<br>
- iview->isl.base_level,<br>
- iview->isl.base_array_layer, fb->layers,<br>
- render_area.offset.x, render_area.offset.y,<br>
- render_area.offset.x + render_area.extent.width,<br>
- render_area.offset.y + render_area.extent.height);<br>
+ for (unsigned p = 0; p < iview->n_planes; p++)<br>
+ blorp_fast_clear(&batch, &surf, iview->planes[p].isl.format,<br>
+ iview->planes[p].isl.base_<wbr>level,<br>
+ iview->planes[p].isl.base_<wbr>array_layer, fb->layers,<br>
+ render_area.offset.x, render_area.offset.y,<br>
+ render_area.offset.x + render_area.extent.width,<br>
+ render_area.offset.y + render_area.extent.height);<br>
<br>
cmd_buffer->state.pending_<wbr>pipe_bits |=<br>
ANV_PIPE_RENDER_TARGET_CACHE_<wbr>FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;<br>
} else {<br>
- blorp_clear(&batch, &surf, iview->isl.format,<br>
- anv_swizzle_for_render(iview-><wbr>isl.swizzle),<br>
- iview->isl.base_level,<br>
- iview->isl.base_array_layer, fb->layers,<br>
- render_area.offset.x, render_area.offset.y,<br>
- render_area.offset.x + render_area.extent.width,<br>
- render_area.offset.y + render_area.extent.height,<br>
- vk_to_isl_color(att_state-><wbr>clear_value.color), NULL);<br>
+ for (unsigned p = 0; p < iview->n_planes; p++)<br>
+ blorp_clear(&batch, &surf, iview->planes[p].isl.format,<br>
+ anv_swizzle_for_render(iview-><wbr>planes[p].isl.swizzle),<br>
+ iview->planes[p].isl.base_<wbr>level,<br>
+ iview->planes[p].isl.base_<wbr>array_layer, fb->layers,<br>
+ render_area.offset.x, render_area.offset.y,<br>
+ render_area.offset.x + render_area.extent.width,<br>
+ render_area.offset.y + render_area.extent.height,<br>
+ vk_to_isl_color(att_state-><wbr>clear_value.color), NULL);<br>
}<br>
<br>
att_state->pending_clear_<wbr>aspects = 0;<br>
@@ -1207,7 +1257,7 @@ anv_cmd_buffer_clear_subpass(<wbr>struct anv_cmd_buffer *cmd_buffer)<br>
* a stencil clear in addition to using the BLORP-fallback for depth.<br>
*/<br>
if (clear_depth) {<br>
- if (!blorp_can_hiz_clear_depth(<wbr>gen, iview->isl.format,<br>
+ if (!blorp_can_hiz_clear_depth(<wbr>gen, iview->planes[0].isl.format,<br>
iview->image->samples,<br>
render_area.offset.x,<br>
render_area.offset.y,<br>
@@ -1224,8 +1274,7 @@ anv_cmd_buffer_clear_subpass(<wbr>struct anv_cmd_buffer *cmd_buffer)<br>
clear_with_hiz = false;<br>
} else if (gen == 8 &&<br>
anv_can_sample_with_hiz(&cmd_<wbr>buffer->device->info,<br>
- iview->aspect_mask,<br>
- iview->image->samples)) {<br>
+ iview->image)) {<br>
/* Only gen9+ supports returning ANV_HZ_FC_VAL when sampling a<br>
* fast-cleared portion of a HiZ buffer. Testing has revealed<br>
* that Gen8 only supports returning 0.0f. Gens prior to gen8 do<br>
@@ -1276,13 +1325,30 @@ anv_cmd_buffer_clear_subpass(<wbr>struct anv_cmd_buffer *cmd_buffer)<br>
blorp_batch_finish(&batch);<br>
}<br>
<br>
+static void<br>
+resolve_surface(struct blorp_batch *batch,<br>
+ struct blorp_surf *src_surf,<br>
+ uint32_t src_level, uint32_t src_layer,<br>
+ struct blorp_surf *dst_surf,<br>
+ uint32_t dst_level, uint32_t dst_layer,<br>
+ uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,<br>
+ uint32_t width, uint32_t height)<br>
+{<br>
+ blorp_blit(batch,<br>
+ src_surf, src_level, src_layer,<br>
+ ISL_FORMAT_UNSUPPORTED, ISL_SWIZZLE_IDENTITY,<br>
+ dst_surf, dst_level, dst_layer,<br>
+ ISL_FORMAT_UNSUPPORTED, ISL_SWIZZLE_IDENTITY,<br>
+ src_x, src_y, src_x + width, src_y + height,<br>
+ dst_x, dst_y, dst_x + width, dst_y + height,<br>
+ 0x2600 /* GL_NEAREST */, false, false);<br>
+}<br>
+<br>
static void<br>
resolve_image(struct blorp_batch *batch,<br>
const struct anv_image *src_image,<br>
- enum isl_aux_usage src_aux_usage,<br>
uint32_t src_level, uint32_t src_layer,<br>
const struct anv_image *dst_image,<br>
- enum isl_aux_usage dst_aux_usage,<br>
uint32_t dst_level, uint32_t dst_layer,<br>
VkImageAspectFlags aspect_mask,<br>
uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,<br>
@@ -1292,25 +1358,31 @@ resolve_image(struct blorp_batch *batch,<br>
assert(src_image->samples > 1);<br>
assert(dst_image->type == VK_IMAGE_TYPE_2D);<br>
assert(dst_image->samples == 1);<br>
+ assert(src_image->n_planes == dst_image->n_planes);<br>
<br>
- uint32_t a;<br>
- for_each_bit(a, aspect_mask) {<br>
- VkImageAspectFlagBits aspect = 1 << a;<br>
-<br>
+ uint32_t plane, aspect_bit;<br>
+ anv_foreach_plane_aspect_bit(<wbr>plane, aspect_bit, aspect_mask,<br>
+ src_image->aspects) {<br>
struct blorp_surf src_surf, dst_surf;<br>
- get_blorp_surf_for_anv_image(<wbr>src_image, aspect,<br>
- src_aux_usage, &src_surf);<br>
- get_blorp_surf_for_anv_image(<wbr>dst_image, aspect,<br>
- dst_aux_usage, &dst_surf);<br>
-<br>
- blorp_blit(batch,<br>
- &src_surf, src_level, src_layer,<br>
- ISL_FORMAT_UNSUPPORTED, ISL_SWIZZLE_IDENTITY,<br>
- &dst_surf, dst_level, dst_layer,<br>
- ISL_FORMAT_UNSUPPORTED, ISL_SWIZZLE_IDENTITY,<br>
- src_x, src_y, src_x + width, src_y + height,<br>
- dst_x, dst_y, dst_x + width, dst_y + height,<br>
- 0x2600 /* GL_NEAREST */, false, false);<br>
+ get_blorp_surf_for_anv_image(<wbr>src_image, plane, 1UL << aspect_bit,<br>
+ src_image->planes[plane].aux_<wbr>usage,<br>
+ &src_surf);<br>
+ get_blorp_surf_for_anv_image(<wbr>dst_image, plane, 1UL << aspect_bit,<br>
+ dst_image->planes[plane].aux_<wbr>usage,<br>
+ &dst_surf);<br>
+<br>
+ uint32_t width_div = src_image->format->planes[<wbr>plane].denominator_scales[0],<br>
+ height_div = src_image->format->planes[<wbr>plane].denominator_scales[1];<br></blockquote><div><br></div><div>Multisample YUV isn't a thing. I don't think we need to do anything here except assert that we're not YUV.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+ resolve_surface(batch,<br>
+ &src_surf, src_level, src_layer,<br>
+ &dst_surf, dst_level, dst_layer,<br>
+ src_x / width_div,<br>
+ src_y / height_div,<br>
+ dst_x / width_div,<br>
+ dst_y / height_div,<br>
+ width / width_div,<br>
+ height / height_div);<br>
}<br>
}<br>
<br>
@@ -1339,12 +1411,17 @@ void anv_CmdResolveImage(<br>
const uint32_t layer_count =<br>
anv_get_layerCount(dst_image, &pRegions[r].dstSubresource);<br>
<br>
+ VkImageAspectFlags src_mask = pRegions[r].srcSubresource.<wbr>aspectMask,<br>
+ dst_mask = pRegions[r].dstSubresource.<wbr>aspectMask;<br>
+<br>
+ assert(anv_image_aspects_<wbr>compatible(src_mask, dst_mask));<br>
+<br>
for (uint32_t layer = 0; layer < layer_count; layer++) {<br>
resolve_image(&batch,<br>
- src_image, src_image->aux_usage,<br>
+ src_image,<br>
pRegions[r].srcSubresource.<wbr>mipLevel,<br>
pRegions[r].srcSubresource.<wbr>baseArrayLayer + layer,<br>
- dst_image, dst_image->aux_usage,<br>
+ dst_image,<br>
pRegions[r].dstSubresource.<wbr>mipLevel,<br>
pRegions[r].dstSubresource.<wbr>baseArrayLayer + layer,<br>
pRegions[r].dstSubresource.<wbr>aspectMask,<br>
@@ -1360,6 +1437,7 @@ void anv_CmdResolveImage(<br>
void<br>
anv_image_fast_clear(struct anv_cmd_buffer *cmd_buffer,<br>
const struct anv_image *image,<br>
+ const uint32_t plane,<br>
const uint32_t base_level, const uint32_t level_count,<br>
const uint32_t base_layer, uint32_t layer_count)<br>
{<br>
@@ -1374,9 +1452,9 @@ anv_image_fast_clear(struct anv_cmd_buffer *cmd_buffer,<br>
blorp_batch_init(&cmd_buffer-><wbr>device->blorp, &batch, cmd_buffer, 0);<br>
<br>
struct blorp_surf surf;<br>
- get_blorp_surf_for_anv_image(<wbr>image, VK_IMAGE_ASPECT_COLOR_BIT,<br>
- image->aux_usage == ISL_AUX_USAGE_NONE ?<br>
- ISL_AUX_USAGE_CCS_D : image->aux_usage,<br>
+ get_blorp_surf_for_anv_image(<wbr>image, plane, VK_IMAGE_ASPECT_COLOR_BIT,<br>
+ image->planes[plane].aux_usage == ISL_AUX_USAGE_NONE ?<br>
+ ISL_AUX_USAGE_CCS_D : image->planes[plane].aux_<wbr>usage,<br>
&surf);<br>
<br>
/* From the Sky Lake PRM Vol. 7, "Render Target Fast Clear":<br>
@@ -1397,6 +1475,9 @@ anv_image_fast_clear(struct anv_cmd_buffer *cmd_buffer,<br>
cmd_buffer->state.pending_<wbr>pipe_bits |=<br>
ANV_PIPE_RENDER_TARGET_CACHE_<wbr>FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;<br>
<br>
+ uint32_t width_div = image->format->planes[plane].<wbr>denominator_scales[0],<br>
+ height_div = image->format->planes[plane].<wbr>denominator_scales[1];<br>
+<br>
for (uint32_t l = 0; l < level_count; l++) {<br>
const uint32_t level = base_level + l;<br>
<br>
@@ -1409,11 +1490,13 @@ anv_image_fast_clear(struct anv_cmd_buffer *cmd_buffer,<br>
if (image->type == VK_IMAGE_TYPE_3D)<br>
layer_count = extent.depth;<br>
<br>
- assert(level < anv_image_aux_levels(image));<br>
- assert(base_layer + layer_count <= anv_image_aux_layers(image, level));<br>
+ assert(level < anv_image_aux_levels(image, plane));<br>
+ assert(base_layer + layer_count <= anv_image_aux_layers(image, plane, level));<br>
blorp_fast_clear(&batch, &surf, surf.surf->format,<br>
level, base_layer, layer_count,<br>
- 0, 0, extent.width, extent.height);<br>
+ 0, 0,<br>
+ extent.width / width_div,<br>
+ extent.height / height_div);<br>
}<br>
<br>
cmd_buffer->state.pending_<wbr>pipe_bits |=<br>
@@ -1470,17 +1553,34 @@ anv_cmd_buffer_resolve_<wbr>subpass(struct anv_cmd_buffer *cmd_buffer)<br>
const VkRect2D render_area = cmd_buffer->state.render_area;<br>
<br>
assert(src_iview->aspect_mask == dst_iview->aspect_mask);<br>
+ assert(src_iview->n_planes == 1);<br>
+ assert(dst_iview->n_planes == 1);<br>
<br>
- resolve_image(&batch, src_iview->image, src_aux_usage,<br>
- src_iview->isl.base_level,<br>
- src_iview->isl.base_array_<wbr>layer,<br>
- dst_iview->image, dst_aux_usage,<br>
- dst_iview->isl.base_level,<br>
- dst_iview->isl.base_array_<wbr>layer,<br>
- src_iview->aspect_mask,<br>
- render_area.offset.x, render_area.offset.y,<br>
- render_area.offset.x, render_area.offset.y,<br>
- render_area.extent.width, render_area.extent.height);<br>
+ const struct anv_format *format = src_iview->image->format;<br>
+<br>
+ uint32_t width_div = format->planes[0].denominator_<wbr>scales[0],<br>
+ height_div = format->planes[0].denominator_<wbr>scales[1];<br></blockquote><div><br></div><div>YUV is not going to be used as an input/output attachment. We should just assert here and not pretend to support it.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+ struct blorp_surf src_surf, dst_surf;<br>
+ get_blorp_surf_for_anv_image(<wbr>src_iview->image, 0,<br>
+ src_iview->aspect_mask,<br>
+ src_aux_usage, &src_surf);<br>
+ get_blorp_surf_for_anv_image(<wbr>dst_iview->image, 0,<br>
+ dst_iview->aspect_mask,<br>
+ dst_aux_usage, &dst_surf);<br>
+<br>
+ resolve_surface(&batch, &src_surf,<br>
+ src_iview->planes[0].isl.base_<wbr>level,<br>
+ src_iview->planes[0].isl.base_<wbr>array_layer,<br>
+ &dst_surf,<br>
+ dst_iview->planes[0].isl.base_<wbr>level,<br>
+ dst_iview->planes[0].isl.base_<wbr>array_layer,<br>
+ render_area.offset.x / width_div,<br>
+ render_area.offset.y / height_div,<br>
+ render_area.offset.x / width_div,<br>
+ render_area.offset.y / height_div,<br>
+ render_area.extent.width / width_div,<br>
+ render_area.extent.height / height_div);<br>
}<br>
<br>
blorp_batch_finish(&batch);<br>
@@ -1490,7 +1590,7 @@ anv_cmd_buffer_resolve_<wbr>subpass(struct anv_cmd_buffer *cmd_buffer)<br>
void<br>
anv_image_copy_to_shadow(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
const struct anv_image *image,<br>
- VkImageAspectFlagBits aspect,<br>
+ uint32_t plane,<br>
uint32_t base_level, uint32_t level_count,<br>
uint32_t base_layer, uint32_t layer_count)<br>
{<br>
@@ -1498,14 +1598,15 @@ anv_image_copy_to_shadow(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
blorp_batch_init(&cmd_buffer-><wbr>device->blorp, &batch, cmd_buffer, 0);<br>
<br>
struct blorp_surf surf;<br>
- get_blorp_surf_for_anv_image(<wbr>image, VK_IMAGE_ASPECT_COLOR_BIT,<br>
+ get_blorp_surf_for_anv_image(<wbr>image, plane, VK_IMAGE_ASPECT_COLOR_BIT,<br>
ISL_AUX_USAGE_NONE, &surf);<br></blockquote><div><br></div><div>Ugh... This function takes an aspect and then entirely ignores it. :-( We can just hard-code plane to 0 here because it's for compressed textures which will never be YUV.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
struct blorp_surf shadow_surf = {<br>
- .surf = &image->shadow_surface.isl,<br>
+ .surf = &image->planes[plane].shadow_<wbr>surface.isl,<br>
.addr = {<br>
- .buffer = image->bo,<br>
- .offset = image->offset + image->shadow_surface.offset,<br>
+ .buffer = image->planes[plane].bo,<br>
+ .offset = image->planes[plane].bo_offset +<br>
+ image->planes[plane].shadow_<wbr>surface.offset,<br>
},<br>
};<br>
<br>
@@ -1544,7 +1645,7 @@ anv_gen8_hiz_op_resolve(struct anv_cmd_buffer *cmd_buffer,<br>
* don't perform such a resolve on gens that don't support it.<br>
*/<br>
if (cmd_buffer->device->info.gen < 8 ||<br>
- image->aux_usage != ISL_AUX_USAGE_HIZ)<br>
+ image->planes[0].aux_usage != ISL_AUX_USAGE_HIZ)<br>
return;<br>
<br>
assert(op == BLORP_HIZ_OP_HIZ_RESOLVE ||<br>
@@ -1554,14 +1655,15 @@ anv_gen8_hiz_op_resolve(struct anv_cmd_buffer *cmd_buffer,<br>
blorp_batch_init(&cmd_buffer-><wbr>device->blorp, &batch, cmd_buffer, 0);<br>
<br>
struct blorp_surf surf;<br>
- get_blorp_surf_for_anv_image(<wbr>image, VK_IMAGE_ASPECT_DEPTH_BIT,<br>
+ get_blorp_surf_for_anv_image(<wbr>image, 0, VK_IMAGE_ASPECT_DEPTH_BIT,<br>
ISL_AUX_USAGE_NONE, &surf);<br>
<br>
/* Manually add the aux HiZ surf */<br>
- surf.aux_surf = &image->aux_surface.isl,<br>
+ surf.aux_surf = &image->planes[0].aux_surface.<wbr>isl,<br>
surf.aux_addr = (struct blorp_address) {<br>
- .buffer = image->bo,<br>
- .offset = image->offset + image->aux_surface.offset,<br>
+ .buffer = image->planes[0].bo,<br>
+ .offset = image->planes[0].bo_offset +<br>
+ image->planes[0].aux_surface.<wbr>offset,<br>
};<br>
surf.aux_usage = ISL_AUX_USAGE_HIZ;<br>
<br>
@@ -1575,15 +1677,16 @@ void<br>
anv_ccs_resolve(struct anv_cmd_buffer * const cmd_buffer,<br>
const struct anv_state surface_state,<br>
const struct anv_image * const image,<br>
+ const uint32_t plane,<br>
const uint8_t level, const uint32_t layer_count,<br>
const enum blorp_fast_clear_op op)<br>
{<br>
assert(cmd_buffer && image);<br>
<br>
/* The resolved subresource range must have a CCS buffer. */<br>
- assert(level < anv_image_aux_levels(image));<br>
- assert(layer_count <= anv_image_aux_layers(image, level));<br>
- assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT && image->samples == 1);<br>
+ assert(level < anv_image_aux_levels(image, plane));<br>
+ assert(layer_count <= anv_image_aux_layers(image, plane, level));<br>
+ assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT && image->samples == 1);<br>
<br>
/* Create a binding table for this surface state. */<br>
uint32_t binding_table;<br>
@@ -1598,13 +1701,14 @@ anv_ccs_resolve(struct anv_cmd_buffer * const cmd_buffer,<br>
BLORP_BATCH_PREDICATE_ENABLE);<br>
<br>
struct blorp_surf surf;<br>
- get_blorp_surf_for_anv_image(<wbr>image, VK_IMAGE_ASPECT_COLOR_BIT,<br>
- image->aux_usage == ISL_AUX_USAGE_CCS_E ?<br>
+ get_blorp_surf_for_anv_image(<wbr>image, plane, VK_IMAGE_ASPECT_COLOR_BIT,<br>
+ image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E ?<br>
ISL_AUX_USAGE_CCS_E : ISL_AUX_USAGE_CCS_D,<br>
&surf);<br>
<br>
blorp_ccs_resolve_attachment(&<wbr>batch, binding_table, &surf, level,<br>
- layer_count, image->color_surface.isl.<wbr>format,<br>
+ layer_count,<br>
+ image->planes[plane].surface.<wbr>isl.format,<br>
op);<br>
<br>
blorp_batch_finish(&batch);<br>
diff --git a/src/intel/vulkan/anv_dump.c b/src/intel/vulkan/anv_dump.c<br>
index 0608904219e..160c18c4f17 100644<br>
--- a/src/intel/vulkan/anv_dump.c<br>
+++ b/src/intel/vulkan/anv_dump.c<br>
@@ -424,20 +424,25 @@ anv_dump_add_framebuffer(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
uint32_t b;<br>
for_each_bit(b, iview->image->aspects) {<br>
VkImageAspectFlagBits aspect = (1 << b);<br>
- char suffix;<br>
+ const char *suffix;<br>
switch (aspect) {<br>
- case VK_IMAGE_ASPECT_COLOR_BIT: suffix = 'c'; break;<br>
- case VK_IMAGE_ASPECT_DEPTH_BIT: suffix = 'd'; break;<br>
- case VK_IMAGE_ASPECT_STENCIL_BIT: suffix = 's'; break;<br>
+ case VK_IMAGE_ASPECT_COLOR_BIT: suffix = "c"; break;<br>
+ case VK_IMAGE_ASPECT_DEPTH_BIT: suffix = "d"; break;<br>
+ case VK_IMAGE_ASPECT_STENCIL_BIT: suffix = "s"; break;<br>
+ case VK_IMAGE_ASPECT_PLANE_0_BIT_<wbr>KHR: suffix = "c0"; break;<br>
+ case VK_IMAGE_ASPECT_PLANE_1_BIT_<wbr>KHR: suffix = "c1"; break;<br>
+ case VK_IMAGE_ASPECT_PLANE_2_BIT_<wbr>KHR: suffix = "c2"; break;<br>
default:<br>
unreachable("Invalid aspect");<br>
}<br>
<br>
- char *filename = ralloc_asprintf(dump_ctx, "framebuffer%04d-%d%c.ppm",<br>
+ char *filename = ralloc_asprintf(dump_ctx, "framebuffer%04d-%d%s.ppm",<br>
dump_idx, i, suffix);<br>
<br>
+ unsigned plane = anv_image_aspect_to_plane(<wbr>iview->image->aspects, aspect);<br>
dump_add_image(cmd_buffer, (struct anv_image *)iview->image, aspect,<br>
- iview->isl.base_level, iview->isl.base_array_layer,<br>
+ iview->planes[plane].isl.base_<wbr>level,<br>
+ iview->planes[plane].isl.base_<wbr>array_layer,<br>
filename);<br>
}<br>
}<br>
diff --git a/src/intel/vulkan/anv_<wbr>formats.c b/src/intel/vulkan/anv_<wbr>formats.c<br>
index 303531a6ab9..3a941d4bd06 100644<br>
--- a/src/intel/vulkan/anv_<wbr>formats.c<br>
+++ b/src/intel/vulkan/anv_<wbr>formats.c<br>
@@ -423,8 +423,7 @@ anv_get_plane_format(const struct gen_device_info *devinfo, VkFormat vk_format,<br>
return plane_format;<br>
}<br>
<br>
- assert(aspect == VK_IMAGE_ASPECT_COLOR_BIT);<br>
- assert(vk_format_aspects(vk_<wbr>format) == VK_IMAGE_ASPECT_COLOR_BIT);<br>
+ assert((aspect & ~VK_IMAGE_ASPECT_ANY_COLOR_<wbr>BIT) == 0);<br>
<br>
const struct isl_format_layout *isl_layout =<br>
isl_format_get_layout(plane_<wbr>format.isl_format);<br>
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c<br>
index 262be68575a..6b3b70803d0 100644<br>
--- a/src/intel/vulkan/anv_image.c<br>
+++ b/src/intel/vulkan/anv_image.c<br>
@@ -68,6 +68,9 @@ choose_isl_surf_usage(<wbr>VkImageCreateFlags vk_create_flags,<br>
isl_usage |= ISL_SURF_USAGE_STENCIL_BIT;<br>
break;<br>
case VK_IMAGE_ASPECT_COLOR_BIT:<br>
+ case VK_IMAGE_ASPECT_PLANE_0_BIT_<wbr>KHR:<br>
+ case VK_IMAGE_ASPECT_PLANE_1_BIT_<wbr>KHR:<br>
+ case VK_IMAGE_ASPECT_PLANE_2_BIT_<wbr>KHR:<br>
break;<br>
default:<br>
unreachable("bad VkImageAspect");<br>
@@ -95,26 +98,31 @@ choose_isl_surf_usage(<wbr>VkImageCreateFlags vk_create_flags,<br>
static struct anv_surface *<br>
get_surface(struct anv_image *image, VkImageAspectFlags aspect)<br>
{<br>
- switch (aspect) {<br>
- default:<br>
- unreachable("bad VkImageAspect");<br>
- case VK_IMAGE_ASPECT_COLOR_BIT:<br>
- return &image->color_surface;<br>
- case VK_IMAGE_ASPECT_DEPTH_BIT:<br>
- return &image->depth_surface;<br>
- case VK_IMAGE_ASPECT_STENCIL_BIT:<br>
- return &image->stencil_surface;<br>
- }<br>
+ uint32_t plane = anv_image_aspect_to_plane(<wbr>image->aspects, aspect);<br>
+ return &image->planes[plane].surface;<br>
}<br>
<br>
static void<br>
-add_surface(struct anv_image *image, struct anv_surface *surf)<br>
+add_surface(struct anv_image *image, struct anv_surface *surf, uint32_t plane)<br>
{<br>
assert(surf->isl.size > 0); /* isl surface must be initialized */<br>
<br>
- surf->offset = align_u32(image->size, surf->isl.alignment);<br>
+ if (image->disjoint) {<br>
+ surf->offset = align_u32(image->planes[plane]<wbr>.size, surf->isl.alignment);<br>
+ /* Plane offset is always 0 when it's disjoint. */<br>
+ } else {<br>
+ surf->offset = align_u32(image->size, surf->isl.alignment);<br>
+ /* Determine plane's offset only once when the first surface is added. */<br>
+ if (image->planes[plane].size == 0)<br>
+ image->planes[plane].offset = image->size;<br></blockquote><div><br></div><div>This seems to be in conflict with code below (A)<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+ }<br>
+<br>
image->size = surf->offset + surf->isl.size;<br>
+ image->planes[plane].size = (surf->offset + surf->isl.size) - image->planes[plane].offset;<br></blockquote><div><br></div><div>Is surf->offset relative to the image or the plane? I think, based on what you have here, that it's relative to the image but it's confusing. :(</div><div><br></div><div>Also, what do we use the plane size for? Does it even make sense for non-disjoint?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
image->alignment = MAX2(image->alignment, surf->isl.alignment);<br>
+ image->planes[plane].alignment = MAX2(image->planes[plane].<wbr>alignment,<br>
+ surf->isl.alignment);<br>
}<br>
<br>
<br>
@@ -194,11 +202,12 @@ all_formats_ccs_e_compatible(<wbr>const struct gen_device_info *devinfo,<br>
*/<br>
static void<br>
add_fast_clear_state_buffer(<wbr>struct anv_image *image,<br>
+ uint32_t plane,<br>
const struct anv_device *device)<br>
{<br>
assert(image && device);<br>
- assert(image->aux_surface.isl.<wbr>size > 0 &&<br>
- image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);<br>
+ assert(image->planes[plane].<wbr>aux_surface.isl.size > 0 &&<br>
+ image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT)<wbr>;<br>
<br>
/* The offset to the buffer of clear values must be dword-aligned for GPU<br>
* memcpy operations. It is located immediately after the auxiliary surface.<br>
@@ -212,18 +221,31 @@ add_fast_clear_state_buffer(<wbr>struct anv_image *image,<br>
/* Auxiliary buffers should be a multiple of 4K, so the start of the clear<br>
* values buffer should already be dword-aligned.<br>
*/<br>
- assert(image->aux_surface.isl.<wbr>size % 4 == 0);<br>
+ assert((image->planes[plane].<wbr>offset + image->planes[plane].size) % 4 == 0);<br>
<br>
- /* This buffer should be at the very end of the image. */<br>
- assert(image->size ==<br>
- image->aux_surface.offset + image->aux_surface.isl.size);<br>
+ /* This buffer should be at the very end of the plane. */<br>
+ if (image->disjoint) {<br>
+ assert(image->planes[plane].<wbr>size ==<br>
+ (image->planes[plane].offset + image->planes[plane].size));<br>
+ } else {<br>
+ assert(image->size ==<br>
+ (image->planes[plane].offset + image->planes[plane].size));<br>
+ }<br>
<br>
const unsigned entry_size = anv_fast_clear_state_entry_<wbr>size(device);<br>
/* There's no padding between entries, so ensure that they're always a<br>
* multiple of 32 bits in order to enable GPU memcpy operations.<br>
*/<br>
assert(entry_size % 4 == 0);<br>
- image->size += entry_size * anv_image_aux_levels(image);<br>
+<br>
+ const unsigned plane_state_size =<br>
+ entry_size * anv_image_aux_levels(image, plane);<br>
+<br>
+ image->planes[plane].fast_<wbr>clear_state_offset =<br>
+ image->planes[plane].offset + image->planes[plane].size;<br>
+<br>
+ image->planes[plane].size += plane_state_size;<br>
+ image->size += plane_state_size;<br>
}<br>
<br>
/**<br>
@@ -259,15 +281,13 @@ make_surface(const struct anv_device *dev,<br>
<br>
assert(tiling_flags);<br>
<br>
- struct anv_surface *anv_surf = get_surface(image, aspect);<br>
-<br>
image->extent = anv_sanitize_image_extent(vk_<wbr>info->imageType,<br>
vk_info->extent);<br>
<br>
- enum isl_format format =<br>
- anv_get_isl_plane_format(&dev-<wbr>>info, vk_info->format,<br>
- aspect, vk_info->tiling);<br>
- assert(format != ISL_FORMAT_UNSUPPORTED);<br>
+ const unsigned plane = anv_image_aspect_to_plane(<wbr>image->aspects, aspect);<br>
+ const struct anv_format_plane plane_format =<br>
+ anv_get_plane_format(&dev-><wbr>info, image->vk_format, aspect, image->tiling);<br>
+ struct anv_surface *anv_surf = &image->planes[plane].surface;<br>
<br>
/* If an image is created as BLOCK_TEXEL_VIEW_COMPATIBLE, then we need to<br>
* fall back to linear on Broadwell and earlier because we aren't<br>
@@ -279,16 +299,16 @@ make_surface(const struct anv_device *dev,<br>
if (dev->info.gen <= 8 &&<br>
(vk_info->flags & VK_IMAGE_CREATE_BLOCK_TEXEL_<wbr>VIEW_COMPATIBLE_BIT_KHR) &&<br>
vk_info->tiling == VK_IMAGE_TILING_OPTIMAL) {<br>
- assert(isl_format_is_<wbr>compressed(format));<br>
+ assert(isl_format_is_<wbr>compressed(plane_format.isl_<wbr>format));<br>
tiling_flags = ISL_TILING_LINEAR_BIT;<br>
needs_shadow = true;<br>
}<br>
<br>
ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl,<br>
.dim = vk_to_isl_surf_dim[vk_info-><wbr>imageType],<br>
- .format = format,<br>
- .width = image->extent.width,<br>
- .height = image->extent.height,<br>
+ .format = plane_format.isl_format,<br>
+ .width = image->extent.width / plane_format.denominator_<wbr>scales[0],<br>
+ .height = image->extent.height / plane_format.denominator_<wbr>scales[1],<br>
.depth = image->extent.depth,<br>
.levels = vk_info->mipLevels,<br>
.array_len = vk_info->arrayLayers,<br>
@@ -303,7 +323,18 @@ make_surface(const struct anv_device *dev,<br>
*/<br>
assert(ok);<br>
<br>
- add_surface(image, anv_surf);<br>
+ image->planes[plane].aux_usage = ISL_AUX_USAGE_NONE;<br>
+<br>
+ if (!image->disjoint) {<br>
+ /* With non disjoint planes, align the plane to its surface alignment.<br>
+ */<br>
+ uint32_t previous_plane_size = plane == 0 ? 0 :<br>
+ (image->planes[plane - 1].offset + image->planes[plane - 1].size);<br>
+ image->planes[plane].offset = align_u32(previous_plane_size,<br>
+ anv_surf->isl.alignment);<br>
+ }<br></blockquote><div><br></div><div>(A) add_surface already does this for us as far as I can tell.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+ add_surface(image, anv_surf, plane);<br>
<br>
/* If an image is created as BLOCK_TEXEL_VIEW_COMPATIBLE, then we need to<br>
* create an identical tiled shadow surface for use while texturing so we<br>
@@ -313,9 +344,9 @@ make_surface(const struct anv_device *dev,<br>
assert(aspect == VK_IMAGE_ASPECT_COLOR_BIT);<br>
assert(tiling_flags == ISL_TILING_LINEAR_BIT);<br>
<br>
- ok = isl_surf_init(&dev->isl_dev, &image->shadow_surface.isl,<br>
+ ok = isl_surf_init(&dev->isl_dev, &image->planes[plane].shadow_<wbr>surface.isl,<br>
.dim = vk_to_isl_surf_dim[vk_info-><wbr>imageType],<br>
- .format = format,<br>
+ .format = plane_format.isl_format,<br>
.width = image->extent.width,<br>
.height = image->extent.height,<br>
.depth = image->extent.depth,<br>
@@ -332,7 +363,7 @@ make_surface(const struct anv_device *dev,<br>
*/<br>
assert(ok);<br>
<br>
- add_surface(image, &image->shadow_surface);<br>
+ add_surface(image, &image->planes[plane].shadow_<wbr>surface, plane);<br>
}<br>
<br>
/* Add a HiZ surface to a depth buffer that will be used for rendering.<br>
@@ -358,24 +389,43 @@ make_surface(const struct anv_device *dev,<br>
} else if (dev->info.gen == 8 && vk_info->samples > 1) {<br>
anv_perf_warn(dev->instance, image, "Enable gen8 multisampled HiZ");<br>
} else if (!unlikely(INTEL_DEBUG & DEBUG_NO_HIZ)) {<br>
- assert(image->aux_surface.isl.<wbr>size == 0);<br>
- ok = isl_surf_get_hiz_surf(&dev-><wbr>isl_dev, &image->depth_surface.isl,<br>
- &image->aux_surface.isl);<br>
+ assert(image->planes[plane].<wbr>aux_surface.isl.size == 0);<br>
+ ok = isl_surf_get_hiz_surf(&dev-><wbr>isl_dev,<br>
+ &image->planes[plane].surface.<wbr>isl,<br>
+ &image->planes[plane].aux_<wbr>surface.isl);<br>
assert(ok);<br>
- add_surface(image, &image->aux_surface);<br>
- image->aux_usage = ISL_AUX_USAGE_HIZ;<br>
+ add_surface(image, &image->planes[plane].aux_<wbr>surface, plane);<br>
+ image->planes[plane].aux_usage = ISL_AUX_USAGE_HIZ;<br>
}<br>
- } else if (aspect == VK_IMAGE_ASPECT_COLOR_BIT && vk_info->samples == 1) {<br>
- if (!unlikely(INTEL_DEBUG & DEBUG_NO_RBC)) {<br>
- assert(image->aux_surface.isl.<wbr>size == 0);<br>
- ok = isl_surf_get_ccs_surf(&dev-><wbr>isl_dev, &anv_surf->isl,<br>
- &image->aux_surface.isl, 0);<br>
+ } else if ((aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT) && vk_info->samples == 1) {<br>
+ /* TODO: Allow compression on :<br>
+ *<br>
+ * 1) non multiplanar images (We appear to hit a sampler bug with CCS &<br>
+ * R16G16 format. Putting the clear state a page (4096 bytes)<br>
+ * further fixes the issue.<br></blockquote><div><br></div><div>Did we never get anywhere on this? I know we talked about it and I thought we had it sorted but I don't remember.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+ *<br>
+ * 2) alias images, because they might be aliases of images described<br>
+ * in 1)<br>
+ *<br>
+ * 3) if compression is disabled by debug<br>
+ */<br>
+ const bool allow_compression =<br>
+ image->n_planes == 1 &&<br>
+ (vk_info->flags & VK_IMAGE_CREATE_ALIAS_BIT_KHR) == 0 &&<br>
+ likely((INTEL_DEBUG & DEBUG_NO_RBC) == 0);<br>
+<br>
+ if (allow_compression) {<br>
+ assert(image->planes[plane].<wbr>aux_surface.isl.size == 0);<br>
+ ok = isl_surf_get_ccs_surf(&dev-><wbr>isl_dev,<br>
+ &image->planes[plane].surface.<wbr>isl,<br>
+ &image->planes[plane].aux_<wbr>surface.isl, 0);<br>
if (ok) {<br>
<br>
/* Disable CCS when it is not useful (i.e., when you can't render<br>
* to the image with CCS enabled).<br>
*/<br>
- if (!isl_format_supports_<wbr>rendering(&dev->info, format)) {<br>
+ if (!isl_format_supports_<wbr>rendering(&dev->info,<br>
+ plane_format.isl_format)) {<br>
/* While it may be technically possible to enable CCS for this<br>
* image, we currently don't have things hooked up to get it<br>
* working.<br>
@@ -383,12 +433,12 @@ make_surface(const struct anv_device *dev,<br>
anv_perf_warn(dev->instance, image,<br>
"This image format doesn't support rendering. "<br>
"Not allocating an CCS buffer.");<br>
- image->aux_surface.isl.size = 0;<br>
+ image->planes[plane].aux_<wbr>surface.isl.size = 0;<br>
return VK_SUCCESS;<br>
}<br>
<br>
- add_surface(image, &image->aux_surface);<br>
- add_fast_clear_state_buffer(<wbr>image, dev);<br>
+ add_surface(image, &image->planes[plane].aux_<wbr>surface, plane);<br>
+ add_fast_clear_state_buffer(<wbr>image, plane, dev);<br>
<br>
/* For images created without MUTABLE_FORMAT_BIT set, we know that<br>
* they will always be used with the original format. In<br>
@@ -400,22 +450,42 @@ make_surface(const struct anv_device *dev,<br>
*/<br>
if (!(vk_info->usage & VK_IMAGE_USAGE_STORAGE_BIT) &&<br>
all_formats_ccs_e_compatible(&<wbr>dev->info, vk_info)) {<br>
- image->aux_usage = ISL_AUX_USAGE_CCS_E;<br>
+ image->planes[plane].aux_usage = ISL_AUX_USAGE_CCS_E;<br>
}<br>
}<br>
}<br>
- } else if (aspect == VK_IMAGE_ASPECT_COLOR_BIT && vk_info->samples > 1) {<br>
- assert(image->aux_surface.isl.<wbr>size == 0);<br>
+ } else if ((aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT) && vk_info->samples > 1) {<br>
assert(!(vk_info->usage & VK_IMAGE_USAGE_STORAGE_BIT));<br>
- ok = isl_surf_get_mcs_surf(&dev-><wbr>isl_dev, &anv_surf->isl,<br>
- &image->aux_surface.isl);<br>
+ assert(image->planes[plane].<wbr>aux_surface.isl.size == 0);<br>
+ ok = isl_surf_get_mcs_surf(&dev-><wbr>isl_dev,<br>
+ &image->planes[plane].surface.<wbr>isl,<br>
+ &image->planes[plane].aux_<wbr>surface.isl);<br>
if (ok) {<br>
- add_surface(image, &image->aux_surface);<br>
- add_fast_clear_state_buffer(<wbr>image, dev);<br>
- image->aux_usage = ISL_AUX_USAGE_MCS;<br>
+ add_surface(image, &image->planes[plane].aux_<wbr>surface, plane);<br>
+ add_fast_clear_state_buffer(<wbr>image, plane, dev);<br>
+ image->planes[plane].aux_usage = ISL_AUX_USAGE_MCS;<br>
}<br>
}<br>
<br>
+ assert((image->planes[plane].<wbr>offset + image->planes[plane].size) == image->size);<br>
+<br>
+ /* Upper bound of the last surface should be smaller than the plane's<br>
+ * size.<br>
+ */<br>
+ assert((MAX2(image->planes[<wbr>plane].surface.offset,<br>
+ image->planes[plane].aux_<wbr>surface.offset) +<br>
+ (image->planes[plane].aux_<wbr>surface.isl.size > 0 ?<br>
+ image->planes[plane].aux_<wbr>surface.isl.size :<br>
+ image->planes[plane].surface.<wbr>isl.size)) <=<br>
+ (image->planes[plane].offset + image->planes[plane].size));<br>
+<br>
+ if (image->planes[plane].aux_<wbr>surface.isl.size) {<br>
+ /* assert(image->planes[plane].<wbr>fast_clear_state_offset == */<br>
+ /* (image->planes[plane].aux_<wbr>surface.offset + image->planes[plane].aux_<wbr>surface.isl.size)); */<br>
+ assert(image->planes[plane].<wbr>fast_clear_state_offset <<br>
+ (image->planes[plane].offset + image->planes[plane].size));<br>
+ }<br>
+<br>
return VK_SUCCESS;<br>
}<br>
<br>
@@ -447,13 +517,18 @@ anv_image_create(VkDevice _device,<br>
image->type = pCreateInfo->imageType;<br>
image->extent = pCreateInfo->extent;<br>
image->vk_format = pCreateInfo->format;<br>
+ image->format = anv_get_format(pCreateInfo-><wbr>format);<br>
image->aspects = vk_format_aspects(image->vk_<wbr>format);<br>
image->levels = pCreateInfo->mipLevels;<br>
image->array_size = pCreateInfo->arrayLayers;<br>
image->samples = pCreateInfo->samples;<br>
image->usage = pCreateInfo->usage;<br>
image->tiling = pCreateInfo->tiling;<br>
- image->aux_usage = ISL_AUX_USAGE_NONE;<br>
+<br>
+ const struct anv_format *format = anv_get_format(image->vk_<wbr>format);<br>
+ assert(format != NULL);<br>
+<br>
+ image->n_planes = format->n_planes;<br>
<br>
uint32_t b;<br>
for_each_bit(b, image->aspects) {<br>
@@ -500,37 +575,41 @@ anv_DestroyImage(VkDevice _device, VkImage _image,<br>
vk_free2(&device->alloc, pAllocator, image);<br>
}<br>
<br>
-static void<br>
-anv_bind_image_memory(const VkBindImageMemoryInfoKHR *pBindInfo)<br>
+static VkResult anv_image_bind_memory_plane(<wbr>struct anv_device *device,<br>
+ struct anv_image *image,<br>
+ uint32_t plane,<br>
+ struct anv_device_memory *memory,<br>
+ uint32_t memory_offset)<br>
{<br>
- ANV_FROM_HANDLE(anv_device_<wbr>memory, mem, pBindInfo->memory);<br>
- ANV_FROM_HANDLE(anv_image, image, pBindInfo->image);<br>
-<br>
- assert(pBindInfo->sType == VK_STRUCTURE_TYPE_BIND_IMAGE_<wbr>MEMORY_INFO_KHR);<br>
-<br>
- if (mem == NULL) {<br>
- image->bo = NULL;<br>
- image->offset = 0;<br>
- return;<br>
+ if (memory) {<br>
+ image->planes[plane].bo = memory->bo;<br>
+ image->planes[plane].bo_offset = memory_offset;<br>
+ } else {<br>
+ image->planes[plane].bo = NULL;<br>
+ image->planes[plane].bo_offset = 0;<br>
}<br>
<br>
- image->bo = mem->bo;<br>
- image->offset = pBindInfo->memoryOffset;<br>
+ return VK_SUCCESS;<br>
}<br>
<br>
VkResult anv_BindImageMemory(<br>
- VkDevice device,<br>
- VkImage image,<br>
- VkDeviceMemory memory,<br>
+ VkDevice _device,<br>
+ VkImage _image,<br>
+ VkDeviceMemory _memory,<br>
VkDeviceSize memoryOffset)<br>
{<br>
- anv_bind_image_memory(<br>
- &(VkBindImageMemoryInfoKHR) {<br>
- .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_<wbr>MEMORY_INFO_KHR,<br>
- .image = image,<br>
- .memory = memory,<br>
- .memoryOffset = memoryOffset,<br>
- });<br>
+ ANV_FROM_HANDLE(anv_device, device, _device);<br>
+ ANV_FROM_HANDLE(anv_device_<wbr>memory, mem, _memory);<br>
+ ANV_FROM_HANDLE(anv_image, image, _image);<br>
+<br>
+ uint32_t plane, aspect_bit;<br>
+ anv_foreach_plane_aspect_bit(<wbr>plane, aspect_bit,<br>
+ image->aspects, image->aspects) {<br>
+ VkResult result = anv_image_bind_memory_plane(<wbr>device, image, plane,<br>
+ mem, memoryOffset);<br>
+ if (result != VK_SUCCESS)<br>
+ return vk_error(result);<br>
+ }<br>
<br>
return VK_SUCCESS;<br>
}<br>
@@ -540,10 +619,27 @@ VkResult anv_BindImageMemory2KHR(<br>
uint32_t bindInfoCount,<br>
const VkBindImageMemoryInfoKHR* pBindInfos)<br>
{<br>
- for (uint32_t i = 0; i < bindInfoCount; i++)<br>
- anv_bind_image_memory(&<wbr>pBindInfos[i]);<br>
+ VkResult result = VK_SUCCESS;<br>
<br>
- return VK_SUCCESS;<br>
+ for (uint32_t i = 0; i < bindInfoCount; i++) {<br>
+ const VkBindImageMemoryInfoKHR *bind_info = &pBindInfos[i];<br>
+<br>
+ if (pBindInfos->pNext == NULL) {<br>
+ result = anv_BindImageMemory(device, bind_info->image,<br>
+ bind_info->memory,<br>
+ bind_info->memoryOffset);<br></blockquote><div><br></div><div>This isn't right. We're supposed to ignore extension structs we don't know about. We can't just not bind the memory if pNext != NULL.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+ } else {<br>
+ vk_foreach_struct_const(s, bind_info->pNext) {<br>
+ switch (s->sType) {<br>
+ default:<br>
+ anv_debug_ignored_stype(s-><wbr>sType);<br>
+ break;<br>
+ }<br>
+ }<br>
+ }<br>
+ }<br>
+<br>
+ return result;<br>
}<br>
<br>
static void<br>
@@ -575,22 +671,10 @@ void anv_GetImageSubresourceLayout(<br>
<br>
assert(__builtin_popcount(<wbr>pSubresource->aspectMask) == 1);<br>
<br>
- switch (pSubresource->aspectMask) {<br>
- case VK_IMAGE_ASPECT_COLOR_BIT:<br>
- anv_surface_get_subresource_<wbr>layout(image, &image->color_surface,<br>
- pSubresource, pLayout);<br>
- break;<br>
- case VK_IMAGE_ASPECT_DEPTH_BIT:<br>
- anv_surface_get_subresource_<wbr>layout(image, &image->depth_surface,<br>
- pSubresource, pLayout);<br>
- break;<br>
- case VK_IMAGE_ASPECT_STENCIL_BIT:<br>
- anv_surface_get_subresource_<wbr>layout(image, &image->stencil_surface,<br>
- pSubresource, pLayout);<br>
- break;<br>
- default:<br>
- assert(!"Invalid image aspect");<br>
- }<br>
+ anv_surface_get_subresource_<wbr>layout(image,<br>
+ get_surface(image,<br>
+ pSubresource->aspectMask),<br>
+ pSubresource, pLayout);<br>
}<br>
<br>
/**<br>
@@ -601,7 +685,7 @@ void anv_GetImageSubresourceLayout(<br>
*<br>
* @param devinfo The device information of the Intel GPU.<br>
* @param image The image that may contain a collection of buffers.<br>
- * @param aspects The aspect(s) of the image to be accessed.<br>
+ * @param plane The plane of the image to be accessed.<br>
* @param layout The current layout of the image aspect(s).<br>
*<br>
* @return The primary buffer that should be used for the given layout.<br>
@@ -609,7 +693,7 @@ void anv_GetImageSubresourceLayout(<br>
enum isl_aux_usage<br>
anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,<br>
const struct anv_image * const image,<br>
- const VkImageAspectFlags aspects,<br>
+ const uint32_t plane,<br>
const VkImageLayout layout)<br>
{<br>
/* Validate the inputs. */<br>
@@ -620,35 +704,41 @@ anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,<br>
/* The layout of a NULL image is not properly defined. */<br>
assert(image != NULL);<br>
<br>
- /* The aspects must be a subset of the image aspects. */<br>
- assert(aspects & image->aspects && aspects <= image->aspects);<br>
-<br>
/* Determine the optimal buffer. */<br>
<br>
- /* If there is no auxiliary surface allocated, we must use the one and only<br>
- * main buffer.<br>
+ /* Depth & stencil buffers share the same auxilliary buffer, we need to<br>
+ * process them differently from color buffers.<br>
*/<br>
- if (image->aux_surface.isl.size == 0)<br>
- return ISL_AUX_USAGE_NONE;<br>
+ if (image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT) {<br>
+ /* If there is no auxiliary surface allocated, we must use the one and<br>
+ * only main buffer.<br>
+ */<br>
+ if (image->planes[plane].aux_<wbr>surface.isl.size == 0)<br>
+ return ISL_AUX_USAGE_NONE;<br>
+ } else {<br>
+ /* If there is no auxiliary surface allocated, we must use the one and<br>
+ * only main buffer.<br>
+ */<br>
+ if (image->planes[plane].aux_<wbr>surface.isl.size == 0)<br>
+ return ISL_AUX_USAGE_NONE;<br>
+<br>
+ /* On BDW+, when clearing the stencil aspect of a depth stencil image,<br>
+ * the HiZ buffer allows us to record the clear with a relatively small<br>
+ * number of packets. Prior to BDW, the HiZ buffer provides no known<br>
+ * benefit to the stencil aspect.<br>
+ */<br>
+ if (devinfo->gen < 8 && plane != 0 /* aka stencil */)<br>
+ return ISL_AUX_USAGE_NONE;<br>
+ }<br>
<br>
/* All images that use an auxiliary surface are required to be tiled. */<br>
assert(image->tiling == VK_IMAGE_TILING_OPTIMAL);<br>
<br>
- /* On BDW+, when clearing the stencil aspect of a depth stencil image,<br>
- * the HiZ buffer allows us to record the clear with a relatively small<br>
- * number of packets. Prior to BDW, the HiZ buffer provides no known benefit<br>
- * to the stencil aspect.<br>
- */<br>
- if (devinfo->gen < 8 && aspects == VK_IMAGE_ASPECT_STENCIL_BIT)<br>
- return ISL_AUX_USAGE_NONE;<br>
-<br>
- const bool color_aspect = aspects == VK_IMAGE_ASPECT_COLOR_BIT;<br>
-<br>
/* The following switch currently only handles depth stencil aspects.<br>
* TODO: Handle the color aspect.<br>
*/<br>
- if (color_aspect)<br>
- return image->aux_usage;<br>
+ if (image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT)<br>
+ return image->planes[plane].aux_<wbr>usage;<br>
<br>
switch (layout) {<br>
<br>
@@ -682,17 +772,17 @@ anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,<br>
<br>
/* Sampling Layouts */<br>
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_<wbr>READ_ONLY_OPTIMAL:<br>
- assert(!color_aspect);<br>
+ assert((image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT) == 0);<br>
/* Fall-through */<br>
case VK_IMAGE_LAYOUT_SHADER_READ_<wbr>ONLY_OPTIMAL:<br>
case VK_IMAGE_LAYOUT_DEPTH_READ_<wbr>ONLY_STENCIL_ATTACHMENT_<wbr>OPTIMAL_KHR:<br>
- if (anv_can_sample_with_hiz(<wbr>devinfo, aspects, image->samples))<br>
+ if (anv_can_sample_with_hiz(<wbr>devinfo, image))<br>
return ISL_AUX_USAGE_HIZ;<br>
else<br>
return ISL_AUX_USAGE_NONE;<br>
<br>
case VK_IMAGE_LAYOUT_PRESENT_SRC_<wbr>KHR:<br>
- assert(color_aspect);<br>
+ assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT)<wbr>;<br>
<br>
/* On SKL+, the render buffer can be decompressed by the presentation<br>
* engine. Support for this feature has not yet landed in the wider<br>
@@ -714,12 +804,12 @@ anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,<br>
<br>
/* Rendering Layouts */<br>
case VK_IMAGE_LAYOUT_COLOR_<wbr>ATTACHMENT_OPTIMAL:<br>
- assert(color_aspect);<br>
+ assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT)<wbr>;<br>
unreachable("Color images are not yet supported.");<br>
<br>
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_<wbr>ATTACHMENT_OPTIMAL:<br>
case VK_IMAGE_LAYOUT_DEPTH_<wbr>ATTACHMENT_STENCIL_READ_ONLY_<wbr>OPTIMAL_KHR:<br>
- assert(!color_aspect);<br>
+ assert((image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT) == 0);<br>
return ISL_AUX_USAGE_HIZ;<br>
<br>
case VK_IMAGE_LAYOUT_SHARED_<wbr>PRESENT_KHR:<br>
@@ -761,7 +851,7 @@ remap_swizzle(<wbr>VkComponentSwizzle swizzle, VkComponentSwizzle component,<br>
void<br>
anv_image_fill_surface_state(<wbr>struct anv_device *device,<br>
const struct anv_image *image,<br>
- VkImageAspectFlagBits aspect,<br>
+ uint32_t plane,<br>
const struct isl_view *view_in,<br>
isl_surf_usage_flags_t view_usage,<br>
enum isl_aux_usage aux_usage,<br>
@@ -770,8 +860,8 @@ anv_image_fill_surface_state(<wbr>struct anv_device *device,<br>
struct anv_surface_state *state_inout,<br>
struct brw_image_param *image_param_out)<br>
{<br>
- const struct anv_surface *surface =<br>
- anv_image_get_surface_for_<wbr>aspect_mask(image, aspect);<br>
+ const struct anv_surface *surface = &image->planes[plane].surface,<br>
+ *aux_surface = &image->planes[plane].aux_<wbr>surface;<br>
<br>
struct isl_view view = *view_in;<br>
view.usage |= view_usage;<br>
@@ -781,13 +871,13 @@ anv_image_fill_surface_state(<wbr>struct anv_device *device,<br>
* the primary surface. The shadow surface will be tiled, unlike the main<br>
* surface, so it should get significantly better performance.<br>
*/<br>
- if (image->shadow_surface.isl.<wbr>size > 0 &&<br>
+ if (image->planes[plane].shadow_<wbr>surface.isl.size > 0 &&<br>
isl_format_is_compressed(view.<wbr>format) &&<br>
(flags & ANV_IMAGE_VIEW_STATE_TEXTURE_<wbr>OPTIMAL)) {<br>
assert(isl_format_is_<wbr>compressed(surface->isl.<wbr>format));<br>
assert(surface->isl.tiling == ISL_TILING_LINEAR);<br>
- assert(image->shadow_surface.<wbr>isl.tiling != ISL_TILING_LINEAR);<br>
- surface = &image->shadow_surface;<br>
+ assert(image->planes[plane].<wbr>shadow_surface.isl.tiling != ISL_TILING_LINEAR);<br>
+ surface = &image->planes[plane].shadow_<wbr>surface;<br>
}<br>
<br>
if (view_usage == ISL_SURF_USAGE_RENDER_TARGET_<wbr>BIT)<br>
@@ -802,9 +892,9 @@ anv_image_fill_surface_state(<wbr>struct anv_device *device,<br>
if (!clear_color)<br>
clear_color = &default_clear_color;<br>
<br>
- const uint64_t address = image->offset + surface->offset;<br>
- const uint64_t aux_address = (aux_usage == ISL_AUX_USAGE_NONE) ? 0 :<br>
- image->offset + image->aux_surface.offset;<br>
+ const uint64_t address = image->planes[plane].bo_offset + surface->offset;<br>
+ const uint64_t aux_address = aux_usage == ISL_AUX_USAGE_NONE ?<br>
+ 0 : (image->planes[plane].bo_<wbr>offset + aux_surface->offset);<br>
<br>
if (view_usage == ISL_SURF_USAGE_STORAGE_BIT &&<br>
!(flags & ANV_IMAGE_VIEW_STATE_STORAGE_<wbr>WRITE_ONLY) &&<br>
@@ -893,7 +983,7 @@ anv_image_fill_surface_state(<wbr>struct anv_device *device,<br>
.view = &view,<br>
.address = address + offset_B,<br>
.clear_color = *clear_color,<br>
- .aux_surf = &image->aux_surface.isl,<br>
+ .aux_surf = &aux_surface->isl,<br>
.aux_usage = aux_usage,<br>
.aux_address = aux_address,<br>
.mocs = device->default_mocs,<br>
@@ -924,6 +1014,22 @@ anv_image_fill_surface_state(<wbr>struct anv_device *device,<br>
}<br>
}<br>
<br>
+static VkImageAspectFlags<br>
+remap_aspect_flags(<wbr>VkImageAspectFlags view_aspects)<br>
+{<br>
+ if (view_aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT) {<br>
+ if (_mesa_bitcount(view_aspects) == 1)<br>
+ return VK_IMAGE_ASPECT_COLOR_BIT;<br>
+<br>
+ VkImageAspectFlags color_aspects = 0;<br>
+ for (uint32_t i = 0; i < _mesa_bitcount(view_aspects); i++)<br>
+ color_aspects |= VK_IMAGE_ASPECT_PLANE_0_BIT_<wbr>KHR << i;<br>
+ return color_aspects;<br>
+ }<br>
+ /* No special remapping needed for depth & stencil aspects. */<br>
+ return view_aspects;<br>
+}<br>
+<br>
VkResult<br>
anv_CreateImageView(VkDevice _device,<br>
const VkImageViewCreateInfo *pCreateInfo,<br>
@@ -968,106 +1074,125 @@ anv_CreateImageView(VkDevice _device,<br>
break;<br>
}<br>
<br>
+ /* First expand aspects to the image's ones (for example<br>
+ * VK_IMAGE_ASPECT_COLOR_BIT will be converted to<br>
+ * VK_IMAGE_ASPECT_PLANE_0_BIT_<wbr>KHR | VK_IMAGE_ASPECT_PLANE_1_BIT_<wbr>KHR |<br>
+ * VK_IMAGE_ASPECT_PLANE_2_BIT_<wbr>KHR for an image of format<br>
+ * VK_FORMAT_G8_B8_R8_3PLANE_420_<wbr>UNORM_KHR.<br>
+ */<br>
+ VkImageAspectFlags expanded_aspects =<br>
+ anv_image_color_aspects(image, range->aspectMask);<br>
+<br>
iview->image = image;<br>
<br>
- iview->aspect_mask = pCreateInfo->subresourceRange.<wbr>aspectMask;<br>
+ /* Remap the expanded aspects for the image view. For example if only<br>
+ * VK_IMAGE_ASPECT_PLANE_1_BIT_<wbr>KHR was given in range->aspectMask, we will<br>
+ * convert it to VK_IMAGE_ASPECT_COLOR_BIT since from the point of view of<br>
+ * the image view, it only has a single plane.<br>
+ */<br>
+ iview->aspect_mask = remap_aspect_flags(expanded_<wbr>aspects);<br>
+ iview->n_planes = anv_image_aspect_get_planes(<wbr>iview->aspect_mask);<br>
iview->vk_format = pCreateInfo->format;<br>
<br>
- struct anv_format_plane format =<br>
- anv_get_plane_format(&device-><wbr>info, pCreateInfo->format,<br>
- range->aspectMask == (VK_IMAGE_ASPECT_DEPTH_BIT |<br>
- VK_IMAGE_ASPECT_STENCIL_BIT) ?<br>
- VK_IMAGE_ASPECT_DEPTH_BIT : range->aspectMask,<br>
- image->tiling);<br>
-<br>
- iview->isl = (struct isl_view) {<br>
- .format = format.isl_format,<br>
- .base_level = range->baseMipLevel,<br>
- .levels = anv_get_levelCount(image, range),<br>
- .base_array_layer = range->baseArrayLayer,<br>
- .array_len = anv_get_layerCount(image, range),<br>
- .swizzle = {<br>
- .r = remap_swizzle(pCreateInfo-><wbr>components.r,<br>
- VK_COMPONENT_SWIZZLE_R, format.swizzle),<br>
- .g = remap_swizzle(pCreateInfo-><wbr>components.g,<br>
- VK_COMPONENT_SWIZZLE_G, format.swizzle),<br>
- .b = remap_swizzle(pCreateInfo-><wbr>components.b,<br>
- VK_COMPONENT_SWIZZLE_B, format.swizzle),<br>
- .a = remap_swizzle(pCreateInfo-><wbr>components.a,<br>
- VK_COMPONENT_SWIZZLE_A, format.swizzle),<br>
- },<br>
- };<br>
-<br>
iview->extent = (VkExtent3D) {<br>
.width = anv_minify(image->extent.width , range->baseMipLevel),<br>
.height = anv_minify(image->extent.<wbr>height, range->baseMipLevel),<br>
.depth = anv_minify(image->extent.depth , range->baseMipLevel),<br>
};<br>
<br>
- if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_3D) {<br>
- iview->isl.base_array_layer = 0;<br>
- iview->isl.array_len = iview->extent.depth;<br>
- }<br>
+ /* Now go through the underlying image selected planes (computed in<br>
+ * expanded_aspects) and map them to planes in the image view.<br>
+ */<br>
+ uint32_t iaspect_bit, vplane = 0, iplane;<br>
+ anv_foreach_plane_aspect_bit(<wbr>iplane, iaspect_bit,<br>
+ expanded_aspects, image->aspects) {<br>
+ VkImageAspectFlags vplane_aspect =<br>
+ anv_plane_to_aspect(iview-><wbr>aspect_mask, vplane);<br>
+ struct anv_format_plane format =<br>
+ anv_get_plane_format(&device-><wbr>info, pCreateInfo->format,<br>
+ vplane_aspect, image->tiling);<br>
+<br>
+ iview->planes[vplane].image_<wbr>plane = iplane;<br>
+<br>
+ iview->planes[vplane].isl = (struct isl_view) {<br>
+ .format = format.isl_format,<br>
+ .base_level = range->baseMipLevel,<br>
+ .levels = anv_get_levelCount(image, range),<br>
+ .base_array_layer = range->baseArrayLayer,<br>
+ .array_len = anv_get_layerCount(image, range),<br>
+ .swizzle = {<br>
+ .r = remap_swizzle(pCreateInfo-><wbr>components.r,<br>
+ VK_COMPONENT_SWIZZLE_R, format.swizzle),<br>
+ .g = remap_swizzle(pCreateInfo-><wbr>components.g,<br>
+ VK_COMPONENT_SWIZZLE_G, format.swizzle),<br>
+ .b = remap_swizzle(pCreateInfo-><wbr>components.b,<br>
+ VK_COMPONENT_SWIZZLE_B, format.swizzle),<br>
+ .a = remap_swizzle(pCreateInfo-><wbr>components.a,<br>
+ VK_COMPONENT_SWIZZLE_A, format.swizzle),<br>
+ },<br>
+ };<br>
+<br>
+ if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_3D) {<br>
+ iview->planes[vplane].isl.<wbr>base_array_layer = 0;<br>
+ iview->planes[vplane].isl.<wbr>array_len = iview->extent.depth;<br>
+ }<br>
<br>
- if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE ||<br>
- pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {<br>
- iview->isl.usage = ISL_SURF_USAGE_CUBE_BIT;<br>
- } else {<br>
- iview->isl.usage = 0;<br>
- }<br>
+ if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE ||<br>
+ pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {<br>
+ iview->planes[vplane].isl.<wbr>usage = ISL_SURF_USAGE_CUBE_BIT;<br>
+ } else {<br>
+ iview->planes[vplane].isl.<wbr>usage = 0;<br>
+ }<br>
<br>
- /* Input attachment surfaces for color are allocated and filled<br>
- * out at BeginRenderPass time because they need compression information.<br>
- * Compression is not yet enabled for depth textures and stencil doesn't<br>
- * allow compression so we can just use the texture surface state from the<br>
- * view.<br>
- */<br>
- if (view_usage & VK_IMAGE_USAGE_SAMPLED_BIT ||<br>
- (view_usage & VK_IMAGE_USAGE_INPUT_<wbr>ATTACHMENT_BIT &&<br>
- !(iview->aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT))) {<br>
- iview->optimal_sampler_<wbr>surface_state.state = alloc_surface_state(device);<br>
- iview->general_sampler_<wbr>surface_state.state = alloc_surface_state(device);<br>
-<br>
- enum isl_aux_usage general_aux_usage =<br>
- anv_layout_to_aux_usage(&<wbr>device->info, image, iview->aspect_mask,<br>
- VK_IMAGE_LAYOUT_GENERAL);<br>
- enum isl_aux_usage optimal_aux_usage =<br>
- anv_layout_to_aux_usage(&<wbr>device->info, image, iview->aspect_mask,<br>
- VK_IMAGE_LAYOUT_SHADER_READ_<wbr>ONLY_OPTIMAL);<br>
-<br>
- anv_image_fill_surface_state(<wbr>device, image, iview->aspect_mask,<br>
- &iview->isl, ISL_SURF_USAGE_TEXTURE_BIT,<br>
- optimal_aux_usage, NULL,<br>
- ANV_IMAGE_VIEW_STATE_TEXTURE_<wbr>OPTIMAL,<br>
- &iview->optimal_sampler_<wbr>surface_state,<br>
- NULL);<br>
-<br>
- anv_image_fill_surface_state(<wbr>device, image, iview->aspect_mask,<br>
- &iview->isl, ISL_SURF_USAGE_TEXTURE_BIT,<br>
- general_aux_usage, NULL,<br>
- 0,<br>
- &iview->general_sampler_<wbr>surface_state,<br>
- NULL);<br>
- }<br>
+ if (view_usage & VK_IMAGE_USAGE_SAMPLED_BIT ||<br>
+ (view_usage & VK_IMAGE_USAGE_INPUT_<wbr>ATTACHMENT_BIT &&<br>
+ !(iview->aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT))) {<br>
+ iview->planes[vplane].optimal_<wbr>sampler_surface_state.state = alloc_surface_state(device);<br>
+ iview->planes[vplane].general_<wbr>sampler_surface_state.state = alloc_surface_state(device);<br>
+<br>
+ enum isl_aux_usage general_aux_usage =<br>
+ anv_layout_to_aux_usage(&<wbr>device->info, image, iplane,<br>
+ VK_IMAGE_LAYOUT_GENERAL);<br>
+ enum isl_aux_usage optimal_aux_usage =<br>
+ anv_layout_to_aux_usage(&<wbr>device->info, image, iplane,<br>
+ VK_IMAGE_LAYOUT_SHADER_READ_<wbr>ONLY_OPTIMAL);<br>
+<br>
+ anv_image_fill_surface_state(<wbr>device, image, iplane,<br>
+ &iview->planes[vplane].isl, ISL_SURF_USAGE_TEXTURE_BIT,<br>
+ optimal_aux_usage, NULL,<br>
+ ANV_IMAGE_VIEW_STATE_TEXTURE_<wbr>OPTIMAL,<br>
+ &iview->planes[vplane].<wbr>optimal_sampler_surface_state,<br>
+ NULL);<br>
+<br>
+ anv_image_fill_surface_state(<wbr>device, image, iplane,<br>
+ &iview->planes[vplane].isl, ISL_SURF_USAGE_TEXTURE_BIT,<br>
+ general_aux_usage, NULL,<br>
+ 0,<br>
+ &iview->planes[vplane].<wbr>general_sampler_surface_state,<br>
+ NULL);<br>
+ }<br>
+<br>
+ /* NOTE: This one needs to go last since it may stomp isl_view.format */<br>
+ if (view_usage & VK_IMAGE_USAGE_STORAGE_BIT) {<br>
+ iview->planes[vplane].storage_<wbr>surface_state.state = alloc_surface_state(device);<br>
+ iview->planes[vplane].<wbr>writeonly_storage_surface_<wbr>state.state = alloc_surface_state(device);<br>
+<br>
+ anv_image_fill_surface_state(<wbr>device, image, iplane,<br>
+ &iview->planes[vplane].isl, ISL_SURF_USAGE_STORAGE_BIT,<br>
+ ISL_AUX_USAGE_NONE, NULL,<br>
+ 0,<br>
+ &iview->planes[vplane].<wbr>storage_surface_state,<br>
+ &iview->planes[vplane].<wbr>storage_image_param);<br>
+<br>
+ anv_image_fill_surface_state(<wbr>device, image, iplane,<br>
+ &iview->planes[vplane].isl, ISL_SURF_USAGE_STORAGE_BIT,<br>
+ ISL_AUX_USAGE_NONE, NULL,<br>
+ ANV_IMAGE_VIEW_STATE_STORAGE_<wbr>WRITE_ONLY,<br>
+ &iview->planes[vplane].<wbr>writeonly_storage_surface_<wbr>state,<br>
+ NULL);<br>
+ }<br>
<br>
- /* NOTE: This one needs to go last since it may stomp isl_view.format */<br>
- if (view_usage & VK_IMAGE_USAGE_STORAGE_BIT) {<br>
- iview->storage_surface_state.<wbr>state = alloc_surface_state(device);<br>
- iview->writeonly_storage_<wbr>surface_state.state = alloc_surface_state(device);<br>
-<br>
- anv_image_fill_surface_state(<wbr>device, image, iview->aspect_mask,<br>
- &iview->isl, ISL_SURF_USAGE_STORAGE_BIT,<br>
- ISL_AUX_USAGE_NONE, NULL,<br>
- 0,<br>
- &iview->storage_surface_state,<br>
- &iview->storage_image_param);<br>
-<br>
- anv_image_fill_surface_state(<wbr>device, image, iview->aspect_mask,<br>
- &iview->isl, ISL_SURF_USAGE_STORAGE_BIT,<br>
- ISL_AUX_USAGE_NONE, NULL,<br>
- ANV_IMAGE_VIEW_STATE_STORAGE_<wbr>WRITE_ONLY,<br>
- &iview->writeonly_storage_<wbr>surface_state,<br>
- NULL);<br>
+ vplane++;<br>
}<br>
<br>
*pView = anv_image_view_to_handle(<wbr>iview);<br>
@@ -1085,24 +1210,26 @@ anv_DestroyImageView(VkDevice _device, VkImageView _iview,<br>
if (!iview)<br>
return;<br>
<br>
- if (iview->optimal_sampler_<wbr>surface_state.state.alloc_size > 0) {<br>
- anv_state_pool_free(&device-><wbr>surface_state_pool,<br>
- iview->optimal_sampler_<wbr>surface_state.state);<br>
- }<br>
+ for (uint32_t plane = 0; plane < iview->n_planes; plane++) {<br>
+ if (iview->planes[plane].optimal_<wbr>sampler_surface_state.state.<wbr>alloc_size > 0) {<br>
+ anv_state_pool_free(&device-><wbr>surface_state_pool,<br>
+ iview->planes[plane].optimal_<wbr>sampler_surface_state.state);<br>
+ }<br>
<br>
- if (iview->general_sampler_<wbr>surface_state.state.alloc_size > 0) {<br>
- anv_state_pool_free(&device-><wbr>surface_state_pool,<br>
- iview->general_sampler_<wbr>surface_state.state);<br>
- }<br>
+ if (iview->planes[plane].general_<wbr>sampler_surface_state.state.<wbr>alloc_size > 0) {<br>
+ anv_state_pool_free(&device-><wbr>surface_state_pool,<br>
+ iview->planes[plane].general_<wbr>sampler_surface_state.state);<br>
+ }<br>
<br>
- if (iview->storage_surface_state.<wbr>state.alloc_size > 0) {<br>
- anv_state_pool_free(&device-><wbr>surface_state_pool,<br>
- iview->storage_surface_state.<wbr>state);<br>
- }<br>
+ if (iview->planes[plane].storage_<wbr>surface_state.state.alloc_size > 0) {<br>
+ anv_state_pool_free(&device-><wbr>surface_state_pool,<br>
+ iview->planes[plane].storage_<wbr>surface_state.state);<br>
+ }<br>
<br>
- if (iview->writeonly_storage_<wbr>surface_state.state.alloc_size > 0) {<br>
- anv_state_pool_free(&device-><wbr>surface_state_pool,<br>
- iview->writeonly_storage_<wbr>surface_state.state);<br>
+ if (iview->planes[plane].<wbr>writeonly_storage_surface_<wbr>state.state.alloc_size > 0) {<br>
+ anv_state_pool_free(&device-><wbr>surface_state_pool,<br>
+ iview->planes[plane].<wbr>writeonly_storage_surface_<wbr>state.state);<br>
+ }<br>
}<br>
<br>
vk_free2(&device->alloc, pAllocator, iview);<br>
@@ -1210,16 +1337,21 @@ const struct anv_surface *<br>
anv_image_get_surface_for_<wbr>aspect_mask(const struct anv_image *image,<br>
VkImageAspectFlags aspect_mask)<br>
{<br>
+ VkImageAspectFlags sanitized_mask;<br>
+<br>
switch (aspect_mask) {<br>
case VK_IMAGE_ASPECT_COLOR_BIT:<br>
assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);<br>
- return &image->color_surface;<br>
+ sanitized_mask = VK_IMAGE_ASPECT_COLOR_BIT;<br>
+ break;<br>
case VK_IMAGE_ASPECT_DEPTH_BIT:<br>
assert(image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT);<br>
- return &image->depth_surface;<br>
+ sanitized_mask = VK_IMAGE_ASPECT_DEPTH_BIT;<br>
+ break;<br>
case VK_IMAGE_ASPECT_STENCIL_BIT:<br>
assert(image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT);<br>
- return &image->stencil_surface;<br>
+ sanitized_mask = VK_IMAGE_ASPECT_STENCIL_BIT;<br>
+ break;<br>
case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:<br>
/* FINISHME: The Vulkan spec (git a511ba2) requires support for<br>
* combined depth stencil formats. Specifically, it states:<br>
@@ -1233,13 +1365,29 @@ anv_image_get_surface_for_<wbr>aspect_mask(const struct anv_image *image,<br>
* stencil surfaces from the underlying surface.<br>
*/<br>
if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {<br>
- return &image->depth_surface;<br>
+ sanitized_mask = VK_IMAGE_ASPECT_DEPTH_BIT;<br>
} else {<br>
assert(image->aspects == VK_IMAGE_ASPECT_STENCIL_BIT);<br>
- return &image->stencil_surface;<br>
+ sanitized_mask = VK_IMAGE_ASPECT_STENCIL_BIT;<br>
}<br></blockquote><div><br></div><div>Does this case actually happen? I know it's in there for some reason but I have a feeling that reason is now bogus. If so, then we can get rid of this whole switch mess and replace it all with the two lines you added below.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
- default:<br>
+ break;<br>
+ case VK_IMAGE_ASPECT_PLANE_0_BIT_<wbr>KHR:<br>
+ assert((image->aspects & ~VK_IMAGE_ASPECT_ANY_COLOR_<wbr>BIT) == 0);<br>
+ sanitized_mask = VK_IMAGE_ASPECT_PLANE_0_BIT_<wbr>KHR;<br>
+ break;<br>
+ case VK_IMAGE_ASPECT_PLANE_1_BIT_<wbr>KHR:<br>
+ assert((image->aspects & ~VK_IMAGE_ASPECT_ANY_COLOR_<wbr>BIT) == 0);<br>
+ sanitized_mask = VK_IMAGE_ASPECT_PLANE_1_BIT_<wbr>KHR;<br>
+ break;<br>
+ case VK_IMAGE_ASPECT_PLANE_2_BIT_<wbr>KHR:<br>
+ assert((image->aspects & ~VK_IMAGE_ASPECT_ANY_COLOR_<wbr>BIT) == 0);<br>
+ sanitized_mask = VK_IMAGE_ASPECT_PLANE_2_BIT_<wbr>KHR;<br>
+ break;<br>
+ default:<br>
unreachable("image does not have aspect");<br>
return NULL;<br>
}<br>
+<br>
+ uint32_t plane = anv_image_aspect_to_plane(<wbr>image->aspects, sanitized_mask);<br>
+ return &image->planes[plane].surface;<br>
}<br>
diff --git a/src/intel/vulkan/anv_intel.c b/src/intel/vulkan/anv_intel.c<br>
index 991a93542d2..d4ef3beb743 100644<br>
--- a/src/intel/vulkan/anv_intel.c<br>
+++ b/src/intel/vulkan/anv_intel.c<br>
@@ -80,8 +80,8 @@ VkResult anv_CreateDmaBufImageINTEL(<br>
pAllocator, &image_h);<br>
<br>
image = anv_image_from_handle(image_h)<wbr>;<br>
- image->bo = mem->bo;<br>
- image->offset = 0;<br>
+ image->planes[0].bo = mem->bo;<br>
+ image->planes[0].bo_offset = 0;<br>
<br>
assert(image->extent.width > 0);<br>
assert(image->extent.height > 0);<br>
diff --git a/src/intel/vulkan/anv_<wbr>private.h b/src/intel/vulkan/anv_<wbr>private.h<br>
index 5e14f49b196..cb324a3995e 100644<br>
--- a/src/intel/vulkan/anv_<wbr>private.h<br>
+++ b/src/intel/vulkan/anv_<wbr>private.h<br>
@@ -1566,6 +1566,16 @@ anv_pipe_invalidate_bits_for_<wbr>access_flags(VkAccessFlags flags)<br>
return pipe_bits;<br>
}<br>
<br>
+#define VK_IMAGE_ASPECT_ANY_COLOR_BIT ( \<br>
+ VK_IMAGE_ASPECT_COLOR_BIT | \<br>
+ VK_IMAGE_ASPECT_PLANE_0_BIT_<wbr>KHR | \<br>
+ VK_IMAGE_ASPECT_PLANE_1_BIT_<wbr>KHR | \<br>
+ VK_IMAGE_ASPECT_PLANE_2_BIT_<wbr>KHR)<br>
+#define VK_IMAGE_ASPECT_PLANES_BITS ( \<br>
+ VK_IMAGE_ASPECT_PLANE_0_BIT_<wbr>KHR | \<br>
+ VK_IMAGE_ASPECT_PLANE_1_BIT_<wbr>KHR | \<br>
+ VK_IMAGE_ASPECT_PLANE_2_BIT_<wbr>KHR)<br>
+<br>
struct anv_vertex_binding {<br>
struct anv_buffer * buffer;<br>
VkDeviceSize offset;<br>
@@ -2236,10 +2246,48 @@ anv_image_aspect_to_plane(<wbr>VkImageAspectFlags image_aspects,<br>
case VK_IMAGE_ASPECT_PLANE_2_BIT_<wbr>KHR:<br>
return 2;<br>
default:<br>
+ /* Purposefully assert with depth/stencil aspects. */<br>
unreachable("invalid image aspect");<br>
}<br>
}<br>
<br>
+static inline uint32_t<br>
+anv_image_aspect_get_planes(<wbr>VkImageAspectFlags aspect_mask)<br>
+{<br>
+ uint32_t planes = 0;<br>
+<br>
+ if (aspect_mask & (VK_IMAGE_ASPECT_COLOR_BIT |<br>
+ VK_IMAGE_ASPECT_DEPTH_BIT |<br>
+ VK_IMAGE_ASPECT_STENCIL_BIT |<br>
+ VK_IMAGE_ASPECT_PLANE_0_BIT_<wbr>KHR))<br>
+ planes++;<br>
+ if (aspect_mask & VK_IMAGE_ASPECT_PLANE_1_BIT_<wbr>KHR)<br>
+ planes++;<br>
+ if (aspect_mask & VK_IMAGE_ASPECT_PLANE_2_BIT_<wbr>KHR)<br>
+ planes++;<br>
+<br>
+ return planes;<br>
+}<br>
+<br>
+static inline VkImageAspectFlags<br>
+anv_plane_to_aspect(<wbr>VkImageAspectFlags image_aspects,<br>
+ uint32_t plane)<br>
+{<br>
+ if (image_aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT) {<br>
+ if (_mesa_bitcount(image_aspects) > 1)<br>
+ return VK_IMAGE_ASPECT_PLANE_0_BIT_<wbr>KHR << plane;<br>
+ return VK_IMAGE_ASPECT_COLOR_BIT;<br>
+ }<br>
+ if (image_aspects & VK_IMAGE_ASPECT_DEPTH_BIT)<br>
+ return VK_IMAGE_ASPECT_DEPTH_BIT << plane;<br>
+ assert(image_aspects == VK_IMAGE_ASPECT_STENCIL_BIT);<br>
+ return VK_IMAGE_ASPECT_STENCIL_BIT;<br>
+}<br>
+<br>
+#define anv_foreach_plane_aspect_bit(<wbr>p, b, aspects, image_aspects) \<br>
+ for_each_bit(b, aspects) \<br>
+ for (p = anv_image_aspect_to_plane(<wbr>image_aspects, 1 << b); p != ~0; p = ~0)<br></blockquote><div><br></div><div>Why not something like this:</div><div><br></div><div>VkImageAspectFlags<br></div><div>anv_image_expand_aspects(struct anv_image *image, VkImageAspectFlags aspects)</div><div>{</div><div> if (aspects & VK_IMAGE_ASPECT_COLOR_BIT) {</div><div> assert(aspects == VK_IMAGE_ASPECT_COLOR_BIT);</div><div> if (!(image->aspects & VK_IMAGE_ASPECT_COLOR_BIT) &&</div><div> (image->aspects & VK_IMAGE_ASPECT_PLANE0_BIT)) {</div><div> aspects &= VK_IMAGE_ASPECT_COLOR_BIT;</div><div> aspects |= image->aspects & VK_IMAGE_ASPECT_PLANES_BITS;<br></div><div> }<br></div><div> }</div><div><br></div><div> assert((aspects & image->aspects) == aspects);</div><div> return aspects;<br></div><div>}</div><div><br></div><div>#define anv_image_foreach_aspect(a, image, aspects) \</div><div> for (VkImageAspectFlags _bits = anv_image_expand_aspects(image, aspects), \<br></div><div> a = (1 << (ffs(_bits) - 1)); \<br></div><div> a; \<br></div><div> _bits &= ~a, a = (1 << (ffs(_bits) - 1)))</div><div><br></div><div>I think I got that more-or-less right; I did type it blind. :) Anyway, I think something like that would be much nicer to use. Also, it's not a double loop so break works the way you would expect.<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
const struct anv_format *<br>
anv_get_format(VkFormat format);<br>
<br>
@@ -2300,72 +2348,115 @@ struct anv_image {<br>
* of the actual surface formats.<br>
*/<br>
VkFormat vk_format;<br>
+ const struct anv_format *format;<br>
+<br>
VkImageAspectFlags aspects;<br>
VkExtent3D extent;<br>
uint32_t levels;<br>
uint32_t array_size;<br>
uint32_t samples; /**< VkImageCreateInfo::samples */<br>
+ uint32_t n_planes;<br>
VkImageUsageFlags usage; /**< Superset of VkImageCreateInfo::usage. */<br>
VkImageTiling tiling; /** VkImageCreateInfo::tiling */<br>
<br>
VkDeviceSize size;<br>
uint32_t alignment;<br>
<br>
- /* Set when bound */<br>
- struct anv_bo *bo;<br>
- VkDeviceSize offset;<br>
+ bool disjoint;<br>
<br>
/**<br>
* Image subsurfaces<br>
*<br>
- * For each foo, anv_image::foo_surface is valid if and only if<br>
- * anv_image::aspects has a foo aspect.<br>
+ * For each foo, anv_image::planes[x].surface is valid if and only if<br>
+ * anv_image::aspects has a x aspect. Refer to anv_image_aspect_to_plane()<br>
+ * to figure the number associated with a given aspect.<br>
*<br>
* The hardware requires that the depth buffer and stencil buffer be<br>
* separate surfaces. From Vulkan's perspective, though, depth and stencil<br>
* reside in the same VkImage. To satisfy both the hardware and Vulkan, we<br>
* allocate the depth and stencil buffers as separate surfaces in the same<br>
* bo.<br>
+ *<br>
+ * Memory layout :<br>
+ *<br>
+ * -----------------------<br>
+ * | surface0 | /|\<br>
+ * ----------------------- |<br>
+ * | shadow surface0 | |<br>
+ * ----------------------- | Plane 0<br>
+ * | aux surface0 | |<br>
+ * ----------------------- |<br>
+ * | fast clear colors0 | \|/<br>
+ * -----------------------<br>
+ * | surface1 | /|\<br>
+ * ----------------------- |<br>
+ * | shadow surface1 | |<br>
+ * ----------------------- | Plane 1<br>
+ * | aux surface1 | |<br>
+ * ----------------------- |<br>
+ * | fast clear colors1 | \|/<br>
+ * -----------------------<br>
+ * | ... |<br>
+ * | |<br>
+ * -----------------------<br>
*/<br>
- union {<br>
- struct anv_surface color_surface;<br>
+ struct {<br>
+ /**<br>
+ * Offset of the entire plane (whenever the image is disjoint this is<br>
+ * set to 0).<br>
+ */<br>
+ uint32_t offset;<br>
<br>
- struct {<br>
- struct anv_surface depth_surface;<br>
- struct anv_surface stencil_surface;<br>
- };<br>
- };<br>
+ VkDeviceSize size;<br>
+ uint32_t alignment;<br>
<br>
- /**<br>
- * A surface which shadows the main surface and may have different tiling.<br>
- * This is used for sampling using a tiling that isn't supported for other<br>
- * operations.<br>
- */<br>
- struct anv_surface shadow_surface;<br>
+ struct anv_surface surface;<br>
<br>
- /**<br>
- * For color images, this is the aux usage for this image when not used as a<br>
- * color attachment.<br>
- *<br>
- * For depth/stencil images, this is set to ISL_AUX_USAGE_HIZ if the image<br>
- * has a HiZ buffer.<br>
- */<br>
- enum isl_aux_usage aux_usage;<br>
+ /**<br>
+ * A surface which shadows the main surface and may have different<br>
+ * tiling. This is used for sampling using a tiling that isn't supported<br>
+ * for other operations.<br>
+ */<br>
+ struct anv_surface shadow_surface;<br>
+<br>
+ /**<br>
+ * For color images, this is the aux usage for this image when not used<br>
+ * as a color attachment.<br>
+ *<br>
+ * For depth/stencil images, this is set to ISL_AUX_USAGE_HIZ if the<br>
+ * image has a HiZ buffer.<br>
+ */<br>
+ enum isl_aux_usage aux_usage;<br>
<br>
- struct anv_surface aux_surface;<br>
+ struct anv_surface aux_surface;<br>
+<br>
+ /**<br>
+ * Offset of the fast clear state (used to compute the<br>
+ * fast_clear_state_offset of the following planes).<br>
+ */<br>
+ uint32_t fast_clear_state_offset;<br>
+<br>
+ /**<br>
+ * BO associated with this plane, set when bound.<br>
+ */<br>
+ struct anv_bo *bo;<br>
+ VkDeviceSize bo_offset;<br>
+ } planes[3];<br>
};<br>
<br>
/* Returns the number of auxiliary buffer levels attached to an image. */<br>
static inline uint8_t<br>
-anv_image_aux_levels(const struct anv_image * const image)<br>
+anv_image_aux_levels(const struct anv_image * const image, uint8_t plane)<br>
{<br>
assert(image);<br>
- return image->aux_surface.isl.size > 0 ? image->aux_surface.isl.levels : 0;<br>
+ return image->planes[plane].aux_<wbr>surface.isl.size > 0 ?<br>
+ image->planes[plane].aux_<wbr>surface.isl.levels : 0;<br>
}<br>
<br>
/* Returns the number of auxiliary buffer layers attached to an image. */<br>
static inline uint32_t<br>
anv_image_aux_layers(const struct anv_image * const image,<br>
+ const uint32_t plane,<br>
const uint8_t miplevel)<br>
{<br>
assert(image);<br>
@@ -2373,14 +2464,14 @@ anv_image_aux_layers(const struct anv_image * const image,<br>
/* The miplevel must exist in the main buffer. */<br>
assert(miplevel < image->levels);<br>
<br>
- if (miplevel >= anv_image_aux_levels(image)) {<br>
+ if (miplevel >= anv_image_aux_levels(image, plane)) {<br>
/* There are no layers with auxiliary data because the miplevel has no<br>
* auxiliary data.<br>
*/<br>
return 0;<br>
} else {<br>
- return MAX2(image->aux_surface.isl.<wbr>logical_level0_px.array_len,<br>
- image->aux_surface.isl.<wbr>logical_level0_px.depth >> miplevel);<br>
+ return MAX2(image->planes[plane].aux_<wbr>surface.isl.logical_level0_px.<wbr>array_len,<br>
+ image->planes[plane].aux_<wbr>surface.isl.logical_level0_px.<wbr>depth >> miplevel);<br>
}<br>
}<br>
<br>
@@ -2404,13 +2495,12 @@ anv_fast_clear_state_entry_<wbr>size(const struct anv_device *device)<br>
/* Returns true if a HiZ-enabled depth buffer can be sampled from. */<br>
static inline bool<br>
anv_can_sample_with_hiz(const struct gen_device_info * const devinfo,<br>
- const VkImageAspectFlags aspect_mask,<br>
- const uint32_t samples)<br>
+ const struct anv_image *image)<br>
{<br>
/* Validate the inputs. */<br>
- assert(devinfo && aspect_mask && samples);<br>
- return devinfo->gen >= 8 && (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) &&<br>
- samples == 1;<br>
+ assert(devinfo && image && image->samples);<br>
+ return devinfo->gen >= 8 && (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) &&<br>
+ image->samples == 1;<br>
}<br>
<br>
void<br>
@@ -2421,19 +2511,21 @@ void<br>
anv_ccs_resolve(struct anv_cmd_buffer * const cmd_buffer,<br>
const struct anv_state surface_state,<br>
const struct anv_image * const image,<br>
+ const uint32_t plane,<br>
const uint8_t level, const uint32_t layer_count,<br>
const enum blorp_fast_clear_op op);<br>
<br>
void<br>
anv_image_fast_clear(struct anv_cmd_buffer *cmd_buffer,<br>
const struct anv_image *image,<br>
+ const uint32_t plane,<br>
const uint32_t base_level, const uint32_t level_count,<br>
const uint32_t base_layer, uint32_t layer_count);<br>
<br>
void<br>
anv_image_copy_to_shadow(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
const struct anv_image *image,<br>
- VkImageAspectFlagBits aspect,<br>
+ uint32_t plane,<br></blockquote><div><br></div><div>Why do we need both the plane and the aspect on all these? Just the aspect should be sufficient. This same question applies to a lot of functions in this patch.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
uint32_t base_level, uint32_t level_count,<br>
uint32_t base_layer, uint32_t layer_count);<br>
<br>
@@ -2458,37 +2550,71 @@ anv_get_levelCount(const struct anv_image *image,<br>
image->levels - range->baseMipLevel : range->levelCount;<br>
}<br>
<br>
+static inline VkImageAspectFlags<br>
+anv_image_color_aspects(<wbr>struct anv_image *image, VkImageAspectFlags aspects)<br>
+{<br>
+ /* If the underlying image has color plane aspects and<br>
+ * VK_IMAGE_ASPECT_COLOR_BIT has been requested, then return the aspects of<br>
+ * the underlying image. */<br>
+ if ((image->aspects & VK_IMAGE_ASPECT_PLANES_BITS) != 0 &&<br>
+ aspects == VK_IMAGE_ASPECT_COLOR_BIT)<br>
+ return image->aspects;<br>
+<br>
+ return aspects;<br>
+}<br></blockquote><div><br></div><div>I guess this is basically the expand_aspects function I wrote above.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+static inline bool<br>
+anv_image_aspects_compatible(<wbr>VkImageAspectFlags aspects1,<br>
+ VkImageAspectFlags aspects2)<br>
+{<br>
+ if (aspects1 == aspects2)<br>
+ return true;<br>
+<br>
+ /* Only 1 color aspects are compatibles. */<br>
+ if ((aspects1 & VK_IMAGE_ASPECT_ANY_COLOR_BIT) != 0 &&<br>
+ (aspects2 & VK_IMAGE_ASPECT_ANY_COLOR_BIT) != 0 &&<br>
+ _mesa_bitcount(aspects1) == _mesa_bitcount(aspects2))<br>
+ return true;<br>
+<br>
+ return false;<br>
+}<br>
<br>
struct anv_image_view {<br>
const struct anv_image *image; /**< VkImageViewCreateInfo::image */<br>
<br>
- struct isl_view isl;<br>
-<br>
VkImageAspectFlags aspect_mask;<br>
VkFormat vk_format;<br>
VkExtent3D extent; /**< Extent of VkImageViewCreateInfo::<wbr>baseMipLevel. */<br>
<br>
- /**<br>
- * RENDER_SURFACE_STATE when using image as a sampler surface with an image<br>
- * layout of SHADER_READ_ONLY_OPTIMAL or DEPTH_STENCIL_READ_ONLY_<wbr>OPTIMAL.<br>
- */<br>
- struct anv_surface_state optimal_sampler_surface_state;<br>
+ unsigned n_planes;<br>
+ struct {<br>
+ uint32_t image_plane;<br>
<br>
- /**<br>
- * RENDER_SURFACE_STATE when using image as a sampler surface with an image<br>
- * layout of GENERAL.<br>
- */<br>
- struct anv_surface_state general_sampler_surface_state;<br>
+ struct isl_view isl;<br>
<br>
- /**<br>
- * RENDER_SURFACE_STATE when using image as a storage image. Separate states<br>
- * for write-only and readable, using the real format for write-only and the<br>
- * lowered format for readable.<br>
- */<br>
- struct anv_surface_state storage_surface_state;<br>
- struct anv_surface_state writeonly_storage_surface_<wbr>state;<br>
+ /**<br>
+ * RENDER_SURFACE_STATE when using image as a sampler surface with an<br>
+ * image layout of SHADER_READ_ONLY_OPTIMAL or<br>
+ * DEPTH_STENCIL_READ_ONLY_<wbr>OPTIMAL.<br>
+ */<br>
+ struct anv_surface_state optimal_sampler_surface_state;<br>
<br>
- struct brw_image_param storage_image_param;<br>
+ /**<br>
+ * RENDER_SURFACE_STATE when using image as a sampler surface with an<br>
+ * image layout of GENERAL.<br>
+ */<br>
+ struct anv_surface_state general_sampler_surface_state;<br>
+<br>
+ /**<br>
+ * RENDER_SURFACE_STATE when using image as a storage image. Separate<br>
+ * states for write-only and readable, using the real format for<br>
+ * write-only and the lowered format for readable.<br>
+ */<br>
+ struct anv_surface_state storage_surface_state;<br>
+ struct anv_surface_state writeonly_storage_surface_<wbr>state;<br>
+<br>
+ struct brw_image_param storage_image_param;<br>
+ } planes[3];<br>
};<br>
<br>
enum anv_image_view_state_flags {<br>
@@ -2498,7 +2624,7 @@ enum anv_image_view_state_flags {<br>
<br>
void anv_image_fill_surface_state(<wbr>struct anv_device *device,<br>
const struct anv_image *image,<br>
- VkImageAspectFlagBits aspect,<br>
+ uint32_t plane,<br>
const struct isl_view *view,<br>
isl_surf_usage_flags_t view_usage,<br>
enum isl_aux_usage aux_usage,<br>
diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c<br>
index c3e5dc1870b..3fca076894c 100644<br>
--- a/src/intel/vulkan/anv_wsi.c<br>
+++ b/src/intel/vulkan/anv_wsi.c<br>
@@ -221,7 +221,7 @@ anv_wsi_image_create(VkDevice device_h,<br>
result = anv_AllocateMemory(anv_device_<wbr>to_handle(device),<br>
&(VkMemoryAllocateInfo) {<br>
.sType = VK_STRUCTURE_TYPE_MEMORY_<wbr>ALLOCATE_INFO,<br>
- .allocationSize = image->size,<br>
+ .allocationSize = image->planes[0].surface.isl.<wbr>size,<br>
.memoryTypeIndex = 0,<br>
},<br>
NULL /* XXX: pAllocator */,<br>
@@ -240,7 +240,7 @@ anv_wsi_image_create(VkDevice device_h,<br>
<br>
anv_BindImageMemory(device_h, image_h, memory_h, 0);<br>
<br>
- struct anv_surface *surface = &image->color_surface;<br>
+ struct anv_surface *surface = &image->planes[0].surface;<br>
assert(surface->isl.tiling == ISL_TILING_X);<br>
<br>
*row_pitch = surface->isl.row_pitch;<br>
@@ -266,8 +266,8 @@ anv_wsi_image_create(VkDevice device_h,<br>
*image_p = image_h;<br>
*memory_p = memory_h;<br>
*fd_p = fd;<br>
- *size = image->size;<br>
- *offset = image->offset;<br>
+ *size = image->planes[0].surface.isl.<wbr>size;<br>
+ *offset = image->planes[0].surface.<wbr>offset;<br>
return VK_SUCCESS;<br>
fail_alloc_memory:<br>
anv_FreeMemory(device_h, memory_h, pAllocator);<br>
diff --git a/src/intel/vulkan/gen8_cmd_<wbr>buffer.c b/src/intel/vulkan/gen8_cmd_<wbr>buffer.c<br>
index 7bea231ea76..f19867ca320 100644<br>
--- a/src/intel/vulkan/gen8_cmd_<wbr>buffer.c<br>
+++ b/src/intel/vulkan/gen8_cmd_<wbr>buffer.c<br>
@@ -323,7 +323,7 @@ want_stencil_pma_fix(struct anv_cmd_buffer *cmd_buffer)<br>
/* HiZ is enabled so we had better have a depth buffer with HiZ */<br>
const struct anv_image_view *ds_iview =<br>
anv_cmd_buffer_get_depth_<wbr>stencil_view(cmd_buffer);<br>
- assert(ds_iview && ds_iview->image->aux_usage == ISL_AUX_USAGE_HIZ);<br>
+ assert(ds_iview && ds_iview->image->planes[0].<wbr>aux_usage == ISL_AUX_USAGE_HIZ);<br>
<br>
/* 3DSTATE_PS_EXTRA::<wbr>PixelShaderValid */<br>
struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;<br>
diff --git a/src/intel/vulkan/genX_cmd_<wbr>buffer.c b/src/intel/vulkan/genX_cmd_<wbr>buffer.c<br>
index dc5cf687dc6..71e46acfe4d 100644<br>
--- a/src/intel/vulkan/genX_cmd_<wbr>buffer.c<br>
+++ b/src/intel/vulkan/genX_cmd_<wbr>buffer.c<br>
@@ -181,18 +181,45 @@ add_surface_state_reloc(struct anv_cmd_buffer *cmd_buffer,<br>
static void<br>
add_image_relocs(struct anv_cmd_buffer *cmd_buffer,<br>
const struct anv_image *image,<br>
+ const uint32_t plane,<br>
struct anv_surface_state state)<br>
{<br>
const struct isl_device *isl_dev = &cmd_buffer->device->isl_dev;<br>
<br>
- add_surface_state_reloc(cmd_<wbr>buffer, state.state, image->bo, state.address);<br>
+ add_surface_state_reloc(cmd_<wbr>buffer, state.state,<br>
+ image->planes[plane].bo, state.address);<br>
<br>
if (state.aux_address) {<br>
VkResult result =<br>
anv_reloc_list_add(&cmd_<wbr>buffer->surface_relocs,<br>
&cmd_buffer->pool->alloc,<br>
state.state.offset + isl_dev->ss.aux_addr_offset,<br>
- image->bo, state.aux_address);<br>
+ image->planes[plane].bo,<br>
+ state.aux_address);<br>
+ if (result != VK_SUCCESS)<br>
+ anv_batch_set_error(&cmd_<wbr>buffer->batch, result);<br>
+ }<br>
+}<br>
+<br>
+static void<br>
+add_image_view_relocs(struct anv_cmd_buffer *cmd_buffer,<br>
+ const struct anv_image_view *image_view,<br>
+ const uint32_t plane,<br>
+ struct anv_surface_state state)<br>
+{<br>
+ const struct isl_device *isl_dev = &cmd_buffer->device->isl_dev;<br>
+ const struct anv_image *image = image_view->image;<br>
+ uint32_t image_plane = image_view->planes[plane].<wbr>image_plane;<br>
+<br>
+ add_surface_state_reloc(cmd_<wbr>buffer, state.state,<br>
+ image->planes[image_plane].bo, state.address);<br>
+<br>
+ if (state.aux_address) {<br>
+ VkResult result =<br>
+ anv_reloc_list_add(&cmd_<wbr>buffer->surface_relocs,<br>
+ &cmd_buffer->pool->alloc,<br>
+ state.state.offset + isl_dev->ss.aux_addr_offset,<br>
+ image->planes[image_plane].bo, state.aux_address);<br>
if (result != VK_SUCCESS)<br>
anv_batch_set_error(&cmd_<wbr>buffer->batch, result);<br>
}<br>
@@ -225,8 +252,11 @@ color_attachment_compute_aux_<wbr>usage(struct anv_device * device,<br>
struct anv_attachment_state *att_state = &cmd_state->attachments[att];<br>
struct anv_image_view *iview = cmd_state->framebuffer-><wbr>attachments[att];<br>
<br>
- if (iview->isl.base_array_layer >=<br>
- anv_image_aux_layers(iview-><wbr>image, iview->isl.base_level)) {<br>
+ assert(iview->n_planes == 1);<br>
+<br>
+ if (iview->planes[0].isl.base_<wbr>array_layer >=<br>
+ anv_image_aux_layers(iview-><wbr>image, 0,<br>
+ iview->planes[0].isl.base_<wbr>level)) {<br>
/* There is no aux buffer which corresponds to the level and layer(s)<br>
* being accessed.<br>
*/<br>
@@ -234,12 +264,12 @@ color_attachment_compute_aux_<wbr>usage(struct anv_device * device,<br>
att_state->input_aux_usage = ISL_AUX_USAGE_NONE;<br>
att_state->fast_clear = false;<br>
return;<br>
- } else if (iview->image->aux_usage == ISL_AUX_USAGE_MCS) {<br>
+ } else if (iview->image->planes[0].aux_<wbr>usage == ISL_AUX_USAGE_MCS) {<br>
att_state->aux_usage = ISL_AUX_USAGE_MCS;<br>
att_state->input_aux_usage = ISL_AUX_USAGE_MCS;<br>
att_state->fast_clear = false;<br>
return;<br>
- } else if (iview->image->aux_usage == ISL_AUX_USAGE_CCS_E) {<br>
+ } else if (iview->image->planes[0].aux_<wbr>usage == ISL_AUX_USAGE_CCS_E) {<br>
att_state->aux_usage = ISL_AUX_USAGE_CCS_E;<br>
att_state->input_aux_usage = ISL_AUX_USAGE_CCS_E;<br>
} else {<br>
@@ -255,7 +285,7 @@ color_attachment_compute_aux_<wbr>usage(struct anv_device * device,<br>
* In other words, we can only sample from a fast-cleared image if it<br>
* also supports color compression.<br>
*/<br>
- if (isl_format_supports_ccs_e(&<wbr>device->info, iview->isl.format)) {<br>
+ if (isl_format_supports_ccs_e(&<wbr>device->info, iview->planes[0].isl.format)) {<br>
att_state->input_aux_usage = ISL_AUX_USAGE_CCS_D;<br>
<br>
/* While fast-clear resolves and partial resolves are fairly cheap in the<br>
@@ -274,10 +304,10 @@ color_attachment_compute_aux_<wbr>usage(struct anv_device * device,<br>
}<br>
}<br>
<br>
- assert(iview->image->aux_<wbr>surface.isl.usage & ISL_SURF_USAGE_CCS_BIT);<br>
+ assert(iview->image->planes[0]<wbr>.aux_surface.isl.usage & ISL_SURF_USAGE_CCS_BIT);<br>
<br>
att_state->clear_color_is_<wbr>zero_one =<br>
- color_is_zero_one(att_state-><wbr>clear_value.color, iview->isl.format);<br>
+ color_is_zero_one(att_state-><wbr>clear_value.color, iview->planes[0].isl.format);<br>
att_state->clear_color_is_zero =<br>
att_state->clear_value.color.<wbr>uint32[0] == 0 &&<br>
att_state->clear_value.color.<wbr>uint32[1] == 0 &&<br>
@@ -309,7 +339,8 @@ color_attachment_compute_aux_<wbr>usage(struct anv_device * device,<br>
* layers.<br>
*/<br>
if (cmd_state->framebuffer-><wbr>layers !=<br>
- anv_image_aux_layers(iview-><wbr>image, iview->isl.base_level)) {<br>
+ anv_image_aux_layers(iview-><wbr>image, 0,<br>
+ iview->planes[0].isl.base_<wbr>level)) {<br>
att_state->fast_clear = false;<br>
if (GEN_GEN == 7) {<br>
anv_perf_warn(device-><wbr>instance, iview->image,<br>
@@ -325,7 +356,7 @@ color_attachment_compute_aux_<wbr>usage(struct anv_device * device,<br>
if (cmd_state->pass->attachments[<wbr>att].first_subpass_layout ==<br>
VK_IMAGE_LAYOUT_GENERAL &&<br>
(!att_state->clear_color_is_<wbr>zero ||<br>
- iview->image->aux_usage == ISL_AUX_USAGE_NONE)) {<br>
+ iview->image->planes[0].aux_<wbr>usage == ISL_AUX_USAGE_NONE)) {<br>
att_state->fast_clear = false;<br>
}<br>
<br>
@@ -370,14 +401,14 @@ transition_depth_buffer(struct anv_cmd_buffer *cmd_buffer,<br>
* that's currently in the buffer. Therefore, a data-preserving resolve<br>
* operation is not needed.<br>
*/<br>
- if (image->aux_usage != ISL_AUX_USAGE_HIZ || initial_layout == final_layout)<br>
+ if (image->planes[0].aux_usage != ISL_AUX_USAGE_HIZ || initial_layout == final_layout)<br>
return;<br>
<br>
const bool hiz_enabled = ISL_AUX_USAGE_HIZ ==<br>
- anv_layout_to_aux_usage(&cmd_<wbr>buffer->device->info, image, image->aspects,<br>
+ anv_layout_to_aux_usage(&cmd_<wbr>buffer->device->info, image, 0,<br>
initial_layout);<br>
const bool enable_hiz = ISL_AUX_USAGE_HIZ ==<br>
- anv_layout_to_aux_usage(&cmd_<wbr>buffer->device->info, image, image->aspects,<br>
+ anv_layout_to_aux_usage(&cmd_<wbr>buffer->device->info, image, 0,<br>
final_layout);<br>
<br>
enum blorp_hiz_op hiz_op;<br>
@@ -403,14 +434,16 @@ enum fast_clear_state_field {<br>
static inline uint32_t<br>
get_fast_clear_state_offset(<wbr>const struct anv_device *device,<br>
const struct anv_image *image,<br>
- unsigned level, enum fast_clear_state_field field)<br>
+ unsigned plane, unsigned level,<br>
+ enum fast_clear_state_field field)<br>
{<br>
assert(device && image);<br>
- assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);<br>
- assert(level < anv_image_aux_levels(image));<br>
- uint32_t offset = image->offset + image->aux_surface.offset +<br>
- image->aux_surface.isl.size +<br>
- anv_fast_clear_state_entry_<wbr>size(device) * level;<br>
+ assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT)<wbr>;<br>
+ assert(level < anv_image_aux_levels(image, plane));<br>
+ /* Refer to the definition of anv_image for the memory layout. */<br>
+ uint32_t offset = image->planes[plane].fast_<wbr>clear_state_offset;<br>
+<br>
+ offset += anv_fast_clear_state_entry_<wbr>size(device) * level;<br>
<br>
switch (field) {<br>
case FAST_CLEAR_STATE_FIELD_NEEDS_<wbr>RESOLVE:<br>
@@ -420,7 +453,8 @@ get_fast_clear_state_offset(<wbr>const struct anv_device *device,<br>
break;<br>
}<br>
<br>
- assert(offset < image->offset + image->size);<br>
+ assert(offset < image->planes[plane].surface.<wbr>offset + image->planes[plane].size);<br>
+<br>
return offset;<br>
}<br>
<br>
@@ -433,14 +467,14 @@ get_fast_clear_state_offset(<wbr>const struct anv_device *device,<br>
static void<br>
genX(set_image_needs_resolve)(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
const struct anv_image *image,<br>
- unsigned level, bool needs_resolve)<br>
+ unsigned plane, unsigned level, bool needs_resolve)<br>
{<br>
assert(cmd_buffer && image);<br>
- assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);<br>
- assert(level < anv_image_aux_levels(image));<br>
+ assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT)<wbr>;<br>
+ assert(level < anv_image_aux_levels(image, plane));<br>
<br>
const uint32_t resolve_flag_offset =<br>
- get_fast_clear_state_offset(<wbr>cmd_buffer->device, image, level,<br>
+ get_fast_clear_state_offset(<wbr>cmd_buffer->device, image, plane, level,<br>
FAST_CLEAR_STATE_FIELD_NEEDS_<wbr>RESOLVE);<br>
<br>
/* The HW docs say that there is no way to guarantee the completion of<br>
@@ -448,7 +482,8 @@ genX(set_image_needs_resolve)(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
* issues in testing is currently being used in the GL driver.<br>
*/<br>
anv_batch_emit(&cmd_buffer-><wbr>batch, GENX(MI_STORE_DATA_IMM), sdi) {<br>
- sdi.Address = (struct anv_address) { image->bo, resolve_flag_offset };<br>
+ sdi.Address = (struct anv_address) { image->planes[plane].bo,<br>
+ resolve_flag_offset };<br>
sdi.ImmediateData = needs_resolve;<br>
}<br>
}<br>
@@ -456,14 +491,14 @@ genX(set_image_needs_resolve)(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
static void<br>
genX(load_needs_resolve_<wbr>predicate)(struct anv_cmd_buffer *cmd_buffer,<br>
const struct anv_image *image,<br>
- unsigned level)<br>
+ unsigned plane, unsigned level)<br>
{<br>
assert(cmd_buffer && image);<br>
- assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);<br>
- assert(level < anv_image_aux_levels(image));<br>
+ assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT)<wbr>;<br>
+ assert(level < anv_image_aux_levels(image, plane));<br>
<br>
const uint32_t resolve_flag_offset =<br>
- get_fast_clear_state_offset(<wbr>cmd_buffer->device, image, level,<br>
+ get_fast_clear_state_offset(<wbr>cmd_buffer->device, image, plane, level,<br>
FAST_CLEAR_STATE_FIELD_NEEDS_<wbr>RESOLVE);<br>
<br>
/* Make the pending predicated resolve a no-op if one is not needed.<br>
@@ -473,7 +508,7 @@ genX(load_needs_resolve_<wbr>predicate)(struct anv_cmd_buffer *cmd_buffer,<br>
emit_lri(&cmd_buffer->batch, MI_PREDICATE_SRC1 + 4, 0);<br>
emit_lri(&cmd_buffer->batch, MI_PREDICATE_SRC0 , 0);<br>
emit_lrm(&cmd_buffer->batch, MI_PREDICATE_SRC0 + 4,<br>
- image->bo, resolve_flag_offset);<br>
+ image->planes[plane].bo, resolve_flag_offset);<br>
anv_batch_emit(&cmd_buffer-><wbr>batch, GENX(MI_PREDICATE), mip) {<br>
mip.LoadOperation = LOAD_LOADINV;<br>
mip.CombineOperation = COMBINE_SET;<br>
@@ -484,11 +519,11 @@ genX(load_needs_resolve_<wbr>predicate)(struct anv_cmd_buffer *cmd_buffer,<br>
static void<br>
init_fast_clear_state_entry(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
const struct anv_image *image,<br>
- unsigned level)<br>
+ unsigned plane, unsigned level)<br>
{<br>
assert(cmd_buffer && image);<br>
- assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);<br>
- assert(level < anv_image_aux_levels(image));<br>
+ assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT)<wbr>;<br>
+ assert(level < anv_image_aux_levels(image, plane));<br>
<br>
/* The resolve flag should updated to signify that fast-clear/compression<br>
* data needs to be removed when leaving the undefined layout. Such data<br>
@@ -496,8 +531,8 @@ init_fast_clear_state_entry(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
* to return incorrect data. The fast clear data in CCS_D buffers should<br>
* be removed because CCS_D isn't enabled all the time.<br>
*/<br>
- genX(set_image_needs_resolve)(<wbr>cmd_buffer, image, level,<br>
- image->aux_usage == ISL_AUX_USAGE_NONE);<br>
+ genX(set_image_needs_resolve)(<wbr>cmd_buffer, image, plane, level,<br>
+ image->planes[plane].aux_usage == ISL_AUX_USAGE_NONE);<br>
<br>
/* The fast clear value dword(s) will be copied into a surface state object.<br>
* Ensure that the restrictions of the fields in the dword(s) are followed.<br>
@@ -514,13 +549,14 @@ init_fast_clear_state_entry(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
for (; i < cmd_buffer->device->isl_dev.<wbr>ss.clear_value_size; i += 4) {<br>
anv_batch_emit(&cmd_buffer-><wbr>batch, GENX(MI_STORE_DATA_IMM), sdi) {<br>
const uint32_t entry_offset =<br>
- get_fast_clear_state_offset(<wbr>cmd_buffer->device, image, level,<br>
+ get_fast_clear_state_offset(<wbr>cmd_buffer->device, image, plane, level,<br>
FAST_CLEAR_STATE_FIELD_CLEAR_<wbr>COLOR);<br>
- sdi.Address = (struct anv_address) { image->bo, entry_offset + i };<br>
+ sdi.Address = (struct anv_address) { image->planes[plane].bo,<br>
+ entry_offset + i };<br>
<br>
if (GEN_GEN >= 9) {<br>
/* MCS buffers on SKL+ can only have 1/0 clear colors. */<br>
- assert(image->aux_usage == ISL_AUX_USAGE_MCS);<br>
+ assert(image->planes[plane].<wbr>aux_usage == ISL_AUX_USAGE_MCS);<br>
sdi.ImmediateData = 0;<br>
} else if (GEN_VERSIONx10 >= 75) {<br>
/* Pre-SKL, the dword containing the clear values also contains<br>
@@ -550,28 +586,31 @@ static void<br>
genX(copy_fast_clear_dwords)(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
struct anv_state surface_state,<br>
const struct anv_image *image,<br>
- unsigned level,<br>
+ unsigned plane, unsigned level,<br>
bool copy_from_surface_state)<br>
{<br>
assert(cmd_buffer && image);<br>
- assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);<br>
- assert(level < anv_image_aux_levels(image));<br>
+ assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT)<wbr>;<br>
+ assert(level < anv_image_aux_levels(image, plane));<br>
<br>
struct anv_bo *ss_bo =<br>
&cmd_buffer->device-><a href="http://surface_state_pool.block_pool.bo" rel="noreferrer" target="_blank">surface_<wbr>state_pool.block_pool.bo</a>;<br>
uint32_t ss_clear_offset = surface_state.offset +<br>
cmd_buffer->device->isl_dev.<wbr>ss.clear_value_offset;<br>
uint32_t entry_offset =<br>
- get_fast_clear_state_offset(<wbr>cmd_buffer->device, image, level,<br>
+ get_fast_clear_state_offset(<wbr>cmd_buffer->device, image, plane, level,<br>
FAST_CLEAR_STATE_FIELD_CLEAR_<wbr>COLOR);<br>
unsigned copy_size = cmd_buffer->device->isl_dev.<wbr>ss.clear_value_size;<br>
<br>
if (copy_from_surface_state) {<br>
- genX(cmd_buffer_mi_memcpy)(<wbr>cmd_buffer, image->bo, entry_offset,<br>
+ genX(cmd_buffer_mi_memcpy)(<wbr>cmd_buffer,<br>
+ image->planes[plane].bo,<br>
+ entry_offset,<br>
ss_bo, ss_clear_offset, copy_size);<br>
} else {<br>
genX(cmd_buffer_mi_memcpy)(<wbr>cmd_buffer, ss_bo, ss_clear_offset,<br>
- image->bo, entry_offset, copy_size);<br>
+ image->planes[plane].bo,<br>
+ entry_offset, copy_size);<br>
<br>
/* Updating a surface state object may require that the state cache be<br>
* invalidated. From the SKL PRM, Shared Functions -> State -> State<br>
@@ -603,6 +642,7 @@ genX(copy_fast_clear_dwords)(<wbr>struct anv_cmd_buffer *cmd_buffer,<br>
static void<br>
transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,<br>
const struct anv_image *image,<br>
+ const uint32_t plane,<br>
const uint32_t base_level, uint32_t level_count,<br>
uint32_t base_layer, uint32_t layer_count,<br>
VkImageLayout initial_layout,<br>
@@ -610,7 +650,7 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,<br>
{<br>
/* Validate the inputs. */<br>
assert(cmd_buffer);<br>
- assert(image && image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);<br>
+ assert(image && image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT)<wbr>;<br>
/* These values aren't supported for simplicity's sake. */<br>
assert(level_count != VK_REMAINING_MIP_LEVELS &&<br>
layer_count != VK_REMAINING_ARRAY_LAYERS);<br>
@@ -630,22 +670,22 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,<br>
if (initial_layout == final_layout)<br>
return;<br>
<br>
- if (image->shadow_surface.isl.<wbr>size > 0 &&<br>
+ if (image->planes[plane].shadow_<wbr>surface.isl.size > 0 &&<br>
final_layout == VK_IMAGE_LAYOUT_SHADER_READ_<wbr>ONLY_OPTIMAL) {<br>
/* This surface is a linear compressed image with a tiled shadow surface<br>
* for texturing. The client is about to use it in READ_ONLY_OPTIMAL so<br>
* we need to ensure the shadow copy is up-to-date.<br>
*/<br>
assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);<br>
- assert(image->color_surface.<wbr>isl.tiling == ISL_TILING_LINEAR);<br>
- assert(image->shadow_surface.<wbr>isl.tiling != ISL_TILING_LINEAR);<br>
- assert(isl_format_is_<wbr>compressed(image->color_<wbr>surface.isl.format));<br>
- anv_image_copy_to_shadow(cmd_<wbr>buffer, image, VK_IMAGE_ASPECT_COLOR_BIT,<br>
+ assert(image->planes[plane].<wbr>surface.isl.tiling == ISL_TILING_LINEAR);<br>
+ assert(image->planes[plane].<wbr>shadow_surface.isl.tiling != ISL_TILING_LINEAR);<br>
+ assert(isl_format_is_<wbr>compressed(image->planes[<wbr>plane].surface.isl.format));<br>
+ anv_image_copy_to_shadow(cmd_<wbr>buffer, image, plane,<br>
base_level, level_count,<br>
base_layer, layer_count);<br>
}<br>
<br>
- if (base_layer >= anv_image_aux_layers(image, base_level))<br>
+ if (base_layer >= anv_image_aux_layers(image, plane, base_level))<br>
return;<br>
<br>
/* A transition of a 3D subresource works on all slices at a time. */<br>
@@ -655,9 +695,9 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,<br>
}<br>
<br>
/* We're interested in the subresource range subset that has aux data. */<br>
- level_count = MIN2(level_count, anv_image_aux_levels(image) - base_level);<br>
+ level_count = MIN2(level_count, anv_image_aux_levels(image, plane) - base_level);<br>
layer_count = MIN2(layer_count,<br>
- anv_image_aux_layers(image, base_level) - base_layer);<br>
+ anv_image_aux_layers(image, plane, base_level) - base_layer);<br>
last_level_num = base_level + level_count;<br>
<br>
/* Record whether or not the layout is undefined. Pre-initialized images<br>
@@ -678,7 +718,7 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,<br>
* Initialize the relevant clear buffer entries.<br>
*/<br>
for (unsigned level = base_level; level < last_level_num; level++)<br>
- init_fast_clear_state_entry(<wbr>cmd_buffer, image, level);<br>
+ init_fast_clear_state_entry(<wbr>cmd_buffer, image, plane, level);<br>
<br>
/* Initialize the aux buffers to enable correct rendering. This operation<br>
* requires up to two steps: one to rid the aux buffer of data that may<br>
@@ -702,7 +742,8 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,<br>
"define an MCS buffer.");<br>
}<br>
<br>
- anv_image_fast_clear(cmd_<wbr>buffer, image, base_level, level_count,<br>
+ anv_image_fast_clear(cmd_<wbr>buffer, image, plane,<br>
+ base_level, level_count,<br>
base_layer, layer_count);<br>
}<br>
/* At this point, some elements of the CCS buffer may have the fast-clear<br>
@@ -714,7 +755,8 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,<br>
* enabled. In this case, we must force the associated CCS buffers of the<br>
* specified range to enter the ambiguated state in advance.<br>
*/<br>
- if (image->samples == 1 && image->aux_usage != ISL_AUX_USAGE_CCS_E &&<br>
+ if (image->samples == 1 &&<br>
+ image->planes[plane].aux_usage != ISL_AUX_USAGE_CCS_E &&<br>
final_layout != VK_IMAGE_LAYOUT_COLOR_<wbr>ATTACHMENT_OPTIMAL) {<br>
/* The CCS_D buffer may not be enabled in the final layout. Continue<br>
* executing this function to perform a resolve.<br>
@@ -766,13 +808,14 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,<br>
<br>
/* The number of layers changes at each 3D miplevel. */<br>
if (image->type == VK_IMAGE_TYPE_3D) {<br>
- layer_count = MIN2(layer_count, anv_image_aux_layers(image, level));<br>
+ layer_count = MIN2(layer_count, anv_image_aux_layers(image, plane, level));<br>
}<br>
<br>
- genX(load_needs_resolve_<wbr>predicate)(cmd_buffer, image, level);<br>
+ genX(load_needs_resolve_<wbr>predicate)(cmd_buffer, image, plane, level);<br>
<br>
- enum isl_aux_usage aux_usage = image->aux_usage == ISL_AUX_USAGE_NONE ?<br>
- ISL_AUX_USAGE_CCS_D : image->aux_usage;<br>
+ enum isl_aux_usage aux_usage =<br>
+ image->planes[plane].aux_usage == ISL_AUX_USAGE_NONE ?<br>
+ ISL_AUX_USAGE_CCS_D : image->planes[plane].aux_<wbr>usage;<br>
<br>
/* Create a surface state with the right clear color and perform the<br>
* resolve.<br>
@@ -780,9 +823,9 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,<br>
struct anv_surface_state surface_state;<br>
surface_state.state = anv_cmd_buffer_alloc_surface_<wbr>state(cmd_buffer);<br>
anv_image_fill_surface_state(<wbr>cmd_buffer->device,<br>
- image, VK_IMAGE_ASPECT_COLOR_BIT,<br>
+ image, plane,<br>
&(struct isl_view) {<br>
- .format = image->color_surface.isl.<wbr>format,<br>
+ .format = image->planes[plane].surface.<wbr>isl.format,<br>
.swizzle = ISL_SWIZZLE_IDENTITY,<br>
.base_level = level,<br>
.levels = 1,<br>
@@ -792,16 +835,16 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,<br>
ISL_SURF_USAGE_RENDER_TARGET_<wbr>BIT,<br>
aux_usage, NULL, 0,<br>
&surface_state, NULL);<br>
- add_image_relocs(cmd_buffer, image, surface_state);<br>
+ add_image_relocs(cmd_buffer, image, 0, surface_state);<br>
genX(copy_fast_clear_dwords)(<wbr>cmd_buffer, surface_state.state, image,<br>
- level, false /* copy to ss */);<br>
+ plane, level, false /* copy to ss */);<br>
anv_ccs_resolve(cmd_buffer, surface_state.state, image,<br>
- level, layer_count,<br>
- image->aux_usage == ISL_AUX_USAGE_CCS_E ?<br>
+ plane, level, layer_count,<br>
+ image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E ?<br>
BLORP_FAST_CLEAR_OP_RESOLVE_<wbr>PARTIAL :<br>
BLORP_FAST_CLEAR_OP_RESOLVE_<wbr>FULL);<br>
<br>
- genX(set_image_needs_resolve)(<wbr>cmd_buffer, image, level, false);<br>
+ genX(set_image_needs_resolve)(<wbr>cmd_buffer, image, plane, level, false);<br>
}<br>
<br>
cmd_buffer->state.pending_<wbr>pipe_bits |=<br>
@@ -887,7 +930,7 @@ genX(cmd_buffer_setup_<wbr>attachments)(struct anv_cmd_buffer *cmd_buffer,<br>
VkImageAspectFlags att_aspects = vk_format_aspects(att->format)<wbr>;<br>
VkImageAspectFlags clear_aspects = 0;<br>
<br>
- if (att_aspects == VK_IMAGE_ASPECT_COLOR_BIT) {<br>
+ if (att_aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT) {<br>
/* color attachment */<br>
if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {<br>
clear_aspects |= VK_IMAGE_ASPECT_COLOR_BIT;<br>
@@ -911,17 +954,17 @@ genX(cmd_buffer_setup_<wbr>attachments)(struct anv_cmd_buffer *cmd_buffer,<br>
<br>
struct anv_image_view *iview = framebuffer->attachments[i];<br>
anv_assert(iview->vk_format == att->format);<br>
+ anv_assert(iview->n_planes == 1);<br>
<br>
union isl_color_value clear_color = { .u32 = { 0, } };<br>
- if (att_aspects == VK_IMAGE_ASPECT_COLOR_BIT) {<br>
+ if (att_aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT) {<br>
color_attachment_compute_aux_<wbr>usage(cmd_buffer->device,<br>
state, i, begin->renderArea,<br>
&clear_color);<br>
<br>
anv_image_fill_surface_state(<wbr>cmd_buffer->device,<br>
- iview->image,<br>
- VK_IMAGE_ASPECT_COLOR_BIT,<br>
- &iview->isl,<br>
+ iview->image, 0,<br>
+ &iview->planes[0].isl,<br>
ISL_SURF_USAGE_RENDER_TARGET_<wbr>BIT,<br>
state->attachments[i].aux_<wbr>usage,<br>
&clear_color,<br>
@@ -929,8 +972,8 @@ genX(cmd_buffer_setup_<wbr>attachments)(struct anv_cmd_buffer *cmd_buffer,<br>
&state->attachments[i].color,<br>
NULL);<br>
<br>
- add_image_relocs(cmd_buffer, iview->image,<br>
- state->attachments[i].color);<br>
+ add_image_view_relocs(cmd_<wbr>buffer, iview, 0,<br>
+ state->attachments[i].color);<br>
} else {<br>
/* This field will be initialized after the first subpass<br>
* transition.<br>
@@ -942,9 +985,8 @@ genX(cmd_buffer_setup_<wbr>attachments)(struct anv_cmd_buffer *cmd_buffer,<br>
<br>
if (need_input_attachment_state(&<wbr>pass->attachments[i])) {<br>
anv_image_fill_surface_state(<wbr>cmd_buffer->device,<br>
- iview->image,<br>
- VK_IMAGE_ASPECT_COLOR_BIT,<br>
- &iview->isl,<br>
+ iview->image, 0,<br>
+ &iview->planes[0].isl,<br>
ISL_SURF_USAGE_TEXTURE_BIT,<br>
state->attachments[i].input_<wbr>aux_usage,<br>
&clear_color,<br>
@@ -952,8 +994,8 @@ genX(cmd_buffer_setup_<wbr>attachments)(struct anv_cmd_buffer *cmd_buffer,<br>
&state->attachments[i].input,<br>
NULL);<br>
<br>
- add_image_relocs(cmd_buffer, iview->image,<br>
- state->attachments[i].input);<br>
+ add_image_view_relocs(cmd_<wbr>buffer, iview, 0,<br>
+ state->attachments[i].input);<br>
}<br>
}<br>
}<br>
@@ -1378,14 +1420,21 @@ void genX(CmdPipelineBarrier)(<br>
transition_depth_buffer(cmd_<wbr>buffer, image,<br>
pImageMemoryBarriers[i].<wbr>oldLayout,<br>
pImageMemoryBarriers[i].<wbr>newLayout);<br>
- } else if (range->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {<br>
- transition_color_buffer(cmd_<wbr>buffer, image,<br>
- range->baseMipLevel,<br>
- anv_get_levelCount(image, range),<br>
- range->baseArrayLayer,<br>
- anv_get_layerCount(image, range),<br>
- pImageMemoryBarriers[i].<wbr>oldLayout,<br>
- pImageMemoryBarriers[i].<wbr>newLayout);<br>
+ } else if (range->aspectMask & VK_IMAGE_ASPECT_ANY_COLOR_BIT) {<br>
+ VkImageAspectFlags color_aspects =<br>
+ anv_image_color_aspects(image, range->aspectMask);<br>
+ uint32_t aspect_bit, plane;<br>
+<br>
+ anv_foreach_plane_aspect_bit(<wbr>plane, aspect_bit, color_aspects,<br>
+ image->aspects) {<br>
+ transition_color_buffer(cmd_<wbr>buffer, image, plane,<br>
+ range->baseMipLevel,<br>
+ anv_get_levelCount(image, range),<br>
+ range->baseArrayLayer,<br>
+ anv_get_layerCount(image, range),<br>
+ pImageMemoryBarriers[i].<wbr>oldLayout,<br>
+ pImageMemoryBarriers[i].<wbr>newLayout);<br>
+ }<br>
}<br>
}<br>
<br>
@@ -1574,26 +1623,28 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer,<br>
case VK_DESCRIPTOR_TYPE_SAMPLED_<wbr>IMAGE: {<br>
struct anv_surface_state sstate =<br>
(desc->layout == VK_IMAGE_LAYOUT_GENERAL) ?<br>
- desc->image_view->general_<wbr>sampler_surface_state :<br>
- desc->image_view->optimal_<wbr>sampler_surface_state;<br>
+ desc->image_view->planes[<wbr>binding->plane].general_<wbr>sampler_surface_state :<br>
+ desc->image_view->planes[<wbr>binding->plane].optimal_<wbr>sampler_surface_state;<br>
surface_state = sstate.state;<br>
assert(surface_state.alloc_<wbr>size);<br>
- add_image_relocs(cmd_buffer, desc->image_view->image, sstate);<br>
+ add_image_view_relocs(cmd_<wbr>buffer, desc->image_view,<br>
+ binding->plane, sstate);<br>
break;<br>
}<br>
case VK_DESCRIPTOR_TYPE_INPUT_<wbr>ATTACHMENT:<br>
assert(stage == MESA_SHADER_FRAGMENT);<br>
- if (desc->image_view->aspect_mask != VK_IMAGE_ASPECT_COLOR_BIT) {<br>
+ if ((desc->image_view->aspect_<wbr>mask & VK_IMAGE_ASPECT_ANY_COLOR_BIT) == 0) {<br>
/* For depth and stencil input attachments, we treat it like any<br>
* old texture that a user may have bound.<br>
*/<br>
struct anv_surface_state sstate =<br>
(desc->layout == VK_IMAGE_LAYOUT_GENERAL) ?<br>
- desc->image_view->general_<wbr>sampler_surface_state :<br>
- desc->image_view->optimal_<wbr>sampler_surface_state;<br>
+ desc->image_view->planes[<wbr>binding->plane].general_<wbr>sampler_surface_state :<br>
+ desc->image_view->planes[<wbr>binding->plane].optimal_<wbr>sampler_surface_state;<br>
surface_state = sstate.state;<br>
assert(surface_state.alloc_<wbr>size);<br>
- add_image_relocs(cmd_buffer, desc->image_view->image, sstate);<br>
+ add_image_view_relocs(cmd_<wbr>buffer, desc->image_view,<br>
+ binding->plane, sstate);<br>
} else {<br>
/* For color input attachments, we create the surface state at<br>
* vkBeginRenderPass time so that we can include aux and clear<br>
@@ -1608,16 +1659,17 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer,<br>
<br>
case VK_DESCRIPTOR_TYPE_STORAGE_<wbr>IMAGE: {<br>
struct anv_surface_state sstate = (binding->write_only)<br>
- ? desc->image_view->writeonly_<wbr>storage_surface_state<br>
- : desc->image_view->storage_<wbr>surface_state;<br>
+ ? desc->image_view->planes[<wbr>binding->plane].writeonly_<wbr>storage_surface_state<br>
+ : desc->image_view->planes[<wbr>binding->plane].storage_<wbr>surface_state;<br>
surface_state = sstate.state;<br>
assert(surface_state.alloc_<wbr>size);<br>
- add_image_relocs(cmd_buffer, desc->image_view->image, sstate);<br>
+ add_image_view_relocs(cmd_<wbr>buffer, desc->image_view,<br>
+ binding->plane, sstate);<br>
<br>
struct brw_image_param *image_param =<br>
&cmd_buffer->state.push_<wbr>constants[stage]->images[<wbr>image++];<br>
<br>
- *image_param = desc->image_view->storage_<wbr>image_param;<br>
+ *image_param = desc->image_view->planes[<wbr>binding->plane].storage_image_<wbr>param;<br>
image_param->surface_idx = bias + s;<br>
break;<br>
}<br>
@@ -2753,41 +2805,51 @@ cmd_buffer_emit_depth_stencil(<wbr>struct anv_cmd_buffer *cmd_buffer)<br>
};<br>
<br>
if (iview)<br>
- info.view = &iview->isl;<br>
+ info.view = &iview->planes[0].isl;<br>
<br>
if (image && (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) {<br>
- info.depth_surf = &image->depth_surface.isl;<br>
+ uint32_t depth_plane =<br>
+ anv_image_aspect_to_plane(<wbr>image->aspects, VK_IMAGE_ASPECT_DEPTH_BIT);<br>
+ const struct anv_surface *surface = &image->planes[depth_plane].<wbr>surface;<br>
+<br>
+ info.depth_surf = &surface->isl;<br>
<br>
info.depth_address =<br>
anv_batch_emit_reloc(&cmd_<wbr>buffer->batch,<br>
dw + device->isl_dev.ds.depth_<wbr>offset / 4,<br>
- image->bo,<br>
- image->offset + image->depth_surface.offset);<br>
+ image->planes[depth_plane].bo,<br>
+ image->planes[depth_plane].bo_<wbr>offset +<br>
+ surface->offset);<br>
<br>
const uint32_t ds =<br>
cmd_buffer->state.subpass-><wbr>depth_stencil_attachment.<wbr>attachment;<br>
info.hiz_usage = cmd_buffer->state.attachments[<wbr>ds].aux_usage;<br>
if (info.hiz_usage == ISL_AUX_USAGE_HIZ) {<br>
- info.hiz_surf = &image->aux_surface.isl;<br>
+ info.hiz_surf = &image->planes[depth_plane].<wbr>aux_surface.isl;<br>
<br>
info.hiz_address =<br>
anv_batch_emit_reloc(&cmd_<wbr>buffer->batch,<br>
dw + device->isl_dev.ds.hiz_offset / 4,<br>
- image->bo,<br>
- image->offset + image->aux_surface.offset);<br>
+ image->planes[depth_plane].bo,<br>
+ image->planes[depth_plane].bo_<wbr>offset +<br>
+ image->planes[depth_plane].<wbr>aux_surface.offset);<br>
<br>
info.depth_clear_value = ANV_HZ_FC_VAL;<br>
}<br>
}<br>
<br>
if (image && (image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT)) {<br>
- info.stencil_surf = &image->stencil_surface.isl;<br>
+ uint32_t stencil_plane =<br>
+ anv_image_aspect_to_plane(<wbr>image->aspects, VK_IMAGE_ASPECT_STENCIL_BIT);<br>
+ const struct anv_surface *surface = &image->planes[stencil_plane].<wbr>surface;<br>
+<br>
+ info.stencil_surf = &surface->isl;<br>
<br>
info.stencil_address =<br>
anv_batch_emit_reloc(&cmd_<wbr>buffer->batch,<br>
dw + device->isl_dev.ds.stencil_<wbr>offset / 4,<br>
- image->bo,<br>
- image->offset + image->stencil_surface.offset)<wbr>;<br>
+ image->planes[stencil_plane].<wbr>bo,<br>
+ image->planes[stencil_plane].<wbr>bo_offset + surface->offset);<br>
}<br>
<br>
isl_emit_depth_stencil_hiz_s(&<wbr>device->isl_dev, dw, &info);<br>
@@ -2877,7 +2939,7 @@ cmd_buffer_subpass_transition_<wbr>layouts(struct anv_cmd_buffer * const cmd_buffer,<br>
att_state->input_aux_usage != att_state->aux_usage;<br>
if (subpass_end) {<br>
target_layout = att_desc->final_layout;<br>
- } else if (iview->aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT &&<br>
+ } else if (iview->aspect_mask & VK_IMAGE_ASPECT_ANY_COLOR_BIT &&<br>
!input_needs_resolve) {<br>
/* Layout transitions before the final only help to enable sampling as<br>
* an input attachment. If the input attachment supports sampling<br>
@@ -2895,12 +2957,12 @@ cmd_buffer_subpass_transition_<wbr>layouts(struct anv_cmd_buffer * const cmd_buffer,<br>
att_state->current_layout, target_layout);<br>
att_state->aux_usage =<br>
anv_layout_to_aux_usage(&cmd_<wbr>buffer->device->info, image,<br>
- image->aspects, target_layout);<br>
- } else if (image->aspects == VK_IMAGE_ASPECT_COLOR_BIT) {<br>
- transition_color_buffer(cmd_<wbr>buffer, image,<br>
- iview->isl.base_level, 1,<br>
- iview->isl.base_array_layer,<br>
- iview->isl.array_len,<br>
+ 0, target_layout);<br>
+ } else if (image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT) {<br>
+ transition_color_buffer(cmd_<wbr>buffer, image, 0,<br>
+ iview->planes[0].isl.base_<wbr>level, 1,<br>
+ iview->planes[0].isl.base_<wbr>array_layer,<br>
+ iview->planes[0].isl.array_<wbr>len,<br>
att_state->current_layout, target_layout);<br>
}<br>
<br>
@@ -2945,22 +3007,24 @@ cmd_buffer_subpass_sync_fast_<wbr>clear_values(struct anv_cmd_buffer *cmd_buffer)<br>
if (att_state->pending_clear_<wbr>aspects && att_state->fast_clear) {<br>
/* Update the fast clear state entry. */<br>
genX(copy_fast_clear_dwords)(<wbr>cmd_buffer, att_state->color.state,<br>
- iview->image, iview->isl.base_level,<br>
+ iview->image, 0, iview->planes[0].isl.base_<wbr>level,<br>
true /* copy from ss */);<br>
<br>
/* Fast-clears impact whether or not a resolve will be necessary. */<br>
- if (iview->image->aux_usage == ISL_AUX_USAGE_CCS_E &&<br>
+ if (iview->image->planes[0].aux_<wbr>usage == ISL_AUX_USAGE_CCS_E &&<br>
att_state->clear_color_is_<wbr>zero) {<br>
/* This image always has the auxiliary buffer enabled. We can mark<br>
* the subresource as not needing a resolve because the clear color<br>
* will match what's in every RENDER_SURFACE_STATE object when it's<br>
* being used for sampling.<br>
*/<br>
- genX(set_image_needs_resolve)(<wbr>cmd_buffer, iview->image,<br>
- iview->isl.base_level, false);<br>
+ genX(set_image_needs_resolve)(<wbr>cmd_buffer, iview->image, 0,<br>
+ iview->planes[0].isl.base_<wbr>level,<br>
+ false);<br>
} else {<br>
- genX(set_image_needs_resolve)(<wbr>cmd_buffer, iview->image,<br>
- iview->isl.base_level, true);<br>
+ genX(set_image_needs_resolve)(<wbr>cmd_buffer, iview->image, 0,<br>
+ iview->planes[0].isl.base_<wbr>level,<br>
+ true);<br>
}<br>
} else if (rp_att->load_op == VK_ATTACHMENT_LOAD_OP_LOAD) {<br>
/* The attachment may have been fast-cleared in a previous render<br>
@@ -2969,13 +3033,13 @@ cmd_buffer_subpass_sync_fast_<wbr>clear_values(struct anv_cmd_buffer *cmd_buffer)<br>
* TODO: Do this only once per render pass instead of every subpass.<br>
*/<br>
genX(copy_fast_clear_dwords)(<wbr>cmd_buffer, att_state->color.state,<br>
- iview->image, iview->isl.base_level,<br>
+ iview->image, 0, iview->planes[0].isl.base_<wbr>level,<br>
false /* copy to ss */);<br>
<br>
if (need_input_attachment_state(<wbr>rp_att) &&<br>
att_state->input_aux_usage != ISL_AUX_USAGE_NONE) {<br>
genX(copy_fast_clear_dwords)(<wbr>cmd_buffer, att_state->input.state,<br>
- iview->image, iview->isl.base_level,<br>
+ iview->image, 0, iview->planes[0].isl.base_<wbr>level,<br>
false /* copy to ss */);<br>
}<br>
}<br>
<span class="gmail-HOEnZb"><font color="#888888">--<br>
2.14.2<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>