render/vulkan: detect which _UNORM formats support _SRGB views

master
Manuel Stoeckl 1 year ago committed by Simon Ser
parent acc70ee3a5
commit fd4548bb93

@ -101,6 +101,7 @@ const struct wlr_vk_format *vulkan_get_format_from_drm(uint32_t drm_format);
struct wlr_vk_format_modifier_props { struct wlr_vk_format_modifier_props {
VkDrmFormatModifierPropertiesEXT props; VkDrmFormatModifierPropertiesEXT props;
VkExtent2D max_extent; VkExtent2D max_extent;
bool has_mutable_srgb;
}; };
struct wlr_vk_format_props { struct wlr_vk_format_props {
@ -109,6 +110,7 @@ struct wlr_vk_format_props {
struct { struct {
VkExtent2D max_extent; VkExtent2D max_extent;
VkFormatFeatureFlags features; VkFormatFeatureFlags features;
bool has_mutable_srgb;
} shm; } shm;
struct { struct {

@ -258,16 +258,28 @@ static const VkFormatFeatureFlags ycbcr_tex_features =
VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT |
VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT; VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT;
// vk_format_variant should be set to 0=VK_FORMAT_UNDEFINED when not used
static bool query_modifier_usage_support(struct wlr_vk_device *dev, VkFormat vk_format, static bool query_modifier_usage_support(struct wlr_vk_device *dev, VkFormat vk_format,
VkImageUsageFlags usage, const VkDrmFormatModifierPropertiesEXT *m, VkFormat vk_format_variant, VkImageUsageFlags usage,
const VkDrmFormatModifierPropertiesEXT *m,
struct wlr_vk_format_modifier_props *out, const char **errmsg) { struct wlr_vk_format_modifier_props *out, const char **errmsg) {
VkResult res; VkResult res;
*errmsg = NULL; *errmsg = NULL;
VkFormat view_formats[2] = {
vk_format,
vk_format_variant,
};
VkImageFormatListCreateInfoKHR listi = {
.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR,
.pViewFormats = view_formats,
.viewFormatCount = vk_format_variant ? 2 : 1,
};
VkPhysicalDeviceImageDrmFormatModifierInfoEXT modi = { VkPhysicalDeviceImageDrmFormatModifierInfoEXT modi = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT, .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
.drmFormatModifier = m->drmFormatModifier, .drmFormatModifier = m->drmFormatModifier,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE, .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.pNext = &listi,
}; };
VkPhysicalDeviceExternalImageFormatInfo efmti = { VkPhysicalDeviceExternalImageFormatInfo efmti = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
@ -279,6 +291,7 @@ static bool query_modifier_usage_support(struct wlr_vk_device *dev, VkFormat vk_
.type = VK_IMAGE_TYPE_2D, .type = VK_IMAGE_TYPE_2D,
.format = vk_format, .format = vk_format,
.usage = usage, .usage = usage,
.flags = vk_format_variant ? VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT : 0,
.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, .tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
.pNext = &efmti, .pNext = &efmti,
}; };
@ -316,18 +329,29 @@ static bool query_modifier_usage_support(struct wlr_vk_device *dev, VkFormat vk_
} }
static bool query_shm_support(struct wlr_vk_device *dev, VkFormat vk_format, static bool query_shm_support(struct wlr_vk_device *dev, VkFormat vk_format,
VkImageFormatProperties *out, const char **errmsg) { VkFormat vk_format_variant, VkImageFormatProperties *out,
const char **errmsg) {
VkResult res; VkResult res;
*errmsg = NULL; *errmsg = NULL;
VkFormat view_formats[2] = {
vk_format,
vk_format_variant,
};
VkImageFormatListCreateInfoKHR listi = {
.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR,
.pViewFormats = view_formats,
.viewFormatCount = vk_format_variant ? 2 : 1,
.pNext = NULL,
};
VkPhysicalDeviceImageFormatInfo2 fmti = { VkPhysicalDeviceImageFormatInfo2 fmti = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
.type = VK_IMAGE_TYPE_2D, .type = VK_IMAGE_TYPE_2D,
.format = vk_format, .format = vk_format,
.tiling = VK_IMAGE_TILING_OPTIMAL, .tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = vulkan_shm_tex_usage, .usage = vulkan_shm_tex_usage,
.flags = 0, .flags = vk_format_variant ? VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT : 0,
.pNext = NULL, .pNext = &listi,
}; };
VkImageFormatProperties2 ifmtp = { VkImageFormatProperties2 ifmtp = {
.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
@ -390,7 +414,18 @@ static bool query_modifier_support(struct wlr_vk_device *dev,
if ((m.drmFormatModifierTilingFeatures & render_features) == render_features && if ((m.drmFormatModifierTilingFeatures & render_features) == render_features &&
!props->format.is_ycbcr) { !props->format.is_ycbcr) {
struct wlr_vk_format_modifier_props p = {0}; struct wlr_vk_format_modifier_props p = {0};
if (query_modifier_usage_support(dev, props->format.vk, vulkan_render_usage, &m, &p, &errmsg)) { bool supported = false;
if (query_modifier_usage_support(dev, props->format.vk,
props->format.vk_srgb, vulkan_render_usage, &m, &p, &errmsg)) {
supported = true;
p.has_mutable_srgb = props->format.vk_srgb != 0;
}
if (!supported && props->format.vk_srgb) {
supported = query_modifier_usage_support(dev, props->format.vk,
0, vulkan_render_usage, &m, &p, &errmsg);
}
if (supported) {
props->dmabuf.render_mods[props->dmabuf.render_mod_count++] = p; props->dmabuf.render_mods[props->dmabuf.render_mod_count++] = p;
wlr_drm_format_set_add(&dev->dmabuf_render_formats, wlr_drm_format_set_add(&dev->dmabuf_render_formats,
props->format.drm, m.drmFormatModifier); props->format.drm, m.drmFormatModifier);
@ -413,7 +448,18 @@ static bool query_modifier_support(struct wlr_vk_device *dev,
} }
if ((m.drmFormatModifierTilingFeatures & features) == features) { if ((m.drmFormatModifierTilingFeatures & features) == features) {
struct wlr_vk_format_modifier_props p = {0}; struct wlr_vk_format_modifier_props p = {0};
if (query_modifier_usage_support(dev, props->format.vk, vulkan_dma_tex_usage, &m, &p, &errmsg)) { bool supported = false;
if (query_modifier_usage_support(dev, props->format.vk,
props->format.vk_srgb, vulkan_dma_tex_usage, &m, &p, &errmsg)) {
supported = true;
p.has_mutable_srgb = props->format.vk_srgb != 0;
}
if (!supported && props->format.vk_srgb) {
supported = query_modifier_usage_support(dev, props->format.vk,
0, vulkan_dma_tex_usage, &m, &p, &errmsg);
}
if (supported) {
props->dmabuf.texture_mods[props->dmabuf.texture_mod_count++] = p; props->dmabuf.texture_mods[props->dmabuf.texture_mod_count++] = p;
wlr_drm_format_set_add(&dev->dmabuf_texture_formats, wlr_drm_format_set_add(&dev->dmabuf_texture_formats,
props->format.drm, m.drmFormatModifier); props->format.drm, m.drmFormatModifier);
@ -473,10 +519,20 @@ void vulkan_format_props_query(struct wlr_vk_device *dev,
if ((fmtp.formatProperties.optimalTilingFeatures & shm_tex_features) == shm_tex_features && if ((fmtp.formatProperties.optimalTilingFeatures & shm_tex_features) == shm_tex_features &&
!format->is_ycbcr && format_info != NULL) { !format->is_ycbcr && format_info != NULL) {
VkImageFormatProperties ifmtp; VkImageFormatProperties ifmtp;
if (query_shm_support(dev, format->vk, &ifmtp, &errmsg)) { bool supported = false, has_mutable_srgb = false;
if (query_shm_support(dev, format->vk, format->vk_srgb, &ifmtp, &errmsg)) {
supported = true;
has_mutable_srgb = format->vk_srgb != 0;
}
if (!supported && format->vk_srgb) {
supported = query_shm_support(dev, format->vk, 0, &ifmtp, &errmsg);
}
if (supported) {
props.shm.max_extent.width = ifmtp.maxExtent.width; props.shm.max_extent.width = ifmtp.maxExtent.width;
props.shm.max_extent.height = ifmtp.maxExtent.height; props.shm.max_extent.height = ifmtp.maxExtent.height;
props.shm.features = fmtp.formatProperties.optimalTilingFeatures; props.shm.features = fmtp.formatProperties.optimalTilingFeatures;
props.shm.has_mutable_srgb = has_mutable_srgb;
dev->shm_formats[dev->shm_format_count] = format->drm; dev->shm_formats[dev->shm_format_count] = format->drm;
++dev->shm_format_count; ++dev->shm_format_count;

@ -455,8 +455,8 @@ struct wlr_vk_device *vulkan_device_create(struct wlr_vk_instance *ini,
dev->drm_fd = -1; dev->drm_fd = -1;
// For dmabuf import we require at least the external_memory_fd, // For dmabuf import we require at least the external_memory_fd,
// external_memory_dma_buf, queue_family_foreign and // external_memory_dma_buf, queue_family_foreign,
// image_drm_format_modifier extensions. // image_drm_format_modifier, and image_format_list extensions.
// The size is set to a large number to allow for other conditional // The size is set to a large number to allow for other conditional
// extensions before the device is created // extensions before the device is created
const char *extensions[32] = {0}; const char *extensions[32] = {0};

Loading…
Cancel
Save