From 941b48e992ac2272d3034e987a1313f8f5c1ca4f Mon Sep 17 00:00:00 2001 From: Chad Versace Date: Fri, 28 Aug 2015 07:08:58 -0700 Subject: [PATCH] vk/image: Let anv_image have one anv_surface per aspect Split anv_image::primary_surface into two: anv_image::color_surface and depth_surface. --- src/vulkan/anv_image.c | 82 +++++++++++++++++++++++++++++----------- src/vulkan/anv_private.h | 29 ++++++++++++-- src/vulkan/anv_x11.c | 2 +- src/vulkan/gen7_state.c | 21 ++-------- src/vulkan/gen8_state.c | 21 ++-------- 5 files changed, 94 insertions(+), 61 deletions(-) diff --git a/src/vulkan/anv_image.c b/src/vulkan/anv_image.c index 15a736c25bc..198f4a40212 100644 --- a/src/vulkan/anv_image.c +++ b/src/vulkan/anv_image.c @@ -258,26 +258,28 @@ anv_image_create(VkDevice _device, image->array_size = pCreateInfo->arraySize; image->surf_type = surf_type; - if (likely(!image->format->has_stencil || image->format->depth_format)) { - /* The image's primary surface is a color or depth surface. */ + if (likely(anv_format_is_color(image->format))) { r = anv_image_make_surface(create_info, image->format, &image->size, &image->alignment, - &image->primary_surface); - if (r != VK_SUCCESS) - goto fail; - } - - if (image->format->has_stencil) { - /* From the GPU's perspective, the depth buffer and stencil buffer are - * separate buffers. From Vulkan's perspective, though, depth and - * stencil reside in the same image. To satisfy Vulkan and the GPU, we - * place the depth and stencil buffers in the same bo. - */ - r = anv_image_make_surface(create_info, anv_format_s8_uint, - &image->size, &image->alignment, - &image->stencil_surface); + &image->color_surface); if (r != VK_SUCCESS) goto fail; + } else { + if (image->format->depth_format) { + r = anv_image_make_surface(create_info, image->format, + &image->size, &image->alignment, + &image->depth_surface); + if (r != VK_SUCCESS) + goto fail; + } + + if (image->format->has_stencil) { + r = anv_image_make_surface(create_info, anv_format_s8_uint, + &image->size, &image->alignment, + &image->stencil_surface); + if (r != VK_SUCCESS) + goto fail; + } } *pImage = anv_image_to_handle(image); @@ -462,28 +464,64 @@ anv_depth_stencil_view_init(struct anv_depth_stencil_view *view, const VkAttachmentViewCreateInfo *pCreateInfo) { ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image); - struct anv_surface *depth_surface = &image->primary_surface; - struct anv_surface *stencil_surface = &image->stencil_surface; view->base.attachment_type = ANV_ATTACHMENT_VIEW_TYPE_DEPTH_STENCIL; /* XXX: We don't handle any of these */ + assert(anv_format_is_depth_or_stencil(image->format)); anv_assert(pCreateInfo->mipLevel == 0); anv_assert(pCreateInfo->baseArraySlice == 0); anv_assert(pCreateInfo->arraySize == 1); view->bo = image->bo; - view->depth_stride = depth_surface->stride; - view->depth_offset = image->offset + depth_surface->offset; + view->depth_stride = image->depth_surface.stride; + view->depth_offset = image->offset + image->depth_surface.offset; view->depth_format = image->format->depth_format; view->depth_qpitch = 0; /* FINISHME: QPitch */ - view->stencil_stride = stencil_surface->stride; - view->stencil_offset = image->offset + stencil_surface->offset; + view->stencil_stride = image->stencil_surface.stride; + view->stencil_offset = image->offset + image->stencil_surface.offset; view->stencil_qpitch = 0; /* FINISHME: QPitch */ } +struct anv_surface * +anv_image_get_surface_for_aspect(struct anv_image *image, VkImageAspect aspect) +{ + switch (aspect) { + case VK_IMAGE_ASPECT_COLOR: + assert(anv_format_is_color(image->format)); + return &image->color_surface; + case VK_IMAGE_ASPECT_DEPTH: + assert(image->format->depth_format); + return &image->depth_surface; + case VK_IMAGE_ASPECT_STENCIL: + assert(image->format->has_stencil); + anv_finishme("stencil image views"); + abort(); + return &image->stencil_surface; + default: + unreachable("image does not have aspect"); + return NULL; + } +} + +/** The attachment may be a color view into a non-color image. */ +struct anv_surface * +anv_image_get_surface_for_color_attachment(struct anv_image *image) +{ + if (anv_format_is_color(image->format)) { + return &image->color_surface; + } else if (image->format->depth_format) { + return &image->depth_surface; + } else if (image->format->has_stencil) { + return &image->stencil_surface; + } else { + unreachable("image has bad format"); + return NULL; + } +} + void anv_color_attachment_view_init(struct anv_color_attachment_view *aview, struct anv_device *device, diff --git a/src/vulkan/anv_private.h b/src/vulkan/anv_private.h index 55affd160d9..2d037b4cbb3 100644 --- a/src/vulkan/anv_private.h +++ b/src/vulkan/anv_private.h @@ -1063,11 +1063,26 @@ struct anv_image { /** RENDER_SURFACE_STATE.SurfaceType */ uint8_t surf_type; - /** Primary surface is either color or depth. */ - struct anv_surface primary_surface; + /** + * Image subsurfaces + * + * For each foo, anv_image::foo_surface is valid if and only if + * anv_image::format has a foo aspect. + * + * The hardware requires that the depth buffer and stencil buffer be + * separate surfaces. From Vulkan's perspective, though, depth and stencil + * reside in the same VkImage. To satisfy both the hardware and Vulkan, we + * allocate the depth and stencil buffers as separate surfaces in the same + * bo. + */ + union { + struct anv_surface color_surface; - /** Stencil surface is optional. */ - struct anv_surface stencil_surface; + struct { + struct anv_surface depth_surface; + struct anv_surface stencil_surface; + }; + }; }; struct anv_surface_view { @@ -1128,6 +1143,12 @@ VkResult anv_image_create(VkDevice _device, const struct anv_image_create_info *info, VkImage *pImage); +struct anv_surface * +anv_image_get_surface_for_aspect(struct anv_image *image, VkImageAspect aspect); + +struct anv_surface * +anv_image_get_surface_for_color_attachment(struct anv_image *image); + void anv_image_view_init(struct anv_image_view *view, struct anv_device *device, const VkImageViewCreateInfo* pCreateInfo, diff --git a/src/vulkan/anv_x11.c b/src/vulkan/anv_x11.c index aee5775c9de..f65a86487cb 100644 --- a/src/vulkan/anv_x11.c +++ b/src/vulkan/anv_x11.c @@ -145,7 +145,7 @@ VkResult anv_CreateSwapChainWSI( image = anv_image_from_handle(image_h); assert(anv_format_is_color(image->format)); - surface = &image->primary_surface; + surface = &image->color_surface; anv_AllocMemory(_device, &(VkMemoryAllocInfo) { diff --git a/src/vulkan/gen7_state.c b/src/vulkan/gen7_state.c index 801716ea884..faf99a5aef8 100644 --- a/src/vulkan/gen7_state.c +++ b/src/vulkan/gen7_state.c @@ -273,7 +273,8 @@ gen7_image_view_init(struct anv_image_view *iview, const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange; struct anv_surface_view *view = &iview->view; - struct anv_surface *surface; + struct anv_surface *surface = + anv_image_get_surface_for_aspect(image, range->aspect); const struct anv_format *format = anv_format_for_vk_format(pCreateInfo->format); @@ -284,21 +285,6 @@ gen7_image_view_init(struct anv_image_view *iview, if (pCreateInfo->viewType != VK_IMAGE_VIEW_TYPE_2D) anv_finishme("non-2D image views"); - switch (pCreateInfo->subresourceRange.aspect) { - case VK_IMAGE_ASPECT_STENCIL: - anv_finishme("stencil image views"); - abort(); - break; - case VK_IMAGE_ASPECT_DEPTH: - case VK_IMAGE_ASPECT_COLOR: - view->offset = image->offset; - surface = &image->primary_surface; - break; - default: - unreachable(""); - break; - } - view->bo = image->bo; view->offset = image->offset + surface->offset; view->format = anv_format_for_vk_format(pCreateInfo->format); @@ -381,7 +367,8 @@ gen7_color_attachment_view_init(struct anv_color_attachment_view *aview, { ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image); struct anv_surface_view *view = &aview->view; - struct anv_surface *surface = &image->primary_surface; + struct anv_surface *surface = + anv_image_get_surface_for_color_attachment(image); aview->base.attachment_type = ANV_ATTACHMENT_VIEW_TYPE_COLOR; diff --git a/src/vulkan/gen8_state.c b/src/vulkan/gen8_state.c index 0d65f169231..5e79a37f402 100644 --- a/src/vulkan/gen8_state.c +++ b/src/vulkan/gen8_state.c @@ -149,7 +149,8 @@ gen8_image_view_init(struct anv_image_view *iview, const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange; struct anv_surface_view *view = &iview->view; - struct anv_surface *surface; + struct anv_surface *surface = + anv_image_get_surface_for_aspect(image, range->aspect); const struct anv_format *format_info = anv_format_for_vk_format(pCreateInfo->format); @@ -160,21 +161,6 @@ gen8_image_view_init(struct anv_image_view *iview, if (pCreateInfo->viewType != VK_IMAGE_VIEW_TYPE_2D) anv_finishme("non-2D image views"); - switch (pCreateInfo->subresourceRange.aspect) { - case VK_IMAGE_ASPECT_STENCIL: - anv_finishme("stencil image views"); - abort(); - break; - case VK_IMAGE_ASPECT_DEPTH: - case VK_IMAGE_ASPECT_COLOR: - view->offset = image->offset; - surface = &image->primary_surface; - break; - default: - unreachable(""); - break; - } - view->bo = image->bo; view->offset = image->offset + surface->offset; view->format = format_info; @@ -269,7 +255,8 @@ gen8_color_attachment_view_init(struct anv_color_attachment_view *aview, { ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image); struct anv_surface_view *view = &aview->view; - struct anv_surface *surface = &image->primary_surface; + struct anv_surface *surface = + anv_image_get_surface_for_color_attachment(image); const struct anv_format *format_info = anv_format_for_vk_format(pCreateInfo->format); -- 2.30.2