zink: hook up planar image format creation
it'll explode if used for anything, but this is how it's done Reviewed-by: Dave Airlie <airlied@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13865>
This commit is contained in:
committed by
Marge Bot
parent
bff042fd43
commit
129e31cd4f
@@ -117,6 +117,7 @@ EXTENSIONS = [
|
||||
features=True,
|
||||
conditions=["$feats.indexTypeUint8"]),
|
||||
Extension("VK_KHR_image_format_list"),
|
||||
Extension("VK_KHR_sampler_ycbcr_conversion"),
|
||||
Extension("VK_KHR_imageless_framebuffer",
|
||||
alias="imgless",
|
||||
features=True,
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#endif
|
||||
#include "vulkan/wsi/wsi_common.h"
|
||||
|
||||
#include "vk_format.h"
|
||||
#include "util/slab.h"
|
||||
#include "util/u_blitter.h"
|
||||
#include "util/u_debug.h"
|
||||
@@ -189,6 +190,11 @@ check_ici(struct zink_screen *screen, VkImageCreateInfo *ici, uint64_t modifier)
|
||||
VkImageFormatProperties2 props2;
|
||||
props2.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
|
||||
props2.pNext = NULL;
|
||||
VkSamplerYcbcrConversionImageFormatProperties ycbcr_props;
|
||||
ycbcr_props.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES;
|
||||
ycbcr_props.pNext = NULL;
|
||||
if (screen->info.have_KHR_sampler_ycbcr_conversion)
|
||||
props2.pNext = &ycbcr_props;
|
||||
VkPhysicalDeviceImageFormatInfo2 info;
|
||||
info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2;
|
||||
info.format = ici->format;
|
||||
@@ -209,6 +215,9 @@ check_ici(struct zink_screen *screen, VkImageCreateInfo *ici, uint64_t modifier)
|
||||
info.pNext = NULL;
|
||||
|
||||
ret = VKSCR(GetPhysicalDeviceImageFormatProperties2)(screen->pdev, &info, &props2);
|
||||
/* this is using VK_IMAGE_CREATE_EXTENDED_USAGE_BIT and can't be validated */
|
||||
if (vk_format_aspects(ici->format) & VK_IMAGE_ASPECT_PLANE_1_BIT)
|
||||
ret = VK_SUCCESS;
|
||||
image_props = props2.imageFormatProperties;
|
||||
} else
|
||||
ret = VKSCR(GetPhysicalDeviceImageFormatProperties)(screen->pdev, ici->format, ici->imageType,
|
||||
@@ -220,18 +229,20 @@ static VkImageUsageFlags
|
||||
get_image_usage_for_feats(struct zink_screen *screen, VkFormatFeatureFlags feats, const struct pipe_resource *templ, unsigned bind)
|
||||
{
|
||||
VkImageUsageFlags usage = 0;
|
||||
bool is_planar = util_format_get_num_planes(templ->format) > 1;
|
||||
|
||||
if (bind & ZINK_BIND_TRANSIENT)
|
||||
usage |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
|
||||
else {
|
||||
/* sadly, gallium doesn't let us know if it'll ever need this, so we have to assume */
|
||||
if (feats & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT)
|
||||
if (is_planar || (feats & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT))
|
||||
usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
if (feats & VK_FORMAT_FEATURE_TRANSFER_DST_BIT)
|
||||
if (is_planar || (feats & VK_FORMAT_FEATURE_TRANSFER_DST_BIT))
|
||||
usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
if (feats & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)
|
||||
usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
|
||||
if ((feats & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) && (bind & PIPE_BIND_SHADER_IMAGE)) {
|
||||
if ((is_planar || (feats & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) && (bind & PIPE_BIND_SHADER_IMAGE)) {
|
||||
assert(templ->nr_samples <= 1 || screen->info.feats.features.shaderStorageImageMultisample);
|
||||
usage |= VK_IMAGE_USAGE_STORAGE_BIT;
|
||||
}
|
||||
@@ -242,7 +253,7 @@ get_image_usage_for_feats(struct zink_screen *screen, VkFormatFeatureFlags feats
|
||||
usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
if ((bind & (PIPE_BIND_LINEAR | PIPE_BIND_SHARED)) != (PIPE_BIND_LINEAR | PIPE_BIND_SHARED))
|
||||
usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
|
||||
} else
|
||||
} else if (!(bind & ZINK_BIND_VIDEO))
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -335,7 +346,10 @@ create_ici(struct zink_screen *screen, VkImageCreateInfo *ici, const struct pipe
|
||||
{
|
||||
ici->sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
ici->pNext = NULL;
|
||||
ici->flags = modifiers_count || dmabuf || bind & (PIPE_BIND_SCANOUT | PIPE_BIND_DEPTH_STENCIL) ? 0 : VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
|
||||
if (util_format_get_num_planes(templ->format) > 1)
|
||||
ici->flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
|
||||
else
|
||||
ici->flags = modifiers_count || dmabuf || bind & (PIPE_BIND_SCANOUT | PIPE_BIND_DEPTH_STENCIL) ? 0 : VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
|
||||
ici->usage = 0;
|
||||
ici->queueFamilyIndexCount = 0;
|
||||
|
||||
@@ -459,21 +473,32 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
VkMemoryRequirements reqs;
|
||||
VkMemoryRequirements reqs = {0};
|
||||
VkMemoryPropertyFlags flags;
|
||||
bool need_dedicated = false;
|
||||
bool shared = templ->bind & PIPE_BIND_SHARED;
|
||||
VkExternalMemoryHandleTypeFlags export_types = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
|
||||
|
||||
unsigned num_planes = util_format_get_num_planes(templ->format);
|
||||
VkImageAspectFlags plane_aspects[] = {
|
||||
VK_IMAGE_ASPECT_PLANE_0_BIT,
|
||||
VK_IMAGE_ASPECT_PLANE_1_BIT,
|
||||
VK_IMAGE_ASPECT_PLANE_2_BIT,
|
||||
};
|
||||
VkExternalMemoryHandleTypeFlags external = 0;
|
||||
bool needs_export = (templ->bind & ZINK_BIND_VIDEO) != 0;
|
||||
if (whandle) {
|
||||
if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
|
||||
if (whandle->type == WINSYS_HANDLE_TYPE_FD || whandle->type == ZINK_EXTERNAL_MEMORY_HANDLE)
|
||||
needs_export |= true;
|
||||
else
|
||||
unreachable("unknown handle type");
|
||||
}
|
||||
if (needs_export) {
|
||||
if (whandle && whandle->type == ZINK_EXTERNAL_MEMORY_HANDLE) {
|
||||
external = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
|
||||
} else {
|
||||
external = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
|
||||
export_types |= VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
|
||||
} else if (whandle->type == ZINK_EXTERNAL_MEMORY_HANDLE) {
|
||||
external = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
|
||||
} else
|
||||
unreachable("unknown handle type");
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: remove linear for wsi */
|
||||
@@ -515,6 +540,8 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
|
||||
if (!success)
|
||||
goto fail1;
|
||||
|
||||
obj->render_target = (ici.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0;
|
||||
|
||||
if (shared || external) {
|
||||
emici.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO;
|
||||
emici.pNext = NULL;
|
||||
@@ -528,11 +555,6 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
|
||||
idfmeci.pNext = ici.pNext;
|
||||
idfmeci.drmFormatModifier = mod;
|
||||
|
||||
/* TODO: store these values from other planes in their
|
||||
* respective zink_resource, and walk the next-pointers to
|
||||
* build up the planar array here instead.
|
||||
*/
|
||||
assert(util_format_get_num_planes(templ->format) == 1);
|
||||
idfmeci.drmFormatModifierPlaneCount = 1;
|
||||
VkSubresourceLayout plane_layout = {
|
||||
.offset = whandle->offset,
|
||||
@@ -576,6 +598,60 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
|
||||
image_wsi_info.pNext = ici.pNext;
|
||||
ici.pNext = &image_wsi_info;
|
||||
}
|
||||
if (util_format_is_yuv(templ->format)) {
|
||||
VkFormatFeatureFlags feats = VK_FORMAT_FEATURE_FLAG_BITS_MAX_ENUM;
|
||||
switch (ici.tiling) {
|
||||
case VK_IMAGE_TILING_LINEAR:
|
||||
feats = screen->format_props[templ->format].linearTilingFeatures;
|
||||
break;
|
||||
case VK_IMAGE_TILING_OPTIMAL:
|
||||
feats = screen->format_props[templ->format].optimalTilingFeatures;
|
||||
break;
|
||||
case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT:
|
||||
/*
|
||||
If is tiling then VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, the value of
|
||||
imageCreateFormatFeatures is found by calling vkGetPhysicalDeviceFormatProperties2
|
||||
with VkImageFormatProperties::format equal to VkImageCreateInfo::format and with
|
||||
VkDrmFormatModifierPropertiesListEXT chained into VkImageFormatProperties2; by
|
||||
collecting all members of the returned array
|
||||
VkDrmFormatModifierPropertiesListEXT::pDrmFormatModifierProperties
|
||||
whose drmFormatModifier belongs to imageCreateDrmFormatModifiers; and by taking the bitwise
|
||||
intersection, over the collected array members, of drmFormatModifierTilingFeatures.
|
||||
(The resultant imageCreateFormatFeatures may be empty).
|
||||
* -Chapter 12. Resource Creation
|
||||
*/
|
||||
for (unsigned i = 0; i < screen->modifier_props[templ->format].drmFormatModifierCount; i++)
|
||||
feats &= screen->modifier_props[templ->format].pDrmFormatModifierProperties[i].drmFormatModifierTilingFeatures;
|
||||
break;
|
||||
default:
|
||||
unreachable("unknown tiling");
|
||||
}
|
||||
if (feats & VK_FORMAT_FEATURE_DISJOINT_BIT)
|
||||
ici.flags |= VK_IMAGE_CREATE_DISJOINT_BIT;
|
||||
VkSamplerYcbcrConversionCreateInfo sycci = {0};
|
||||
sycci.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO;
|
||||
sycci.pNext = NULL;
|
||||
sycci.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
|
||||
sycci.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709;
|
||||
sycci.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
|
||||
sycci.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
sycci.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
sycci.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
sycci.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||
if (!feats || (feats & VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT)) {
|
||||
sycci.xChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN;
|
||||
sycci.yChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN;
|
||||
} else {
|
||||
assert(feats & VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT);
|
||||
sycci.xChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
|
||||
sycci.yChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
|
||||
}
|
||||
sycci.chromaFilter = VK_FILTER_LINEAR;
|
||||
sycci.forceExplicitReconstruction = VK_FALSE;
|
||||
VkResult res = VKSCR(CreateSamplerYcbcrConversion)(screen->dev, &sycci, NULL, &obj->sampler_conversion);
|
||||
if (res != VK_SUCCESS)
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
VkResult result = VKSCR(CreateImage)(screen->dev, &ici, NULL, &obj->image);
|
||||
if (result != VK_SUCCESS) {
|
||||
@@ -614,9 +690,22 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
|
||||
ded.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
|
||||
ded.pNext = NULL;
|
||||
req2.pNext = &ded;
|
||||
VKSCR(GetImageMemoryRequirements2)(screen->dev, &info2, &req2);
|
||||
memcpy(&reqs, &req2.memoryRequirements, sizeof(VkMemoryRequirements));
|
||||
need_dedicated = ded.prefersDedicatedAllocation || ded.requiresDedicatedAllocation;
|
||||
VkImagePlaneMemoryRequirementsInfo plane;
|
||||
plane.sType = VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO;
|
||||
plane.pNext = NULL;
|
||||
if (num_planes > 1)
|
||||
info2.pNext = &plane;
|
||||
for (unsigned i = 0; i < num_planes; i++) {
|
||||
assert(i < ARRAY_SIZE(plane_aspects));
|
||||
plane.planeAspect = plane_aspects[i];
|
||||
VKSCR(GetImageMemoryRequirements2)(screen->dev, &info2, &req2);
|
||||
if (!i)
|
||||
reqs.alignment = req2.memoryRequirements.alignment;
|
||||
obj->plane_sizes[i] = req2.memoryRequirements.size;
|
||||
reqs.size += req2.memoryRequirements.size;
|
||||
reqs.memoryTypeBits |= req2.memoryRequirements.memoryTypeBits;
|
||||
need_dedicated |= ded.prefersDedicatedAllocation || ded.requiresDedicatedAllocation;
|
||||
}
|
||||
} else {
|
||||
VKSCR(GetImageMemoryRequirements)(screen->dev, obj->image, &reqs);
|
||||
}
|
||||
@@ -675,7 +764,7 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
|
||||
}
|
||||
|
||||
VkExportMemoryAllocateInfo emai;
|
||||
if (templ->bind & PIPE_BIND_SHARED && shared) {
|
||||
if ((templ->bind & ZINK_BIND_VIDEO) || ((templ->bind & PIPE_BIND_SHARED) && shared)) {
|
||||
emai.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
|
||||
emai.handleTypes = export_types;
|
||||
|
||||
@@ -739,9 +828,28 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
|
||||
if (VKSCR(BindBufferMemory)(screen->dev, obj->buffer, zink_bo_get_mem(obj->bo), obj->offset) != VK_SUCCESS)
|
||||
goto fail3;
|
||||
} else {
|
||||
if (!(templ->flags & PIPE_RESOURCE_FLAG_SPARSE))
|
||||
if (VKSCR(BindImageMemory)(screen->dev, obj->image, zink_bo_get_mem(obj->bo), obj->offset) != VK_SUCCESS)
|
||||
if (num_planes > 1) {
|
||||
VkBindImageMemoryInfo infos[3];
|
||||
VkBindImagePlaneMemoryInfo planes[3];
|
||||
unsigned offset = 0;
|
||||
for (unsigned i = 0; i < num_planes; i++) {
|
||||
infos[i].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
|
||||
infos[i].pNext = &planes[i];
|
||||
infos[i].image = obj->image;
|
||||
infos[i].memory = zink_bo_get_mem(obj->bo);
|
||||
infos[i].memoryOffset = offset;
|
||||
planes[i].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO;
|
||||
planes[i].pNext = NULL;
|
||||
planes[i].planeAspect = plane_aspects[i];
|
||||
offset += obj->plane_sizes[i];
|
||||
}
|
||||
if (VKSCR(BindImageMemory2)(screen->dev, num_planes, infos) != VK_SUCCESS)
|
||||
goto fail3;
|
||||
} else {
|
||||
if (!(templ->flags & PIPE_RESOURCE_FLAG_SPARSE))
|
||||
if (VKSCR(BindImageMemory)(screen->dev, obj->image, zink_bo_get_mem(obj->bo), obj->offset) != VK_SUCCESS)
|
||||
goto fail3;
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
|
||||
@@ -909,8 +1017,11 @@ zink_resource_get_param(struct pipe_screen *pscreen, struct pipe_context *pctx,
|
||||
default:
|
||||
unreachable("how many planes you got in this thing?");
|
||||
}
|
||||
} else
|
||||
} else if (res->obj->sampler_conversion) {
|
||||
aspect = VK_IMAGE_ASPECT_PLANE_0_BIT;
|
||||
} else {
|
||||
aspect = res->aspect;
|
||||
}
|
||||
switch (param) {
|
||||
case PIPE_RESOURCE_PARAM_NPLANES:
|
||||
if (screen->info.have_EXT_image_drm_format_modifier)
|
||||
|
||||
@@ -44,6 +44,7 @@ struct zink_bo;
|
||||
|
||||
#define ZINK_MAP_TEMPORARY (PIPE_MAP_DRV_PRV << 0)
|
||||
#define ZINK_BIND_TRANSIENT (1 << 30) //transient fb attachment
|
||||
#define ZINK_BIND_VIDEO (1 << 31)
|
||||
|
||||
struct mem_key {
|
||||
unsigned seen_count;
|
||||
@@ -75,6 +76,7 @@ struct zink_resource_object {
|
||||
|
||||
bool storage_init; //layout was set for image
|
||||
bool transfer_dst;
|
||||
bool render_target;
|
||||
bool is_buffer;
|
||||
|
||||
struct zink_bo *bo;
|
||||
@@ -83,6 +85,8 @@ struct zink_resource_object {
|
||||
VkImageUsageFlags vkusage;
|
||||
uint64_t modifier;
|
||||
VkImageAspectFlags modifier_aspect;
|
||||
VkSamplerYcbcrConversionKHR sampler_conversion;
|
||||
unsigned plane_sizes[3];
|
||||
|
||||
bool host_visible;
|
||||
bool coherent;
|
||||
|
||||
Reference in New Issue
Block a user