summaryrefslogtreecommitdiffstats
path: root/src/vulkan/anv_image.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vulkan/anv_image.c')
-rw-r--r--src/vulkan/anv_image.c199
1 files changed, 113 insertions, 86 deletions
diff --git a/src/vulkan/anv_image.c b/src/vulkan/anv_image.c
index 2b3c444428f..3f4d9b15c92 100644
--- a/src/vulkan/anv_image.c
+++ b/src/vulkan/anv_image.c
@@ -45,7 +45,6 @@ static const uint8_t anv_surf_type_from_image_type[] = {
[VK_IMAGE_TYPE_1D] = SURFTYPE_1D,
[VK_IMAGE_TYPE_2D] = SURFTYPE_2D,
[VK_IMAGE_TYPE_3D] = SURFTYPE_3D,
-
};
static const struct anv_image_view_info
@@ -259,6 +258,26 @@ anv_image_make_surface(const struct anv_image_create_info *create_info,
return VK_SUCCESS;
}
+static VkImageUsageFlags
+anv_image_get_full_usage(const VkImageCreateInfo *info)
+{
+ VkImageUsageFlags usage = info->usage;
+
+ if (usage & VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT) {
+ /* Meta will transfer from the image by binding it as a texture. */
+ usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
+ }
+
+ if (usage & VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT) {
+ /* Meta will transfer to the image by binding it as a color attachment,
+ * even if the image format is not a color format.
+ */
+ usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+ }
+
+ return usage;
+}
+
VkResult
anv_image_create(VkDevice _device,
const struct anv_image_create_info *create_info,
@@ -304,19 +323,16 @@ anv_image_create(VkDevice _device,
image->format = anv_format_for_vk_format(pCreateInfo->format);
image->levels = pCreateInfo->mipLevels;
image->array_size = pCreateInfo->arraySize;
- image->usage = pCreateInfo->usage;
- image->surf_type = surf_type;
+ image->usage = anv_image_get_full_usage(pCreateInfo);
+ image->surface_type = surf_type;
- if (pCreateInfo->usage & VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT) {
- /* Meta will transfer from the image by binding it as a texture. */
- image->usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
+ if (image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
+ VK_IMAGE_USAGE_STORAGE_BIT)) {
+ image->needs_nonrt_surface_state = true;
}
- if (pCreateInfo->usage & VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT) {
- /* Meta will transfer to the image by binding it as a color attachment,
- * even if the image format is not a color format.
- */
- image->usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+ if (image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
+ image->needs_color_rt_surface_state = true;
}
if (likely(anv_format_is_color(image->format))) {
@@ -472,9 +488,27 @@ anv_image_view_init(struct anv_image_view *iview,
struct anv_cmd_buffer *cmd_buffer)
{
ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
+ const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
+ assert(range->arraySize > 0);
+ assert(range->baseMipLevel < image->levels);
assert(image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
- VK_IMAGE_USAGE_STORAGE_BIT));
+ VK_IMAGE_USAGE_STORAGE_BIT |
+ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
+ VK_IMAGE_USAGE_DEPTH_STENCIL_BIT));
+
+ switch (image->type) {
+ default:
+ unreachable("bad VkImageType");
+ case VK_IMAGE_TYPE_1D:
+ case VK_IMAGE_TYPE_2D:
+ assert(range->baseArrayLayer + range->arraySize - 1 <= image->array_size);
+ break;
+ case VK_IMAGE_TYPE_3D:
+ assert(range->baseArrayLayer + range->arraySize - 1
+ <= anv_minify(image->extent.depth, range->baseMipLevel));
+ break;
+ }
switch (device->info.gen) {
case 7:
@@ -508,29 +542,30 @@ anv_CreateImageView(VkDevice _device,
return VK_SUCCESS;
}
-void
-anv_DestroyImageView(VkDevice _device, VkImageView _iview)
+static void
+anv_image_view_destroy(struct anv_device *device,
+ struct anv_image_view *iview)
{
- ANV_FROM_HANDLE(anv_device, device, _device);
- ANV_FROM_HANDLE(anv_image_view, iview, _iview);
+ if (iview->image->needs_color_rt_surface_state) {
+ anv_state_pool_free(&device->surface_state_pool,
+ iview->color_rt_surface_state);
+ }
+
+ if (iview->image->needs_nonrt_surface_state) {
+ anv_state_pool_free(&device->surface_state_pool,
+ iview->nonrt_surface_state);
+ }
- anv_state_pool_free(&device->surface_state_pool, iview->surface_state);
anv_device_free(device, iview);
}
-static void
-anv_depth_stencil_view_init(struct anv_image_view *iview,
- const VkAttachmentViewCreateInfo *pCreateInfo)
+void
+anv_DestroyImageView(VkDevice _device, VkImageView _iview)
{
- ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
-
- assert(image->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_BIT);
-
- iview->image = image;
- iview->format = anv_format_for_vk_format(pCreateInfo->format);
+ ANV_FROM_HANDLE(anv_device, device, _device);
+ ANV_FROM_HANDLE(anv_image_view, iview, _iview);
- assert(anv_format_is_depth_or_stencil(image->format));
- assert(anv_format_is_depth_or_stencil(iview->format));
+ anv_image_view_destroy(device, iview);
}
struct anv_surface *
@@ -538,8 +573,22 @@ anv_image_get_surface_for_aspect_mask(struct anv_image *image, VkImageAspectFlag
{
switch (aspect_mask) {
case VK_IMAGE_ASPECT_COLOR_BIT:
- assert(anv_format_is_color(image->format));
- return &image->color_surface;
+ /* Dragons will eat you.
+ *
+ * Meta attaches all destination surfaces as color render targets. Guess
+ * what surface the Meta Dragons really want.
+ */
+ if (image->format->depth_format && image->format->has_stencil) {
+ anv_finishme("combined depth stencil formats");
+ return &image->depth_surface;
+ } else if (image->format->depth_format) {
+ return &image->depth_surface;
+ } else if (image->format->has_stencil) {
+ return &image->stencil_surface;
+ } else {
+ return &image->color_surface;
+ }
+ break;
case VK_IMAGE_ASPECT_DEPTH_BIT:
assert(image->format->depth_format);
return &image->depth_surface;
@@ -562,67 +611,52 @@ anv_image_get_surface_for_aspect_mask(struct anv_image *image, VkImageAspectFlag
}
}
-/** 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_image_view *iview,
- struct anv_device *device,
- const VkAttachmentViewCreateInfo* pCreateInfo,
- struct anv_cmd_buffer *cmd_buffer)
-{
- ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
-
- assert(image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
-
- switch (device->info.gen) {
- case 7:
- gen7_color_attachment_view_init(iview, device, pCreateInfo, cmd_buffer);
- break;
- case 8:
- gen8_color_attachment_view_init(iview, device, pCreateInfo, cmd_buffer);
- break;
- default:
- unreachable("unsupported gen\n");
- }
-}
-
VkResult
anv_CreateAttachmentView(VkDevice _device,
- const VkAttachmentViewCreateInfo *pCreateInfo,
+ const VkAttachmentViewCreateInfo *info,
VkAttachmentView *pView)
{
ANV_FROM_HANDLE(anv_device, device, _device);
struct anv_image_view *iview;
- assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO);
+ assert(info->sType == VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO);
iview = anv_device_alloc(device, sizeof(*iview), 8,
VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
if (iview == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
- const struct anv_format *format =
- anv_format_for_vk_format(pCreateInfo->format);
-
- if (anv_format_is_depth_or_stencil(format)) {
- anv_depth_stencil_view_init(iview, pCreateInfo);
- } else {
- anv_color_attachment_view_init(iview, device, pCreateInfo, NULL);
- }
+ const struct anv_format *format = anv_format_for_vk_format(info->format);
+
+ VkImageAspectFlags aspect_mask = 0;
+ if (format->depth_format)
+ aspect_mask |= VK_IMAGE_ASPECT_DEPTH_BIT;
+ if (format->has_stencil)
+ aspect_mask |= VK_IMAGE_ASPECT_STENCIL_BIT;
+ if (!aspect_mask)
+ aspect_mask |= VK_IMAGE_ASPECT_COLOR_BIT;
+
+ anv_image_view_init(iview, device,
+ &(VkImageViewCreateInfo) {
+ .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+ .image = info->image,
+ .viewType = VK_IMAGE_VIEW_TYPE_2D,
+ .format = info->format,
+ .channels = {
+ .r = VK_CHANNEL_SWIZZLE_R,
+ .g = VK_CHANNEL_SWIZZLE_G,
+ .b = VK_CHANNEL_SWIZZLE_B,
+ .a = VK_CHANNEL_SWIZZLE_A,
+ },
+ .subresourceRange = {
+ .aspectMask = aspect_mask,
+ .baseMipLevel = info->mipLevel,
+ .mipLevels = 1,
+ .baseArrayLayer = info->baseArraySlice,
+ .arraySize = info->arraySize,
+ },
+ },
+ NULL);
pView->handle = anv_image_view_to_handle(iview).handle;
@@ -636,12 +670,5 @@ anv_DestroyAttachmentView(VkDevice _device, VkAttachmentView _aview)
VkImageView _iview = { .handle = _aview.handle };
ANV_FROM_HANDLE(anv_image_view, iview, _iview);
- /* Depth and stencil render targets have no RENDER_SURFACE_STATE. Instead,
- * they use 3DSTATE_DEPTH_BUFFER and 3DSTATE_STENCIL_BUFFER.
- */
- if (!anv_format_is_depth_or_stencil(iview->format)) {
- anv_state_pool_free(&device->surface_state_pool, iview->surface_state);
- }
-
- anv_device_free(device, iview);
+ anv_image_view_destroy(device, iview);
}