mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	render/vulkan: detect which _UNORM formats support _SRGB views
This commit is contained in:
		
							parent
							
								
									acc70ee3a5
								
							
						
					
					
						commit
						fd4548bb93
					
				
					 3 changed files with 67 additions and 9 deletions
				
			
		| 
						 | 
					@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue