mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-05 10:48:24 +02:00
vulkan/wsi/wayland: Correctly map 24bpp format types
VK_FORMAT_{R8G8B8,B8G8R8}_{UNORM,SRGB} describe a 3-component, 8bpc,
24bpp, format. This is mapped to that type for Android, and implemented
as such by panvk. radv maps these to 4-component/32bpp formats, but only
support these formats for buffers rather than images. The outlier is
ANV, which relies on the 24->32bpp mapping to happen.
The Wayland WSI was mapping this to the 32bpp R8G8B8A8/B8G8R8A8 formats
instead. This would cause a failure to import the dmabuf into the
compositor on panvk, as it would send a buffer which was too small. (Or,
if it did import: garbage.)
Signed-off-by: Daniel Stone <daniels@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39552>
This commit is contained in:
parent
ec6d077351
commit
b8eb0f88d3
5 changed files with 82 additions and 26 deletions
|
|
@ -49,7 +49,10 @@ anv_init_wsi(struct anv_physical_device *physical_device)
|
|||
&physical_device->instance->vk.alloc,
|
||||
physical_device->master_fd,
|
||||
&physical_device->instance->dri_options,
|
||||
&(struct wsi_device_options){.sw_device = false});
|
||||
&(struct wsi_device_options){
|
||||
.sw_device = false,
|
||||
.emulate_24as32 = true,
|
||||
});
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,10 @@ anv_init_wsi(struct anv_physical_device *physical_device)
|
|||
&physical_device->instance->vk.alloc,
|
||||
physical_device->master_fd,
|
||||
&physical_device->instance->dri_options,
|
||||
&(struct wsi_device_options){.sw_device = false});
|
||||
&(struct wsi_device_options){
|
||||
.sw_device = false,
|
||||
.emulate_24as32 = false
|
||||
});
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ wsi_device_init(struct wsi_device *wsi,
|
|||
wsi->wants_linear = (WSI_DEBUG & WSI_DEBUG_LINEAR) != 0;
|
||||
wsi->x11.extra_xwayland_image = device_options->extra_xwayland_image;
|
||||
wsi->wayland.disable_timestamps = (WSI_DEBUG & WSI_DEBUG_NOWLTS) != 0;
|
||||
wsi->emulate_24as32 = device_options->emulate_24as32;
|
||||
#define WSI_GET_CB(func) \
|
||||
PFN_vk##func func = (PFN_vk##func)proc_addr(pdevice, "vk" #func)
|
||||
WSI_GET_CB(GetPhysicalDeviceExternalSemaphoreProperties);
|
||||
|
|
|
|||
|
|
@ -75,6 +75,14 @@ struct wsi_device {
|
|||
bool has_import_memory_host;
|
||||
bool has_timeline_semaphore;
|
||||
|
||||
/** Whether the device uses 32bpp formats for 24bpp
|
||||
*
|
||||
* If true, VkImages created with R8G8B8/B8G8R8 formats will be
|
||||
* exported as 32bpp to the window system, as if they were B8G8R8A8
|
||||
* or R8G8B8A8
|
||||
*/
|
||||
bool emulate_24as32;
|
||||
|
||||
/** Indicates if wsi_image_create_info::scanout is supported
|
||||
*
|
||||
* If false, WSI will always use either modifiers or the prime blit path.
|
||||
|
|
@ -253,6 +261,7 @@ typedef PFN_vkVoidFunction (VKAPI_PTR *WSI_FN_GetPhysicalDeviceProcAddr)(VkPhysi
|
|||
struct wsi_device_options {
|
||||
bool sw_device;
|
||||
bool extra_xwayland_image;
|
||||
bool emulate_24as32;
|
||||
};
|
||||
|
||||
VkResult
|
||||
|
|
|
|||
|
|
@ -409,6 +409,8 @@ wsi_wl_display_add_drm_format_modifier(struct wsi_wl_display *display,
|
|||
uint32_t drm_format, uint64_t modifier)
|
||||
{
|
||||
VK_FROM_HANDLE(vk_physical_device, pdevice, display->wsi_wl->physical_device);
|
||||
struct wsi_device *wsi_device = pdevice->wsi_device;
|
||||
|
||||
/* From Vulkan 1.3 onwards, we can always try adding the 4444 formats.
|
||||
* If the format isn't supported or isn't renderable,
|
||||
* wsi_wl_display_add_vk_format() will reject it via
|
||||
|
|
@ -567,16 +569,34 @@ wsi_wl_display_add_drm_format_modifier(struct wsi_wl_display *display,
|
|||
* linear -> nonlinear SRGB colorspace conversion before the data is stored.
|
||||
* The inverse function is applied when sampling from SRGB images.
|
||||
* From Wayland's perspective nothing changes, the difference is just how
|
||||
* Vulkan interprets the pixel data. */
|
||||
* Vulkan interprets the pixel data.
|
||||
*
|
||||
* For bonus points, 24bpp VkFormats may appear as 32bpp, depending on the
|
||||
* driver.
|
||||
*/
|
||||
case DRM_FORMAT_BGR888:
|
||||
if (!wsi_device->emulate_24as32) {
|
||||
wsi_wl_display_add_vk_format_modifier(display, formats,
|
||||
VK_FORMAT_R8G8B8_SRGB,
|
||||
WSI_WL_FMT_ALPHA | WSI_WL_FMT_OPAQUE,
|
||||
modifier);
|
||||
wsi_wl_display_add_vk_format_modifier(display, formats,
|
||||
VK_FORMAT_R8G8B8_UNORM,
|
||||
WSI_WL_FMT_ALPHA | WSI_WL_FMT_OPAQUE,
|
||||
modifier);
|
||||
}
|
||||
break;
|
||||
case DRM_FORMAT_XBGR8888:
|
||||
wsi_wl_display_add_vk_format_modifier(display, formats,
|
||||
VK_FORMAT_R8G8B8_SRGB,
|
||||
WSI_WL_FMT_ALPHA | WSI_WL_FMT_OPAQUE,
|
||||
modifier);
|
||||
wsi_wl_display_add_vk_format_modifier(display, formats,
|
||||
VK_FORMAT_R8G8B8_UNORM,
|
||||
WSI_WL_FMT_ALPHA | WSI_WL_FMT_OPAQUE,
|
||||
modifier);
|
||||
if (wsi_device->emulate_24as32) {
|
||||
wsi_wl_display_add_vk_format_modifier(display, formats,
|
||||
VK_FORMAT_R8G8B8_SRGB,
|
||||
WSI_WL_FMT_ALPHA | WSI_WL_FMT_OPAQUE,
|
||||
modifier);
|
||||
wsi_wl_display_add_vk_format_modifier(display, formats,
|
||||
VK_FORMAT_R8G8B8_UNORM,
|
||||
WSI_WL_FMT_ALPHA | WSI_WL_FMT_OPAQUE,
|
||||
modifier);
|
||||
}
|
||||
wsi_wl_display_add_vk_format_modifier(display, formats,
|
||||
VK_FORMAT_R8G8B8A8_SRGB,
|
||||
WSI_WL_FMT_OPAQUE, modifier);
|
||||
|
|
@ -592,15 +612,29 @@ wsi_wl_display_add_drm_format_modifier(struct wsi_wl_display *display,
|
|||
VK_FORMAT_R8G8B8A8_UNORM,
|
||||
WSI_WL_FMT_ALPHA, modifier);
|
||||
break;
|
||||
case DRM_FORMAT_RGB888:
|
||||
if (!wsi_device->emulate_24as32) {
|
||||
wsi_wl_display_add_vk_format_modifier(display, formats,
|
||||
VK_FORMAT_B8G8R8_SRGB,
|
||||
WSI_WL_FMT_ALPHA | WSI_WL_FMT_OPAQUE,
|
||||
modifier);
|
||||
wsi_wl_display_add_vk_format_modifier(display, formats,
|
||||
VK_FORMAT_B8G8R8_UNORM,
|
||||
WSI_WL_FMT_ALPHA | WSI_WL_FMT_OPAQUE,
|
||||
modifier);
|
||||
}
|
||||
break;
|
||||
case DRM_FORMAT_XRGB8888:
|
||||
wsi_wl_display_add_vk_format_modifier(display, formats,
|
||||
VK_FORMAT_B8G8R8_SRGB,
|
||||
WSI_WL_FMT_ALPHA | WSI_WL_FMT_OPAQUE,
|
||||
modifier);
|
||||
wsi_wl_display_add_vk_format_modifier(display, formats,
|
||||
VK_FORMAT_B8G8R8_UNORM,
|
||||
WSI_WL_FMT_ALPHA | WSI_WL_FMT_OPAQUE,
|
||||
modifier);
|
||||
if (wsi_device->emulate_24as32) {
|
||||
wsi_wl_display_add_vk_format_modifier(display, formats,
|
||||
VK_FORMAT_B8G8R8_SRGB,
|
||||
WSI_WL_FMT_ALPHA | WSI_WL_FMT_OPAQUE,
|
||||
modifier);
|
||||
wsi_wl_display_add_vk_format_modifier(display, formats,
|
||||
VK_FORMAT_B8G8R8_UNORM,
|
||||
WSI_WL_FMT_ALPHA | WSI_WL_FMT_OPAQUE,
|
||||
modifier);
|
||||
}
|
||||
wsi_wl_display_add_vk_format_modifier(display, formats,
|
||||
VK_FORMAT_B8G8R8A8_SRGB,
|
||||
WSI_WL_FMT_OPAQUE, modifier);
|
||||
|
|
@ -645,7 +679,8 @@ wsi_wl_display_add_wl_shm_format(struct wsi_wl_display *display,
|
|||
}
|
||||
|
||||
static uint32_t
|
||||
wl_drm_format_for_vk_format(VkFormat vk_format, bool alpha)
|
||||
wl_drm_format_for_vk_format(struct wsi_device *wsi_device,
|
||||
VkFormat vk_format, bool alpha)
|
||||
{
|
||||
switch (vk_format) {
|
||||
case VK_FORMAT_A4R4G4B4_UNORM_PACK16:
|
||||
|
|
@ -678,13 +713,13 @@ wl_drm_format_for_vk_format(VkFormat vk_format, bool alpha)
|
|||
#endif
|
||||
case VK_FORMAT_R8G8B8_UNORM:
|
||||
case VK_FORMAT_R8G8B8_SRGB:
|
||||
return DRM_FORMAT_XBGR8888;
|
||||
return wsi_device->emulate_24as32 ? DRM_FORMAT_XBGR8888 : DRM_FORMAT_BGR888;
|
||||
case VK_FORMAT_R8G8B8A8_UNORM:
|
||||
case VK_FORMAT_R8G8B8A8_SRGB:
|
||||
return alpha ? DRM_FORMAT_ABGR8888 : DRM_FORMAT_XBGR8888;
|
||||
case VK_FORMAT_B8G8R8_UNORM:
|
||||
case VK_FORMAT_B8G8R8_SRGB:
|
||||
return DRM_FORMAT_BGRX8888;
|
||||
return wsi_device->emulate_24as32 ? DRM_FORMAT_XRGB8888 : DRM_FORMAT_RGB888;
|
||||
case VK_FORMAT_B8G8R8A8_UNORM:
|
||||
case VK_FORMAT_B8G8R8A8_SRGB:
|
||||
return alpha ? DRM_FORMAT_ARGB8888 : DRM_FORMAT_XRGB8888;
|
||||
|
|
@ -696,9 +731,12 @@ wl_drm_format_for_vk_format(VkFormat vk_format, bool alpha)
|
|||
}
|
||||
|
||||
static enum wl_shm_format
|
||||
wl_shm_format_for_vk_format(VkFormat vk_format, bool alpha)
|
||||
wl_shm_format_for_vk_format(struct wsi_device *wsi_device,
|
||||
VkFormat vk_format, bool alpha)
|
||||
{
|
||||
uint32_t drm_format = wl_drm_format_for_vk_format(vk_format, alpha);
|
||||
uint32_t drm_format =
|
||||
wl_drm_format_for_vk_format(wsi_device, vk_format, alpha);
|
||||
|
||||
if (drm_format == DRM_FORMAT_INVALID) {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -3799,9 +3837,11 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
|
|||
chain->vk_format = pCreateInfo->imageFormat;
|
||||
chain->buffer_type = buffer_type;
|
||||
if (buffer_type == WSI_WL_BUFFER_NATIVE) {
|
||||
chain->drm_format = wl_drm_format_for_vk_format(chain->vk_format, alpha);
|
||||
chain->drm_format = wl_drm_format_for_vk_format(wsi_device,
|
||||
chain->vk_format, alpha);
|
||||
} else {
|
||||
chain->shm_format = wl_shm_format_for_vk_format(chain->vk_format, alpha);
|
||||
chain->shm_format = wl_shm_format_for_vk_format(wsi_device,
|
||||
chain->vk_format, alpha);
|
||||
}
|
||||
chain->num_drm_modifiers = num_drm_modifiers;
|
||||
if (num_drm_modifiers) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue