{ .format = VK_FORMAT_B8G8R8A8_UNORM, .drm_format = DRM_FORMAT_XRGB8888 },
};
+static void
+get_sorted_vk_formats(struct wsi_device *wsi_device, VkFormat *sorted_formats)
+{
+ for (unsigned i = 0; i < ARRAY_SIZE(available_surface_formats); i++)
+ sorted_formats[i] = available_surface_formats[i].format;
+
+ if (wsi_device->force_bgra8_unorm_first) {
+ for (unsigned i = 0; i < ARRAY_SIZE(available_surface_formats); i++) {
+ if (sorted_formats[i] == VK_FORMAT_B8G8R8A8_UNORM) {
+ sorted_formats[i] = sorted_formats[0];
+ sorted_formats[0] = VK_FORMAT_B8G8R8A8_UNORM;
+ break;
+ }
+ }
+ }
+}
+
static VkResult
wsi_display_surface_get_formats(VkIcdSurfaceBase *icd_surface,
struct wsi_device *wsi_device,
{
VK_OUTARRAY_MAKE(out, surface_formats, surface_format_count);
- for (unsigned i = 0; i < ARRAY_SIZE(available_surface_formats); i++) {
+ VkFormat sorted_formats[ARRAY_SIZE(available_surface_formats)];
+ get_sorted_vk_formats(wsi_device, sorted_formats);
+
+ for (unsigned i = 0; i < ARRAY_SIZE(sorted_formats); i++) {
vk_outarray_append(&out, f) {
- f->format = available_surface_formats[i].format;
+ f->format = sorted_formats[i];
f->colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
}
}
{
VK_OUTARRAY_MAKE(out, surface_formats, surface_format_count);
- for (unsigned i = 0; i < ARRAY_SIZE(available_surface_formats); i++) {
+ VkFormat sorted_formats[ARRAY_SIZE(available_surface_formats)];
+ get_sorted_vk_formats(wsi_device, sorted_formats);
+
+ for (unsigned i = 0; i < ARRAY_SIZE(sorted_formats); i++) {
vk_outarray_append(&out, f) {
assert(f->sType == VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR);
- f->surfaceFormat.format = available_surface_formats[i].format;
+ f->surfaceFormat.format = sorted_formats[i];
f->surfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
}
}
wsi_display_destroy_buffer(struct wsi_display *wsi,
uint32_t buffer)
{
- (void) drmIoctl(wsi->fd, DRM_IOCTL_MODE_DESTROY_DUMB,
- &((struct drm_mode_destroy_dumb) { .handle = buffer }));
+ (void) drmIoctl(wsi->fd, DRM_IOCTL_GEM_CLOSE,
+ &((struct drm_gem_close) { .handle = buffer }));
}
static VkResult
&connector->id, 1,
&connector->current_drm_mode);
if (ret == 0) {
+ /* Disable the HW cursor as the app doesn't have a mechanism
+ * to control it.
+ * Refer to question 12 of the VK_KHR_display spec.
+ */
+ ret = drmModeSetCursor(wsi->fd, connector->crtc_id, 0, 0, 0 );
+ if (ret != 0) {
+ wsi_display_debug("failed to hide cursor err %d %s\n", ret, strerror(-ret));
+ }
+
/* Assume that the mode set is synchronous and that any
* previous image is now idle.
*/
chain->base.get_wsi_image = wsi_display_get_wsi_image;
chain->base.acquire_next_image = wsi_display_acquire_next_image;
chain->base.queue_present = wsi_display_queue_present;
- chain->base.present_mode = create_info->presentMode;
+ chain->base.present_mode = wsi_swapchain_get_present_mode(wsi_device, create_info);
chain->base.image_count = num_images;
chain->wsi = wsi;
return ret;
}
+
+/*
+ * Local version fo the libdrm helper. Added to avoid depending on bleeding
+ * edge version of the library.
+ */
+static int
+local_drmIsMaster(int fd)
+{
+ /* Detect master by attempting something that requires master.
+ *
+ * Authenticating magic tokens requires master and 0 is an
+ * internal kernel detail which we could use. Attempting this on
+ * a master fd would fail therefore fail with EINVAL because 0
+ * is invalid.
+ *
+ * A non-master fd will fail with EACCES, as the kernel checks
+ * for master before attempting to do anything else.
+ *
+ * Since we don't want to leak implementation details, use
+ * EACCES.
+ */
+ return drmAuthMagic(fd, 0) != -EACCES;
+}
+
VkResult
wsi_display_init_wsi(struct wsi_device *wsi_device,
const VkAllocationCallbacks *alloc,
}
wsi->fd = display_fd;
+ if (wsi->fd != -1 && !local_drmIsMaster(wsi->fd))
+ wsi->fd = -1;
+
wsi->alloc = alloc;
list_inithead(&wsi->connectors);