333 lines
11 KiB
C
333 lines
11 KiB
C
/*
|
|
* Copyright © 2021 Intel Corporation
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice (including the next
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
* Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
* IN THE SOFTWARE.
|
|
*/
|
|
#ifndef VK_IMAGE_H
|
|
#define VK_IMAGE_H
|
|
|
|
#include "vk_object.h"
|
|
|
|
#include "util/u_math.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
struct vk_image {
|
|
struct vk_object_base base;
|
|
|
|
VkImageCreateFlags create_flags;
|
|
VkImageType image_type;
|
|
VkFormat format;
|
|
VkExtent3D extent;
|
|
uint32_t mip_levels;
|
|
uint32_t array_layers;
|
|
VkSampleCountFlagBits samples;
|
|
VkImageTiling tiling;
|
|
VkImageUsageFlags usage;
|
|
|
|
/* Derived from format */
|
|
VkImageAspectFlags aspects;
|
|
|
|
/* VK_EXT_separate_stencil_usage */
|
|
VkImageUsageFlags stencil_usage;
|
|
|
|
/* VK_KHR_external_memory */
|
|
VkExternalMemoryHandleTypeFlags external_handle_types;
|
|
|
|
/* wsi_image_create_info::scanout */
|
|
bool wsi_legacy_scanout;
|
|
|
|
#ifndef _WIN32
|
|
/* VK_EXT_drm_format_modifier
|
|
*
|
|
* Initialized by vk_image_create/init() to DRM_FORMAT_MOD_INVALID. It's
|
|
* the job of the driver to parse the VK_EXT_drm_format_modifier extension
|
|
* structs and choose the actual modifier.
|
|
*
|
|
* Must be DRM_FORMAT_MOD_INVALID unless tiling is
|
|
* VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT.
|
|
*/
|
|
uint64_t drm_format_mod;
|
|
#endif
|
|
|
|
#ifdef ANDROID
|
|
/* VK_ANDROID_external_memory_android_hardware_buffer */
|
|
uint64_t android_external_format;
|
|
#endif
|
|
};
|
|
VK_DEFINE_NONDISP_HANDLE_CASTS(vk_image, base, VkImage,
|
|
VK_OBJECT_TYPE_IMAGE);
|
|
|
|
void vk_image_init(struct vk_device *device,
|
|
struct vk_image *image,
|
|
const VkImageCreateInfo *pCreateInfo);
|
|
void vk_image_finish(struct vk_image *image);
|
|
|
|
void *vk_image_create(struct vk_device *device,
|
|
const VkImageCreateInfo *pCreateInfo,
|
|
const VkAllocationCallbacks *alloc,
|
|
size_t size);
|
|
void vk_image_destroy(struct vk_device *device,
|
|
const VkAllocationCallbacks *alloc,
|
|
struct vk_image *image);
|
|
|
|
void vk_image_set_format(struct vk_image *image, VkFormat format);
|
|
|
|
VkImageUsageFlags vk_image_usage(const struct vk_image *image,
|
|
VkImageAspectFlags aspect_mask);
|
|
|
|
VkImageAspectFlags vk_image_expand_aspect_mask(const struct vk_image *image,
|
|
VkImageAspectFlags aspect_mask);
|
|
|
|
static inline VkExtent3D
|
|
vk_image_mip_level_extent(const struct vk_image *image,
|
|
uint32_t mip_level)
|
|
{
|
|
const VkExtent3D extent = {
|
|
u_minify(image->extent.width, mip_level),
|
|
u_minify(image->extent.height, mip_level),
|
|
u_minify(image->extent.depth, mip_level),
|
|
};
|
|
return extent;
|
|
}
|
|
|
|
/* This is defined as a macro so that it works for both
|
|
* VkImageSubresourceRange and VkImageSubresourceLayers
|
|
*/
|
|
#define vk_image_subresource_layer_count(_image, _range) \
|
|
((_range)->layerCount == VK_REMAINING_ARRAY_LAYERS ? \
|
|
(_image)->array_layers - (_range)->baseArrayLayer : (_range)->layerCount)
|
|
|
|
static inline uint32_t
|
|
vk_image_subresource_level_count(const struct vk_image *image,
|
|
const VkImageSubresourceRange *range)
|
|
{
|
|
return range->levelCount == VK_REMAINING_MIP_LEVELS ?
|
|
image->mip_levels - range->baseMipLevel : range->levelCount;
|
|
}
|
|
|
|
static inline VkExtent3D
|
|
vk_image_sanitize_extent(const struct vk_image *image,
|
|
const VkExtent3D imageExtent)
|
|
{
|
|
switch (image->image_type) {
|
|
case VK_IMAGE_TYPE_1D:
|
|
return (VkExtent3D) { imageExtent.width, 1, 1 };
|
|
case VK_IMAGE_TYPE_2D:
|
|
return (VkExtent3D) { imageExtent.width, imageExtent.height, 1 };
|
|
case VK_IMAGE_TYPE_3D:
|
|
return imageExtent;
|
|
default:
|
|
unreachable("invalid image type");
|
|
}
|
|
}
|
|
|
|
VkExtent3D
|
|
vk_image_extent_to_elements(const struct vk_image *image, VkExtent3D extent);
|
|
|
|
static inline VkOffset3D
|
|
vk_image_sanitize_offset(const struct vk_image *image,
|
|
const VkOffset3D imageOffset)
|
|
{
|
|
switch (image->image_type) {
|
|
case VK_IMAGE_TYPE_1D:
|
|
return (VkOffset3D) { imageOffset.x, 0, 0 };
|
|
case VK_IMAGE_TYPE_2D:
|
|
return (VkOffset3D) { imageOffset.x, imageOffset.y, 0 };
|
|
case VK_IMAGE_TYPE_3D:
|
|
return imageOffset;
|
|
default:
|
|
unreachable("invalid image type");
|
|
}
|
|
}
|
|
|
|
VkOffset3D
|
|
vk_image_offset_to_elements(const struct vk_image *image, VkOffset3D offset);
|
|
|
|
struct vk_image_buffer_layout {
|
|
/**
|
|
* VkBufferImageCopy2::bufferRowLength or
|
|
* VkBufferImageCopy2::extent::width as needed.
|
|
*/
|
|
uint32_t row_length;
|
|
|
|
/**
|
|
* VkBufferImageCopy2::bufferImageHeight or
|
|
* VkBufferImageCopy2::extent::height as needed.
|
|
*/
|
|
uint32_t image_height;
|
|
|
|
/** Size of a single element (pixel or compressed block) in bytes */
|
|
uint32_t element_size_B;
|
|
|
|
/** Row stride in bytes */
|
|
uint32_t row_stride_B;
|
|
|
|
/** Image (or layer) stride in bytes
|
|
*
|
|
* For 1D or 2D array images, this is the stride in bytes between array
|
|
* slices. For 3D images, this is the stride in bytes between fixed-Z
|
|
* slices.
|
|
*/
|
|
uint64_t image_stride_B;
|
|
};
|
|
|
|
struct vk_image_buffer_layout
|
|
vk_image_buffer_copy_layout(const struct vk_image *image,
|
|
const VkBufferImageCopy2* region);
|
|
|
|
struct vk_image_view {
|
|
struct vk_object_base base;
|
|
|
|
VkImageViewCreateFlags create_flags;
|
|
struct vk_image *image;
|
|
VkImageViewType view_type;
|
|
|
|
/** VkImageViewCreateInfo::format */
|
|
VkFormat format;
|
|
|
|
/** Image view format, relative to the selected aspects
|
|
*
|
|
* For a depth/stencil image:
|
|
*
|
|
* - If vk_image_view::aspects contains both depth and stencil, this will
|
|
* be the full depth/stencil format of the image.
|
|
*
|
|
* - If only one aspect is selected, this will be the depth-only or
|
|
* stencil-only format, as per the selected aspect.
|
|
*
|
|
* For color images, we have three cases:
|
|
*
|
|
* 1. It's a single-plane image in which case this is the unmodified
|
|
* format provided to VkImageViewCreateInfo::format.
|
|
*
|
|
* 2. It's a YCbCr view of a multi-plane image in which case the
|
|
* client will have asked for VK_IMAGE_ASPECT_COLOR_BIT and the
|
|
* format provided will be the full planar format. In this case,
|
|
* the format will be the full format containing all the planes.
|
|
*
|
|
* 3. It's a single-plane view of a multi-plane image in which case
|
|
* the client will have asked for VK_IMAGE_ASPECT_PLANE_N_BIT and
|
|
* will have provided a format compatible with that specific
|
|
* plane of the multi-planar format. In this case, the format will be
|
|
* the plane-compatible format requested by the client.
|
|
*/
|
|
VkFormat view_format;
|
|
|
|
/* Component mapping, aka swizzle
|
|
*
|
|
* Unlike the swizzle provided via VkImageViewCreateInfo::components, this
|
|
* will never contain VK_COMPONENT_SWIZZLE_IDENTITY. It will be resolved
|
|
* to VK_COMPONENT_SWIZZLE_R/G/B/A, as appropriate.
|
|
*/
|
|
VkComponentMapping swizzle;
|
|
|
|
/** Aspects from the image represented by this view
|
|
*
|
|
* For depth/stencil images, this is the aspectMask provided by
|
|
* VkImageViewCreateinfo::subresourceRange::aspectMask.
|
|
*
|
|
* For color images, we have three cases:
|
|
*
|
|
* 1. It's a single-plane image in which case this only aspect is
|
|
* VK_IMAGE_ASPECT_COLOR_BIT.
|
|
*
|
|
* 2. It's a YCbCr view of a multi-plane image in which case the
|
|
* client will have asked for VK_IMAGE_ASPECT_COLOR_BIT and the
|
|
* format provided will be the full planar format. In this case,
|
|
* aspects will be the full set of plane aspects in the image.
|
|
*
|
|
* 3. It's a single-plane view of a multi-plane image in which case
|
|
* the client will have asked for VK_IMAGE_ASPECT_PLANE_N_BIT and
|
|
* will have provided a format compatible with that specific
|
|
* plane of the multi-planar format. In this case, aspects will be
|
|
* VK_IMAGE_ASPECT_PLANE_N_BIT where N is the selected plane.
|
|
*
|
|
* This seems almost backwards from the API but ensures that
|
|
* vk_image_view::aspects is always a subset of vk_image::aspects.
|
|
*/
|
|
VkImageAspectFlags aspects;
|
|
|
|
uint32_t base_mip_level;
|
|
uint32_t level_count;
|
|
uint32_t base_array_layer;
|
|
uint32_t layer_count;
|
|
|
|
/* VK_EXT_image_view_min_lod */
|
|
float min_lod;
|
|
|
|
/* Image extent at LOD 0 */
|
|
VkExtent3D extent;
|
|
|
|
/* VK_KHR_maintenance2 */
|
|
VkImageUsageFlags usage;
|
|
};
|
|
VK_DEFINE_NONDISP_HANDLE_CASTS(vk_image_view, base, VkImageView,
|
|
VK_OBJECT_TYPE_IMAGE_VIEW);
|
|
|
|
void vk_image_view_init(struct vk_device *device,
|
|
struct vk_image_view *image_view,
|
|
bool driver_internal,
|
|
const VkImageViewCreateInfo *pCreateInfo);
|
|
void vk_image_view_finish(struct vk_image_view *image_view);
|
|
|
|
void *vk_image_view_create(struct vk_device *device,
|
|
bool driver_internal,
|
|
const VkImageViewCreateInfo *pCreateInfo,
|
|
const VkAllocationCallbacks *alloc,
|
|
size_t size);
|
|
void vk_image_view_destroy(struct vk_device *device,
|
|
const VkAllocationCallbacks *alloc,
|
|
struct vk_image_view *image_view);
|
|
|
|
static inline VkImageSubresourceRange
|
|
vk_image_view_subresource_range(const struct vk_image_view *view)
|
|
{
|
|
VkImageSubresourceRange range = {
|
|
.aspectMask = view->aspects,
|
|
.baseMipLevel = view->base_mip_level,
|
|
.levelCount = view->level_count,
|
|
.baseArrayLayer = view->base_array_layer,
|
|
.layerCount = view->layer_count,
|
|
};
|
|
|
|
return range;
|
|
}
|
|
|
|
bool vk_image_layout_is_read_only(VkImageLayout layout,
|
|
VkImageAspectFlagBits aspect);
|
|
bool vk_image_layout_is_depth_only(VkImageLayout layout);
|
|
|
|
VkImageUsageFlags vk_image_layout_to_usage_flags(VkImageLayout layout,
|
|
VkImageAspectFlagBits aspect);
|
|
|
|
VkImageLayout vk_att_ref_stencil_layout(const VkAttachmentReference2 *att_ref,
|
|
const VkAttachmentDescription2 *attachments);
|
|
VkImageLayout vk_att_desc_stencil_layout(const VkAttachmentDescription2 *att_desc,
|
|
bool final);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* VK_IMAGE_H */
|